rmixl_intr.c revision 1.1.2.39 1 /* rmixl_intr.c,v 1.1.2.35 2012/01/19 08:05:24 matt Exp */
2
3 /*-
4 * Copyright (c) 2007 Ruslan Ermilov and Vsevolod Lobko.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or
8 * without modification, are permitted provided that the following
9 * conditions 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
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 * 3. The names of the authors may not be used to endorse or promote
17 * products derived from this software without specific prior
18 * written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
27 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
29 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31 * OF SUCH DAMAGE.
32 */
33 /*-
34 * Copyright (c) 2001 The NetBSD Foundation, Inc.
35 * All rights reserved.
36 *
37 * This code is derived from software contributed to The NetBSD Foundation
38 * by Jason R. Thorpe.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
50 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
51 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
52 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
53 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
54 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
55 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
56 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
57 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
58 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
59 * POSSIBILITY OF SUCH DAMAGE.
60 */
61
62 /*
63 * Platform-specific interrupt support for the RMI XLP, XLR, XLS
64 */
65
66 #include <sys/cdefs.h>
67 __KERNEL_RCSID(0, "rmixl_intr.c,v 1.1.2.35 2012/01/19 08:05:24 matt Exp");
68
69 #include "opt_ddb.h"
70 #include "opt_multiprocessor.h"
71 #define __INTR_PRIVATE
72
73 #include <sys/param.h>
74 #include <sys/queue.h>
75 #include <sys/malloc.h>
76 #include <sys/systm.h>
77 #include <sys/device.h>
78 #include <sys/kernel.h>
79 #include <sys/atomic.h>
80 #include <sys/mutex.h>
81 #include <sys/cpu.h>
82
83 #include <machine/bus.h>
84 #include <machine/intr.h>
85
86 #include <mips/cpu.h>
87 #include <mips/cpuset.h>
88 #include <mips/locore.h>
89
90 #include <mips/rmi/rmixlreg.h>
91 #include <mips/rmi/rmixlvar.h>
92
93 #include <mips/rmi/rmixl_cpuvar.h>
94 #include <mips/rmi/rmixl_intr.h>
95
96 #include <dev/pci/pcireg.h>
97 #include <dev/pci/pcivar.h>
98
99 //#define IOINTR_DEBUG 1
100 #ifdef IOINTR_DEBUG
101 int iointr_debug = IOINTR_DEBUG;
102 # define DPRINTF(x) do { if (iointr_debug) printf x ; } while(0)
103 #else
104 # define DPRINTF(x)
105 #endif
106
107 static void rmixl_intr_disestablish_private(void *);
108
109 static int
110 rmixl_stray_intr(void *v)
111 {
112 return 0;
113 }
114
115 #define RMIXL_PICREG_READ(off) \
116 RMIXL_IOREG_READ(RMIXL_IO_DEV_PIC + (off))
117 #define RMIXL_PICREG_WRITE(off, val) \
118 RMIXL_IOREG_WRITE(RMIXL_IO_DEV_PIC + (off), (val))
119
120 /* XXX this will need to deal with node */
121 #define RMIXLP_PICREG_READ(off) \
122 rmixlp_read_8(RMIXLP_PIC_PCITAG, (off))
123 #define RMIXLP_PICREG_WRITE(off, val) \
124 rmixlp_write_8(RMIXLP_PIC_PCITAG, (off), (val));
125
126 /*
127 * do not clear these when acking EIRR
128 * (otherwise they get lost)
129 */
130 #define RMIXL_EIRR_PRESERVE_MASK \
131 ((MIPS_INT_MASK_5|MIPS_SOFT_INT_MASK) >> 8)
132
133 /*
134 * IRT assignments depends on the RMI chip family
135 * (XLS1xx vs. XLS2xx vs. XLS3xx vs. XLS6xx)
136 * use the right display string table for the CPU that's running.
137 */
138
139 #ifdef MIPS64_XLR
140 /*
141 * rmixl_irtnames_xlrxxx
142 * - use for XLRxxx
143 */
144 static const char * const rmixl_irtnames_xlrxxx[RMIXLR_NIRTS] = {
145 "pic int 0 (watchdog)", /* 0 */
146 "pic int 1 (timer0)", /* 1 */
147 "pic int 2 (timer1)", /* 2 */
148 "pic int 3 (timer2)", /* 3 */
149 "pic int 4 (timer3)", /* 4 */
150 "pic int 5 (timer4)", /* 5 */
151 "pic int 6 (timer5)", /* 6 */
152 "pic int 7 (timer6)", /* 7 */
153 "pic int 8 (timer7)", /* 8 */
154 "pic int 9 (uart0)", /* 9 */
155 "pic int 10 (uart1)", /* 10 */
156 "pic int 11 (i2c0)", /* 11 */
157 "pic int 12 (i2c1)", /* 12 */
158 "pic int 13 (pcmcia)", /* 13 */
159 "pic int 14 (gpio)", /* 14 */
160 "pic int 15 (hyper)", /* 15 */
161 "pic int 16 (pcix)", /* 16 */
162 "pic int 17 (gmac0)", /* 17 */
163 "pic int 18 (gmac1)", /* 18 */
164 "pic int 19 (gmac2)", /* 19 */
165 "pic int 20 (gmac3)", /* 20 */
166 "pic int 21 (xgs0)", /* 21 */
167 "pic int 22 (xgs1)", /* 22 */
168 "pic int 23 (?)", /* 23 */
169 "pic int 24 (hyper_fatal)", /* 24 */
170 "pic int 25 (bridge_aerr)", /* 25 */
171 "pic int 26 (bridge_berr)", /* 26 */
172 "pic int 27 (bridge_tb)", /* 27 */
173 "pic int 28 (bridge_nmi)", /* 28 */
174 "pic int 29 (bridge_sram_derr)",/* 29 */
175 "pic int 30 (gpio_fatal)", /* 30 */
176 "pic int 31 (reserved)", /* 31 */
177 };
178 #endif /* MIPS64_XLR */
179
180 #ifdef MIPS64_XLS
181 /*
182 * rmixl_irtnames_xls2xx
183 * - use for XLS2xx
184 */
185 static const char * const rmixl_irtnames_xls2xx[RMIXLS_NIRTS] = {
186 "pic int 0 (watchdog)", /* 0 */
187 "pic int 1 (timer0)", /* 1 */
188 "pic int 2 (timer1)", /* 2 */
189 "pic int 3 (timer2)", /* 3 */
190 "pic int 4 (timer3)", /* 4 */
191 "pic int 5 (timer4)", /* 5 */
192 "pic int 6 (timer5)", /* 6 */
193 "pic int 7 (timer6)", /* 7 */
194 "pic int 8 (timer7)", /* 8 */
195 "pic int 9 (uart0)", /* 9 */
196 "pic int 10 (uart1)", /* 10 */
197 "pic int 11 (i2c0)", /* 11 */
198 "pic int 12 (i2c1)", /* 12 */
199 "pic int 13 (pcmcia)", /* 13 */
200 "pic int 14 (gpio_a)", /* 14 */
201 "pic int 15 (?)", /* 15 */
202 "pic int 16 (bridge_tb)", /* 16 */
203 "pic int 17 (gmac0)", /* 17 */
204 "pic int 18 (gmac1)", /* 18 */
205 "pic int 19 (gmac2)", /* 19 */
206 "pic int 20 (gmac3)", /* 20 */
207 "pic int 21 (?)", /* 21 */
208 "pic int 22 (?)", /* 22 */
209 "pic int 23 (pcie_link2)", /* 23 */
210 "pic int 24 (pcie_link3)", /* 24 */
211 "pic int 25 (bridge_err)", /* 25 */
212 "pic int 26 (pcie_link0)", /* 26 */
213 "pic int 27 (pcie_link1)", /* 27 */
214 "pic int 28 (?)", /* 28 */
215 "pic int 29 (pcie_err)", /* 29 */
216 "pic int 30 (gpio_b)", /* 30 */
217 "pic int 31 (usb)", /* 31 */
218 };
219
220 /*
221 * rmixl_irtnames_xls1xx
222 * - use for XLS1xx, XLS4xx-Lite
223 */
224 static const char * const rmixl_irtnames_xls1xx[RMIXLS_NIRTS] = {
225 "pic int 0 (watchdog)", /* 0 */
226 "pic int 1 (timer0)", /* 1 */
227 "pic int 2 (timer1)", /* 2 */
228 "pic int 3 (timer2)", /* 3 */
229 "pic int 4 (timer3)", /* 4 */
230 "pic int 5 (timer4)", /* 5 */
231 "pic int 6 (timer5)", /* 6 */
232 "pic int 7 (timer6)", /* 7 */
233 "pic int 8 (timer7)", /* 8 */
234 "pic int 9 (uart0)", /* 9 */
235 "pic int 10 (uart1)", /* 10 */
236 "pic int 11 (i2c0)", /* 11 */
237 "pic int 12 (i2c1)", /* 12 */
238 "pic int 13 (pcmcia)", /* 13 */
239 "pic int 14 (gpio_a)", /* 14 */
240 "pic int 15 (?)", /* 15 */
241 "pic int 16 (bridge_tb)", /* 16 */
242 "pic int 17 (gmac0)", /* 17 */
243 "pic int 18 (gmac1)", /* 18 */
244 "pic int 19 (gmac2)", /* 19 */
245 "pic int 20 (gmac3)", /* 20 */
246 "pic int 21 (?)", /* 21 */
247 "pic int 22 (?)", /* 22 */
248 "pic int 23 (?)", /* 23 */
249 "pic int 24 (?)", /* 24 */
250 "pic int 25 (bridge_err)", /* 25 */
251 "pic int 26 (pcie_link0)", /* 26 */
252 "pic int 27 (pcie_link1)", /* 27 */
253 "pic int 28 (?)", /* 28 */
254 "pic int 29 (pcie_err)", /* 29 */
255 "pic int 30 (gpio_b)", /* 30 */
256 "pic int 31 (usb)", /* 31 */
257 };
258
259 /*
260 * rmixl_irtnames_xls4xx:
261 * - use for XLS4xx, XLS6xx
262 */
263 static const char * const rmixl_irtnames_xls4xx[RMIXLS_NIRTS] = {
264 "pic int 0 (watchdog)", /* 0 */
265 "pic int 1 (timer0)", /* 1 */
266 "pic int 2 (timer1)", /* 2 */
267 "pic int 3 (timer2)", /* 3 */
268 "pic int 4 (timer3)", /* 4 */
269 "pic int 5 (timer4)", /* 5 */
270 "pic int 6 (timer5)", /* 6 */
271 "pic int 7 (timer6)", /* 7 */
272 "pic int 8 (timer7)", /* 8 */
273 "pic int 9 (uart0)", /* 9 */
274 "pic int 10 (uart1)", /* 10 */
275 "pic int 11 (i2c0)", /* 11 */
276 "pic int 12 (i2c1)", /* 12 */
277 "pic int 13 (pcmcia)", /* 13 */
278 "pic int 14 (gpio_a)", /* 14 */
279 "pic int 15 (?)", /* 15 */
280 "pic int 16 (bridge_tb)", /* 16 */
281 "pic int 17 (gmac0)", /* 17 */
282 "pic int 18 (gmac1)", /* 18 */
283 "pic int 19 (gmac2)", /* 19 */
284 "pic int 20 (gmac3)", /* 20 */
285 "pic int 21 (?)", /* 21 */
286 "pic int 22 (?)", /* 22 */
287 "pic int 23 (?)", /* 23 */
288 "pic int 24 (?)", /* 24 */
289 "pic int 25 (bridge_err)", /* 25 */
290 "pic int 26 (pcie_link0)", /* 26 */
291 "pic int 27 (pcie_link1)", /* 27 */
292 "pic int 28 (pcie_link2)", /* 28 */
293 "pic int 29 (pcie_link3)", /* 29 */
294 "pic int 30 (gpio_b)", /* 30 */
295 "pic int 31 (usb)", /* 31 */
296 };
297 #endif /* MIPS64_XLS */
298
299 #ifdef MIPS64_XLP
300 /*
301 * rmixl_irtnames_xlp:
302 * - use for XLP
303 */
304 static const char * const rmixl_irtnames_xlp8xx[RMIXLP_NIRTS] = {
305 [ 0] = "pic int 0 (watchdog0)",
306 [ 1] = "pic int 1 (watchdog1)",
307 [ 2] = "pic int 2 (watchdogNMI0)",
308 [ 3] = "pic int 3 (watchdogNMI1)",
309 [ 4] = "pic int 4 (timer0)",
310 [ 5] = "pic int 5 (timer1)",
311 [ 6] = "pic int 6 (timer2)",
312 [ 7] = "pic int 7 (timer3)",
313 [ 8] = "pic int 8 (timer4)",
314 [ 9] = "pic int 9 (timer5)",
315 [ 10] = "pic int 10 (timer6)",
316 [ 11] = "pic int 11 (timer7)",
317 [ 12] = "pic int 12 (fmn0)",
318 [ 13] = "pic int 13 (fmn1)",
319 [ 14] = "pic int 14 (fmn2)",
320 [ 15] = "pic int 15 (fmn3)",
321 [ 16] = "pic int 16 (fmn4)",
322 [ 17] = "pic int 17 (fmn5)",
323 [ 18] = "pic int 18 (fmn6)",
324 [ 19] = "pic int 19 (fmn7)",
325 [ 20] = "pic int 20 (fmn8)",
326 [ 21] = "pic int 21 (fmn9)",
327 [ 22] = "pic int 22 (fmn10)",
328 [ 23] = "pic int 23 (fmn11)",
329 [ 24] = "pic int 24 (fmn12)",
330 [ 25] = "pic int 25 (fmn13)",
331 [ 26] = "pic int 26 (fmn14)",
332 [ 27] = "pic int 27 (fmn15)",
333 [ 28] = "pic int 28 (fmn16)",
334 [ 29] = "pic int 29 (fmn17)",
335 [ 30] = "pic int 30 (fmn18)",
336 [ 31] = "pic int 31 (fmn19)",
337 [ 32] = "pic int 22 (fmn20)",
338 [ 33] = "pic int 23 (fmn21)",
339 [ 34] = "pic int 24 (fmn22)",
340 [ 35] = "pic int 25 (fmn23)",
341 [ 36] = "pic int 26 (fmn24)",
342 [ 37] = "pic int 27 (fmn25)",
343 [ 38] = "pic int 28 (fmn26)",
344 [ 39] = "pic int 29 (fmn27)",
345 [ 40] = "pic int 30 (fmn28)",
346 [ 41] = "pic int 31 (fmn29)",
347 [ 42] = "pic int 42 (fmn30)",
348 [ 43] = "pic int 43 (fmn31)",
349 [ 44] = "pic int 44 (fmnerr0)",
350 [ 45] = "pic int 45 (fmnerr1)",
351 [ 46] = "pic int 46 (pcie_msix0)",
352 [ 47] = "pic int 47 (pcie_msix1)",
353 [ 48] = "pic int 48 (pcie_msix2)",
354 [ 49] = "pic int 49 (pcie_msix3)",
355 [ 50] = "pic int 50 (pcie_msix4)",
356 [ 51] = "pic int 51 (pcie_msix5)",
357 [ 52] = "pic int 52 (pcie_msix6)",
358 [ 53] = "pic int 53 (pcie_msix7)",
359 [ 54] = "pic int 54 (pcie_msix8)",
360 [ 55] = "pic int 55 (pcie_msix9)",
361 [ 56] = "pic int 56 (pcie_msix10)",
362 [ 57] = "pic int 57 (pcie_msix11)",
363 [ 58] = "pic int 58 (pcie_msix12)",
364 [ 59] = "pic int 59 (pcie_msix13)",
365 [ 60] = "pic int 60 (pcie_msix14)",
366 [ 61] = "pic int 61 (pcie_msix15)",
367 [ 62] = "pic int 62 (pcie_msix16)",
368 [ 63] = "pic int 63 (pcie_msix17)",
369 [ 64] = "pic int 64 (pcie_msix18)",
370 [ 65] = "pic int 65 (pcie_msix19)",
371 [ 66] = "pic int 66 (pcie_msix20)",
372 [ 67] = "pic int 67 (pcie_msix21)",
373 [ 68] = "pic int 68 (pcie_msix22)",
374 [ 69] = "pic int 69 (pcie_msix23)",
375 [ 70] = "pic int 70 (pcie_msix24)",
376 [ 71] = "pic int 71 (pcie_msix25)",
377 [ 72] = "pic int 72 (pcie_msix26)",
378 [ 73] = "pic int 73 (pcie_msix27)",
379 [ 74] = "pic int 74 (pcie_msix28)",
380 [ 75] = "pic int 75 (pcie_msix29)",
381 [ 76] = "pic int 76 (pcie_msix30)",
382 [ 77] = "pic int 77 (pcie_msix31)",
383 [ 78] = "pic int 78 (pcie_link0)",
384 [ 79] = "pic int 79 (pcie_link1)",
385 [ 80] = "pic int 80 (pcie_link2)",
386 [ 81] = "pic int 81 (pcie_link3)",
387 [ 82] = "pic int 82 (nae0)",
388 [ 83] = "pic int 83 (nae1)",
389 [ 84] = "pic int 84 (nae2)",
390 [ 85] = "pic int 85 (nae3)",
391 [ 86] = "pic int 86 (nae4)",
392 [ 87] = "pic int 87 (nae5)",
393 [ 88] = "pic int 88 (nae6)",
394 [ 89] = "pic int 89 (nae7)",
395 [ 90] = "pic int 90 (nae8)",
396 [ 91] = "pic int 91 (nae9)",
397 [ 92] = "pic int 92 (nae10)",
398 [ 93] = "pic int 93 (nae11)",
399 [ 94] = "pic int 94 (nae12)",
400 [ 95] = "pic int 95 (nae13)",
401 [ 96] = "pic int 96 (nae14)",
402 [ 97] = "pic int 97 (nae15)",
403 [ 98] = "pic int 98 (nae16)",
404 [ 99] = "pic int 99 (nae17)",
405 [100] = "pic int 100 (nae18)",
406 [101] = "pic int 101 (?)",
407 [102] = "pic int 102 (naecom0)",
408 [103] = "pic int 103 (naecom1)",
409 [104] = "pic int 104 (?)",
410 [105] = "pic int 105 (?)",
411 [106] = "pic int 106 (?)",
412 [107] = "pic int 107 (?)",
413 [108] = "pic int 108 (?)",
414 [109] = "pic int 109 (?)",
415 [110] = "pic int 100 (?)",
416 [111] = "pic int 111 (?)",
417 [112] = "pic int 112 (?)",
418 [113] = "pic int 113 (?)",
419 [114] = "pic int 114 (poe)",
420 [115] = "pic int 115 (ehci0)",
421 [116] = "pic int 116 (ohci0)",
422 [117] = "pic int 117 (ohci1)",
423 [118] = "pic int 118 (ehci1)",
424 [119] = "pic int 119 (ohci2)",
425 [120] = "pic int 120 (ohci3)",
426 [121] = "pic int 121 (dma)",
427 [122] = "pic int 122 (sae)",
428 [123] = "pic int 123 (pke)",
429 [124] = "pic int 124 (cde0)",
430 [125] = "pic int 125 (cde1)",
431 [126] = "pic int 126 (cde2)",
432 [127] = "pic int 127 (cde3)",
433 [128] = "pic int 128 (?)",
434 [129] = "pic int 129 (ici0)",
435 [130] = "pic int 130 (ici1)",
436 [131] = "pic int 131 (ici2)",
437 [132] = "pic int 132 (kbp)",
438 [133] = "pic int 133 (uart0)",
439 [134] = "pic int 134 (uart1)",
440 [135] = "pic int 135 (i2c0)",
441 [136] = "pic int 136 (i2c1)",
442 [137] = "pic int 137 (sysmgt0)",
443 [138] = "pic int 138 (sysmgt1)",
444 [139] = "pic int 139 (jtag)",
445 [140] = "pic int 140 (pic)",
446 [141] = "pic int 141 (?)",
447 [142] = "pic int 142 (?)",
448 [143] = "pic int 143 (?)",
449 [144] = "pic int 144 (?)",
450 [145] = "pic int 145 (?)",
451 [146] = "pic int 146 (gpio0)",
452 [147] = "pic int 147 (gpio1)",
453 [148] = "pic int 148 (gpio2)",
454 [149] = "pic int 149 (gpio3)",
455 [150] = "pic int 150 (norflash)",
456 [151] = "pic int 151 (nandflash)",
457 [152] = "pic int 152 (spi)",
458 [153] = "pic int 153 (sdmmc)",
459 [154] = "pic int 154 (mem-io-bridge)",
460 [155] = "pic int 155 (l3)",
461 [156] = "pic int 156 (gcu)",
462 [157] = "pic int 157 (dram3_0)",
463 [158] = "pic int 158 (dram3_1)",
464 [159] = "pic int 159 (tracebuf)",
465 };
466
467 /*
468 * rmixl_irtnames_xlp:
469 * - use for XLP
470 */
471 static const char * const rmixl_irtnames_xlp3xx[RMIXLP_NIRTS] = {
472 [ 0] = "pic int 0 (watchdog0)",
473 [ 1] = "pic int 1 (watchdog1)",
474 [ 2] = "pic int 2 (watchdogNMI0)",
475 [ 3] = "pic int 3 (watchdogNMI1)",
476 [ 4] = "pic int 4 (timer0)",
477 [ 5] = "pic int 5 (timer1)",
478 [ 6] = "pic int 6 (timer2)",
479 [ 7] = "pic int 7 (timer3)",
480 [ 8] = "pic int 8 (timer4)",
481 [ 9] = "pic int 9 (timer5)",
482 [ 10] = "pic int 10 (timer6)",
483 [ 11] = "pic int 11 (timer7)",
484 [ 12] = "pic int 12 (gpio0)",
485 [ 13] = "pic int 13 (gpio1)",
486 [ 14] = "pic int 14 (gpio2)",
487 [ 15] = "pic int 15 (gpio3)",
488 [ 16] = "pic int 16 (gpio4)",
489 [ 17] = "pic int 17 (gpio5)",
490 [ 18] = "pic int 18 (gpio6)",
491 [ 19] = "pic int 19 (gpio7)",
492 [ 20] = "pic int 20 (gpio8)",
493 [ 21] = "pic int 21 (gpio0)",
494 [ 22] = "pic int 22 (gpio10)",
495 [ 23] = "pic int 23 (gpio11)",
496 [ 24] = "pic int 24 (?)",
497 [ 25] = "pic int 25 (?)",
498 [ 26] = "pic int 26 (?)",
499 [ 27] = "pic int 27 (?)",
500 [ 28] = "pic int 28 (fmn0)",
501 [ 29] = "pic int 29 (fmn1)",
502 [ 30] = "pic int 30 (fmn2)",
503 [ 31] = "pic int 31 (fmn3)",
504 [ 32] = "pic int 32 (fmn4)",
505 [ 33] = "pic int 33 (fmn5)",
506 [ 34] = "pic int 34 (fmn6)",
507 [ 35] = "pic int 35 (fmn7)",
508 [ 36] = "pic int 36 (fmn8)",
509 [ 37] = "pic int 37 (fmn9)",
510 [ 38] = "pic int 38 (fmn10)",
511 [ 39] = "pic int 39 (fmn11)",
512 [ 40] = "pic int 40 (fmn12)",
513 [ 41] = "pic int 41 (fmn13)",
514 [ 42] = "pic int 42 (fmn14)",
515 [ 43] = "pic int 43 (fmn15)",
516 [ 44] = "pic int 44 (fmnerr0)",
517 [ 45] = "pic int 45 (fmnerr1)",
518 [ 46] = "pic int 46 (pcie_msix0)",
519 [ 47] = "pic int 47 (pcie_msix1)",
520 [ 48] = "pic int 48 (pcie_msix2)",
521 [ 49] = "pic int 49 (pcie_msix3)",
522 [ 50] = "pic int 50 (pcie_msix4)",
523 [ 51] = "pic int 51 (pcie_msix5)",
524 [ 52] = "pic int 52 (pcie_msix6)",
525 [ 53] = "pic int 53 (pcie_msix7)",
526 [ 54] = "pic int 54 (pcie_msix8)",
527 [ 55] = "pic int 55 (pcie_msix9)",
528 [ 56] = "pic int 56 (pcie_msix10)",
529 [ 57] = "pic int 57 (pcie_msix11)",
530 [ 58] = "pic int 58 (pcie_msix12)",
531 [ 59] = "pic int 59 (pcie_msix13)",
532 [ 60] = "pic int 60 (pcie_msix14)",
533 [ 61] = "pic int 61 (pcie_msix15)",
534 [ 62] = "pic int 62 (pcie_msix16)",
535 [ 63] = "pic int 63 (pcie_msix17)",
536 [ 64] = "pic int 64 (pcie_msix18)",
537 [ 65] = "pic int 65 (pcie_msix19)",
538 [ 66] = "pic int 66 (pcie_msix20)",
539 [ 67] = "pic int 67 (pcie_msix21)",
540 [ 68] = "pic int 68 (pcie_msix22)",
541 [ 69] = "pic int 69 (pcie_msix23)",
542 [ 70] = "pic int 70 (pcie_msix24)",
543 [ 71] = "pic int 71 (pcie_msix25)",
544 [ 72] = "pic int 72 (pcie_msix26)",
545 [ 73] = "pic int 73 (pcie_msix27)",
546 [ 74] = "pic int 74 (pcie_msix28)",
547 [ 75] = "pic int 75 (pcie_msix29)",
548 [ 76] = "pic int 76 (pcie_msix30)",
549 [ 77] = "pic int 77 (pcie_msix31)",
550 [ 78] = "pic int 78 (pcie_link0)",
551 [ 79] = "pic int 79 (pcie_link1)",
552 [ 80] = "pic int 80 (pcie_link2)",
553 [ 81] = "pic int 81 (pcie_link3)",
554 [ 82] = "pic int 82 (?)",
555 [ 83] = "pic int 83 (?)",
556 [ 84] = "pic int 84 (?)",
557 [ 85] = "pic int 85 (?)",
558 [ 86] = "pic int 86 (?)",
559 [ 87] = "pic int 87 (?)",
560 [ 88] = "pic int 88 (?)",
561 [ 89] = "pic int 89 (?)",
562 [ 90] = "pic int 90 (?)",
563 [ 91] = "pic int 91 (?)",
564 [ 92] = "pic int 92 (?)",
565 [ 93] = "pic int 93 (?)",
566 [ 94] = "pic int 94 (?)",
567 [ 95] = "pic int 95 (?)",
568 [ 96] = "pic int 96 (?)",
569 [ 97] = "pic int 97 (?)",
570 [ 98] = "pic int 98 (nae0)",
571 [ 99] = "pic int 99 (nae1)",
572 [100] = "pic int 100 (nae2)",
573 [101] = "pic int 101 (nae3)",
574 [102] = "pic int 102 (nae4)",
575 [103] = "pic int 103 (nae5)",
576 [104] = "pic int 104 (nae6)",
577 [105] = "pic int 105 (nae7)",
578 [106] = "pic int 106 (nae8)",
579 [107] = "pic int 107 (?)",
580 [108] = "pic int 108 (?)",
581 [109] = "pic int 109 (?)",
582 [110] = "pic int 110 (naecom0)",
583 [111] = "pic int 111 (naecom1)",
584 [112] = "pic int 112 (?)",
585 [113] = "pic int 113 (?)",
586 [114] = "pic int 114 (poe)",
587 [115] = "pic int 115 (ehci0)",
588 [116] = "pic int 116 (ohci0)",
589 [117] = "pic int 117 (ohci1)",
590 [118] = "pic int 118 (ehci1)",
591 [119] = "pic int 119 (ohci2)",
592 [120] = "pic int 120 (ohci3)",
593 [121] = "pic int 121 (dma)",
594 [122] = "pic int 122 (sae)",
595 [123] = "pic int 123 (pke)",
596 [124] = "pic int 124 (cde0)",
597 [125] = "pic int 125 (?)",
598 [126] = "pic int 126 (?)",
599 [127] = "pic int 127 (?)",
600 [128] = "pic int 128 (?)",
601 [129] = "pic int 129 (?)",
602 [130] = "pic int 130 (?)",
603 [131] = "pic int 131 (?)",
604 [132] = "pic int 132 (?)",
605 [133] = "pic int 133 (uart0)",
606 [134] = "pic int 134 (uart1)",
607 [135] = "pic int 135 (i2c0)",
608 [136] = "pic int 136 (i2c1)",
609 [137] = "pic int 137 (sysmgt0)",
610 [138] = "pic int 138 (sysmgt1)",
611 [139] = "pic int 139 (jtag)",
612 [140] = "pic int 140 (pic)",
613 [141] = "pic int 141 (rxe0)",
614 [142] = "pic int 142 (rxe1)",
615 [143] = "pic int 143 (sata)",
616 [144] = "pic int 144 (srio0)",
617 [145] = "pic int 145 (srio1)",
618 [146] = "pic int 146 (srio2)",
619 [147] = "pic int 147 (srio3)",
620 [148] = "pic int 148 (srio4)",
621 [149] = "pic int 149 (?)",
622 [150] = "pic int 150 (norflash)",
623 [151] = "pic int 151 (nandflash)",
624 [152] = "pic int 152 (spi)",
625 [153] = "pic int 153 (sdmmc)",
626 [154] = "pic int 154 (mem-io-bridge)",
627 [155] = "pic int 155 (l3)",
628 [156] = "pic int 156 (?)",
629 [157] = "pic int 157 (dram3_0)",
630 [158] = "pic int 158 (dram3_1)",
631 [159] = "pic int 159 (tracebuf)",
632 };
633
634 /*
635 * rmixl_irtnames_xlp:
636 * - use for XLP
637 */
638 static const char * const rmixl_irtnames_xlp2xx[RMIXLP_NIRTS] = {
639 [ 0] = "pic int 0 (watchdog0)",
640 [ 1] = "pic int 1 (watchdog1)",
641 [ 2] = "pic int 2 (watchdogNMI0)",
642 [ 3] = "pic int 3 (watchdogNMI1)",
643 [ 4] = "pic int 4 (timer0)",
644 [ 5] = "pic int 5 (timer1)",
645 [ 6] = "pic int 6 (timer2)",
646 [ 7] = "pic int 7 (timer3)",
647 [ 8] = "pic int 8 (timer4)",
648 [ 9] = "pic int 9 (timer5)",
649 [ 10] = "pic int 10 (timer6)",
650 [ 11] = "pic int 11 (timer7)",
651 [ 12] = "pic int 12 (gpio0)",
652 [ 13] = "pic int 13 (gpio1)",
653 [ 14] = "pic int 14 (gpio2)",
654 [ 15] = "pic int 15 (gpio3)",
655 [ 16] = "pic int 16 (gpio4)",
656 [ 17] = "pic int 17 (gpio5)",
657 [ 18] = "pic int 18 (gpio6)",
658 [ 19] = "pic int 19 (gpio7)",
659 [ 20] = "pic int 20 (gpio8)",
660 [ 21] = "pic int 21 (gpio0)",
661 [ 22] = "pic int 22 (gpio10)",
662 [ 23] = "pic int 23 (gpio11)",
663 [ 24] = "pic int 24 (?)",
664 [ 25] = "pic int 25 (?)",
665 [ 26] = "pic int 26 (?)",
666 [ 27] = "pic int 27 (?)",
667 [ 28] = "pic int 28 (?)",
668 [ 29] = "pic int 29 (?)",
669 [ 30] = "pic int 30 (?)",
670 [ 31] = "pic int 31 (?)",
671 [ 32] = "pic int 22 (?)",
672 [ 33] = "pic int 23 (?)",
673 [ 34] = "pic int 24 (?)",
674 [ 35] = "pic int 25 (?)",
675 [ 36] = "pic int 36 (fmn0)",
676 [ 37] = "pic int 37 (fmn1)",
677 [ 38] = "pic int 38 (fmn2)",
678 [ 39] = "pic int 39 (fmn3)",
679 [ 40] = "pic int 40 (fmn4)",
680 [ 41] = "pic int 41 (fmn5)",
681 [ 42] = "pic int 42 (fmn6)",
682 [ 43] = "pic int 43 (fmn7)",
683 [ 44] = "pic int 44 (fmnerr0)",
684 [ 45] = "pic int 45 (fmnerr1)",
685 [ 46] = "pic int 46 (pcie_msix0)",
686 [ 47] = "pic int 47 (pcie_msix1)",
687 [ 48] = "pic int 48 (pcie_msix2)",
688 [ 49] = "pic int 49 (pcie_msix3)",
689 [ 50] = "pic int 50 (pcie_msix4)",
690 [ 51] = "pic int 51 (pcie_msix5)",
691 [ 52] = "pic int 52 (pcie_msix6)",
692 [ 53] = "pic int 53 (pcie_msix7)",
693 [ 54] = "pic int 54 (pcie_msix8)",
694 [ 55] = "pic int 55 (pcie_msix9)",
695 [ 56] = "pic int 56 (pcie_msix10)",
696 [ 57] = "pic int 57 (pcie_msix11)",
697 [ 58] = "pic int 58 (pcie_msix12)",
698 [ 59] = "pic int 59 (pcie_msix13)",
699 [ 60] = "pic int 60 (pcie_msix14)",
700 [ 61] = "pic int 61 (pcie_msix15)",
701 [ 62] = "pic int 62 (pcie_msix16)",
702 [ 63] = "pic int 63 (pcie_msix17)",
703 [ 64] = "pic int 64 (pcie_msix18)",
704 [ 65] = "pic int 65 (pcie_msix19)",
705 [ 66] = "pic int 66 (pcie_msix20)",
706 [ 67] = "pic int 67 (pcie_msix21)",
707 [ 68] = "pic int 68 (pcie_msix22)",
708 [ 69] = "pic int 69 (pcie_msix23)",
709 [ 70] = "pic int 70 (pcie_msix24)",
710 [ 71] = "pic int 71 (pcie_msix25)",
711 [ 72] = "pic int 72 (pcie_msix26)",
712 [ 73] = "pic int 73 (pcie_msix27)",
713 [ 74] = "pic int 74 (pcie_msix28)",
714 [ 75] = "pic int 75 (pcie_msix29)",
715 [ 76] = "pic int 76 (pcie_msix30)",
716 [ 77] = "pic int 77 (pcie_msix31)",
717 [ 78] = "pic int 78 (pcie_link0)",
718 [ 79] = "pic int 79 (pcie_link1)",
719 [ 80] = "pic int 80 (pcie_link2)",
720 [ 81] = "pic int 81 (pcie_link3)",
721 [ 82] = "pic int 82 (?)",
722 [ 83] = "pic int 83 (?)",
723 [ 84] = "pic int 84 (?)",
724 [ 85] = "pic int 85 (?)",
725 [ 86] = "pic int 86 (?)",
726 [ 87] = "pic int 87 (?)",
727 [ 88] = "pic int 88 (?)",
728 [ 89] = "pic int 89 (?)",
729 [ 90] = "pic int 90 (?)",
730 [ 91] = "pic int 91 (?)",
731 [ 92] = "pic int 92 (?)",
732 [ 93] = "pic int 93 (?)",
733 [ 94] = "pic int 94 (?)",
734 [ 95] = "pic int 95 (?)",
735 [ 96] = "pic int 96 (?)",
736 [ 97] = "pic int 97 (?)",
737 [ 98] = "pic int 98 (nae0)",
738 [ 99] = "pic int 99 (nae1)",
739 [100] = "pic int 100 (nae2)",
740 [101] = "pic int 101 (nae3)",
741 [102] = "pic int 102 (nae4)",
742 [103] = "pic int 103 (nae5)",
743 [104] = "pic int 104 (nae6)",
744 [105] = "pic int 105 (nae7)",
745 [106] = "pic int 106 (nae8)",
746 [107] = "pic int 107 (?)",
747 [108] = "pic int 108 (?)",
748 [109] = "pic int 109 (?)",
749 [110] = "pic int 110 (naecom0)",
750 [111] = "pic int 111 (naecom1)",
751 [112] = "pic int 112 (?)",
752 [113] = "pic int 113 (?)",
753 [114] = "pic int 114 (poe)",
754 [115] = "pic int 115 (xhci0)",
755 [116] = "pic int 116 (xhci1)",
756 [117] = "pic int 117 (xhci2)",
757 [118] = "pic int 118 (?)",
758 [119] = "pic int 119 (?)",
759 [120] = "pic int 120 (?)",
760 [121] = "pic int 121 (dma)",
761 [122] = "pic int 122 (sae)",
762 [123] = "pic int 123 (pke)",
763 [124] = "pic int 124 (cde0)",
764 [125] = "pic int 125 (i2c0)",
765 [126] = "pic int 126 (i2c1)",
766 [127] = "pic int 127 (i2c2)",
767 [128] = "pic int 128 (i2c3)",
768 [129] = "pic int 129 (?)",
769 [130] = "pic int 130 (?)",
770 [131] = "pic int 131 (?)",
771 [132] = "pic int 132 (?)",
772 [133] = "pic int 133 (uart0)",
773 [134] = "pic int 134 (uart1)",
774 [135] = "pic int 135 (?)",
775 [136] = "pic int 136 (systemp0)",
776 [137] = "pic int 137 (systemp1)",
777 [138] = "pic int 138 (sysmgt)",
778 [139] = "pic int 139 (jtag)",
779 [140] = "pic int 140 (pic)",
780 [141] = "pic int 141 (rxe0)",
781 [142] = "pic int 142 (rxe1)",
782 [143] = "pic int 143 (?)",
783 [144] = "pic int 144 (?)",
784 [145] = "pic int 145 (?)",
785 [146] = "pic int 146 (?)",
786 [147] = "pic int 147 (?)",
787 [148] = "pic int 148 (?)",
788 [149] = "pic int 149 (?)",
789 [150] = "pic int 150 (norflash)",
790 [151] = "pic int 151 (nandflash)",
791 [152] = "pic int 152 (spi)",
792 [153] = "pic int 153 (sdmmc)",
793 [154] = "pic int 154 (mem-io-bridge)",
794 [155] = "pic int 155 (l3)",
795 [156] = "pic int 156 (?)",
796 [157] = "pic int 157 (dram3_0)",
797 [158] = "pic int 158 (dram3_1)",
798 [159] = "pic int 159 (tracebuf)",
799 };
800 #endif /* MIPS64_XLP */
801
802 /*
803 * rmixl_vecnames_common:
804 * - use for unknown cpu implementation
805 * - covers all vectors, not just IRT intrs
806 */
807 static const char * const rmixl_vecnames_common[NINTRVECS] = {
808 "vec 0 (sw0)", /* 0 */
809 "vec 1 (sw1)", /* 1 */
810 "vec 2 (hw2)", /* 2 */
811 "vec 3 (hw3)", /* 3 */
812 "vec 4 (hw4)", /* 4 */
813 "vec 5 (hw5)", /* 5 */
814 "vec 6 (hw6)", /* 6 */
815 "vec 7 (hw7)", /* 7 */
816 "vec 8", /* 8 */
817 "vec 9", /* 9 */
818 "vec 10", /* 10 */
819 "vec 11", /* 11 */
820 "vec 12", /* 12 */
821 "vec 13", /* 13 */
822 "vec 14", /* 14 */
823 "vec 15", /* 15 */
824 "vec 16", /* 16 */
825 "vec 17", /* 17 */
826 "vec 18", /* 18 */
827 "vec 19", /* 19 */
828 "vec 20", /* 20 */
829 "vec 21", /* 21 */
830 "vec 22", /* 22 */
831 "vec 23", /* 23 */
832 "vec 24", /* 24 */
833 "vec 25", /* 25 */
834 "vec 26", /* 26 */
835 "vec 27", /* 27 */
836 "vec 28", /* 28 */
837 "vec 29", /* 29 */
838 "vec 30", /* 30 */
839 "vec 31", /* 31 */
840 "vec 32", /* 32 */
841 "vec 33", /* 33 */
842 "vec 34", /* 34 */
843 "vec 35", /* 35 */
844 "vec 36", /* 36 */
845 "vec 37", /* 37 */
846 "vec 38", /* 38 */
847 "vec 39", /* 39 */
848 "vec 40", /* 40 */
849 "vec 41", /* 41 */
850 "vec 42", /* 42 */
851 "vec 43", /* 43 */
852 "vec 44", /* 44 */
853 "vec 45", /* 45 */
854 "vec 46", /* 46 */
855 "vec 47", /* 47 */
856 "vec 48", /* 48 */
857 "vec 49", /* 49 */
858 "vec 50", /* 50 */
859 "vec 51", /* 51 */
860 "vec 52", /* 52 */
861 "vec 53", /* 53 */
862 "vec 54", /* 54 */
863 "vec 55", /* 55 */
864 "vec 56", /* 56 */
865 "vec 57", /* 57 */
866 "vec 58", /* 58 */
867 "vec 59", /* 59 */
868 "vec 60", /* 60 */
869 "vec 61", /* 61 */
870 "vec 62", /* 63 */
871 "vec 63", /* 63 */
872 };
873
874 /*
875 * mask of CPUs attached
876 * once they are attached, this var is read-only so mp safe
877 */
878 static __cpuset_t cpu_present_mask;
879
880 kmutex_t *rmixl_ipi_lock; /* covers RMIXL_PIC_IPIBASE */
881 kmutex_t *rmixl_intr_lock; /* covers rest of PIC, and rmixl_intrhand[] */
882 rmixl_intrvecq_t rmixl_intrvec_lruq[_IPL_N] = {
883 [IPL_NONE] = TAILQ_HEAD_INITIALIZER(rmixl_intrvec_lruq[IPL_NONE]),
884 [IPL_SOFTCLOCK] = TAILQ_HEAD_INITIALIZER(rmixl_intrvec_lruq[IPL_SOFTCLOCK]),
885 [IPL_SOFTNET] = TAILQ_HEAD_INITIALIZER(rmixl_intrvec_lruq[IPL_SOFTNET]),
886 [IPL_VM] = TAILQ_HEAD_INITIALIZER(rmixl_intrvec_lruq[IPL_VM]),
887 [IPL_SCHED] = TAILQ_HEAD_INITIALIZER(rmixl_intrvec_lruq[IPL_SCHED]),
888 [IPL_DDB] = TAILQ_HEAD_INITIALIZER(rmixl_intrvec_lruq[IPL_DDB]),
889 [IPL_HIGH] = TAILQ_HEAD_INITIALIZER(rmixl_intrvec_lruq[IPL_HIGH]),
890 };
891
892 rmixl_intrvec_t rmixl_intrvec[NINTRVECS] = {
893 [0 ... NINTRVECS-1] = {
894 .iv_intrhand = {
895 .ih_common = {
896 .ihc_func = rmixl_stray_intr,
897 .ihc_arg = rmixl_stray_intr,
898 }
899 },
900 },
901 };
902 #define RMIXL_NIRTS MAX(MAX(RMIXLR_NIRTS,RMIXLS_NIRTS), RMIXLP_NIRTS)
903 rmixl_intrhand_t rmixl_irt_intrhands[RMIXL_NIRTS] = {
904 [0 ... RMIXL_NIRTS-1] = {
905 .ih_common = {
906 .ihc_func = rmixl_stray_intr,
907 .ihc_arg = rmixl_stray_intr,
908 }
909 },
910 };
911 static u_int rmixl_nirts;
912 const char * const *rmixl_irtnames;
913
914 #ifdef DIAGNOSTIC
915 static int rmixl_pic_init_done;
916 #endif
917
918
919 static uint32_t rmixl_irt_thread_mask(__cpuset_t);
920 static void rmixl_irt_init(size_t);
921 static void rmixl_irt_disestablish(size_t);
922 static void rmixl_irt_establish(size_t, size_t, int);
923
924 #ifdef MULTIPROCESSOR
925 static int rmixl_send_ipi(struct cpu_info *, int);
926 static int rmixl_ipi_intr(void *);
927 #endif
928
929 #if defined(DIAGNOSTIC) || defined(IOINTR_DEBUG) || defined(DDB)
930 int rmixl_intrvec_print_subr(size_t);
931 int rmixl_intrhand_print(void);
932 int rmixl_irt_print(void);
933 void rmixl_ipl_eimr_map_print(void);
934 #endif
935
936
937 void
938 evbmips_intr_init(void)
939 {
940 const bool is_xlp_p = cpu_rmixlp(mips_options.mips_cpu);
941 const bool is_xlr_p = cpu_rmixlr(mips_options.mips_cpu);
942 const bool is_xls_p = cpu_rmixls(mips_options.mips_cpu);
943
944 KASSERT(is_xlp_p || is_xlr_p || is_xls_p);
945
946 /*
947 * The number of IRT entries is different for XLP .vs. XLR/XLS.
948 */
949 if (is_xlp_p) {
950 #ifdef MIPS64_XLP
951 if (RMIXLP_2XX_P) {
952 rmixl_irtnames = rmixl_irtnames_xlp2xx;
953 rmixl_nirts = __arraycount(rmixl_irtnames_xlp2xx);
954 } else if (RMIXLP_3XX_P) {
955 rmixl_irtnames = rmixl_irtnames_xlp3xx;
956 rmixl_nirts = __arraycount(rmixl_irtnames_xlp3xx);
957 } else {
958 rmixl_irtnames = rmixl_irtnames_xlp8xx;
959 rmixl_nirts = __arraycount(rmixl_irtnames_xlp8xx);
960 }
961 #endif
962 } else if (is_xlr_p) {
963 #ifdef MIPS64_XLR
964 rmixl_irtnames = rmixl_irtnames_xlrxxx;
965 rmixl_nirts = __arraycount(rmixl_irtnames_xlrxxx);
966 #endif
967 } else if (is_xls_p) {
968 #ifdef MIPS64_XLS
969 switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
970 case MIPS_XLS104:
971 case MIPS_XLS108:
972 case MIPS_XLS404LITE:
973 case MIPS_XLS408LITE:
974 rmixl_irtnames = rmixl_irtnames_xls1xx;
975 rmixl_nirts = __arraycount(rmixl_irtnames_xls1xx);
976 break;
977 case MIPS_XLS204:
978 case MIPS_XLS208:
979 rmixl_irtnames = rmixl_irtnames_xls2xx;
980 rmixl_nirts = __arraycount(rmixl_irtnames_xls2xx);
981 break;
982 case MIPS_XLS404:
983 case MIPS_XLS408:
984 case MIPS_XLS416:
985 case MIPS_XLS608:
986 case MIPS_XLS616:
987 rmixl_irtnames = rmixl_irtnames_xls4xx;
988 rmixl_nirts = __arraycount(rmixl_irtnames_xls4xx);
989 break;
990 default:
991 rmixl_irtnames = rmixl_vecnames_common;
992 rmixl_nirts = __arraycount(rmixl_vecnames_common);
993 break;
994 }
995 #endif /* MIPS64_XLS */
996 }
997
998 #ifdef DIAGNOSTIC
999 if (rmixl_pic_init_done != 0)
1000 panic("%s: rmixl_pic_init_done %d",
1001 __func__, rmixl_pic_init_done);
1002 #endif
1003
1004 rmixl_ipi_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_HIGH);
1005 rmixl_intr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_HIGH);
1006
1007 mutex_enter(rmixl_intr_lock);
1008
1009 /*
1010 * Insert all non-IPI non-normal MIPS vectors on lru queue.
1011 */
1012 for (size_t i = RMIXL_INTRVEC_IPI; i < NINTRVECS; i++) {
1013 TAILQ_INSERT_TAIL(&rmixl_intrvec_lruq[IPL_NONE],
1014 &rmixl_intrvec[i], iv_lruq_link);
1015 }
1016
1017 /*
1018 * initialize (zero) all IRT Entries in the PIC
1019 */
1020 for (size_t i = 0; i < rmixl_nirts; i++) {
1021 rmixl_irt_init(i);
1022 }
1023
1024 /*
1025 * disable watchdog NMI, timers
1026 */
1027 if (is_xlp_p) {
1028 /*
1029 * Reset the interrupt thread enables to disable all CPUs.
1030 */
1031 for (size_t i = 0; i < 8; i++) {
1032 RMIXLP_PICREG_WRITE(RMIXLP_PIC_INT_THREAD_ENABLE01(i), 0);
1033 RMIXLP_PICREG_WRITE(RMIXLP_PIC_INT_THREAD_ENABLE23(i), 0);
1034 }
1035
1036 /*
1037 * Enable interrupts for node 0 core 0 thread 0.
1038 */
1039 RMIXLP_PICREG_WRITE(RMIXLP_PIC_INT_THREAD_ENABLE01(0), 1);
1040
1041 /*
1042 * Disable watchdogs and system timers.
1043 */
1044 uint64_t r = RMIXLP_PICREG_READ(RMIXLP_PIC_CTRL);
1045 r &= ~(RMIXLP_PIC_CTRL_WTE|RMIXLP_PIC_CTRL_STE);
1046 RMIXLP_PICREG_WRITE(RMIXLP_PIC_CTRL, r);
1047 } else {
1048 /*
1049 * XXX
1050 * WATCHDOG_ENB is preserved because clearing it causes
1051 * hang on the XLS616 (but not on the XLS408)
1052 */
1053 uint32_t r = RMIXL_PICREG_READ(RMIXL_PIC_CONTROL);
1054 r &= RMIXL_PIC_CONTROL_RESV|RMIXL_PIC_CONTROL_WATCHDOG_ENB;
1055 RMIXL_PICREG_WRITE(RMIXL_PIC_CONTROL, r);
1056 }
1057
1058 #ifdef DIAGNOSTIC
1059 rmixl_pic_init_done = 1;
1060 #endif
1061 mutex_exit(rmixl_intr_lock);
1062 }
1063
1064 /*
1065 * establish vector for mips3 count/compare clock interrupt
1066 * this ensures we enable in EIRR,
1067 * even though cpu_intr() handles the interrupt
1068 * note the 'mpsafe' arg here is a placeholder only
1069 */
1070 void
1071 rmixl_intr_init_clk(void)
1072 {
1073 const size_t vec = ffs(MIPS_INT_MASK_5 >> MIPS_INT_MASK_SHIFT) - 1;
1074
1075 mutex_enter(rmixl_intr_lock);
1076
1077 void *ih = rmixl_vec_establish(vec, NULL, IPL_SCHED, NULL, NULL, false);
1078 if (ih == NULL)
1079 panic("%s: establish vec %zu failed", __func__, vec);
1080
1081 mutex_exit(rmixl_intr_lock);
1082 }
1083
1084 #ifdef MULTIPROCESSOR
1085 /*
1086 * establish IPI interrupt and send function
1087 */
1088 void
1089 rmixl_intr_init_ipi(void)
1090 {
1091 mutex_enter(rmixl_intr_lock);
1092
1093 for (size_t ipi = 0; ipi < NIPIS; ipi++) {
1094 const size_t vec = RMIXL_INTRVEC_IPI + ipi;
1095 void * const ih = rmixl_vec_establish(vec, NULL, IPL_SCHED,
1096 rmixl_ipi_intr, (void *)(uintptr_t)ipi, true);
1097 if (ih == NULL)
1098 panic("%s: establish ipi %zu at vec %zu failed",
1099 __func__, ipi, vec);
1100 }
1101
1102 mips_locoresw.lsw_send_ipi = rmixl_send_ipi;
1103
1104 mutex_exit(rmixl_intr_lock);
1105 }
1106 #endif /* MULTIPROCESSOR */
1107
1108 /*
1109 * initialize per-cpu interrupt stuff in softc
1110 * accumulate per-cpu bits in 'cpu_present_mask'
1111 */
1112 void
1113 rmixl_intr_init_cpu(struct cpu_info *ci)
1114 {
1115 struct cpu_softc * const sc = ci->ci_softc;
1116 const char * xname = device_xname(sc->sc_dev);
1117
1118 KASSERT(sc != NULL);
1119 KASSERT(NINTRVECS <= __arraycount(sc->sc_vec_evcnts));
1120 KASSERT(rmixl_nirts <= __arraycount(sc->sc_irt_evcnts));
1121
1122 for (size_t vec = 0; vec < NINTRVECS; vec++) {
1123 evcnt_attach_dynamic(&sc->sc_vec_evcnts[vec],
1124 EVCNT_TYPE_INTR, NULL, xname, rmixl_intr_string(vec));
1125 }
1126
1127 for (size_t irt = 0; irt < rmixl_nirts; irt++) {
1128 evcnt_attach_dynamic(&sc->sc_irt_evcnts[irt],
1129 EVCNT_TYPE_INTR, NULL, xname, rmixl_irtnames[irt]);
1130 }
1131
1132 KASSERT(cpu_index(ci) < (sizeof(cpu_present_mask) * 8));
1133 atomic_or_32((volatile uint32_t *)&cpu_present_mask, 1 << cpu_index(ci));
1134 }
1135
1136 const char *
1137 rmixl_irt_string(size_t irt)
1138 {
1139 KASSERT(irt < rmixl_nirts);
1140
1141 return rmixl_irtnames[irt];
1142 }
1143
1144 /*
1145 * rmixl_intr_string - return pointer to display name of a PIC-based interrupt
1146 */
1147 const char *
1148 rmixl_intr_string(size_t vec)
1149 {
1150
1151 if (vec >= NINTRVECS)
1152 panic("%s: vec index %zu out of range, max %d",
1153 __func__, vec, NINTRVECS - 1);
1154
1155 return rmixl_vecnames_common[vec];
1156 }
1157
1158 size_t
1159 rmixl_intr_get_vec(int ipl)
1160 {
1161 KASSERT(mutex_owned(rmixl_intr_lock));
1162 KASSERT(IPL_VM <= ipl && ipl <= IPL_HIGH);
1163
1164 /*
1165 * In reality higer ipls should have higher vec numbers,
1166 * but for now don't worry about it.
1167 */
1168 struct rmixl_intrvecq * const freeq = &rmixl_intrvec_lruq[IPL_NONE];
1169 struct rmixl_intrvecq * const iplq = &rmixl_intrvec_lruq[ipl];
1170 rmixl_intrvec_t *iv;
1171
1172 /*
1173 * If there's a free vector, grab it otherwise choose the least
1174 * recently assigned vector sharing this IPL.
1175 */
1176 if ((iv = TAILQ_FIRST(freeq)) == NULL) {
1177 iv = TAILQ_FIRST(iplq);
1178 KASSERT(iv != NULL);
1179 }
1180
1181 return iv - rmixl_intrvec;
1182 }
1183
1184 /*
1185 * rmixl_irt_thread_mask
1186 *
1187 * given a bitmask of cpus, return a, IRT thread mask
1188 */
1189 static uint32_t
1190 rmixl_irt_thread_mask(__cpuset_t cpumask)
1191 {
1192 uint32_t irtc0;
1193
1194 #if defined(MULTIPROCESSOR)
1195 #ifndef NOTYET
1196 if (cpumask == -1)
1197 return 1; /* XXX TMP FIXME */
1198 #endif
1199
1200 /*
1201 * discount cpus not present
1202 */
1203 cpumask &= cpu_present_mask;
1204
1205 switch (MIPS_PRID_IMPL(mips_options.mips_cpu_id)) {
1206 case MIPS_XLS104:
1207 case MIPS_XLS204:
1208 case MIPS_XLS404:
1209 case MIPS_XLS404LITE:
1210 irtc0 = ((cpumask >> 2) << 4) | (cpumask & __BITS(1,0));
1211 irtc0 &= (__BITS(5,4) | __BITS(1,0));
1212 break;
1213 case MIPS_XLS108:
1214 case MIPS_XLS208:
1215 case MIPS_XLS408:
1216 case MIPS_XLS408LITE:
1217 case MIPS_XLS608:
1218 irtc0 = cpumask & __BITS(7,0);
1219 break;
1220 case MIPS_XLS416:
1221 case MIPS_XLS616:
1222 irtc0 = cpumask & __BITS(15,0);
1223 break;
1224 default:
1225 panic("%s: unknown cpu ID %#x\n", __func__,
1226 mips_options.mips_cpu_id);
1227 }
1228 #else
1229 irtc0 = 1;
1230 #endif /* MULTIPROCESSOR */
1231
1232 return irtc0;
1233 }
1234
1235 /*
1236 * rmixl_irt_init
1237 * - initialize IRT Entry for given index
1238 * - unmask Thread#0 in low word (assume we only have 1 thread)
1239 */
1240 static void
1241 rmixl_irt_init(size_t irt)
1242 {
1243 KASSERT(irt < rmixl_nirts);
1244 if (cpu_rmixlp(mips_options.mips_cpu)) {
1245 RMIXLP_PICREG_WRITE(RMIXLP_PIC_IRTENTRY(irt), 0);
1246 } else {
1247 RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(irt), 0); /* high word */
1248 RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC0(irt), 0); /* low word */
1249 }
1250 }
1251
1252 /*
1253 * rmixl_irt_disestablish
1254 * - invalidate IRT Entry for given index
1255 */
1256 static void
1257 rmixl_irt_disestablish(size_t irt)
1258 {
1259 KASSERT(mutex_owned(rmixl_intr_lock));
1260 DPRINTF(("%s: irt %zu, irtc1 %#x\n", __func__, irt, 0));
1261 rmixl_irt_init(irt);
1262 }
1263
1264 /*
1265 * rmixl_irt_establish
1266 * - construct an IRT Entry for irt and write to PIC
1267 */
1268 static void
1269 rmixl_irt_establish(size_t irt, size_t vec, int ist)
1270 {
1271 const bool is_xlp_p = cpu_rmixlp(mips_options.mips_cpu);
1272
1273 KASSERT(mutex_owned(rmixl_intr_lock));
1274
1275 if (irt >= rmixl_nirts)
1276 panic("%s: bad irt %zu\n", __func__, irt);
1277
1278 /*
1279 * All XLP interrupt are level (high).
1280 */
1281 if (ist != IST_LEVEL && ist != IST_LEVEL_HIGH
1282 && (is_xlp_p
1283 || (ist != IST_EDGE
1284 && ist != IST_EDGE_FALLING
1285 && ist != IST_EDGE_RISING))) {
1286 panic("%s: bad ist %d\n", __func__, ist);
1287 }
1288
1289 /*
1290 * XXX IRT entries are not shared
1291 */
1292 if (is_xlp_p) {
1293 KASSERT(RMIXLP_PICREG_READ(RMIXLP_PIC_IRTENTRY(irt)) == 0);
1294 uint64_t irtc0 = RMIXLP_PIC_IRTENTRY_EN
1295 | RMIXLP_PIC_IRTENTRY_LOCAL
1296 | RMIXLP_PIC_IRTENTRY_DT_ITE
1297 | RMIXLP_PIC_IRTENTRY_ITE(0)
1298 | __SHIFTIN(vec, RMIXLP_PIC_IRTENTRY_INTVEC)
1299
1300 /*
1301 * write IRT Entry to PIC
1302 */
1303 DPRINTF(("%s: vec %zu (%#x), irt %zu (%s), irtc0 %#"PRIx64"\n",
1304 __func__, vec, vec, irt, rmixl_irtnames[irt], irtc0));
1305
1306 RMIXLP_PICREG_WRITE(RMIXLP_PIC_IRTENTRY(irt), irtc0);
1307 } else {
1308 KASSERT(RMIXL_PICREG_READ(RMIXL_PIC_IRTENTRYC0(irt)) == 0);
1309 KASSERT(RMIXL_PICREG_READ(RMIXL_PIC_IRTENTRYC1(irt)) == 0);
1310
1311 __cpuset_t cpumask = 1; /* XXX */
1312 uint32_t irtc0 = rmixl_irt_thread_mask(cpumask);
1313
1314 uint32_t irtc1 = RMIXL_PIC_IRTENTRYC1_VALID;
1315 irtc1 |= RMIXL_PIC_IRTENTRYC1_GL; /* local */
1316 KASSERT((irtc1 & RMIXL_PIC_IRTENTRYC1_NMI) == 0);
1317
1318 if (ist == IST_LEVEL
1319 || ist == IST_LEVEL_LOW
1320 || ist == IST_LEVEL_HIGH)
1321 irtc1 |= RMIXL_PIC_IRTENTRYC1_TRG;
1322 KASSERT((irtc1 & RMIXL_PIC_IRTENTRYC1_NMI) == 0);
1323
1324 if (ist == IST_LEVEL_LOW || ist == IST_EDGE_FALLING)
1325 irtc1 |= RMIXL_PIC_IRTENTRYC1_P;
1326 KASSERT((irtc1 & RMIXL_PIC_IRTENTRYC1_NMI) == 0);
1327
1328 irtc1 |= vec; /* vector in EIRR */
1329 KASSERT((irtc1 & RMIXL_PIC_IRTENTRYC1_NMI) == 0);
1330
1331 /*
1332 * write IRT Entry to PIC
1333 */
1334 DPRINTF(("%s: vec %zu (%#x), irt %zu, irtc0 %#x, irtc1 %#x\n",
1335 __func__, vec, vec, irt, irtc0, irtc1));
1336 RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC0(irt), irtc0); /* low word */
1337 RMIXL_PICREG_WRITE(RMIXL_PIC_IRTENTRYC1(irt), irtc1); /* high word */
1338 }
1339 }
1340
1341 void *
1342 rmixl_vec_establish(size_t vec, rmixl_intrhand_t *ih, int ipl,
1343 int (*func)(void *), void *arg, bool mpsafe)
1344 {
1345
1346 KASSERT(mutex_owned(rmixl_intr_lock));
1347
1348 DPRINTF(("%s: vec %zu ih %p ipl %d func %p arg %p mpsafe %d\n",
1349 __func__, vec, ih, ipl, func, arg, mpsafe));
1350
1351 #ifdef DIAGNOSTIC
1352 if (rmixl_pic_init_done == 0)
1353 panic("%s: called before evbmips_intr_init", __func__);
1354 #endif
1355
1356 /*
1357 * check args
1358 */
1359 if (vec >= NINTRVECS)
1360 panic("%s: vec %zu out of range, max %d",
1361 __func__, vec, NINTRVECS - 1);
1362 if (ipl < IPL_VM || ipl > IPL_HIGH)
1363 panic("%s: ipl %d out of range, min %d, max %d",
1364 __func__, ipl, IPL_VM, IPL_HIGH);
1365
1366 const int s = splhigh();
1367
1368 rmixl_intrvec_t * const iv = &rmixl_intrvec[vec];
1369 if (ih == NULL) {
1370 ih = &iv->iv_intrhand;
1371 }
1372
1373 if (vec >= 8) {
1374 TAILQ_REMOVE(&rmixl_intrvec_lruq[iv->iv_ipl], iv, iv_lruq_link);
1375 }
1376
1377 if (LIST_EMPTY(&iv->iv_hands)) {
1378 KASSERT(iv->iv_ipl == IPL_NONE);
1379 iv->iv_ipl = ipl;
1380 } else {
1381 KASSERT(iv->iv_ipl == ipl);
1382 }
1383
1384 if (vec >= 8) {
1385 TAILQ_INSERT_TAIL(&rmixl_intrvec_lruq[iv->iv_ipl],
1386 iv, iv_lruq_link);
1387 }
1388
1389 if (ih->ih_common.ihc_func != rmixl_stray_intr) {
1390 #ifdef DIAGNOSTIC
1391 printf("%s: intrhand[%zu] busy\n", __func__, vec);
1392 #endif
1393 splx(s);
1394 return NULL;
1395 }
1396
1397 ih->ih_common.ihc_arg = arg;
1398 #ifdef MULTIPROCESSOR
1399 ih->ih_common.ihc_mpsafe = mpsafe;
1400 #endif
1401 ih->ih_vec = vec;
1402
1403 LIST_INSERT_HEAD(&iv->iv_hands, ih, ih_link);
1404
1405 const uint64_t eimr_bit = (uint64_t)1 << vec;
1406 for (int i = ipl; --i >= 0; ) {
1407 KASSERT((ipl_eimr_map[i] & eimr_bit) == 0);
1408 ipl_eimr_map[i] |= eimr_bit;
1409 }
1410
1411 ih->ih_common.ihc_func = func; /* do this last */
1412
1413 splx(s);
1414
1415 return ih;
1416 }
1417
1418 /*
1419 * rmixl_intr_establish
1420 * - used to establish an IRT-based interrupt only
1421 */
1422 void *
1423 rmixl_intr_establish(size_t irt, int ipl, int ist,
1424 int (*func)(void *), void *arg, bool mpsafe)
1425 {
1426 #ifdef DIAGNOSTIC
1427 if (rmixl_pic_init_done == 0)
1428 panic("%s: called before rmixl_pic_init_done", __func__);
1429 #endif
1430
1431 /*
1432 * check args
1433 */
1434 if (irt >= rmixl_nirts)
1435 panic("%s: irt %zu out of range, max %d",
1436 __func__, irt, rmixl_nirts - 1);
1437 if (ipl < IPL_VM || ipl > IPL_HIGH)
1438 panic("%s: ipl %d out of range, min %d, max %d",
1439 __func__, ipl, IPL_VM, IPL_HIGH);
1440
1441 mutex_enter(rmixl_intr_lock);
1442
1443 rmixl_intrhand_t *ih = &rmixl_irt_intrhands[irt];
1444
1445 KASSERT(ih->ih_common.ihc_func == rmixl_stray_intr);
1446
1447 const size_t vec = rmixl_intr_get_vec(ipl);
1448
1449 DPRINTF(("%s: irt %zu, ih %p vec %zu, ipl %d\n",
1450 __func__, irt, ih, vec, ipl));
1451
1452 /*
1453 * establish vector
1454 */
1455 ih = rmixl_vec_establish(vec, ih, ipl, func, arg, mpsafe);
1456
1457 /*
1458 * establish IRT Entry
1459 */
1460 rmixl_irt_establish(irt, vec, ist);
1461
1462 mutex_exit(rmixl_intr_lock);
1463
1464 ih->ih_common.ihc_disestablish = rmixl_intr_disestablish_private;
1465
1466 return ih;
1467 }
1468
1469 void
1470 rmixl_vec_disestablish(void *cookie)
1471 {
1472 rmixl_intrhand_t * const ih = cookie;
1473 const size_t vec = ih->ih_vec;
1474 rmixl_intrvec_t * const iv = &rmixl_intrvec[vec];
1475
1476 KASSERT(mutex_owned(rmixl_intr_lock));
1477 KASSERT(vec < NINTRVECS);
1478 KASSERT(ih->ih_common.ihc_func != rmixl_stray_intr);
1479 KASSERT(ih->ih_common.ihc_arg != rmixl_stray_intr);
1480 KASSERT(IPL_VM <= iv->iv_ipl && iv->iv_ipl <= IPL_HIGH);
1481
1482 LIST_REMOVE(ih, ih_link);
1483
1484 ih->ih_common.ihc_func = rmixl_stray_intr; /* do this first */
1485
1486 const uint64_t eimr_bit = __BIT(ih->ih_vec);
1487 for (int i = iv->iv_ipl; --i >= 0; ) {
1488 KASSERT((ipl_eimr_map[i] & eimr_bit) != 0);
1489 ipl_eimr_map[i] ^= eimr_bit;
1490 }
1491
1492 ih->ih_vec = 0;
1493 #ifdef MULTIPROCESSOR
1494 ih->ih_common.ihc_mpsafe = false;
1495 #endif
1496 ih->ih_common.ihc_arg = rmixl_stray_intr;
1497
1498 /*
1499 * If this vector isn't servicing any interrupts, then check to
1500 * see if this IPL has other vectors using it. If it does, then
1501 * return this vector to the freeq (lruq for IPL_NONE). This makes
1502 * there will always be at least one vector per IPL.
1503 */
1504 if (vec > 8 && LIST_EMPTY(&iv->iv_hands)) {
1505 rmixl_intrvecq_t * const freeq = &rmixl_intrvec_lruq[IPL_NONE];
1506 rmixl_intrvecq_t * const iplq = &rmixl_intrvec_lruq[iv->iv_ipl];
1507
1508 if (TAILQ_NEXT(iv, iv_lruq_link) != NULL
1509 || TAILQ_FIRST(iplq) != iv) {
1510 TAILQ_REMOVE(iplq, iv, iv_lruq_link);
1511 iv->iv_ipl = IPL_NONE;
1512 TAILQ_INSERT_TAIL(freeq, iv, iv_lruq_link);
1513 }
1514 }
1515 }
1516
1517 void
1518 rmixl_intr_disestablish_private(void *cookie)
1519 {
1520 rmixl_intrhand_t * const ih = cookie;
1521 const size_t vec = ih->ih_vec;
1522 rmixl_intrvec_t * const iv = &rmixl_intrvec[vec];
1523
1524 KASSERT(vec < NINTRVECS);
1525
1526 mutex_enter(rmixl_intr_lock);
1527
1528 /*
1529 * disable/invalidate the IRT Entry if needed
1530 */
1531 if (ih != &iv->iv_intrhand) {
1532 size_t irt = ih - rmixl_irt_intrhands;
1533 KASSERT(irt < rmixl_nirts);
1534 rmixl_irt_disestablish(irt);
1535 }
1536
1537 /*
1538 * disasociate from vector and free the handle
1539 */
1540 rmixl_vec_disestablish(cookie);
1541
1542 mutex_exit(rmixl_intr_lock);
1543 }
1544
1545 void
1546 evbmips_iointr(int ipl, vaddr_t pc, uint32_t pending)
1547 {
1548 struct cpu_softc * const sc = curcpu()->ci_softc;
1549 const bool is_xlp_p = cpu_rmixlp(mips_options.mips_cpu);
1550
1551 DPRINTF(("%s: cpu%u: ipl %d, pc %#"PRIxVADDR", pending %#x\n",
1552 __func__, cpu_number(), ipl, pc, pending));
1553
1554 /*
1555 * 'pending' arg is a summary that there is something to do
1556 * the real pending status is obtained from EIRR
1557 */
1558 KASSERT(pending == MIPS_INT_MASK_1);
1559
1560 for (;;) {
1561 rmixl_intrhand_t *ih;
1562 uint64_t eirr;
1563 uint64_t eimr;
1564 uint64_t vecbit;
1565 int vec;
1566
1567 __asm volatile("dmfc0 %0, $9, 6;" : "=r"(eirr));
1568 __asm volatile("dmfc0 %0, $9, 7;" : "=r"(eimr));
1569
1570 #ifdef IOINTR_DEBUG
1571 printf("%s: cpu%u: eirr %#"PRIx64", eimr %#"PRIx64", mask %#"PRIx64"\n",
1572 __func__, cpu_number(), eirr, eimr, ipl_eimr_map[ipl-1]);
1573 #endif /* IOINTR_DEBUG */
1574
1575 /*
1576 * reduce eirr to
1577 * - ints that are enabled at or below this ipl
1578 * - exclude count/compare clock and soft ints
1579 * they are handled elsewhere
1580 */
1581 eirr &= ipl_eimr_map[ipl-1];
1582 eirr &= ~ipl_eimr_map[ipl];
1583 eirr &= ~((MIPS_INT_MASK_5 | MIPS_SOFT_INT_MASK) >> 8);
1584 if (eirr == 0)
1585 break;
1586
1587 vec = 63 - __builtin_clzll(eirr);
1588 rmixl_intrvec_t * const iv = &rmixl_intrvec[vec];
1589 vecbit = 1ULL << vec;
1590 KASSERT (iv->iv_ipl == ipl);
1591 LIST_FOREACH(ih, &iv->iv_hands, ih_link) {
1592 KASSERT ((vecbit & eimr) == 0);
1593 KASSERT ((vecbit & RMIXL_EIRR_PRESERVE_MASK) == 0);
1594
1595 /*
1596 * ack in EIRR, and in PIC if needed,
1597 * the irq we are about to handle
1598 */
1599 rmixl_eirr_ack(eimr, vecbit, RMIXL_EIRR_PRESERVE_MASK);
1600 if (ih != &iv->iv_intrhand) {
1601 size_t irt = ih - rmixl_irt_intrhands;
1602 KASSERT(irt < rmixl_nirts);
1603 if (is_xlp_p) {
1604 RMIXLP_PICREG_WRITE(RMIXLP_PIC_INT_ACK,
1605 irt);
1606 } else {
1607 RMIXL_PICREG_WRITE(RMIXL_PIC_INTRACK,
1608 1 << irt);
1609 }
1610 sc->sc_irt_evcnts[irt].ev_count++;
1611 }
1612
1613 rmixl_intr_deliver(&ih->ih_common,
1614 &sc->sc_vec_evcnts[vec], ipl);
1615
1616 KASSERT(ipl == iv->iv_ipl);
1617 KASSERTMSG(curcpu()->ci_cpl >= ipl,
1618 "%s: after %s: cpl (%d) < ipl %d",
1619 __func__, sc->sc_vec_evcnts[vec].ev_name,
1620 ipl, curcpu()->ci_cpl);
1621 }
1622 }
1623 }
1624
1625 #ifdef MULTIPROCESSOR
1626 static int
1627 rmixl_send_ipi(struct cpu_info *ci, int tag)
1628 {
1629 const cpuid_t cpuid = ci->ci_cpuid;
1630 const uint64_t req = 1 << tag;
1631 const bool is_xlp_p = cpu_rmixlp(mips_options.mips_cpu);
1632 uint32_t r;
1633
1634 if (! CPUSET_HAS_P(cpus_running, cpu_index(ci)))
1635 return -1;
1636
1637 KASSERT(tag >= 0 && tag < NIPIS);
1638
1639 if (is_xlp_p) {
1640 r = RMIXLP_PIC_IPI_CTRL_MAKE(0, __BIT(cpuid & 15),
1641 RMIXL_INTRVEC_IPI + tag);
1642 } else {
1643 const uint32_t core = (uint32_t)(cpuid >> 2);
1644 const uint32_t thread = (uint32_t)(cpuid & __BITS(1,0));
1645 r = RMIXL_PIC_IPIBASE_MAKE(0, core, thread,
1646 RMIXL_INTRVEC_IPI + tag);
1647 }
1648
1649 mutex_enter(rmixl_ipi_lock);
1650 atomic_or_64(&ci->ci_request_ipis, req);
1651 __asm __volatile("sync");
1652 if (is_xlp_p) {
1653 RMIXLP_PICREG_WRITE(RMIXLP_PIC_IPI_CTRL, r);
1654 } else {
1655 RMIXL_PICREG_WRITE(RMIXL_PIC_IPIBASE, r);
1656 }
1657 mutex_exit(rmixl_ipi_lock);
1658
1659 return 0;
1660 }
1661
1662 static int
1663 rmixl_ipi_intr(void *arg)
1664 {
1665 struct cpu_info * const ci = curcpu();
1666 const uint64_t ipi_mask = 1 << (uintptr_t)arg;
1667
1668 KASSERT(ci->ci_cpl >= IPL_SCHED);
1669 KASSERT((uintptr_t)arg < NIPIS);
1670 KASSERT(!ci->ci_softc->sc_in_ipi);
1671
1672 /* if the request is clear, it was previously processed */
1673 if ((ci->ci_request_ipis & ipi_mask) == 0)
1674 return 0;
1675
1676 ci->ci_softc->sc_in_ipi = true;
1677
1678 atomic_or_64(&ci->ci_active_ipis, ipi_mask);
1679 atomic_and_64(&ci->ci_request_ipis, ~ipi_mask);
1680
1681 ipi_process(ci, ipi_mask);
1682
1683 atomic_and_64(&ci->ci_active_ipis, ~ipi_mask);
1684
1685 ci->ci_softc->sc_in_ipi = false;
1686 return 1;
1687 }
1688 #endif /* MULTIPROCESSOR */
1689
1690 #if defined(DIAGNOSTIC) || defined(IOINTR_DEBUG) || defined(DDB)
1691 int
1692 rmixl_intrvec_print_subr(size_t vec)
1693 {
1694 rmixl_intrvec_t * const iv = &rmixl_intrvec[vec];
1695 rmixl_intrhand_t *ih;
1696
1697 printf("vec %zu: ipl %u\n", vec, iv->iv_ipl);
1698
1699 LIST_FOREACH(ih, &iv->iv_hands, ih_link) {
1700 if (ih == &iv->iv_intrhand) {
1701 printf(" [%s]: func %p, arg %p\n",
1702 rmixl_vecnames_common[vec],
1703 ih->ih_common.ihc_func, ih->ih_common.ihc_arg);
1704 } else {
1705 const size_t irt = ih - rmixl_irt_intrhands;
1706 printf(" irt %zu [%s]: func %p, arg %p\n",
1707 irt, rmixl_irtnames[irt],
1708 ih->ih_common.ihc_func, ih->ih_common.ihc_arg);
1709 }
1710 }
1711 return 0;
1712 }
1713 int
1714 rmixl_intrhand_print(void)
1715 {
1716 for (size_t vec = 0; vec < NINTRVECS; vec++)
1717 rmixl_intrvec_print_subr(vec);
1718 return 0;
1719 }
1720
1721 static inline void
1722 rmixl_irt_entry_print(size_t irt)
1723 {
1724 if (irt >= rmixl_nirts)
1725 return;
1726 if (cpu_rmixlp(mips_options.mips_cpu)) {
1727 uint64_t c = RMIXLP_PICREG_READ(RMIXLP_PIC_IRTENTRY(irt));
1728 printf("irt[%zu]: %#"PRIx64"\n", irt, c);
1729 } else {
1730 uint32_t c0 = RMIXL_PICREG_READ(RMIXL_PIC_IRTENTRYC0(irt));
1731 uint32_t c1 = RMIXL_PICREG_READ(RMIXL_PIC_IRTENTRYC1(irt));
1732 printf("irt[%zu]: %#x, %#x\n", irt, c0, c1);
1733 }
1734 }
1735
1736 int
1737 rmixl_irt_print(void)
1738 {
1739 printf("%s:\n", __func__);
1740 for (size_t irt = 0; irt < rmixl_nirts ; irt++)
1741 rmixl_irt_entry_print(irt);
1742 return 0;
1743 }
1744
1745 void
1746 rmixl_ipl_eimr_map_print(void)
1747 {
1748 printf("IPL_NONE=%d, mask %#"PRIx64"\n",
1749 IPL_NONE, ipl_eimr_map[IPL_NONE]);
1750 printf("IPL_SOFTCLOCK=%d, mask %#"PRIx64"\n",
1751 IPL_SOFTCLOCK, ipl_eimr_map[IPL_SOFTCLOCK]);
1752 printf("IPL_SOFTNET=%d, mask %#"PRIx64"\n",
1753 IPL_SOFTNET, ipl_eimr_map[IPL_SOFTNET]);
1754 printf("IPL_VM=%d, mask %#"PRIx64"\n",
1755 IPL_VM, ipl_eimr_map[IPL_VM]);
1756 printf("IPL_SCHED=%d, mask %#"PRIx64"\n",
1757 IPL_SCHED, ipl_eimr_map[IPL_SCHED]);
1758 printf("IPL_DDB=%d, mask %#"PRIx64"\n",
1759 IPL_DDB, ipl_eimr_map[IPL_DDB]);
1760 printf("IPL_HIGH=%d, mask %#"PRIx64"\n",
1761 IPL_HIGH, ipl_eimr_map[IPL_HIGH]);
1762 }
1763
1764 #endif
1765