Home | History | Annotate | Line # | Download | only in booke
e500_intr.c revision 1.2
      1 /*	$NetBSD: e500_intr.c,v 1.2 2011/01/18 01:02:52 matt Exp $	*/
      2 /*-
      3  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
      4  * All rights reserved.
      5  *
      6  * This code is derived from software contributed to The NetBSD Foundation
      7  * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
      8  * Agency and which was developed by Matt Thomas of 3am Software Foundry.
      9  *
     10  * This material is based upon work supported by the Defense Advanced Research
     11  * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
     12  * Contract No. N66001-09-C-2073.
     13  * Approved for Public Release, Distribution Unlimited
     14  *
     15  * Redistribution and use in source and binary forms, with or without
     16  * modification, are permitted provided that the following conditions
     17  * are met:
     18  * 1. Redistributions of source code must retain the above copyright
     19  *    notice, this list of conditions and the following disclaimer.
     20  * 2. Redistributions in binary form must reproduce the above copyright
     21  *    notice, this list of conditions and the following disclaimer in the
     22  *    documentation and/or other materials provided with the distribution.
     23  *
     24  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     27  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     34  * POSSIBILITY OF SUCH DAMAGE.
     35  */
     36 
     37 #define __INTR_PRIVATE
     38 
     39 #include <sys/param.h>
     40 #include <sys/proc.h>
     41 #include <sys/intr.h>
     42 #include <sys/cpu.h>
     43 #include <sys/kmem.h>
     44 #include <sys/atomic.h>
     45 #include <sys/bus.h>
     46 
     47 #include <uvm/uvm_extern.h>
     48 
     49 #include <powerpc/spr.h>
     50 #include <powerpc/booke/spr.h>
     51 
     52 #include <powerpc/booke/cpuvar.h>
     53 #include <powerpc/booke/e500reg.h>
     54 #include <powerpc/booke/e500var.h>
     55 #include <powerpc/booke/openpicreg.h>
     56 
     57 #define	IPL2CTPR(ipl)		((ipl) + 15 - IPL_HIGH)
     58 #define CTPR2IPL(ctpr)		((ctpr) - (15 - IPL_HIGH))
     59 
     60 #define	IST_PERCPU_P(ist)	((ist) >= IST_TIMER)
     61 
     62 #define	IPL_SOFTMASK \
     63 	    ((1 << IPL_SOFTSERIAL) | (1 << IPL_SOFTNET   )	\
     64 	    |(1 << IPL_SOFTBIO   ) | (1 << IPL_SOFTCLOCK ))
     65 
     66 #define SOFTINT2IPL_MAP \
     67 	    ((IPL_SOFTSERIAL << (4*SOFTINT_SERIAL))	\
     68 	    |(IPL_SOFTNET    << (4*SOFTINT_NET   ))	\
     69 	    |(IPL_SOFTBIO    << (4*SOFTINT_BIO   ))	\
     70 	    |(IPL_SOFTCLOCK  << (4*SOFTINT_CLOCK )))
     71 #define	SOFTINT2IPL(si_level)	((SOFTINT2IPL_MAP >> (4 * si_level)) & 0x0f)
     72 
     73 struct e500_intr_irq_info {
     74 	bus_addr_t irq_vpr;
     75 	bus_addr_t irq_dr;
     76 	u_int irq_vector;
     77 };
     78 
     79 struct intr_source {
     80 	int (*is_func)(void *);
     81 	void *is_arg;
     82 	int8_t is_ipl;
     83 	uint8_t is_ist;
     84 	uint8_t is_irq;
     85 	bus_size_t is_vpr;
     86 	bus_size_t is_dr;
     87 };
     88 
     89 #define	INTR_SOURCE_INITIALIZER \
     90 	{ .is_func = e500_intr_spurious, .is_arg = NULL, \
     91 	.is_irq = -1, .is_ipl = IPL_NONE, .is_ist = IST_NONE, }
     92 
     93 struct e500_intr_name {
     94 	uint8_t in_irq;
     95 	const char in_name[15];
     96 };
     97 
     98 static const struct e500_intr_name e500_onchip_intr_names[] = {
     99 	{ ISOURCE_L2, "l2" },
    100 	{ ISOURCE_ECM, "ecm" },
    101 	{ ISOURCE_DDR, "ddr" },
    102 	{ ISOURCE_LBC, "lbc" },
    103 	{ ISOURCE_DMA_CHAN1, "dma-chan1" },
    104 	{ ISOURCE_DMA_CHAN2, "dma-chan2" },
    105 	{ ISOURCE_DMA_CHAN3, "dma-chan3" },
    106 	{ ISOURCE_DMA_CHAN4, "dma-chan4" },
    107 	{ ISOURCE_PCI1, "pci1" },
    108 	{ ISOURCE_PCIEX2, "pcie2" },
    109 	{ ISOURCE_PCIEX	, "pcie1" },
    110 	{ ISOURCE_PCIEX3, "pcie3" },
    111 	{ ISOURCE_ETSEC1_TX, "etsec1-tx" },
    112 	{ ISOURCE_ETSEC1_RX, "etsec1-rx" },
    113 	{ ISOURCE_ETSEC3_TX, "etsec3-tx" },
    114 	{ ISOURCE_ETSEC3_RX, "etsec3-rx" },
    115 	{ ISOURCE_ETSEC3_ERR, "etsec3-err" },
    116 	{ ISOURCE_ETSEC1_ERR, "etsec1-err" },
    117 	{ ISOURCE_ETSEC2_TX, "etsec2-tx" },
    118 	{ ISOURCE_ETSEC2_RX, "etsec2-rx" },
    119 	{ ISOURCE_ETSEC4_TX, "etsec4-tx" },
    120 	{ ISOURCE_ETSEC4_RX, "etsec4-rx" },
    121 	{ ISOURCE_ETSEC4_ERR, "etsec4-err" },
    122 	{ ISOURCE_ETSEC2_ERR, "etsec2-err" },
    123 	{ ISOURCE_DUART, "duart" },
    124 	{ ISOURCE_I2C, "i2c" },
    125 	{ ISOURCE_PERFMON, "perfmon" },
    126 	{ ISOURCE_SECURITY1, "sec1" },
    127 	{ ISOURCE_SRIO_EWPU, "srio-ewpu" },
    128 	{ ISOURCE_SRIO_ODBELL, "srio-odbell" },
    129 	{ ISOURCE_SRIO_IDBELL, "srio-idbell" },
    130 	{ ISOURCE_SRIO_OMU1, "srio-omu1" },
    131 	{ ISOURCE_SRIO_IMU1, "srio-imu1" },
    132 	{ ISOURCE_SRIO_OMU2, "srio-omu2" },
    133 	{ ISOURCE_SRIO_IMU2, "srio-imu2" },
    134 	{ 0, "" },
    135 };
    136 
    137 const struct e500_intr_name mpc8548_external_intr_names[] = {
    138 	{ 0, "" },
    139 };
    140 
    141 const struct e500_intr_name mpc8536_external_intr_names[] = {
    142 	{ 0, "" },
    143 };
    144 
    145 const struct e500_intr_name mpc8572_external_intr_names[] = {
    146 	{ 0, "" },
    147 };
    148 
    149 const struct e500_intr_name mpc8548_onchip_intr_names[] = {
    150 	{ ISOURCE_PCI1, "pci1" },
    151 	{ ISOURCE_PCI2, "pci2" },
    152 	{ 0, "" },
    153 };
    154 
    155 const struct e500_intr_name mpc8544_onchip_intr_names[] = {
    156 	{ 0, "" },
    157 };
    158 
    159 const struct e500_intr_name mpc8536_onchip_intr_names[] = {
    160 	{ ISOURCE_USB1, "usb1" },
    161 	{ ISOURCE_SATA2, "sata2" },
    162 	{ ISOURCE_USB2, "usb2" },
    163 	{ ISOURCE_SECURITY2, "sec2" },
    164 	{ ISOURCE_SPI, "spi" },
    165 	{ ISOURCE_USB3, "usb3" },
    166 	{ ISOURCE_ETSEC1_PTP, "etsec1-ptp" },
    167 	{ ISOURCE_ETSEC3_PTP, "etsec3-ptp" },
    168 	{ ISOURCE_ESDHC, "esdhc" },
    169 	{ ISOURCE_SATA1, "sata1" },
    170 	{ 0, "" },
    171 };
    172 
    173 const struct e500_intr_name mpc8572_onchip_intr_names[] = {
    174 	{ ISOURCE_PCIEX3_MPC8572, "pcie3" },
    175 	{ ISOURCE_FEC, "fec" },
    176 	{ ISOURCE_GPIO, "gpio" },
    177 	{ ISOURCE_PME_GENERAL, "pme" },
    178 	{ ISOURCE_SECURITY2, "sec2" },
    179 	{ ISOURCE_TLU1, "tlu1" },
    180 	{ ISOURCE_TLU2, "tlu2" },
    181 	{ ISOURCE_PME_CHAN1, "pme-chan1" },
    182 	{ ISOURCE_PME_CHAN2, "pme-chan2" },
    183 	{ ISOURCE_PME_CHAN3, "pme-chan3" },
    184 	{ ISOURCE_PME_CHAN4, "pme-chan4" },
    185 	{ ISOURCE_ETSEC1_PTP, "etsec1-ptp" },
    186 	{ ISOURCE_ETSEC2_PTP, "etsec2-ptp" },
    187 	{ ISOURCE_ETSEC3_PTP, "etsec3-ptp" },
    188 	{ ISOURCE_ETSEC4_PTP, "etsec4-ptp" },
    189 	{ ISOURCE_DMA2_CHAN1, "dma2-chan1" },
    190 	{ ISOURCE_DMA2_CHAN2, "dma2-chan2" },
    191 	{ ISOURCE_DMA2_CHAN3, "dma2-chan3" },
    192 	{ ISOURCE_DMA2_CHAN4, "dma2-chan4" },
    193 	{ 0, "" },
    194 };
    195 
    196 static const struct e500_intr_name e500_msigroup_intr_names[] = {
    197 	{ 0, "msigroup0" },
    198 	{ 1, "msigroup1" },
    199 	{ 2, "msigroup2" },
    200 	{ 3, "msigroup3" },
    201 	{ 4, "msigroup4" },
    202 	{ 5, "msigroup5" },
    203 	{ 6, "msigroup6" },
    204 	{ 7, "msigroup7" },
    205 	{ 0, "" },
    206 };
    207 
    208 static const struct e500_intr_name e500_timer_intr_names[] = {
    209 	{ 0, "timer0" },
    210 	{ 1, "timer1" },
    211 	{ 2, "timer2" },
    212 	{ 3, "timer3" },
    213 	{ 0, "" },
    214 };
    215 
    216 static const struct e500_intr_name e500_ipi_intr_names[] = {
    217 	{ 0, "ipi0" },
    218 	{ 1, "ipi1" },
    219 	{ 2, "ipi2" },
    220 	{ 3, "ipi3" },
    221 	{ 0, "" },
    222 };
    223 
    224 static const struct e500_intr_name e500_mi_intr_names[] = {
    225 	{ 0, "mi0" },
    226 	{ 1, "mi1" },
    227 	{ 2, "mi2" },
    228 	{ 3, "mi3" },
    229 	{ 0, "" },
    230 };
    231 
    232 struct e500_intr_info {
    233 	u_int ii_external_sources;
    234 	uint32_t ii_onchip_bitmap[2];
    235 	u_int ii_onchip_sources;
    236 	u_int ii_msigroup_sources;
    237 	u_int ii_ipi_sources;			/* per-cpu */
    238 	u_int ii_timer_sources;			/* per-cpu */
    239 	u_int ii_mi_sources;			/* per-cpu */
    240 	u_int ii_percpu_sources;
    241 	const struct e500_intr_name *ii_external_intr_names;
    242 	const struct e500_intr_name *ii_onchip_intr_names;
    243 	u_int8_t ii_ist_vectors[IST_MAX+1];
    244 };
    245 
    246 static kmutex_t e500_intr_lock __aligned(32);
    247 static struct e500_intr_info e500_intr_info;
    248 
    249 static const struct e500_intr_info mpc8548_intr_info = {
    250 	.ii_external_sources = MPC8548_EXTERNALSOURCES,
    251 	.ii_onchip_bitmap = MPC8548_ONCHIPBITMAP,
    252 	.ii_onchip_sources = MPC8548_ONCHIPSOURCES,
    253 	.ii_msigroup_sources = MPC8548_MSIGROUPSOURCES,
    254 	.ii_timer_sources = MPC8548_TIMERSOURCES,
    255 	.ii_ipi_sources = MPC8548_IPISOURCES,
    256 	.ii_mi_sources = MPC8548_MISOURCES,
    257 	.ii_percpu_sources = MPC8548_TIMERSOURCES
    258 	    + MPC8548_IPISOURCES + MPC8548_MISOURCES,
    259 	.ii_external_intr_names = mpc8548_external_intr_names,
    260 	.ii_onchip_intr_names = mpc8548_onchip_intr_names,
    261 	.ii_ist_vectors = {
    262 		[IST_NONE]		= ~0,
    263 		[IST_EDGE]		= 0,
    264 		[IST_LEVEL_LOW]		= 0,
    265 		[IST_LEVEL_HIGH]	= 0,
    266 		[IST_ONCHIP]		= MPC8548_EXTERNALSOURCES,
    267 		[IST_MSIGROUP]		= MPC8548_EXTERNALSOURCES
    268 					    + MPC8548_ONCHIPSOURCES,
    269 		[IST_TIMER]		= MPC8548_EXTERNALSOURCES
    270 					    + MPC8548_ONCHIPSOURCES
    271 					    + MPC8548_MSIGROUPSOURCES,
    272 		[IST_IPI]		= MPC8548_EXTERNALSOURCES
    273 					    + MPC8548_ONCHIPSOURCES
    274 					    + MPC8548_MSIGROUPSOURCES
    275 					    + MPC8548_TIMERSOURCES,
    276 		[IST_MI]		= MPC8548_EXTERNALSOURCES
    277 					    + MPC8548_ONCHIPSOURCES
    278 					    + MPC8548_MSIGROUPSOURCES
    279 					    + MPC8548_TIMERSOURCES
    280 					    + MPC8548_IPISOURCES,
    281 		[IST_MAX]		= MPC8548_EXTERNALSOURCES
    282 					    + MPC8548_ONCHIPSOURCES
    283 					    + MPC8548_MSIGROUPSOURCES
    284 					    + MPC8548_TIMERSOURCES
    285 					    + MPC8548_IPISOURCES
    286 					    + MPC8548_MISOURCES,
    287 	},
    288 };
    289 
    290 static const struct e500_intr_info mpc8536_intr_info = {
    291 	.ii_external_sources = MPC8536_EXTERNALSOURCES,
    292 	.ii_onchip_bitmap = MPC8536_ONCHIPBITMAP,
    293 	.ii_onchip_sources = MPC8536_ONCHIPSOURCES,
    294 	.ii_msigroup_sources = MPC8536_MSIGROUPSOURCES,
    295 	.ii_timer_sources = MPC8536_TIMERSOURCES,
    296 	.ii_ipi_sources = MPC8536_IPISOURCES,
    297 	.ii_mi_sources = MPC8536_MISOURCES,
    298 	.ii_percpu_sources = MPC8536_TIMERSOURCES
    299 	    + MPC8536_IPISOURCES + MPC8536_MISOURCES,
    300 	.ii_external_intr_names = mpc8536_external_intr_names,
    301 	.ii_onchip_intr_names = mpc8536_onchip_intr_names,
    302 	.ii_ist_vectors = {
    303 		[IST_NONE]		= ~0,
    304 		[IST_EDGE]		= 0,
    305 		[IST_LEVEL_LOW]		= 0,
    306 		[IST_LEVEL_HIGH]	= 0,
    307 		[IST_ONCHIP]		= MPC8536_EXTERNALSOURCES,
    308 		[IST_MSIGROUP]		= MPC8536_EXTERNALSOURCES
    309 					    + MPC8536_ONCHIPSOURCES,
    310 		[IST_TIMER]		= MPC8536_EXTERNALSOURCES
    311 					    + MPC8536_ONCHIPSOURCES
    312 					    + MPC8536_MSIGROUPSOURCES,
    313 		[IST_IPI]		= MPC8536_EXTERNALSOURCES
    314 					    + MPC8536_ONCHIPSOURCES
    315 					    + MPC8536_MSIGROUPSOURCES
    316 					    + MPC8536_TIMERSOURCES,
    317 		[IST_MI]		= MPC8536_EXTERNALSOURCES
    318 					    + MPC8536_ONCHIPSOURCES
    319 					    + MPC8536_MSIGROUPSOURCES
    320 					    + MPC8536_TIMERSOURCES
    321 					    + MPC8536_IPISOURCES,
    322 		[IST_MAX]		= MPC8536_EXTERNALSOURCES
    323 					    + MPC8536_ONCHIPSOURCES
    324 					    + MPC8536_MSIGROUPSOURCES
    325 					    + MPC8536_TIMERSOURCES
    326 					    + MPC8536_IPISOURCES
    327 					    + MPC8536_MISOURCES,
    328 	},
    329 };
    330 
    331 static const struct e500_intr_info mpc8572_intr_info = {
    332 	.ii_external_sources = MPC8572_EXTERNALSOURCES,
    333 	.ii_onchip_bitmap = MPC8572_ONCHIPBITMAP,
    334 	.ii_onchip_sources = MPC8572_ONCHIPSOURCES,
    335 	.ii_msigroup_sources = MPC8572_MSIGROUPSOURCES,
    336 	.ii_timer_sources = MPC8572_TIMERSOURCES,
    337 	.ii_ipi_sources = MPC8572_IPISOURCES,
    338 	.ii_mi_sources = MPC8572_MISOURCES,
    339 	.ii_percpu_sources = MPC8572_TIMERSOURCES
    340 	    + MPC8572_IPISOURCES + MPC8572_MISOURCES,
    341 	.ii_external_intr_names = mpc8572_external_intr_names,
    342 	.ii_onchip_intr_names = mpc8572_onchip_intr_names,
    343 	.ii_ist_vectors = {
    344 		[IST_NONE]		= ~0,
    345 		[IST_EDGE]		= 0,
    346 		[IST_LEVEL_LOW]		= 0,
    347 		[IST_LEVEL_HIGH]	= 0,
    348 		[IST_ONCHIP]		= MPC8572_EXTERNALSOURCES,
    349 		[IST_MSIGROUP]		= MPC8572_EXTERNALSOURCES
    350 					    + MPC8572_ONCHIPSOURCES,
    351 		[IST_TIMER]		= MPC8572_EXTERNALSOURCES
    352 					    + MPC8572_ONCHIPSOURCES
    353 					    + MPC8572_MSIGROUPSOURCES,
    354 		[IST_IPI]		= MPC8572_EXTERNALSOURCES
    355 					    + MPC8572_ONCHIPSOURCES
    356 					    + MPC8572_MSIGROUPSOURCES
    357 					    + MPC8572_TIMERSOURCES,
    358 		[IST_MI]		= MPC8572_EXTERNALSOURCES
    359 					    + MPC8572_ONCHIPSOURCES
    360 					    + MPC8572_MSIGROUPSOURCES
    361 					    + MPC8572_TIMERSOURCES
    362 					    + MPC8572_IPISOURCES,
    363 		[IST_MAX]		= MPC8572_EXTERNALSOURCES
    364 					    + MPC8572_ONCHIPSOURCES
    365 					    + MPC8572_MSIGROUPSOURCES
    366 					    + MPC8572_TIMERSOURCES
    367 					    + MPC8572_IPISOURCES
    368 					    + MPC8572_MISOURCES,
    369 	},
    370 };
    371 
    372 static const char ist_names[][12] = {
    373 	[IST_NONE] = "none",
    374 	[IST_EDGE] = "edge",
    375 	[IST_LEVEL_LOW] = "level-",
    376 	[IST_LEVEL_HIGH] = "level+",
    377 	[IST_MSI] = "msi",
    378 	[IST_ONCHIP] = "onchip",
    379 	[IST_MSIGROUP] = "msigroup",
    380 	[IST_TIMER] = "timer",
    381 	[IST_IPI] = "ipi",
    382 	[IST_MI] = "msgint",
    383 };
    384 
    385 static struct intr_source *e500_intr_sources;
    386 static const struct intr_source *e500_intr_last_source;
    387 
    388 static void 	*e500_intr_establish(int, int, int, int (*)(void *), void *);
    389 static void 	e500_intr_disestablish(void *);
    390 static void 	e500_intr_cpu_init(struct cpu_info *ci);
    391 static void 	e500_intr_init(void);
    392 static const char *e500_intr_string(int, int);
    393 static void 	e500_critintr(struct trapframe *tf);
    394 static void 	e500_decrintr(struct trapframe *tf);
    395 static void 	e500_extintr(struct trapframe *tf);
    396 static void 	e500_fitintr(struct trapframe *tf);
    397 static void 	e500_wdogintr(struct trapframe *tf);
    398 static void	e500_spl0(void);
    399 static int 	e500_splraise(int);
    400 static void 	e500_splx(int);
    401 #ifdef __HAVE_FAST_SOFTINTS
    402 static void 	e500_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p);
    403 static void 	e500_softint_trigger(uintptr_t machdep);
    404 #endif
    405 
    406 const struct intrsw e500_intrsw = {
    407 	.intrsw_establish = e500_intr_establish,
    408 	.intrsw_disestablish = e500_intr_disestablish,
    409 	.intrsw_init = e500_intr_init,
    410 	.intrsw_cpu_init = e500_intr_cpu_init,
    411 	.intrsw_string = e500_intr_string,
    412 
    413 	.intrsw_critintr = e500_critintr,
    414 	.intrsw_decrintr = e500_decrintr,
    415 	.intrsw_extintr = e500_extintr,
    416 	.intrsw_fitintr = e500_fitintr,
    417 	.intrsw_wdogintr = e500_wdogintr,
    418 
    419 	.intrsw_splraise = e500_splraise,
    420 	.intrsw_splx = e500_splx,
    421 	.intrsw_spl0 = e500_spl0,
    422 
    423 #ifdef __HAVE_FAST_SOFTINTS
    424 	.intrsw_softint_init_md = e500_softint_init_md,
    425 	.intrsw_softint_trigger = e500_softint_trigger,
    426 #endif
    427 };
    428 
    429 static inline uint32_t
    430 openpic_read(struct cpu_softc *cpu, bus_size_t offset)
    431 {
    432 
    433 	return bus_space_read_4(cpu->cpu_bst, cpu->cpu_bsh,
    434 	    OPENPIC_BASE + offset);
    435 }
    436 
    437 static inline void
    438 openpic_write(struct cpu_softc *cpu, bus_size_t offset, uint32_t val)
    439 {
    440 
    441 	return bus_space_write_4(cpu->cpu_bst, cpu->cpu_bsh,
    442 	    OPENPIC_BASE + offset, val);
    443 }
    444 
    445 static const char *
    446 e500_intr_external_name_lookup(int irq)
    447 {
    448 	prop_array_t extirqs = board_info_get_object("external-irqs");
    449 	prop_string_t irqname = prop_array_get(extirqs, irq);
    450 	KASSERT(irqname != NULL);
    451 	KASSERT(prop_object_type(irqname) == PROP_TYPE_STRING);
    452 
    453 	return prop_string_cstring_nocopy(irqname);
    454 }
    455 
    456 static const char *
    457 e500_intr_name_lookup(const struct e500_intr_name *names, int irq)
    458 {
    459 	for (; names->in_name[0] != '\0'; names++) {
    460 		if (names->in_irq == irq)
    461 			return names->in_name;
    462 	}
    463 
    464 	return NULL;
    465 }
    466 
    467 static const char *
    468 e500_intr_onchip_name_lookup(int irq)
    469 {
    470 	const char *name;
    471 
    472 	return e500_intr_name_lookup(e500_intr_info.ii_onchip_intr_names, irq);
    473 	if (name != NULL)
    474 		return name;
    475 
    476 	name = e500_intr_name_lookup(e500_onchip_intr_names, irq);
    477 }
    478 
    479 #ifdef __HAVE_FAST_SOFTINTS
    480 static inline void
    481 e500_softint_deliver(struct cpu_info *ci, struct cpu_softc *cpu,
    482 	int ipl, int si_level)
    483 {
    484 	KASSERT(ci->ci_data.cpu_softints & (1 << ipl));
    485 	ci->ci_data.cpu_softints ^= 1 << ipl;
    486 	softint_fast_dispatch(cpu->cpu_softlwps[si_level], ipl);
    487 	KASSERT(cpu->cpu_softlwps[si_level]->l_ctxswtch == 0);
    488 	KASSERTMSG(ci->ci_cpl == IPL_HIGH,
    489 	    ("%s: cpl (%d) != HIGH", __func__, ci->ci_cpl));
    490 }
    491 
    492 static inline void
    493 e500_softint(struct cpu_info *ci, struct cpu_softc *cpu, int old_ipl)
    494 {
    495 	const u_int softint_mask = (IPL_SOFTMASK << old_ipl) & IPL_SOFTMASK;
    496 	u_int softints;
    497 
    498 	KASSERT(ci->ci_mtx_count == 0);
    499 	KASSERT(ci->ci_cpl == IPL_HIGH);
    500 	while ((softints = (ci->ci_data.cpu_softints & softint_mask)) != 0) {
    501 		KASSERT(old_ipl < IPL_SOFTSERIAL);
    502 		if (softints & (1 << IPL_SOFTSERIAL)) {
    503 			e500_softint_deliver(ci, cpu, IPL_SOFTSERIAL,
    504 			    SOFTINT_SERIAL);
    505 			continue;
    506 		}
    507 		KASSERT(old_ipl < IPL_SOFTNET);
    508 		if (softints & (1 << IPL_SOFTNET)) {
    509 			e500_softint_deliver(ci, cpu, IPL_SOFTNET,
    510 			    SOFTINT_NET);
    511 			continue;
    512 		}
    513 		KASSERT(old_ipl < IPL_SOFTBIO);
    514 		if (softints & (1 << IPL_SOFTBIO)) {
    515 			e500_softint_deliver(ci, cpu, IPL_SOFTBIO,
    516 			    SOFTINT_BIO);
    517 			continue;
    518 		}
    519 		KASSERT(old_ipl < IPL_SOFTCLOCK);
    520 		if (softints & (1 << IPL_SOFTCLOCK)) {
    521 			e500_softint_deliver(ci, cpu, IPL_SOFTCLOCK,
    522 			    SOFTINT_CLOCK);
    523 			continue;
    524 		}
    525 	}
    526 }
    527 #endif /* __HAVE_FAST_SOFTINTS */
    528 
    529 static inline void
    530 e500_splset(struct cpu_info *ci, int ipl)
    531 {
    532 	struct cpu_softc * const cpu = ci->ci_softc;
    533 	//KASSERT(!cpu_intr_p() || ipl >= IPL_VM);
    534 	KASSERT((curlwp->l_pflag & LP_INTR) == 0 || ipl != IPL_NONE);
    535 #if 0
    536 	u_int ctpr = ipl;
    537 	KASSERT(openpic_read(cpu, OPENPIC_CTPR) == ci->ci_cpl);
    538 #elif 0
    539 	u_int old_ctpr = (ci->ci_cpl >= IPL_VM ? 15 : ci->ci_cpl);
    540 	u_int ctpr = (ipl >= IPL_VM ? 15 : ipl);
    541 	KASSERT(openpic_read(cpu, OPENPIC_CTPR) == old_ctpr);
    542 #else
    543 	u_int old_ctpr = IPL2CTPR(ci->ci_cpl);
    544 	u_int ctpr = IPL2CTPR(ipl);
    545 	KASSERT(openpic_read(cpu, OPENPIC_CTPR) == old_ctpr);
    546 #endif
    547 	openpic_write(cpu, OPENPIC_CTPR, ctpr);
    548 	KASSERT(openpic_read(cpu, OPENPIC_CTPR) == ctpr);
    549 	ci->ci_cpl = ipl;
    550 }
    551 
    552 static void
    553 e500_spl0(void)
    554 {
    555 	struct cpu_info * const ci = curcpu();
    556 
    557 	wrtee(0);
    558 
    559 #ifdef __HAVE_FAST_SOFTINTS
    560 	if (__predict_false(ci->ci_data.cpu_softints != 0)) {
    561 		e500_splset(ci, IPL_HIGH);
    562 		e500_softint(ci, ci->ci_softc, IPL_NONE);
    563 	}
    564 #endif /* __HAVE_FAST_SOFTINTS */
    565 	e500_splset(ci, IPL_NONE);
    566 
    567 	wrtee(PSL_EE);
    568 }
    569 
    570 static void
    571 e500_splx(int ipl)
    572 {
    573 	struct cpu_info * const ci = curcpu();
    574 	const int old_ipl = ci->ci_cpl;
    575 
    576 	KASSERT(mfmsr() & PSL_CE);
    577 
    578 	if (ipl == old_ipl)
    579 		return;
    580 
    581 	if (__predict_false(ipl > old_ipl)) {
    582 		printf("%s: %p: cpl=%u: ignoring splx(%u) to raise ipl\n",
    583 		    __func__, __builtin_return_address(0), old_ipl, ipl);
    584 		if (old_ipl == IPL_NONE)
    585 			Debugger();
    586 	}
    587 
    588 	// const
    589 	register_t msr = wrtee(0);
    590 #ifdef __HAVE_FAST_SOFTINTS
    591 	const u_int softints = (ci->ci_data.cpu_softints << ipl) & IPL_SOFTMASK;
    592 	if (__predict_false(softints != 0)) {
    593 		e500_splset(ci, IPL_HIGH);
    594 		e500_softint(ci, ci->ci_softc, ipl);
    595 	}
    596 #endif /* __HAVE_FAST_SOFTINTS */
    597 	e500_splset(ci, ipl);
    598 #if 1
    599 	if (ipl < IPL_VM && old_ipl >= IPL_VM)
    600 		msr = PSL_EE;
    601 #endif
    602 	wrtee(msr);
    603 }
    604 
    605 static int
    606 e500_splraise(int ipl)
    607 {
    608 	struct cpu_info * const ci = curcpu();
    609 	const int old_ipl = ci->ci_cpl;
    610 
    611 	KASSERT(mfmsr() & PSL_CE);
    612 
    613 	if (old_ipl < ipl) {
    614 		//const
    615 		register_t msr = wrtee(0);
    616 		e500_splset(ci, ipl);
    617 #if 1
    618 		if (old_ipl < IPL_VM && ipl >= IPL_VM)
    619 			msr = 0;
    620 #endif
    621 		wrtee(msr);
    622 	} else if (ipl == IPL_NONE) {
    623 		panic("%s: %p: cpl=%u: attempt to splraise(IPL_NONE)",
    624 		    __func__, __builtin_return_address(0), old_ipl);
    625 #if 0
    626 	} else if (old_ipl > ipl) {
    627 		printf("%s: %p: cpl=%u: ignoring splraise(%u) to lower ipl\n",
    628 		    __func__, __builtin_return_address(0), old_ipl, ipl);
    629 #endif
    630 	}
    631 
    632 	return old_ipl;
    633 }
    634 
    635 #ifdef __HAVE_FAST_SOFTINTS
    636 static void
    637 e500_softint_init_md(lwp_t *l, u_int si_level, uintptr_t *machdep_p)
    638 {
    639 	struct cpu_info * const ci = l->l_cpu;
    640 	struct cpu_softc * const cpu = ci->ci_softc;
    641 
    642 	*machdep_p = 1 << SOFTINT2IPL(si_level);
    643 	KASSERT(*machdep_p & IPL_SOFTMASK);
    644 	cpu->cpu_softlwps[si_level] = l;
    645 }
    646 
    647 static void
    648 e500_softint_trigger(uintptr_t machdep)
    649 {
    650 	struct cpu_info * const ci = curcpu();
    651 
    652 	atomic_or_uint(&ci->ci_data.cpu_softints, machdep);
    653 	if (machdep == (1 << IPL_SOFTBIO))
    654 		printf("%s(%u): cpl=%u\n", __func__, machdep, ci->ci_cpl);
    655 }
    656 #endif /* __HAVE_FAST_SOFTINTS */
    657 
    658 static int
    659 e500_intr_spurious(void *arg)
    660 {
    661 	return 0;
    662 }
    663 
    664 static bool
    665 e500_intr_irq_info_get(struct cpu_info *ci, u_int irq, int ipl, int ist,
    666 	struct e500_intr_irq_info *ii)
    667 {
    668 	const struct e500_intr_info * const info = &e500_intr_info;
    669 	bool ok;
    670 
    671 #if DEBUG > 2
    672 	printf("%s(%p,irq=%u,ipl=%u,ist=%u,%p)\n", __func__, ci, irq, ipl, ist, ii);
    673 #endif
    674 
    675 	if (ipl < IPL_VM || ipl > IPL_HIGH) {
    676 #if DEBUG > 2
    677 		printf("%s:%d ipl=%u\n", __func__, __LINE__, ipl);
    678 #endif
    679 		return false;
    680 	}
    681 
    682 	if (ist <= IST_NONE || ist >= IST_MAX) {
    683 #if DEBUG > 2
    684 		printf("%s:%d ist=%u\n", __func__, __LINE__, ist);
    685 #endif
    686 		return false;
    687 	}
    688 
    689 	ii->irq_vector = irq + info->ii_ist_vectors[ist];
    690 	if (IST_PERCPU_P(ist))
    691 		ii->irq_vector += ci->ci_cpuid * info->ii_percpu_sources;
    692 
    693 	switch (ist) {
    694 	default:
    695 		ii->irq_vpr = OPENPIC_EIVPR(irq);
    696 		ii->irq_dr  = OPENPIC_EIDR(irq);
    697 		ok = irq < info->ii_external_sources
    698 		    && (ist == IST_EDGE
    699 			|| ist == IST_LEVEL_LOW
    700 			|| ist == IST_LEVEL_HIGH);
    701 		break;
    702 	case IST_ONCHIP:
    703 		ii->irq_vpr = OPENPIC_IIVPR(irq);
    704 		ii->irq_dr  = OPENPIC_IIDR(irq);
    705 		ok = irq < 32 * __arraycount(info->ii_onchip_bitmap);
    706 #if DEBUG > 2
    707 		printf("%s: irq=%u: ok=%u\n", __func__, irq, ok);
    708 #endif
    709 		ok = ok && (info->ii_onchip_bitmap[irq/32] & (1 << (irq & 31)));
    710 #if DEBUG > 2
    711 		printf("%s: %08x%08x -> %08x%08x: ok=%u\n", __func__,
    712 		    irq < 32 ? 0 : (1 << irq), irq < 32 ? (1 << irq) : 0,
    713 		    info->ii_onchip_bitmap[1], info->ii_onchip_bitmap[0],
    714 		    ok);
    715 #endif
    716 		break;
    717 	case IST_MSIGROUP:
    718 		ii->irq_vpr = OPENPIC_MSIVPR(irq);
    719 		ii->irq_dr  = OPENPIC_MSIDR(irq);
    720 		ok = irq < info->ii_msigroup_sources
    721 		    && ipl == IPL_VM;
    722 		break;
    723 	case IST_TIMER:
    724 		ii->irq_vpr = OPENPIC_GTVPR(ci->ci_cpuid, irq);
    725 		ii->irq_dr  = OPENPIC_GTDR(ci->ci_cpuid, irq);
    726 		ok = irq < info->ii_timer_sources;
    727 #if DEBUG > 2
    728 		printf("%s: IST_TIMER irq=%u: ok=%u\n", __func__, irq, ok);
    729 #endif
    730 		break;
    731 	case IST_IPI:
    732 		ii->irq_vpr = OPENPIC_IPIVPR(irq);
    733 		ii->irq_dr  = OPENPIC_IPIDR(irq);
    734 		ok = irq < info->ii_ipi_sources;
    735 		break;
    736 	case IST_MI:
    737 		ii->irq_vpr = OPENPIC_MIVPR(irq);
    738 		ii->irq_dr  = OPENPIC_MIDR(irq);
    739 		ok = irq < info->ii_mi_sources;
    740 		break;
    741 	}
    742 
    743 	return ok;
    744 }
    745 
    746 static const char *
    747 e500_intr_string(int irq, int ist)
    748 {
    749 	struct cpu_info * const ci = curcpu();
    750 	struct cpu_softc * const cpu = ci->ci_softc;
    751 	struct e500_intr_irq_info ii;
    752 
    753 	if (!e500_intr_irq_info_get(ci, irq, IPL_VM, ist, &ii))
    754 		return NULL;
    755 
    756 	return cpu->cpu_evcnt_intrs[ii.irq_vector].ev_name;
    757 }
    758 
    759 static void *
    760 e500_intr_cpu_establish(struct cpu_info *ci, int irq, int ipl, int ist,
    761 	int (*handler)(void *), void *arg)
    762 {
    763 	struct cpu_softc * const cpu = ci->ci_softc;
    764 	struct e500_intr_irq_info ii;
    765 
    766 	KASSERT(ipl >= IPL_VM && ipl <= IPL_HIGH);
    767 	KASSERT(ist > IST_NONE && ist < IST_MAX && ist != IST_MSI);
    768 
    769 	if (!e500_intr_irq_info_get(ci, irq, ipl, ist, &ii)) {
    770 		printf("%s: e500_intr_irq_info_get(%p,%u,%u,%u,%p) failed\n",
    771 		    __func__, ci, irq, ipl, ist, &ii);
    772 		return NULL;
    773 	}
    774 
    775 	struct intr_source * const is = &e500_intr_sources[ii.irq_vector];
    776 	mutex_enter(&e500_intr_lock);
    777 	if (is->is_ipl != IPL_NONE)
    778 		return NULL;
    779 
    780 	is->is_func = handler;
    781 	is->is_arg = arg;
    782 	is->is_ipl = ipl;
    783 	is->is_ist = ist;
    784 	is->is_irq = irq;
    785 	is->is_vpr = ii.irq_vpr;
    786 	is->is_dr = ii.irq_dr;
    787 
    788 	uint32_t vpr = VPR_PRIORITY_MAKE(IPL2CTPR(ipl))
    789 	    | VPR_VECTOR_MAKE(((ii.irq_vector + 1) << 4) | ipl)
    790 	    | (ist == IST_LEVEL_LOW
    791 		? VPR_LEVEL_LOW
    792 		: (ist == IST_LEVEL_HIGH
    793 		    ? VPR_LEVEL_HIGH
    794 		    : (ist == IST_ONCHIP
    795 		      ? VPR_P_HIGH
    796 		      : 0)));
    797 
    798 	/*
    799 	 * All interrupts go to the primary except per-cpu interrupts which get
    800 	 * routed to the appropriate cpu.
    801 	 */
    802 	uint32_t dr = IST_PERCPU_P(ist) ? 1 << ci->ci_cpuid : 1;
    803 
    804 	/*
    805 	 * Update the vector/priority and destination registers keeping the
    806 	 * interrupt masked.
    807 	 */
    808 	const register_t msr = wrtee(0);	/* disable interrupts */
    809 	openpic_write(cpu, ii.irq_vpr, vpr | VPR_MSK);
    810 	openpic_write(cpu, ii.irq_dr, dr);
    811 
    812 	/*
    813 	 * Now unmask the interrupt.
    814 	 */
    815 	openpic_write(cpu, ii.irq_vpr, vpr);
    816 
    817 	wrtee(msr);				/* re-enable interrupts */
    818 
    819 	mutex_exit(&e500_intr_lock);
    820 
    821 	return is;
    822 }
    823 
    824 static void *
    825 e500_intr_establish(int irq, int ipl, int ist,
    826 	int (*handler)(void *), void *arg)
    827 {
    828 	return e500_intr_cpu_establish(curcpu(), irq, ipl, ist, handler, arg);
    829 }
    830 
    831 static void
    832 e500_intr_disestablish(void *vis)
    833 {
    834 	struct cpu_softc * const cpu = curcpu()->ci_softc;
    835 	struct intr_source * const is = vis;
    836 	struct e500_intr_irq_info ii;
    837 
    838 	KASSERT(e500_intr_sources <= is);
    839 	KASSERT(is < e500_intr_last_source);
    840 	KASSERT(!cpu_intr_p());
    841 
    842 	bool ok = e500_intr_irq_info_get(curcpu(), is->is_irq, is->is_ipl,
    843 	    is->is_ist, &ii);
    844 	(void)ok;	/* appease gcc */
    845 	KASSERT(ok);
    846 	KASSERT(is - e500_intr_sources == ii.irq_vector);
    847 
    848 	mutex_enter(&e500_intr_lock);
    849 	/*
    850 	 * Mask the source using the mask (MSK) bit in the vector/priority reg.
    851 	 */
    852 	uint32_t vpr = openpic_read(cpu, ii.irq_vpr);
    853 	openpic_write(cpu, ii.irq_vpr, VPR_MSK | vpr);
    854 
    855 	/*
    856 	 * Wait for the Activity (A) bit for the source to be cleared.
    857 	 */
    858 	while (openpic_read(cpu, ii.irq_vpr) & VPR_A)
    859 		;
    860 
    861 	/*
    862 	 * Now the source can be modified.
    863 	 */
    864 	openpic_write(cpu, ii.irq_dr, 0);		/* stop delivery */
    865 	openpic_write(cpu, ii.irq_vpr, VPR_MSK);	/* mask/reset it */
    866 
    867 	*is = (struct intr_source)INTR_SOURCE_INITIALIZER;
    868 
    869 	mutex_exit(&e500_intr_lock);
    870 }
    871 
    872 static void
    873 e500_critintr(struct trapframe *tf)
    874 {
    875 	panic("%s: srr0/srr1=%#lx/%#lx", __func__, tf->tf_srr0, tf->tf_srr1);
    876 }
    877 
    878 static void
    879 e500_decrintr(struct trapframe *tf)
    880 {
    881 	panic("%s: srr0/srr1=%#lx/%#lx", __func__, tf->tf_srr0, tf->tf_srr1);
    882 }
    883 
    884 static void
    885 e500_fitintr(struct trapframe *tf)
    886 {
    887 	panic("%s: srr0/srr1=%#lx/%#lx", __func__, tf->tf_srr0, tf->tf_srr1);
    888 }
    889 
    890 static void
    891 e500_wdogintr(struct trapframe *tf)
    892 {
    893 	mtspr(SPR_TSR, TSR_ENW|TSR_WIS);
    894 	panic("%s: tf=%p tb=%"PRId64" srr0/srr1=%#lx/%#lx", __func__, tf,
    895 	    mftb(), tf->tf_srr0, tf->tf_srr1);
    896 }
    897 
    898 static void
    899 e500_extintr(struct trapframe *tf)
    900 {
    901 	struct cpu_info * const ci = curcpu();
    902 	struct cpu_softc * const cpu = ci->ci_softc;
    903 	const int old_ipl = ci->ci_cpl;
    904 
    905 	KASSERT(mfmsr() & PSL_CE);
    906 
    907 #if 0
    908 //	printf("%s(%p): idepth=%d enter\n", __func__, tf, ci->ci_idepth);
    909 	if ((register_t)tf >= (register_t)curlwp->l_addr + USPACE
    910 	    || (register_t)tf < (register_t)curlwp->l_addr + NBPG) {
    911 		printf("%s(entry): pid %d.%d (%s): srr0/srr1=%#lx/%#lx: invalid tf addr %p\n",
    912 		    __func__, curlwp->l_proc->p_pid, curlwp->l_lid,
    913 		    curlwp->l_proc->p_comm, tf->tf_srr0, tf->tf_srr1, tf);
    914 	}
    915 #endif
    916 
    917 
    918 	ci->ci_data.cpu_nintr++;
    919 	tf->tf_cf.cf_idepth = ci->ci_idepth++;
    920 	cpu->cpu_pcpls[ci->ci_idepth] = old_ipl;
    921 #if 1
    922 	if (mfmsr() & PSL_EE)
    923 		panic("%s(%p): MSR[EE] is on (%#lx)!", __func__, tf, mfmsr());
    924 	if (old_ipl == IPL_HIGH
    925 	    || IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
    926 		panic("%s(%p): old_ipl(%u) == IPL_HIGH(%u) "
    927 		    "|| old_ipl + %u != OPENPIC_CTPR (%u)",
    928 		    __func__, tf, old_ipl, IPL_HIGH,
    929 		    15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
    930 #else
    931 	if (old_ipl >= IPL_VM)
    932 		panic("%s(%p): old_ipl(%u) >= IPL_VM(%u) CTPR=%u",
    933 		    __func__, tf, old_ipl, IPL_VM, openpic_read(cpu, OPENPIC_CTPR));
    934 #endif
    935 
    936 	for (;;) {
    937 		/*
    938 		 * Find out the pending interrupt.
    939 		 */
    940 	if (mfmsr() & PSL_EE)
    941 		panic("%s(%p): MSR[EE] turned on (%#lx)!", __func__, tf, mfmsr());
    942 		if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
    943 			panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
    944 			    __func__, tf, __LINE__, old_ipl,
    945 			    15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
    946 		const uint32_t iack = openpic_read(cpu, OPENPIC_IACK);
    947 		const int ipl = iack & 0xf;
    948 		const int irq = (iack >> 4) - 1;
    949 #if 0
    950 		printf("%s: iack=%d ipl=%d irq=%d <%s>\n",
    951 		    __func__, iack, ipl, irq,
    952 		    (iack != IRQ_SPURIOUS ?
    953 			cpu->cpu_evcnt_intrs[irq].ev_name : "spurious"));
    954 #endif
    955 		if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
    956 			panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
    957 			    __func__, tf, __LINE__, old_ipl,
    958 			    15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
    959 		if (iack == IRQ_SPURIOUS)
    960 			break;
    961 
    962 		struct intr_source * const is = &e500_intr_sources[irq];
    963 		if (__predict_true(is < e500_intr_last_source)) {
    964 			/*
    965 			 * Timer interrupts get their argument overriden with
    966 			 * the pointer to the trapframe.
    967 			 */
    968 			KASSERT(is->is_ipl == ipl);
    969 			void *arg = (is->is_ist == IST_TIMER ? tf : is->is_arg);
    970 			if (is->is_ipl <= old_ipl)
    971 				panic("%s(%p): %s (%u): is->is_ipl (%u) <= old_ipl (%u)\n",
    972 				    __func__, tf,
    973 				    cpu->cpu_evcnt_intrs[irq].ev_name, irq,
    974 				    is->is_ipl, old_ipl);
    975 			KASSERT(is->is_ipl > old_ipl);
    976 			e500_splset(ci, is->is_ipl);	/* change IPL */
    977 			if (__predict_false(is->is_func == NULL)) {
    978 				aprint_error_dev(ci->ci_dev,
    979 				    "interrupt from unestablished irq %d\n",
    980 				    irq);
    981 			} else {
    982 				int (*func)(void *) = is->is_func;
    983 				wrtee(PSL_EE);
    984 				int rv = (*func)(arg);
    985 				wrtee(0);
    986 #if DEBUG > 2
    987 				printf("%s: %s handler %p(%p) returned %d\n",
    988 				    __func__,
    989 				    cpu->cpu_evcnt_intrs[irq].ev_name,
    990 				    func, arg, rv);
    991 #endif
    992 				if (rv == 0)
    993 					cpu->cpu_evcnt_spurious_intr.ev_count++;
    994 			}
    995 			e500_splset(ci, old_ipl);	/* restore IPL */
    996 			cpu->cpu_evcnt_intrs[irq].ev_count++;
    997 		} else {
    998 			aprint_error_dev(ci->ci_dev,
    999 			    "interrupt from illegal irq %d\n", irq);
   1000 			cpu->cpu_evcnt_spurious_intr.ev_count++;
   1001 		}
   1002 		/*
   1003 		 * If this is a nested interrupt, simply ack it and exit
   1004 		 * because the loop we interrupted will complete looking
   1005 		 * for interrupts.
   1006 		 */
   1007 	if (mfmsr() & PSL_EE)
   1008 		panic("%s(%p): MSR[EE] left on (%#lx)!", __func__, tf, mfmsr());
   1009 		if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
   1010 			panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
   1011 			    __func__, tf, __LINE__, old_ipl,
   1012 			    15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
   1013 
   1014 		openpic_write(cpu, OPENPIC_EOI, 0);
   1015 		if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
   1016 			panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
   1017 			    __func__, tf, __LINE__, old_ipl,
   1018 			    15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
   1019 		if (ci->ci_idepth > 0)
   1020 			break;
   1021 	}
   1022 
   1023 	ci->ci_idepth--;
   1024 
   1025 #ifdef __HAVE_FAST_SOFTINTS
   1026 	/*
   1027 	 * Before exiting, deal with any softints that need to be dealt with.
   1028 	 */
   1029 	const u_int softints = (ci->ci_data.cpu_softints << old_ipl) & IPL_SOFTMASK;
   1030 	if (__predict_false(softints != 0)) {
   1031 		KASSERT(old_ipl < IPL_VM);
   1032 		e500_splset(ci, IPL_HIGH);	/* pop to high */
   1033 		e500_softint(ci, cpu, old_ipl);	/* deal with them */
   1034 		e500_splset(ci, old_ipl);	/* and drop back */
   1035 	}
   1036 #endif /* __HAVE_FAST_SOFTINTS */
   1037 #if 1
   1038 	KASSERT(ci->ci_cpl == old_ipl);
   1039 #else
   1040 	e500_splset(ci, old_ipl);		/* and drop back */
   1041 #endif
   1042 
   1043 //	printf("%s(%p): idepth=%d exit\n", __func__, tf, ci->ci_idepth);
   1044 }
   1045 
   1046 static void
   1047 e500_intr_init(void)
   1048 {
   1049 	struct cpu_info * const ci = curcpu();
   1050 	struct cpu_softc * const cpu = ci->ci_softc;
   1051 	const uint32_t frr = openpic_read(cpu, OPENPIC_FRR);
   1052 	const u_int nirq = FRR_NIRQ_GET(frr) + 1;
   1053 //	const u_int ncpu = FRR_NCPU_GET(frr) + 1;
   1054 	struct intr_source *is;
   1055 	struct e500_intr_info * const ii = &e500_intr_info;
   1056 
   1057 	switch (nirq) {
   1058 	case MPC8548_SOURCES: {
   1059 		CTASSERT(MPC8548_ONCHIPSOURCES == MPC8544_ONCHIPSOURCES);
   1060 		*ii = mpc8548_intr_info;
   1061 		if ((mfspr(SPR_SVR) >> 16) == (SVR_MPC8544v1 >> 16)) {
   1062 			uint32_t bitmap[2] = MPC8548_ONCHIPBITMAP;
   1063 			ii->ii_onchip_bitmap[0] = bitmap[0];
   1064 			ii->ii_onchip_bitmap[1] = bitmap[1];
   1065 			ii->ii_onchip_sources = MPC8544_ONCHIPSOURCES;
   1066 			ii->ii_onchip_intr_names = mpc8544_onchip_intr_names;
   1067 		}
   1068 		break;
   1069 	}
   1070 	case MPC8536_SOURCES:
   1071 		*ii = mpc8536_intr_info;
   1072 		break;
   1073 	case MPC8572_SOURCES:
   1074 		*ii = mpc8572_intr_info;
   1075 		break;
   1076 	default:
   1077 		panic("%s: don't know how to deal with %u interrupt sources",
   1078 		    __func__, nirq);
   1079 	}
   1080 
   1081 	/*
   1082 	 * We need to be in mixed mode.
   1083 	 */
   1084 	openpic_write(cpu, OPENPIC_GCR, GCR_M);
   1085 
   1086 	/*
   1087 	 * Make we and the openpic both agree about the current SPL level.
   1088 	 */
   1089 	e500_splset(ci, ci->ci_cpl);
   1090 
   1091 	/*
   1092 	 * Allow the required number of interrupt sources.
   1093 	 */
   1094 	is = kmem_zalloc(nirq * sizeof(*is), KM_SLEEP);
   1095 	KASSERT(is);
   1096 	e500_intr_sources = is;
   1097 	e500_intr_last_source = is + nirq;
   1098 
   1099 	/*
   1100 	 * Initialize all the external interrupts as active low.
   1101 	 */
   1102 	for (u_int irq = 0; irq < e500_intr_info.ii_external_sources; irq++) {
   1103 		openpic_write(cpu, OPENPIC_EIVPR(irq),
   1104 		    VPR_VECTOR_MAKE(irq) | VPR_LEVEL_LOW);
   1105 	}
   1106 }
   1107 
   1108 static void
   1109 e500_intr_cpu_init(struct cpu_info *ci)
   1110 {
   1111 	struct cpu_softc * const cpu = ci->ci_softc;
   1112 	const char * const xname = device_xname(ci->ci_dev);
   1113 
   1114 	const u_int32_t frr = openpic_read(cpu, OPENPIC_FRR);
   1115 	const u_int nirq = FRR_NIRQ_GET(frr) + 1;
   1116 //	const u_int ncpu = FRR_NCPU_GET(frr) + 1;
   1117 
   1118 	const struct e500_intr_info * const info = &e500_intr_info;
   1119 
   1120 	cpu->cpu_clock_gtbcr = OPENPIC_GTBCR(ci->ci_cpuid, E500_CLOCK_TIMER);
   1121 
   1122 	cpu->cpu_evcnt_intrs =
   1123 	    kmem_zalloc(nirq * sizeof(cpu->cpu_evcnt_intrs[0]), KM_SLEEP);
   1124 	KASSERT(cpu->cpu_evcnt_intrs);
   1125 
   1126 	struct evcnt *evcnt = cpu->cpu_evcnt_intrs;
   1127 	for (size_t j = 0; j < info->ii_external_sources; j++, evcnt++) {
   1128 		const char *name = e500_intr_external_name_lookup(j);
   1129 		evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, NULL, xname, name);
   1130 	}
   1131 	KASSERT(evcnt == cpu->cpu_evcnt_intrs + info->ii_ist_vectors[IST_ONCHIP]);
   1132 	for (size_t j = 0; j < info->ii_onchip_sources; j++, evcnt++) {
   1133 		const char *name = e500_intr_onchip_name_lookup(j);
   1134 		if (name != NULL) {
   1135 			evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
   1136 			    NULL, xname, name);
   1137 		}
   1138 	}
   1139 
   1140 	KASSERT(evcnt == cpu->cpu_evcnt_intrs + info->ii_ist_vectors[IST_MSIGROUP]);
   1141 	for (size_t j = 0; j < info->ii_msigroup_sources; j++, evcnt++) {
   1142 		evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
   1143 		    NULL, xname, e500_msigroup_intr_names[j].in_name);
   1144 	}
   1145 
   1146 	KASSERT(evcnt == cpu->cpu_evcnt_intrs + info->ii_ist_vectors[IST_TIMER]);
   1147 	evcnt += ci->ci_cpuid * info->ii_percpu_sources;
   1148 	for (size_t j = 0; j < info->ii_timer_sources; j++, evcnt++) {
   1149 		evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
   1150 		    NULL, xname, e500_timer_intr_names[j].in_name);
   1151 	}
   1152 
   1153 	for (size_t j = 0; j < info->ii_ipi_sources; j++, evcnt++) {
   1154 		evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
   1155 		    NULL, xname, e500_ipi_intr_names[j].in_name);
   1156 	}
   1157 
   1158 	for (size_t j = 0; j < info->ii_mi_sources; j++, evcnt++) {
   1159 		evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
   1160 		    NULL, xname, e500_mi_intr_names[j].in_name);
   1161 	}
   1162 
   1163 	/*
   1164 	 * Establish interrupt for this CPU.
   1165 	 */
   1166 	if (e500_intr_cpu_establish(ci, E500_CLOCK_TIMER, IPL_CLOCK, IST_TIMER,
   1167 	    e500_clock_intr, NULL) == NULL)
   1168 		panic("%s: failed to establish clock interrupt!", __func__);
   1169 
   1170 	/*
   1171 	 * Enable watchdog interrupts.
   1172 	 */
   1173 	uint32_t tcr = mfspr(SPR_TCR);
   1174 	tcr |= TCR_WIE;
   1175 	mtspr(SPR_TCR, tcr);
   1176 }
   1177