diff options
author | des <des@FreeBSD.org> | 2009-09-25 22:45:59 +0000 |
---|---|---|
committer | des <des@FreeBSD.org> | 2009-09-25 22:45:59 +0000 |
commit | bf5117185e83a178d672946c3f7053d0ef92be27 (patch) | |
tree | 394fcfe01b613c0b5b5edbfc414a17c73481ad5d /sys/i386/acpica/madt.c | |
parent | b79ff8160af6fa640e29ce784e59acd49cd1e7fc (diff) | |
parent | 5c2742e3dae3ef549329b770ec44b16ca930dc1f (diff) | |
download | FreeBSD-src-bf5117185e83a178d672946c3f7053d0ef92be27.zip FreeBSD-src-bf5117185e83a178d672946c3f7053d0ef92be27.tar.gz |
Sync with head
Diffstat (limited to 'sys/i386/acpica/madt.c')
-rw-r--r-- | sys/i386/acpica/madt.c | 232 |
1 files changed, 10 insertions, 222 deletions
diff --git a/sys/i386/acpica/madt.c b/sys/i386/acpica/madt.c index f9756ec..114fbc7 100644 --- a/sys/i386/acpica/madt.c +++ b/sys/i386/acpica/madt.c @@ -36,27 +36,19 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/malloc.h> #include <sys/smp.h> - #include <vm/vm.h> -#include <vm/vm_param.h> #include <vm/pmap.h> #include <machine/apicreg.h> -#include <machine/frame.h> #include <machine/intr_machdep.h> #include <machine/apicvar.h> -#include <machine/md_var.h> -#include <machine/specialreg.h> #include <contrib/dev/acpica/include/acpi.h> -#include <contrib/dev/acpica/include/accommon.h> #include <contrib/dev/acpica/include/actables.h> #include <dev/acpica/acpivar.h> #include <dev/pci/pcivar.h> -typedef void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg); - /* These two arrays are indexed by APIC IDs. */ struct ioapic_info { void *io_apic; @@ -79,8 +71,6 @@ static enum intr_polarity interrupt_polarity(UINT16 IntiFlags, UINT8 Source); static enum intr_trigger interrupt_trigger(UINT16 IntiFlags, UINT8 Source); static int madt_find_cpu(u_int acpi_id, u_int *apic_id); static int madt_find_interrupt(int intr, void **apic, u_int *pin); -static void *madt_map(vm_paddr_t pa, int offset, vm_offset_t length); -static void *madt_map_table(vm_paddr_t pa, int offset, const char *sig); static void madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg); static void madt_parse_interrupt_override( ACPI_MADT_INTERRUPT_OVERRIDE *intr); @@ -92,13 +82,10 @@ static int madt_probe(void); static int madt_probe_cpus(void); static void madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg __unused); -static int madt_probe_table(vm_paddr_t address); static void madt_register(void *dummy); static int madt_setup_local(void); static int madt_setup_io(void); -static void madt_unmap(void *data, vm_offset_t length); -static void madt_unmap_table(void *table); -static void madt_walk_table(madt_entry_handler *handler, void *arg); +static void madt_walk_table(acpi_subtable_handler *handler, void *arg); static struct apic_enumerator madt_enumerator = { "MADT", @@ -108,87 +95,6 @@ static struct apic_enumerator madt_enumerator = { madt_setup_io }; -/* - * Code to abuse the crashdump map to map in the tables for the early - * probe. We cheat and make the following assumptions about how we - * use this KVA: pages 0 and 1 are used to map in the header of each - * table found via the RSDT or XSDT and pages 2 to n are used to map - * in the RSDT or XSDT. We have to use 2 pages for the table headers - * in case a header spans a page boundary. The offset is in pages; - * the length is in bytes. - */ -static void * -madt_map(vm_paddr_t pa, int offset, vm_offset_t length) -{ - vm_offset_t va, off; - void *data; - - off = pa & PAGE_MASK; - length = roundup(length + off, PAGE_SIZE); - pa = pa & PG_FRAME; - va = (vm_offset_t)pmap_kenter_temporary(pa, offset) + - (offset * PAGE_SIZE); - data = (void *)(va + off); - length -= PAGE_SIZE; - while (length > 0) { - va += PAGE_SIZE; - pa += PAGE_SIZE; - length -= PAGE_SIZE; - pmap_kenter(va, pa); - invlpg(va); - } - return (data); -} - -static void -madt_unmap(void *data, vm_offset_t length) -{ - vm_offset_t va, off; - - va = (vm_offset_t)data; - off = va & PAGE_MASK; - length = roundup(length + off, PAGE_SIZE); - va &= ~PAGE_MASK; - while (length > 0) { - pmap_kremove(va); - invlpg(va); - va += PAGE_SIZE; - length -= PAGE_SIZE; - } -} - -static void * -madt_map_table(vm_paddr_t pa, int offset, const char *sig) -{ - ACPI_TABLE_HEADER *header; - vm_offset_t length; - void *table; - - header = madt_map(pa, offset, sizeof(ACPI_TABLE_HEADER)); - if (strncmp(header->Signature, sig, ACPI_NAME_SIZE) != 0) { - madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); - return (NULL); - } - length = header->Length; - madt_unmap(header, sizeof(ACPI_TABLE_HEADER)); - table = madt_map(pa, offset, length); - if (ACPI_FAILURE(AcpiTbChecksum(table, length))) { - if (bootverbose) - printf("MADT: Failed checksum for table %s\n", sig); - madt_unmap(table, length); - return (NULL); - } - return (table); -} - -static void -madt_unmap_table(void *table) -{ - ACPI_TABLE_HEADER *header; - - header = (ACPI_TABLE_HEADER *)table; - madt_unmap(table, header->Length); -} /* * Look for an ACPI Multiple APIC Description Table ("APIC") @@ -196,137 +102,25 @@ madt_unmap_table(void *table) static int madt_probe(void) { - ACPI_PHYSICAL_ADDRESS rsdp_ptr; - ACPI_TABLE_RSDP *rsdp; - ACPI_TABLE_RSDT *rsdt; - ACPI_TABLE_XSDT *xsdt; - int i, count; - - if (resource_disabled("acpi", 0)) - return (ENXIO); - - /* - * Map in the RSDP. Since ACPI uses AcpiOsMapMemory() which in turn - * calls pmap_mapbios() to find the RSDP, we assume that we can use - * pmap_mapbios() to map the RSDP. - */ - if ((rsdp_ptr = AcpiOsGetRootPointer()) == 0) - return (ENXIO); - rsdp = pmap_mapbios(rsdp_ptr, sizeof(ACPI_TABLE_RSDP)); - if (rsdp == NULL) { - if (bootverbose) - printf("MADT: Failed to map RSDP\n"); - return (ENXIO); - } - - /* - * For ACPI >= 2.0, use the XSDT if it is available. - * Otherwise, use the RSDT. We map the XSDT or RSDT at page 1 - * in the crashdump area. Page 0 is used to map in the - * headers of candidate ACPI tables. - */ - if (rsdp->Revision >= 2 && rsdp->XsdtPhysicalAddress != 0) { - /* - * AcpiOsGetRootPointer only verifies the checksum for - * the version 1.0 portion of the RSDP. Version 2.0 has - * an additional checksum that we verify first. - */ - if (AcpiTbChecksum((UINT8 *)rsdp, ACPI_RSDP_XCHECKSUM_LENGTH)) { - if (bootverbose) - printf("MADT: RSDP failed extended checksum\n"); - return (ENXIO); - } - xsdt = madt_map_table(rsdp->XsdtPhysicalAddress, 2, - ACPI_SIG_XSDT); - if (xsdt == NULL) { - if (bootverbose) - printf("MADT: Failed to map XSDT\n"); - return (ENXIO); - } - count = (xsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / - sizeof(UINT64); - for (i = 0; i < count; i++) - if (madt_probe_table(xsdt->TableOffsetEntry[i])) - break; - madt_unmap_table(xsdt); - } else { - rsdt = madt_map_table(rsdp->RsdtPhysicalAddress, 2, - ACPI_SIG_RSDT); - if (rsdt == NULL) { - if (bootverbose) - printf("MADT: Failed to map RSDT\n"); - return (ENXIO); - } - count = (rsdt->Header.Length - sizeof(ACPI_TABLE_HEADER)) / - sizeof(UINT32); - for (i = 0; i < count; i++) - if (madt_probe_table(rsdt->TableOffsetEntry[i])) - break; - madt_unmap_table(rsdt); - } - pmap_unmapbios((vm_offset_t)rsdp, sizeof(ACPI_TABLE_RSDP)); - if (madt_physaddr == 0) { - if (bootverbose) - printf("MADT: No MADT table found\n"); - return (ENXIO); - } - if (bootverbose) - printf("MADT: Found table at 0x%jx\n", - (uintmax_t)madt_physaddr); - /* - * Verify that we can map the full table and that its checksum is - * correct, etc. - */ - madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT); - if (madt == NULL) + madt_physaddr = acpi_find_table(ACPI_SIG_MADT); + if (madt_physaddr == 0) return (ENXIO); - madt_unmap_table(madt); - madt = NULL; - return (0); } /* - * See if a given ACPI table is the MADT. - */ -static int -madt_probe_table(vm_paddr_t address) -{ - ACPI_TABLE_HEADER *table; - - table = madt_map(address, 0, sizeof(ACPI_TABLE_HEADER)); - if (table == NULL) { - if (bootverbose) - printf("MADT: Failed to map table at 0x%jx\n", - (uintmax_t)address); - return (0); - } - if (bootverbose) - printf("Table '%.4s' at 0x%jx\n", table->Signature, - (uintmax_t)address); - - if (strncmp(table->Signature, ACPI_SIG_MADT, ACPI_NAME_SIZE) != 0) { - madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); - return (0); - } - madt_physaddr = address; - madt_length = table->Length; - madt_unmap(table, sizeof(ACPI_TABLE_HEADER)); - return (1); -} - -/* * Run through the MP table enumerating CPUs. */ static int madt_probe_cpus(void) { - madt = madt_map_table(madt_physaddr, 0, ACPI_SIG_MADT); + madt = acpi_map_table(madt_physaddr, ACPI_SIG_MADT); + madt_length = madt->Header.Length; KASSERT(madt != NULL, ("Unable to re-map MADT")); madt_walk_table(madt_probe_cpus_handler, NULL); - madt_unmap_table(madt); + acpi_unmap_table(madt); madt = NULL; return (0); } @@ -416,17 +210,11 @@ SYSINIT(madt_register, SI_SUB_CPU - 1, SI_ORDER_SECOND, madt_register, NULL); * Call the handler routine for each entry in the MADT table. */ static void -madt_walk_table(madt_entry_handler *handler, void *arg) +madt_walk_table(acpi_subtable_handler *handler, void *arg) { - ACPI_SUBTABLE_HEADER *entry; - u_char *p, *end; - - end = (u_char *)(madt) + madt->Header.Length; - for (p = (u_char *)(madt + 1); p < end; ) { - entry = (ACPI_SUBTABLE_HEADER *)p; - handler(entry, arg); - p += entry->Length; - } + + acpi_walk_subtables(madt + 1, (char *)madt + madt->Header.Length, + handler, arg); } static void |