Limit the number of CPUs in the gicv1/2 driver

The GICv2 can only send IPIs to 8 CPUs. Because of this it should only
be in machines with no more than 8 cores.

Create a new macro to hold this limit to reduce the size of the softc.

Reviewed by:	emaste
Sponsored by:	Arm Ltd
Differential Revision:	https://reviews.freebsd.org/D41322
This commit is contained in:
Andrew Turner 2023-08-04 16:06:44 +01:00
parent 348bea10b6
commit a0e20c0ded
2 changed files with 23 additions and 5 deletions

View file

@ -146,7 +146,7 @@ static int gic_debug_spurious = 0;
#endif
TUNABLE_INT("hw.gic.debug_spurious", &gic_debug_spurious);
static u_int arm_gic_map[MAXCPU];
static u_int arm_gic_map[GIC_MAXCPU];
static struct arm_gic_softc *gic_sc = NULL;
@ -209,6 +209,7 @@ arm_gic_init_secondary(device_t dev)
/* Set the mask so we can find this CPU to send it IPIs */
cpu = PCPU_GET(cpuid);
MPASS(cpu < GIC_MAXCPU);
arm_gic_map[cpu] = gic_cpu_mask(sc);
for (irq = 0; irq < sc->nirqs; irq += 4)
@ -317,6 +318,12 @@ arm_gic_attach(device_t dev)
if (gic_sc)
return (ENXIO);
if (mp_ncpus > GIC_MAXCPU) {
device_printf(dev, "Too many CPUs for IPIs to work (%d > %d)\n",
mp_ncpus, GIC_MAXCPU);
return (ENXIO);
}
sc = device_get_softc(dev);
if (bus_alloc_resources(dev, arm_gic_spec, sc->gic_res)) {
@ -362,6 +369,7 @@ arm_gic_attach(device_t dev)
/* Find the current cpu mask */
mask = gic_cpu_mask(sc);
/* Set the mask so we can find this CPU to send it IPIs */
MPASS(PCPU_GET(cpuid) < GIC_MAXCPU);
arm_gic_map[PCPU_GET(cpuid)] = mask;
/* Set all four targets to this cpu */
mask |= mask << 8;
@ -649,7 +657,7 @@ gic_bind(struct arm_gic_softc *sc, u_int irq, cpuset_t *cpus)
{
uint32_t cpu, end, mask;
end = min(mp_ncpus, 8);
end = min(mp_ncpus, GIC_MAXCPU);
for (cpu = end; cpu < MAXCPU; cpu++)
if (CPU_ISSET(cpu, cpus))
return (EINVAL);
@ -988,9 +996,12 @@ arm_gic_ipi_send(device_t dev, struct intr_irqsrc *isrc, cpuset_t cpus,
struct gic_irqsrc *gi = (struct gic_irqsrc *)isrc;
uint32_t val = 0, i;
for (i = 0; i < MAXCPU; i++)
if (CPU_ISSET(i, &cpus))
for (i = 0; i < MAXCPU; i++) {
if (CPU_ISSET(i, &cpus)) {
MPASS(i < GIC_MAXCPU);
val |= arm_gic_map[i] << GICD_SGI_TARGET_SHIFT;
}
}
gic_d_write_4(sc, GICD_SGIR, val | gi->gi_irq);
}

View file

@ -39,6 +39,13 @@
#ifndef _ARM_GIC_H_
#define _ARM_GIC_H_
/* The GICv1/2 only supports 8 CPUs */
#if MAXCPU > 8
#define GIC_MAXCPU 8
#else
#define GIC_MAXCPU MAXCPU
#endif
struct arm_gic_softc {
device_t gic_dev;
void * gic_intrhand;
@ -50,7 +57,7 @@ struct arm_gic_softc {
struct mtx mutex;
uint32_t nirqs;
uint32_t typer;
uint32_t last_irq[MAXCPU];
uint32_t last_irq[GIC_MAXCPU];
uint32_t gic_iidr;
u_int gic_bus;