rombios: Obtain S3 wake vector from >1MB.
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 29 Jul 2008 15:03:58 +0000 (16:03 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 29 Jul 2008 15:03:58 +0000 (16:03 +0100)
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
tools/firmware/rombios/32bit/32bitbios.c
tools/firmware/rombios/32bit/tcgbios/tcgbios.c
tools/firmware/rombios/32bit/tcgbios/tcgbios.h
tools/firmware/rombios/32bit/util.c
tools/firmware/rombios/32bit/util.h
tools/firmware/rombios/32bitgateway.c
tools/firmware/rombios/32bitprotos.h
tools/firmware/rombios/rombios.c

index 14dba9bf33cd59b536e7dd62a93a840b7ac54449..551a9ffdc038349b395202fdcb86117da743dc85 100644 (file)
@@ -47,5 +47,7 @@ uint32_t jumptable[IDX_LAST+1] __attribute__((section (".biosjumptable"))) =
 
        TABLE_ENTRY(IDX_TCPA_INITIALIZE_TPM, tcpa_initialize_tpm),
 
+       TABLE_ENTRY(IDX_GET_S3_WAKING_VECTOR, get_s3_waking_vector),
+
        TABLE_ENTRY(IDX_LAST       , 0)     /* keep last */
 };
index 263607471bdf49a256375239efd05ce8b5529a01..b06af22f00616fdce09a4ed9be40a00865325961 100644 (file)
 #include "rombios_compat.h"
 #include "tpm_drivers.h"
 
+#include "util.h"
 #include "tcgbios.h"
 #include "32bitprotos.h"
