hvmloader: Load ACPI tables outside BIOS area, so they are writable by
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 29 Jul 2008 14:10:58 +0000 (15:10 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 29 Jul 2008 14:10:58 +0000 (15:10 +0100)
OSPM (particularly the S3 firmware_waking_vector).

TODO: rombios must enter protected mode to fetch the vector on S3 resume.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
tools/firmware/hvmloader/acpi/acpi2_0.h
tools/firmware/hvmloader/acpi/build.c
tools/firmware/hvmloader/hvmloader.c
tools/firmware/hvmloader/util.h

index 5846cb2fac1cf454033437543b35463980708126..cf0ca016171513b45541cfa0a8941558b4e94328 100644 (file)
@@ -381,7 +381,7 @@ struct acpi_20_madt_intsrcovr {
 
 #pragma pack ()
 
-int acpi_build_tables(uint8_t *);
+void acpi_build_tables(void);
 
 #endif /* _ACPI_2_0_H_ */
 
index 75e1a60e5573a0c1fe08f1bbaa9fd5c234927f59..e753bf32762e295701427be4e624bdadedcb4b9c 100644 (file)
@@ -248,8 +248,7 @@ static int construct_secondary_tables(uint8_t *buf, unsigned long *table_ptrs)
     return align16(offset);
 }
 
-/* Copy all the ACPI table to buffer. */
-int acpi_build_tables(uint8_t *buf)
+static void __acpi_build_tables(uint8_t *buf, int *low_sz, int *high_sz)
 {
     struct acpi_20_rsdp *rsdp;
     struct acpi_20_rsdt *rsdt;
@@ -261,7 +260,9 @@ int acpi_build_tables(uint8_t *buf)
     unsigned long        secondary_tables[16];
     int                  offset = 0, i;
 
-    offset += construct_bios_info_table(&buf[offset]);
+    /*
+     * Fill in high-memory data structures, starting at @buf.
+     */
 
     facs = (struct acpi_20_facs *)&buf[offset];
     memcpy(facs, &Facs, sizeof(struct acpi_20_facs));
@@ -325,7 +326,18 @@ int acpi_build_tables(uint8_t *buf)
                  offsetof(struct acpi_header, checksum),
                  rsdt->header.length);
 
+    *high_sz = offset;
+
+    /*
+     * Fill in low-memory data structures: bios_info_table and RSDP.
+     */
+
+    buf = (uint8_t *)ACPI_PHYSICAL_ADDRESS;
+    offset = 0;
+
+    offset += construct_bios_info_table(&buf[offset]);
     rsdp = (struct acpi_20_rsdp *)&buf[offset];
+
     memcpy(rsdp, &Rsdp, sizeof(struct acpi_20_rsdp));
     offset += align16(sizeof(struct acpi_20_rsdp));
     rsdp->rsdt_address = (unsigned long)rsdt;
@@ -337,7 +349,28 @@ int acpi_build_tables(uint8_t *buf)
                  offsetof(struct acpi_20_rsdp, extended_checksum),
                  sizeof(struct acpi_20_rsdp));
 
-    return offset;
+    *low_sz = offset;
+}
+
+void acpi_build_tables(void)
+{
+    int high_sz, low_sz;
+    uint8_t *buf;
+
+    /* Find out size of high-memory ACPI data area. */
+    buf = (uint8_t *)&_end;
+    __acpi_build_tables(buf, &low_sz, &high_sz);
+    memset(buf, 0, high_sz);
+
+    /* Allocate data area and set up ACPI tables there. */
+    buf = (uint8_t *)e820_malloc(high_sz);
+    __acpi_build_tables(buf, &low_sz, &high_sz);
+
+    printf(" - Lo data: %08lx-%08lx\n"
+           " - Hi data: %08lx-%08lx\n",
+           (unsigned long)ACPI_PHYSICAL_ADDRESS,
+           (unsigned long)ACPI_PHYSICAL_ADDRESS + low_sz - 1,
+           (unsigned long)buf, (unsigned long)buf + high_sz - 1);
 }
 
 /*
index 5f1f22e6dd0d8ef180fcb0b5960585a6c3fce3b7..f0e5816caa040921329ab3bceaac5d287c7f5528 100644 (file)
@@ -449,7 +449,7 @@ static void init_xen_platform_io_base(void)
 
 int main(void)
 {
-    int acpi_sz = 0, vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
+    int vgabios_sz = 0, etherboot_sz = 0, rombios_sz, smbios_sz;
     int extboot_sz = 0;
 
     printf("HVM Loader\n");
@@ -508,8 +508,7 @@ int main(void)
     if ( get_acpi_enabled() )
     {
         printf("Loading ACPI ...\n");
-        acpi_sz = acpi_build_tables((uint8_t *)ACPI_PHYSICAL_ADDRESS);
-        ASSERT((ACPI_PHYSICAL_ADDRESS + acpi_sz) <= 0xF0000);
+        acpi_build_tables();
     }
 
     cmos_write_memory_size();
@@ -531,10 +530,6 @@ int main(void)
         printf(" %05x-%05x: SMBIOS tables\n",
                SMBIOS_PHYSICAL_ADDRESS,
                SMBIOS_PHYSICAL_ADDRESS + smbios_sz - 1);
-    if ( acpi_sz )
-        printf(" %05x-%05x: ACPI tables\n",
-               ACPI_PHYSICAL_ADDRESS,
-               ACPI_PHYSICAL_ADDRESS + acpi_sz - 1);
     if ( rombios_sz )
         printf(" %05x-%05x: Main BIOS\n",
                ROMBIOS_PHYSICAL_ADDRESS,
index 455b2f66e644f96ef8299f5545f6bfda2d669f3f..4d85e2cef959c5c3d842ffd78eb59865588209e7 100644 (file)
@@ -145,4 +145,6 @@ void smp_initialise(void);
 
 #define isdigit(c) ((c) >= '0' && (c) <= '9')
 
+extern char _start[], _end[];
+
 #endif /* __HVMLOADER_UTIL_H__ */