From: Keir Fraser Date: Tue, 29 Jul 2008 15:03:58 +0000 (+0100) Subject: rombios: Obtain S3 wake vector from >1MB. X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~14165^2~89 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=b5ee8eb3d6e30a13a2b983daf892bcbfa4991a0d;p=xen.git rombios: Obtain S3 wake vector from >1MB. Signed-off-by: Keir Fraser --- diff --git a/tools/firmware/rombios/32bit/32bitbios.c b/tools/firmware/rombios/32bit/32bitbios.c index 14dba9bf33..551a9ffdc0 100644 --- a/tools/firmware/rombios/32bit/32bitbios.c +++ b/tools/firmware/rombios/32bit/32bitbios.c @@ -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 */ }; diff --git a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c index 263607471b..b06af22f00 100644 --- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c +++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c @@ -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_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) { diff --git a/tools/firmware/rombios/32bit/tcgbios/tcgbios.h b/tools/firmware/rombios/32bit/tcgbios/tcgbios.h index bf2b133c52..f16b586b28 100644 --- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.h +++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.h @@ -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 @@ -117,15 +116,8 @@ /* 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 { diff --git a/tools/firmware/rombios/32bit/util.c b/tools/firmware/rombios/32bit/util.c index ad60b9eedb..a47bb71cde 100644 --- a/tools/firmware/rombios/32bit/util.c +++ b/tools/firmware/rombios/32bit/util.c @@ -19,6 +19,7 @@ */ #include #include +#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; +} diff --git a/tools/firmware/rombios/32bit/util.h b/tools/firmware/rombios/32bit/util.h index 6d05b502d5..e245be6569 100644 --- a/tools/firmware/rombios/32bit/util.h +++ b/tools/firmware/rombios/32bit/util.h @@ -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 diff --git a/tools/firmware/rombios/32bitgateway.c b/tools/firmware/rombios/32bitgateway.c index 4da5a39c45..9592dfbca1 100644 --- a/tools/firmware/rombios/32bitgateway.c +++ b/tools/firmware/rombios/32bitgateway.c @@ -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 +} diff --git a/tools/firmware/rombios/32bitprotos.h b/tools/firmware/rombios/32bitprotos.h index 69ec87dc34..f0c401476a 100644 --- a/tools/firmware/rombios/32bitprotos.h +++ b/tools/firmware/rombios/32bitprotos.h @@ -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 diff --git a/tools/firmware/rombios/rombios.c b/tools/firmware/rombios/rombios.c index cb2da617c7..1546c3d644 100644 --- a/tools/firmware/rombios/rombios.c +++ b/tools/firmware/rombios/rombios.c @@ -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