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