Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/75677?usp=email )
Change subject: acpi: Add a debug option to print out tables in ACPICA compatible hex ......................................................................
acpi: Add a debug option to print out tables in ACPICA compatible hex
Sometimes systems don't boot to the OS due to wrong ACPI tables. Printing the tables in an ACPICA compatible format makes analysis of ACPI tables easier.
To achieve this capture the coreboot log between "Printing ACPI in ACPICA compatible table" and "Done printing ACPI in ACPICA compatible table". Remove the prefix "[SPEW ] " and then call 'acpixtract -a dump' to extract all the tables. Then use iasl on the .dat files to decompile the tables.
Signed-off-by: Arthur Heymans arthur@aheymans.xyz Change-Id: I7b5d879014563f7a2e1f70c45cf871ba72f142dc --- M src/Kconfig M src/acpi/acpi.c 2 files changed, 88 insertions(+), 13 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/77/75677/1
diff --git a/src/Kconfig b/src/Kconfig index f8d7f76..0958fb4 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -1294,6 +1294,13 @@ mainboard code supports this. On supported Intel platforms this works by changing the settings in the descriptor.bin file.
+config DEBUG_ACPICA_COMPATIBLE + bool "Print out ACPI tables in ACPICA compatible format" + depends on HAVE_ACPI_TABLES + help + Select this to print out ACPI tables in an ACPICA compatible + format. + endmenu
############################################################################### diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index 4fdbd6f..da55e92 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -1822,23 +1822,79 @@ return coreboot_rsdp; }
+static void acpixtract_compatible_hexdump(const void *memory, size_t length) +{ + size_t i, j; + uint8_t *line; + int all_zero = 0; + int all_one = 0; + size_t num_bytes; + + for (i = 0; i < length; i += 16) { + num_bytes = MIN(length - i, 16); + line = ((uint8_t *)memory) + i; + + all_zero++; + all_one++; + for (j = 0; j < num_bytes; j++) { + if (line[j] != 0) { + all_zero = 0; + break; + } + } + + for (j = 0; j < num_bytes; j++) { + if (line[j] != 0xff) { + all_one = 0; + break; + } + } + + if ((all_zero < 2) && (all_one < 2)) { + printk(BIOS_SPEW, " %04lX:", i); + for (j = 0; j < num_bytes; j++) + printk(BIOS_SPEW, " %02x", line[j]); + for (; j < 16; j++) + printk(BIOS_SPEW, " "); + printk(BIOS_SPEW, " "); + for (j = 0; j < num_bytes; j++) + printk(BIOS_SPEW, "%c", + isprint(line[j]) ? line[j] : '.'); + printk(BIOS_SPEW, "\n"); + } else if ((all_zero == 2) || (all_one == 2)) { + printk(BIOS_SPEW, "...\n"); + } + } +} + +static void acpidump_print(void *table_ptr) +{ + const acpi_header_t *header = (acpi_header_t *)table_ptr; + const size_t table_size = header->length; + char table_signature[5] = {}; + memcpy(table_signature, header->signature, sizeof(header->signature)); + printk(BIOS_SPEW, "%s @ 0x0000000000000000\n", table_signature); + acpixtract_compatible_hexdump(table_ptr, table_size); + printk(BIOS_SPEW, "\n"); +} + unsigned long write_acpi_tables(unsigned long start) { unsigned long current; acpi_rsdp_t *rsdp; - acpi_rsdt_t *rsdt; - acpi_xsdt_t *xsdt; - acpi_fadt_t *fadt; - acpi_facs_t *facs; - acpi_header_t *slic_file, *slic; - acpi_header_t *ssdt; - acpi_header_t *dsdt_file, *dsdt; - acpi_mcfg_t *mcfg; - acpi_tcpa_t *tcpa; - acpi_tpm2_t *tpm2; - acpi_madt_t *madt; - acpi_lpit_t *lpit; - acpi_bert_t *bert; + acpi_rsdt_t *rsdt = NULL; + acpi_xsdt_t *xsdt = NULL; + acpi_fadt_t *fadt = NULL; + acpi_facs_t *facs = NULL; + acpi_header_t *slic_file, *slic = NULL; + acpi_header_t *ssdt = NULL; + acpi_header_t *dsdt_file, *dsdt = NULL; + acpi_mcfg_t *mcfg = NULL; + acpi_tcpa_t *tcpa = NULL; + acpi_tpm2_t *tpm2 = NULL; + acpi_madt_t *madt = NULL; + acpi_lpit_t *lpit = NULL; + acpi_bert_t *bert = NULL; struct device *dev; unsigned long fw; size_t slic_size, dsdt_size; @@ -2101,6 +2157,18 @@ }
printk(BIOS_INFO, "ACPI: done.\n"); + + if (CONFIG(DEBUG_ACPICA_COMPATIBLE)) { + printk(BIOS_DEBUG, "Printing ACPI in ACPICA compatible table\n"); + void *acpi_tables[] = { rsdt, xsdt, fadt, facs, slic, ssdt, dsdt, mcfg, tcpa, tpm2, madt, lpit, bert }; + for (size_t i = 0; i < ARRAY_SIZE(acpi_tables); i++) { + if (acpi_tables[i] == NULL) + continue; + acpidump_print(acpi_tables[i]); + } + printk(BIOS_DEBUG, "Done printing ACPI in ACPICA compatible table\n"); + } + return current; }