1 /*- 2 * SPDX-License-Identifier: BSD-3-Clause 3 * 4 * Copyright (c) 2011 The FreeBSD Foundation 5 * All rights reserved. 6 * 7 * Developed by Damjan Marion <damjan.marion@gmail.com> 8 * 9 * Based on OMAP4 GIC code by Ben Gray 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. The name of the company nor the name of the author may be used to 20 * endorse or promote products derived from this software without specific 21 * prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include <sys/cdefs.h> 37 #include "opt_acpi.h" 38 #include "opt_ddb.h" 39 #include "opt_platform.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/bus.h> 44 #include <sys/kernel.h> 45 #include <sys/ktr.h> 46 #include <sys/module.h> 47 #include <sys/malloc.h> 48 #include <sys/rman.h> 49 #include <sys/pcpu.h> 50 #include <sys/proc.h> 51 #include <sys/cpuset.h> 52 #include <sys/lock.h> 53 #include <sys/mutex.h> 54 #include <sys/smp.h> 55 #include <sys/sched.h> 56 57 #include <vm/vm.h> 58 #include <vm/pmap.h> 59 60 #include <machine/bus.h> 61 #include <machine/intr.h> 62 #include <machine/smp.h> 63 64 #ifdef FDT 65 #include <dev/fdt/fdt_intr.h> 66 #include <dev/ofw/ofw_bus_subr.h> 67 #endif 68 69 #ifdef DEV_ACPI 70 #include <contrib/dev/acpica/include/acpi.h> 71 #include <dev/acpica/acpivar.h> 72 #endif 73 74 #ifdef DDB 75 #include <ddb/ddb.h> 76 #include <ddb/db_lex.h> 77 #endif 78 79 #include <arm/arm/gic.h> 80 #include <arm/arm/gic_common.h> 81 82 #include "gic_if.h" 83 #include "pic_if.h" 84 #include "msi_if.h" 85 86 /* We are using GICv2 register naming */ 87 88 /* Distributor Registers */ 89 90 /* CPU Registers */ 91 #define GICC_CTLR 0x0000 /* v1 ICCICR */ 92 #define GICC_PMR 0x0004 /* v1 ICCPMR */ 93 #define GICC_BPR 0x0008 /* v1 ICCBPR */ 94 #define GICC_IAR 0x000C /* v1 ICCIAR */ 95 #define GICC_EOIR 0x0010 /* v1 ICCEOIR */ 96 #define GICC_RPR 0x0014 /* v1 ICCRPR */ 97 #define GICC_HPPIR 0x0018 /* v1 ICCHPIR */ 98 #define GICC_ABPR 0x001C /* v1 ICCABPR */ 99 #define GICC_IIDR 0x00FC /* v1 ICCIIDR*/ 100 101 /* TYPER Registers */ 102 #define GICD_TYPER_SECURITYEXT 0x400 103 #define GIC_SUPPORT_SECEXT(_sc) \ 104 ((_sc->typer & GICD_TYPER_SECURITYEXT) == GICD_TYPER_SECURITYEXT) 105 106 #ifndef GIC_DEFAULT_ICFGR_INIT 107 #define GIC_DEFAULT_ICFGR_INIT 0x00000000 108 #endif 109 110 struct gic_irqsrc { 111 struct intr_irqsrc gi_isrc; 112 uint32_t gi_irq; 113 enum intr_polarity gi_pol; 114 enum intr_trigger gi_trig; 115 #define GI_FLAG_EARLY_EOI (1 << 0) 116 #define GI_FLAG_MSI (1 << 1) /* This interrupt source should only */ 117 /* be used for MSI/MSI-X interrupts */ 118 #define GI_FLAG_MSI_USED (1 << 2) /* This irq is already allocated */ 119 /* for a MSI/MSI-X interrupt */ 120 u_int gi_flags; 121 }; 122 123 static u_int gic_irq_cpu; 124 static int arm_gic_bind_intr(device_t dev, struct intr_irqsrc *isrc); 125 126 #ifdef SMP 127 static u_int sgi_to_ipi[GIC_LAST_SGI - GIC_FIRST_SGI + 1]; 128 static u_int sgi_first_unused = GIC_FIRST_SGI; 129 #endif 130 131 #define GIC_INTR_ISRC(sc, irq) (&sc->gic_irqs[irq].gi_isrc) 132 133 static struct resource_spec arm_gic_spec[] = { 134 { SYS_RES_MEMORY, 0, RF_ACTIVE }, /* Distributor registers */ 135 { SYS_RES_MEMORY, 1, RF_ACTIVE }, /* CPU Interrupt Intf. registers */ 136 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_OPTIONAL }, /* Parent interrupt */ 137 { -1, 0 } 138 }; 139 140 #if defined(__arm__) && defined(INVARIANTS) 141 static int gic_debug_spurious = 1; 142 #else 143 static int gic_debug_spurious = 0; 144 #endif 145 TUNABLE_INT("hw.gic.debug_spurious", &gic_debug_spurious); 146 147 static u_int arm_gic_map[GIC_MAXCPU]; 148 149 static struct arm_gic_softc *gic_sc = NULL; 150 151 /* CPU Interface */ 152 #define gic_c_read_4(_sc, _reg) \ 153 bus_read_4((_sc)->gic_res[GIC_RES_CPU], (_reg)) 154 #define gic_c_write_4(_sc, _reg, _val) \ 155 bus_write_4((_sc)->gic_res[GIC_RES_CPU], (_reg), (_val)) 156 /* Distributor Interface */ 157 #define gic_d_read_4(_sc, _reg) \ 158 bus_read_4((_sc)->gic_res[GIC_RES_DIST], (_reg)) 159 #define gic_d_write_1(_sc, _reg, _val) \ 160 bus_write_1((_sc)->gic_res[GIC_RES_DIST], (_reg), (_val)) 161 #define gic_d_write_4(_sc, _reg, _val) \ 162 bus_write_4((_sc)->gic_res[GIC_RES_DIST], (_reg), (_val)) 163 164 static inline void 165 gic_irq_unmask(struct arm_gic_softc *sc, u_int irq) 166 { 167 168 gic_d_write_4(sc, GICD_ISENABLER(irq), GICD_I_MASK(irq)); 169 } 170 171 static inline void 172 gic_irq_mask(struct arm_gic_softc *sc, u_int irq) 173 { 174 175 gic_d_write_4(sc, GICD_ICENABLER(irq), GICD_I_MASK(irq)); 176 } 177 178 static uint8_t 179 gic_cpu_mask(struct arm_gic_softc *sc) 180 { 181 uint32_t mask; 182 int i; 183 184 /* Read the current cpuid mask by reading ITARGETSR{0..7} */ 185 for (i = 0; i < 8; i++) { 186 mask = gic_d_read_4(sc, GICD_ITARGETSR(4 * i)); 187 if (mask != 0) 188 break; 189 } 190 /* No mask found, assume we are on CPU interface 0 */ 191 if (mask == 0) 192 return (1); 193 194 /* Collect the mask in the lower byte */ 195 mask |= mask >> 16; 196 mask |= mask >> 8; 197 198 return (mask); 199 } 200 201 #ifdef SMP 202 static void 203 arm_gic_init_secondary(device_t dev) 204 { 205 struct arm_gic_softc *sc = device_get_softc(dev); 206 u_int irq, cpu; 207 208 /* Set the mask so we can find this CPU to send it IPIs */ 209 cpu = PCPU_GET(cpuid); 210 MPASS(cpu < GIC_MAXCPU); 211 arm_gic_map[cpu] = gic_cpu_mask(sc); 212 213 for (irq = 0; irq < sc->nirqs; irq += 4) 214 gic_d_write_4(sc, GICD_IPRIORITYR(irq), 0); 215 216 /* Set all the interrupts to be in Group 0 (secure) */ 217 for (irq = 0; GIC_SUPPORT_SECEXT(sc) && irq < sc->nirqs; irq += 32) { 218 gic_d_write_4(sc, GICD_IGROUPR(irq), 0); 219 } 220 221 /* Enable CPU interface */ 222 gic_c_write_4(sc, GICC_CTLR, 1); 223 224 /* Set priority mask register. */ 225 gic_c_write_4(sc, GICC_PMR, 0xff); 226 227 /* Enable interrupt distribution */ 228 gic_d_write_4(sc, GICD_CTLR, 0x01); 229 230 /* Unmask attached SGI interrupts. */ 231 for (irq = GIC_FIRST_SGI; irq <= GIC_LAST_SGI; irq++) 232 if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu)) 233 gic_irq_unmask(sc, irq); 234 235 /* Unmask attached PPI interrupts. */ 236 for (irq = GIC_FIRST_PPI; irq <= GIC_LAST_PPI; irq++) 237 if (intr_isrc_init_on_cpu(GIC_INTR_ISRC(sc, irq), cpu)) 238 gic_irq_unmask(sc, irq); 239 } 240 #endif /* SMP */ 241 242 static int 243 arm_gic_register_isrcs(struct arm_gic_softc *sc, uint32_t num) 244 { 245 int error; 246 uint32_t irq; 247 struct gic_irqsrc *irqs; 248 struct intr_irqsrc *isrc; 249 const char *name; 250 251 irqs = malloc(num * sizeof(struct gic_irqsrc), M_DEVBUF, 252 M_WAITOK | M_ZERO); 253 254 name = device_get_nameunit(sc->gic_dev); 255 for (irq = 0; irq < num; irq++) { 256 irqs[irq].gi_irq = irq; 257 irqs[irq].gi_pol = INTR_POLARITY_CONFORM; 258 irqs[irq].gi_trig = INTR_TRIGGER_CONFORM; 259 260 isrc = &irqs[irq].gi_isrc; 261 if (irq <= GIC_LAST_SGI) { 262 error = intr_isrc_register(isrc, sc->gic_dev, 263 INTR_ISRCF_IPI, "%s,i%u", name, irq - GIC_FIRST_SGI); 264 } else if (irq <= GIC_LAST_PPI) { 265 error = intr_isrc_register(isrc, sc->gic_dev, 266 INTR_ISRCF_PPI, "%s,p%u", name, irq - GIC_FIRST_PPI); 267 } else { 268 error = intr_isrc_register(isrc, sc->gic_dev, 0, 269 "%s,s%u", name, irq - GIC_FIRST_SPI); 270 } 271 if (error != 0) { 272 /* XXX call intr_isrc_deregister() */ 273 free(irqs, M_DEVBUF); 274 return (error); 275 } 276 } 277 sc->gic_irqs = irqs; 278 sc->nirqs = num; 279 return (0); 280 } 281 282 static void 283 arm_gic_reserve_msi_range(device_t dev, u_int start, u_int count) 284 { 285 struct arm_gic_softc *sc; 286 int i; 287 288 sc = device_get_softc(dev); 289 290 KASSERT((start + count) <= sc->nirqs, 291 ("%s: Trying to allocate too many MSI IRQs: %d + %d > %d", __func__, 292 start, count, sc->nirqs)); 293 for (i = 0; i < count; i++) { 294 KASSERT(sc->gic_irqs[start + i].gi_isrc.isrc_handlers == 0, 295 ("%s: MSI interrupt %d already has a handler", __func__, 296 count + i)); 297 KASSERT(sc->gic_irqs[start + i].gi_pol == INTR_POLARITY_CONFORM, 298 ("%s: MSI interrupt %d already has a polarity", __func__, 299 count + i)); 300 KASSERT(sc->gic_irqs[start + i].gi_trig == INTR_TRIGGER_CONFORM, 301 ("%s: MSI interrupt %d already has a trigger", __func__, 302 count + i)); 303 sc->gic_irqs[start + i].gi_pol = INTR_POLARITY_HIGH; 304 sc->gic_irqs[start + i].gi_trig = INTR_TRIGGER_EDGE; 305 sc->gic_irqs[start + i].gi_flags |= GI_FLAG_MSI; 306 } 307 } 308 309 int 310 arm_gic_attach(device_t dev) 311 { 312 struct arm_gic_softc *sc; 313 int i; 314 uint32_t icciidr, mask, nirqs; 315 316 if (gic_sc) 317 return (ENXIO); 318 319 if (mp_ncpus > GIC_MAXCPU) { 320 device_printf(dev, "Too many CPUs for IPIs to work (%d > %d)\n", 321 mp_ncpus, GIC_MAXCPU); 322 return (ENXIO); 323 } 324 325 sc = device_get_softc(dev); 326 327 if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) { 328 device_printf(dev, "could not allocate resources\n"); 329 return (ENXIO); 330 } 331 332 sc->gic_dev = dev; 333 gic_sc = sc; 334 335 /* Initialize mutex */ 336 mtx_init(&sc->mutex, "GIC lock", NULL, MTX_SPIN); 337 338 /* Disable interrupt forwarding to the CPU interface */ 339 gic_d_write_4(sc, GICD_CTLR, 0x00); 340 341 /* Get the number of interrupts */ 342 sc->typer = gic_d_read_4(sc, GICD_TYPER); 343 nirqs = GICD_TYPER_I_NUM(sc->typer); 344 345 if (arm_gic_register_isrcs(sc, nirqs)) { 346 device_printf(dev, "could not register irqs\n"); 347 goto cleanup; 348 } 349 350 icciidr = gic_c_read_4(sc, GICC_IIDR); 351 device_printf(dev, 352 "pn 0x%x, arch 0x%x, rev 0x%x, implementer 0x%x irqs %u\n", 353 GICD_IIDR_PROD(icciidr), GICD_IIDR_VAR(icciidr), 354 GICD_IIDR_REV(icciidr), GICD_IIDR_IMPL(icciidr), sc->nirqs); 355 sc->gic_iidr = icciidr; 356 357 /* Set all global interrupts to be level triggered, active low. */ 358 for (i = 32; i < sc->nirqs; i += 16) { 359 gic_d_write_4(sc, GICD_ICFGR(i), GIC_DEFAULT_ICFGR_INIT); 360 } 361 362 /* Disable all interrupts. */ 363 for (i = 32; i < sc->nirqs; i += 32) { 364 gic_d_write_4(sc, GICD_ICENABLER(i), 0xFFFFFFFF); 365 } 366 367 /* Find the current cpu mask */ 368 mask = gic_cpu_mask(sc); 369 /* Set the mask so we can find this CPU to send it IPIs */ 370 MPASS(PCPU_GET(cpuid) < GIC_MAXCPU); 371 arm_gic_map[PCPU_GET(cpuid)] = mask; 372 /* Set all four targets to this cpu */ 373 mask |= mask << 8; 374 mask |= mask << 16; 375 376 for (i = 0; i < sc->nirqs; i += 4) { 377 gic_d_write_4(sc, GICD_IPRIORITYR(i), 0); 378 if (i > 32) { 379 gic_d_write_4(sc, GICD_ITARGETSR(i), mask); 380 } 381 } 382 383 /* Set all the interrupts to be in Group 0 (secure) */ 384 for (i = 0; GIC_SUPPORT_SECEXT(sc) && i < sc->nirqs; i += 32) { 385 gic_d_write_4(sc, GICD_IGROUPR(i), 0); 386 } 387 388 /* Enable CPU interface */ 389 gic_c_write_4(sc, GICC_CTLR, 1); 390 391 /* Set priority mask register. */ 392 gic_c_write_4(sc, GICC_PMR, 0xff); 393 394 /* Enable interrupt distribution */ 395 gic_d_write_4(sc, GICD_CTLR, 0x01); 396 return (0); 397 398 cleanup: 399 arm_gic_detach(dev); 400 return(ENXIO); 401 } 402 403 int 404 arm_gic_detach(device_t dev) 405 { 406 struct arm_gic_softc *sc; 407 408 sc = device_get_softc(dev); 409 410 if (sc->gic_irqs != NULL) 411 free(sc->gic_irqs, M_DEVBUF); 412 413 bus_release_resources(dev, arm_gic_spec, sc->gic_res); 414 415 return (0); 416 } 417 418 static int 419 arm_gic_print_child(device_t bus, device_t child) 420 { 421 struct resource_list *rl; 422 int rv; 423 424 rv = bus_print_child_header(bus, child); 425 426 rl = BUS_GET_RESOURCE_LIST(bus, child); 427 if (rl != NULL) { 428 rv += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 429 "%#jx"); 430 rv += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%jd"); 431 } 432 433 rv += bus_print_child_footer(bus, child); 434 435 return (rv); 436 } 437 438 static struct resource * 439 arm_gic_alloc_resource(device_t bus, device_t child, int type, int *rid, 440 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 441 { 442 struct arm_gic_softc *sc; 443 struct resource_list_entry *rle; 444 struct resource_list *rl; 445 int j; 446 447 KASSERT(type == SYS_RES_MEMORY, ("Invalid resoure type %x", type)); 448 449 sc = device_get_softc(bus); 450 451 /* 452 * Request for the default allocation with a given rid: use resource 453 * list stored in the local device info. 454 */ 455 if (RMAN_IS_DEFAULT_RANGE(start, end)) { 456 rl = BUS_GET_RESOURCE_LIST(bus, child); 457 458 if (type == SYS_RES_IOPORT) 459 type = SYS_RES_MEMORY; 460 461 rle = resource_list_find(rl, type, *rid); 462 if (rle == NULL) { 463 if (bootverbose) 464 device_printf(bus, "no default resources for " 465 "rid = %d, type = %d\n", *rid, type); 466 return (NULL); 467 } 468 start = rle->start; 469 end = rle->end; 470 count = rle->count; 471 } 472 473 /* Remap through ranges property */ 474 for (j = 0; j < sc->nranges; j++) { 475 if (start >= sc->ranges[j].bus && end < 476 sc->ranges[j].bus + sc->ranges[j].size) { 477 start -= sc->ranges[j].bus; 478 start += sc->ranges[j].host; 479 end -= sc->ranges[j].bus; 480 end += sc->ranges[j].host; 481 break; 482 } 483 } 484 if (j == sc->nranges && sc->nranges != 0) { 485 if (bootverbose) 486 device_printf(bus, "Could not map resource " 487 "%#jx-%#jx\n", (uintmax_t)start, (uintmax_t)end); 488 489 return (NULL); 490 } 491 492 return (bus_generic_alloc_resource(bus, child, type, rid, start, end, 493 count, flags)); 494 } 495 496 static int 497 arm_gic_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 498 { 499 struct arm_gic_softc *sc; 500 501 sc = device_get_softc(dev); 502 503 switch(which) { 504 case GIC_IVAR_HW_REV: 505 KASSERT(GICD_IIDR_VAR(sc->gic_iidr) < 3, 506 ("arm_gic_read_ivar: Unknown IIDR revision %u (%.08x)", 507 GICD_IIDR_VAR(sc->gic_iidr), sc->gic_iidr)); 508 *result = GICD_IIDR_VAR(sc->gic_iidr); 509 return (0); 510 case GIC_IVAR_BUS: 511 KASSERT(sc->gic_bus != GIC_BUS_UNKNOWN, 512 ("arm_gic_read_ivar: Unknown bus type")); 513 KASSERT(sc->gic_bus <= GIC_BUS_MAX, 514 ("arm_gic_read_ivar: Invalid bus type %u", sc->gic_bus)); 515 *result = sc->gic_bus; 516 return (0); 517 } 518 519 return (ENOENT); 520 } 521 522 static int 523 arm_gic_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 524 { 525 switch(which) { 526 case GIC_IVAR_HW_REV: 527 case GIC_IVAR_BUS: 528 return (EINVAL); 529 } 530 531 return (ENOENT); 532 } 533 534 int 535 arm_gic_intr(void *arg) 536 { 537 struct arm_gic_softc *sc = arg; 538 struct gic_irqsrc *gi; 539 uint32_t irq_active_reg, irq; 540 struct trapframe *tf; 541 542 irq_active_reg = gic_c_read_4(sc, GICC_IAR); 543 irq = irq_active_reg & 0x3FF; 544 545 /* 546 * 1. We do EOI here because recent read value from active interrupt 547 * register must be used for it. Another approach is to save this 548 * value into associated interrupt source. 549 * 2. EOI must be done on same CPU where interrupt has fired. Thus 550 * we must ensure that interrupted thread does not migrate to 551 * another CPU. 552 * 3. EOI cannot be delayed by any preemption which could happen on 553 * critical_exit() used in MI intr code, when interrupt thread is 554 * scheduled. See next point. 555 * 4. IPI_RENDEZVOUS assumes that no preemption is permitted during 556 * an action and any use of critical_exit() could break this 557 * assumption. See comments within smp_rendezvous_action(). 558 * 5. We always return FILTER_HANDLED as this is an interrupt 559 * controller dispatch function. Otherwise, in cascaded interrupt 560 * case, the whole interrupt subtree would be masked. 561 */ 562 563 if (irq >= sc->nirqs) { 564 if (gic_debug_spurious) 565 device_printf(sc->gic_dev, 566 "Spurious interrupt detected: last irq: %d on CPU%d\n", 567 sc->last_irq[PCPU_GET(cpuid)], PCPU_GET(cpuid)); 568 return (FILTER_HANDLED); 569 } 570 571 tf = curthread->td_intr_frame; 572 dispatch_irq: 573 gi = sc->gic_irqs + irq; 574 /* 575 * Note that GIC_FIRST_SGI is zero and is not used in 'if' statement 576 * as compiler complains that comparing u_int >= 0 is always true. 577 */ 578 if (irq <= GIC_LAST_SGI) { 579 #ifdef SMP 580 /* Call EOI for all IPI before dispatch. */ 581 gic_c_write_4(sc, GICC_EOIR, irq_active_reg); 582 intr_ipi_dispatch(sgi_to_ipi[gi->gi_irq]); 583 goto next_irq; 584 #else 585 device_printf(sc->gic_dev, "SGI %u on UP system detected\n", 586 irq - GIC_FIRST_SGI); 587 gic_c_write_4(sc, GICC_EOIR, irq_active_reg); 588 goto next_irq; 589 #endif 590 } 591 592 if (gic_debug_spurious) 593 sc->last_irq[PCPU_GET(cpuid)] = irq; 594 if ((gi->gi_flags & GI_FLAG_EARLY_EOI) == GI_FLAG_EARLY_EOI) 595 gic_c_write_4(sc, GICC_EOIR, irq_active_reg); 596 597 if (intr_isrc_dispatch(&gi->gi_isrc, tf) != 0) { 598 gic_irq_mask(sc, irq); 599 if ((gi->gi_flags & GI_FLAG_EARLY_EOI) != GI_FLAG_EARLY_EOI) 600 gic_c_write_4(sc, GICC_EOIR, irq_active_reg); 601 device_printf(sc->gic_dev, "Stray irq %u disabled\n", irq); 602 } 603 604 next_irq: 605 arm_irq_memory_barrier(irq); 606 irq_active_reg = gic_c_read_4(sc, GICC_IAR); 607 irq = irq_active_reg & 0x3FF; 608 if (irq < sc->nirqs) 609 goto dispatch_irq; 610 611 return (FILTER_HANDLED); 612 } 613 614 static void 615 gic_config(struct arm_gic_softc *sc, u_int irq, enum intr_trigger trig, 616 enum intr_polarity pol) 617 { 618 uint32_t reg; 619 uint32_t mask; 620 621 if (irq < GIC_FIRST_SPI) 622 return; 623 624 mtx_lock_spin(&sc->mutex); 625 626 reg = gic_d_read_4(sc, GICD_ICFGR(irq)); 627 mask = (reg >> 2*(irq % 16)) & 0x3; 628 629 if (pol == INTR_POLARITY_LOW) { 630 mask &= ~GICD_ICFGR_POL_MASK; 631 mask |= GICD_ICFGR_POL_LOW; 632 } else if (pol == INTR_POLARITY_HIGH) { 633 mask &= ~GICD_ICFGR_POL_MASK; 634 mask |= GICD_ICFGR_POL_HIGH; 635 } 636 637 if (trig == INTR_TRIGGER_LEVEL) { 638 mask &= ~GICD_ICFGR_TRIG_MASK; 639 mask |= GICD_ICFGR_TRIG_LVL; 640 } else if (trig == INTR_TRIGGER_EDGE) { 641 mask &= ~GICD_ICFGR_TRIG_MASK; 642 mask |= GICD_ICFGR_TRIG_EDGE; 643 } 644 645 /* Set mask */ 646 reg = reg & ~(0x3 << 2*(irq % 16)); 647 reg = reg | (mask << 2*(irq % 16)); 648 gic_d_write_4(sc, GICD_ICFGR(irq), reg); 649 650 mtx_unlock_spin(&sc->mutex); 651 } 652 653 static int 654 gic_bind(struct arm_gic_softc *sc, u_int irq, cpuset_t *cpus) 655 { 656 uint32_t cpu, end, mask; 657 658 end = min(mp_ncpus, GIC_MAXCPU); 659 for (cpu = end; cpu < MAXCPU; cpu++) 660 if (CPU_ISSET(cpu, cpus)) 661 return (EINVAL); 662 663 for (mask = 0, cpu = 0; cpu < end; cpu++) 664 if (CPU_ISSET(cpu, cpus)) 665 mask |= arm_gic_map[cpu]; 666 667 gic_d_write_1(sc, GICD_ITARGETSR(0) + irq, mask); 668 return (0); 669 } 670 671 #ifdef FDT 672 static int 673 gic_map_fdt(device_t dev, u_int ncells, pcell_t *cells, u_int *irqp, 674 enum intr_polarity *polp, enum intr_trigger *trigp) 675 { 676 677 if (ncells == 1) { 678 *irqp = cells[0]; 679 *polp = INTR_POLARITY_CONFORM; 680 *trigp = INTR_TRIGGER_CONFORM; 681 return (0); 682 } 683 if (ncells == 3) { 684 u_int irq, tripol; 685 686 /* 687 * The 1st cell is the interrupt type: 688 * 0 = SPI 689 * 1 = PPI 690 * The 2nd cell contains the interrupt number: 691 * [0 - 987] for SPI 692 * [0 - 15] for PPI 693 * The 3rd cell is the flags, encoded as follows: 694 * bits[3:0] trigger type and level flags 695 * 1 = low-to-high edge triggered 696 * 2 = high-to-low edge triggered 697 * 4 = active high level-sensitive 698 * 8 = active low level-sensitive 699 * bits[15:8] PPI interrupt cpu mask 700 * Each bit corresponds to each of the 8 possible cpus 701 * attached to the GIC. A bit set to '1' indicated 702 * the interrupt is wired to that CPU. 703 */ 704 switch (cells[0]) { 705 case 0: 706 irq = GIC_FIRST_SPI + cells[1]; 707 /* SPI irq is checked later. */ 708 break; 709 case 1: 710 irq = GIC_FIRST_PPI + cells[1]; 711 if (irq > GIC_LAST_PPI) { 712 device_printf(dev, "unsupported PPI interrupt " 713 "number %u\n", cells[1]); 714 return (EINVAL); 715 } 716 break; 717 default: 718 device_printf(dev, "unsupported interrupt type " 719 "configuration %u\n", cells[0]); 720 return (EINVAL); 721 } 722 723 tripol = cells[2] & 0xff; 724 if (tripol & 0xf0 || (tripol & FDT_INTR_LOW_MASK && 725 cells[0] == 0)) 726 device_printf(dev, "unsupported trigger/polarity " 727 "configuration 0x%02x\n", tripol); 728 729 *irqp = irq; 730 *polp = INTR_POLARITY_CONFORM; 731 *trigp = tripol & FDT_INTR_EDGE_MASK ? 732 INTR_TRIGGER_EDGE : INTR_TRIGGER_LEVEL; 733 return (0); 734 } 735 return (EINVAL); 736 } 737 #endif 738 739 static int 740 gic_map_msi(device_t dev, struct intr_map_data_msi *msi_data, u_int *irqp, 741 enum intr_polarity *polp, enum intr_trigger *trigp) 742 { 743 struct gic_irqsrc *gi; 744 745 /* Map a non-GICv2m MSI */ 746 gi = (struct gic_irqsrc *)msi_data->isrc; 747 if (gi == NULL) 748 return (ENXIO); 749 750 *irqp = gi->gi_irq; 751 752 /* MSI/MSI-X interrupts are always edge triggered with high polarity */ 753 *polp = INTR_POLARITY_HIGH; 754 *trigp = INTR_TRIGGER_EDGE; 755 756 return (0); 757 } 758 759 static int 760 gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp, 761 enum intr_polarity *polp, enum intr_trigger *trigp) 762 { 763 u_int irq; 764 enum intr_polarity pol; 765 enum intr_trigger trig; 766 struct arm_gic_softc *sc; 767 struct intr_map_data_msi *dam; 768 #ifdef FDT 769 struct intr_map_data_fdt *daf; 770 #endif 771 #ifdef DEV_ACPI 772 struct intr_map_data_acpi *daa; 773 #endif 774 775 sc = device_get_softc(dev); 776 switch (data->type) { 777 #ifdef FDT 778 case INTR_MAP_DATA_FDT: 779 daf = (struct intr_map_data_fdt *)data; 780 if (gic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol, 781 &trig) != 0) 782 return (EINVAL); 783 KASSERT(irq >= sc->nirqs || 784 (sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) == 0, 785 ("%s: Attempting to map a MSI interrupt from FDT", 786 __func__)); 787 break; 788 #endif 789 #ifdef DEV_ACPI 790 case INTR_MAP_DATA_ACPI: 791 daa = (struct intr_map_data_acpi *)data; 792 irq = daa->irq; 793 pol = daa->pol; 794 trig = daa->trig; 795 break; 796 #endif 797 case INTR_MAP_DATA_MSI: 798 /* Non-GICv2m MSI */ 799 dam = (struct intr_map_data_msi *)data; 800 if (gic_map_msi(dev, dam, &irq, &pol, &trig) != 0) 801 return (EINVAL); 802 break; 803 default: 804 return (ENOTSUP); 805 } 806 807 if (irq >= sc->nirqs) 808 return (EINVAL); 809 if (pol != INTR_POLARITY_CONFORM && pol != INTR_POLARITY_LOW && 810 pol != INTR_POLARITY_HIGH) 811 return (EINVAL); 812 if (trig != INTR_TRIGGER_CONFORM && trig != INTR_TRIGGER_EDGE && 813 trig != INTR_TRIGGER_LEVEL) 814 return (EINVAL); 815 816 *irqp = irq; 817 if (polp != NULL) 818 *polp = pol; 819 if (trigp != NULL) 820 *trigp = trig; 821 return (0); 822 } 823 824 static int 825 arm_gic_map_intr(device_t dev, struct intr_map_data *data, 826 struct intr_irqsrc **isrcp) 827 { 828 int error; 829 u_int irq; 830 struct arm_gic_softc *sc; 831 832 error = gic_map_intr(dev, data, &irq, NULL, NULL); 833 if (error == 0) { 834 sc = device_get_softc(dev); 835 *isrcp = GIC_INTR_ISRC(sc, irq); 836 } 837 return (error); 838 } 839 840 static int 841 arm_gic_setup_intr(device_t dev, struct intr_irqsrc *isrc, 842 struct resource *res, struct intr_map_data *data) 843 { 844 struct arm_gic_softc *sc = device_get_softc(dev); 845 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 846 enum intr_trigger trig; 847 enum intr_polarity pol; 848 849 if ((gi->gi_flags & GI_FLAG_MSI) == GI_FLAG_MSI) { 850 /* GICv2m MSI */ 851 pol = gi->gi_pol; 852 trig = gi->gi_trig; 853 KASSERT(pol == INTR_POLARITY_HIGH, 854 ("%s: MSI interrupts must be active-high", __func__)); 855 KASSERT(trig == INTR_TRIGGER_EDGE, 856 ("%s: MSI interrupts must be edge triggered", __func__)); 857 } else if (data != NULL) { 858 u_int irq; 859 860 /* Get config for resource. */ 861 if (gic_map_intr(dev, data, &irq, &pol, &trig) || 862 gi->gi_irq != irq) 863 return (EINVAL); 864 } else { 865 pol = INTR_POLARITY_CONFORM; 866 trig = INTR_TRIGGER_CONFORM; 867 } 868 869 /* Compare config if this is not first setup. */ 870 if (isrc->isrc_handlers != 0) { 871 if ((pol != INTR_POLARITY_CONFORM && pol != gi->gi_pol) || 872 (trig != INTR_TRIGGER_CONFORM && trig != gi->gi_trig)) 873 return (EINVAL); 874 else 875 return (0); 876 } 877 878 /* For MSI/MSI-X we should have already configured these */ 879 if ((gi->gi_flags & GI_FLAG_MSI) == 0) { 880 if (pol == INTR_POLARITY_CONFORM) 881 pol = INTR_POLARITY_LOW; /* just pick some */ 882 if (trig == INTR_TRIGGER_CONFORM) 883 trig = INTR_TRIGGER_EDGE; /* just pick some */ 884 885 gi->gi_pol = pol; 886 gi->gi_trig = trig; 887 888 /* Edge triggered interrupts need an early EOI sent */ 889 if (gi->gi_trig == INTR_TRIGGER_EDGE) 890 gi->gi_flags |= GI_FLAG_EARLY_EOI; 891 } 892 893 /* 894 * XXX - In case that per CPU interrupt is going to be enabled in time 895 * when SMP is already started, we need some IPI call which 896 * enables it on others CPUs. Further, it's more complicated as 897 * pic_enable_source() and pic_disable_source() should act on 898 * per CPU basis only. Thus, it should be solved here somehow. 899 */ 900 if (isrc->isrc_flags & INTR_ISRCF_PPI) 901 CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu); 902 903 gic_config(sc, gi->gi_irq, gi->gi_trig, gi->gi_pol); 904 arm_gic_bind_intr(dev, isrc); 905 return (0); 906 } 907 908 static int 909 arm_gic_teardown_intr(device_t dev, struct intr_irqsrc *isrc, 910 struct resource *res, struct intr_map_data *data) 911 { 912 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 913 914 if (isrc->isrc_handlers == 0 && (gi->gi_flags & GI_FLAG_MSI) == 0) { 915 gi->gi_pol = INTR_POLARITY_CONFORM; 916 gi->gi_trig = INTR_TRIGGER_CONFORM; 917 } 918 return (0); 919 } 920 921 static void 922 arm_gic_enable_intr(device_t dev, struct intr_irqsrc *isrc) 923 { 924 struct arm_gic_softc *sc = device_get_softc(dev); 925 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 926 927 arm_irq_memory_barrier(gi->gi_irq); 928 gic_irq_unmask(sc, gi->gi_irq); 929 } 930 931 static void 932 arm_gic_disable_intr(device_t dev, struct intr_irqsrc *isrc) 933 { 934 struct arm_gic_softc *sc = device_get_softc(dev); 935 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 936 937 gic_irq_mask(sc, gi->gi_irq); 938 } 939 940 static void 941 arm_gic_pre_ithread(device_t dev, struct intr_irqsrc *isrc) 942 { 943 struct arm_gic_softc *sc = device_get_softc(dev); 944 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 945 946 arm_gic_disable_intr(dev, isrc); 947 gic_c_write_4(sc, GICC_EOIR, gi->gi_irq); 948 } 949 950 static void 951 arm_gic_post_ithread(device_t dev, struct intr_irqsrc *isrc) 952 { 953 954 arm_irq_memory_barrier(0); 955 arm_gic_enable_intr(dev, isrc); 956 } 957 958 static void 959 arm_gic_post_filter(device_t dev, struct intr_irqsrc *isrc) 960 { 961 struct arm_gic_softc *sc = device_get_softc(dev); 962 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 963 964 /* EOI for edge-triggered done earlier. */ 965 if ((gi->gi_flags & GI_FLAG_EARLY_EOI) == GI_FLAG_EARLY_EOI) 966 return; 967 968 arm_irq_memory_barrier(0); 969 gic_c_write_4(sc, GICC_EOIR, gi->gi_irq); 970 } 971 972 static int 973 arm_gic_bind_intr(device_t dev, struct intr_irqsrc *isrc) 974 { 975 struct arm_gic_softc *sc = device_get_softc(dev); 976 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 977 978 if (gi->gi_irq < GIC_FIRST_SPI) 979 return (EINVAL); 980 981 if (CPU_EMPTY(&isrc->isrc_cpu)) { 982 gic_irq_cpu = intr_irq_next_cpu(gic_irq_cpu, &all_cpus); 983 CPU_SETOF(gic_irq_cpu, &isrc->isrc_cpu); 984 } 985 return (gic_bind(sc, gi->gi_irq, &isrc->isrc_cpu)); 986 } 987 988 #ifdef SMP 989 static void 990 arm_gic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus, 991 u_int ipi) 992 { 993 struct arm_gic_softc *sc = device_get_softc(dev); 994 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 995 uint32_t val = 0, i; 996 997 for (i = 0; i < MAXCPU; i++) { 998 if (CPU_ISSET(i, &cpus)) { 999 MPASS(i < GIC_MAXCPU); 1000 val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT; 1001 } 1002 } 1003 1004 gic_d_write_4(sc, GICD_SGIR, val | gi->gi_irq); 1005 } 1006 1007 static int 1008 arm_gic_ipi_setup(device_t dev, u_int ipi, struct intr_irqsrc **isrcp) 1009 { 1010 struct intr_irqsrc *isrc; 1011 struct arm_gic_softc *sc = device_get_softc(dev); 1012 1013 if (sgi_first_unused > GIC_LAST_SGI) 1014 return (ENOSPC); 1015 1016 isrc = GIC_INTR_ISRC(sc, sgi_first_unused); 1017 sgi_to_ipi[sgi_first_unused++] = ipi; 1018 1019 CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu); 1020 1021 *isrcp = isrc; 1022 return (0); 1023 } 1024 #endif 1025 1026 static int 1027 arm_gic_alloc_msi(device_t dev, u_int mbi_start, u_int mbi_count, int count, 1028 int maxcount, struct intr_irqsrc **isrc) 1029 { 1030 struct arm_gic_softc *sc; 1031 int i, irq, end_irq; 1032 bool found; 1033 1034 KASSERT(powerof2(count), ("%s: bad count", __func__)); 1035 KASSERT(powerof2(maxcount), ("%s: bad maxcount", __func__)); 1036 1037 sc = device_get_softc(dev); 1038 1039 mtx_lock_spin(&sc->mutex); 1040 1041 found = false; 1042 for (irq = mbi_start; irq < mbi_start + mbi_count; irq++) { 1043 /* Start on an aligned interrupt */ 1044 if ((irq & (maxcount - 1)) != 0) 1045 continue; 1046 1047 /* Assume we found a valid range until shown otherwise */ 1048 found = true; 1049 1050 /* Check this range is valid */ 1051 for (end_irq = irq; end_irq != irq + count; end_irq++) { 1052 /* No free interrupts */ 1053 if (end_irq == mbi_start + mbi_count) { 1054 found = false; 1055 break; 1056 } 1057 1058 KASSERT((sc->gic_irqs[end_irq].gi_flags & GI_FLAG_MSI)!= 0, 1059 ("%s: Non-MSI interrupt found", __func__)); 1060 1061 /* This is already used */ 1062 if ((sc->gic_irqs[end_irq].gi_flags & GI_FLAG_MSI_USED) == 1063 GI_FLAG_MSI_USED) { 1064 found = false; 1065 break; 1066 } 1067 } 1068 if (found) 1069 break; 1070 } 1071 1072 /* Not enough interrupts were found */ 1073 if (!found || irq == mbi_start + mbi_count) { 1074 mtx_unlock_spin(&sc->mutex); 1075 return (ENXIO); 1076 } 1077 1078 for (i = 0; i < count; i++) { 1079 /* Mark the interrupt as used */ 1080 sc->gic_irqs[irq + i].gi_flags |= GI_FLAG_MSI_USED; 1081 } 1082 mtx_unlock_spin(&sc->mutex); 1083 1084 for (i = 0; i < count; i++) 1085 isrc[i] = (struct intr_irqsrc *)&sc->gic_irqs[irq + i]; 1086 1087 return (0); 1088 } 1089 1090 static int 1091 arm_gic_release_msi(device_t dev, int count, struct intr_irqsrc **isrc) 1092 { 1093 struct arm_gic_softc *sc; 1094 struct gic_irqsrc *gi; 1095 int i; 1096 1097 sc = device_get_softc(dev); 1098 1099 mtx_lock_spin(&sc->mutex); 1100 for (i = 0; i < count; i++) { 1101 gi = (struct gic_irqsrc *)isrc[i]; 1102 1103 KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED, 1104 ("%s: Trying to release an unused MSI-X interrupt", 1105 __func__)); 1106 1107 gi->gi_flags &= ~GI_FLAG_MSI_USED; 1108 } 1109 mtx_unlock_spin(&sc->mutex); 1110 1111 return (0); 1112 } 1113 1114 static int 1115 arm_gic_alloc_msix(device_t dev, u_int mbi_start, u_int mbi_count, 1116 struct intr_irqsrc **isrc) 1117 { 1118 struct arm_gic_softc *sc; 1119 int irq; 1120 1121 sc = device_get_softc(dev); 1122 1123 mtx_lock_spin(&sc->mutex); 1124 /* Find an unused interrupt */ 1125 for (irq = mbi_start; irq < mbi_start + mbi_count; irq++) { 1126 KASSERT((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) != 0, 1127 ("%s: Non-MSI interrupt found", __func__)); 1128 if ((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI_USED) == 0) 1129 break; 1130 } 1131 /* No free interrupt was found */ 1132 if (irq == mbi_start + mbi_count) { 1133 mtx_unlock_spin(&sc->mutex); 1134 return (ENXIO); 1135 } 1136 1137 /* Mark the interrupt as used */ 1138 sc->gic_irqs[irq].gi_flags |= GI_FLAG_MSI_USED; 1139 mtx_unlock_spin(&sc->mutex); 1140 1141 *isrc = (struct intr_irqsrc *)&sc->gic_irqs[irq]; 1142 1143 return (0); 1144 } 1145 1146 static int 1147 arm_gic_release_msix(device_t dev, struct intr_irqsrc *isrc) 1148 { 1149 struct arm_gic_softc *sc; 1150 struct gic_irqsrc *gi; 1151 1152 sc = device_get_softc(dev); 1153 gi = (struct gic_irqsrc *)isrc; 1154 1155 KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED, 1156 ("%s: Trying to release an unused MSI-X interrupt", __func__)); 1157 1158 mtx_lock_spin(&sc->mutex); 1159 gi->gi_flags &= ~GI_FLAG_MSI_USED; 1160 mtx_unlock_spin(&sc->mutex); 1161 1162 return (0); 1163 } 1164 1165 #ifdef DDB 1166 static void 1167 arm_gic_db_show(device_t dev) 1168 { 1169 struct arm_gic_softc *sc = device_get_softc(dev); 1170 uint32_t val; 1171 u_int i; 1172 1173 db_printf("%s CPU registers:\n", device_get_nameunit(dev)); 1174 db_printf(" CTLR: %08x PMR: %08x BPR: %08x RPR: %08x\n", 1175 gic_c_read_4(sc, GICC_CTLR), gic_c_read_4(sc, GICC_PMR), 1176 gic_c_read_4(sc, GICC_BPR), gic_c_read_4(sc, GICC_RPR)); 1177 db_printf("HPPIR: %08x IIDR: %08x\n", gic_c_read_4(sc, GICC_HPPIR), 1178 gic_c_read_4(sc, GICC_IIDR)); 1179 1180 db_printf("%s Distributor registers:\n", device_get_nameunit(dev)); 1181 db_printf(" CTLR: %08x TYPER: %08x IIDR: %08x\n", 1182 gic_d_read_4(sc, GICD_CTLR), gic_d_read_4(sc, GICD_TYPER), 1183 gic_d_read_4(sc, GICD_IIDR)); 1184 for (i = 0; i < sc->nirqs; i++) { 1185 if (i <= GIC_LAST_SGI) 1186 db_printf("SGI %2u ", i); 1187 else if (i <= GIC_LAST_PPI) 1188 db_printf("PPI %2u ", i - GIC_FIRST_PPI); 1189 else 1190 db_printf("SPI %2u ", i - GIC_FIRST_SPI); 1191 db_printf(" grp:%u", 1192 !!(gic_d_read_4(sc, GICD_IGROUPR(i)) & GICD_I_MASK(i))); 1193 db_printf(" enable:%u pend:%u active:%u", 1194 !!(gic_d_read_4(sc, GICD_ISENABLER(i)) & GICD_I_MASK(i)), 1195 !!(gic_d_read_4(sc, GICD_ISPENDR(i)) & GICD_I_MASK(i)), 1196 !!(gic_d_read_4(sc, GICD_ISACTIVER(i)) & GICD_I_MASK(i))); 1197 db_printf(" pri:%u", 1198 (gic_d_read_4(sc, GICD_IPRIORITYR(i)) >> 8 * (i & 0x3)) & 1199 0xff); 1200 db_printf(" trg:%u", 1201 (gic_d_read_4(sc, GICD_ITARGETSR(i)) >> 8 * (i & 0x3)) & 1202 0xff); 1203 val = gic_d_read_4(sc, GICD_ICFGR(i)) >> 2 * (i & 0xf); 1204 if ((val & GICD_ICFGR_POL_MASK) == GICD_ICFGR_POL_LOW) 1205 db_printf(" LO"); 1206 else 1207 db_printf(" HI"); 1208 if ((val & GICD_ICFGR_TRIG_MASK) == GICD_ICFGR_TRIG_LVL) 1209 db_printf(" LV"); 1210 else 1211 db_printf(" ED"); 1212 db_printf("\n"); 1213 } 1214 } 1215 #endif 1216 1217 static device_method_t arm_gic_methods[] = { 1218 /* Bus interface */ 1219 DEVMETHOD(bus_print_child, arm_gic_print_child), 1220 DEVMETHOD(bus_add_child, bus_generic_add_child), 1221 DEVMETHOD(bus_alloc_resource, arm_gic_alloc_resource), 1222 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 1223 DEVMETHOD(bus_activate_resource,bus_generic_activate_resource), 1224 DEVMETHOD(bus_read_ivar, arm_gic_read_ivar), 1225 DEVMETHOD(bus_write_ivar, arm_gic_write_ivar), 1226 1227 /* Interrupt controller interface */ 1228 DEVMETHOD(pic_disable_intr, arm_gic_disable_intr), 1229 DEVMETHOD(pic_enable_intr, arm_gic_enable_intr), 1230 DEVMETHOD(pic_map_intr, arm_gic_map_intr), 1231 DEVMETHOD(pic_setup_intr, arm_gic_setup_intr), 1232 DEVMETHOD(pic_teardown_intr, arm_gic_teardown_intr), 1233 DEVMETHOD(pic_post_filter, arm_gic_post_filter), 1234 DEVMETHOD(pic_post_ithread, arm_gic_post_ithread), 1235 DEVMETHOD(pic_pre_ithread, arm_gic_pre_ithread), 1236 #ifdef SMP 1237 DEVMETHOD(pic_bind_intr, arm_gic_bind_intr), 1238 DEVMETHOD(pic_init_secondary, arm_gic_init_secondary), 1239 DEVMETHOD(pic_ipi_send, arm_gic_ipi_send), 1240 DEVMETHOD(pic_ipi_setup, arm_gic_ipi_setup), 1241 #endif 1242 1243 /* GIC */ 1244 DEVMETHOD(gic_reserve_msi_range, arm_gic_reserve_msi_range), 1245 DEVMETHOD(gic_alloc_msi, arm_gic_alloc_msi), 1246 DEVMETHOD(gic_release_msi, arm_gic_release_msi), 1247 DEVMETHOD(gic_alloc_msix, arm_gic_alloc_msix), 1248 DEVMETHOD(gic_release_msix, arm_gic_release_msix), 1249 #ifdef DDB 1250 DEVMETHOD(gic_db_show, arm_gic_db_show), 1251 #endif 1252 1253 { 0, 0 } 1254 }; 1255 1256 DEFINE_CLASS_0(gic, arm_gic_driver, arm_gic_methods, 1257 sizeof(struct arm_gic_softc)); 1258 1259 #ifdef DDB 1260 DB_SHOW_COMMAND_FLAGS(gic, db_show_gic, CS_OWN) 1261 { 1262 device_t dev; 1263 int t; 1264 bool valid; 1265 1266 valid = false; 1267 t = db_read_token(); 1268 if (t == tIDENT) { 1269 dev = device_lookup_by_name(db_tok_string); 1270 valid = true; 1271 } 1272 db_skip_to_eol(); 1273 if (!valid) { 1274 db_printf("usage: show gic <name>\n"); 1275 return; 1276 } 1277 1278 if (dev == NULL) { 1279 db_printf("device not found\n"); 1280 return; 1281 } 1282 1283 GIC_DB_SHOW(dev); 1284 } 1285 1286 DB_SHOW_ALL_COMMAND(gics, db_show_all_gics) 1287 { 1288 devclass_t dc; 1289 device_t dev; 1290 int i; 1291 1292 dc = devclass_find("gic"); 1293 if (dc == NULL) 1294 return; 1295 1296 for (i = 0; i < devclass_get_maxunit(dc); i++) { 1297 dev = devclass_get_device(dc, i); 1298 if (dev != NULL) 1299 GIC_DB_SHOW(dev); 1300 if (db_pager_quit) 1301 break; 1302 } 1303 } 1304 1305 #endif 1306 1307 /* 1308 * GICv2m support -- the GICv2 MSI/MSI-X controller. 1309 */ 1310 1311 #define GICV2M_MSI_TYPER 0x008 1312 #define MSI_TYPER_SPI_BASE(x) (((x) >> 16) & 0x3ff) 1313 #define MSI_TYPER_SPI_COUNT(x) (((x) >> 0) & 0x3ff) 1314 #define GICv2M_MSI_SETSPI_NS 0x040 1315 #define GICV2M_MSI_IIDR 0xFCC 1316 1317 int 1318 arm_gicv2m_attach(device_t dev) 1319 { 1320 struct arm_gicv2m_softc *sc; 1321 uint32_t typer; 1322 int rid; 1323 1324 sc = device_get_softc(dev); 1325 1326 rid = 0; 1327 sc->sc_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 1328 RF_ACTIVE); 1329 if (sc->sc_mem == NULL) { 1330 device_printf(dev, "Unable to allocate resources\n"); 1331 return (ENXIO); 1332 } 1333 1334 typer = bus_read_4(sc->sc_mem, GICV2M_MSI_TYPER); 1335 sc->sc_spi_start = MSI_TYPER_SPI_BASE(typer); 1336 sc->sc_spi_count = MSI_TYPER_SPI_COUNT(typer); 1337 1338 /* Reserve these interrupts for MSI/MSI-X use */ 1339 GIC_RESERVE_MSI_RANGE(device_get_parent(dev), sc->sc_spi_start, 1340 sc->sc_spi_count); 1341 1342 intr_msi_register(dev, sc->sc_xref); 1343 1344 if (bootverbose) 1345 device_printf(dev, "using spi %u to %u\n", sc->sc_spi_start, 1346 sc->sc_spi_start + sc->sc_spi_count - 1); 1347 1348 return (0); 1349 } 1350 1351 static int 1352 arm_gicv2m_alloc_msi(device_t dev, device_t child, int count, int maxcount, 1353 device_t *pic, struct intr_irqsrc **srcs) 1354 { 1355 struct arm_gicv2m_softc *sc; 1356 int error; 1357 1358 sc = device_get_softc(dev); 1359 error = GIC_ALLOC_MSI(device_get_parent(dev), sc->sc_spi_start, 1360 sc->sc_spi_count, count, maxcount, srcs); 1361 if (error != 0) 1362 return (error); 1363 1364 *pic = dev; 1365 return (0); 1366 } 1367 1368 static int 1369 arm_gicv2m_release_msi(device_t dev, device_t child, int count, 1370 struct intr_irqsrc **isrc) 1371 { 1372 return (GIC_RELEASE_MSI(device_get_parent(dev), count, isrc)); 1373 } 1374 1375 static int 1376 arm_gicv2m_alloc_msix(device_t dev, device_t child, device_t *pic, 1377 struct intr_irqsrc **isrcp) 1378 { 1379 struct arm_gicv2m_softc *sc; 1380 int error; 1381 1382 sc = device_get_softc(dev); 1383 error = GIC_ALLOC_MSIX(device_get_parent(dev), sc->sc_spi_start, 1384 sc->sc_spi_count, isrcp); 1385 if (error != 0) 1386 return (error); 1387 1388 *pic = dev; 1389 return (0); 1390 } 1391 1392 static int 1393 arm_gicv2m_release_msix(device_t dev, device_t child, struct intr_irqsrc *isrc) 1394 { 1395 return (GIC_RELEASE_MSIX(device_get_parent(dev), isrc)); 1396 } 1397 1398 static int 1399 arm_gicv2m_map_msi(device_t dev, device_t child, struct intr_irqsrc *isrc, 1400 uint64_t *addr, uint32_t *data) 1401 { 1402 struct arm_gicv2m_softc *sc = device_get_softc(dev); 1403 struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc; 1404 1405 *addr = vtophys(rman_get_virtual(sc->sc_mem)) + GICv2M_MSI_SETSPI_NS; 1406 *data = gi->gi_irq; 1407 1408 return (0); 1409 } 1410 1411 static device_method_t arm_gicv2m_methods[] = { 1412 /* Device interface */ 1413 DEVMETHOD(device_attach, arm_gicv2m_attach), 1414 1415 /* MSI/MSI-X */ 1416 DEVMETHOD(msi_alloc_msi, arm_gicv2m_alloc_msi), 1417 DEVMETHOD(msi_release_msi, arm_gicv2m_release_msi), 1418 DEVMETHOD(msi_alloc_msix, arm_gicv2m_alloc_msix), 1419 DEVMETHOD(msi_release_msix, arm_gicv2m_release_msix), 1420 DEVMETHOD(msi_map_msi, arm_gicv2m_map_msi), 1421 1422 /* End */ 1423 DEVMETHOD_END 1424 }; 1425 1426 DEFINE_CLASS_0(gicv2m, arm_gicv2m_driver, arm_gicv2m_methods, 1427 sizeof(struct arm_gicv2m_softc)); 1428