[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [HVMLOADER][VTPM] Add support for a TCG ACPI table.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID d19b8542865b61ae884f49340ca5dbaddadc2973 # Parent ca9b569ffb634604e6da477ab0b7a26004fe26bf [HVMLOADER][VTPM] Add support for a TCG ACPI table. The ACPI table is generated if the probing for the TIS interface succeeds. I cleaned up the ACPI signatures in acpi2_0.h to be more readable. The specification for the layout of these ACPI tables can be found here: https://www.trustedcomputinggroup.org/groups/server/TCG_ACPIGeneralSpecification_1-00_1-00_FINAL.pdf Extensions to the Bochs BIOS that use these ACPI extensions will follow. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx> --- tools/firmware/hvmloader/acpi/acpi2_0.h | 34 +++- tools/firmware/hvmloader/acpi_utils.c | 219 +++++++++++++++++++++----------- tools/firmware/hvmloader/util.c | 51 +++++++ tools/firmware/hvmloader/util.h | 4 4 files changed, 230 insertions(+), 78 deletions(-) diff -r ca9b569ffb63 -r d19b8542865b tools/firmware/hvmloader/acpi/acpi2_0.h --- a/tools/firmware/hvmloader/acpi/acpi2_0.h Fri Nov 17 10:05:12 2006 +0000 +++ b/tools/firmware/hvmloader/acpi/acpi2_0.h Fri Nov 17 10:24:22 2006 +0000 @@ -34,6 +34,11 @@ typedef signed long int64_t; #include <xen/xen.h> +#define ASCII32(a,b,c,d) \ + (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24)) +#define ASCII64(a,b,c,d,e,f,g,h) \ + (((uint64_t)ASCII32(a,b,c,d)) | (((uint64_t)ASCII32(e,f,g,h)) << 32)) + #pragma pack (1) /* @@ -52,7 +57,7 @@ struct acpi_header { }; #define ACPI_OEM_ID {'I','N','T','E','L',' '} -#define ACPI_OEM_TABLE_ID 0x544244 /* "TBD" */ +#define ACPI_OEM_TABLE_ID ASCII32(' ','T','B','D') #define ACPI_OEM_REVISION 0x00000002 #define ACPI_CREATOR_ID 0x00 /* TBD */ #define ACPI_CREATOR_REVISION 0x00000002 @@ -126,6 +131,20 @@ struct acpi_20_xsdt { uint64_t entry[ACPI_MAX_NUM_TABLES]; }; #define ACPI_2_0_XSDT_REVISION 0x01 + +/* + * TCG Hardware Interface Table (TCPA) + */ + +typedef struct _ACPI_2_0_TCPA_CLIENT { + struct acpi_header header; + uint16_t PlatformClass; + uint32_t LAML; + uint64_t LASA; +} ACPI_2_0_TCPA_CLIENT; + +#define ACPI_2_0_TCPA_REVISION 0x02 +#define ACPI_2_0_TCPA_LAML_SIZE (64*1024) /* * Fixed ACPI Description Table Structure (FADT). @@ -297,12 +316,13 @@ struct acpi_20_madt { /* * Table Signatures. */ -#define ACPI_2_0_RSDP_SIGNATURE 0x2052545020445352LL /* "RSD PTR " */ -#define ACPI_2_0_FACS_SIGNATURE 0x53434146 /* "FACS" */ -#define ACPI_2_0_FADT_SIGNATURE 0x50434146 /* "FADT" */ -#define ACPI_2_0_MADT_SIGNATURE 0x43495041 /* "APIC" */ -#define ACPI_2_0_RSDT_SIGNATURE 0x54445352 /* "RSDT" */ -#define ACPI_2_0_XSDT_SIGNATURE 0x54445358 /* "XSDT" */ +#define ACPI_2_0_RSDP_SIGNATURE ASCII64('R','S','D',' ','P','T','R',' ') +#define ACPI_2_0_FACS_SIGNATURE ASCII32('F','A','C','S') +#define ACPI_2_0_FADT_SIGNATURE ASCII32('F','A','C','P') +#define ACPI_2_0_MADT_SIGNATURE ASCII32('A','P','I','C') +#define ACPI_2_0_RSDT_SIGNATURE ASCII32('R','S','D','T') +#define ACPI_2_0_XSDT_SIGNATURE ASCII32('X','S','D','T') +#define ACPI_2_0_TCPA_SIGNATURE ASCII32('T','C','P','A') #pragma pack () diff -r ca9b569ffb63 -r d19b8542865b tools/firmware/hvmloader/acpi_utils.c --- a/tools/firmware/hvmloader/acpi_utils.c Fri Nov 17 10:05:12 2006 +0000 +++ b/tools/firmware/hvmloader/acpi_utils.c Fri Nov 17 10:24:22 2006 +0000 @@ -23,8 +23,11 @@ #include "acpi/acpi2_0.h" #include "acpi_utils.h" #include "util.h" +#include <xen/hvm/e820.h> static int acpi_rsdt_add_entry_pointer(unsigned char *acpi_start, + unsigned char *entry); +static int acpi_xsdt_add_entry_pointer(unsigned char *acpi_start, unsigned char *entry); static unsigned char *acpi_xsdt_add_entry(unsigned char *acpi_start, unsigned char **freemem, @@ -34,45 +37,78 @@ static unsigned char *acpi_xsdt_add_entr void set_checksum(void *start, int checksum_offset, int len) { - unsigned char sum = 0; - unsigned char *ptr; - - ptr = start; - ptr[checksum_offset] = 0; - while (len--) - sum += *ptr++; - - ptr = start; - ptr[checksum_offset] = -sum; + unsigned char sum = 0; + unsigned char *ptr; + + ptr = start; + ptr[checksum_offset] = 0; + while ( len-- ) + sum += *ptr++; + + ptr = start; + ptr[checksum_offset] = -sum; } #include "acpi_ssdt_tpm.h" -static int acpi_tpm_tis_probe(unsigned char *acpi_start, - unsigned char **freemem, - unsigned char *limit) -{ - int success = 1; /* not successful means 'out of memory' */ - unsigned char *addr; - /* check TPM_DID, TPM_VID, TPM_RID in ioemu/hw/tpm_tis.c */ - uint16_t tis_did_vid_rid[] = {0x0001, 0x0001, 0x0001}; - - /* probe for TIS interface ... */ - if (memcmp((char *)(0xFED40000 + 0xF00), - tis_did_vid_rid, - sizeof(tis_did_vid_rid)) == 0) { - puts("TIS is available\n"); - addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, - AmlCode_TPM, sizeof(AmlCode_TPM)); - if (addr == NULL) - success = 0; - else { - /* legacy systems need an RSDT entry */ - acpi_rsdt_add_entry_pointer(acpi_start, - addr); - } - } - return success; +static void acpi_tpm_tis_probe(unsigned char *acpi_start, + unsigned char **freemem, + unsigned char *limit) +{ + unsigned char *addr; + ACPI_2_0_TCPA_CLIENT *tcpa; + /* check TPM_DID, TPM_VID, TPM_RID in ioemu/hw/tpm_tis.c */ + uint16_t tis_did_vid_rid[] = {0x0001, 0x0001, 0x0001}; + static const ACPI_2_0_TCPA_CLIENT Tcpa = { + .header = { + .signature = ACPI_2_0_TCPA_SIGNATURE, + .length = sizeof(ACPI_2_0_TCPA_CLIENT), + .revision = ACPI_2_0_TCPA_REVISION, + .oem_id = {'I', 'B', 'M', ' ', ' ', ' '}, + .oem_table_id = ASCII64(' ', ' ', ' ', ' ', ' ', 'x', 'e', 'n'), + .oem_revision = 1, + .creator_id = ASCII32('I', 'B', 'M', ' '), + .creator_revision = 1, + } + }; + + /* probe for TIS interface ... */ + if ( memcmp((char *)(0xFED40000 + 0xF00), + tis_did_vid_rid, + sizeof(tis_did_vid_rid)) != 0 ) + return; + + puts("TIS is available\n"); + addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, + AmlCode_TPM, sizeof(AmlCode_TPM)); + if ( addr == NULL ) + return; + + /* legacy systems need an RSDT entry */ + acpi_rsdt_add_entry_pointer(acpi_start, addr); + + /* add ACPI TCPA table */ + addr = acpi_xsdt_add_entry(acpi_start, freemem, limit, + (unsigned char *)&Tcpa, + sizeof(Tcpa)); + if ( addr == NULL ) + return; + + tcpa = (ACPI_2_0_TCPA_CLIENT *)addr; + tcpa->LASA = e820_malloc( + ACPI_2_0_TCPA_LAML_SIZE, E820_RESERVED, (uint32_t)~0); + if ( tcpa->LASA ) + { + tcpa->LAML = ACPI_2_0_TCPA_LAML_SIZE; + memset((char *)(unsigned long)tcpa->LASA, + 0x0, + tcpa->LAML); + set_checksum(tcpa, + FIELD_OFFSET(struct acpi_header, checksum), + tcpa->header.length); + } + + acpi_rsdt_add_entry_pointer(acpi_start, addr); } @@ -95,17 +131,20 @@ struct acpi_20_rsdt *acpi_rsdt_get(unsig struct acpi_20_rsdt *rsdt; rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); - if (rsdp->signature != ACPI_2_0_RSDP_SIGNATURE) { + if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) + { puts("Bad RSDP signature\n"); return NULL; } rsdt = (struct acpi_20_rsdt *) (acpi_start + rsdp->rsdt_address - ACPI_PHYSICAL_ADDRESS); - if (rsdt->header.signature != ACPI_2_0_RSDT_SIGNATURE) { + if ( rsdt->header.signature != ACPI_2_0_RSDT_SIGNATURE ) + { puts("Bad RSDT signature\n"); return NULL; } + return rsdt; } @@ -119,17 +158,20 @@ static int acpi_rsdt_add_entry_pointer(u int found = 0; int i = 0; - /* get empty slot in the RSDT table */ - while (i < ACPI_MAX_NUM_TABLES) { - if (rsdt->entry[i] == 0) { - found = 1; - break; - } - i++; - } - - if (found) { - rsdt->entry[i] = (uint64_t)(long)entry; + /* Find an empty slot in the RSDT table. */ + while ( i < ACPI_MAX_NUM_TABLES ) + { + if ( rsdt->entry[i] == 0 ) + { + found = 1; + break; + } + i++; + } + + if ( found ) + { + rsdt->entry[i] = (uint64_t)(unsigned long)entry; rsdt->header.length = sizeof(struct acpi_header) + (i + 1) * sizeof(uint64_t); @@ -141,25 +183,62 @@ static int acpi_rsdt_add_entry_pointer(u return found; } -/* Get the XSDT table */ +/* Get the XSDT table. */ struct acpi_20_xsdt *acpi_xsdt_get(unsigned char *acpi_start) { struct acpi_20_rsdp *rsdp; struct acpi_20_xsdt *xsdt; rsdp = (struct acpi_20_rsdp *)(acpi_start + sizeof(struct acpi_20_facs)); - if (rsdp->signature != ACPI_2_0_RSDP_SIGNATURE) { + if ( rsdp->signature != ACPI_2_0_RSDP_SIGNATURE ) + { puts("Bad RSDP signature\n"); return NULL; } xsdt = (struct acpi_20_xsdt *) (acpi_start + rsdp->xsdt_address - ACPI_PHYSICAL_ADDRESS); - if (xsdt->header.signature != ACPI_2_0_XSDT_SIGNATURE) { + if ( xsdt->header.signature != ACPI_2_0_XSDT_SIGNATURE ) + { puts("Bad XSDT signature\n"); return NULL; } return xsdt; +} + +/* + * Add an entry to the XSDT table given the pointer to the entry. + */ +static int acpi_xsdt_add_entry_pointer(unsigned char *acpi_start, + unsigned char *entry) +{ + struct acpi_20_xsdt *xsdt = acpi_xsdt_get(acpi_start); + int found = 0; + int i = 0; + + /* Find an empty slot in the XSDT table. */ + while ( i < ACPI_MAX_NUM_TABLES ) + { + if ( xsdt->entry[i] == 0 ) + { + found = 1; + break; + } + i++; + } + + if ( found ) + { + xsdt->entry[i] = (uint64_t)(unsigned long)entry; + xsdt->header.length = + sizeof(struct acpi_header) + + (i + 1) * sizeof(uint64_t); + set_checksum(xsdt, + FIELD_OFFSET(struct acpi_header, checksum), + xsdt->header.length); + } + + return found; } /* @@ -177,31 +256,29 @@ static unsigned char *acpi_xsdt_add_entr int found = 0, i = 0; unsigned char *addr = NULL; - /* get empty slot in the Xsdt table */ - while (i < ACPI_MAX_NUM_TABLES) { - if (xsdt->entry[i] == 0) { - found = 1; - break; - } - i++; - } - - if (found) { + /* Check for an empty slot in the Xsdt table. */ + while ( i < ACPI_MAX_NUM_TABLES ) + { + if ( xsdt->entry[i] == 0 ) + { + found = 1; + break; + } + i++; + } + + if ( found ) + { /* memory below hard limit ? */ if (*freemem + table_size <= limit) { puts("Copying SSDT entry!\n"); addr = *freemem; memcpy(addr, table, table_size); - xsdt->entry[i] = (uint64_t)(long)addr; *freemem += table_size; - /* update the XSDT table */ - xsdt->header.length = - sizeof(struct acpi_header) + - (i + 1) * sizeof(uint64_t); - set_checksum(xsdt, - FIELD_OFFSET(struct acpi_header, checksum), - xsdt->header.length); - } - } + + acpi_xsdt_add_entry_pointer(acpi_start, addr); + } + } + return addr; } diff -r ca9b569ffb63 -r d19b8542865b tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Fri Nov 17 10:05:12 2006 +0000 +++ b/tools/firmware/hvmloader/util.c Fri Nov 17 10:24:22 2006 +0000 @@ -90,6 +90,23 @@ void *memcpy(void *dest, const void *src return dest; } +void *memmove(void *dest, const void *src, unsigned n) +{ + if ((long)dest > (long)src) { + n--; + while (n > 0) { + ((char *)dest)[n] = ((char *)src)[n]; + n--; + } + } else { + memcpy(dest, src, n); + } + return dest; +} + + + + void puts(const char *s) { while (*s) @@ -229,3 +246,37 @@ uuid_to_string(char *dest, uint8_t *uuid } *p = 0; } + +#include <xen/hvm/e820.h> +#define E820_MAP_NR ((unsigned char *)E820_MAP_PAGE + E820_MAP_NR_OFFSET) +#define E820_MAP ((struct e820entry *)(E820_MAP_PAGE + E820_MAP_OFFSET)) +uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask) +{ + uint64_t addr = 0; + int c = *E820_MAP_NR - 1; + struct e820entry *e820entry = (struct e820entry *)E820_MAP; + + while (c >= 0) { + if (e820entry[c].type == E820_RAM && + (e820entry[c].addr & (~mask)) == 0 && + e820entry[c].size >= size) { + addr = e820entry[c].addr; + if (e820entry[c].size != size) { + (*E820_MAP_NR)++; + memmove(&e820entry[c+1], + &e820entry[c], + (*E820_MAP_NR - c) * + sizeof(struct e820entry)); + e820entry[c].size -= size; + addr += e820entry[c].size; + c++; + } + e820entry[c].addr = addr; + e820entry[c].size = size; + e820entry[c].type = type; + break; + } + c--; + } + return addr; +} diff -r ca9b569ffb63 -r d19b8542865b tools/firmware/hvmloader/util.h --- a/tools/firmware/hvmloader/util.h Fri Nov 17 10:05:12 2006 +0000 +++ b/tools/firmware/hvmloader/util.h Fri Nov 17 10:24:22 2006 +0000 @@ -22,6 +22,7 @@ unsigned strlen(const char *s); unsigned strlen(const char *s); int memcmp(const void *s1, const void *s2, unsigned n); void *memcpy(void *dest, const void *src, unsigned n); +void *memmove(void *dest, const void *src, unsigned n); void *memset(void *s, int c, unsigned n); char *itoa(char *a, unsigned int i); @@ -38,4 +39,7 @@ void uuid_to_string(char *dest, uint8_t /* Debug output */ void puts(const char *s); +/* Allocate region of specified type in the e820 table. */ +uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask); + #endif /* __HVMLOADER_UTIL_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |