Exemple #1
0
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);
}
Exemple #2
0
static void
srat_walk_table(acpi_subtable_handler *handler, void *arg)
{

	acpi_walk_subtables(srat + 1, (char *)srat + srat->Header.Length,
	    handler, arg);
}
Exemple #3
0
/*
 * 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);
}
Exemple #4
0
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);
}
Exemple #5
0
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);
}
Exemple #6
0
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);
}
Exemple #7
0
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);
}