git: 289967bbad82 - stable/13 - Stop using the rid as an index in the arm timer
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 15 May 2023 15:45:58 UTC
The branch stable/13 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=289967bbad82442be4578ed148462b21f10e524c commit 289967bbad82442be4578ed148462b21f10e524c Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2023-03-15 13:35:04 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2023-05-15 10:53:59 +0000 Stop using the rid as an index in the arm timer The order of the interrupt array doesn't matter. Store the described interrupts at the start of the array to simplify iterating over them. Reviewed by: imp, kevans Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D39094 (cherry picked from commit 5c4bd8756fbc23a48ddd8976df0b8429311fba83) --- sys/arm/arm/generic_timer.c | 61 ++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 20 deletions(-) diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c index 01ec46977a4e..d84ae3841869 100644 --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -99,12 +99,14 @@ struct arm_tmr_irq { struct resource *res; void *ihl; int rid; + int idx; }; struct arm_tmr_softc { struct arm_tmr_irq irqs[GT_IRQ_COUNT]; uint64_t (*get_cntxct)(bool); uint32_t clkfreq; + int irq_count; struct eventtimer et; bool physical; }; @@ -357,9 +359,12 @@ static int arm_tmr_attach_irq(device_t dev, struct arm_tmr_softc *sc, const struct arm_tmr_irq_defs *irq_def, int rid, int flags) { - sc->irqs[irq_def->idx].res = bus_alloc_resource_any(dev, SYS_RES_IRQ, + struct arm_tmr_irq *irq; + + irq = &sc->irqs[sc->irq_count]; + irq->res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, flags); - if (sc->irqs[irq_def->idx].res == NULL) { + if (irq->res == NULL) { if (bootverbose || (flags & RF_OPTIONAL) == 0) { device_printf(dev, "could not allocate irq for %s interrupt '%s'\n", @@ -369,8 +374,13 @@ arm_tmr_attach_irq(device_t dev, struct arm_tmr_softc *sc, if ((flags & RF_OPTIONAL) == 0) return (ENXIO); - } else if (bootverbose) { - device_printf(dev, "allocated irq for '%s'\n", irq_def->name); + } else { + if (bootverbose) + device_printf(dev, "allocated irq for '%s'\n", + irq_def->name); + irq->rid = rid; + irq->idx = irq_def->idx; + sc->irq_count++; } return (0); @@ -461,11 +471,9 @@ arm_tmr_fdt_attach(device_t dev) error = arm_tmr_attach(dev); out: if (error != 0) { - for (i = 0; i < GT_IRQ_COUNT; i++) { - if (sc->irqs[i].res != NULL) { - bus_release_resource(dev, SYS_RES_IRQ, - sc->irqs[i].rid, sc->irqs[i].res); - } + for (i = 0; i < sc->irq_count; i++) { + bus_release_resource(dev, SYS_RES_IRQ, sc->irqs[i].rid, + sc->irqs[i].res); } } @@ -544,11 +552,9 @@ arm_tmr_acpi_attach(device_t dev) error = arm_tmr_attach(dev); out: if (error != 0) { - for (int i = 0; i < GT_IRQ_COUNT; i++) { - if (sc->irqs[i].res != NULL) { - bus_release_resource(dev, SYS_RES_IRQ, - sc->irqs[i].rid, sc->irqs[i].res); - } + for (int i = 0; i < sc->irq_count; i++) { + bus_release_resource(dev, SYS_RES_IRQ, + sc->irqs[i].rid, sc->irqs[i].res); } } return (error); @@ -559,7 +565,9 @@ static int arm_tmr_attach(device_t dev) { struct arm_tmr_softc *sc; +#ifdef INVARIANTS const struct arm_tmr_irq_defs *irq_def; +#endif #ifdef FDT phandle_t node; pcell_t clock; @@ -600,13 +608,25 @@ arm_tmr_attach(device_t dev) return (ENXIO); } +#ifdef INVARIANTS /* Confirm that non-optional irqs were allocated before coming in. */ for (i = 0; i < nitems(arm_tmr_irq_defs); i++) { + int j; + irq_def = &arm_tmr_irq_defs[i]; - MPASS(sc->irqs[irq_def->idx].res != NULL || - (irq_def->flags & RF_OPTIONAL) != 0); + /* Skip optional interrupts */ + if ((irq_def->flags & RF_OPTIONAL) != 0) + continue; + + for (j = 0; j < sc->irq_count; j++) { + if (sc->irqs[j].idx == irq_def->idx) + break; + } + KASSERT(j < sc->irq_count, ("%s: Missing required interrupt %s", + __func__, irq_def->name)); } +#endif #ifdef __aarch64__ /* Use the virtual timer if we have one. */ @@ -626,15 +646,16 @@ arm_tmr_attach(device_t dev) arm_tmr_sc = sc; /* Setup secure, non-secure and virtual IRQs handler */ - for (i = first_timer; i <= last_timer; i++) { - /* If we do not have the interrupt, skip it. */ - if (sc->irqs[i].res == NULL) + for (i = 0; i < sc->irq_count; i++) { + /* Only enable IRQs on timers we expect to use */ + if (sc->irqs[i].idx < first_timer || + sc->irqs[i].idx > last_timer) continue; error = bus_setup_intr(dev, sc->irqs[i].res, INTR_TYPE_CLK, arm_tmr_intr, NULL, sc, &sc->irqs[i].ihl); if (error) { device_printf(dev, "Unable to alloc int resource.\n"); - for (int j = first_timer; j < i; j++) + for (int j = 0; j < i; j++) bus_teardown_intr(dev, sc->irqs[j].res, &sc->irqs[j].ihl); return (ENXIO);