Lines Matching +full:revision +full:- +full:id2
1 /*-
2 * Copyright (c) 2015-2016 The FreeBSD Foundation
112 static u_int sgi_to_ipi[GIC_LAST_SGI - GIC_FIRST_SGI + 1];
144 /* MSI/MSI-X */
166 * Driver-specific definitions.
173 /* Destination registers, either Distributor or Re-Distributor */
185 /* be used for MSI/MSI-X interrupts */
187 /* for a MSI/MSI-X interrupt */
226 rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)].res;
227 offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)].offset;
238 rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)].res;
239 offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)].offset;
250 rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)].res;
251 offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)].offset;
262 rdist = sc->gic_redists.pcpu[PCPU_GET(cpuid)].res;
263 offset += sc->gic_redists.pcpu[PCPU_GET(cpuid)].offset;
275 KASSERT((start + count) < sc->gic_nirqs,
277 start, count, sc->gic_nirqs));
279 KASSERT(sc->gic_irqs[start + i].gi_isrc.isrc_handlers == 0,
282 KASSERT(sc->gic_irqs[start + i].gi_pol == INTR_POLARITY_CONFORM,
285 KASSERT(sc->gic_irqs[start + i].gi_trig == INTR_TRIGGER_CONFORM,
288 sc->gic_irqs[start + i].gi_pol = INTR_POLARITY_HIGH;
289 sc->gic_irqs[start + i].gi_trig = INTR_TRIGGER_EDGE;
290 sc->gic_irqs[start + i].gi_flags |= GI_FLAG_MSI;
310 sc->gic_registered = FALSE;
311 sc->dev = dev;
315 mtx_init(&sc->gic_mtx, "GICv3 lock", NULL, MTX_SPIN);
319 * One entry for Distributor and all remaining for Re-Distributor.
321 sc->gic_res = malloc(
322 sizeof(*sc->gic_res) * (sc->gic_redists.nregions + 1),
326 for (i = 0, rid = 0; i < (sc->gic_redists.nregions + 1); i++, rid++) {
327 sc->gic_res[rid] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
329 if (sc->gic_res[rid] == NULL)
336 sc->gic_dist = sc->gic_res[0];
339 * Re-Dristributor interface
342 sc->gic_redists.regions = malloc(
343 sizeof(*sc->gic_redists.regions) * sc->gic_redists.nregions,
346 /* Fill-up bus_space information for each region. */
347 for (i = 0, rid = 1; i < sc->gic_redists.nregions; i++, rid++)
348 sc->gic_redists.regions[i] = sc->gic_res[rid];
352 sc->gic_nirqs = GICD_TYPER_I_NUM(typer);
353 if (sc->gic_nirqs > GIC_I_NUM_MAX)
354 sc->gic_nirqs = GIC_I_NUM_MAX;
356 sc->gic_irqs = malloc(sizeof(*sc->gic_irqs) * sc->gic_nirqs,
359 for (irq = 0; irq < sc->gic_nirqs; irq++) {
362 sc->gic_irqs[irq].gi_irq = irq;
363 sc->gic_irqs[irq].gi_pol = INTR_POLARITY_CONFORM;
364 sc->gic_irqs[irq].gi_trig = INTR_TRIGGER_CONFORM;
366 isrc = &sc->gic_irqs[irq].gi_isrc;
368 err = intr_isrc_register(isrc, sc->dev,
369 INTR_ISRCF_IPI, "%s,i%u", name, irq - GIC_FIRST_SGI);
371 err = intr_isrc_register(isrc, sc->dev,
372 INTR_ISRCF_PPI, "%s,p%u", name, irq - GIC_FIRST_PPI);
374 err = intr_isrc_register(isrc, sc->dev, 0,
375 "%s,s%u", name, irq - GIC_FIRST_SPI);
379 free(sc->gic_irqs, M_DEVBUF);
384 mtx_init(&sc->gic_mbi_mtx, "GICv3 mbi lock", NULL, MTX_DEF);
385 if (sc->gic_mbi_start > 0) {
386 if (!sc->gic_mbi_end) {
391 sc->gic_mbi_end = sc->gic_nirqs - 1;
393 gic_v3_reserve_msi_range(dev, sc->gic_mbi_start,
394 sc->gic_mbi_end - sc->gic_mbi_start);
397 device_printf(dev, "using spi %u to %u\n", sc->gic_mbi_start,
398 sc->gic_mbi_end);
403 * Read the Peripheral ID2 register. This is an implementation
407 sc->gic_pidr2 = gic_d_read(sc, 4, GICD_PIDR2);
410 sc->gic_idbits = GICD_TYPER_IDBITS(typer);
414 sc->gic_nirqs, (1 << sc->gic_idbits) - 1);
439 if (sc->gic_registered)
442 for (rid = 0; rid < (sc->gic_redists.nregions + 1); rid++)
443 bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->gic_res[rid]);
445 free(sc->gic_redists.pcpu, M_GIC_V3);
447 free(sc->ranges, M_GIC_V3);
448 free(sc->gic_res, M_GIC_V3);
449 free(sc->gic_redists.regions, M_GIC_V3);
475 if (di->gic_domain < 0)
478 *domain = di->gic_domain;
492 *result = (intr_nirq - sc->gic_nirqs) / sc->gic_nchildren;
495 *result = (uintptr_t)&sc->gic_redists.pcpu[PCPU_GET(cpuid)];
503 GICR_PIDR2_ARCH(sc->gic_pidr2) == GICR_PIDR2_ARCH_GICv3 ||
504 GICR_PIDR2_ARCH(sc->gic_pidr2) == GICR_PIDR2_ARCH_GICv4,
506 GICR_PIDR2_ARCH(sc->gic_pidr2), sc->gic_pidr2));
507 *result = GICR_PIDR2_ARCH(sc->gic_pidr2);
510 KASSERT(sc->gic_bus != GIC_BUS_UNKNOWN,
512 KASSERT(sc->gic_bus <= GIC_BUS_MAX,
513 ("gic_v3_read_ivar: Invalid bus type %u", sc->gic_bus));
514 *result = sc->gic_bus;
520 *result = di->is_vgic;
566 start = rle->start;
567 end = rle->end;
568 count = rle->count;
572 for (j = 0; j < sc->nranges; j++) {
573 if (start >= sc->ranges[j].bus && end <
574 sc->ranges[j].bus + sc->ranges[j].size) {
575 start -= sc->ranges[j].bus;
576 start += sc->ranges[j].host;
577 end -= sc->ranges[j].bus;
578 end += sc->ranges[j].host;
582 if (j == sc->nranges && sc->nranges != 0) {
585 "%#jx-%#jx\n", (uintmax_t)start, (uintmax_t)end);
603 pic = sc->gic_pic;
609 * Chip revision: Pass 1.0 (early version)
628 if (__predict_false(active_irq >= sc->gic_nirqs))
631 tf = curthread->td_intr_frame;
632 gi = &sc->gic_irqs[active_irq];
637 intr_ipi_dispatch(sgi_to_ipi[gi->gi_irq]);
639 device_printf(sc->dev, "SGI %ju on UP system detected\n",
640 (uintmax_t)(active_irq - GIC_FIRST_SGI));
644 if (gi->gi_trig == INTR_TRIGGER_EDGE)
645 gic_icc_write(EOIR1, gi->gi_irq);
647 if (intr_isrc_dispatch(&gi->gi_isrc, tf) != 0) {
648 if (gi->gi_trig != INTR_TRIGGER_EDGE)
649 gic_icc_write(EOIR1, gi->gi_irq);
650 gic_v3_disable_intr(sc->dev, &gi->gi_isrc);
651 device_printf(sc->dev,
673 * [0 - 987] for SPI
674 * [0 - 15] for PPI
679 * 4 = level-sensitive
680 * 8 = level-sensitive (PPI only)
739 /* SPI-mapped MSI */
740 gi = (struct gic_v3_irqsrc *)msi_data->isrc;
744 *irqp = gi->gi_irq;
746 /* MSI/MSI-X interrupts are always edge triggered with high polarity */
771 switch (data->type) {
775 if (gic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol,
783 irq = daa->irq;
784 pol = daa->pol;
785 trig = daa->trig;
789 /* SPI-mapped MSI */
798 if (irq >= sc->gic_nirqs)
850 struct intr_irqsrc *isrc = args->isrc;
852 device_t dev = args->dev;
853 u_int irq = gi->gi_irq;
863 mtx_lock_spin(&sc->gic_mtx);
865 if (isrc->isrc_flags & INTR_ISRCF_PPI)
866 CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
875 if (gi->gi_trig == INTR_TRIGGER_LEVEL)
890 mtx_unlock_spin(&sc->gic_mtx);
911 if (gi->gi_irq != irq || pol == INTR_POLARITY_CONFORM ||
916 if (isrc->isrc_handlers != 0) {
917 if (pol != gi->gi_pol || trig != gi->gi_trig)
923 /* For MSI/MSI-X we should have already configured these */
924 if ((gi->gi_flags & GI_FLAG_MSI) == 0) {
925 gi->gi_pol = pol;
926 gi->gi_trig = trig;
932 if (isrc->isrc_flags & INTR_ISRCF_PPI) {
953 if (isrc->isrc_handlers == 0 && (gi->gi_flags & GI_FLAG_MSI) == 0) {
954 gi->gi_pol = INTR_POLARITY_CONFORM;
955 gi->gi_trig = INTR_TRIGGER_CONFORM;
970 irq = gi->gi_irq;
973 /* SGIs and PPIs in corresponding Re-Distributor */
989 struct gic_v3_irqsrc *gi = (struct gic_v3_irqsrc *)args->isrc;
990 device_t dev = args->dev;
992 u_int irq = gi->gi_irq;
994 /* SGIs and PPIs in corresponding Re-Distributor */
1009 irq = gi->gi_irq;
1042 gic_icc_write(EOIR1, gi->gi_irq);
1057 if (gi->gi_trig == INTR_TRIGGER_EDGE)
1060 gic_icc_write(EOIR1, gi->gi_irq);
1072 KASSERT(gi->gi_irq >= GIC_FIRST_SPI && gi->gi_irq <= GIC_LAST_SPI,
1077 if (CPU_EMPTY(&isrc->isrc_cpu)) {
1079 CPU_SETOF(gic_irq_cpu, &isrc->isrc_cpu);
1080 gic_d_write(sc, 8, GICD_IROUTER(gi->gi_irq),
1087 cpu = CPU_FFS(&isrc->isrc_cpu) - 1;
1088 gic_d_write(sc, 8, GICD_IROUTER(gi->gi_irq), CPU_AFFINITY(cpu));
1141 for (i = 0; i < sc->gic_nchildren; i++) {
1142 child = sc->gic_children[i];
1158 irq = gi->gi_irq;
1207 CPU_SET(PCPU_GET(cpuid), &isrc->isrc_cpu);
1229 res = sc->gic_dist;
1233 res = sc->gic_redists.pcpu[cpuid].res;
1234 offset = sc->gic_redists.pcpu[PCPU_GET(cpuid)].offset;
1243 if (us_left-- == 0)
1278 device_printf(sc->dev, "ERROR: CPU%u cannot enable CPU interface "
1282 device_printf(sc->dev,
1299 /* Priority mask to minimum - accept all interrupts */
1325 /* Set all SPIs to be Group 1 Non-secure */
1326 for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i += GICD_I_PER_IGROUPRn)
1330 for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i += GICD_I_PER_ICFGRn)
1335 i < sc->gic_nirqs; i += GICD_I_PER_IPRIORITYn) {
1342 * Re-Distributor registers.
1344 for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i += GICD_I_PER_ISENABLERn)
1360 for (i = GIC_FIRST_SPI; i < sc->gic_nirqs; i++)
1366 /* Re-Distributor */
1370 sc->gic_redists.pcpu = mallocarray(mp_maxid + 1,
1371 sizeof(sc->gic_redists.pcpu[0]), M_GIC_V3, M_WAITOK);
1394 device_printf(sc->dev,
1395 "Start searching for Re-Distributor\n");
1397 /* Iterate through Re-Distributor regions */
1398 for (i = 0; i < sc->gic_redists.nregions; i++) {
1400 r_res = sc->gic_redists.regions[i];
1408 device_printf(sc->dev,
1409 "No Re-Distributor found for CPU%u\n", cpuid);
1418 ("Invalid pointer to per-CPU redistributor"));
1420 sc->gic_redists.pcpu[cpuid].res = r_res;
1421 sc->gic_redists.pcpu[cpuid].offset = offset;
1422 sc->gic_redists.pcpu[cpuid].lpi_enabled = false;
1424 device_printf(sc->dev,
1425 "CPU%u Re-Distributor has been found\n",
1437 !sc->gic_redists.single && (typer & GICR_TYPER_LAST) == 0);
1440 device_printf(sc->dev, "No Re-Distributor found for CPU%u\n", cpuid);
1451 /* Wake up Re-Distributor for this CPU */
1456 * ChildrenAsleep to become zero following the processor power-on.
1460 if (us_left-- == 0) {
1461 panic("Could not wake Re-Distributor for CPU%u",
1467 device_printf(sc->dev, "CPU%u Re-Distributor woke up\n",
1488 /* Configure SGIs and PPIs to be Group1 Non-secure */
1511 * SPI-mapped Message Based Interrupts -- a GICv3 MSI/MSI-X controller.
1527 mtx_lock(&sc->gic_mbi_mtx);
1532 if ((irq & (maxcount - 1)) != 0)
1546 KASSERT((sc->gic_irqs[end_irq].gi_flags & GI_FLAG_MSI)!= 0,
1547 ("%s: Non-MSI interrupt found", __func__));
1550 if ((sc->gic_irqs[end_irq].gi_flags & GI_FLAG_MSI_USED) ==
1562 mtx_unlock(&sc->gic_mbi_mtx);
1568 sc->gic_irqs[irq + i].gi_flags |= GI_FLAG_MSI_USED;
1570 mtx_unlock(&sc->gic_mbi_mtx);
1573 isrc[i] = (struct intr_irqsrc *)&sc->gic_irqs[irq + i];
1587 mtx_lock(&sc->gic_mbi_mtx);
1591 KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED,
1592 ("%s: Trying to release an unused MSI-X interrupt",
1595 gi->gi_flags &= ~GI_FLAG_MSI_USED;
1597 mtx_unlock(&sc->gic_mbi_mtx);
1611 mtx_lock(&sc->gic_mbi_mtx);
1614 KASSERT((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI) != 0,
1615 ("%s: Non-MSI interrupt found", __func__));
1616 if ((sc->gic_irqs[irq].gi_flags & GI_FLAG_MSI_USED) == 0)
1621 mtx_unlock(&sc->gic_mbi_mtx);
1626 sc->gic_irqs[irq].gi_flags |= GI_FLAG_MSI_USED;
1627 mtx_unlock(&sc->gic_mbi_mtx);
1629 *isrcp = (struct intr_irqsrc *)&sc->gic_irqs[irq];
1643 KASSERT((gi->gi_flags & GI_FLAG_MSI_USED) == GI_FLAG_MSI_USED,
1644 ("%s: Trying to release an unused MSI-X interrupt", __func__));
1646 mtx_lock(&sc->gic_mbi_mtx);
1647 gi->gi_flags &= ~GI_FLAG_MSI_USED;
1648 mtx_unlock(&sc->gic_mbi_mtx);
1661 error = gic_v3_gic_alloc_msi(dev, sc->gic_mbi_start,
1662 sc->gic_mbi_end - sc->gic_mbi_start, count, maxcount, isrc);
1685 error = gic_v3_gic_alloc_msix(dev, sc->gic_mbi_start,
1686 sc->gic_mbi_end - sc->gic_mbi_start, isrc);
1708 *addr = vtophys(rman_get_virtual(sc->gic_dist)) + GICD_SETSPI_NSR;
1709 *data = gi->gi_irq;