+
+
+Romain::Observer::ObserverReturnVal
+Romain::Factory::handle(Romain::App_instance* inst,
+ Romain::App_thread* t,
+ Romain::Thread_group* tg,
+ Romain::App_model* am)
+{
+ MSGt(t) << "Factory system call";
+ l4_utcb_t *utcb = reinterpret_cast<l4_utcb_t*>(t->remote_utcb());
+ MSGt(t) << "UTCB @ " << std::hex << (unsigned)utcb;
+ _check((l4_addr_t)utcb == ~0UL, "remote utcb ptr??");
+
+ l4_umword_t obj = l4_utcb_mr_u(utcb)->mr[0];
+ l4_umword_t cap = l4_utcb_br_u(utcb)->br[0] & ~L4_RCV_ITEM_SINGLE_CAP;
+ MSGt(t) << std::hex << L4_PROTO_THREAD;
+ MSGt(t) << "object type: " << std::hex << obj
+ << " cap: " << cap;
+
+ switch(obj) {
+ case L4_PROTO_THREAD:
+ create_thread(inst, t, tg, am, cap);
+ return Romain::Observer::Replicatable;
+
+ case L4_PROTO_IRQ:
+ create_irq(inst, t, tg, am, cap);
+ return Romain::Observer::Replicatable;
+
+ case L4Re::Protocol::Dataspace:
+ SyscallHandler::proxy_syscall(inst, t, tg, am);
+ return Romain::Observer::Replicatable;
+
+ default:
+ break;
+ }
+
+ enter_kdebug("theObjectFactory");
+ return Romain::Observer::Finished;
+}
+
+
+Romain::Observer::ObserverReturnVal
+Romain::Scheduling::handle(Romain::App_instance* inst,
+ Romain::App_thread* t,
+ Romain::Thread_group* tg,
+ Romain::App_model* am)
+{
+ l4_utcb_t *utcb = reinterpret_cast<l4_utcb_t*>(t->remote_utcb());
+ l4_umword_t op = l4_utcb_mr_u(utcb)->mr[0];
+
+ MSGt(t) << "\033[32mschedule(" << std::hex << op << ")\033[0m";
+ if (op == L4_SCHEDULER_RUN_THREAD_OP) {
+ l4_umword_t cap = l4_utcb_mr_u(utcb)->mr[6] >> L4_CAP_SHIFT;
+ Romain::Thread_group* group = theObjectFactory.thread_for_cap(cap);
+ group->scheduler_run(t);
+ } else {
+ enter_kdebug("run_thread != 1");
+ SyscallHandler::proxy_syscall(inst, t, tg, am);
+ }
+
+ return Romain::Observer::Replicatable;
+}
+
+
+Romain::Observer::ObserverReturnVal
+Romain::IrqHandler::handle(Romain::App_instance* inst,
+ Romain::App_thread* t,
+ Romain::Thread_group* tg,
+ Romain::App_model* am)
+{
+ l4_utcb_t *utcb = reinterpret_cast<l4_utcb_t*>(t->remote_utcb());
+ unsigned op = l4_utcb_mr_u(utcb)->mr[0];
+ unsigned label = l4_utcb_mr_u(utcb)->mr[1];
+ unsigned cap = t->vcpu()->r()->dx & L4_CAP_MASK;
+ l4_msgtag_t ret;
+
+ L4::Cap<L4::Irq> irq(cap);
+
+ DEBUGt(t) << "IRQ: cap = " << std::hex << cap << " op = " << op;
+
+ if (!theObjectFactory.is_irq(cap)) {
+ SyscallHandler::proxy_syscall(inst, t, tg, am);
+ return Romain::Observer::Replicatable;
+ }
+
+ switch(op) {
+ /*
+ * For attach(), we cannot simply redirect to the gate
+ * agent, because we need to modify the thread that is
+ * attached to the IRQ
+ */
+ case L4_IRQ_OP_ATTACH:
+ {
+ l4_umword_t attach_cap = l4_utcb_mr_u(utcb)->mr[3] & L4_FPAGE_ADDR_MASK;
+ DEBUG() << "attach " << std::hex << (attach_cap >> L4_CAP_SHIFT);
+ Romain::Thread_group *group = theObjectFactory.thread_for_cap(attach_cap >> L4_CAP_SHIFT);
+ l4_msgtag_t ret;
+
+ if (!group) {
+ ERROR() << "Unimplemented: Attaching someone else but myself!";
+ enter_kdebug();
+ }
+
+ ret = irq->attach(label, group->gateagent->listener_cap);
+
+ t->vcpu()->r()->ax = ret.raw;
+ DEBUG() << std::hex << ret.raw ;
+ return Romain::Observer::Replicatable;
+ }
+ break;
+
+ case L4_IRQ_OP_TRIGGER:
+ DEBUGt(t) << ":: trigger";
+ //enter_kdebug("trigger");
+ irq->trigger();
+ break;
+ case L4_IRQ_OP_EOI:
+ DEBUGt(t) << ":: eoi";
+ tg->gateagent->trigger_agent(t);
+ break;
+
+ case L4_IRQ_OP_CHAIN:
+ enter_kdebug("irq::chain?");
+ }
+
+ return Romain::Observer::Replicatable;
+}