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)
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:
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>
105 explicit Irq(L4Re::Util::Auto_cap<L4::Irq>::Cap const &cap)
111 int bind(ICU *, L4::Snd_fpage const &irq_fp);
112 int unbind(ICU *, L4::Snd_fpage const &irq_fp);
113 void mask(bool mask) const
116 int msi_info(L4::Ipc_ostream &) const
117 { return -L4_EINVAL; }
119 L4::Cap<L4::Irq> cap() const { return _cap.get(); }
122 L4Re::Util::Auto_cap<L4::Irq>::Cap _cap;
131 Icu_cap_array_svr(unsigned nr_irqs, Irq *irqs)
132 : _irqs(irqs), _nr_irqs(nr_irqs)
135 Irq *icu_get_irq(l4_umword_t irqnum)
137 if (irqnum >= _nr_irqs)
140 return _irqs + irqnum;
143 void icu_get_info(l4_icu_info_t *inf)
146 inf->nr_irqs = _nr_irqs;
151 template< typename ICU >
153 Icu_cap_array_svr<ICU>::Irq::bind(ICU *cfb, L4::Snd_fpage const &irq_fp)
155 if (!irq_fp.cap_received())
158 _cap = L4Re::Util::cap_alloc.alloc<L4::Irq>();
159 if (!_cap.is_valid())
161 _cap.get().move(L4::cap_cast<L4::Irq>(cfb->rcv_cap()));
165 template< typename ICU >
167 Icu_cap_array_svr<ICU>::Irq::unbind(ICU *, L4::Snd_fpage const &/*irq_fp*/)
169 L4Re::Env::env()->task()->unmap(_cap.fpage(L4_FPAGE_RWX), L4_FP_ALL_SPACES);
170 _cap = L4::Cap<L4::Irq>::Invalid;