From c2830c96616c689502401f31be7279e54a35d449 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 22 Aug 2023 12:50:43 +0200 Subject: acpi.c: Add XSDT on QEMU Since d8f2dce "acpi.c: Swap XSDT and RSDT for adding/finding tables" XSDT is primarily used to add new tables or to find the S3 resume vector. However with QEMU coreboot does not generate most ACPI tables but takes them from whatever QEMU provides. Qemu only creates an RSDT and lacks an XSDT. To keep the codebase simple with the assumption that XSDT is always present, create an XSDT based on the existing RSDT and update the address in RSDP. Signed-off-by: Arthur Heymans Change-Id: Ia9b7f090f55e436de98afad6f23597c3d426bb88 Reviewed-on: https://review.coreboot.org/c/coreboot/+/77385 Reviewed-by: Tim Wawrzynczak Reviewed-by: Eric Lai Tested-by: build bot (Jenkins) --- src/acpi/acpi.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/acpi/acpi.c b/src/acpi/acpi.c index e357f6a87d..17cd24c023 100644 --- a/src/acpi/acpi.c +++ b/src/acpi/acpi.c @@ -48,7 +48,7 @@ void acpi_add_table(acpi_rsdp_t *rsdp, void *table) { int i, entries_num; acpi_rsdt_t *rsdt; - acpi_xsdt_t *xsdt = NULL; + acpi_xsdt_t *xsdt; /* The 32bit RSDT may not be valid if tables live above 4GiB */ rsdt = (acpi_rsdt_t *)(uintptr_t)rsdp->rsdt_address; @@ -1408,10 +1408,33 @@ unsigned long write_acpi_tables(const unsigned long start) if (!rsdp) return fw; + current = fw; + current = acpi_align_current(current); + if (rsdp->xsdt_address == 0) { + xsdt = (acpi_xsdt_t *)current; + current += sizeof(acpi_xsdt_t); + current = acpi_align_current(current); + + /* + * Qemu only creates an RSDT. + * Add an XSDT based on the existing RSDT entries. + */ + acpi_rsdt_t *existing_rsdt = (acpi_rsdt_t *)(uintptr_t)rsdp->rsdt_address; + acpi_write_rsdp(rsdp, existing_rsdt, xsdt, oem_id); + acpi_write_xsdt(xsdt, oem_id, oem_table_id); + /* + * Copy existing entries to the new XSDT. This will override existing + * RSDT entries with the same value. + */ + for (int i = 0; existing_rsdt->entry[i]; i++) + acpi_add_table(rsdp, (void *)(uintptr_t)existing_rsdt->entry[i]); + + } + /* Add BOOT0000 for Linux google firmware driver */ printk(BIOS_DEBUG, "ACPI: * SSDT\n"); - ssdt = (acpi_header_t *)fw; - current = (unsigned long)ssdt + sizeof(acpi_header_t); + ssdt = (acpi_header_t *)current; + current += sizeof(acpi_header_t); memset((void *)ssdt, 0, sizeof(acpi_header_t)); -- cgit v1.2.3