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