intr.c revision 129198
1/*	$NetBSD: intr.c,v 1.12 2003/07/15 00:24:41 lukem Exp $	*/
2
3/*
4 * Copyright (c) 2004 Olivier Houchard.
5 * Copyright (c) 1994-1998 Mark Brinicombe.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by Mark Brinicombe
19 *	for the NetBSD Project.
20 * 4. The name of the company nor the name of the author may be used to
21 *    endorse or promote products derived from this software without specific
22 *    prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * Soft interrupt and other generic interrupt functions.
37 */
38
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: head/sys/arm/arm/intr.c 129198 2004-05-14 11:46:45Z cognet $");
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/syslog.h>
44#include <sys/malloc.h>
45#include <sys/bus.h>
46#include <sys/interrupt.h>
47#include <sys/conf.h>
48#include <machine/atomic.h>
49#include <machine/intr.h>
50#include <machine/cpu.h>
51
52int current_spl_level = _SPL_SERIAL;
53
54u_int spl_masks[_SPL_LEVELS + 1];
55u_int spl_smasks[_SPL_LEVELS];
56extern u_int irqmasks[];
57
58#define NIRQ 0x20 /* XXX */
59struct ithd *ithreads[NIRQ];
60void
61set_splmasks()
62{
63		int loop;
64
65	for (loop = 0; loop < _SPL_LEVELS; ++loop) {
66		spl_masks[loop] = 0xffffffff;
67		spl_smasks[loop] = 1;
68	}
69
70	spl_masks[_SPL_NET]        = irqmasks[IPL_NET];
71	spl_masks[_SPL_SOFTSERIAL] = irqmasks[IPL_TTY];
72	spl_masks[_SPL_TTY]        = irqmasks[IPL_TTY];
73	spl_masks[_SPL_VM]         = irqmasks[IPL_VM];
74	spl_masks[_SPL_AUDIO]      = irqmasks[IPL_AUDIO];
75	spl_masks[_SPL_CLOCK]      = irqmasks[IPL_CLOCK];
76#ifdef IPL_STATCLOCK
77	spl_masks[_SPL_STATCLOCK]  = irqmasks[IPL_STATCLOCK];
78#else
79	spl_masks[_SPL_STATCLOCK]  = irqmasks[IPL_CLOCK];
80#endif
81	spl_masks[_SPL_HIGH]       = irqmasks[IPL_HIGH];
82	spl_masks[_SPL_SERIAL]     = irqmasks[IPL_SERIAL];
83	spl_masks[_SPL_LEVELS]     = 0;
84
85	spl_smasks[_SPL_0] = 0xffffffff;
86	for (loop = 0; loop < _SPL_SOFTSERIAL; ++loop)
87		spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_SERIAL);
88	for (loop = 0; loop < _SPL_SOFTNET; ++loop)
89		spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_NET);
90	for (loop = 0; loop < _SPL_SOFTCLOCK; ++loop)
91		spl_smasks[loop] |= SOFTIRQ_BIT(SOFTIRQ_CLOCK);
92}
93
94void arm_setup_irqhandler(const char *name, void (*hand)(void*), void *arg,
95    int irq, int flags, void **cookiep)
96{
97	struct ithd *cur_ith;
98	int error;
99
100	if (irq < 0 || irq >= NIRQ)
101		return;
102	cur_ith = ithreads[irq];
103	if (cur_ith == NULL) {
104		error = ithread_create(&cur_ith, irq, 0, NULL, NULL, "intr%d:",
105		    irq);
106		if (error)
107			return;
108		ithreads[irq] = cur_ith;
109	}
110	ithread_add_handler(cur_ith, name, hand, arg, ithread_priority(flags),
111	    flags, cookiep);
112}
113
114void dosoftints(void);
115void
116dosoftints(void)
117{
118}
119
120void
121arm_handler_execute(void *);
122void
123arm_handler_execute(void *irq)
124{
125	struct ithd *ithd;
126	int i;
127	int irqnb = (int)irq;
128	struct intrhand *ih;
129
130	for (i = 0; i < NIRQ; i++) {
131		if (1 << i & irqnb) {
132			ithd = ithreads[i];
133			if (!ithd) /* FUCK */
134				return;
135			ih = TAILQ_FIRST(&ithd->it_handlers);
136			if (ih && ih->ih_flags & IH_FAST) {
137				TAILQ_FOREACH(ih, &ithd->it_handlers,
138				    ih_next) {
139					ih->ih_handler(ih->ih_argument);
140					/*
141					 * XXX: what about the irq frame if
142					 * the arg is NULL ?
143					 */
144				}
145			} else if (ih) {
146				ithread_schedule(ithd, !cold);
147			}
148		}
149	}
150}
151