# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1217343838 -3600
# Node ID 979e098dfb925938b850c0d176e27000dcbc9a33
# Parent a538185695edbd22b74338afd0683607baa93dd8
rombios: Obtain S3 wake vector from >1MB.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
tools/firmware/rombios/32bit/32bitbios.c | 2
tools/firmware/rombios/32bit/tcgbios/tcgbios.c | 47 +++-------------
tools/firmware/rombios/32bit/tcgbios/tcgbios.h | 41 --------------
tools/firmware/rombios/32bit/util.c | 72 +++++++++++++++++++++++--
tools/firmware/rombios/32bit/util.h | 3 +
tools/firmware/rombios/32bitgateway.c | 12 ++++
tools/firmware/rombios/32bitprotos.h | 6 +-
tools/firmware/rombios/rombios.c | 29 +++++-----
8 files changed, 114 insertions(+), 98 deletions(-)
diff -r a538185695ed -r 979e098dfb92 tools/firmware/rombios/32bit/32bitbios.c
--- a/tools/firmware/rombios/32bit/32bitbios.c Tue Jul 29 15:10:58 2008 +0100
+++ b/tools/firmware/rombios/32bit/32bitbios.c Tue Jul 29 16:03:58 2008 +0100
@@ -47,5 +47,7 @@ uint32_t jumptable[IDX_LAST+1] __attribu
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 */
};
diff -r a538185695ed -r 979e098dfb92
tools/firmware/rombios/32bit/tcgbios/tcgbios.c
--- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Tue Jul 29 15:10:58
2008 +0100
+++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Tue Jul 29 16:03:58
2008 +0100
@@ -24,10 +24,9 @@
#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_
}
-/*
- * 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 @@ unsigned char *tcpa_get_lasa_base_ptr(vo
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 @@ uint32_t tcpa_get_laml(void)
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) {
diff -r a538185695ed -r 979e098dfb92
tools/firmware/rombios/32bit/tcgbios/tcgbios.h
--- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.h Tue Jul 29 15:10:58
2008 +0100
+++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.h Tue Jul 29 16:03:58
2008 +0100
@@ -1,6 +1,5 @@
#ifndef TCGBIOS_H
#define TCGBIOS_H
-
/* TCPA ACPI definitions */
#define TCPA_ACPI_CLASS_CLIENT 0
@@ -117,14 +116,7 @@
/* 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 */
@@ -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 {
diff -r a538185695ed -r 979e098dfb92 tools/firmware/rombios/32bit/util.c
--- a/tools/firmware/rombios/32bit/util.c Tue Jul 29 15:10:58 2008 +0100
+++ b/tools/firmware/rombios/32bit/util.c Tue Jul 29 16:03:58 2008 +0100
@@ -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 *c
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;
+}
diff -r a538185695ed -r 979e098dfb92 tools/firmware/rombios/32bit/util.h
--- a/tools/firmware/rombios/32bit/util.h Tue Jul 29 15:10:58 2008 +0100
+++ b/tools/firmware/rombios/32bit/util.h Tue Jul 29 16:03:58 2008 +0100
@@ -1,5 +1,7 @@
#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);
@@ -39,5 +41,6 @@ static inline uint32_t mmio_readl(uint32
return *(volatile uint32_t *)addr;
}
+struct acpi_20_rsdp *find_rsdp(void);
#endif
diff -r a538185695ed -r 979e098dfb92 tools/firmware/rombios/32bitgateway.c
--- a/tools/firmware/rombios/32bitgateway.c Tue Jul 29 15:10:58 2008 +0100
+++ b/tools/firmware/rombios/32bitgateway.c Tue Jul 29 16:03:58 2008 +0100
@@ -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
@@ -381,6 +384,8 @@ Upcall:
push bp
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
+}
diff -r a538185695ed -r 979e098dfb92 tools/firmware/rombios/32bitprotos.h
--- a/tools/firmware/rombios/32bitprotos.h Tue Jul 29 15:10:58 2008 +0100
+++ b/tools/firmware/rombios/32bitprotos.h Tue Jul 29 16:03:58 2008 +0100
@@ -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_measure_post( PARMS(Bit32u fro
void tcpa_measure_post( PARMS(Bit32u from, Bit32u to) );
Bit32u tcpa_initialize_tpm( PARMS(Bit32u physpres) );
+Bit32u get_s3_waking_vector( PARMS(void) );
+
#endif
diff -r a538185695ed -r 979e098dfb92 tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c Tue Jul 29 15:10:58 2008 +0100
+++ b/tools/firmware/rombios/rombios.c Tue Jul 29 16:03:58 2008 +0100
@@ -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
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|