From: Andrei Borzenkov Subject: [PATCH] lsacpi: print table address and allow bypassing stored pointers 1. Print memory address for each table, similat to what Linux kernel does. 2. Add "--scan" option to ignore stored RSDP address (after acpi command) and use normal platform-specific way to search for it. This provides for better debugging results of replacing tables with acpi. --- grub-core/commands/acpi.c | 34 ++++++++------ grub-core/commands/acpihalt.c | 4 +- grub-core/commands/lsacpi.c | 86 ++++++++++++++++++++++++++++++------ grub-core/efiemu/i386/pc/cfgtables.c | 4 +- grub-core/loader/multiboot_mbi2.c | 6 +-- include/grub/acpi.h | 12 ++++- 6 files changed, 109 insertions(+), 37 deletions(-) diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index b5c2f27..4163a78 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -100,22 +100,28 @@ static grub_size_t dsdt_size = 0; static grub_uint32_t facs_addr = 0; struct grub_acpi_rsdp_v20 * -grub_acpi_get_rsdpv2 (void) +grub_acpi_get_rsdpv2 (int scan) { - if (rsdpv2_new) - return rsdpv2_new; - if (rsdpv1_new) - return 0; + if (!scan) + { + if (rsdpv2_new) + return rsdpv2_new; + if (rsdpv1_new) + return 0; + } return grub_machine_acpi_get_rsdpv2 (); } struct grub_acpi_rsdp_v10 * -grub_acpi_get_rsdpv1 (void) +grub_acpi_get_rsdpv1 (int scan) { - if (rsdpv1_new) - return rsdpv1_new; - if (rsdpv2_new) - return 0; + if (!scan) + { + if (rsdpv1_new) + return rsdpv1_new; + if (rsdpv2_new) + return 0; + } return grub_machine_acpi_get_rsdpv1 (); } @@ -198,8 +204,8 @@ grub_acpi_create_ebda (void) *((grub_uint16_t *) targetebda) = ebda_kb_len + 1; target = targetebda; - v1 = grub_acpi_get_rsdpv1 (); - v2 = grub_acpi_get_rsdpv2 (); + v1 = grub_acpi_get_rsdpv1 (0); + v2 = grub_acpi_get_rsdpv2 (0); if (v2 && v2->length > 40) v2 = 0; @@ -762,9 +768,9 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args) struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID; grub_efi_system_table->boot_services->install_configuration_table - (&acpi20, grub_acpi_get_rsdpv2 ()); + (&acpi20, grub_acpi_get_rsdpv2 (0)); grub_efi_system_table->boot_services->install_configuration_table - (&acpi, grub_acpi_get_rsdpv1 ()); + (&acpi, grub_acpi_get_rsdpv1 (0)); } #endif diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index 9cc7f18..d7c51e1 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -395,11 +395,11 @@ grub_acpi_halt (void) grub_uint32_t port = 0; int sleep_type = -1; - rsdp2 = grub_acpi_get_rsdpv2 (); + rsdp2 = grub_acpi_get_rsdpv2 (0); if (rsdp2) rsdp1 = &(rsdp2->rsdpv1); else - rsdp1 = grub_acpi_get_rsdpv1 (); + rsdp1 = grub_acpi_get_rsdpv1 (0); grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1); if (!rsdp1) return; diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c index 0824914..34c1220 100644 --- a/grub-core/commands/lsacpi.c +++ b/grub-core/commands/lsacpi.c @@ -43,6 +43,7 @@ print_strn (grub_uint8_t *str, grub_size_t len) static void disp_acpi_table (struct grub_acpi_table_header *t) { + grub_printf ("%p: ", t); print_field (t->signature); grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u chksum=0x%02x (%s) OEM=", t->length, t->revision, t->checksum, grub_byte_checksum (t, t->length) == 0 ? "valid" : "invalid"); @@ -59,7 +60,6 @@ disp_madt_table (struct grub_acpi_madt *t) struct grub_acpi_madt_entry_header *d; grub_uint32_t len; - disp_acpi_table (&t->hdr); grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T " Flags=%08" PRIxGRUB_UINT32_T "\n", t->lapic_addr, t->flags); @@ -174,6 +174,61 @@ disp_madt_table (struct grub_acpi_madt *t) } static void +disp_facs_header (struct grub_acpi_facs_header *t) +{ + grub_printf ("%p: ", t); + print_field (t->signature); + grub_printf ("%4" PRIuGRUB_UINT32_T "B", t->length); + grub_printf ("\n"); +} + +static void +disp_fadt_table (struct grub_acpi_fadt *t) +{ + struct grub_acpi_facs_header *facs = NULL; + struct grub_acpi_table_header *dsdt = NULL; + + if (t->hdr.revision >= 3) + { + if (t->facs_xaddr) + { + if (t->facs_addr) + grub_printf (" Ignoring FACS 0x08%" PRIxGRUB_UINT32_T "\n", t->facs_addr); + +#if GRUB_CPU_SIZEOF_VOID_P == 4 + if (t->facs_xaddr >= (1ULL << 32)) + grub_printf (" Unreachable FACS 0x%016" PRIxGRUB_UINT64_T "\n", t->facs_xaddr); + else +#endif + facs = (struct grub_acpi_facs_header *) (grub_addr_t) t->dsdt_xaddr; + } + + if (t->dsdt_xaddr) + { + if (t->dsdt_addr) + grub_printf (" Ignoring DSDT 0x08%" PRIxGRUB_UINT32_T "\n", t->dsdt_addr); + +#if GRUB_CPU_SIZEOF_VOID_P == 4 + if (t->dsdt_xaddr >= (1ULL << 32)) + grub_printf (" Unreachable DSDT 0x%016" PRIxGRUB_UINT64_T "\n", t->dsdt_xaddr); + else +#endif + dsdt = (struct grub_acpi_table_header *) (grub_addr_t) t->dsdt_xaddr; + } + } + else + { + facs = (struct grub_acpi_facs_header *) (grub_addr_t) t->facs_addr; + dsdt = (struct grub_acpi_table_header *) (grub_addr_t) t->dsdt_addr; + } + + if (facs) + disp_facs_header (facs); + if (dsdt) + disp_acpi_table (dsdt); +} + +static void disp_acpi_xsdt_table (struct grub_acpi_table_header *t) { grub_uint32_t len; @@ -187,7 +242,7 @@ disp_acpi_xsdt_table (struct grub_acpi_table_header *t) #if GRUB_CPU_SIZEOF_VOID_P == 4 if (*desc >= (1ULL << 32)) { - grub_printf ("Unreachable table\n"); + grub_printf (" Unreachable table 0x%016" PRIxGRUB_UINT64_T "\n", *desc); continue; } #endif @@ -196,11 +251,13 @@ disp_acpi_xsdt_table (struct grub_acpi_table_header *t) if (t == NULL) continue; + disp_acpi_table (t); if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE, sizeof (t->signature)) == 0) disp_madt_table ((struct grub_acpi_madt *) t); - else - disp_acpi_table (t); + else if (grub_memcmp (t->signature, GRUB_ACPI_FADT_SIGNATURE, + sizeof (t->signature)) == 0) + disp_fadt_table ((struct grub_acpi_fadt *) t); } } @@ -220,11 +277,13 @@ disp_acpi_rsdt_table (struct grub_acpi_table_header *t) if (t == NULL) continue; + disp_acpi_table (t); if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE, sizeof (t->signature)) == 0) disp_madt_table ((struct grub_acpi_madt *) t); - else - disp_acpi_table (t); + else if (grub_memcmp (t->signature, GRUB_ACPI_FADT_SIGNATURE, + sizeof (t->signature)) == 0) + disp_fadt_table ((struct grub_acpi_fadt *) t); } } @@ -235,15 +294,13 @@ disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp) grub_printf ("chksum:%02x (%s), OEM-ID: ", rsdp->checksum, grub_byte_checksum (rsdp, sizeof (*rsdp)) == 0 ? "valid" : "invalid"); print_field (rsdp->oemid); grub_printf ("rev=%d\n", rsdp->revision); - grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr); } static void disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp) { disp_acpi_rsdpv1 (&rsdp->rsdpv1); - grub_printf ("len=%d chksum=%02x (%s) XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid", - rsdp->xsdt_addr); + grub_printf ("len=%d chksum=%02x (%s)\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid"); if (rsdp->length != sizeof (*rsdp)) grub_printf (" length mismatch %d != %d\n", rsdp->length, (int) sizeof (*rsdp)); @@ -254,6 +311,7 @@ disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp) static const struct grub_arg_option options[] = { {"v1", '1', 0, N_("Show version 1 tables only."), 0, ARG_TYPE_NONE}, {"v2", '2', 0, N_("Show version 2 and version 3 tables only."), 0, ARG_TYPE_NONE}, + {"scan", 0, 0, N_("Ignore cached RSDP pointers and rescan."), 0, ARG_TYPE_NONE}, {0, 0, 0, 0, 0, 0} }; @@ -264,12 +322,12 @@ grub_cmd_lsacpi (struct grub_extcmd_context *ctxt, { if (!ctxt->state[1].set) { - struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 (); + struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 (ctxt->state[2].set); if (!rsdp1) grub_printf ("No RSDPv1\n"); else { - grub_printf ("RSDPv1 signature:"); + grub_printf ("%p: RSDPv1 signature:", rsdp1); disp_acpi_rsdpv1 (rsdp1); disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr); } @@ -277,7 +335,7 @@ grub_cmd_lsacpi (struct grub_extcmd_context *ctxt, if (!ctxt->state[0].set) { - struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 (); + struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 (ctxt->state[2].set); if (!rsdp2) grub_printf ("No RSDPv2\n"); else @@ -288,7 +346,7 @@ grub_cmd_lsacpi (struct grub_extcmd_context *ctxt, else #endif { - grub_printf ("RSDPv2 signature:"); + grub_printf ("%p: RSDPv2 signature:", rsdp2); disp_acpi_rsdpv2 (rsdp2); disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr); grub_printf ("\n"); @@ -302,7 +360,7 @@ static grub_extcmd_t cmd; GRUB_MOD_INIT(lsapi) { - cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, "[-1|-2]", + cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, "[-1|-2] [--scan]", N_("Show ACPI information."), options); } diff --git a/grub-core/efiemu/i386/pc/cfgtables.c b/grub-core/efiemu/i386/pc/cfgtables.c index 492c07c..99a9228 100644 --- a/grub-core/efiemu/i386/pc/cfgtables.c +++ b/grub-core/efiemu/i386/pc/cfgtables.c @@ -43,14 +43,14 @@ grub_machine_efiemu_init_tables (void) if (err) return err; - table = grub_acpi_get_rsdpv1 (); + table = grub_acpi_get_rsdpv1 (0); if (table) { err = grub_efiemu_register_configuration_table (acpi, 0, 0, table); if (err) return err; } - table = grub_acpi_get_rsdpv2 (); + table = grub_acpi_get_rsdpv2 (0); if (table) { err = grub_efiemu_register_configuration_table (acpi20, 0, 0, table); diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c index b0679a9..640a8de 100644 --- a/grub-core/loader/multiboot_mbi2.c +++ b/grub-core/loader/multiboot_mbi2.c @@ -391,7 +391,7 @@ static grub_size_t acpiv2_size (void) { #if GRUB_MACHINE_HAS_ACPI - struct grub_acpi_rsdp_v20 *p = grub_acpi_get_rsdpv2 (); + struct grub_acpi_rsdp_v20 *p = grub_acpi_get_rsdpv2 (0); if (!p) return 0; @@ -938,7 +938,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) { struct multiboot_tag_old_acpi *tag = (struct multiboot_tag_old_acpi *) ptrorig; - struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 (); + struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 (0); if (a) { tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD; @@ -952,7 +952,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target) { struct multiboot_tag_new_acpi *tag = (struct multiboot_tag_new_acpi *) ptrorig; - struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 (); + struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 (0); if (a) { tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW; diff --git a/include/grub/acpi.h b/include/grub/acpi.h index 66148f6..f00e1d6 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -60,6 +60,14 @@ struct grub_acpi_table_header grub_uint32_t creator_rev; } GRUB_PACKED; +#define GRUB_ACPI_FACS_SIGNATURE "FACS" + +struct grub_acpi_facs_header +{ + grub_uint8_t signature[4]; + grub_uint32_t length; +} GRUB_PACKED; + #define GRUB_ACPI_FADT_SIGNATURE "FACP" struct grub_acpi_fadt @@ -180,8 +188,8 @@ enum }; #ifndef GRUB_DSDT_TEST -struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void); -struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void); +struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (int scan); +struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (int scan); struct grub_acpi_rsdp_v10 *EXPORT_FUNC(grub_machine_acpi_get_rsdpv1) (void); struct grub_acpi_rsdp_v20 *EXPORT_FUNC(grub_machine_acpi_get_rsdpv2) (void); grub_uint8_t EXPORT_FUNC(grub_byte_checksum) (void *base, grub_size_t size); -- tg: (17cb997..) u/lsacpi/print-table-address (depends on: u/lsacpi/printf-pointer-align)