[BACK]Return to rmixl_intr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / mips / rmi

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>