Add TCG ACPI spec table (TCPA) support.

Submitted by:	Hans-Joerg_Hoexer@genua.de
This commit is contained in:
takawata 2010-08-11 23:21:25 +00:00
parent 0737955344
commit c320859512
2 changed files with 274 additions and 0 deletions

View File

@ -68,6 +68,7 @@ static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
static void acpi_print_facs(ACPI_TABLE_FACS *facs);
@ -81,6 +82,46 @@ static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
/* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
static int addr_size;
/* Strings used in the TCPA table */
static const char *tcpa_event_type_strings[] = {
"PREBOOT Certificate",
"POST Code",
"Unused",
"No Action",
"Separator",
"Action",
"Event Tag",
"S-CRTM Contents",
"S-CRTM Version",
"CPU Microcode",
"Platform Config Flags",
"Table of Devices",
"Compact Hash",
"IPL",
"IPL Partition Data",
"Non-Host Code",
"Non-Host Config",
"Non-Host Info"
};
static const char *TCPA_pcclient_strings[] = {
"<undefined>",
"SMBIOS",
"BIS Certificate",
"POST BIOS ROM Strings",
"ESCD",
"CMOS",
"NVRAM",
"Option ROM Execute",
"Option ROM Configurateion",
"<undefined>",
"Option ROM Microcode Update ",
"S-CRTM Version String",
"S-CRTM Contents",
"POST Contents",
"Table of Devices",
};
static void
acpi_print_string(char *s, size_t length)
{
@ -492,6 +533,165 @@ acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
printf("\tProximity Domain=%d\n", proximity_domain);
}
static char *
acpi_tcpa_evname(struct TCPAevent *event)
{
struct TCPApc_event *pc_event;
char *eventname = NULL;
pc_event = (struct TCPApc_event *)(event + 1);
switch(event->event_type) {
case PREBOOT:
case POST_CODE:
case UNUSED:
case NO_ACTION:
case SEPARATOR:
case SCRTM_CONTENTS:
case SCRTM_VERSION:
case CPU_MICROCODE:
case PLATFORM_CONFIG_FLAGS:
case TABLE_OF_DEVICES:
case COMPACT_HASH:
case IPL:
case IPL_PARTITION_DATA:
case NONHOST_CODE:
case NONHOST_CONFIG:
case NONHOST_INFO:
asprintf(&eventname, "%s",
tcpa_event_type_strings[event->event_type]);
break;
case ACTION:
eventname = calloc(event->event_size + 1, sizeof(char));
memcpy(eventname, pc_event, event->event_size);
break;
case EVENT_TAG:
switch (pc_event->event_id) {
case SMBIOS:
case BIS_CERT:
case CMOS:
case NVRAM:
case OPTION_ROM_EXEC:
case OPTION_ROM_CONFIG:
case S_CRTM_VERSION:
case POST_BIOS_ROM:
case ESCD:
case OPTION_ROM_MICROCODE:
case S_CRTM_CONTENTS:
case POST_CONTENTS:
asprintf(&eventname, "%s",
TCPA_pcclient_strings[pc_event->event_id]);
break;
default:
asprintf(&eventname, "<unknown tag 0x%02x>",
pc_event->event_id);
break;
}
break;
default:
asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
break;
}
return eventname;
}
static void
acpi_print_tcpa(struct TCPAevent *event)
{
int i;
char *eventname;
eventname = acpi_tcpa_evname(event);
printf("\t%d", event->pcr_index);
printf(" 0x");
for (i = 0; i < 20; i++)
printf("%02x", event->pcr_value[i]);
printf(" [%s]\n", eventname ? eventname : "<unknown>");
free(eventname);
}
static void
acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
{
struct TCPAbody *tcpa;
struct TCPAevent *event;
u_int64_t len, paddr;
unsigned char *vaddr = NULL;
unsigned char *vend = NULL;
printf(BEGIN_COMMENT);
acpi_print_sdt(sdp);
tcpa = (struct TCPAbody *) sdp;
switch (tcpa->platform_class) {
case ACPI_TCPA_BIOS_CLIENT:
len = tcpa->client.log_max_len;
paddr = tcpa->client.log_start_addr;
break;
case ACPI_TCPA_BIOS_SERVER:
len = tcpa->server.log_max_len;
paddr = tcpa->server.log_start_addr;
break;
default:
printf("XXX");
printf(END_COMMENT);
return;
}
printf("\tClass %d Base Address 0x%jx Length %lld\n\n",
tcpa->platform_class, paddr, len);
if (len == 0) {
printf("\tEmpty TCPA table\n");
printf(END_COMMENT);
return;
}
vaddr = (unsigned char *)acpi_map_physical(paddr, len);
vend = vaddr + len;
while (vaddr != NULL) {
if (vaddr + sizeof(struct TCPAevent) >= vend)
break;
event = (struct TCPAevent *)vaddr;
if (vaddr + event->event_size >= vend)
break;
if (event->event_type == 0 && event->event_size == 0)
break;
#if 0
{
unsigned int i, j, k;
printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
for (j = 0, i = 0; i <
sizeof(struct TCPAevent) + event->event_size; i++) {
printf("%02x ", vaddr[i]);
if ((i+1) % 8 == 0) {
for (k = 0; k < 8; k++)
printf("%c", isprint(vaddr[j+k]) ?
vaddr[j+k] : '.');
printf("\n\t\t%p ", &vaddr[i + 1]);
j = i + 1;
}
}
printf("\n"); }
#endif
acpi_print_tcpa(event);
vaddr += sizeof(struct TCPAevent) + event->event_size;
}
printf(END_COMMENT);
}
static void
acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
{
@ -886,6 +1086,8 @@ acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
acpi_handle_mcfg(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
acpi_handle_srat(sdp);
else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
acpi_handle_tcpa(sdp);
else {
printf(BEGIN_COMMENT);
acpi_print_sdt(sdp);

View File

@ -55,6 +55,78 @@
/* Find and map the RSD PTR structure and return it for parsing */
ACPI_TABLE_HEADER *sdt_load_devmem(void);
/* TCPA */
struct TCPAbody {
ACPI_TABLE_HEADER header;
uint16_t platform_class;
#define ACPI_TCPA_BIOS_CLIENT 0x00
#define ACPI_TCPA_BIOS_SERVER 0x01
union {
struct client_hdr {
uint32_t log_max_len __packed;
uint64_t log_start_addr __packed;
} client;
struct server_hdr {
uint16_t reserved;
uint64_t log_max_len __packed;
uint64_t log_start_addr __packed;
} server;
};
} __packed;
struct TCPAevent {
u_int32_t pcr_index;
u_int32_t event_type;
u_int8_t pcr_value[20];
u_int32_t event_size;
u_int8_t event_data[0];
};
struct TCPApc_event {
u_int32_t event_id;
u_int32_t event_size;
u_int8_t event_data[0];
};
enum TCPAevent_types {
PREBOOT = 0,
POST_CODE,
UNUSED,
NO_ACTION,
SEPARATOR,
ACTION,
EVENT_TAG,
SCRTM_CONTENTS,
SCRTM_VERSION,
CPU_MICROCODE,
PLATFORM_CONFIG_FLAGS,
TABLE_OF_DEVICES,
COMPACT_HASH,
IPL,
IPL_PARTITION_DATA,
NONHOST_CODE,
NONHOST_CONFIG,
NONHOST_INFO,
EVENT_TYPE_MAX,
};
enum TCPApcclient_ids {
SMBIOS = 1,
BIS_CERT,
POST_BIOS_ROM,
ESCD,
CMOS,
NVRAM,
OPTION_ROM_EXEC,
OPTION_ROM_CONFIG,
OPTION_ROM_MICROCODE = 10,
S_CRTM_VERSION,
S_CRTM_CONTENTS,
POST_CONTENTS,
HOST_TABLE_OF_DEVICES,
PCCLIENT_ID_MAX,
};
/*
* Load the DSDT from a previous save file. Note that other tables are
* not saved (i.e. FADT)