[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] hvm: Add a revision 1 FADT in ACPI, and link the original revision-4



# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1173872306 0
# Node ID 4d7327502ba6e5776f22c80e541f9298ee0692d5
# Parent  2787228610af8b70114f60a302078797ab596b80
hvm: Add a revision 1 FADT in ACPI, and link the original revision-4
FADT only to XSDT. It avoids a buffer overflow in the initialization
of Window 2000 ACPI HAL (pre ACPI 2.0 OS), and thus enables the
installation and boot. This compatibility practice is also used in
hardware, please refer to:
 http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt

Signed-off-by: Qing He <qing.he@xxxxxxxxx>
---
 tools/firmware/hvmloader/acpi/acpi2_0.h |   52 ++++++++++++++++++++++++++++++--
 tools/firmware/hvmloader/acpi/build.c   |   22 ++++++++++++-
 2 files changed, 70 insertions(+), 4 deletions(-)

diff -r 2787228610af -r 4d7327502ba6 tools/firmware/hvmloader/acpi/acpi2_0.h
--- a/tools/firmware/hvmloader/acpi/acpi2_0.h   Wed Mar 14 11:22:59 2007 +0000
+++ b/tools/firmware/hvmloader/acpi/acpi2_0.h   Wed Mar 14 11:38:26 2007 +0000
@@ -143,9 +143,9 @@ struct acpi_20_tcpa {
 #define ACPI_2_0_TCPA_LAML_SIZE (64*1024)
 
 /*
- * Fixed ACPI Description Table Structure (FADT).
- */
-struct acpi_20_fadt {
+ * Fixed ACPI Description Table Structure (FADT) in ACPI 1.0.
+ */
+struct acpi_10_fadt {
     struct acpi_header header;
     uint32_t firmware_ctrl;
     uint32_t dsdt;
@@ -185,6 +185,51 @@ struct acpi_20_fadt {
     uint16_t iapc_boot_arch;
     uint8_t  reserved1;
     uint32_t flags;
+};
+
+/*
+ * Fixed ACPI Description Table Structure (FADT).
+ */
+struct acpi_20_fadt {
+    struct acpi_header header;
+    uint32_t firmware_ctrl;
+    uint32_t dsdt;
+    uint8_t  reserved0;
+    uint8_t  preferred_pm_profile;
+    uint16_t sci_int;
+    uint32_t smi_cmd;
+    uint8_t  acpi_enable;
+    uint8_t  acpi_disable;
+    uint8_t  s4bios_req;
+    uint8_t  pstate_cnt;
+    uint32_t pm1a_evt_blk;
+    uint32_t pm1b_evt_blk;
+    uint32_t pm1a_cnt_blk;
+    uint32_t pm1b_cnt_blk;
+    uint32_t pm2_cnt_blk;
+    uint32_t pm_tmr_blk;
+    uint32_t gpe0_blk;
+    uint32_t gpe1_blk;
+    uint8_t  pm1_evt_len;
+    uint8_t  pm1_cnt_len;
+    uint8_t  pm2_cnt_len;
+    uint8_t  pm_tmr_len;
+    uint8_t  gpe0_blk_len;
+    uint8_t  gpe1_blk_len;
+    uint8_t  gpe1_base;
+    uint8_t  cst_cnt;
+    uint16_t p_lvl2_lat;
+    uint16_t p_lvl3_lat;
+    uint16_t flush_size;
+    uint16_t flush_stride;
+    uint8_t  duty_offset;
+    uint8_t  duty_width;
+    uint8_t  day_alrm;
+    uint8_t  mon_alrm;
+    uint8_t  century;
+    uint16_t iapc_boot_arch;
+    uint8_t  reserved1;
+    uint32_t flags;
     struct acpi_20_generic_address reset_reg;
     uint8_t  reset_value;
     uint8_t  reserved2[3];
@@ -345,6 +390,7 @@ struct acpi_20_madt_intsrcovr {
 #define ACPI_2_0_XSDT_REVISION 0x01
 #define ACPI_2_0_TCPA_REVISION 0x02
 #define ACPI_2_0_HPET_REVISION 0x01
+#define ACPI_1_0_FADT_REVISION 0x01
 
 #pragma pack ()
 
diff -r 2787228610af -r 4d7327502ba6 tools/firmware/hvmloader/acpi/build.c
--- a/tools/firmware/hvmloader/acpi/build.c     Wed Mar 14 11:22:59 2007 +0000
+++ b/tools/firmware/hvmloader/acpi/build.c     Wed Mar 14 11:38:26 2007 +0000
@@ -293,6 +293,7 @@ int acpi_build_tables(uint8_t *buf)
     struct acpi_20_rsdt *rsdt;
     struct acpi_20_xsdt *xsdt;
     struct acpi_20_fadt *fadt;
+    struct acpi_10_fadt *fadt_10;
     struct acpi_20_facs *facs;
     unsigned char       *dsdt;
     unsigned long        secondary_tables[16];
@@ -305,6 +306,25 @@ int acpi_build_tables(uint8_t *buf)
     dsdt = (unsigned char *)&buf[offset];
     memcpy(dsdt, &AmlCode, DsdtLen);
     offset += align16(DsdtLen);
+
+    /*
+     * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2
+     * or above properly, notably Windows 2000, which tries to copy FADT
+     * into a 116 bytes buffer thus causing an overflow. The solution is to
+     * link the higher revision FADT with the XSDT only and introduce a
+     * compatible revision 1 FADT that is linked with the RSDT. Refer to:
+     *     http://www.acpi.info/presentations/S01USMOBS169_OS%20new.ppt
+     */
+    fadt_10 = (struct acpi_10_fadt *)&buf[offset];
+    memcpy(fadt_10, &Fadt, sizeof(struct acpi_10_fadt));
+    offset += align16(sizeof(struct acpi_10_fadt));
+    fadt_10->header.length = sizeof(struct acpi_10_fadt);
+    fadt_10->header.revision = ACPI_1_0_FADT_REVISION;
+    fadt_10->dsdt          = (unsigned long)dsdt;
+    fadt_10->firmware_ctrl = (unsigned long)facs;
+    set_checksum(fadt_10,
+                 offsetof(struct acpi_header, checksum),
+                 sizeof(struct acpi_10_fadt));
 
     fadt = (struct acpi_20_fadt *)&buf[offset];
     memcpy(fadt, &Fadt, sizeof(struct acpi_20_fadt));
@@ -332,7 +352,7 @@ int acpi_build_tables(uint8_t *buf)
 
     rsdt = (struct acpi_20_rsdt *)&buf[offset];
     memcpy(rsdt, &Rsdt, sizeof(struct acpi_header));
-    rsdt->entry[0] = (unsigned long)fadt;
+    rsdt->entry[0] = (unsigned long)fadt_10;
     for ( i = 0; secondary_tables[i]; i++ )
         rsdt->entry[i+1] = secondary_tables[i];
     rsdt->header.length = sizeof(struct acpi_header) + (i+1)*sizeof(uint32_t);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.