summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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));