drivers/amd/ftpm: Add fTPM driver for PSP emulated CRB TPMs

The AMD fTPM uses the CRB interface, but doesn't implement all registers
defined in the TCG specification. Add a new driver that deals with the
reduced register set.

The reduced CRB MMIO register space has:
- A START register to ring the doorbell
- An error STATUS register with only one bit
- DMA address and size register for the CRB
- No other status or control registers
- No way to read current locality (assumption is locality 0)
- No interface ID register
- No read only registers

The TPM interface also assumes that the DRTM is always using locality 0.

The fTPM needs to access the SPI flash and this is currently done using
the PSP SMI handler. Thus the fTPM will only operate after SMM has been
set up.

The fTPM needs the PSP directory files type 0x04 and type 0x54. When
the regions are missing or corrupted the fTPM won't be operational.

Based off https://github.com/teslamotors/coreboot/tree/tesla-4.12-amd

TEST=Works on AMD glinda (Fam 1Ah).

This adds the following new log messages:
[DEBUG]  PSP: Querying PSP capabilities...OK
[DEBUG]  PSP: Querying fTPM capabilities... OK
[DEBUG]  PSP: Querying fTPM capabilities... OK
[DEBUG]  TPM: CRB buffer created at 0x7b5ee000
[SPEW ]  fTPM: CRB TPM initialized successfully
[INFO ]  Initialized TPM device fTPM

...

[DEBUG]  PSP: Querying fTPM capabilities... OK
[DEBUG]  TPM2 log created at 0x7b5b1000
[DEBUG]  PSP: Querying fTPM capabilities... OK
[DEBUG]  ACPI:    * TPM2
[DEBUG]  ACPI: added table 4/32, length now 68

Change-Id: I780bdab621228e12b37f3a89868e16bc62a05e7b
Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/88247
Reviewed-by: Maximilian Brune <maximilian.brune@9elements.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
Reviewed-by: Alicja Michalska <ahplka19@gmail.com>
This commit is contained in:
Patrick Rudolph 2025-06-30 13:02:03 +02:00 committed by Felix Held
commit 6fd865f409
11 changed files with 591 additions and 6 deletions

View file

