diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2023-08-22 12:50:43 +0200 |
---|---|---|
committer | Arthur Heymans <arthur@aheymans.xyz> | 2023-09-14 10:37:33 +0000 |
commit | c2830c96616c689502401f31be7279e54a35d449 (patch) | |
tree | c27f74af8b21f16efe1a548f70ad04b5ae5939d0 /src | |
parent | 218964078669de938aaac75e48dc86af69bda2c1 (diff) |
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 <arthur@aheymans.xyz>
Change-Id: Ia9b7f090f55e436de98afad6f23597c3d426bb88
Reviewed-on: https://review.coreboot.org/c/coreboot/+/77385
Reviewed-by: Tim Wawrzynczak <inforichland@gmail.com>
Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/acpi/acpi.c | 29 |
1 files changed, 26 insertions, 3 deletions
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)); |