4 #include "kobject_helper.h"
5 #include "l4_buf_iter.h"
16 Op_eoi = Irq::Op_eoi_2, // 4
29 template< typename REAL_ICU >
30 class Icu_h : public Kobject_h<REAL_ICU>, public Icu_h_base
33 REAL_ICU const *this_icu() const
34 { return nonull_static_cast<REAL_ICU const *>(this); }
37 { return nonull_static_cast<REAL_ICU *>(this); }
46 Icu_h_base::deref_irq(L4_msg_tag *tag, Utcb const *utcb)
48 L4_snd_item_iter snd_items(utcb, tag->words());
51 if (!tag->items() || !snd_items.next())
53 *tag = Kobject_iface::commit_result(-L4_err::EInval);
57 L4_fpage bind_irq(snd_items.get()->d);
58 if (EXPECT_FALSE(!bind_irq.is_objpage()))
60 *tag = Kobject_iface::commit_error(utcb, L4_error::Overflow);
64 register Context *const c_thread = ::current();
65 register Space *const c_space = c_thread->space();
66 unsigned char irq_rights = 0;
67 irq = Kobject::dcast<Irq*>(c_space->lookup_local(bind_irq.obj_index(), &irq_rights));
71 *tag = Kobject_iface::commit_result(-L4_err::EInval);
75 if (EXPECT_FALSE(!(irq_rights & L4_fpage::X)))
77 *tag = Kobject_iface::commit_result(-L4_err::EPerm);
86 template<typename REAL_ICU>
88 Icu_h<REAL_ICU>::icu_mask_irq(bool mask, unsigned irqnum)
90 Irq_base *i = this_icu()->icu_get_irq(irqnum);
102 template<typename REAL_ICU>
104 Icu_h<REAL_ICU>::icu_unbind_irq(unsigned irqnum)
106 Irq_base *irq = this_icu()->icu_get_irq(irqnum);
111 return Kobject_iface::commit_result(0);
115 template<typename REAL_ICU>
117 Icu_h<REAL_ICU>::icu_get_msi_info(Mword msi, Utcb *out)
121 return Kobject_iface::commit_result(-L4_err::EInval);
124 PUBLIC template< typename REAL_ICU >
127 Icu_h<REAL_ICU>::icu_invoke(L4_obj_ref, Mword /*rights*/,
129 Utcb const *utcb, Utcb *out)
131 L4_msg_tag tag = f->tag();
133 switch (utcb->values[0])
137 return Kobject_iface::commit_result(-L4_err::EInval);
139 if (Irq *irq = deref_irq(&tag, utcb))
140 return this_icu()->icu_bind_irq(irq, utcb->values[1]);
146 return Kobject_iface::commit_result(-L4_err::EInval);
148 if (deref_irq(&tag, utcb))
149 return this_icu()->icu_unbind_irq(utcb->values[1]);
154 this_icu()->icu_get_info(&out->values[0], &out->values[1], &out->values[2]);
155 return Kobject_iface::commit_result(0, 3);
159 return Kobject_iface::commit_result(-L4_err::EInval);
160 return this_icu()->icu_get_msi_info(utcb->values[1], out);
165 return Kobject_h<REAL_ICU>::no_reply();
167 this_icu()->icu_mask_irq(utcb->values[0] == Op_mask, utcb->values[1]);
168 return Kobject_h<REAL_ICU>::no_reply();
171 if (tag.words() >= 3)
173 Irq_base *irq = this_icu()->icu_get_irq(utcb->values[1]);
177 irq->set_mode(utcb->values[2]);
178 return Kobject_iface::commit_result(0);
182 return Kobject_iface::commit_result(-L4_err::EInval);
185 return Kobject_iface::commit_result(-L4_err::ENosys);
190 template< typename REAL_ICU >
192 Icu_h<REAL_ICU>::kinvoke(L4_obj_ref ref, Mword rights,
194 Utcb const *in, Utcb *out)
196 L4_msg_tag tag = f->tag();
198 if (EXPECT_FALSE(tag.proto() != L4_msg_tag::Label_irq))
199 return Kobject_iface::commit_result(-L4_err::EBadproto);
201 return icu_invoke(ref, rights, f, in, out);