@ -27,7 +27,11 @@
#include <device/device.h>
#include <device/mmio.h>
#include <device/pci.h>
#if CONFIG(AMD_CRB_FTPM)
#include <drivers/amd/ftpm/tpm.h>
#else
#include <drivers/crb/tpm.h>
#endif
#include <drivers/uart/pl011.h>
#include <security/tpm/tss.h>
#include <string.h>
@ -260,7 +264,7 @@ static void acpi_create_tpm2(acpi_header_t *header, void *unused)
if (tlcl_get_family() != TPM_2)
return;
if (CONFIG(CRB_TPM) && !(CONFIG(SPI_TPM) || CONFIG(I2C_TPM) || CONFIG(MEMORY_MAPPED_TPM)))
if ((CONFIG(CRB_TPM) || CONFIG(AMD_CRB_FTPM)) && !(CONFIG(SPI_TPM) || CONFIG(I2C_TPM) || CONFIG(MEMORY_MAPPED_TPM)))
if (!crb_tpm_is_active())
return;
@ -281,7 +285,12 @@ static void acpi_create_tpm2(acpi_header_t *header, void *unused)
/* Hard to detect for coreboot. Just set it to 0 */
tpm2->platform_class = 0;
if (CONFIG(CRB_TPM)) {
if (CONFIG(AMD_CRB_FTPM) && crb_tpm_is_active()) {
/* Must be set to 2 for AMD fTPM Support */
tpm2->control_area = crb_tpm_base_address() + 0x40;
tpm2->start_method = 2;
} else if (CONFIG(CRB_TPM) && crb_tpm_is_active()) {
/* Must be set to 7 for CRB Support */
tpm2->control_area = crb_tpm_base_address() + 0x40;
tpm2->start_method = 7;

View file

@ -67,6 +67,7 @@
#define CBMEM_ID_TIMESTAMP 0x54494d45
#define CBMEM_ID_TPM2_TCG_LOG 0x54504d32 /* TPM log per TPM 2.0 specification */
#define CBMEM_ID_TPM_PPI 0x54505049
#define CBMEM_ID_TPM2_CRB 0x43524220
#define CBMEM_ID_VBOOT_HANDOFF 0x780074f0 /* deprecated */
#define CBMEM_ID_VBOOT_SEL_REG 0x780074f1 /* deprecated */
#define CBMEM_ID_VBOOT_WORKBUF 0x78007343
@ -153,6 +154,7 @@
{ CBMEM_ID_TIMESTAMP, "TIME STAMP " }, \
{ CBMEM_ID_TPM2_TCG_LOG, "TPM2 TCGLOG" }, \
{ CBMEM_ID_TPM_PPI, "TPM PPI " }, \
{ CBMEM_ID_TPM2_CRB, "TPM CRB " }, \
{ CBMEM_ID_VBOOT_HANDOFF, "VBOOT " }, \
{ CBMEM_ID_VBOOT_SEL_REG, "VBOOT SEL " }, \
{ CBMEM_ID_VBOOT_WORKBUF, "VBOOT WORK " }, \

View file

@ -0,0 +1,14 @@
## SPDX-License-Identifier: GPL-2.0-only
config AMD_CRB_FTPM
bool
default n
depends on !CRB_TPM
depends on SOC_AMD_COMMON_BLOCK_PSP_GEN2
# The fTPM needs to access the SPI flash when ROM Armor
# is not being used, thus select SOC_AMD_COMMON_BLOCK_PSP_SMI.
select SOC_AMD_COMMON_BLOCK_PSP_SMI
help
Mainboard has AMD fTPM with Command Response Buffer support.
The fTPM is based on the CRB interface as defined by TCG,
but with reduced set of registers being implemented.

View file

@ -0,0 +1,7 @@
## SPDX-License-Identifier: GPL-2.0-only
ifeq ($(CONFIG_AMD_CRB_FTPM),y)
# Currently depends on SOC_AMD_COMMON_BLOCK_PSP_SMI, that means
# fTPM is only accepting commands after SMM has been set up.
ramstage-y += tis.c tpm.c
endif

View file

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef DRIVERS_AMD_FTPM_CHIP_H
#define DRIVERS_AMD_FTPM_CHIP_H
struct drivers_amd_ftpm_config {
};
#endif /* DRIVERS_AMD_FTPM_CHIP_H */

206
src/drivers/amd/ftpm/tis.c Normal file
View file

@ -0,0 +1,206 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/mmio.h>
#include <console/console.h>
#include <security/tpm/tis.h>
#include <acpi/acpigen.h>
#include <device/device.h>
#include <security/tpm/tss.h>
#include <endian.h>
#include <smbios.h>
#include <string.h>
#include "tpm.h"
#include "chip.h"
static const char *tis_get_dev_name(void)
{
return "fTPM";
}
static tpm_result_t crb_tpm_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf,
size_t *rbuf_len)
{
int len = crb_tpm_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len);
if (len <= 0)
return TPM_CB_FAIL;
*rbuf_len = len;
return TPM_SUCCESS;
}
tis_sendrecv_fn crb_tis_probe(enum tpm_family *family)
{
/* Wake TPM up (if necessary) */
if (crb_tpm_init())
return NULL;
/* CRB interface exists only in TPM2 */
if (family != NULL)
*family = TPM_2;
printk(BIOS_INFO, "Initialized TPM device %s\n", tis_get_dev_name());
return &crb_tpm_sendrecv;
}
static void tpm_start_func0_cb(void *arg)
{
/* Function 1. */
acpigen_write_return_singleton_buffer(0x3);
}
static void tpm_start_func1_cb(void *arg)
{
/* Just return success. fTPM is already operational. */
acpigen_write_return_byte(0);
}
static void (*tpm_start_callbacks[])(void *) = {
tpm_start_func0_cb,
tpm_start_func1_cb,
};
#define TPM_START_UUID "6bbf6cab-5463-4714-b7cd-f0203c0368d4"
static void crb_tpm_fill_ssdt(const struct device *dev)
{
assert(dev->path.type == DEVICE_PATH_MMIO);
assert(dev->path.mmio.addr == crb_tpm_base_address());
/* Device */
acpigen_write_scope("\\_SB");
acpigen_write_device(acpi_device_name(dev));
acpigen_write_name_string("_HID", "MSFT0101");
acpigen_write_name_string("_CID", "MSFT0101");
acpi_device_write_uid(dev);
if (crb_tpm_is_active())
acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON);
else
acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_OFF);
/* Resources */
acpigen_write_name("_CRS");
acpigen_write_resourcetemplate_header();
acpigen_write_mem32fixed(1, read32(CRB_REG(CRB_REG_CMD_ADDR)),
read32(CRB_REG(CRB_REG_CMD_SIZE)));
acpigen_write_mem32fixed(1, read32(CRB_REG(CRB_REG_RESP_ADDR)),
read32(CRB_REG(CRB_REG_RESP_SIZE)));
acpigen_write_resourcetemplate_footer();
/*
* _DSM method
*/
struct dsm_uuid ids[] = {
DSM_UUID(TPM_START_UUID, tpm_start_callbacks,
ARRAY_SIZE(tpm_start_callbacks), NULL),
};
acpigen_write_dsm_uuid_arr(ids, ARRAY_SIZE(ids));
acpigen_pop_len(); /* Device */
acpigen_pop_len(); /* Scope */
}
static const char *crb_tpm_acpi_name(const struct device *dev)
{
return "TPM2";
}
#if CONFIG(GENERATE_SMBIOS_TABLES)
static tpm_result_t tpm_get_cap(uint32_t property, uint32_t *value)
{
TPMS_CAPABILITY_DATA cap_data;
int i;
tpm_result_t rc;
if (!value)
return TPM_CB_INVALID_ARG;
rc = tlcl2_get_capability(TPM_CAP_TPM_PROPERTIES, property, 1, &cap_data);
if (rc)
return rc;
for (i = 0; i < cap_data.data.tpmProperties.count; i++) {
if (cap_data.data.tpmProperties.tpmProperty[i].property == property) {
*value = cap_data.data.tpmProperties.tpmProperty[i].value;
return TPM_SUCCESS;
}
}
return TPM_CB_FAIL;
}
static int smbios_write_type43_tpm(struct device *dev, int *handle, unsigned long *current)
{
uint32_t tpm_manuf, tpm_family;
uint32_t fw_ver1, fw_ver2;
uint8_t major_spec_ver, minor_spec_ver;
/* Vendor ID is the value returned by TPM2_GetCapabiltiy TPM_PT_MANUFACTURER */
if (tpm_get_cap(TPM_PT_MANUFACTURER, &tpm_manuf)) {
printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_MANUFACTURER failed\n");
return 0;
}
tpm_manuf = be32toh(tpm_manuf);
if (tpm_get_cap(TPM_PT_FIRMWARE_VERSION_1, &fw_ver1)) {
printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FIRMWARE_VERSION_1 failed\n");
return 0;
}
if (tpm_get_cap(TPM_PT_FIRMWARE_VERSION_2, &fw_ver2)) {
printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FIRMWARE_VERSION_2 failed\n");
return 0;
}
if (tpm_get_cap(TPM_PT_FAMILY_INDICATOR, &tpm_family)) {
printk(BIOS_DEBUG, "TPM2_GetCap TPM_PT_FAMILY_INDICATOR failed\n");
return 0;
}
tpm_family = be32toh(tpm_family);
if (!strncmp((char *)&tpm_family, "2.0", 4)) {
major_spec_ver = 2;
minor_spec_ver = 0;
} else {
printk(BIOS_ERR, "%s: Invalid TPM family\n", __func__);
return 0;
}
return smbios_write_type43(current, handle, tpm_manuf, major_spec_ver, minor_spec_ver,
fw_ver1, fw_ver2, tis_get_dev_name(),
SMBIOS_TPM_DEVICE_CHARACTERISTICS_NOT_SUPPORTED, 0);
}
#endif
static struct device_operations __maybe_unused amd_crb_ops = {
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
#if CONFIG(HAVE_ACPI_TABLES)
.acpi_name = crb_tpm_acpi_name,
.acpi_fill_ssdt = crb_tpm_fill_ssdt,
#endif
#if CONFIG(GENERATE_SMBIOS_TABLES)
.get_smbios_data = smbios_write_type43_tpm,
#endif
};
static void enable_dev(struct device *dev)
{
#if !DEVTREE_EARLY
dev->ops = &amd_crb_ops;
#endif
}
struct chip_operations drivers_amd_ftpm_ops = {
.name = "AMD CRB fTPM",
.enable_dev = enable_dev
};

