interrupt.c revision 1.1 1 /* $NetBSD: interrupt.c,v 1.1 2006/06/25 16:11:41 tsutsui Exp $ */
2 /* $OpenBSD: trap.c,v 1.22 1999/05/24 23:08:59 jason Exp $ */
3
4 /*
5 * Copyright (c) 1992, 1993
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * the Systems Programming Group of the University of Utah Computer
10 * Science Department and Ralph Campbell.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR 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 * from: Utah Hdr: trap.c 1.32 91/04/06
37 *
38 * @(#)trap.c 8.5 (Berkeley) 1/11/94
39 */
40 /*
41 * Copyright (c) 1988 University of Utah.
42 *
43 * This code is derived from software contributed to Berkeley by
44 * the Systems Programming Group of the University of Utah Computer
45 * Science Department and Ralph Campbell.
46 *
47 * Redistribution and use in source and binary forms, with or without
48 * modification, are permitted provided that the following conditions
49 * are met:
50 * 1. Redistributions of source code must retain the above copyright
51 * notice, this list of conditions and the following disclaimer.
52 * 2. Redistributions in binary form must reproduce the above copyright
53 * notice, this list of conditions and the following disclaimer in the
54 * documentation and/or other materials provided with the distribution.
55 * 3. All advertising materials mentioning features or use of this software
56 * must display the following acknowledgement:
57 * This product includes software developed by the University of
58 * California, Berkeley and its contributors.
59 * 4. Neither the name of the University nor the names of its contributors
60 * may be used to endorse or promote products derived from this software
61 * without specific prior written permission.
62 *
63 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
64 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
65 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
66 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
67 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
68 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
69 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
70 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
71 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
72 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
73 * SUCH DAMAGE.
74 *
75 * from: Utah Hdr: trap.c 1.32 91/04/06
76 *
77 * @(#)trap.c 8.5 (Berkeley) 1/11/94
78 */
79
80 #include <sys/cdefs.h>
81 __KERNEL_RCSID(0, "$NetBSD: interrupt.c,v 1.1 2006/06/25 16:11:41 tsutsui Exp $");
82
83 #include <sys/param.h>
84 #include <sys/systm.h>
85 #include <sys/kernel.h>
86
87 #include <uvm/uvm_extern.h>
88
89 #include <mips/locore.h>
90
91 #include <machine/autoconf.h>
92 #include <machine/intr.h>
93 #include <machine/pio.h>
94
95 #include <arc/arc/timervar.h>
96 #include <arc/jazz/pica.h>
97 #include <arc/jazz/rd94.h>
98
99 struct cpu_inttab {
100 uint32_t int_mask;
101 uint32_t (*int_hand)(uint32_t, struct clockframe *);
102 };
103 static struct cpu_inttab cpu_int_tab[ARC_NINTPRI];
104
105 uint32_t cpu_int_mask; /* External cpu interrupt mask */
106
107 #ifdef ENABLE_INT5_STATCLOCK
108 struct evcnt statclock_ev =
109 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "cpu", "statclock");
110 #endif
111
112 /*
113 * Set up handler for external interrupt events.
114 * Events are checked in priority order.
115 */
116 void
117 arc_set_intr(uint32_t mask, uint32_t (*int_hand)(uint32_t, struct clockframe *),
118 int prio)
119 {
120
121 if (prio >= ARC_NINTPRI)
122 panic("arc_set_intr: too high priority");
123
124 if (cpu_int_tab[prio].int_mask != 0 &&
125 (cpu_int_tab[prio].int_mask != mask ||
126 cpu_int_tab[prio].int_hand != int_hand)) {
127 panic("set_intr: int already set");
128 }
129
130 cpu_int_tab[prio].int_hand = int_hand;
131 cpu_int_tab[prio].int_mask = mask;
132 cpu_int_mask |= mask >> 10;
133 }
134
135 /*
136 * Handle an interrupt.
137 * N.B., curlwp might be NULL.
138 */
139 void
140 cpu_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
141 {
142 struct clockframe cf;
143 struct cpu_inttab *inttab;
144 u_int i;
145
146 uvmexp.intrs++;
147
148 cf.pc = pc;
149 cf.sr = status;
150
151 /* check MIPS3 internal clock interrupt */
152 if (ipending & MIPS_INT_MASK_5) {
153 #ifdef ENABLE_INT5_STATCLOCK
154 /* call statclock(9) handler */
155 statclockintr(&cf);
156 statclock_ev.ev_count++;
157 #else
158 /*
159 * Writing a value to the Compare register,
160 * as a side effect, clears the timer interrupt request.
161 */
162 mips3_cp0_compare_write(0);
163 #endif
164 cause &= ~MIPS_INT_MASK_5;
165 }
166 _splset((status & MIPS_INT_MASK_5) | MIPS_SR_INT_IE);
167
168 /*
169 * If there is an independent timer interrupt handler, call it first.
170 * Called interrupt routine returns mask of interrupts to be reenabled.
171 */
172 inttab = &cpu_int_tab[ARC_INTPRI_TIMER_INT];
173 if (inttab->int_mask & ipending) {
174 if ((ipending & MIPS_INT_MASK & ~inttab->int_mask) == 0) {
175 /*
176 * If all interrupts were enabled and there is no
177 * pending interrupts, set MIPS_SR_INT_IE so that
178 * spllowerclock() in hardclock() works properly.
179 */
180 #if 0 /* MIPS_SR_INT_IE is enabled above */
181 _splset(MIPS_SR_INT_IE);
182 #endif
183 } else {
184 /*
185 * If there are any pending interrputs, clear
186 * MIPS_SR_INT_IE in cf.sr so that spllowerclock()
187 * in hardclock() will not happen.
188 */
189 cf.sr &= ~MIPS_SR_INT_IE;
190 }
191 cause &= (*inttab->int_hand)(ipending, &cf);
192 }
193 _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
194
195 inttab++;
196
197 /*
198 * Check off all other enabled interrupts.
199 * Called handlers return mask of interrupts to be reenabled.
200 */
201 for (i = ARC_INTPRI_TIMER_INT + 1; i < ARC_NINTPRI; i++) {
202 if (inttab->int_mask & ipending) {
203 cause &= (*inttab->int_hand)(ipending, &cf);
204 }
205 inttab++;
206 }
207 _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
208
209 /* software interrupts */
210 ipending &= (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0);
211 if (ipending == 0)
212 return;
213
214 _clrsoftintr(ipending);
215
216 softintr_dispatch(ipending);
217 }
218