From patchwork Mon Jan 27 05:06:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 240258 List-Id: U-Boot discussion From: sjg at chromium.org (Simon Glass) Date: Sun, 26 Jan 2020 22:06:53 -0700 Subject: [PATCH 106/108] acpi: tpm: Add a TPM2 table In-Reply-To: <20200127050655.170614-1-sjg@chromium.org> References: <20200127050655.170614-1-sjg@chromium.org> Message-ID: <20200126220508.106.I01fe3266661295f6b3a4f1aebefb75d3838bdb32@changeid> 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_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 #include #include +#include #include #include #include @@ -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 */ }; /**