acpi: Factor out SDT functions to locate specified SDT
[dragonfly.git] / sys / platform / pc32 / acpica5 / acpi_madt.c
index 9183181..ba2a6ed 100644 (file)
 #include <machine/specialreg.h>
 #include <machine_base/apic/mpapic.h>
 
+#include "acpi_sdt.h"
+#include "acpi_sdt_var.h"
+
 #define MADT_VPRINTF(fmt, arg...) \
 do { \
        if (bootverbose) \
                kprintf("ACPI MADT: " fmt , ##arg); \
 } while (0)
 
-#define ACPI_RSDP_EBDA_MAPSZ   1024
-#define ACPI_RSDP_BIOS_MAPSZ   0x20000
-#define ACPI_RSDP_BIOS_MAPADDR 0xe0000
-
-#define ACPI_RSDP_ALIGN                16
-
-#define ACPI_RSDP_SIGLEN       8
-#define ACPI_RSDP_SIG          "RSD PTR "
-
-#define ACPI_SDTH_SIGLEN       4
-#define ACPI_RSDT_SIG          "RSDT"
-#define ACPI_XSDT_SIG          "XSDT"
-#define ACPI_MADT_SIG          "APIC"
-
-/* Root System Description Pointer */
-struct acpi_rsdp {
-       uint8_t                 rsdp_sig[ACPI_RSDP_SIGLEN];
-       uint8_t                 rsdp_cksum;
-       uint8_t                 rsdp_oem_id[6];
-       uint8_t                 rsdp_rev;
-       uint32_t                rsdp_rsdt;
-       uint32_t                rsdp_len;
-       uint64_t                rsdp_xsdt;
-       uint8_t                 rsdp_ext_cksum;
-       uint8_t                 rsdp_rsvd[3];
-} __packed;
-
-/* System Description Table Header */
-struct acpi_sdth {
-       uint8_t                 sdth_sig[ACPI_SDTH_SIGLEN];
-       uint32_t                sdth_len;
-       uint8_t                 sdth_rev;
-       uint8_t                 sdth_cksum;
-       uint8_t                 sdth_oem_id[6];
-       uint8_t                 sdth_oem_tbid[8];
-       uint32_t                sdth_oem_rev;
-       uint32_t                sdth_crt_id;
-       uint32_t                sdth_crt_rev;
-} __packed;
-
-/* Extended System Description Table */
-struct acpi_xsdt {
-       struct acpi_sdth        xsdt_hdr;
-       uint64_t                xsdt_ents[1];
-} __packed;
-
-/* Root System Description Table */
-struct acpi_rsdt {
-       struct acpi_sdth        rsdt_hdr;
-       uint32_t                rsdt_ents[1];
-} __packed;
-
 /* Multiple APIC Description Table */
 struct acpi_madt {
        struct acpi_sdth        madt_hdr;
@@ -170,15 +121,9 @@ struct acpi_madt_lapic_addr {
        uint64_t                mla_lapic_addr;
 } __packed;
 
-typedef        vm_paddr_t              (*madt_search_t)(vm_paddr_t);
 typedef int                    (*madt_iter_t)(void *,
                                    const struct acpi_madt_ent *);
 
-static const struct acpi_rsdp  *madt_rsdp_search(const uint8_t *, int);
-static void                    *madt_sdth_map(vm_paddr_t);
-static void                    madt_sdth_unmap(struct acpi_sdth *);
-static vm_paddr_t              madt_search_xsdt(vm_paddr_t);
-static vm_paddr_t              madt_search_rsdt(vm_paddr_t);
 static int                     madt_check(vm_paddr_t);
 static int                     madt_iterate_entries(struct acpi_madt *,
                                    madt_iter_t, void *);
@@ -193,61 +138,16 @@ static void                       madt_ioapic_enumerate(
                                    struct ioapic_enumerator *);
 static int                     madt_ioapic_probe(struct ioapic_enumerator *);
 
-extern u_long                  ebda_addr;
-
 static vm_paddr_t              madt_phyaddr;
 
 static void
 madt_probe(void)
 {
-       const struct acpi_rsdp *rsdp;
-       madt_search_t search;
-       vm_paddr_t search_paddr, madt_paddr;
-       vm_size_t mapsz;
-       uint8_t *ptr;
+       vm_paddr_t madt_paddr;
 
        KKASSERT(madt_phyaddr == 0);
 
-       if (ebda_addr != 0) {
-               mapsz = ACPI_RSDP_EBDA_MAPSZ;
-               ptr = pmap_mapdev(ebda_addr, mapsz);
-
-               rsdp = madt_rsdp_search(ptr, mapsz);
-               if (rsdp == NULL) {
-                       MADT_VPRINTF("RSDP not in EBDA\n");
-                       pmap_unmapdev((vm_offset_t)ptr, mapsz);
-
-                       ptr = NULL;
-                       mapsz = 0;
-               } else {
-                       MADT_VPRINTF("RSDP in EBDA\n");
-                       goto found_rsdp;
-               }
-       }
-
-       mapsz = ACPI_RSDP_BIOS_MAPSZ;
-       ptr = pmap_mapdev(ACPI_RSDP_BIOS_MAPADDR, mapsz);
-
-       rsdp = madt_rsdp_search(ptr, mapsz);
-       if (rsdp == NULL) {
-               kprintf("madt_probe: no RSDP\n");
-               pmap_unmapdev((vm_offset_t)ptr, mapsz);
-               return;
-       } else {
-               MADT_VPRINTF("RSDP in BIOS mem\n");
-       }
-
-found_rsdp:
-       if (rsdp->rsdp_rev != 2) {
-               search_paddr = rsdp->rsdp_rsdt;
-               search = madt_search_rsdt;
-       } else {
-               search_paddr = rsdp->rsdp_xsdt;
-               search = madt_search_xsdt;
-       }
-       pmap_unmapdev((vm_offset_t)ptr, mapsz);
-
-       madt_paddr = search(search_paddr);
+       madt_paddr = sdt_search(ACPI_MADT_SIG);
        if (madt_paddr == 0) {
                kprintf("madt_probe: can't locate MADT\n");
                return;
@@ -261,162 +161,7 @@ found_rsdp:
 
        madt_phyaddr = madt_paddr;
 }
-SYSINIT(madt_probe, SI_BOOT2_PRESMP, SI_ORDER_FIRST, madt_probe, 0);
-
-static const struct acpi_rsdp *
-madt_rsdp_search(const uint8_t *target, int size)
-{
-       const struct acpi_rsdp *rsdp;
-       int i;
-
-       KKASSERT(size > sizeof(*rsdp));
-
-       for (i = 0; i < size - sizeof(*rsdp); i += ACPI_RSDP_ALIGN) {
-               rsdp = (const struct acpi_rsdp *)&target[i];
-               if (memcmp(rsdp->rsdp_sig, ACPI_RSDP_SIG,
-                          ACPI_RSDP_SIGLEN) == 0)
-                       return rsdp;
-       }
-       return NULL;
-}
-
-static void *
-madt_sdth_map(vm_paddr_t paddr)
-{
-       struct acpi_sdth *sdth;
-       vm_size_t mapsz;
-
-       sdth = pmap_mapdev(paddr, sizeof(*sdth));
-       mapsz = sdth->sdth_len;
-       pmap_unmapdev((vm_offset_t)sdth, sizeof(*sdth));
-
-       if (mapsz < sizeof(*sdth))
-               return NULL;
-
-       return pmap_mapdev(paddr, mapsz);
-}
-
-static void
-madt_sdth_unmap(struct acpi_sdth *sdth)
-{
-       pmap_unmapdev((vm_offset_t)sdth, sdth->sdth_len);
-}
-
-static vm_paddr_t
-madt_search_xsdt(vm_paddr_t xsdt_paddr)
-{
-       struct acpi_xsdt *xsdt;
-       vm_paddr_t madt_paddr = 0;
-       int i, nent;
-
-       if (xsdt_paddr == 0) {
-               kprintf("madt_search_xsdt: XSDT paddr == 0\n");
-               return 0;
-       }
-
-       xsdt = madt_sdth_map(xsdt_paddr);
-       if (xsdt == NULL) {
-               kprintf("madt_search_xsdt: can't map XSDT\n");
-               return 0;
-       }
-
-       if (memcmp(xsdt->xsdt_hdr.sdth_sig, ACPI_XSDT_SIG,
-                  ACPI_SDTH_SIGLEN) != 0) {
-               kprintf("madt_search_xsdt: not XSDT\n");
-               goto back;
-       }
-
-       if (xsdt->xsdt_hdr.sdth_rev != 1) {
-               kprintf("madt_search_xsdt: unsupported XSDT revision %d\n",
-                       xsdt->xsdt_hdr.sdth_rev);
-               goto back;
-       }
-
-       nent = (xsdt->xsdt_hdr.sdth_len - sizeof(xsdt->xsdt_hdr)) /
-              sizeof(xsdt->xsdt_ents[0]);
-       for (i = 0; i < nent; ++i) {
-               struct acpi_sdth *sdth;
-
-               if (xsdt->xsdt_ents[i] == 0)
-                       continue;
-
-               sdth = madt_sdth_map(xsdt->xsdt_ents[i]);
-               if (sdth != NULL) {
-                       int ret;
-
-                       ret = memcmp(sdth->sdth_sig, ACPI_MADT_SIG,
-                                    ACPI_SDTH_SIGLEN);
-                       madt_sdth_unmap(sdth);
-
-                       if (ret == 0) {
-                               MADT_VPRINTF("MADT in XSDT\n");
-                               madt_paddr = xsdt->xsdt_ents[i];
-                               break;
-                       }
-               }
-       }
-back:
-       madt_sdth_unmap(&xsdt->xsdt_hdr);
-       return madt_paddr;
-}
-
-static vm_paddr_t
-madt_search_rsdt(vm_paddr_t rsdt_paddr)
-{
-       struct acpi_rsdt *rsdt;
-       vm_paddr_t madt_paddr = 0;
-       int i, nent;
-
-       if (rsdt_paddr == 0) {
-               kprintf("madt_search_rsdt: RSDT paddr == 0\n");
-               return 0;
-       }
-
-       rsdt = madt_sdth_map(rsdt_paddr);
-       if (rsdt == NULL) {
-               kprintf("madt_search_rsdt: can't map RSDT\n");
-               return 0;
-       }
-
-       if (memcmp(rsdt->rsdt_hdr.sdth_sig, ACPI_RSDT_SIG,
-                  ACPI_SDTH_SIGLEN) != 0) {
-               kprintf("madt_search_rsdt: not RSDT\n");
-               goto back;
-       }
-
-       if (rsdt->rsdt_hdr.sdth_rev != 1) {
-               kprintf("madt_search_rsdt: unsupported RSDT revision %d\n",
-                       rsdt->rsdt_hdr.sdth_rev);
-               goto back;
-       }
-
-       nent = (rsdt->rsdt_hdr.sdth_len - sizeof(rsdt->rsdt_hdr)) /
-              sizeof(rsdt->rsdt_ents[0]);
-       for (i = 0; i < nent; ++i) {
-               struct acpi_sdth *sdth;
-
-               if (rsdt->rsdt_ents[i] == 0)
-                       continue;
-
-               sdth = madt_sdth_map(rsdt->rsdt_ents[i]);
-               if (sdth != NULL) {
-                       int ret;
-
-                       ret = memcmp(sdth->sdth_sig, ACPI_MADT_SIG,
-                                    ACPI_SDTH_SIGLEN);
-                       madt_sdth_unmap(sdth);
-
-                       if (ret == 0) {
-                               MADT_VPRINTF("MADT in RSDT\n");
-                               madt_paddr = rsdt->rsdt_ents[i];
-                               break;
-                       }
-               }
-       }
-back:
-       madt_sdth_unmap(&rsdt->rsdt_hdr);
-       return madt_paddr;
-}
+SYSINIT(madt_probe, SI_BOOT2_PRESMP, SI_ORDER_SECOND, madt_probe, 0);
 
 static int
 madt_check(vm_paddr_t madt_paddr)
@@ -426,7 +171,7 @@ madt_check(vm_paddr_t madt_paddr)
 
        KKASSERT(madt_paddr != 0);
 
-       madt = madt_sdth_map(madt_paddr);
+       madt = sdt_sdth_map(madt_paddr);
        KKASSERT(madt != NULL);
 
        /*
@@ -447,7 +192,7 @@ madt_check(vm_paddr_t madt_paddr)
                goto back;
        }
 back:
-       madt_sdth_unmap(&madt->madt_hdr);
+       sdt_sdth_unmap(&madt->madt_hdr);
        return error;
 }
 
@@ -549,7 +294,7 @@ madt_lapic_pass1(void)
 
        KKASSERT(madt_phyaddr != 0);
 
-       madt = madt_sdth_map(madt_phyaddr);
+       madt = sdt_sdth_map(madt_phyaddr);
        KKASSERT(madt != NULL);
 
        MADT_VPRINTF("LAPIC address 0x%08x, flags %#x\n",
@@ -569,7 +314,7 @@ madt_lapic_pass1(void)
                lapic_addr = lapic_addr64;
        }
 
-       madt_sdth_unmap(&madt->madt_hdr);
+       sdt_sdth_unmap(&madt->madt_hdr);
 
        return lapic_addr;
 }
@@ -615,7 +360,7 @@ madt_lapic_pass2(int bsp_apic_id)
 
        KKASSERT(madt_phyaddr != 0);
 
-       madt = madt_sdth_map(madt_phyaddr);
+       madt = sdt_sdth_map(madt_phyaddr);
        KKASSERT(madt != NULL);
 
        bzero(&arg, sizeof(arg));
@@ -630,7 +375,7 @@ madt_lapic_pass2(int bsp_apic_id)
        KKASSERT(arg.cpu > 1);
        mp_naps = arg.cpu - 1; /* exclude BSP */
 
-       madt_sdth_unmap(&madt->madt_hdr);
+       sdt_sdth_unmap(&madt->madt_hdr);
 
        return 0;
 }
@@ -677,7 +422,7 @@ madt_lapic_probe(struct lapic_enumerator *e)
        if (madt_phyaddr == 0)
                return ENXIO;
 
-       madt = madt_sdth_map(madt_phyaddr);
+       madt = sdt_sdth_map(madt_phyaddr);
        KKASSERT(madt != NULL);
 
        bzero(&arg, sizeof(arg));
@@ -696,7 +441,7 @@ madt_lapic_probe(struct lapic_enumerator *e)
                }
        }
 
