4 * syscalls_factory.h --
6 * Implementation of the factory system call
8 * (c) 2012-2013 Björn Döbel <doebel@os.inf.tu-dresden.de>,
9 * economic rights: Technische Universität Dresden (Germany)
10 * This file is part of TUD:OS and distributed under the terms of the
11 * GNU General Public License 2.
12 * Please see the COPYING-GPL-2 file for details.
16 #include "syscalls_handler.h"
17 #include <l4/util/bitops.h>
24 * Handler for factory system calls.
26 * This class deals mainly with thread and IRQ objects and keeps track
27 * of their capabilities.
29 class Factory : public SyscallHandler
31 /* Trace CAP -> thread mappings
33 * This allows us to easily find the thread group belonging to a
34 * capability (which in reality maps to the gate agent IPC gate)
36 std::map<unsigned, Romain::Thread_group*> _threads;
37 unsigned _thread_count;
39 unsigned _irqbits[16]; // trace if certain caps are IRQ objects
41 void create_thread(Romain::App_instance *i,
42 Romain::App_thread *t,
43 Romain::Thread_group *tg,
48 // writing this in C is sooo much shorter than creating a stringbuf...
49 snprintf(threadname, 24, "thread%d", _thread_count);
53 MSG() << "Creating new thread! " << _threads.size();
54 MSG() << "CAP: " << std::hex << cap;
55 Romain::Thread_group* newgroup =
56 Romain::_the_instance_manager->create_thread_group(0, 0, threadname,
58 MSG() << "Group @ " << (void*)newgroup;
61 _threads[cap] = newgroup;
63 /* We launch the replica threads now. At this point we must have
64 * made sure that all faults raised by these threads will be resolved,
65 * because we cannot be sure if they run before or after any subsequent
68 for (std::vector<Romain::App_thread*>::const_iterator it = newgroup->threads.begin();
69 it != newgroup->threads.end(); ++it)
74 t->vcpu()->r()->ax = l4_msgtag(0, 1, 0, 0).raw;
75 //enter_kdebug("created thread");
80 * Create IRQ and store that this cap is an IRQ.
82 void create_irq(Romain::App_instance *i,
83 Romain::App_thread *t,
84 Romain::Thread_group *tg,
88 DEBUG() << "Creating IRQ with cap " << std::hex << (cap >> L4_CAP_SHIFT);
89 mark_irq((cap >> L4_CAP_SHIFT) - Romain::FIRST_REPLICA_CAP);
90 L4::Cap<L4::Irq> irqcap(cap);
91 t->vcpu()->r()->ax = L4Re::Env::env()->factory()->create_irq(irqcap).raw;
96 * Store that the given cap points to an IRQ object
98 void mark_irq(unsigned cap)
100 DEBUG() << "cap = " << std::hex << cap;
101 unsigned *dest = _irqbits;
102 dest += cap / (sizeof(*dest) * 8);
103 cap &= sizeof(*dest) * 8 - 1;
109 : SyscallHandler(), _threads(), _thread_count(0)
113 Romain::Observer::ObserverReturnVal
114 handle(Romain::App_instance *i,
115 Romain::App_thread *t,
116 Romain::Thread_group *tg,
117 Romain::App_model *a);
120 void register_thread_group(Romain::Thread_group* tg, l4_umword_t cap)
122 _check(cap < Romain::FIRST_REPLICA_CAP, "invalid replica #");
125 DEBUG() << std::hex << cap << " := " << (void*)_threads[cap];
130 * Get the Thread_group to an agent's gate.
132 Romain::Thread_group* thread_for_cap(l4_umword_t cap)
134 DEBUG() << std::hex << cap << " -> " << (void*)_threads[cap];
135 return _threads[cap];
140 * Figure out if a cap belongs to an IRQ object (that was created
141 * through this factory.
143 bool is_irq(unsigned cap)
145 cap >>= L4_CAP_SHIFT;
146 if (cap < Romain::FIRST_REPLICA_CAP) {
149 cap -= Romain::FIRST_REPLICA_CAP;
151 DEBUG() << "cap = " << std::hex << cap;
152 unsigned *dest = _irqbits;
153 dest += cap / (sizeof(*dest) * 8);
154 cap &= sizeof(*dest) * 8 - 1;
155 return *dest & (1 << cap);
161 extern Romain::Factory theObjectFactory;