summaryrefslogtreecommitdiff
path: root/src/acpi
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2023-08-22 12:50:43 +0200
committerArthur Heymans <arthur@aheymans.xyz>2023-09-14 10:37:33 +0000
commitc2830c96616c689502401f31be7279e54a35d449 (patch)
treec27f74af8b21f16efe1a548f70ad04b5ae5939d0 /src/acpi
parent218964078669de938aaac75e48dc86af69bda2c1 (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/acpi')
-rw-r--r--src/acpi/acpi.c29
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));