
This provides information about a v2 TPM in the system. Generate this table if the TPM is present.
Signed-off-by: Simon Glass sjg@chromium.org ---
arch/x86/lib/acpi_table.c | 74 +++++++++++++++++++++++++++++++++++++++ include/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 e757dc419a..1d12e58508 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -10,6 +10,7 @@ #include <acpigen.h> #include <acpi_device.h> #include <acpi_table.h> +#include <bloblist.h> #include <cpu.h> #include <dm.h> #include <dm/uclass-internal.h> @@ -276,6 +277,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 current; @@ -768,6 +827,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_table.h b/include/acpi_table.h index 17f2a90af9..3d51942d32 100644 --- a/include/acpi_table.h +++ b/include/acpi_table.h @@ -104,6 +104,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 7c5b93be4c..d8dccf91fc 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -33,6 +33,7 @@ enum bloblist_tag_t { * Sleeping table. This forms part of the ACPI tables passed to Linux. */ BLOBLISTT_ACPI_GNVS, + BLOBLISTT_TPM2_TCG_LOG, /* TPM v2 log space */ };
/**