Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/gicv3_its.c
Show First 20 Lines • Show All 574 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
its_init_cpu(device_t dev, struct gicv3_its_softc *sc) | its_init_cpu(device_t dev, struct gicv3_its_softc *sc) | ||||
{ | { | ||||
device_t gicv3; | device_t gicv3; | ||||
vm_paddr_t target; | vm_paddr_t target; | ||||
uint64_t xbaser, tmp; | uint64_t xbaser, tmp; | ||||
uint32_t ctlr; | uint32_t ctlr; | ||||
u_int cpuid; | u_int cpuid; | ||||
int domain; | |||||
if (!CPU_ISSET(PCPU_GET(cpuid), &sc->sc_cpus)) | |||||
return (0); | |||||
if (bus_get_domain(dev, &domain) == 0) { | |||||
if (PCPU_GET(domain) != domain) | |||||
return (0); | |||||
} | |||||
gicv3 = device_get_parent(dev); | gicv3 = device_get_parent(dev); | ||||
cpuid = PCPU_GET(cpuid); | cpuid = PCPU_GET(cpuid); | ||||
if (!CPU_ISSET(cpuid, &sc->sc_cpus)) | |||||
return (0); | |||||
/* Check if the ITS is enabled on this CPU */ | /* Check if the ITS is enabled on this CPU */ | ||||
if ((gic_r_read_4(gicv3, GICR_TYPER) & GICR_TYPER_PLPIS) == 0) { | if ((gic_r_read_4(gicv3, GICR_TYPER) & GICR_TYPER_PLPIS) == 0) { | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
/* Disable LPIs */ | /* Disable LPIs */ | ||||
ctlr = gic_r_read_4(gicv3, GICR_CTLR); | ctlr = gic_r_read_4(gicv3, GICR_CTLR); | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | if (err != 0) | ||||
return (err); | return (err); | ||||
/* Protects access to the device list */ | /* Protects access to the device list */ | ||||
mtx_init(&sc->sc_its_dev_lock, "ITS device lock", NULL, MTX_SPIN); | mtx_init(&sc->sc_its_dev_lock, "ITS device lock", NULL, MTX_SPIN); | ||||
/* Protects access to the ITS command circular buffer. */ | /* Protects access to the ITS command circular buffer. */ | ||||
mtx_init(&sc->sc_its_cmd_lock, "ITS cmd lock", NULL, MTX_SPIN); | mtx_init(&sc->sc_its_cmd_lock, "ITS cmd lock", NULL, MTX_SPIN); | ||||
if (bus_get_domain(dev, &domain) == 0) { | |||||
CPU_ZERO(&sc->sc_cpus); | CPU_ZERO(&sc->sc_cpus); | ||||
if (bus_get_domain(dev, &domain) == 0) { | |||||
if (domain < MAXMEMDOM) | if (domain < MAXMEMDOM) | ||||
CPU_COPY(&cpuset_domain[domain], &sc->sc_cpus); | CPU_COPY(&cpuset_domain[domain], &sc->sc_cpus); | ||||
} else { | } else { | ||||
/* XXX : cannot handle more than one ITS per cpu */ | |||||
if (device_get_unit(dev) == 0) | |||||
CPU_COPY(&all_cpus, &sc->sc_cpus); | CPU_COPY(&all_cpus, &sc->sc_cpus); | ||||
} | } | ||||
/* Allocate the command circular buffer */ | /* Allocate the command circular buffer */ | ||||
gicv3_its_cmdq_init(sc); | gicv3_its_cmdq_init(sc); | ||||
/* Allocate the per-CPU collections */ | /* Allocate the per-CPU collections */ | ||||
for (int cpu = 0; cpu <= mp_maxid; cpu++) | for (int cpu = 0; cpu <= mp_maxid; cpu++) | ||||
if (CPU_ISSET(cpu, &sc->sc_cpus) != 0) | if (CPU_ISSET(cpu, &sc->sc_cpus) != 0) | ||||
▲ Show 20 Lines • Show All 986 Lines • ▼ Show 20 Lines | gicv3_its_acpi_attach(device_t dev) | ||||
sc = device_get_softc(dev); | sc = device_get_softc(dev); | ||||
err = gicv3_its_attach(dev); | err = gicv3_its_attach(dev); | ||||
if (err != 0) | if (err != 0) | ||||
return (err); | return (err); | ||||
sc->sc_pic = intr_pic_register(dev, | sc->sc_pic = intr_pic_register(dev, | ||||
device_get_unit(dev) + ACPI_MSI_XREF); | device_get_unit(dev) + ACPI_MSI_XREF); | ||||
intr_pic_add_handler(device_get_parent(dev), sc->sc_pic, | intr_pic_add_handler(device_get_parent(dev), sc->sc_pic, | ||||
gicv3_its_intr, sc, GIC_FIRST_LPI, LPI_NIRQS); | gicv3_its_intr, sc, sc->sc_irq_base, sc->sc_irq_length); | ||||
/* Register this device to handle MSI interrupts */ | /* Register this device to handle MSI interrupts */ | ||||
intr_msi_register(dev, device_get_unit(dev) + ACPI_MSI_XREF); | intr_msi_register(dev, device_get_unit(dev) + ACPI_MSI_XREF); | ||||
return (0); | return (0); | ||||
} | } | ||||
#endif | #endif |