xref: /netbsd-src/sys/arch/arm/arm32/intr.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: intr.c,v 1.25 2007/12/03 15:33:16 ad 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.25 2007/12/03 15:33:16 ad Exp $");
40 
41 #include "opt_irqstats.h"
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/syslog.h>
46 #include <sys/malloc.h>
47 #include <sys/conf.h>
48 
49 #include <uvm/uvm_extern.h>
50 
51 #include <machine/atomic.h>
52 #include <machine/intr.h>
53 #include <machine/cpu.h>
54 
55 #include <net/netisr.h>
56 
57 #include <arm/arm32/machdep.h>
58 
59 extern int current_spl_level;
60 
61 /* Generate soft interrupt counts if IRQSTATS is defined */
62 /* Prototypes */
63 static void clearsoftintr(u_int);
64 
65 static u_int soft_interrupts = 0;
66 static u_int spl_smasks[_SPL_LEVELS];
67 
68 /* Eventually these will become macros */
69 
70 #define	SI_SOFTMASK(si)	(1U << (si))
71 
72 static inline void
73 clearsoftintr(u_int intrmask)
74 {
75 	atomic_clear_bit(&soft_interrupts, intrmask);
76 }
77 
78 void
79 _setsoftintr(int si)
80 {
81 	atomic_set_bit(&soft_interrupts, SI_SOFTMASK(si));
82 }
83 
84 #ifdef __HAVE_FAST_SOFTINTS
85 /* Handle software interrupts */
86 
87 void
88 dosoftints(void)
89 {
90 	u_int softints;
91 	int s;
92 
93 	softints = soft_interrupts & spl_smasks[current_spl_level];
94 	if (softints == 0) return;
95 
96 	/*
97 	 * Serial software interrupts
98 	 */
99 	if (softints & SI_SOFTMASK(SI_SOFTSERIAL)) {
100 		s = splsoftserial();
101 		clearsoftintr(SI_SOFTMASK(SI_SOFTSERIAL));
102 		softintr_dispatch(SI_SOFTSERIAL);
103 		(void)splx(s);
104 	}
105 
106 	/*
107 	 * Network software interrupts
108 	 */
109 	if (softints & SI_SOFTMASK(SI_SOFTNET)) {
110 		s = splsoftnet();
111 		clearsoftintr(SI_SOFTMASK(SI_SOFTNET));
112 		softintr_dispatch(SI_SOFTNET);
113 		(void)splx(s);
114 	}
115 
116 	/*
117 	 * Block software interrupts
118 	 */
119 	if (softints & SI_SOFTMASK(SI_SOFTBIO)) {
120 		s = splsoftbio();
121 		clearsoftintr(SI_SOFTMASK(SI_SOFTBIO));
122 		softintr_dispatch(SI_SOFTBIO);
123 		(void)splx(s);
124 	}
125 
126 	/*
127 	 * Software clock interrupts
128 	 */
129 	if (softints & SI_SOFTMASK(SI_SOFTCLOCK)) {
130 		s = splsoftclock();
131 		clearsoftintr(SI_SOFTMASK(SI_SOFTCLOCK));
132 		softintr_dispatch(SI_SOFTCLOCK);
133 		(void)splx(s);
134 	}
135 }
136 #endif
137 
138 int current_spl_level = _SPL_HIGH;
139 u_int spl_masks[_SPL_LEVELS + 1];
140 int safepri = _SPL_0;
141 
142 extern u_int irqmasks[];
143 
144 void
145 set_spl_masks(void)
146 {
147 	int loop;
148 
149 	for (loop = 0; loop < _SPL_LEVELS; ++loop) {
150 		spl_masks[loop] = 0xffffffff;
151 		spl_smasks[loop] = 0;
152 	}
153 
154 	spl_masks[_SPL_VM]         = irqmasks[IPL_VM];
155 	spl_masks[_SPL_SCHED]      = irqmasks[IPL_SCHED];
156 	spl_masks[_SPL_HIGH]       = irqmasks[IPL_HIGH];
157 	spl_masks[_SPL_LEVELS]     = 0;
158 
159 	spl_smasks[_SPL_0] = 0xffffffff;
160 	for (loop = 0; loop < _SPL_SOFTSERIAL; ++loop)
161 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTSERIAL);
162 	for (loop = 0; loop < _SPL_SOFTNET; ++loop)
163 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTNET);
164 	for (loop = 0; loop < _SPL_SOFTCLOCK; ++loop)
165 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTCLOCK);
166 	for (loop = 0; loop < _SPL_SOFTBIO; ++loop)
167 		spl_smasks[loop] |= SI_SOFTMASK(SI_SOFTBIO);
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