3 * \brief Interrupt functionality
7 * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
8 * Alexander Warg <warg@os.inf.tu-dresden.de>,
9 * Björn Döbel <doebel@os.inf.tu-dresden.de>
10 * economic rights: Technische Universität Dresden (Germany)
12 * This file is part of TUD:OS and distributed under the terms of the
13 * GNU General Public License 2.
14 * Please see the COPYING-GPL-2 file for details.
16 * As a special exception, you may use this file as part of a free software
17 * library without restriction. Specifically, if other files instantiate
18 * templates or use macros or inline functions from this file, or you compile
19 * this file and link it with other files to produce an executable, this
20 * file does not by itself cause the resulting executable to be covered by
21 * the GNU General Public License. This exception does not however
22 * invalidate any other reasons why the executable file might be covered by
23 * the GNU General Public License.
27 #include <l4/sys/kernel_object.h>
28 #include <l4/sys/ipc.h>
31 * \defgroup l4_irq_api IRQs
32 * \ingroup l4_kernel_object_api
34 * \brief The IRQ and IRQ class.
36 * <c>\#include <l4/sys/irq.h></c>
38 * The IRQ class provides access to abstract interrupts
39 * provided by the micro kernel. Interrupts may be hardware interrupts
40 * provided by the platform interrupt controller, virtual device interrupts
41 * provided by the micro kernel virtual devices (virtual serial or trace
42 * buffer), or IRQs (virtual interrupts that can be triggered by user
45 * IRQ objects can be created using a Factory, see \ref l4_factory_api
46 * (l4_factory_create_irq()).
51 * \brief Attach to an interrupt source.
54 * \param irq IRQ to attach to.
55 * \param label Identifier of the IRQ.
56 * \param thread Thread to attach the interrupt to.
58 * \return Syscall return tag
61 l4_irq_attach(l4_cap_idx_t irq, l4_umword_t label,
62 l4_cap_idx_t thread) L4_NOTHROW;
68 l4_irq_attach_u(l4_cap_idx_t irq, l4_umword_t label,
69 l4_cap_idx_t thread, l4_utcb_t *utcb) L4_NOTHROW;
72 * \brief Chain an IRQ to another master IRQ source.
75 * The chaining feature of IRQ objects allows to deal with shared IRQs.
76 * For chaining IRQs there must be a master IRQ object, bound to the
77 * real IRQ source. Note, the master IRQ must not have a thread attached to it.
78 * This function allows to add a limited number of slave IRQs to this master
79 * IRQ, with the semantics that each of the slave IRQs is triggered whenever
80 * the master IRQ is triggered. The master IRQ will be masked automatically
81 * when an IRQ is delivered and shall be unmasked when all attached slave IRQs
84 * \param irq The master IRQ object.
85 * \param label Identifier of the IRQ.
86 * \param slave The slave that shall be attached to the master.
88 * \return Syscall return tag
91 l4_irq_chain(l4_cap_idx_t irq, l4_umword_t label,
92 l4_cap_idx_t slave) L4_NOTHROW;
98 l4_irq_chain_u(l4_cap_idx_t irq, l4_umword_t label,
99 l4_cap_idx_t slave, l4_utcb_t *utcb) L4_NOTHROW;
102 * \brief Detach from an interrupt source.
103 * \ingroup l4_irq_api
105 * \param irq IRQ to detach from.
107 * \return Syscall return tag
109 L4_INLINE l4_msgtag_t
110 l4_irq_detach(l4_cap_idx_t irq) L4_NOTHROW;
115 L4_INLINE l4_msgtag_t
116 l4_irq_detach_u(l4_cap_idx_t irq, l4_utcb_t *utcb) L4_NOTHROW;
120 * \brief Trigger an IRQ.
121 * \ingroup l4_irq_api
123 * \param irq IRQ to trigger.
124 * \pre \a irq must be a reference to an IRQ.
126 * \return Syscall return tag.
128 * Note that this function is a send only operation, i.e. there is no return
129 * value except for a failed send operation. Especially l4_error() will
130 * return an error value from the message tag which still contains the IRQ
131 * protocol used for the send operation.
133 * Use l4_ipc_error() to check for (send) errors.
135 L4_INLINE l4_msgtag_t
136 l4_irq_trigger(l4_cap_idx_t irq) L4_NOTHROW;
141 L4_INLINE l4_msgtag_t
142 l4_irq_trigger_u(l4_cap_idx_t irq, l4_utcb_t *utcb) L4_NOTHROW;
145 * \brief Unmask and wait for specified IRQ.
146 * \ingroup l4_irq_api
148 * \param irq IRQ to wait for.
151 * \return Syscall return tag
153 L4_INLINE l4_msgtag_t
154 l4_irq_receive(l4_cap_idx_t irq, l4_timeout_t to) L4_NOTHROW;
159 L4_INLINE l4_msgtag_t
160 l4_irq_receive_u(l4_cap_idx_t irq, l4_timeout_t to, l4_utcb_t *utcb) L4_NOTHROW;
163 * \brief Unmask IRQ and wait for any message.
164 * \ingroup l4_irq_api
166 * \param irq IRQ to wait for.
167 * \param label Receive label.
170 * \return Syscall return tag
172 L4_INLINE l4_msgtag_t
173 l4_irq_wait(l4_cap_idx_t irq, l4_umword_t *label,
174 l4_timeout_t to) L4_NOTHROW;
179 L4_INLINE l4_msgtag_t
180 l4_irq_wait_u(l4_cap_idx_t irq, l4_umword_t *label,
181 l4_timeout_t to, l4_utcb_t *utcb) L4_NOTHROW;
185 * \ingroup l4_irq_api
187 * \param irq IRQ to unmask.
189 * \return Syscall return tag
191 * \note l4_irq_wait and l4_irq_receive are doing the unmask themselves.
193 L4_INLINE l4_msgtag_t
194 l4_irq_unmask(l4_cap_idx_t irq) L4_NOTHROW;
199 L4_INLINE l4_msgtag_t
200 l4_irq_unmask_u(l4_cap_idx_t irq, l4_utcb_t *utcb) L4_NOTHROW;
207 L4_IRQ_OP_ATTACH = 1,
208 L4_IRQ_OP_TRIGGER = 2,
213 /**************************************************************************
217 L4_INLINE l4_msgtag_t
218 l4_irq_attach_u(l4_cap_idx_t irq, l4_umword_t label,
219 l4_cap_idx_t thread, l4_utcb_t *utcb) L4_NOTHROW
221 l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
222 m->mr[0] = L4_IRQ_OP_ATTACH;
224 m->mr[2] = l4_map_obj_control(0, 0);
225 m->mr[3] = l4_obj_fpage(thread, 0, L4_FPAGE_RWX).raw;
226 return l4_ipc_call(irq, utcb, l4_msgtag(L4_PROTO_IRQ, 2, 1, 0), L4_IPC_NEVER);
229 L4_INLINE l4_msgtag_t
230 l4_irq_chain_u(l4_cap_idx_t irq, l4_umword_t label,
231 l4_cap_idx_t slave, l4_utcb_t *utcb) L4_NOTHROW
233 l4_msg_regs_t *m = l4_utcb_mr_u(utcb);
234 m->mr[0] = L4_IRQ_OP_CHAIN;
236 m->mr[2] = l4_map_obj_control(0, 0);
237 m->mr[3] = l4_obj_fpage(slave, 0, L4_FPAGE_RWX).raw;
238 return l4_ipc_call(irq, utcb, l4_msgtag(L4_PROTO_IRQ, 2, 1, 0), L4_IPC_NEVER);
241 L4_INLINE l4_msgtag_t
242 l4_irq_detach_u(l4_cap_idx_t irq, l4_utcb_t *utcb) L4_NOTHROW
244 l4_utcb_mr_u(utcb)->mr[0] = L4_IRQ_OP_ATTACH;
245 return l4_ipc_call(irq, utcb, l4_msgtag(L4_PROTO_IRQ, 1, 0, 0), L4_IPC_NEVER);
248 L4_INLINE l4_msgtag_t
249 l4_irq_trigger_u(l4_cap_idx_t irq, l4_utcb_t *utcb) L4_NOTHROW
251 l4_utcb_mr_u(utcb)->mr[0] = L4_IRQ_OP_TRIGGER;
252 return l4_ipc_send(irq, utcb, l4_msgtag(L4_PROTO_IRQ, 1, 0, 0),
253 L4_IPC_BOTH_TIMEOUT_0);
256 L4_INLINE l4_msgtag_t
257 l4_irq_receive_u(l4_cap_idx_t irq, l4_timeout_t to, l4_utcb_t *utcb) L4_NOTHROW
259 l4_utcb_mr_u(utcb)->mr[0] = L4_IRQ_OP_EOI;
260 return l4_ipc_call(irq, utcb, l4_msgtag(L4_PROTO_IRQ, 1, 0, 0), to);
263 L4_INLINE l4_msgtag_t
264 l4_irq_wait_u(l4_cap_idx_t irq, l4_umword_t *label,
265 l4_timeout_t to, l4_utcb_t *utcb) L4_NOTHROW
267 l4_utcb_mr_u(utcb)->mr[0] = L4_IRQ_OP_EOI;
268 return l4_ipc_send_and_wait(irq, utcb, l4_msgtag(L4_PROTO_IRQ, 1, 0, 0),
272 L4_INLINE l4_msgtag_t
273 l4_irq_unmask_u(l4_cap_idx_t irq, l4_utcb_t *utcb) L4_NOTHROW
275 l4_utcb_mr_u(utcb)->mr[0] = L4_IRQ_OP_EOI;
276 return l4_ipc_send(irq, utcb, l4_msgtag(L4_PROTO_IRQ, 1, 0, 0), L4_IPC_NEVER);
280 L4_INLINE l4_msgtag_t
281 l4_irq_attach(l4_cap_idx_t irq, l4_umword_t label,
282 l4_cap_idx_t thread) L4_NOTHROW
284 return l4_irq_attach_u(irq, label, thread, l4_utcb());
287 L4_INLINE l4_msgtag_t
288 l4_irq_chain(l4_cap_idx_t irq, l4_umword_t label,
289 l4_cap_idx_t slave) L4_NOTHROW
291 return l4_irq_chain_u(irq, label, slave, l4_utcb());
294 L4_INLINE l4_msgtag_t
295 l4_irq_detach(l4_cap_idx_t irq) L4_NOTHROW
297 return l4_irq_detach_u(irq, l4_utcb());
300 L4_INLINE l4_msgtag_t
301 l4_irq_trigger(l4_cap_idx_t irq) L4_NOTHROW
303 return l4_irq_trigger_u(irq, l4_utcb());
306 L4_INLINE l4_msgtag_t
307 l4_irq_receive(l4_cap_idx_t irq, l4_timeout_t to) L4_NOTHROW
309 return l4_irq_receive_u(irq, to, l4_utcb());
312 L4_INLINE l4_msgtag_t
313 l4_irq_wait(l4_cap_idx_t irq, l4_umword_t *label,
314 l4_timeout_t to) L4_NOTHROW
316 return l4_irq_wait_u(irq, label, to, l4_utcb());
319 L4_INLINE l4_msgtag_t
320 l4_irq_unmask(l4_cap_idx_t irq) L4_NOTHROW
322 return l4_irq_unmask_u(irq, l4_utcb());