git: 5c4bd8756fbc - main - Stop using the rid as an index in the arm timer
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 15 Mar 2023 15:49:18 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=5c4bd8756fbc23a48ddd8976df0b8429311fba83 commit 5c4bd8756fbc23a48ddd8976df0b8429311fba83 Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2023-03-15 13:35:04 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2023-03-15 15:49:00 +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 --- 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 b36fbdf8dcbe..b1f42cbc5b34 100644 --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -103,12 +103,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; }; @@ -403,9 +405,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", @@ -415,8 +420,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); @@ -507,11 +517,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); } } @@ -590,11 +598,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); @@ -605,7 +611,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; @@ -646,13 +654,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__ /* @@ -677,15 +697,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);