307
src/drivers/amd/ftpm/tpm.c Normal file
View file

@ -0,0 +1,307 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* This is a driver for the AMD fTPM CRB Interface.
*
* The AMD fTPM uses the CRB interface, but doesn't implement all registers
* defined in the TCG specification.
*
* The reduced CRB MMIO register space has:
* - A START register to ring the doorbell
* - An error STATUS register with only one bit
* - DMA address and size register for the CRB
* - No other status or control registers
* - No way to read current locality (assumption is locality 0)
* - No interface ID register
* - No read only registers
*
* The TPM interface also assumes that the DRTM is always using locality 0.
*
* The fTPM needs to access the SPI flash and this is currently done using
* the PSP SMI handler. Thus the fTPM will only operate after SMM has been
* set up.
*
* The fTPM needs the PSP directory files type 0x04 and type 0x54. When
* the regions are missing or corrupted the fTPM won't be operational.
*/
#include <timer.h>
#include <amdblocks/psp.h>
#include <amdblocks/reset.h>
#include <cbmem.h>
#include <console/console.h>
#include <commonlib/region.h>
#include <device/mmio.h>
#include <fmap.h>
#include <string.h>
#include "tpm.h"
/* FMAP regions used */
#define FMAP_NAME_PSP_NVRAM "PSP_NVRAM"
#define FMAP_NAME_PSP_RPMC_NVRAM "PSP_RPMC_NVRAM"
/* Size of DMA buffer in DRAM */
#define FTPM_CRB_SIZE (4 * 4096)
/* Index of Count field in TPM response buffer */
#define TPM_RSP_SIZE_BYTE 2
static struct control_area {
uint32_t start;
uint32_t command_size;
void *command_bfr;
uint32_t response_size;
void *response_bfr;
} control_area;
/* Read Control Area Structure back */
static void crb_read_control_area(void)
{
control_area.command_size = read32(CRB_REG(CRB_REG_CMD_SIZE));
control_area.command_bfr =
(void *)(uintptr_t)read64(CRB_REG(CRB_REG_CMD_ADDR));
control_area.response_size = read32(CRB_REG(CRB_REG_RESP_SIZE));
control_area.response_bfr =
(void *)(uintptr_t)read64(CRB_REG(CRB_REG_RESP_ADDR));
}
/* Wait for reg to be expected value */
static tpm_result_t crb_wait_for_reg32(const void *addr,
uint32_t timeout_ms,
uint32_t mask,
uint32_t expected_value)
{
uint32_t reg_value;
struct stopwatch sw;
// Set up a timer which breaks the loop after timeout
stopwatch_init_msecs_expire(&sw, timeout_ms);
while (1) {
// Now check if the TPM is in IDLE mode
reg_value = read32(addr);
if ((reg_value & mask) == expected_value)
return TPM_SUCCESS;
if (stopwatch_expired(&sw)) {
printk(BIOS_ERR,
"fTPM: Timed out with reg_value: %08x, mask: %08x, expected: %08x\n",
reg_value, mask, expected_value);
return TPM_CB_TIMEOUT;
}
}
}
static int erase_region(const char *name)
{
struct region_device store;
if (fmap_locate_area_as_rdev_rw(name, &store)) {
printk(BIOS_ERR, "fTPM: Unable to find FMAP region %s\n", name);
return -1;
}
if (rdev_eraseat(&store, 0, region_device_sz(&store))
!= region_device_sz(&store))
return -1;
printk(BIOS_NOTICE, "fTPM: Erased FMAP region %s\n", name);
return 0;
}
/*
* crb_tpm_init
*
* Even though the TPM does not need an initialization we check
* if the TPM responds and is in IDLE mode, which should be the
* normal bring up mode.
*/
tpm_result_t crb_tpm_init(void)
{
bool psp_rpmc_nvram, psp_nvram, psp_dir;
/*
* When recovery is required psp_ftpm_is_active() always returns false.
* Thus handle recovery before checking if fTPM is usable.
*/
psp_ftpm_needs_recovery(&psp_rpmc_nvram, &psp_nvram, &psp_dir);
if (psp_rpmc_nvram) {
if (erase_region(FMAP_NAME_PSP_RPMC_NVRAM))
psp_rpmc_nvram = false; /* Skip reset if erase failed */
}
if (psp_nvram) {
if (erase_region(FMAP_NAME_PSP_NVRAM))
psp_nvram = false; /* Skip reset if erase failed */
}
if (psp_rpmc_nvram || psp_nvram) {
printk(BIOS_DEBUG, "fTPM: Reset to recover fTPM...\n");
cold_reset();
}
if (psp_dir) {
printk(BIOS_ERR, "fTPM: fTPM driver corrupted. Need FW update.\n");
return CB_ERR;
}
if (!psp_ftpm_is_active())
return CB_ERR_NOT_IMPLEMENTED;
if (ENV_HAS_CBMEM) {
/* setting up fTPM communication buffers in cbmem */
const struct cbmem_entry *entry;
void *buf;
uint32_t length = 2 * FTPM_CRB_SIZE;
/* Only allocate once */
entry = cbmem_entry_find(CBMEM_ID_TPM2_CRB);
if (entry) {
buf = cbmem_entry_start(entry);
length = cbmem_entry_size(entry);
} else {
buf = cbmem_add(CBMEM_ID_TPM2_CRB, length);
if (!buf) {
printk(BIOS_ERR, "fTPM: CBMEM CRB buffer allocation failed\n");
return CB_ERR;
}
printk(BIOS_DEBUG, "fTPM: CRB buffer created at %p\n", buf);
memset(buf, 0, length);
}
/* Set command/response buffers in control area */
write32(CRB_REG(CRB_REG_CMD_SIZE), FTPM_CRB_SIZE);
write64(CRB_REG(CRB_REG_CMD_ADDR), (uintptr_t)buf);
write32(CRB_REG(CRB_REG_RESP_SIZE), FTPM_CRB_SIZE);
write64(CRB_REG(CRB_REG_RESP_ADDR), (uintptr_t)buf + FTPM_CRB_SIZE);
/*
* The OS will read the CRB registers to find the communication
* buffers. No need to advertise it in ACPI.
*/
}
/* Read back control area structure */
crb_read_control_area();
/* Opt out when CRB hasn't been set up yet */
if (!control_area.command_size || !control_area.response_size)
return CB_ERR_NOT_IMPLEMENTED;
/* Good to go. */
printk(BIOS_SPEW, "fTPM: CRB TPM initialized successfully\n");
return TPM_SUCCESS;
}
/*
* crb_tpm_process_command
*
* Transfers data to and from the fTPM.
*
*/
size_t crb_tpm_process_command(const void *tpm2_command, size_t command_size,
void *tpm2_response, size_t max_response)
{
uint32_t rsp_size;
tpm_result_t rc;
if (!control_area.response_size || !control_area.command_size) {
printk(BIOS_ERR, "%s: Control area wasn't set up yet\n", __func__);
return -1;
}
if (command_size > control_area.command_size) {
printk(BIOS_ERR, "%s: Command size is too big: %zu > %u.\n",
__func__, command_size, control_area.command_size);
return -1;
}
/* Check if CMD bit is cleared. */
rc = crb_wait_for_reg32(CRB_REG(CRB_REG_START), 250, CRB_REG_START_START, 0x0);
if (rc) {
printk(BIOS_ERR, "%s: Cmd Bit didn't clear\n", __func__);
return -1;
}
/* Write to Command Buffer */
memcpy(control_area.command_bfr, tpm2_command, command_size);
/* Clear Response buffer */
memset(control_area.response_bfr, 0, control_area.response_size);
/* Set Response size */
write32(CRB_REG(CRB_REG_RESP_SIZE), control_area.response_size);
/* Write Start Bit */
write8(CRB_REG(CRB_REG_START), CRB_REG_START_START);
/* Poll for Response */
rc = crb_wait_for_reg32(CRB_REG(CRB_REG_START), 3500, CRB_REG_START_START, 0);
if (rc) {
printk(BIOS_DEBUG, "%s: Timeout waiting for CMD processing\n", __func__);
return -1;
}
/* Check for errors */
rc = read32(CRB_REG(CRB_REG_STATUS));
if (rc & CRB_REG_STATUS_ERROR) {
printk(BIOS_DEBUG, "fTPM Error (%#x): Command errored.\n", rc);
return -1;
}
/* Get Response Length. Seems to be static on some platforms. */
uint32_t length = read32(CRB_REG(CRB_REG_RESP_SIZE));
assert(length <= control_area.response_size);
/* Response has to have at least 6 bytes */
if (length < 6) {
printk(BIOS_DEBUG, "fTPM Error: Invalid response length: %u\n", length);
return -1;
}
/* Get actual size from TPM packet */
memcpy(&rsp_size, control_area.response_bfr + TPM_RSP_SIZE_BYTE, sizeof(rsp_size));
rsp_size = be32_to_cpu(rsp_size);
if ((size_t)rsp_size > max_response) {
printk(BIOS_DEBUG, "fTPM Error: Response wouldn't fit into target buffer: %u > %zu\n",
rsp_size, max_response);
return -1;
}
/* Copy Response */
length = MIN(length, MIN(max_response, rsp_size));
memcpy(tpm2_response, control_area.response_bfr, length);
return length;
}
/*
* crb_tpm_is_active
*
* Checks that CRB interface is available and active.
*/
bool crb_tpm_is_active(void)
{
if (!psp_ftpm_is_active())
return false;
/* Read back control area structure */
crb_read_control_area();
/* Validate fields */
if (!control_area.command_size || !control_area.response_size ||
!control_area.command_bfr || !control_area.response_bfr ||
(control_area.command_bfr == (void *)-1) ||
(control_area.response_bfr == (void *)-1))
return false;
return true;
}
uintptr_t crb_tpm_base_address(void)
{
return psp_ftpm_base_address();
}

