diff --git a/sys/arch/arm/cortex/gicv3_its.c b/sys/arch/arm/cortex/gicv3_its.c index 865ef18456b7..46f8aefc9293 100644 --- a/sys/arch/arm/cortex/gicv3_its.c +++ b/sys/arch/arm/cortex/gicv3_its.c @@ -496,8 +496,9 @@ gicv3_its_msi_alloc(struct arm_pci_msi *msi, int *count, gicv3_its_msi_enable(its, lpi, *count); /* - * Record target PE + * Record devid and target PE */ + its->its_devid[lpi - its->its_pic->pic_irqbase] = devid; its->its_targets[lpi - its->its_pic->pic_irqbase] = ci; /* @@ -565,8 +566,9 @@ gicv3_its_msix_alloc(struct arm_pci_msi *msi, u_int *table_indexes, int *count, gicv3_its_msix_enable(its, lpi, msix_vec, bst, bsh); /* - * Record target PE + * Record devid and target PE */ + its->its_devid[lpi - its->its_pic->pic_irqbase] = devid; its->its_targets[lpi - its->its_pic->pic_irqbase] = ci; /* @@ -601,7 +603,7 @@ gicv3_its_msi_intr_establish(struct arm_pci_msi *msi, /* Invalidate LPI configuration tables */ pa = its->its_pa[lpi - its->its_pic->pic_irqbase]; KASSERT(pa != NULL); - const uint32_t devid = gicv3_its_devid(pa->pa_pc, pa->pa_tag); + const uint32_t devid = its->its_devid[lpi - its->its_pic->pic_irqbase]; gits_command_inv(its, devid, lpi - its->its_pic->pic_irqbase); return intrh; @@ -623,6 +625,7 @@ gicv3_its_msi_intr_release(struct arm_pci_msi *msi, pci_intr_handle_t *pih, gicv3_its_msi_disable(its, lpi); gicv3_its_msi_free_lpi(its, lpi); its->its_targets[lpi - its->its_pic->pic_irqbase] = NULL; + its->its_devid[lpi - its->its_pic->pic_irqbase] = 0; struct intrsource * const is = its->its_pic->pic_sources[lpi - its->its_pic->pic_irqbase]; if (is != NULL) @@ -784,6 +787,7 @@ gicv3_its_cpu_init(void *priv, struct cpu_info *ci) /* * Map collection ID of this CPU's index to this CPU's redistributor. */ + mutex_enter(its->its_lock); gits_command_mapc(its, cpu_index(ci), rdbase, true); gits_command_invall(its, cpu_index(ci)); gits_wait(its); @@ -797,10 +801,12 @@ gicv3_its_cpu_init(void *priv, struct cpu_info *ci) pa = its->its_pa[irq]; KASSERT(pa != NULL); - const uint32_t devid = gicv3_its_devid(pa->pa_pc, pa->pa_tag); + const uint32_t devid = its->its_devid[irq]; gits_command_movi(its, devid, irq, cpu_index(ci)); gits_command_sync(its, its->its_rdbase[cpu_index(ci)]); } + gits_wait(its); + mutex_exit(its->its_lock); its->its_cpuonline[cpu_index(ci)] = true; } @@ -865,6 +871,7 @@ gicv3_its_init(struct gicv3_softc *sc, bus_space_handle_t bsh, KASSERT(its->its_pic->pic_maxsources > 0); its->its_pa = kmem_zalloc(sizeof(struct pci_attach_args *) * its->its_pic->pic_maxsources, KM_SLEEP); its->its_targets = kmem_zalloc(sizeof(struct cpu_info *) * its->its_pic->pic_maxsources, KM_SLEEP); + its->its_devid = kmem_zalloc(sizeof(uint32_t) * its->its_pic->pic_maxsources, KM_SLEEP); its->its_gic = sc; its->its_rdbase = kmem_zalloc(sizeof(*its->its_rdbase) * ncpu, KM_SLEEP); its->its_cpuonline = kmem_zalloc(sizeof(*its->its_cpuonline) * ncpu, KM_SLEEP); @@ -874,6 +881,7 @@ gicv3_its_init(struct gicv3_softc *sc, bus_space_handle_t bsh, its->its_cb.priv = its; LIST_INIT(&its->its_devices); LIST_INSERT_HEAD(&sc->sc_lpi_callbacks, &its->its_cb, list); + its->its_lock = mutex_obj_alloc(MUTEX_SPIN, IPL_NONE); gicv3_its_command_init(sc, its); gicv3_its_table_init(sc, its); diff --git a/sys/arch/arm/cortex/gicv3_its.h b/sys/arch/arm/cortex/gicv3_its.h index d27702fd4c75..b931f05287fd 100644 --- a/sys/arch/arm/cortex/gicv3_its.h +++ b/sys/arch/arm/cortex/gicv3_its.h @@ -61,6 +61,7 @@ struct gicv3_its { struct pic_softc *its_pic; struct pci_attach_args **its_pa; struct cpu_info **its_targets; + uint32_t *its_devid; LIST_HEAD(, gicv3_its_device) its_devices; @@ -68,6 +69,8 @@ struct gicv3_its { struct gicv3_dma its_tab[8]; /* ITS tables */ struct arm_pci_msi its_msi; + + kmutex_t *its_lock; }; int gicv3_its_init(struct gicv3_softc *, bus_space_handle_t, uint64_t, uint32_t);