6 #include <l4/sys/types.h>
7 #include <l4/cxx/ipc_stream>
11 #include <l4/re/util/cap_alloc>
13 namespace L4Re { namespace Util {
15 template< typename ICU >
19 ICU const *this_icu() const { return static_cast<ICU const *>(this); }
20 ICU *this_icu() { return static_cast<ICU*>(this); }
23 int dispatch(l4_umword_t obj, L4::Ipc::Iostream &iso);
27 template<typename ICU>
29 Icu_svr<ICU>::dispatch(l4_umword_t, L4::Ipc::Iostream &ios)
31 typedef typename ICU::Irq Irq;
34 if (tag.label() != L4_PROTO_IRQ)
44 L4::Ipc::Snd_fpage irq_fp;
45 ios >> irqnum >> irq_fp;
46 Irq *irq = this_icu()->icu_get_irq(irqnum);
50 return irq->bind(this_icu(), irq_fp);
52 case L4_ICU_OP_UNBIND:
55 L4::Ipc::Snd_fpage irq_fp;
56 ios >> irqnum >> irq_fp;
57 Irq *irq = this_icu()->icu_get_irq(irqnum);
61 return irq->unbind(this_icu(), irq_fp);
66 this_icu()->icu_get_info(&i);
67 ios << (l4_umword_t)i.features << (l4_umword_t)i.nr_irqs
68 << (l4_umword_t)i.nr_msis;
71 case L4_ICU_OP_MSI_INFO:
75 Irq *irq = this_icu()->icu_get_irq(msi);
78 return irq->msi_info(ios);
80 case L4_ICU_OP_UNMASK:
85 Irq *irq = this_icu()->icu_get_irq(irqnum);
87 irq->mask(op == L4_ICU_OP_MASK);
96 template< typename ICU >
97 class Icu_cap_array_svr : public Icu_svr<ICU>
100 static L4::Cap<L4::Irq> alloc_irq_cap()
101 { return L4Re::Util::cap_alloc.alloc<L4::Irq>(); }
103 static void free_irq_cap(L4::Cap<L4::Irq> &cap)
107 L4Re::Util::cap_alloc.free(cap);
118 ~Irq() { ICU::free_irq_cap(_cap); }
120 explicit Irq(L4Re::Util::Auto_cap<L4::Irq>::Cap const &cap)
124 { if (_cap) _cap->trigger(); }
126 int bind(ICU *, L4::Ipc::Snd_fpage const &irq_fp);
127 int unbind(ICU *, L4::Ipc::Snd_fpage const &irq_fp);
128 void mask(bool mask) const
131 int msi_info(L4::Ipc::Ostream &) const
132 { return -L4_EINVAL; }
134 L4::Cap<L4::Irq> cap() const { return _cap; }
137 L4::Cap<L4::Irq> _cap;
146 Icu_cap_array_svr(unsigned nr_irqs, Irq *irqs)
147 : _irqs(irqs), _nr_irqs(nr_irqs)
150 Irq *icu_get_irq(l4_umword_t irqnum)
152 if (irqnum >= _nr_irqs)
155 return _irqs + irqnum;
158 void icu_get_info(l4_icu_info_t *inf)
161 inf->nr_irqs = _nr_irqs;
166 template< typename ICU >
168 Icu_cap_array_svr<ICU>::Irq::bind(ICU *cfb, L4::Ipc::Snd_fpage const &irq_fp)
170 if (!irq_fp.cap_received())
173 _cap = ICU::alloc_irq_cap();
174 if (!_cap.is_valid())
176 _cap.move(L4::cap_cast<L4::Irq>(cfb->rcv_cap()));
180 template< typename ICU >
182 Icu_cap_array_svr<ICU>::Irq::unbind(ICU *, L4::Ipc::Snd_fpage const &/*irq_fp*/)
184 L4Re::Env::env()->task()->unmap(_cap.fpage(L4_FPAGE_RWX), L4_FP_ALL_SPACES);
185 _cap = L4::Cap<L4::Irq>::Invalid;