diff --git a/grub-core/kern/acpi.c b/grub-core/kern/acpi.c index 02c1f4f6f..5746ac00c 100644 --- a/grub-core/kern/acpi.c +++ b/grub-core/kern/acpi.c @@ -32,3 +32,88 @@ grub_byte_checksum (void *base, grub_size_t size) ret += *ptr; return ret; } + +static void * +grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig) +{ + grub_size_t s; + grub_unaligned_uint32_t *ptr; + + if (!rsdt) + return 0; + + if (grub_memcmp (rsdt->signature, "RSDT", 4) != 0) + return 0; + + ptr = (grub_unaligned_uint32_t *) (rsdt + 1); + s = (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t); + for (; s; s--, ptr++) + { + struct grub_acpi_table_header *tbl; + tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val; + if (grub_memcmp (tbl->signature, sig, 4) == 0) + return tbl; + } + return 0; +} + +static void * +grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig) +{ + grub_size_t s; + grub_unaligned_uint64_t *ptr; + + if (!xsdt) + return 0; + + if (grub_memcmp (xsdt->signature, "XSDT", 4) != 0) + return 0; + + ptr = (grub_unaligned_uint64_t *) (xsdt + 1); + s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t); + for (; s; s--, ptr++) + { + struct grub_acpi_table_header *tbl; +#if GRUB_CPU_SIZEOF_VOID_P != 8 + if (ptr->val >> 32) + continue; +#endif + tbl = (struct grub_acpi_table_header *) (grub_addr_t) ptr->val; + if (grub_memcmp (tbl->signature, sig, 4) == 0) + return tbl; + } + return 0; +} + +struct grub_acpi_fadt * +grub_acpi_find_fadt (void) +{ + struct grub_acpi_fadt *fadt = 0; + struct grub_acpi_rsdp_v10 *rsdpv1; + struct grub_acpi_rsdp_v20 *rsdpv2; + rsdpv1 = grub_machine_acpi_get_rsdpv1 (); + if (rsdpv1) + fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) + (grub_addr_t) rsdpv1->rsdt_addr, + GRUB_ACPI_FADT_SIGNATURE); + if (fadt) + return fadt; + rsdpv2 = grub_machine_acpi_get_rsdpv2 (); + if (rsdpv2) + fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) + (grub_addr_t) rsdpv2->rsdpv1.rsdt_addr, + GRUB_ACPI_FADT_SIGNATURE); + if (fadt) + return fadt; + if (rsdpv2 +#if GRUB_CPU_SIZEOF_VOID_P != 8 + && !(rsdpv2->xsdt_addr >> 32) +#endif + ) + fadt = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *) + (grub_addr_t) rsdpv2->xsdt_addr, + GRUB_ACPI_FADT_SIGNATURE); + if (fadt) + return fadt; + return 0; +} diff --git a/grub-core/kern/i386/tsc_pmtimer.c b/grub-core/kern/i386/tsc_pmtimer.c index 6a47ab7be..2495e6fd4 100644 --- a/grub-core/kern/i386/tsc_pmtimer.c +++ b/grub-core/kern/i386/tsc_pmtimer.c @@ -27,91 +27,6 @@ #include #include -static void * -grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char *sig) -{ - grub_size_t s; - grub_uint32_t *ptr; - - if (!rsdt) - return 0; - - if (grub_memcmp (rsdt->signature, "RSDT", 4) != 0) - return 0; - - ptr = (grub_uint32_t *) (rsdt + 1); - s = (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t); - for (; s; s--, ptr++) - { - struct grub_acpi_table_header *tbl; - tbl = (struct grub_acpi_table_header *) (grub_addr_t) *ptr; - if (grub_memcmp (tbl->signature, sig, 4) == 0) - return tbl; - } - return 0; -} - -static void * -grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char *sig) -{ - grub_size_t s; - grub_uint64_t *ptr; - - if (!xsdt) - return 0; - - if (grub_memcmp (xsdt->signature, "XSDT", 4) != 0) - return 0; - - ptr = (grub_uint64_t *) (xsdt + 1); - s = (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t); - for (; s; s--, ptr++) - { - struct grub_acpi_table_header *tbl; -#if GRUB_CPU_SIZEOF_VOID_P != 8 - if (*ptr >> 32) - continue; -#endif - tbl = (struct grub_acpi_table_header *) (grub_addr_t) *ptr; - if (grub_memcmp (tbl->signature, sig, 4) == 0) - return tbl; - } - return 0; -} - -struct grub_acpi_fadt * -grub_acpi_find_fadt (void) -{ - struct grub_acpi_fadt *fadt = 0; - struct grub_acpi_rsdp_v10 *rsdpv1; - struct grub_acpi_rsdp_v20 *rsdpv2; - rsdpv1 = grub_machine_acpi_get_rsdpv1 (); - if (rsdpv1) - fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv1->rsdt_addr, - GRUB_ACPI_FADT_SIGNATURE); - if (fadt) - return fadt; - rsdpv2 = grub_machine_acpi_get_rsdpv2 (); - if (rsdpv2) - fadt = grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv2->rsdpv1.rsdt_addr, - GRUB_ACPI_FADT_SIGNATURE); - if (fadt) - return fadt; - if (rsdpv2 -#if GRUB_CPU_SIZEOF_VOID_P != 8 - && !(rsdpv2->xsdt_addr >> 32) -#endif - ) - fadt = grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *) - (grub_addr_t) rsdpv2->xsdt_addr, - GRUB_ACPI_FADT_SIGNATURE); - if (fadt) - return fadt; - return 0; -} - int grub_tsc_calibrate_from_pmtimer (void) { diff --git a/include/grub/acpi.h b/include/grub/acpi.h index a4224e046..66148f684 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -242,6 +242,6 @@ enum }; struct grub_acpi_fadt * -grub_acpi_find_fadt (void); +EXPORT_FUNC(grub_acpi_find_fadt) (void); #endif /* ! GRUB_ACPI_HEADER */