summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortakawata <takawata@FreeBSD.org>2010-08-11 23:21:25 +0000
committertakawata <takawata@FreeBSD.org>2010-08-11 23:21:25 +0000
commitc320859512bcf34cce7e9d6a7d7ce616b7c6a950 (patch)
treedbce9183e95fb639cdbe351b54591d81675bec1f
parent0737955344e4f99aa4ecd858ef6e507e591db2a7 (diff)
downloadFreeBSD-src-c320859512bcf34cce7e9d6a7d7ce616b7c6a950.zip
FreeBSD-src-c320859512bcf34cce7e9d6a7d7ce616b7c6a950.tar.gz
Add TCG ACPI spec table (TCPA) support.
Submitted by: Hans-Joerg_Hoexer@genua.de
-rw-r--r--usr.sbin/acpi/acpidump/acpi.c202
-rw-r--r--usr.sbin/acpi/acpidump/acpidump.h72
2 files changed, 274 insertions, 0 deletions
diff --git a/usr.sbin/acpi/acpidump/acpi.c b/usr.sbin/acpi/acpidump/acpi.c
index 8a89f10..72cbdd6 100644
--- a/usr.sbin/acpi/acpidump/acpi.c
+++ b/usr.sbin/acpi/acpidump/acpi.c
@@ -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);
diff --git a/usr.sbin/acpi/acpidump/acpidump.h b/usr.sbin/acpi/acpidump/acpidump.h
index c75cabd..3421519 100644
--- a/usr.sbin/acpi/acpidump/acpidump.h
+++ b/usr.sbin/acpi/acpidump/acpidump.h
@@ -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)
OpenPOWER on IntegriCloud