Patchwork seabios: acpi: allow qemu to load dsdt as external acpi table.

login
register
mail settings
Submitter Isaku Yamahata
Date June 15, 2010, 3:51 a.m.
Message ID <20100615035116.GW23473@valinux.co.jp>
Download mbox | patch
Permalink /patch/55604/
State New
Headers show

Comments

Isaku Yamahata - June 15, 2010, 3:51 a.m.
allow qemu to load dsdt as external acpi table.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
---
 src/acpi.c |   27 +++++++++++++++++++++++++--
 1 files changed, 25 insertions(+), 2 deletions(-)
Kevin O'Connor - June 22, 2010, 3:02 a.m.
On Tue, Jun 15, 2010 at 12:51:16PM +0900, Isaku Yamahata wrote:
> allow qemu to load dsdt as external acpi table.

I'm okay with the general idea.  However, I don't much like building
and copying the dsdt just to free it later.  It would be preferable if
the code would load in all the qemu provided tables, and then only
build the equivalent seabios table if it isn't already provided by
qemu.

This way, high memory isn't allocated and then later free'd - which
can cause unnecessary high memory reservations.

-Kevin

Patch

diff --git a/src/acpi.c b/src/acpi.c
index 0559443..254e43b 100644
--- a/src/acpi.c
+++ b/src/acpi.c
@@ -126,6 +126,11 @@  struct fadt_descriptor_rev1
 } PACKED;
 
 /*
+ * Differentiated System Descrition Table (DSDT)
+ */
+#define DSDT_SIGNATURE 0x54445344 // DSDT
+
+/*
  * MADT values and structures
  */
 
@@ -280,6 +285,11 @@  static inline u32 cpu_to_le32(u32 x)
     return x;
 }
 
+static inline u32 le32_to_cpu(u32 x)
+{
+    return x;
+}
+
 static void
 build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
 {
@@ -634,7 +644,8 @@  acpi_bios_init(void)
     } while(0)
 
     // Add tables
-    ACPI_INIT_TABLE(build_fadt(bdf));
+    struct fadt_descriptor_rev1 *fadt = build_fadt(bdf);
+    ACPI_INIT_TABLE(fadt);
     ACPI_INIT_TABLE(build_ssdt());
     ACPI_INIT_TABLE(build_madt());
     ACPI_INIT_TABLE(build_hpet());
@@ -649,7 +660,19 @@  acpi_bios_init(void)
             warn_noalloc();
             continue;
         }
-        ACPI_INIT_TABLE(qemu_cfg_next_acpi_table_load(addr, len));
+        struct acpi_table_header *header =
+            qemu_cfg_next_acpi_table_load(addr, len);
+        if (header->signature == DSDT_SIGNATURE) {
+            if (fadt) {
+                free((void*)le32_to_cpu(fadt->dsdt));
+                fadt->dsdt = cpu_to_le32((u32)addr);
+                fadt->checksum -= checksum(fadt, sizeof(*fadt));
+                header->checksum -= checksum(header, len);
+                dprintf(1, "ACPI DSDT=%p\n", addr);
+            }
+        } else {
+            ACPI_INIT_TABLE(header);
+        }
         if (tbl_idx == MAX_ACPI_TABLES) {
             warn_noalloc();
             break;