static void gic_v3_acpi_identify(driver_t *driver, device_t parent) { struct madt_table_data madt_data; ACPI_TABLE_MADT *madt; vm_paddr_t physaddr; device_t dev; physaddr = acpi_find_table(ACPI_SIG_MADT); if (physaddr == 0) return; madt = acpi_map_table(physaddr, ACPI_SIG_MADT); if (madt == NULL) { device_printf(parent, "gic: Unable to map the MADT\n"); return; } madt_data.parent = parent; madt_data.dist = NULL; madt_data.count = 0; acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, madt_handler, &madt_data); if (madt_data.dist == NULL) { device_printf(parent, "No gic interrupt or distributor table\n"); goto out; } /* This is for the wrong GIC version */ if (madt_data.dist->Version != ACPI_MADT_GIC_VERSION_V3) goto out; dev = BUS_ADD_CHILD(parent, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE, "gic", -1); if (dev == NULL) { device_printf(parent, "add gic child failed\n"); goto out; } /* Add the MADT data */ BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0, madt_data.dist->BaseAddress, 128 * 1024); madt_data.dev = dev; acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, rdist_map, &madt_data); acpi_set_private(dev, (void *)(uintptr_t)madt_data.dist->Version); out: acpi_unmap_table(madt); }
static void srat_walk_table(acpi_subtable_handler *handler, void *arg) { acpi_walk_subtables(srat + 1, (char *)srat + srat->Header.Length, handler, arg); }
/* * Call the handler routine for each entry in the MADT table. */ static void madt_walk_table(acpi_subtable_handler *handler, void *arg) { acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, handler, arg); }
static int gic_v3_acpi_count_regions(device_t dev) { struct gic_v3_softc *sc; ACPI_TABLE_MADT *madt; vm_paddr_t physaddr; sc = device_get_softc(dev); physaddr = acpi_find_table(ACPI_SIG_MADT); if (physaddr == 0) return (ENXIO); madt = acpi_map_table(physaddr, ACPI_SIG_MADT); if (madt == NULL) { device_printf(dev, "Unable to map the MADT\n"); return (ENXIO); } acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, madt_count_redistrib, sc); acpi_unmap_table(madt); return (sc->gic_redists.nregions > 0 ? 0 : ENXIO); }
static bool arm_gic_add_children(device_t dev) { struct arm_gic_softc *sc = device_get_softc(dev); ACPI_TABLE_MADT *madt; vm_paddr_t physaddr; /* This should return a valid address as it did in gic_acpi_identify */ physaddr = acpi_find_table(ACPI_SIG_MADT); if (physaddr == 0) return (false); madt = acpi_map_table(physaddr, ACPI_SIG_MADT); if (madt == NULL) { device_printf(dev, "gic: Unable to map the MADT\n"); return (false); } acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, madt_gicv2m_handler, sc); acpi_unmap_table(madt); return (true); }
static void gic_v3_acpi_bus_attach(device_t dev) { ACPI_TABLE_MADT *madt; vm_paddr_t physaddr; physaddr = acpi_find_table(ACPI_SIG_MADT); if (physaddr == 0) return; madt = acpi_map_table(physaddr, ACPI_SIG_MADT); if (madt == NULL) { device_printf(dev, "Unable to map the MADT to add children\n"); return; } acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, gic_v3_add_children, dev); acpi_unmap_table(madt); bus_generic_attach(dev); }
static void gic_acpi_identify(driver_t *driver, device_t parent) { struct madt_table_data madt_data; ACPI_MADT_GENERIC_INTERRUPT *intr; ACPI_TABLE_MADT *madt; vm_paddr_t physaddr; device_t dev; int i; physaddr = acpi_find_table(ACPI_SIG_MADT); if (physaddr == 0) return; madt = acpi_map_table(physaddr, ACPI_SIG_MADT); if (madt == NULL) { device_printf(parent, "gic: Unable to map the MADT\n"); return; } bzero(&madt_data, sizeof(madt_data)); madt_data.parent = parent; madt_data.dist = NULL; acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, madt_handler, &madt_data); /* Check the version of the GIC we have */ switch (madt_data.dist->Version) { case ACPI_MADT_GIC_VERSION_NONE: case ACPI_MADT_GIC_VERSION_V1: case ACPI_MADT_GIC_VERSION_V2: break; default: goto out; } intr = NULL; for (i = 0; i < MAXCPU; i++) { if (madt_data.intr[i] != NULL) { if (intr == NULL) { intr = madt_data.intr[i]; } else if (intr->BaseAddress != madt_data.intr[i]->BaseAddress) { device_printf(parent, "gic: Not all CPU interfaces at the same address, this may fail\n"); } } } if (intr == NULL) { device_printf(parent, "gic: No CPU interfaces found\n"); goto out; } dev = BUS_ADD_CHILD(parent, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE, "gic", -1); if (dev == NULL) { device_printf(parent, "add gic child failed\n"); goto out; } BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0, madt_data.dist->BaseAddress, 4 * 1024); BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 1, intr->BaseAddress, 4 * 1024); acpi_set_private(dev, (void *)(uintptr_t)madt_data.dist->Version); out: acpi_unmap_table(madt); }