-       madt_sdth_unmap(&madt->madt_hdr);
+       sdt_sdth_unmap(&madt->madt_hdr);
        return error;
 }
 
@@ -806,7 +551,7 @@ madt_ioapic_probe(struct ioapic_enumerator *e)
        if (madt_phyaddr == 0)
                return ENXIO;
 
-       madt = madt_sdth_map(madt_phyaddr);
+       madt = sdt_sdth_map(madt_phyaddr);
        KKASSERT(madt != NULL);
 
        bzero(&arg, sizeof(arg));
@@ -823,7 +568,7 @@ madt_ioapic_probe(struct ioapic_enumerator *e)
                }
        }
 
-       madt_sdth_unmap(&madt->madt_hdr);
+       sdt_sdth_unmap(&madt->madt_hdr);
        return error;
 }
 
@@ -900,14 +645,14 @@ madt_ioapic_enumerate(struct ioapic_enumerator *e)
 
        KKASSERT(madt_phyaddr != 0);
 
-       madt = madt_sdth_map(madt_phyaddr);
+       madt = sdt_sdth_map(madt_phyaddr);
        KKASSERT(madt != NULL);
 
        error = madt_iterate_entries(madt, madt_ioapic_enum_callback, NULL);
        if (error)
                panic("madt_ioapic_enumerate failed\n");
 
-       madt_sdth_unmap(&madt->madt_hdr);
+       sdt_sdth_unmap(&madt->madt_hdr);
 }
 
 static struct ioapic_enumerator        madt_ioapic_enumerator = {