View file

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/* This is a driver for a Command Response Buffer Interface
* as found on AMD fTPMs. It only implements a small subset
* of the registers defined in the TCG specification.
*/
#include <amdblocks/psp.h>
#include <security/tpm/tis.h>
#include <security/tpm/tss_errors.h>
/* CRB hardware registers */
#define CRB_REG_STATUS 0x44
#define CRB_REG_STATUS_ERROR 0x01
#define CRB_REG_START 0x4C
#define CRB_REG_START_START 0x01
#define CRB_REG_CMD_SIZE 0x58
#define CRB_REG_CMD_ADDR 0x5C
#define CRB_REG_RESP_SIZE 0x64
#define CRB_REG_RESP_ADDR 0x68
/* address of locality 0 (CRB) */
#define CRB_REG(REG) ((void *)(uintptr_t)(psp_ftpm_base_address() + (REG)))
tpm_result_t crb_tpm_init(void);
size_t crb_tpm_process_command(const void *tpm2_command, size_t command_size,
void *tpm2_response, size_t max_response);
bool crb_tpm_is_active(void);
tis_sendrecv_fn crb_tis_probe(enum tpm_family *family);
uintptr_t crb_tpm_base_address(void);

View file

@ -22,7 +22,7 @@ config TPM1
config TPM2
bool "TPM 2.0"
depends on I2C_TPM || MEMORY_MAPPED_TPM || SPI_TPM || CRB_TPM
depends on I2C_TPM || MEMORY_MAPPED_TPM || SPI_TPM || CRB_TPM || AMD_CRB_FTPM
default y if MAINBOARD_HAS_TPM2
help
Select this option if your TPM uses the newer TPM 2.0 protocol.

