1 /*****************************************************************************/
3 * \file input/lib/src/emul_irq.c
4 * \brief L4INPUT: Linux IRQ handling emulation
7 * \author Christian Helmuth <ch12@os.inf.tu-dresden.de>
8 * \author Frank Mehnert <fm3@os.inf.tu-dresden.de>
12 * (c) 2003-2009 Author(s)
13 * economic rights: Technische Universität Dresden (Germany)
15 * This file is part of TUD:OS and distributed under the terms of the
16 * GNU General Public License 2.
17 * Please see the COPYING-GPL-2 file for details.
22 #include <l4/sys/ipc.h>
23 #include <l4/sys/types.h>
24 //#include <l4/util/irq.h>
25 #include <l4/irq/irq.h>
26 #if !defined(ARCH_arm) && !defined(ARCH_ppc32) && !defined(ARCH_sparc)
27 #include <l4/util/port_io.h>
29 #include <l4/util/macros.h>
34 #include <linux/interrupt.h>
39 #define DEBUG_IRQ_VERBOSE 0
41 /* return within 50ms even if there was no interrupt */
42 #define IRQ_TIMEOUT l4_ipc_timeout(0,0,781,6)
44 /* INTERRUPT HANDLING EMULATION */
46 static struct irq_desc {
51 pthread_mutex_t startup;
52 irqreturn_t (*handler)(int, void *, struct pt_regs *);
55 static int irq_prio = -1;
59 #define OM_MASK 0x00000001
60 #define OM_UNMASK 0x00000002
61 #define OM_CONSUME 0x00000004
62 #define OM_AGAIN 0x00000008
66 * \param irq IRQ number
67 * \retval handle IRQ handle
69 * \return 0 on success (attached interrupt), -1 if attach failed.
71 static inline int __omega0_attach(unsigned int irq, l4irq_t **handle)
73 return (*handle = l4irq_attach(irq)) ? 0 : -1;
76 /** Wait for IRQ notification.
78 * \param irq IRQ number
79 * \param handle IRQ line handle
81 * - \c OM_MASK request IRQ mask
82 * - \c OM_UNMASK request IRQ unmask
83 * - \c OM_CONSUME IRQ consumed
84 * \return 0 for success
85 * L4_IPC_RETIMEOUT if no IRQ was received (timeout)
87 static inline int __omega0_wait(unsigned int irq, l4irq_t *handle,
90 return l4irq_wait(handle);
93 /** IRQ HANDLER THREAD.
95 * \param irq_desc IRQ handling descriptor (IRQ number and handler routine)
97 static void *__irq_handler(void *_data)
99 struct irq_desc *irq_desc = (struct irq_desc *)_data;
100 unsigned int irq = irq_desc->num; /* save irq number */
101 void *cookie = irq_desc->cookie; /* save cookie/dev_id pointer */
104 unsigned int om_flags;
106 /* get permission for attaching to IRQ */
107 ret = __omega0_attach(irq, &irq_handle);
110 fprintf(stderr, "failed to attach IRQ %d!\n", irq);
115 ret = pthread_mutex_unlock(&handlers[irq].startup);
118 printf("emul_irq.c: __irq_handler %p for IRQ %d running\n",
119 irq_desc->handler, irq);
124 fprintf(stderr, "IRQ thread startup failed!\n");
128 om_flags = OM_UNMASK;
130 ret = __omega0_wait(irq, irq_handle, om_flags);
134 #if DEBUG_IRQ_VERBOSE
135 printf("emul_irq.c: got IRQ %d\n", irq);
137 if (irq_desc->active)
138 irq_desc->handler(irq, cookie, NULL);
143 case L4_IPC_RETIMEOUT:
144 if (irq_desc->active)
145 irq_desc->handler(irq, cookie, NULL);
151 fprintf(stderr, "error receiving irq\n");
157 /** Request Interrupt.
160 * \param irq interrupt number
161 * \param handler interrupt handler -> top half
163 * \param cookie cookie pointer passed back
165 * \return 0 on success; error code otherwise
167 int request_irq(unsigned int irq,
168 irqreturn_t (*handler)(int, void *, struct pt_regs *),
169 unsigned long flags, const char *devname, void *cookie)
179 handlers[irq].num = irq;
180 handlers[irq].cookie = cookie;
181 handlers[irq].handler = handler;
183 handlers[irq].active = 1;
185 if(handlers[irq].t) {
187 printf("emul_irq.c: reattached to irq %d\n", irq);
192 sprintf(buf, ".irq%.2X", irq);
193 /* create IRQ handler thread */
194 pthread_mutex_init(&handlers[irq].startup, NULL);
195 pthread_mutex_lock(&handlers[irq].startup);
198 pthread_attr_init(&a);
199 if (irq_prio != -1) {
200 struct sched_param sp;
201 sp.sched_priority = irq_prio;
202 pthread_attr_setschedpolicy(&a, SCHED_L4);
203 pthread_attr_setschedparam(&a, &sp);
204 pthread_attr_setinheritsched(&a, PTHREAD_EXPLICIT_SCHED);
206 if (pthread_create(&irq_tid, &a, __irq_handler, (void *)
209 printf("emul_irq.c: Creating irq-thread failed\n");
210 pthread_mutex_unlock(&handlers[irq].startup);
214 pthread_mutex_lock(&handlers[irq].startup);
215 pthread_mutex_unlock(&handlers[irq].startup);
218 printf("emul_irq.c: attached to irq %d\n", irq);
221 handlers[irq].t = irq_tid;
226 /** Release Interrupt.
228 * \param irq interrupt number
229 * \param cookie cookie pointer passed back
231 * \todo Implementation.
233 void free_irq(unsigned int irq, void *cookie)
235 handlers[irq].active = 0;
238 printf("emul_irq.c: attempt to free irq %d\n", irq);
242 /* INTERRUPT EMULATION INITIALIZATION */
243 void l4input_internal_irq_init(int prio)
247 memset(&handlers, 0, sizeof(handlers));