interrupt.c revision 1.3 1 /* $NetBSD: interrupt.c,v 1.3 2007/12/03 15:33:13 ad 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.3 2007/12/03 15:33:13 ad Exp $");
82
83 #include <sys/param.h>
84 #include <sys/systm.h>
85 #include <sys/kernel.h>
86 #include <sys/intr.h>
87 #include <sys/cpu.h>
88
89 #include <uvm/uvm_extern.h>
90
91 #include <mips/locore.h>
92
93 #include <machine/autoconf.h>
94 #include <machine/pio.h>
95
96 #include <arc/arc/timervar.h>
97 #include <arc/jazz/pica.h>
98 #include <arc/jazz/rd94.h>
99
100 struct cpu_inttab {
101 uint32_t int_mask;
102 uint32_t (*int_hand)(uint32_t, struct clockframe *);
103 };
104 static struct cpu_inttab cpu_int_tab[ARC_NINTPRI];
105
106 uint32_t cpu_int_mask; /* External cpu interrupt mask */
107
108 #ifdef ENABLE_INT5_STATCLOCK
109 struct evcnt statclock_ev =
110 EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "cpu", "statclock");
111 #endif
112
113 /*
114 * Set up handler for external interrupt events.
115 * Events are checked in priority order.
116 */
117 void
118 arc_set_intr(uint32_t mask, uint32_t (*int_hand)(uint32_t, struct clockframe *),
119 int prio)
120 {
121
122 if (prio >= ARC_NINTPRI)
123 panic("arc_set_intr: too high priority");
124
125 if (cpu_int_tab[prio].int_mask != 0 &&
126 (cpu_int_tab[prio].int_mask != mask ||
127 cpu_int_tab[prio].int_hand != int_hand)) {
128 panic("set_intr: int already set");
129 }
130
131 cpu_int_tab[prio].int_hand = int_hand;
132 cpu_int_tab[prio].int_mask = mask;
133 cpu_int_mask |= mask >> 10;
134 }
135
136 /*
137 * Handle an interrupt.
138 * N.B., curlwp might be NULL.
139 */
140 void
141 cpu_intr(uint32_t status, uint32_t cause, uint32_t pc, uint32_t ipending)
142 {
143 struct clockframe cf;
144 struct cpu_inttab *inttab;
145 struct cpu_info *ci;
146 u_int i;
147
148 ci = curcpu();
149 uvmexp.intrs++;
150 ci->ci_idepth++;
151
152 cf.pc = pc;
153 cf.sr = status;
154
155 /* check MIPS3 internal clock interrupt */
156 if (ipending & MIPS_INT_MASK_5) {
157 #ifdef ENABLE_INT5_STATCLOCK
158 /* call statclock(9) handler */
159 statclockintr(&cf);
160 statclock_ev.ev_count++;
161 #else
162 /*
163 * Writing a value to the Compare register,
164 * as a side effect, clears the timer interrupt request.
165 */
166 mips3_cp0_compare_write(0);
167 #endif
168 cause &= ~MIPS_INT_MASK_5;
169 }
170 _splset((status & MIPS_INT_MASK_5) | MIPS_SR_INT_IE);
171
172 /*
173 * If there is an independent timer interrupt handler, call it first.
174 * Called interrupt routine returns mask of interrupts to be reenabled.
175 */
176 inttab = &cpu_int_tab[ARC_INTPRI_TIMER_INT];
177 if (inttab->int_mask & ipending) {
178 cause &= (*inttab->int_hand)(ipending, &cf);
179 }
180 _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
181
182 inttab++;
183
184 /*
185 * Check off all other enabled interrupts.
186 * Called handlers return mask of interrupts to be reenabled.
187 */
188 for (i = ARC_INTPRI_TIMER_INT + 1; i < ARC_NINTPRI; i++) {
189 if (inttab->int_mask & ipending) {
190 cause &= (*inttab->int_hand)(ipending, &cf);
191 }
192 inttab++;
193 }
194 _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
195 ci->ci_idepth--;
196
197 #ifdef __HAVE_FAST_SOFTINTS
198 /* software interrupts */
199 ipending &= (MIPS_SOFT_INT_MASK_1|MIPS_SOFT_INT_MASK_0);
200 if (ipending == 0)
201 return;
202 _clrsoftintr(ipending);
203 softintr_dispatch(ipending);
204 #endif
205 }
206