Fiasco.OC: hold irq-objects in core for resignment

This commit is contained in:
Stefan Kalkowski 2012-07-31 15:27:19 +02:00 committed by Norman Feske
parent 5118b5e1e6
commit 4753aee540
2 changed files with 59 additions and 7 deletions

View File

@ -24,6 +24,7 @@ namespace Fiasco {
#include <l4/sys/factory.h>
}
static Genode::Avl_tree<Genode::Cpu_session_irqs> _irq_tree;
Genode::Ram_dataspace_capability Genode::Cpu_session_component::utcb(Genode::Thread_capability thread_cap)
{
@ -69,18 +70,30 @@ Genode::Cpu_session_component::native_cap(Genode::Thread_capability cap)
Genode::Native_capability Genode::Cpu_session_component::alloc_irq()
{
using namespace Fiasco;
using namespace Genode;
/* find irq object container of this cpu-session */
Cpu_session_irqs* node = _irq_tree.first();
if (node)
node = node->find_by_session(this);
/* if not found, we've to create one */
if (!node) {
node = new (&_md_alloc) Cpu_session_irqs(this);
_irq_tree.insert(node);
}
/* construct irq kernel-object */
Cap_index* i = cap_map()->insert(platform_specific()->cap_id_alloc()->alloc());
l4_msgtag_t res = l4_factory_create_irq(L4_BASE_FACTORY_CAP, i->kcap());
if (l4_error(res))
if (l4_error(res)) {
PWRN("Allocation of irq object failed!");
return Genode::Native_capability();
}
/*
* Increment reference-counter, because we don't hold any
* reference to IRQ object by now
*/
i->inc();
return Genode::Native_capability(i);
/* construct cap and hold a reference in the irq container object */
Genode::Native_capability cap(i);
return (node->add(cap)) ? cap : Genode::Native_capability();
}

View File

@ -151,6 +151,45 @@ namespace Genode {
Native_capability native_cap(Thread_capability);
Native_capability alloc_irq();
};
class Cpu_session_irqs : public Avl_node<Cpu_session_irqs>
{
private:
enum { IRQ_MAX = 20 };
Cpu_session_component* _owner;
Native_capability _irqs[IRQ_MAX];
unsigned _cnt;
public:
Cpu_session_irqs(Cpu_session_component *owner)
: _owner(owner), _cnt(0) {}
bool add(Native_capability irq)
{
if (_cnt >= (IRQ_MAX - 1))
return false;
_irqs[_cnt++] = irq;
return true;
}
/************************
** Avl node interface **
************************/
bool higher(Cpu_session_irqs *c) { return (c->_owner > _owner); }
Cpu_session_irqs *find_by_session(Cpu_session_component *o)
{
if (o == _owner) return this;
Cpu_session_irqs *c = Avl_node<Cpu_session_irqs>::child(o > _owner);
return c ? c->find_by_session(o) : 0;
}
};
}
#endif /* _CORE__INCLUDE__CPU_SESSION_COMPONENT_H_ */