xref: /netbsd-src/sys/arch/arm/arm32/intr.c (revision 8ac07aec990b9d2e483062509d0a9fa5b4f57cf2)
1 /*	$NetBSD: intr.c,v 1.27 2008/02/24 20:51:52 matt Exp $	*/
2 
3 /*
4  * Copyright (c) 1994-1998 Mark Brinicombe.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Mark Brinicombe
18  *	for the NetBSD Project.
19  * 4. The name of the company nor the name of the author may be used to
20  *    endorse or promote products derived from this software without specific
21  *    prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  * Soft interrupt and other generic interrupt functions.
36  */
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.27 2008/02/24 20:51:52 matt Exp $");
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/syslog.h>
44 #include <sys/malloc.h>
45 #include <sys/conf.h>
46 
47 #include <uvm/uvm_extern.h>
48 
49 #include <machine/atomic.h>
50 #include <machine/intr.h>
51 #include <machine/cpu.h>
52 
53 #include <net/netisr.h>
54 
55 #include <arm/arm32/machdep.h>
56 
57 extern int current_spl_level;
58 
59 static u_int spl_smasks[_SPL_LEVELS];
60 
61 /* Eventually these will become macros */
62 
63 #ifdef __HAVE_FAST_SOFTINTS
64 /* Generate soft interrupt counts if IRQSTATS is defined */
65 /* Prototypes */
66 static void clearsoftintr(u_int);
67 
68 static u_int soft_interrupts = 0;
69 #define	SI_SOFTMASK(si)	(1U << (si))
70 
71 static inline void
72 clearsoftintr(u_int intrmask)
73 {
74 	atomic_clear_bit(&soft_interrupts, intrmask);
75 }
76 
77 void
78 _setsoftintr(int si)
79 {
80 	atomic_set_bit(&soft_interrupts, SI_SOFTMASK(si));
81 }
82 
83 /* Handle software interrupts */
84 
85 void
86 dosoftints(void)
87 {
88 	u_int softints;
89 	int s;
90 
91 	softints = soft_interrupts & spl_smasks[current_spl_level];
92 	if (softints == 0) return;
93 
94 	/*
95 	 * Serial software interrupts
96 	 */
97 	if (softints & SI_SOFTMASK(SI_SOFTSERIAL)) {
98 		s = splsoftserial();
99 		clearsoftintr(SI_SOFTMASK(SI_SOFTSERIAL));
100 		softintr_dispatch(SI_SOFTSERIAL);
101 		(void)splx(s);
102 	}
103 
104 	/*
105 	 * Network software interrupts
106 	 */
107 	if (softints & SI_SOFTMASK(SI_SOFTNET)) {
108 		s = splsoftnet();
109 		clearsoftintr(SI_SOFTMASK(SI_SOFTNET));
110 		softintr_dispatch(SI_SOFTNET);
111 		(void)splx(s);
112 	}
113 
114 	/*
115 	 * Block software interrupts
116 	 */
117 	if (softints & SI_SOFTMASK(SI_SOFTBIO)) {
118 		s = splsoftbio();
119 		clearsoftintr(SI_SOFTMASK(SI_SOFTBIO));
120 		softintr_dispatch(SI_SOFTBIO);
121 		(void)splx(s);
122 	}
123 
124 	/*
125 	 * Software clock interrupts
126 	 */
127 	if (softints & SI_SOFTMASK(SI_SOFTCLOCK)) {
128 		s = splsoftclock();
129 		clearsoftintr(SI_SOFTMASK(SI_SOFTCLOCK));
130 		softintr_dispatch(SI_SOFTCLOCK);
131 		(void)splx(s);
132 	}
133 }
134 #endif
135 
136 int current_spl_level = _SPL_HIGH;
137 u_int spl_masks[_SPL_LEVELS + 1];
138 int safepri = _SPL_0;
139 
140 extern u_int irqmasks[];
141 
142 void
143 set_spl_masks(void)
144 {
145 	int loop;
146 
147 	for (loop = 0; loop < _SPL_LEVELS; ++loop) {
148 		spl_masks[loop] = 0xffffffff;
149 		spl_smasks[loop] = 0;
150 	}
151 
152 	spl_masks[_SPL_VM]         = irqmasks[IPL_VM];
153 	spl_masks[_SPL_SCHED]      = irqmasks[IPL_SCHED];
154 	spl_masks[_SPL_HIGH]       = irqmasks[IPL_HIGH];
155 	spl_masks[_SPL_LEVELS]     = 0;
156 
157 	spl_smasks[_SPL_0] = 0xffffffff;
158 #ifdef __HAVE_FAST_SOFTINTS
159 	for (loop = 0; loop < _SPL_SOFTSERIAL; ++loop)
160 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTSERIAL);
161 	for (loop = 0; loop < _SPL_SOFTNET; ++loop)
162 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTNET);
163 	for (loop = 0; loop < _SPL_SOFTCLOCK; ++loop)
164 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTCLOCK);
165 	for (loop = 0; loop < _SPL_SOFTBIO; ++loop)
166 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTBIO);
167 #endif
168 }
169 
170 static const int ipl_to_spl_map[] = {
171 	[IPL_NONE] = 1 + _SPL_0,
172 	[IPL_SOFTCLOCK] = 1 + _SPL_SOFTCLOCK,
173 	[IPL_SOFTBIO] = 1 + _SPL_SOFTBIO,
174 	[IPL_SOFTNET] = 1 + _SPL_SOFTNET,
175 	[IPL_SOFTSERIAL] = 1 + _SPL_SOFTSERIAL,
176 	[IPL_VM] = 1 + _SPL_VM,
177 	[IPL_SCHED] = 1 + _SPL_SCHED,
178 	[IPL_HIGH] = 1 + _SPL_HIGH,
179 };
180 
181 int
182 ipl_to_spl(ipl_t ipl)
183 {
184 	int spl;
185 
186 	KASSERT(ipl < __arraycount(ipl_to_spl_map));
187 	KASSERT(ipl_to_spl_map[ipl]);
188 
189 	spl = ipl_to_spl_map[ipl] - 1;
190 	KASSERT(spl < 0x100);
191 
192 	return spl;
193 }
194 
195 #ifdef DIAGNOSTIC
196 void
197 dump_spl_masks(void)
198 {
199 	int loop;
200 
201 	for (loop = 0; loop < _SPL_LEVELS; ++loop) {
202 		printf("spl_masks[%d]=%08x splsmask[%d]=%08x\n", loop,
203 		    spl_masks[loop], loop, spl_smasks[loop]);
204 	}
205 }
206 #endif
207 
208 /* End of intr.c */
209