e500_intr.c revision 1.32 1 /* $NetBSD: e500_intr.c,v 1.32 2015/01/23 09:02:42 nonaka 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 #include "opt_mpc85xx.h"
38 #include "opt_multiprocessor.h"
39 #include "opt_ddb.h"
40
41 #define __INTR_PRIVATE
42
43 #include <sys/cdefs.h>
44 __KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.32 2015/01/23 09:02:42 nonaka Exp $");
45
46 #include <sys/param.h>
47 #include <sys/proc.h>
48 #include <sys/intr.h>
49 #include <sys/cpu.h>
50 #include <sys/kmem.h>
51 #include <sys/atomic.h>
52 #include <sys/bus.h>
53 #include <sys/xcall.h>
54 #include <sys/ipi.h>
55 #include <sys/bitops.h>
56
57 #include <uvm/uvm_extern.h>
58
59 #ifdef __HAVE_FAST_SOFTINTS
60 #include <powerpc/softint.h>
61 #endif
62
63 #include <powerpc/spr.h>
64 #include <powerpc/booke/spr.h>
65
66 #include <powerpc/booke/cpuvar.h>
67 #include <powerpc/booke/e500reg.h>
68 #include <powerpc/booke/e500var.h>
69 #include <powerpc/booke/openpicreg.h>
70
71 #define IPL2CTPR(ipl) ((ipl) + 15 - IPL_HIGH)
72 #define CTPR2IPL(ctpr) ((ctpr) - (15 - IPL_HIGH))
73
74 #define IST_PERCPU_P(ist) ((ist) >= IST_TIMER)
75
76 struct e500_intr_irq_info {
77 bus_addr_t irq_vpr;
78 bus_addr_t irq_dr;
79 u_int irq_vector;
80 };
81
82 struct intr_source {
83 int (*is_func)(void *);
84 void *is_arg;
85 int8_t is_ipl;
86 uint8_t is_ist;
87 uint8_t is_irq;
88 uint8_t is_refcnt;
89 bus_size_t is_vpr;
90 bus_size_t is_dr;
91 };
92
93 #define INTR_SOURCE_INITIALIZER \
94 { .is_func = e500_intr_spurious, .is_arg = NULL, \
95 .is_irq = -1, .is_ipl = IPL_NONE, .is_ist = IST_NONE, }
96
97 struct e500_intr_name {
98 uint8_t in_irq;
99 const char in_name[15];
100 };
101
102 static const struct e500_intr_name e500_onchip_intr_names[] = {
103 { ISOURCE_L2, "l2" },
104 { ISOURCE_ECM, "ecm" },
105 { ISOURCE_DDR, "ddr" },
106 { ISOURCE_LBC, "lbc" },
107 { ISOURCE_DMA_CHAN1, "dma-chan1" },
108 { ISOURCE_DMA_CHAN2, "dma-chan2" },
109 { ISOURCE_DMA_CHAN3, "dma-chan3" },
110 { ISOURCE_DMA_CHAN4, "dma-chan4" },
111 { ISOURCE_PCI1, "pci1" },
112 { ISOURCE_PCIEX2, "pcie2" },
113 { ISOURCE_PCIEX , "pcie1" },
114 { ISOURCE_PCIEX3, "pcie3" },
115 { ISOURCE_USB1, "usb1" },
116 { ISOURCE_ETSEC1_TX, "etsec1-tx" },
117 { ISOURCE_ETSEC1_RX, "etsec1-rx" },
118 { ISOURCE_ETSEC3_TX, "etsec3-tx" },
119 { ISOURCE_ETSEC3_RX, "etsec3-rx" },
120 { ISOURCE_ETSEC3_ERR, "etsec3-err" },
121 { ISOURCE_ETSEC1_ERR, "etsec1-err" },
122 { ISOURCE_ETSEC2_TX, "etsec2-tx" },
123 { ISOURCE_ETSEC2_RX, "etsec2-rx" },
124 { ISOURCE_ETSEC4_TX, "etsec4-tx" },
125 { ISOURCE_ETSEC4_RX, "etsec4-rx" },
126 { ISOURCE_ETSEC4_ERR, "etsec4-err" },
127 { ISOURCE_ETSEC2_ERR, "etsec2-err" },
128 { ISOURCE_DUART, "duart" },
129 { ISOURCE_I2C, "i2c" },
130 { ISOURCE_PERFMON, "perfmon" },
131 { ISOURCE_SECURITY1, "sec1" },
132 { ISOURCE_GPIO, "gpio" },
133 { ISOURCE_SRIO_EWPU, "srio-ewpu" },
134 { ISOURCE_SRIO_ODBELL, "srio-odbell" },
135 { ISOURCE_SRIO_IDBELL, "srio-idbell" },
136 { ISOURCE_SRIO_OMU1, "srio-omu1" },
137 { ISOURCE_SRIO_IMU1, "srio-imu1" },
138 { ISOURCE_SRIO_OMU2, "srio-omu2" },
139 { ISOURCE_SRIO_IMU2, "srio-imu2" },
140 { ISOURCE_SECURITY2, "sec2" },
141 { ISOURCE_SPI, "spi" },
142 { ISOURCE_ETSEC1_PTP, "etsec1-ptp" },
143 { ISOURCE_ETSEC2_PTP, "etsec2-ptp" },
144 { ISOURCE_ETSEC3_PTP, "etsec3-ptp" },
145 { ISOURCE_ETSEC4_PTP, "etsec4-ptp" },
146 { ISOURCE_ESDHC, "esdhc" },
147 { 0, "" },
148 };
149
150 const struct e500_intr_name default_external_intr_names[] = {
151 { 0, "" },
152 };
153
154 static const struct e500_intr_name e500_msigroup_intr_names[] = {
155 { 0, "msigroup0" },
156 { 1, "msigroup1" },
157 { 2, "msigroup2" },
158 { 3, "msigroup3" },
159 { 4, "msigroup4" },
160 { 5, "msigroup5" },
161 { 6, "msigroup6" },
162 { 7, "msigroup7" },
163 { 0, "" },
164 };
165
166 static const struct e500_intr_name e500_timer_intr_names[] = {
167 { 0, "timer0" },
168 { 1, "timer1" },
169 { 2, "timer2" },
170 { 3, "timer3" },
171 { 0, "" },
172 };
173
174 static const struct e500_intr_name e500_ipi_intr_names[] = {
175 { 0, "ipi0" },
176 { 1, "ipi1" },
177 { 2, "ipi2" },
178 { 3, "ipi3" },
179 { 0, "" },
180 };
181
182 static const struct e500_intr_name e500_mi_intr_names[] = {
183 { 0, "mi0" },
184 { 1, "mi1" },
185 { 2, "mi2" },
186 { 3, "mi3" },
187 { 0, "" },
188 };
189
190 struct e500_intr_info {
191 u_int ii_external_sources;
192 uint32_t ii_onchip_bitmap[2];
193 u_int ii_onchip_sources;
194 u_int ii_msigroup_sources;
195 u_int ii_ipi_sources; /* per-cpu */
196 u_int ii_timer_sources; /* per-cpu */
197 u_int ii_mi_sources; /* per-cpu */
198 u_int ii_percpu_sources;
199 const struct e500_intr_name *ii_external_intr_names;
200 const struct e500_intr_name *ii_onchip_intr_names;
201 u_int8_t ii_ist_vectors[IST_MAX+1];
202 };
203
204 static kmutex_t e500_intr_lock __cacheline_aligned;
205 static struct e500_intr_info e500_intr_info;
206
207 #define INTR_INFO_DECL(lc_chip, UC_CHIP) \
208 static const struct e500_intr_info lc_chip##_intr_info = { \
209 .ii_external_sources = UC_CHIP ## _EXTERNALSOURCES, \
210 .ii_onchip_bitmap = UC_CHIP ## _ONCHIPBITMAP, \
211 .ii_onchip_sources = UC_CHIP ## _ONCHIPSOURCES, \
212 .ii_msigroup_sources = UC_CHIP ## _MSIGROUPSOURCES, \
213 .ii_timer_sources = UC_CHIP ## _TIMERSOURCES, \
214 .ii_ipi_sources = UC_CHIP ## _IPISOURCES, \
215 .ii_mi_sources = UC_CHIP ## _MISOURCES, \
216 .ii_percpu_sources = UC_CHIP ## _TIMERSOURCES \
217 + UC_CHIP ## _IPISOURCES + UC_CHIP ## _MISOURCES, \
218 .ii_external_intr_names = lc_chip ## _external_intr_names, \
219 .ii_onchip_intr_names = lc_chip ## _onchip_intr_names, \
220 .ii_ist_vectors = { \
221 [IST_NONE] = ~0, \
222 [IST_EDGE] = 0, \
223 [IST_LEVEL_LOW] = 0, \
224 [IST_LEVEL_HIGH] = 0, \
225 [IST_PULSE] = 0, \
226 [IST_ONCHIP] = UC_CHIP ## _EXTERNALSOURCES, \
227 [IST_MSIGROUP] = UC_CHIP ## _EXTERNALSOURCES \
228 + UC_CHIP ## _ONCHIPSOURCES, \
229 [IST_TIMER] = UC_CHIP ## _EXTERNALSOURCES \
230 + UC_CHIP ## _ONCHIPSOURCES \
231 + UC_CHIP ## _MSIGROUPSOURCES, \
232 [IST_IPI] = UC_CHIP ## _EXTERNALSOURCES \
233 + UC_CHIP ## _ONCHIPSOURCES \
234 + UC_CHIP ## _MSIGROUPSOURCES \
235 + UC_CHIP ## _TIMERSOURCES, \
236 [IST_MI] = UC_CHIP ## _EXTERNALSOURCES \
237 + UC_CHIP ## _ONCHIPSOURCES \
238 + UC_CHIP ## _MSIGROUPSOURCES \
239 + UC_CHIP ## _TIMERSOURCES \
240 + UC_CHIP ## _IPISOURCES, \
241 [IST_MAX] = UC_CHIP ## _EXTERNALSOURCES \
242 + UC_CHIP ## _ONCHIPSOURCES \
243 + UC_CHIP ## _MSIGROUPSOURCES \
244 + UC_CHIP ## _TIMERSOURCES \
245 + UC_CHIP ## _IPISOURCES \
246 + UC_CHIP ## _MISOURCES, \
247 }, \
248 }
249
250 #ifdef MPC8536
251 #define mpc8536_external_intr_names default_external_intr_names
252 const struct e500_intr_name mpc8536_onchip_intr_names[] = {
253 { ISOURCE_SATA2, "sata2" },
254 { ISOURCE_USB2, "usb2" },
255 { ISOURCE_USB3, "usb3" },
256 { ISOURCE_SATA1, "sata1" },
257 { 0, "" },
258 };
259
260 INTR_INFO_DECL(mpc8536, MPC8536);
261 #endif
262
263 #ifdef MPC8544
264 #define mpc8544_external_intr_names default_external_intr_names
265 const struct e500_intr_name mpc8544_onchip_intr_names[] = {
266 { 0, "" },
267 };
268
269 INTR_INFO_DECL(mpc8544, MPC8544);
270 #endif
271 #ifdef MPC8548
272 #define mpc8548_external_intr_names default_external_intr_names
273 const struct e500_intr_name mpc8548_onchip_intr_names[] = {
274 { ISOURCE_PCI1, "pci1" },
275 { ISOURCE_PCI2, "pci2" },
276 { 0, "" },
277 };
278
279 INTR_INFO_DECL(mpc8548, MPC8548);
280 #endif
281 #ifdef MPC8555
282 #define mpc8555_external_intr_names default_external_intr_names
283 const struct e500_intr_name mpc8555_onchip_intr_names[] = {
284 { ISOURCE_PCI2, "pci2" },
285 { ISOURCE_CPM, "CPM" },
286 { 0, "" },
287 };
288
289 INTR_INFO_DECL(mpc8555, MPC8555);
290 #endif
291 #ifdef MPC8568
292 #define mpc8568_external_intr_names default_external_intr_names
293 const struct e500_intr_name mpc8568_onchip_intr_names[] = {
294 { ISOURCE_QEB_LOW, "QEB low" },
295 { ISOURCE_QEB_PORT, "QEB port" },
296 { ISOURCE_QEB_IECC, "QEB iram ecc" },
297 { ISOURCE_QEB_MUECC, "QEB ram ecc" },
298 { ISOURCE_TLU1, "tlu1" },
299 { ISOURCE_QEB_HIGH, "QEB high" },
300 { 0, "" },
301 };
302
303 INTR_INFO_DECL(mpc8568, MPC8568);
304 #endif
305 #ifdef MPC8572
306 #define mpc8572_external_intr_names default_external_intr_names
307 const struct e500_intr_name mpc8572_onchip_intr_names[] = {
308 { ISOURCE_PCIEX3_MPC8572, "pcie3" },
309 { ISOURCE_FEC, "fec" },
310 { ISOURCE_PME_GENERAL, "pme" },
311 { ISOURCE_TLU1, "tlu1" },
312 { ISOURCE_TLU2, "tlu2" },
313 { ISOURCE_PME_CHAN1, "pme-chan1" },
314 { ISOURCE_PME_CHAN2, "pme-chan2" },
315 { ISOURCE_PME_CHAN3, "pme-chan3" },
316 { ISOURCE_PME_CHAN4, "pme-chan4" },
317 { ISOURCE_DMA2_CHAN1, "dma2-chan1" },
318 { ISOURCE_DMA2_CHAN2, "dma2-chan2" },
319 { ISOURCE_DMA2_CHAN3, "dma2-chan3" },
320 { ISOURCE_DMA2_CHAN4, "dma2-chan4" },
321 { 0, "" },
322 };
323
324 INTR_INFO_DECL(mpc8572, MPC8572);
325 #endif
326
327 #ifdef P1025
328 #define p1025_external_intr_names default_external_intr_names
329 const struct e500_intr_name p1025_onchip_intr_names[] = {
330 { ISOURCE_PCIEX3_MPC8572, "pcie3" },
331 { ISOURCE_ETSEC1_G1_TX, "etsec1-g1-tx" },
332 { ISOURCE_ETSEC1_G1_RX, "etsec1-g1-rx" },
333 { ISOURCE_ETSEC1_G1_ERR, "etsec1-g1-error" },
334 { ISOURCE_ETSEC2_G1_TX, "etsec2-g1-tx" },
335 { ISOURCE_ETSEC2_G1_RX, "etsec2-g1-rx" },
336 { ISOURCE_ETSEC2_G1_ERR, "etsec2-g1-error" },
337 { ISOURCE_ETSEC3_G1_TX, "etsec3-g1-tx" },
338 { ISOURCE_ETSEC3_G1_RX, "etsec3-g1-rx" },
339 { ISOURCE_ETSEC3_G1_ERR, "etsec3-g1-error" },
340 { ISOURCE_QEB_MUECC, "qeb-low" },
341 { ISOURCE_QEB_HIGH, "qeb-crit" },
342 { ISOURCE_DMA2_CHAN1, "dma2-chan1" },
343 { ISOURCE_DMA2_CHAN2, "dma2-chan2" },
344 { ISOURCE_DMA2_CHAN3, "dma2-chan3" },
345 { ISOURCE_DMA2_CHAN4, "dma2-chan4" },
346 { 0, "" },
347 };
348
349 INTR_INFO_DECL(p1025, P1025);
350 #endif
351
352 #ifdef P2020
353 #define p20x0_external_intr_names default_external_intr_names
354 const struct e500_intr_name p20x0_onchip_intr_names[] = {
355 { ISOURCE_PCIEX3_MPC8572, "pcie3" },
356 { ISOURCE_DMA2_CHAN1, "dma2-chan1" },
357 { ISOURCE_DMA2_CHAN2, "dma2-chan2" },
358 { ISOURCE_DMA2_CHAN3, "dma2-chan3" },
359 { ISOURCE_DMA2_CHAN4, "dma2-chan4" },
360 { 0, "" },
361 };
362
363 INTR_INFO_DECL(p20x0, P20x0);
364 #endif
365
366 #ifdef P1023
367 #define p1023_external_intr_names default_external_intr_names
368 const struct e500_intr_name p1023_onchip_intr_names[] = {
369 { ISOURCE_FMAN, "fman" },
370 { ISOURCE_MDIO, "mdio" },
371 { ISOURCE_QMAN0, "qman0" },
372 { ISOURCE_BMAN0, "bman0" },
373 { ISOURCE_QMAN1, "qman1" },
374 { ISOURCE_BMAN1, "bman1" },
375 { ISOURCE_QMAN2, "qman2" },
376 { ISOURCE_BMAN2, "bman2" },
377 { ISOURCE_SECURITY2_P1023, "sec2" },
378 { ISOURCE_SEC_GENERAL, "sec-general" },
379 { ISOURCE_DMA2_CHAN1, "dma2-chan1" },
380 { ISOURCE_DMA2_CHAN2, "dma2-chan2" },
381 { ISOURCE_DMA2_CHAN3, "dma2-chan3" },
382 { ISOURCE_DMA2_CHAN4, "dma2-chan4" },
383 { 0, "" },
384 };
385
386 INTR_INFO_DECL(p1023, P1023);
387 #endif
388
389 static const char ist_names[][12] = {
390 [IST_NONE] = "none",
391 [IST_EDGE] = "edge",
392 [IST_LEVEL_LOW] = "level-",
393 [IST_LEVEL_HIGH] = "level+",
394 [IST_PULSE] = "pulse",
395 [IST_MSI] = "msi",
396 [IST_ONCHIP] = "onchip",
397 [IST_MSIGROUP] = "msigroup",
398 [IST_TIMER] = "timer",
399 [IST_IPI] = "ipi",
400 [IST_MI] = "msgint",
401 };
402
403 static struct intr_source *e500_intr_sources;
404 static const struct intr_source *e500_intr_last_source;
405
406 static void *e500_intr_establish(int, int, int, int (*)(void *), void *);
407 static void e500_intr_disestablish(void *);
408 static void e500_intr_cpu_attach(struct cpu_info *ci);
409 static void e500_intr_cpu_hatch(struct cpu_info *ci);
410 static void e500_intr_cpu_send_ipi(cpuid_t, uintptr_t);
411 static void e500_intr_init(void);
412 static void e500_intr_init_precpu(void);
413 static const char *e500_intr_string(int, int, char *, size_t);
414 static const char *e500_intr_typename(int);
415 static void e500_critintr(struct trapframe *tf);
416 static void e500_decrintr(struct trapframe *tf);
417 static void e500_extintr(struct trapframe *tf);
418 static void e500_fitintr(struct trapframe *tf);
419 static void e500_wdogintr(struct trapframe *tf);
420 static void e500_spl0(void);
421 static int e500_splraise(int);
422 static void e500_splx(int);
423
424 const struct intrsw e500_intrsw = {
425 .intrsw_establish = e500_intr_establish,
426 .intrsw_disestablish = e500_intr_disestablish,
427 .intrsw_init = e500_intr_init,
428 .intrsw_cpu_attach = e500_intr_cpu_attach,
429 .intrsw_cpu_hatch = e500_intr_cpu_hatch,
430 .intrsw_cpu_send_ipi = e500_intr_cpu_send_ipi,
431 .intrsw_string = e500_intr_string,
432 .intrsw_typename = e500_intr_typename,
433
434 .intrsw_critintr = e500_critintr,
435 .intrsw_decrintr = e500_decrintr,
436 .intrsw_extintr = e500_extintr,
437 .intrsw_fitintr = e500_fitintr,
438 .intrsw_wdogintr = e500_wdogintr,
439
440 .intrsw_splraise = e500_splraise,
441 .intrsw_splx = e500_splx,
442 .intrsw_spl0 = e500_spl0,
443
444 #ifdef __HAVE_FAST_SOFTINTS
445 .intrsw_softint_init_md = powerpc_softint_init_md,
446 .intrsw_softint_trigger = powerpc_softint_trigger,
447 #endif
448 };
449
450 static bool wdog_barked;
451
452 static inline uint32_t
453 openpic_read(struct cpu_softc *cpu, bus_size_t offset)
454 {
455
456 return bus_space_read_4(cpu->cpu_bst, cpu->cpu_bsh,
457 OPENPIC_BASE + offset);
458 }
459
460 static inline void
461 openpic_write(struct cpu_softc *cpu, bus_size_t offset, uint32_t val)
462 {
463
464 return bus_space_write_4(cpu->cpu_bst, cpu->cpu_bsh,
465 OPENPIC_BASE + offset, val);
466 }
467
468 static const char *
469 e500_intr_external_name_lookup(int irq)
470 {
471 prop_array_t extirqs = board_info_get_object("external-irqs");
472 prop_string_t irqname = prop_array_get(extirqs, irq);
473 KASSERT(irqname != NULL);
474 KASSERT(prop_object_type(irqname) == PROP_TYPE_STRING);
475
476 return prop_string_cstring_nocopy(irqname);
477 }
478
479 static const char *
480 e500_intr_name_lookup(const struct e500_intr_name *names, int irq)
481 {
482 for (; names->in_name[0] != '\0'; names++) {
483 if (names->in_irq == irq)
484 return names->in_name;
485 }
486
487 return NULL;
488 }
489
490 static const char *
491 e500_intr_onchip_name_lookup(int irq)
492 {
493 const char *name;
494
495 name = e500_intr_name_lookup(e500_intr_info.ii_onchip_intr_names, irq);
496 if (name == NULL)
497 name = e500_intr_name_lookup(e500_onchip_intr_names, irq);
498
499 return name;
500 }
501
502 static inline void
503 e500_splset(struct cpu_info *ci, int ipl)
504 {
505 struct cpu_softc * const cpu = ci->ci_softc;
506
507 KASSERT((curlwp->l_pflag & LP_INTR) == 0 || ipl != IPL_NONE);
508 const u_int ctpr = IPL2CTPR(ipl);
509 KASSERT(openpic_read(cpu, OPENPIC_CTPR) == IPL2CTPR(ci->ci_cpl));
510 openpic_write(cpu, OPENPIC_CTPR, ctpr);
511 KASSERT(openpic_read(cpu, OPENPIC_CTPR) == ctpr);
512 #ifdef DIAGNOSTIC
513 cpu->cpu_spl_tb[ipl][ci->ci_cpl] = mftb();
514 #endif
515 ci->ci_cpl = ipl;
516 }
517
518 static void
519 e500_spl0(void)
520 {
521 wrtee(0);
522
523 struct cpu_info * const ci = curcpu();
524
525 #ifdef __HAVE_FAST_SOFTINTS
526 if (__predict_false(ci->ci_data.cpu_softints != 0)) {
527 e500_splset(ci, IPL_HIGH);
528 wrtee(PSL_EE);
529 powerpc_softint(ci, IPL_NONE,
530 (vaddr_t)__builtin_return_address(0));
531 wrtee(0);
532 }
533 #endif /* __HAVE_FAST_SOFTINTS */
534 e500_splset(ci, IPL_NONE);
535
536 wrtee(PSL_EE);
537 }
538
539 static void
540 e500_splx(int ipl)
541 {
542 struct cpu_info * const ci = curcpu();
543 const int old_ipl = ci->ci_cpl;
544
545 /* if we paniced because of watchdog, PSL_CE will be clear. */
546 KASSERT(wdog_barked || (mfmsr() & PSL_CE));
547
548 if (ipl == old_ipl)
549 return;
550
551 if (__predict_false(ipl > old_ipl)) {
552 printf("%s: %p: cpl=%u: ignoring splx(%u) to raise ipl\n",
553 __func__, __builtin_return_address(0), old_ipl, ipl);
554 if (old_ipl == IPL_NONE)
555 Debugger();
556 }
557
558 // const
559 register_t msr = wrtee(0);
560 #ifdef __HAVE_FAST_SOFTINTS
561 const u_int softints = ci->ci_data.cpu_softints & (IPL_SOFTMASK << ipl);
562 if (__predict_false(softints != 0)) {
563 e500_splset(ci, IPL_HIGH);
564 wrtee(msr);
565 powerpc_softint(ci, ipl,
566 (vaddr_t)__builtin_return_address(0));
567 wrtee(0);
568 }
569 #endif /* __HAVE_FAST_SOFTINTS */
570 e500_splset(ci, ipl);
571 #if 1
572 if (ipl < IPL_VM && old_ipl >= IPL_VM)
573 msr = PSL_EE;
574 #endif
575 wrtee(msr);
576 }
577
578 static int
579 e500_splraise(int ipl)
580 {
581 struct cpu_info * const ci = curcpu();
582 const int old_ipl = ci->ci_cpl;
583
584 /* if we paniced because of watchdog, PSL_CE will be clear. */
585 KASSERT(wdog_barked || (mfmsr() & PSL_CE));
586
587 if (old_ipl < ipl) {
588 //const
589 register_t msr = wrtee(0);
590 e500_splset(ci, ipl);
591 #if 0
592 if (old_ipl < IPL_VM && ipl >= IPL_VM)
593 msr = 0;
594 #endif
595 wrtee(msr);
596 } else if (ipl == IPL_NONE) {
597 panic("%s: %p: cpl=%u: attempt to splraise(IPL_NONE)",
598 __func__, __builtin_return_address(0), old_ipl);
599 #if 0
600 } else if (old_ipl > ipl) {
601 printf("%s: %p: cpl=%u: ignoring splraise(%u) to lower ipl\n",
602 __func__, __builtin_return_address(0), old_ipl, ipl);
603 #endif
604 }
605
606 return old_ipl;
607 }
608
609 static int
610 e500_intr_spurious(void *arg)
611 {
612 return 0;
613 }
614
615 static bool
616 e500_intr_irq_info_get(struct cpu_info *ci, u_int irq, int ipl, int ist,
617 struct e500_intr_irq_info *ii)
618 {
619 const struct e500_intr_info * const info = &e500_intr_info;
620 bool ok;
621
622 #if DEBUG > 2
623 printf("%s(%p,irq=%u,ipl=%u,ist=%u,%p)\n", __func__, ci, irq, ipl, ist, ii);
624 #endif
625
626 if (ipl < IPL_VM || ipl > IPL_HIGH) {
627 #if DEBUG > 2
628 printf("%s:%d ipl=%u\n", __func__, __LINE__, ipl);
629 #endif
630 return false;
631 }
632
633 if (ist <= IST_NONE || ist >= IST_MAX) {
634 #if DEBUG > 2
635 printf("%s:%d ist=%u\n", __func__, __LINE__, ist);
636 #endif
637 return false;
638 }
639
640 ii->irq_vector = irq + info->ii_ist_vectors[ist];
641 if (IST_PERCPU_P(ist) && ist != IST_IPI)
642 ii->irq_vector += ci->ci_cpuid * info->ii_percpu_sources;
643
644 switch (ist) {
645 default:
646 ii->irq_vpr = OPENPIC_EIVPR(irq);
647 ii->irq_dr = OPENPIC_EIDR(irq);
648 ok = irq < info->ii_external_sources
649 && (ist == IST_EDGE
650 || ist == IST_LEVEL_LOW
651 || ist == IST_LEVEL_HIGH);
652 break;
653 case IST_PULSE:
654 ok = false;
655 break;
656 case IST_ONCHIP:
657 ii->irq_vpr = OPENPIC_IIVPR(irq);
658 ii->irq_dr = OPENPIC_IIDR(irq);
659 ok = irq < 32 * __arraycount(info->ii_onchip_bitmap);
660 #if DEBUG > 2
661 printf("%s: irq=%u: ok=%u\n", __func__, irq, ok);
662 #endif
663 ok = ok && (info->ii_onchip_bitmap[irq/32] & (1 << (irq & 31)));
664 #if DEBUG > 2
665 printf("%s: %08x%08x -> %08x%08x: ok=%u\n", __func__,
666 irq < 32 ? 0 : (1 << irq), irq < 32 ? (1 << irq) : 0,
667 info->ii_onchip_bitmap[1], info->ii_onchip_bitmap[0],
668 ok);
669 #endif
670 break;
671 case IST_MSIGROUP:
672 ii->irq_vpr = OPENPIC_MSIVPR(irq);
673 ii->irq_dr = OPENPIC_MSIDR(irq);
674 ok = irq < info->ii_msigroup_sources
675 && ipl == IPL_VM;
676 break;
677 case IST_TIMER:
678 ii->irq_vpr = OPENPIC_GTVPR(ci->ci_cpuid, irq);
679 ii->irq_dr = OPENPIC_GTDR(ci->ci_cpuid, irq);
680 ok = irq < info->ii_timer_sources;
681 #if DEBUG > 2
682 printf("%s: IST_TIMER irq=%u: ok=%u\n", __func__, irq, ok);
683 #endif
684 break;
685 case IST_IPI:
686 ii->irq_vpr = OPENPIC_IPIVPR(irq);
687 ii->irq_dr = OPENPIC_IPIDR(irq);
688 ok = irq < info->ii_ipi_sources;
689 break;
690 case IST_MI:
691 ii->irq_vpr = OPENPIC_MIVPR(irq);
692 ii->irq_dr = OPENPIC_MIDR(irq);
693 ok = irq < info->ii_mi_sources;
694 break;
695 }
696
697 return ok;
698 }
699
700 static const char *
701 e500_intr_string(int irq, int ist, char *buf, size_t len)
702 {
703 struct cpu_info * const ci = curcpu();
704 struct cpu_softc * const cpu = ci->ci_softc;
705 struct e500_intr_irq_info ii;
706
707 if (!e500_intr_irq_info_get(ci, irq, IPL_VM, ist, &ii))
708 return NULL;
709
710 strlcpy(buf, cpu->cpu_evcnt_intrs[ii.irq_vector].ev_name, len);
711 return buf;
712 }
713
714 __CTASSERT(__arraycount(ist_names) == IST_MAX);
715
716 static const char *
717 e500_intr_typename(int ist)
718 {
719 if (IST_NONE <= ist && ist < IST_MAX)
720 return ist_names[ist];
721
722 return NULL;
723 }
724
725 static void *
726 e500_intr_cpu_establish(struct cpu_info *ci, int irq, int ipl, int ist,
727 int (*handler)(void *), void *arg)
728 {
729 struct cpu_softc * const cpu = ci->ci_softc;
730 struct e500_intr_irq_info ii;
731
732 KASSERT(ipl >= IPL_VM && ipl <= IPL_HIGH);
733 KASSERT(ist > IST_NONE && ist < IST_MAX && ist != IST_MSI);
734
735 if (!e500_intr_irq_info_get(ci, irq, ipl, ist, &ii)) {
736 printf("%s: e500_intr_irq_info_get(%p,%u,%u,%u,%p) failed\n",
737 __func__, ci, irq, ipl, ist, &ii);
738 return NULL;
739 }
740
741 struct intr_source * const is = &e500_intr_sources[ii.irq_vector];
742 mutex_enter(&e500_intr_lock);
743 if (is->is_ipl != IPL_NONE) {
744 /* XXX IPI0 is shared by all CPU. */
745 if (is->is_ist != IST_IPI ||
746 is->is_irq != irq ||
747 is->is_ipl != ipl ||
748 is->is_ist != ist ||
749 is->is_func != handler ||
750 is->is_arg != arg) {
751 mutex_exit(&e500_intr_lock);
752 return NULL;
753 }
754 }
755
756 is->is_func = handler;
757 is->is_arg = arg;
758 is->is_ipl = ipl;
759 is->is_ist = ist;
760 is->is_irq = irq;
761 is->is_refcnt++;
762 is->is_vpr = ii.irq_vpr;
763 is->is_dr = ii.irq_dr;
764
765 uint32_t vpr = VPR_PRIORITY_MAKE(IPL2CTPR(ipl))
766 | VPR_VECTOR_MAKE(((ii.irq_vector + 1) << 4) | ipl)
767 | (ist == IST_LEVEL_LOW
768 ? VPR_LEVEL_LOW
769 : (ist == IST_LEVEL_HIGH
770 ? VPR_LEVEL_HIGH
771 : (ist == IST_ONCHIP
772 ? VPR_P_HIGH
773 : 0)));
774
775 /*
776 * All interrupts go to the primary except per-cpu interrupts which get
777 * routed to the appropriate cpu.
778 */
779 uint32_t dr = openpic_read(cpu, ii.irq_dr);
780
781 dr |= 1 << (IST_PERCPU_P(ist) ? ci->ci_cpuid : 0);
782
783 /*
784 * Update the vector/priority and destination registers keeping the
785 * interrupt masked.
786 */
787 const register_t msr = wrtee(0); /* disable interrupts */
788 openpic_write(cpu, ii.irq_vpr, vpr | VPR_MSK);
789 openpic_write(cpu, ii.irq_dr, dr);
790
791 /*
792 * Now unmask the interrupt.
793 */
794 openpic_write(cpu, ii.irq_vpr, vpr);
795
796 wrtee(msr); /* re-enable interrupts */
797
798 mutex_exit(&e500_intr_lock);
799
800 return is;
801 }
802
803 static void *
804 e500_intr_establish(int irq, int ipl, int ist,
805 int (*handler)(void *), void *arg)
806 {
807 return e500_intr_cpu_establish(curcpu(), irq, ipl, ist, handler, arg);
808 }
809
810 static void
811 e500_intr_disestablish(void *vis)
812 {
813 struct cpu_softc * const cpu = curcpu()->ci_softc;
814 struct intr_source * const is = vis;
815 struct e500_intr_irq_info ii;
816
817 KASSERT(e500_intr_sources <= is);
818 KASSERT(is < e500_intr_last_source);
819 KASSERT(!cpu_intr_p());
820
821 bool ok = e500_intr_irq_info_get(curcpu(), is->is_irq, is->is_ipl,
822 is->is_ist, &ii);
823 (void)ok; /* appease gcc */
824 KASSERT(ok);
825 KASSERT(is - e500_intr_sources == ii.irq_vector);
826
827 mutex_enter(&e500_intr_lock);
828
829 if (is->is_refcnt-- > 1) {
830 mutex_exit(&e500_intr_lock);
831 return;
832 }
833
834 /*
835 * Mask the source using the mask (MSK) bit in the vector/priority reg.
836 */
837 uint32_t vpr = openpic_read(cpu, ii.irq_vpr);
838 openpic_write(cpu, ii.irq_vpr, VPR_MSK | vpr);
839
840 /*
841 * Wait for the Activity (A) bit for the source to be cleared.
842 */
843 while (openpic_read(cpu, ii.irq_vpr) & VPR_A)
844 ;
845
846 /*
847 * Now the source can be modified.
848 */
849 openpic_write(cpu, ii.irq_dr, 0); /* stop delivery */
850 openpic_write(cpu, ii.irq_vpr, VPR_MSK); /* mask/reset it */
851
852 *is = (struct intr_source)INTR_SOURCE_INITIALIZER;
853
854 mutex_exit(&e500_intr_lock);
855 }
856
857 static void
858 e500_critintr(struct trapframe *tf)
859 {
860 panic("%s: srr0/srr1=%#lx/%#lx", __func__, tf->tf_srr0, tf->tf_srr1);
861 }
862
863 static void
864 e500_decrintr(struct trapframe *tf)
865 {
866 panic("%s: srr0/srr1=%#lx/%#lx", __func__, tf->tf_srr0, tf->tf_srr1);
867 }
868
869 static void
870 e500_fitintr(struct trapframe *tf)
871 {
872 panic("%s: srr0/srr1=%#lx/%#lx", __func__, tf->tf_srr0, tf->tf_srr1);
873 }
874
875 static void
876 e500_wdogintr(struct trapframe *tf)
877 {
878 struct cpu_info * const ci = curcpu();
879 mtspr(SPR_TSR, TSR_ENW|TSR_WIS);
880 wdog_barked = true;
881 dump_splhist(ci, NULL);
882 dump_trapframe(tf, NULL);
883 panic("%s: tf=%p tb=%"PRId64" srr0/srr1=%#lx/%#lx"
884 " cpl=%d idepth=%d, mtxcount=%d",
885 __func__, tf, mftb(), tf->tf_srr0, tf->tf_srr1,
886 ci->ci_cpl, ci->ci_idepth, ci->ci_mtx_count);
887 }
888
889 static void
890 e500_extintr(struct trapframe *tf)
891 {
892 struct cpu_info * const ci = curcpu();
893 struct cpu_softc * const cpu = ci->ci_softc;
894 const int old_ipl = ci->ci_cpl;
895
896 /* if we paniced because of watchdog, PSL_CE will be clear. */
897 KASSERT(wdog_barked || (mfmsr() & PSL_CE));
898
899 #if 0
900 // printf("%s(%p): idepth=%d enter\n", __func__, tf, ci->ci_idepth);
901 if ((register_t)tf >= (register_t)curlwp->l_addr + USPACE
902 || (register_t)tf < (register_t)curlwp->l_addr + NBPG) {
903 printf("%s(entry): pid %d.%d (%s): srr0/srr1=%#lx/%#lx: invalid tf addr %p\n",
904 __func__, curlwp->l_proc->p_pid, curlwp->l_lid,
905 curlwp->l_proc->p_comm, tf->tf_srr0, tf->tf_srr1, tf);
906 }
907 #endif
908
909
910 ci->ci_data.cpu_nintr++;
911 tf->tf_cf.cf_idepth = ci->ci_idepth++;
912 cpu->cpu_pcpls[ci->ci_idepth] = old_ipl;
913 #if 1
914 if (mfmsr() & PSL_EE)
915 panic("%s(%p): MSR[EE] is on (%#lx)!", __func__, tf, mfmsr());
916 if (old_ipl == IPL_HIGH
917 || IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
918 panic("%s(%p): old_ipl(%u) == IPL_HIGH(%u) "
919 "|| old_ipl + %u != OPENPIC_CTPR (%u)",
920 __func__, tf, old_ipl, IPL_HIGH,
921 15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
922 #else
923 if (old_ipl >= IPL_VM)
924 panic("%s(%p): old_ipl(%u) >= IPL_VM(%u) CTPR=%u",
925 __func__, tf, old_ipl, IPL_VM, openpic_read(cpu, OPENPIC_CTPR));
926 #endif
927
928 for (;;) {
929 /*
930 * Find out the pending interrupt.
931 */
932 KASSERTMSG((mfmsr() & PSL_EE) == 0,
933 "%s(%p): MSR[EE] left on (%#lx)!", __func__, tf, mfmsr());
934 if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
935 panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
936 __func__, tf, __LINE__, old_ipl,
937 15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
938 const uint32_t iack = openpic_read(cpu, OPENPIC_IACK);
939 #ifdef DIAGNOSTIC
940 const int ipl = iack & 0xf;
941 #endif
942 const int irq = (iack >> 4) - 1;
943 #if 0
944 printf("%s: iack=%d ipl=%d irq=%d <%s>\n",
945 __func__, iack, ipl, irq,
946 (iack != IRQ_SPURIOUS ?
947 cpu->cpu_evcnt_intrs[irq].ev_name : "spurious"));
948 #endif
949 if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
950 panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
951 __func__, tf, __LINE__, old_ipl,
952 15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
953 if (iack == IRQ_SPURIOUS)
954 break;
955
956 struct intr_source * const is = &e500_intr_sources[irq];
957 if (__predict_true(is < e500_intr_last_source)) {
958 /*
959 * Timer interrupts get their argument overriden with
960 * the pointer to the trapframe.
961 */
962 KASSERTMSG(is->is_ipl == ipl,
963 "iack %#x: is %p: irq %d ipl %d != iack ipl %d",
964 iack, is, irq, is->is_ipl, ipl);
965 void *arg = (is->is_ist == IST_TIMER ? tf : is->is_arg);
966 if (is->is_ipl <= old_ipl)
967 panic("%s(%p): %s (%u): is->is_ipl (%u) <= old_ipl (%u)\n",
968 __func__, tf,
969 cpu->cpu_evcnt_intrs[irq].ev_name, irq,
970 is->is_ipl, old_ipl);
971 KASSERT(is->is_ipl > old_ipl);
972 e500_splset(ci, is->is_ipl); /* change IPL */
973 if (__predict_false(is->is_func == NULL)) {
974 aprint_error_dev(ci->ci_dev,
975 "interrupt from unestablished irq %d\n",
976 irq);
977 } else {
978 int (*func)(void *) = is->is_func;
979 wrtee(PSL_EE);
980 int rv = (*func)(arg);
981 wrtee(0);
982 #if DEBUG > 2
983 printf("%s: %s handler %p(%p) returned %d\n",
984 __func__,
985 cpu->cpu_evcnt_intrs[irq].ev_name,
986 func, arg, rv);
987 #endif
988 if (rv == 0)
989 cpu->cpu_evcnt_spurious_intr.ev_count++;
990 }
991 e500_splset(ci, old_ipl); /* restore IPL */
992 cpu->cpu_evcnt_intrs[irq].ev_count++;
993 } else {
994 aprint_error_dev(ci->ci_dev,
995 "interrupt from illegal irq %d\n", irq);
996 cpu->cpu_evcnt_spurious_intr.ev_count++;
997 }
998 /*
999 * If this is a nested interrupt, simply ack it and exit
1000 * because the loop we interrupted will complete looking
1001 * for interrupts.
1002 */
1003 KASSERTMSG((mfmsr() & PSL_EE) == 0,
1004 "%s(%p): MSR[EE] left on (%#lx)!", __func__, tf, mfmsr());
1005 if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
1006 panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
1007 __func__, tf, __LINE__, old_ipl,
1008 15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
1009
1010 openpic_write(cpu, OPENPIC_EOI, 0);
1011 if (IPL2CTPR(old_ipl) != openpic_read(cpu, OPENPIC_CTPR))
1012 panic("%s(%p): %d: old_ipl(%u) + %u != OPENPIC_CTPR (%u)",
1013 __func__, tf, __LINE__, old_ipl,
1014 15 - IPL_HIGH, openpic_read(cpu, OPENPIC_CTPR));
1015 if (ci->ci_idepth > 0)
1016 break;
1017 }
1018
1019 ci->ci_idepth--;
1020
1021 #ifdef __HAVE_FAST_SOFTINTS
1022 /*
1023 * Before exiting, deal with any softints that need to be dealt with.
1024 */
1025 const u_int softints = ci->ci_data.cpu_softints & (IPL_SOFTMASK << old_ipl);
1026 if (__predict_false(softints != 0)) {
1027 KASSERT(old_ipl < IPL_VM);
1028 e500_splset(ci, IPL_HIGH); /* pop to high */
1029 wrtee(PSL_EE); /* reenable interrupts */
1030 powerpc_softint(ci, old_ipl, /* deal with them */
1031 tf->tf_srr0);
1032 wrtee(0); /* disable interrupts */
1033 e500_splset(ci, old_ipl); /* and drop back */
1034 }
1035 #endif /* __HAVE_FAST_SOFTINTS */
1036 KASSERT(ci->ci_cpl == old_ipl);
1037
1038 /*
1039 * If we interrupted while power-saving and we need to exit idle,
1040 * we need to clear PSL_POW so we won't go back into power-saving.
1041 */
1042 if (__predict_false(tf->tf_srr1 & PSL_POW) && ci->ci_want_resched)
1043 tf->tf_srr1 &= ~PSL_POW;
1044
1045 // printf("%s(%p): idepth=%d exit\n", __func__, tf, ci->ci_idepth);
1046 }
1047
1048 static void
1049 e500_intr_init(void)
1050 {
1051 struct cpu_info * const ci = curcpu();
1052 struct cpu_softc * const cpu = ci->ci_softc;
1053 const uint32_t frr = openpic_read(cpu, OPENPIC_FRR);
1054 const u_int nirq = FRR_NIRQ_GET(frr) + 1;
1055 // const u_int ncpu = FRR_NCPU_GET(frr) + 1;
1056 struct intr_source *is;
1057 struct e500_intr_info * const ii = &e500_intr_info;
1058
1059 const uint16_t svr = (mfspr(SPR_SVR) & ~0x80000) >> 16;
1060 switch (svr) {
1061 #ifdef MPC8536
1062 case SVR_MPC8536v1 >> 16:
1063 *ii = mpc8536_intr_info;
1064 break;
1065 #endif
1066 #ifdef MPC8544
1067 case SVR_MPC8544v1 >> 16:
1068 *ii = mpc8544_intr_info;
1069 break;
1070 #endif
1071 #ifdef MPC8548
1072 case SVR_MPC8543v1 >> 16:
1073 case SVR_MPC8548v1 >> 16:
1074 *ii = mpc8548_intr_info;
1075 break;
1076 #endif
1077 #ifdef MPC8555
1078 case SVR_MPC8541v1 >> 16:
1079 case SVR_MPC8555v1 >> 16:
1080 *ii = mpc8555_intr_info;
1081 break;
1082 #endif
1083 #ifdef MPC8568
1084 case SVR_MPC8568v1 >> 16:
1085 *ii = mpc8568_intr_info;
1086 break;
1087 #endif
1088 #ifdef MPC8572
1089 case SVR_MPC8572v1 >> 16:
1090 *ii = mpc8572_intr_info;
1091 break;
1092 #endif
1093 #ifdef P1023
1094 case SVR_P1017v1 >> 16:
1095 case SVR_P1023v1 >> 16:
1096 *ii = p1023_intr_info;
1097 break;
1098 #endif
1099 #ifdef P1025
1100 case SVR_P1016v1 >> 16:
1101 case SVR_P1025v1 >> 16:
1102 *ii = p1025_intr_info;
1103 break;
1104 #endif
1105 #ifdef P2020
1106 case SVR_P2010v2 >> 16:
1107 case SVR_P2020v2 >> 16:
1108 *ii = p20x0_intr_info;
1109 break;
1110 #endif
1111 default:
1112 panic("%s: don't know how to deal with SVR %#lx",
1113 __func__, mfspr(SPR_SVR));
1114 }
1115
1116 /*
1117 * Initialize interrupt handler lock
1118 */
1119 mutex_init(&e500_intr_lock, MUTEX_DEFAULT, IPL_HIGH);
1120
1121 /*
1122 * We need to be in mixed mode.
1123 */
1124 openpic_write(cpu, OPENPIC_GCR, GCR_M);
1125
1126 /*
1127 * Make we and the openpic both agree about the current SPL level.
1128 */
1129 e500_splset(ci, ci->ci_cpl);
1130
1131 /*
1132 * Allow the required number of interrupt sources.
1133 */
1134 is = kmem_zalloc(nirq * sizeof(*is), KM_SLEEP);
1135 KASSERT(is);
1136 e500_intr_sources = is;
1137 e500_intr_last_source = is + nirq;
1138
1139 /*
1140 * Initialize all the external interrupts as active low.
1141 */
1142 for (u_int irq = 0; irq < e500_intr_info.ii_external_sources; irq++) {
1143 openpic_write(cpu, OPENPIC_EIVPR(irq),
1144 VPR_VECTOR_MAKE(irq) | VPR_LEVEL_LOW);
1145 }
1146 }
1147
1148 static void
1149 e500_intr_init_precpu(void)
1150 {
1151 struct cpu_info const *ci = curcpu();
1152 struct cpu_softc * const cpu = ci->ci_softc;
1153 bus_addr_t dr;
1154
1155 /*
1156 * timer's DR is set to be delivered to cpu0 as initial value.
1157 */
1158 for (u_int irq = 0; irq < e500_intr_info.ii_timer_sources; irq++) {
1159 dr = OPENPIC_GTDR(ci->ci_cpuid, irq);
1160 openpic_write(cpu, dr, 0); /* stop delivery */
1161 }
1162 }
1163
1164 static void
1165 e500_idlespin(void)
1166 {
1167 KASSERTMSG(curcpu()->ci_cpl == IPL_NONE,
1168 "%s: cpu%u: ci_cpl (%d) != 0", __func__, cpu_number(),
1169 curcpu()->ci_cpl);
1170 KASSERTMSG(CTPR2IPL(openpic_read(curcpu()->ci_softc, OPENPIC_CTPR)) == IPL_NONE,
1171 "%s: cpu%u: CTPR (%d) != IPL_NONE", __func__, cpu_number(),
1172 CTPR2IPL(openpic_read(curcpu()->ci_softc, OPENPIC_CTPR)));
1173 KASSERT(mfmsr() & PSL_EE);
1174
1175 if (powersave > 0)
1176 mtmsr(mfmsr() | PSL_POW);
1177 }
1178
1179 static void
1180 e500_intr_cpu_attach(struct cpu_info *ci)
1181 {
1182 struct cpu_softc * const cpu = ci->ci_softc;
1183 const char * const xname = device_xname(ci->ci_dev);
1184
1185 const u_int32_t frr = openpic_read(cpu, OPENPIC_FRR);
1186 const u_int nirq = FRR_NIRQ_GET(frr) + 1;
1187 // const u_int ncpu = FRR_NCPU_GET(frr) + 1;
1188
1189 const struct e500_intr_info * const info = &e500_intr_info;
1190
1191 cpu->cpu_clock_gtbcr = OPENPIC_GTBCR(ci->ci_cpuid, E500_CLOCK_TIMER);
1192
1193 cpu->cpu_evcnt_intrs =
1194 kmem_zalloc(nirq * sizeof(cpu->cpu_evcnt_intrs[0]), KM_SLEEP);
1195 KASSERT(cpu->cpu_evcnt_intrs);
1196
1197 struct evcnt *evcnt = cpu->cpu_evcnt_intrs;
1198 for (size_t j = 0; j < info->ii_external_sources; j++, evcnt++) {
1199 const char *name = e500_intr_external_name_lookup(j);
1200 evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR, NULL, xname, name);
1201 }
1202 KASSERT(evcnt == cpu->cpu_evcnt_intrs + info->ii_ist_vectors[IST_ONCHIP]);
1203 for (size_t j = 0; j < info->ii_onchip_sources; j++, evcnt++) {
1204 if (info->ii_onchip_bitmap[j / 32] & __BIT(j & 31)) {
1205 const char *name = e500_intr_onchip_name_lookup(j);
1206 if (name != NULL) {
1207 evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
1208 NULL, xname, name);
1209 #ifdef DIAGNOSTIC
1210 } else {
1211 printf("%s: missing evcnt for onchip irq %zu\n",
1212 __func__, j);
1213 #endif
1214 }
1215 }
1216 }
1217
1218 KASSERT(evcnt == cpu->cpu_evcnt_intrs + info->ii_ist_vectors[IST_MSIGROUP]);
1219 for (size_t j = 0; j < info->ii_msigroup_sources; j++, evcnt++) {
1220 evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
1221 NULL, xname, e500_msigroup_intr_names[j].in_name);
1222 }
1223
1224 KASSERT(evcnt == cpu->cpu_evcnt_intrs + info->ii_ist_vectors[IST_TIMER]);
1225 evcnt += ci->ci_cpuid * info->ii_percpu_sources;
1226 for (size_t j = 0; j < info->ii_timer_sources; j++, evcnt++) {
1227 evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
1228 NULL, xname, e500_timer_intr_names[j].in_name);
1229 }
1230
1231 for (size_t j = 0; j < info->ii_ipi_sources; j++, evcnt++) {
1232 evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
1233 NULL, xname, e500_ipi_intr_names[j].in_name);
1234 }
1235
1236 for (size_t j = 0; j < info->ii_mi_sources; j++, evcnt++) {
1237 evcnt_attach_dynamic(evcnt, EVCNT_TYPE_INTR,
1238 NULL, xname, e500_mi_intr_names[j].in_name);
1239 }
1240
1241 ci->ci_idlespin = e500_idlespin;
1242 }
1243
1244 static void
1245 e500_intr_cpu_send_ipi(cpuid_t target, uint32_t ipimsg)
1246 {
1247 struct cpu_info * const ci = curcpu();
1248 struct cpu_softc * const cpu = ci->ci_softc;
1249 uint32_t dstmask;
1250
1251 if (target >= CPU_MAXNUM) {
1252 CPU_INFO_ITERATOR cii;
1253 struct cpu_info *dst_ci;
1254
1255 KASSERT(target == IPI_DST_NOTME || target == IPI_DST_ALL);
1256
1257 dstmask = 0;
1258 for (CPU_INFO_FOREACH(cii, dst_ci)) {
1259 if (target == IPI_DST_ALL || ci != dst_ci) {
1260 dstmask |= 1 << cpu_index(ci);
1261 if (ipimsg)
1262 atomic_or_32(&dst_ci->ci_pending_ipis,
1263 ipimsg);
1264 }
1265 }
1266 } else {
1267 struct cpu_info * const dst_ci = cpu_lookup(target);
1268 KASSERT(dst_ci != NULL);
1269 KASSERTMSG(target == cpu_index(dst_ci),
1270 "%s: target (%lu) != cpu_index(cpu%u)",
1271 __func__, target, cpu_index(dst_ci));
1272 dstmask = (1 << target);
1273 if (ipimsg)
1274 atomic_or_32(&dst_ci->ci_pending_ipis, ipimsg);
1275 }
1276
1277 openpic_write(cpu, OPENPIC_IPIDR(0), dstmask);
1278 }
1279
1280 typedef void (*ipifunc_t)(void);
1281
1282 #ifdef __HAVE_PREEEMPTION
1283 static void
1284 e500_ipi_kpreempt(void)
1285 {
1286 poowerpc_softint_trigger(1 << IPL_NONE);
1287 }
1288 #endif
1289
1290 static void
1291 e500_ipi_suspend(void)
1292 {
1293
1294 #ifdef MULTIPROCESSOR
1295 cpu_pause(NULL);
1296 #endif /* MULTIPROCESSOR */
1297 }
1298
1299 static const ipifunc_t e500_ipifuncs[] = {
1300 [ilog2(IPI_XCALL)] = xc_ipi_handler,
1301 [ilog2(IPI_GENERIC)] = ipi_cpu_handler,
1302 [ilog2(IPI_HALT)] = e500_ipi_halt,
1303 #ifdef __HAVE_PREEMPTION
1304 [ilog2(IPI_KPREEMPT)] = e500_ipi_kpreempt,
1305 #endif
1306 [ilog2(IPI_TLB1SYNC)] = e500_tlb1_sync,
1307 [ilog2(IPI_SUSPEND)] = e500_ipi_suspend,
1308 };
1309
1310 static int
1311 e500_ipi_intr(void *v)
1312 {
1313 struct cpu_info * const ci = curcpu();
1314
1315 ci->ci_ev_ipi.ev_count++;
1316
1317 uint32_t pending_ipis = atomic_swap_32(&ci->ci_pending_ipis, 0);
1318 for (u_int ipi = 31; pending_ipis != 0; ipi--, pending_ipis <<= 1) {
1319 const u_int bits = __builtin_clz(pending_ipis);
1320 ipi -= bits;
1321 pending_ipis <<= bits;
1322 KASSERT(e500_ipifuncs[ipi] != NULL);
1323 (*e500_ipifuncs[ipi])();
1324 }
1325
1326 return 1;
1327 }
1328
1329 static void
1330 e500_intr_cpu_hatch(struct cpu_info *ci)
1331 {
1332
1333 /* Initialize percpu interupts. */
1334 e500_intr_init_precpu();
1335
1336 /*
1337 * Establish clock interrupt for this CPU.
1338 */
1339 if (e500_intr_cpu_establish(ci, E500_CLOCK_TIMER, IPL_CLOCK, IST_TIMER,
1340 e500_clock_intr, NULL) == NULL)
1341 panic("%s: failed to establish clock interrupt!", __func__);
1342
1343 /*
1344 * Establish the IPI interrupts for this CPU.
1345 */
1346 if (e500_intr_cpu_establish(ci, 0, IPL_VM, IST_IPI, e500_ipi_intr,
1347 NULL) == NULL)
1348 panic("%s: failed to establish ipi interrupt!", __func__);
1349
1350 /*
1351 * Enable watchdog interrupts.
1352 */
1353 uint32_t tcr = mfspr(SPR_TCR);
1354 tcr |= TCR_WIE;
1355 mtspr(SPR_TCR, tcr);
1356 }
1357