-#include "util.h"
-
 
 /* local structure and variables */
 struct ptti_cust {
@@ -135,7 +134,7 @@ static inline uint32_t bswap(uint32_t a)
  *******************************************************/
 
 typedef struct {
-       struct acpi_20_tcpa *tcpa_ptr;
+       struct acpi_20_tcpa_clisrv *tcpa_ptr;
        unsigned char       *lasa_last_ptr;
        uint16_t            entry_count;
        uint16_t            flags;
@@ -260,45 +259,19 @@ uint8_t acpi_validate_entry(struct acpi_header *hdr)
 }
 
 
-/*
- * Search for the RSDP ACPI table in the memory starting at addr and
- * ending at addr + len - 1.
- */
-static struct acpi_20_rsdp *find_rsdp(const void *start, unsigned int len)
-{
-       char *rsdp = (char *)start;
-       char *end = rsdp + len;
-       /* scan memory in steps of 16 bytes */
-       while (rsdp < end) {
-               /* check for expected string */
-               if (!strncmp( rsdp, "RSD PTR ", 8))
-                       return (struct acpi_20_rsdp *)rsdp;
-               rsdp += 0x10;
-       }
-       return 0;
-}
-
 void tcpa_acpi_init(void)
 {
        struct acpi_20_rsdt *rsdt;
-       struct acpi_20_tcpa *tcpa = (void *)0;
+       struct acpi_20_tcpa_clisrv *tcpa = (void *)0;
        struct acpi_20_rsdp *rsdp;
        uint32_t length;
        uint16_t off;
        int found = 0;
-       uint16_t ebda_seg;
 
-       if (MA_IsTPMPresent() == 0) {
+       if (MA_IsTPMPresent() == 0)
                return;
-       }
-
-       /* RSDP in EBDA? */
-       ebda_seg = *(uint16_t *)ADDR_FROM_SEG_OFF(0x40, 0xe);
-       rsdp = find_rsdp((void *)(ebda_seg << 16), 1024);
-
-       if (!rsdp)
-               rsdp = find_rsdp((void *)(ACPI_SEGMENT << 4), 0x20000);
 
+       rsdp = find_rsdp();
        if (rsdp) {
                uint32_t ctr = 0;
                /* get RSDT from RSDP */
@@ -307,7 +280,7 @@ void tcpa_acpi_init(void)
                off = 36;
                while ((off + 3) < length) {
                        /* try all pointers to structures */
-                       tcpa = (struct acpi_20_tcpa *)rsdt->entry[ctr];
+                       tcpa = (struct acpi_20_tcpa_clisrv *)rsdt->entry[ctr];
                        /* valid TCPA ACPI table ? */
                        if (ACPI_2_0_TCPA_SIGNATURE == tcpa->header.signature
                            && acpi_validate_entry(&tcpa->header) == 0) {
@@ -398,7 +371,7 @@ static
 unsigned char *tcpa_get_lasa_base_ptr(void)
 {
        unsigned char *lasa = 0;
-       struct acpi_20_tcpa *tcpa = tcpa_acpi.tcpa_ptr;
+       struct acpi_20_tcpa_clisrv *tcpa = tcpa_acpi.tcpa_ptr;
        if (tcpa != 0) {
                uint32_t class = tcpa->platform_class;
                if (class == TCPA_ACPI_CLASS_CLIENT) {
@@ -416,7 +389,7 @@ static
 uint32_t tcpa_get_laml(void)
 {
        uint32_t laml = 0;
-       struct acpi_20_tcpa *tcpa = tcpa_acpi.tcpa_ptr;
+       struct acpi_20_tcpa_clisrv *tcpa = tcpa_acpi.tcpa_ptr;
        if (tcpa != 0) {
                uint32_t class = tcpa->platform_class;
                if (class == TCPA_ACPI_CLASS_CLIENT) {
index bf2b133c5249328bc37a283e343d2722555253d8..f16b586b28b0ba231971d1431b51a5146f994e89 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef TCGBIOS_H
 #define TCGBIOS_H
 
-
 /* TCPA ACPI definitions */
 #define TCPA_ACPI_CLASS_CLIENT          0
 #define TCPA_ACPI_CLASS_SERVER          1
 /* address of locality 0 (TIS) */
 #define TPM_TIS_BASE_ADDRESS        0xfed40000
 
-#define ASCII32(a,b,c,d)     ((((Bit32u)a) <<  0) | (((Bit32u)b) <<  8) | \
-                              (((Bit32u)c) << 16) | (((Bit32u)d) << 24)  )
-#define ACPI_2_0_TCPA_SIGNATURE ASCII32('T','C','P','A') /* "TCPA" */
-
-
 #define STATUS_FLAG_SHUTDOWN                (1 << 0)
 
-#define ACPI_SEGMENT    0xE000
-
 /* Input and Output blocks for the TCG BIOS commands */
 
 struct hleei_short
@@ -232,37 +224,6 @@ struct pcpes
        uint32_t    event;
 } __attribute__((packed));
 
-
-struct acpi_header
-{
-       uint32_t signature;
-       uint32_t length;
-       uint8_t  revision;
-       uint8_t  checksum;
-       uint8_t  oem_id[6];
-       uint64_t oem_table_id;
-       uint32_t oem_revision;
-       uint32_t creator_id;
-       uint32_t creator_revision;
-} __attribute__((packed));
-
-struct acpi_20_rsdt {
-       struct acpi_header header;
-       uint32_t entry[1];
-} __attribute__((packed));
-
-struct acpi_20_rsdp {
-       uint64_t signature;
-       uint8_t  checksum;
-       uint8_t  oem_id[6];
-       uint8_t  revision;
-       uint32_t rsdt_address;
-       uint32_t length;
-       uint64_t xsdt_address;
-       uint8_t  extended_checksum;
-       uint8_t  reserved[3];
-} __attribute__((packed));
-
 struct acpi_20_tcpa_client {
        uint32_t laml;
        uint64_t lasa;
@@ -275,7 +236,7 @@ struct acpi_20_tcpa_server {
        /* more here */
 } __attribute__((packed));
 
-struct acpi_20_tcpa {
+struct acpi_20_tcpa_clisrv {
        struct acpi_header header;
        uint16_t platform_class;
        union {
index ad60b9eedbb8a4a6464cc8481deb7817312ce199..a47bb71cde87b4741e4f766085136ab50b76d4bb 100644 (file)
@@ -19,6 +19,7 @@
  */
 #include <stdarg.h>
 #include <stdint.h>
+#include "rombios_compat.h"
 #include "util.h"
 
 static void putchar(char c);
@@ -92,11 +93,11 @@ int strcmp(const char *cs, const char *ct)
 
 int strncmp(const char *s1, const char *s2, uint32_t n)
 {
-       uint32_t ctr;
-       for (ctr = 0; ctr < n; ctr++)
-               if (s1[ctr] != s2[ctr])
-                       return (int)(s1[ctr] - s2[ctr]);
-       return 0;
+    uint32_t ctr;
+    for (ctr = 0; ctr < n; ctr++)
+        if (s1[ctr] != s2[ctr])
+            return (int)(s1[ctr] - s2[ctr]);
+    return 0;
 }
 
 void *memcpy(void *dest, const void *src, unsigned n)
@@ -402,3 +403,64 @@ void mssleep(uint32_t waittime)
         y = x;
     }
 }
+
+/*
+ * Search for the RSDP ACPI table in the memory starting at addr and
+ * ending at addr + len - 1.
+ */
+static struct acpi_20_rsdp *__find_rsdp(const void *start, unsigned int len)
+{
+    char *rsdp = (char *)start;
+    char *end = rsdp + len;
+    /* scan memory in steps of 16 bytes */
+    while (rsdp < end) {
+        /* check for expected string */
+        if (!strncmp(rsdp, "RSD PTR ", 8))
+            return (struct acpi_20_rsdp *)rsdp;
+        rsdp += 0x10;
+    }
+    return 0;
+}
+
+struct acpi_20_rsdp *find_rsdp(void)
+{
+    struct acpi_20_rsdp *rsdp;
+    uint16_t ebda_seg;
+
+    ebda_seg = *(uint16_t *)ADDR_FROM_SEG_OFF(0x40, 0xe);
+    rsdp = __find_rsdp((void *)(ebda_seg << 16), 1024);
+    if (!rsdp)
+        rsdp = __find_rsdp((void *)0xE0000, 0x20000);
+
+    return rsdp;
+}
+
+uint32_t get_s3_waking_vector(void)
+{
+    struct acpi_20_rsdp *rsdp = find_rsdp();
+    struct acpi_20_xsdt *xsdt;
+    struct acpi_20_fadt *fadt;
+    struct acpi_20_facs *facs;
+    uint32_t vector;
+
+    if (!rsdp)
+        return 0;
+
+    xsdt = (struct acpi_20_xsdt *)(long)rsdp->xsdt_address;
+    if (!xsdt)
+        return 0;
+
+    fadt = (struct acpi_20_fadt *)(long)xsdt->entry[0];
+    if (!fadt || (fadt->header.signature != ACPI_2_0_FADT_SIGNATURE))
+        return 0;
+
+    facs = (struct acpi_20_facs *)(long)fadt->x_firmware_ctrl;
+    if (!facs)
+        return 0;
+
+    vector = facs->x_firmware_waking_vector;
+    if (!vector)
+        vector = facs->firmware_waking_vector;
+
+    return vector;
+}
index 6d05b502d5f3f84e4ac2f92409ce25b62743fbfe..e245be6569f13938525ce0ab1d5890e8c248c3c1 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef UTIL_H
 #define UTIL_H
 
+#include "../hvmloader/acpi/acpi2_0.h"
+
 void outb(uint16_t addr, uint8_t val);
 void outw(uint16_t addr, uint16_t val);
 void outl(uint16_t addr, uint32_t val);
@@ -39,5 +41,6 @@ static inline uint32_t mmio_readl(uint32_t *addr)
        return *(volatile uint32_t *)addr;
 }
 
+struct acpi_20_rsdp *find_rsdp(void);
 
 #endif
index 4da5a39c457d3469eeda6c1dce085c78a37e1768..9592dfbca14ea6fc2692cdb86cc92dfb105c2ee2 100644 (file)
@@ -356,6 +356,9 @@ Upcall:
        call _store_returnaddress       ; store away
        pop ax
 
+       ; XXX GDT munging requires ROM to be writable!
+       call _enable_rom_write_access
+
        rol bx, #2
        mov si, #jmptable
        seg cs
@@ -382,6 +385,8 @@ Upcall:
        mov bp,sp
        push eax                        ; preserve work register
 
+       call _disable_rom_write_access
+
        call _get_returnaddress
        mov 2[bp], ax                   ; 16bit return address onto stack
 
@@ -408,3 +413,10 @@ ASM_END
 #include "32bitgateway.h"
 
 #include "tcgbios.c"
+
+Bit32u get_s3_waking_vector()
+{
+       ASM_START
+       DoUpcall(IDX_GET_S3_WAKING_VECTOR)
+       ASM_END
+}
index 69ec87dc34c029675a0538b770fdd4f14463f99e..f0c401476a98e8894673f6ba44d6d95833d6f290 100644 (file)
@@ -17,8 +17,8 @@
 #define IDX_TCPA_IPL                       10
 #define IDX_TCPA_INITIALIZE_TPM            11
 #define IDX_TCPA_MEASURE_POST              12
-
-#define IDX_LAST                           13 /* keep last! */
+#define IDX_GET_S3_WAKING_VECTOR           13
+#define IDX_LAST                           14 /* keep last! */
 
 #ifdef GCC_PROTOS
   #define PARMS(x...) x
@@ -42,4 +42,6 @@ void tcpa_ipl( PARMS(Bit32u bootcd,Bit32u seg,Bit32u off,Bit32u count) );
 void tcpa_measure_post( PARMS(Bit32u from, Bit32u to) );
 Bit32u tcpa_initialize_tpm( PARMS(Bit32u physpres) );
 
+Bit32u get_s3_waking_vector( PARMS(void) );
+
 #endif
index cb2da617c75b2fb27900b3aa36d3c86a98114980..1546c3d6444ad25a2bd96fda773735573edaa23a 100644 (file)
@@ -1482,6 +1482,16 @@ ASM_START
     out dx,al
 ASM_END
 }
+
+void enable_rom_write_access()
+{
+    set_rom_write_access(0);
+}
+
+void disable_rom_write_access()
+{
+    set_rom_write_access(PFFLAG_ROM_LOCK);
+}
     
 #endif /* HVMASSIST */
 
@@ -2378,14 +2388,9 @@ ASM_END
     if (s3_resume_flag != CMOS_SHUTDOWN_S3)
         return;
 
-    /* get x_firmware_waking_vector */
-    s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+24);
-    if (!s3_wakeup_vector) {
-        /* get firmware_waking_vector */
-       s3_wakeup_vector = facs_get32(ACPI_FACS_OFFSET+12);
-       if (!s3_wakeup_vector)
-            return;
-    }
+    s3_wakeup_vector = get_s3_waking_vector();
+    if (!s3_wakeup_vector)
+        return;
 
     s3_wakeup_ip = s3_wakeup_vector & 0xF;
     s3_wakeup_cs = s3_wakeup_vector >> 4;
@@ -9927,9 +9932,7 @@ normal_post:
   call _log_bios_start
 
 #ifdef HVMASSIST
-  push #0
-  call _set_rom_write_access
-  add sp,#2
+  call _enable_rom_write_access
 #endif
 
   call _clobber_entry_point
@@ -10128,9 +10131,7 @@ post_default_ints:
 #ifdef HVMASSIST
   call _copy_e820_table
   call smbios_init
-  push #PFFLAG_ROM_LOCK
-  call _set_rom_write_access
-  add sp,#2
+  call _disable_rom_write_access
 #endif
 
   call _init_boot_vectors