View file

@ -29,7 +29,7 @@ tpm_result_t tlcl_lib_init(void)
init_done = true;
tlcl_tis_sendrecv = NULL;
if (CONFIG(CRB_TPM))
if (CONFIG(CRB_TPM) || CONFIG(AMD_CRB_FTPM))
tlcl_tis_sendrecv = crb_tis_probe(&tlcl_tpm_family);
if (CONFIG(MEMORY_MAPPED_TPM) && tlcl_tis_sendrecv == NULL)
tlcl_tis_sendrecv = pc80_tis_probe(&tlcl_tpm_family);

View file

@ -64,7 +64,7 @@ enum cb_err psp_get_ftpm_capabilties(uint32_t *capabilities)
},
};
printk(BIOS_DEBUG, "PSP: Querying fTPM capabilities...");
printk(BIOS_DEBUG, "PSP: Querying fTPM capabilities... ");
cmd_status = send_psp_command(MBOX_BIOS_CMD_PSP_FTPM_QUERY, &buffer);
@ -87,7 +87,7 @@ enum cb_err psp_get_hsti_state(uint32_t *state)
},
};
printk(BIOS_DEBUG, "PSP: Querying HSTI state...");
printk(BIOS_DEBUG, "PSP: Querying HSTI state... ");
cmd_status = send_psp_command(MBOX_BIOS_CMD_HSTI_QUERY, &buffer);