From 9179c3571ce587e96b957d0da8f0e4dcabc8d293 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 22 Sep 2020 12:45:32 -0600 Subject: [PATCH] acpi: tpm: Add a TPM2 table This provides information about a v2 TPM in the system. Generate this table if the TPM is present. Signed-off-by: Simon Glass --- arch/x86/lib/acpi_table.c | 74 +++++++++++++++++++++++++++++++++++++++ include/acpi/acpi_table.h | 11 ++++++ include/bloblist.h | 1 + 3 files changed, 86 insertions(+) diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 5876355afe..c31cc923c9 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -214,6 +215,64 @@ static void acpi_create_mcfg(struct acpi_mcfg *mcfg) header->checksum = table_compute_checksum((void *)mcfg, header->length); } +static int get_tpm2_log(void **ptrp, int *sizep) +{ + const int tpm2_default_log_len = 0x10000; + int size; + int ret; + + *sizep = 0; + size = tpm2_default_log_len; + ret = bloblist_ensure_size_ret(BLOBLISTT_TPM2_TCG_LOG, &size, ptrp); + if (ret) + return log_msg_ret("blob", ret); + *sizep = size; + + return 0; +} + +static int acpi_create_tpm2(struct acpi_tpm2 *tpm2) +{ + struct acpi_table_header *header = &tpm2->header; + int tpm2_log_len; + void *lasa; + int ret; + + memset((void *)tpm2, 0, sizeof(struct acpi_tpm2)); + + /* + * Some payloads like SeaBIOS depend on log area to use TPM2. + * Get the memory size and address of TPM2 log area or initialize it. + */ + ret = get_tpm2_log(&lasa, &tpm2_log_len); + if (ret) + return ret; + + /* Fill out header fields. */ + acpi_fill_header(header, "TPM2"); + memcpy(header->aslc_id, ASLC_ID, 4); + + header->length = sizeof(struct acpi_tpm2); + header->revision = acpi_get_table_revision(ACPITAB_TPM2); + + /* Hard to detect for coreboot. Just set it to 0 */ + tpm2->platform_class = 0; + + /* Must be set to 0 for FIFO-interface support */ + tpm2->control_area = 0; + tpm2->start_method = 6; + memset(tpm2->msp, 0, sizeof(tpm2->msp)); + + /* Fill the log area size and start address fields. */ + tpm2->laml = tpm2_log_len; + tpm2->lasa = (uintptr_t)lasa; + + /* Calculate checksum. */ + header->checksum = table_compute_checksum((void *)tpm2, header->length); + + return 0; +} + __weak u32 acpi_fill_csrt(u32 current) { return 0; @@ -499,6 +558,21 @@ ulong write_acpi_tables(ulong start_addr) acpi_inc_align(ctx, mcfg->header.length); acpi_add_table(ctx, mcfg); + if (IS_ENABLED(CONFIG_TPM_V2)) { + struct acpi_tpm2 *tpm2; + int ret; + + debug("ACPI: * TPM2\n"); + tpm2 = (struct acpi_tpm2 *)ctx->current; + ret = acpi_create_tpm2(tpm2); + if (!ret) { + acpi_inc_align(ctx, tpm2->header.length); + acpi_add_table(ctx, tpm2); + } else { + log_warning("TPM2 table creation failed\n"); + } + } + debug("ACPI: * MADT\n"); madt = ctx->current; acpi_create_madt(madt); diff --git a/include/acpi/acpi_table.h b/include/acpi/acpi_table.h index a2e510cf56..c7ee8b55da 100644 --- a/include/acpi/acpi_table.h +++ b/include/acpi/acpi_table.h @@ -93,6 +93,17 @@ struct __packed acpi_hpet { u8 attributes; }; +struct __packed acpi_tpm2 { + struct acpi_table_header header; + u16 platform_class; + u8 reserved[2]; + u64 control_area; + u32 start_method; + u8 msp[12]; + u32 laml; + u64 lasa; +}; + /* FADT Preferred Power Management Profile */ enum acpi_pm_profile { ACPI_PM_UNSPECIFIED = 0, diff --git a/include/bloblist.h b/include/bloblist.h index 7d8480548e..dc7d80bd85 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -33,6 +33,7 @@ enum bloblist_tag_t { */ BLOBLISTT_ACPI_GNVS, BLOBLISTT_INTEL_VBT, /* Intel Video-BIOS table */ + BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */ }; /** -- 2.39.5