1 /*-
2 * Copyright (c) 1991 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * William Jolitz.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32 /*-
33 * Copyright (c) 2002 Benno Rice.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 *
57 * from: @(#)isa.c 7.2 (Berkeley) 5/13/91
58 * form: src/sys/i386/isa/intr_machdep.c,v 1.57 2001/07/20
59 *
60 * $FreeBSD: releng/7.4/sys/powerpc/powerpc/intr_machdep.c 192409 2009-05-19 22:07:54Z jhb $
61 */
62
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/kernel.h>
66 #include <sys/queue.h>
67 #include <sys/bus.h>
68 #include <sys/interrupt.h>
69 #include <sys/ktr.h>
70 #include <sys/lock.h>
71 #include <sys/malloc.h>
72 #include <sys/mutex.h>
73 #include <sys/pcpu.h>
74 #include <sys/syslog.h>
75 #include <sys/vmmeter.h>
76 #include <sys/proc.h>
77
78 #include <machine/frame.h>
79 #include <machine/intr_machdep.h>
80 #include <machine/md_var.h>
81 #include <machine/trap.h>
82
83 #include "pic_if.h"
84
85 #define MAX_STRAY_LOG 5
86
87 MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data");
88
89 struct powerpc_intr {
90 struct intr_event *event;
91 long *cntp;
92 u_int irq;
93 };
94
95 static struct powerpc_intr *powerpc_intrs[INTR_VECTORS];
96 static u_int nvectors; /* Allocated vectors */
97 static u_int stray_count;
98
99 device_t pic;
100
101 static void
102 intrcnt_setname(const char *name, int index)
103 {
104 snprintf(intrnames + (MAXCOMLEN + 1) * index, MAXCOMLEN + 1, "%-*s",
105 MAXCOMLEN, name);
106 }
107
108 static void
109 powerpc_intr_eoi(void *arg)
110 {
111 u_int irq = (uintptr_t)arg;
112
113 PIC_EOI(pic, irq);
114 }
115
116 static void
117 powerpc_intr_mask(void *arg)
118 {
119 u_int irq = (uintptr_t)arg;
120
121 PIC_MASK(pic, irq);
122 }
123
124 static void
125 powerpc_intr_unmask(void *arg)
126 {
127 u_int irq = (uintptr_t)arg;
128
129 PIC_UNMASK(pic, irq);
130 }
131
132 void
133 powerpc_register_pic(device_t dev)
134 {
135
136 pic = dev;
137 }
138
139 int
140 powerpc_enable_intr(void)
141 {
142 struct powerpc_intr *i;
143 int vector;
144
145 for (vector = 0; vector < nvectors; vector++) {
146 i = powerpc_intrs[vector];
147 if (i == NULL)
148 continue;
149
150 PIC_ENABLE(pic, i->irq, vector);
151 }
152
153 return (0);
154 }
155
156 int
157 powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter,
158 driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep)
159 {
160 struct powerpc_intr *i;
161 u_int vector;
162 int error;
163
164 /* XXX lock */
165
166 i = NULL;
167 for (vector = 0; vector < nvectors; vector++) {
168 i = powerpc_intrs[vector];
169 if (i == NULL)
170 continue;
171 if (i->irq == irq)
172 break;
173 i = NULL;
174 }
175
176 if (i == NULL) {
177 if (nvectors >= INTR_VECTORS) {
178 /* XXX unlock */
179 return (ENOENT);
180 }
181
182 i = malloc(sizeof(*i), M_INTR, M_NOWAIT);
183 if (i == NULL) {
184 /* XXX unlock */
185 return (ENOMEM);
186 }
187 error = intr_event_create(&i->event, (void *)irq, 0, irq,
188 powerpc_intr_mask, powerpc_intr_unmask, powerpc_intr_eoi,
189 NULL, "irq%u:", irq);
190 if (error) {
191 /* XXX unlock */
192 free(i, M_INTR);
193 return (error);
194 }
195
196 vector = nvectors++;
197 powerpc_intrs[vector] = i;
198
199 i->irq = irq;
200
201 /* XXX unlock */
202
203 i->cntp = &intrcnt[vector];
204 intrcnt_setname(i->event->ie_fullname, vector);
205
206 if (!cold)
207 PIC_ENABLE(pic, i->irq, vector);
208 } else {
209 /* XXX unlock */
210 }
211
212 error = intr_event_add_handler(i->event, name, filter, handler, arg,
213 intr_priority(flags), flags, cookiep);
214 if (!error)
215 intrcnt_setname(i->event->ie_fullname, vector);
216 return (error);
217 }
218
219 int
220 powerpc_teardown_intr(void *cookie)
221 {
222
223 return (intr_event_remove_handler(cookie));
224 }
225
226 void
227 powerpc_dispatch_intr(u_int vector, struct trapframe *tf)
228 {
229 struct powerpc_intr *i;
230 struct intr_event *ie;
231
232 i = powerpc_intrs[vector];
233 if (i == NULL)
234 goto stray;
235
236 (*i->cntp)++;
237
238 ie = i->event;
239 KASSERT(ie != NULL, ("%s: interrupt without an event", __func__));
240
241 if (intr_event_handle(ie, tf) != 0) {
242 goto stray;
243 }
244 return;
245
246 stray:
247 stray_count++;
248 if (stray_count <= MAX_STRAY_LOG) {
249 printf("stray irq %d\n", i ? i->irq : -1);
250 if (stray_count >= MAX_STRAY_LOG) {
251 printf("got %d stray interrupts, not logging anymore\n",
252 MAX_STRAY_LOG);
253 }
254 }
255 if (i != NULL)
256 PIC_MASK(pic, i->irq);
257 }
Cache object: dcfef14693b39e839bc29102e6423e08
|