Christian Walter has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: src/drivers/crb: Add CRB Driver for TPM Support ......................................................................
src/drivers/crb: Add CRB Driver for TPM Support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC specific.
Untested and WIP.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h 5 files changed, 257 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/1
diff --git a/src/drivers/crb/Kconfig b/src/drivers/crb/Kconfig new file mode 100644 index 0000000..831af3d --- /dev/null +++ b/src/drivers/crb/Kconfig @@ -0,0 +1,5 @@ +config CRB_TPM + bool + help + CRB TPM driver is enabled! + diff --git a/src/drivers/crb/Makefile.inc b/src/drivers/crb/Makefile.inc new file mode 100644 index 0000000..3f12b36 --- /dev/null +++ b/src/drivers/crb/Makefile.inc @@ -0,0 +1,5 @@ +bootblock-$(CONFIG_CRB_TPM) += tis.c tpm.c +verstage-$(CONFIG_CRB_TPM) += tis.c tpm.c +romstage-$(CONFIG_CRB_TPM) += tis.c tpm.c +ramstage-$(CONFIG_CRB_TPM) += tis.c tpm.c +postcar-$(CONFIG_CRB_TPM) += tis.c tpm.c diff --git a/src/drivers/crb/tis.c b/src/drivers/crb/tis.c new file mode 100644 index 0000000..04ae9e6 --- /dev/null +++ b/src/drivers/crb/tis.c @@ -0,0 +1,85 @@ +/* + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <arch/early_variables.h> +#include <console/console.h> +#include <security/tpm/tis.h> + +#include "tpm.h" + +static unsigned tpm_is_open CAR_GLOBAL; + +static const struct { + uint16_t vid; + uint16_t did; + const char *device_name; +} dev_map[] = { + { 0x15d1, 0x001b, "SLB9670" }, + { 0x1ae0, 0x0028, "CR50" }, +}; + +static const char *tis_get_dev_name(struct tpm2_info *info) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(dev_map); i++) + if ((dev_map[i].vid == info->vendor_id) && + (dev_map[i].did == info->device_id)) + return dev_map[i].device_name; + return "Unknown"; +} + +int tis_open(void) +{ + if (car_get_var(tpm_is_open)) { + printk(BIOS_ERR, "%s called twice.\n" __func__); + return -1; + } + return 0; +} + +int tis_close(void) +{ + if (car_get_var(tpm_is_open)) { + + /* + * Do we need to do something here, like waiting for a + * transaction to stop? + */ + car_set_var(tpm_is_open, 0); + } + + return 0; +} + +int tis_init(void) +{ + struct tpm2_info info; + + // Wake TPM up (if necessary) + if (tpm2_init() != 0) + return -1; + + tpm2_get_info(&info); + + printk(BIOS_INFO, "Initialized TPM device %s revision %d\n", + tis_get_dev_name(&info), info.revision); + + return 0; +} + + +int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, + uint8_t *recvbuf, size_t *rbuf_len) +{ + int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len); + + if (len == 0) + return -1; + + *rbuf_len = len; + + return 0; +} diff --git a/src/drivers/crb/tpm.c b/src/drivers/crb/tpm.c new file mode 100644 index 0000000..b5393f7 --- /dev/null +++ b/src/drivers/crb/tpm.c @@ -0,0 +1,128 @@ +/*. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is a driver for a CRB Interface. + * + * The general flow looks like this: + * + * TPM starts in IDLE Mode + * + * IDLE --> READY --> Command Receiption + * ^ | + * | v + -- Cmd Complete <-- Command Execution + */ + +#include <timer.h> +#include <arch/early_variables.h> +#include <console/console.h> + +#include "tpm.h" + +#define CRB_CMD_TIMEOUT 1000 //DEBUG + +uint32_t crb_tpm2_cmd_buffer_size = 0; +uint64_t crb_tpm2_cmd_buffer_addr = 0; +uint32_t crb_tpm2_resp_buffer_size = 0; +uint64_t crb_tpm2_resp_buffer_addr = 0; + +/* + * tpm_is_idle + * + * Check if tpm is in idle mode + * return values: + * 1 if ready + * 0 if idle + * -1 otherwise + */ +static int tpm2_state(void) +{ + struct stopwatch sw; + uint32_t regValue = 0xFFFFFFFF; + + // Set up a timer which breaks the loop after timeout + stopwatch_init_msecs_expire(&sw, CRB_CMD_TIMEOUT); + + while (1) { + // Now check if the TPM is in IDLE mode + regValue = read32(CRB_REG(0, CRB_REG_STATUS)); + if ((regValue && CRB_REG_STATUS_IDLE) == 0x01) { + printk(BIOS_INFO, "TPM is in idle state.\n"); + return 0; + } + + if ((regValue && (CRB_REG_STATUS_IDLE || CRB_REG_STATUS_ERROR)) == 0x00) { + printk(BIOS_INFO, "TPM is in ready state\n"); + return 1; + } + + if (stopwatch_expired(&sw)) + return -1; + } + + return -1; +} + +/* TPM should be ready to receive here */ +static void write_command(const void *tpm2_command, size_t command_size) +{ + +} + +/* TPM should be done so that we can copy the response over */ +static void read_commnad(void *tpm2_response, size_t max_response) +{ + +} + +/* + * tpm2_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. + * + */ +int tpm2_init(void) +{ + // Check if TPM is in idle state when it powers on. + if (tpm2_set_ready() == -1) { + printk(BIOS_ERR, "TPM CRB Init failed.\n"); + // Todo - set it to idle and retry + return -1; + } + printk(BIOS_INFO, "TPM initialized successfully"); + + // Fetch Information from the TPM + + return 0; +} + +/* + * tpm2_process_command + */ +size_t tpm2_process_command(const void *tpm2_command, size_t command_size, + void *tpm2_response, size_t max_response) +( + // Check device state + + // Write to Command Buffer + + // Poll for Response + + // Copy Response + + // Clear Bits +) + +/* + * tp2_get_info + * + * Returns information about the TPM + * + */ +void tpm2_get_info(struct tpm2_info *tpm2_info) +{ + //TODO +} diff --git a/src/drivers/crb/tpm.h b/src/drivers/crb/tpm.h new file mode 100644 index 0000000..05735c1 --- /dev/null +++ b/src/drivers/crb/tpm.h @@ -0,0 +1,34 @@ +/* + * Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is a driver for a Command Response Buffer Interface + */ + +/* CRB driver */ +/* address of locality 0 (CRB) */ +#define TPM_CRB_BASE_ADDRESS 0xfed40000 + +#define CRB_REG(LOCTY, REG) \ + (void *)(TPM_CRB_BASE_ADDRESS + (LOCTY << 12) + REG) + +/* hardware registers */ +#define CRB_REG_REQUEST 0x00 +#define CRB_REG_STATUS 0x04 +#define CRB_REG_CANCEL 0x08 +#define CRB_REG_START 0x0C +#define CRB_REG_INT_CTRL 0x10 +#define CRB_REG_CMD_SIZE 0x18 +#define CRB_REG_CMD_ADDR 0x1C +#define CRB_REG_RESP_SIZE 0x24 +#define CRB_REG_RESP_ADDR 0x28 + +/*REQUEST Register related */ +#define CRB_REG_REQUEST_CMD_RDY 0x01 +#define CRB_REG_REQUEST_GO_IDLE 0x02 + +/* STATUS Register related */ +#define CRB_REG_STATUS_ERROR 0x01 +#define CRB_REG_STATUS_IDLE 0x02 +
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: src/drivers/crb: Add CRB Driver for TPM Support ......................................................................
Patch Set 4:
This change is ready for review.
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: src/drivers/crb: Add CRB Driver for TPM2 Support ......................................................................
Patch Set 12:
(6 comments)
This change is ready for review.
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tis.c File src/drivers/crb/tis.c:
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tis.c@93 PS8, Line 93: const char *path = "\_SB_.TPM";
use acpi_device_path() […]
Ack
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tis.c@111 PS8, Line 111: acpigen_write_mem32fixed(1, TPM_CRB_BASE_ADDRESS, 0x5000);
TPM_CRB_BASE_ADDRESS can be read from *dev
What is the point here in NOT using the define?
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tpm.c File src/drivers/crb/tpm.c:
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tpm.c@48 PS8, Line 48: control_area.request = read32(CRB_REG(current_locality, CRB_REG_REQUEST));
all those lines are quite long. […]
Ack
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tpm.c@109 PS8, Line 109: return -1;
use break here?
removed the unreachable return - though this should be fine.
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tpm.c@113 PS8, Line 113: return -1;
unreachable
Ack
https://review.coreboot.org/c/coreboot/+/34106/8/src/drivers/crb/tpm.c@230 PS8, Line 230: // Write to Command Buffer
c++ comments are mixed with C89 comments
So?
Patrick Rudolph has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: src/drivers/crb: Add CRB Driver for TPM2 Support ......................................................................
Patch Set 19:
(1 comment)
https://review.coreboot.org/c/coreboot/+/34106/19/src/drivers/crb/tpm.h File src/drivers/crb/tpm.h:
https://review.coreboot.org/c/coreboot/+/34106/19/src/drivers/crb/tpm.h@16 PS19, Line 16: (void *)(0xFED30800 + REG) 0xFED40800?
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: src/drivers/crb: Add CRB Driver for TPM2 Support ......................................................................
Patch Set 19:
(1 comment)
https://review.coreboot.org/c/coreboot/+/34106/19/src/drivers/crb/tpm.h File src/drivers/crb/tpm.h:
https://review.coreboot.org/c/coreboot/+/34106/19/src/drivers/crb/tpm.h@16 PS19, Line 16: (void *)(0xFED30800 + REG)
0xFED40800?
Ack
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#20).
Change subject: src/drivers/crb: Add CRB Driver for TPM2 Support ......................................................................
src/drivers/crb: Add CRB Driver for TPM2 Support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig 7 files changed, 538 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/20
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#21).
Change subject: src/drivers/crb: Add CRB Driver for TPM2 Support ......................................................................
src/drivers/crb: Add CRB Driver for TPM2 Support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig 7 files changed, 538 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/21
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: src/drivers/crb: Add CRB Driver for TPM2 Support ......................................................................
Patch Set 21:
(8 comments)
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.h File src/drivers/crb/tpm.h:
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.h@13 PS4, Line 13: #define TPM_CRB_BASE_ADDRESS 0xfed40000
should be a Kconfig, like SPI_BUS/SPI_ADDR on SPI TPM
Done
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.h@44 PS4, Line 44: extern struct control_area
move to tpm. […]
Done
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.c File src/drivers/crb/tpm.c:
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.c@31 PS4, Line 31: struct control_area control_area;
static […]
Done
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.c@32 PS4, Line 32: uint8_t current_locality = 0;
static […]
Done
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.c@72 PS4, Line 72: if ((tpmStatus & ((1<<17) | (1 << 19))) != 0) {
use defines for bitmask
Done
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.c@115 PS4, Line 115: uint8_t rc = crb_wait_for_reg32(CRB_REG(0, CRB_REG_LOC_STATE), 750, 0x2, 0x2);
int, as crb_wait_for_reg32 returns int
Done
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.c@181 PS4, Line 181: // Check if PTT establishment bit is valid
that's not part of CRB spec and need to be run somewhere else
Done
https://review.coreboot.org/c/coreboot/+/34106/4/src/drivers/crb/tpm.c@257 PS4, Line 257: // Copy Response
verify length before copying data
Done
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#22).
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig 7 files changed, 538 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/22
Philipp Deppenwiese has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
Patch Set 22: Code-Review+1
(2 comments)
Fix license headers to the coreboot default one
https://review.coreboot.org/c/coreboot/+/34106/22/src/drivers/crb/tis.c File src/drivers/crb/tis.c:
https://review.coreboot.org/c/coreboot/+/34106/22/src/drivers/crb/tis.c@22 PS22, Line 22: {0x15d1, 0x001b, "SLB9670"}, remove
https://review.coreboot.org/c/coreboot/+/34106/22/src/drivers/crb/tis.c@114 PS22, Line 114: Implement PPI and MCI, or we do it in a follow up
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
Patch Set 22:
(2 comments)
https://review.coreboot.org/c/coreboot/+/34106/22/src/drivers/crb/tis.c File src/drivers/crb/tis.c:
https://review.coreboot.org/c/coreboot/+/34106/22/src/drivers/crb/tis.c@22 PS22, Line 22: {0x15d1, 0x001b, "SLB9670"},
remove
Ack
https://review.coreboot.org/c/coreboot/+/34106/22/src/drivers/crb/tis.c@114 PS22, Line 114:
Implement PPI and MCI, or we do it in a follow up
I would do it in a following patch
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#23).
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig 7 files changed, 546 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/23
Philipp Deppenwiese has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
Patch Set 23: Code-Review+2
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#24).
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig M src/security/tpm/tss/tcg-2.0/tss.c 8 files changed, 555 insertions(+), 10 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/24
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#25).
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig M src/security/tpm/tss/tcg-2.0/tss.c 8 files changed, 546 insertions(+), 10 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/25
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#26).
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig D src/security/tpm/tss/tcg-2.0/tss.c 8 files changed, 546 insertions(+), 407 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/26
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#27).
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig M src/security/tpm/tss/tcg-2.0/tss.c 8 files changed, 549 insertions(+), 4 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/27
Hello Patrick Rudolph, Julius Werner, Philipp Deppenwiese, Felix Singer, build bot (Jenkins), Patrick Georgi, Martin Roth,
I'd like you to reexamine a change. Please visit
https://review.coreboot.org/c/coreboot/+/34106
to look at the new patch set (#28).
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig 7 files changed, 546 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/34106/28
Christian Walter has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
Patch Set 28:
Sorry - my git skills are just.. bad.
Philipp Deppenwiese has submitted this change and it was merged. ( https://review.coreboot.org/c/coreboot/+/34106 )
Change subject: drivers/crb: Add CRB driver for TPM2 support ......................................................................
drivers/crb: Add CRB driver for TPM2 support
Add the Command Response Buffer which is defined in the TPM 2.0 Specs. CRB can be specified with MAINBOARD_HAS_CRB_TPM, even though it is actually SoC/SB specific.
Change-Id: I477e45963fe3cdbc02cda9ae99c19142747e4b46 Signed-off-by: Christian Walter christian.walter@9elements.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/34106 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Philipp Deppenwiese zaolin.daisuki@gmail.com --- A src/drivers/crb/Kconfig A src/drivers/crb/Makefile.inc A src/drivers/crb/chip.h A src/drivers/crb/tis.c A src/drivers/crb/tpm.c A src/drivers/crb/tpm.h M src/security/tpm/Kconfig 7 files changed, 546 insertions(+), 2 deletions(-)
Approvals: build bot (Jenkins): Verified Philipp Deppenwiese: Looks good to me, approved
diff --git a/src/drivers/crb/Kconfig b/src/drivers/crb/Kconfig new file mode 100644 index 0000000..bfd8be0 --- /dev/null +++ b/src/drivers/crb/Kconfig @@ -0,0 +1,17 @@ +config CRB_TPM + bool + help + CRB TPM driver is enabled! + +config CRB_TPM_BASE_ADDRESS + hex + default 0xfed40000 + help + Base Address of the CRB TPM Command Structure + +config MAINBOARD_HAS_CRB_TPM + bool + default n + select CRB_TPM + help + Mainboard has Command Response Buffer support diff --git a/src/drivers/crb/Makefile.inc b/src/drivers/crb/Makefile.inc new file mode 100644 index 0000000..3f12b36 --- /dev/null +++ b/src/drivers/crb/Makefile.inc @@ -0,0 +1,5 @@ +bootblock-$(CONFIG_CRB_TPM) += tis.c tpm.c +verstage-$(CONFIG_CRB_TPM) += tis.c tpm.c +romstage-$(CONFIG_CRB_TPM) += tis.c tpm.c +ramstage-$(CONFIG_CRB_TPM) += tis.c tpm.c +postcar-$(CONFIG_CRB_TPM) += tis.c tpm.c diff --git a/src/drivers/crb/chip.h b/src/drivers/crb/chip.h new file mode 100644 index 0000000..8e74a68 --- /dev/null +++ b/src/drivers/crb/chip.h @@ -0,0 +1,22 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2014 Google Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef DRIVERS_CRB_CHIP_H +#define DRIVERS_CRB_CHIP_H + +typedef struct drivers_crb_config { +} tpm_config_t; + +#endif /* DRIVERS_CRB_CHIP_H */ diff --git a/src/drivers/crb/tis.c b/src/drivers/crb/tis.c new file mode 100644 index 0000000..c110151 --- /dev/null +++ b/src/drivers/crb/tis.c @@ -0,0 +1,150 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <arch/early_variables.h> +#include <console/console.h> +#include <security/tpm/tis.h> +#include <arch/acpigen.h> +#include <device/device.h> + +#include "tpm.h" +#include "chip.h" + +static unsigned tpm_is_open CAR_GLOBAL; + +static const struct { + uint16_t vid; + uint16_t did; + const char *device_name; +} dev_map[] = { + {0x1ae0, 0x0028, "CR50"}, + {0xa13a, 0x8086, "Intel iTPM"} +}; + +static const char *tis_get_dev_name(struct tpm2_info *info) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(dev_map); i++) + if ((dev_map[i].vid == info->vendor_id) && (dev_map[i].did == info->device_id)) + return dev_map[i].device_name; + return "Unknown"; +} + + +int tis_open(void) +{ + if (car_get_var(tpm_is_open)) { + printk(BIOS_ERR, "%s called twice.\n", __func__); + return -1; + } + + return 0; +} + +int tis_close(void) +{ + if (car_get_var(tpm_is_open)) { + + /* + * Do we need to do something here, like waiting for a + * transaction to stop? + */ + car_set_var(tpm_is_open, 0); + } + + return 0; +} + +int tis_init(void) +{ + struct tpm2_info info; + + // Wake TPM up (if necessary) + if (tpm2_init() != 0) + return -1; + + tpm2_get_info(&info); + + printk(BIOS_INFO, "Initialized TPM device %s revision %d\n", tis_get_dev_name(&info), + info.revision); + + return 0; +} + + +int tis_sendrecv(const uint8_t *sendbuf, size_t sbuf_size, uint8_t *recvbuf, size_t *rbuf_len) +{ + int len = tpm2_process_command(sendbuf, sbuf_size, recvbuf, *rbuf_len); + + if (len == 0) + return -1; + + *rbuf_len = len; + + return 0; +} + +#ifdef __RAMSTAGE__ + +static void crb_tpm_fill_ssdt(struct device *dev) +{ + const char *path = acpi_device_path(dev); + if (!path) { + path = "\_SB_.TPM"; + printk(BIOS_DEBUG, "Using default TPM2 ACPI path: '%s'\n", path); + } + + /* Device */ + acpigen_write_device(path); + + acpigen_write_name_string("_HID", "MSFT0101"); + acpigen_write_name_string("_CID", "MSFT0101"); + + acpigen_write_name_integer("_UID", 1); + + acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); + + /* Resources */ + acpigen_write_name("_CRS"); + acpigen_write_resourcetemplate_header(); + acpigen_write_mem32fixed(1, TPM_CRB_BASE_ADDRESS, 0x5000); + + acpigen_write_resourcetemplate_footer(); + + acpigen_pop_len(); /* Device */ +} + +static const char *crb_tpm_acpi_name(const struct device *dev) +{ + return "TPM"; +} + +static struct device_operations crb_ops = { + .read_resources = DEVICE_NOOP, + .set_resources = DEVICE_NOOP, +#if CONFIG(HAVE_ACPI_TABLES) + .acpi_name = crb_tpm_acpi_name, + .acpi_fill_ssdt_generator = crb_tpm_fill_ssdt, +#endif + +}; + +static void enable_dev(struct device *dev) +{ + dev->ops = &crb_ops; +} + +struct chip_operations drivers_crb_ops = {CHIP_NAME("CRB TPM").enable_dev = enable_dev}; + +#endif /* __RAMSTAGE__ */ diff --git a/src/drivers/crb/tpm.c b/src/drivers/crb/tpm.c new file mode 100644 index 0000000..0393417 --- /dev/null +++ b/src/drivers/crb/tpm.c @@ -0,0 +1,280 @@ +/*. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is a driver for a CRB Interface. + * + * The general flow looks like this: + * + * TPM starts in IDLE Mode + * + * IDLE --> READY --> Command Receiption + * ^ | + * | v + -- Cmd Complete <-- Command Execution + */ + +#include <timer.h> +#include <arch/early_variables.h> +#include <console/console.h> +#include <arch/mmio.h> +#include <delay.h> +#include <string.h> +#include <endian.h> +#include <soc/pci_devs.h> +#include <device/pci_ops.h> + +#include "tpm.h" + +static struct control_area { + uint32_t request; + uint32_t status; + uint32_t cancel; + uint32_t start; + uint64_t interrupt_control; + uint32_t command_size; + void *command_bfr; + uint32_t response_size; + void *response_bfr; +} control_area; + +static uint8_t cur_loc = 0; + +/* Read Control Area Structure back */ +static void crb_readControlArea(void) +{ + control_area.request = read32(CRB_REG(cur_loc, CRB_REG_REQUEST)); + control_area.status = read32(CRB_REG(cur_loc, CRB_REG_STATUS)); + control_area.cancel = read32(CRB_REG(cur_loc, CRB_REG_CANCEL)); + control_area.interrupt_control = read64(CRB_REG(cur_loc, CRB_REG_INT_CTRL)); + control_area.command_size = read32(CRB_REG(cur_loc, CRB_REG_CMD_SIZE)); + control_area.command_bfr = (void *)(uint32_t)read64(CRB_REG(cur_loc, CRB_REG_CMD_ADDR)); + control_area.response_size = read32(CRB_REG(cur_loc, CRB_REG_RESP_SIZE)); + control_area.response_bfr = + (void *)(uint32_t)read64(CRB_REG(cur_loc, CRB_REG_RESP_ADDR)); +} + +/* Wait for Reg to be expected Value */ +static int crb_wait_for_reg32(const void *addr, uint32_t timeoutMs, uint32_t mask, + uint32_t expectedValue) +{ + uint32_t regValue; + struct stopwatch sw; + + // Set up a timer which breaks the loop after timeout + stopwatch_init_msecs_expire(&sw, timeoutMs); + + while (1) { + // Now check if the TPM is in IDLE mode + regValue = read32(addr); + + if ((regValue & mask) == expectedValue) + return 0; + + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, + "CRB_WAIT: Error - Returning Zero with RegValue: %08x, Mask: %08x, Expected: %08x\n", + regValue, mask, expectedValue); + return -1; + } + } +} + +/* CRB PROBE + * + * Checks if the CRB Interface is ready + */ +static int crb_probe(void) +{ + uint64_t tpmStatus = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID)); + printk(BIOS_SPEW, "Interface ID Reg. %llx\n", tpmStatus); + + if ((tpmStatus & CRB_INTF_REG_CAP_CRB) == 0) { + printk(BIOS_DEBUG, "TPM: CRB Interface is not supported.\n"); + return -1; + } + + if ((tpmStatus & (0xf)) != 1) { + printk(BIOS_DEBUG, + "TPM: CRB Interface is not active. System needs reboot in order to active TPM.\n"); + write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL); + return -1; + } + + write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_SEL); + write32(CRB_REG(cur_loc, CRB_REG_INTF_ID), CRB_INTF_REG_INTF_LOCK); + + return 0; +} + +/* + * Get active Locality + * + * Get the active locality + */ +static uint8_t crb_activate_locality(void) +{ + + uint8_t locality = (read8(CRB_REG(0, CRB_REG_LOC_STATE)) >> 2) & 0x07; + printk(BIOS_SPEW, "Active locality: %i\n", locality); + + int rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750, + LOC_STATE_LOC_ASSIGN, LOC_STATE_LOC_ASSIGN); + if (!rc && (locality == 0)) + return locality; + + if (rc) + write8(CRB_REG(locality, CRB_REG_LOC_CTRL), LOC_CTRL_REQ_ACCESS); + + + rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 750, LOC_STATE_LOC_ASSIGN, + LOC_STATE_LOC_ASSIGN); + if (rc) { + printk(BIOS_ERR, "TPM: Error - No Locality has been assigned TPM-wise.\n"); + return 0; + } + + rc = crb_wait_for_reg32(CRB_REG(locality, CRB_REG_LOC_STATE), 1500, + LOC_STATE_REG_VALID_STS, LOC_STATE_REG_VALID_STS); + if (rc) { + printk(BIOS_ERR, "TPM: Error - LOC_STATE Register %u contains errors.\n", + locality); + return 0; + } + + + return locality; +} + +/* Switch Device into a Ready State */ +static int crb_switch_to_ready(void) +{ + /* Transition into ready state */ + write8(CRB_REG(cur_loc, CRB_REG_REQUEST), 0x1); + int rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_REQUEST), 200, + CRB_REG_REQUEST_CMD_RDY, 0x0); + if (rc) { + printk(BIOS_ERR, + "TPM: Error - TPM did not transition into ready state in time.\n"); + return -1; + } + + /* Check TPM_CRB_CTRL_STS[0] to be "0" - no unrecoverable error */ + rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 500, CRB_REG_STATUS_ERROR, + 0x0); + if (rc) { + printk(BIOS_ERR, "TPM: Fatal Error - Could not recover.\n"); + return -1; + } + + return 0; +} + +/* + * tpm2_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. + * + */ +int tpm2_init(void) +{ + + + if (crb_probe()) { + printk(BIOS_ERR, "TPM: Probe failed.\n"); + return -1; + } + + /* Read back control area structure */ + crb_readControlArea(); + + /* Good to go. */ + printk(BIOS_SPEW, "TPM: CRB TPM initialized successfully\n"); + + return 0; +} + +/* + * tpm2_process_command + */ +size_t tpm2_process_command(const void *tpm2_command, size_t command_size, void *tpm2_response, + size_t max_response) +{ + int rc; + + if (command_size > control_area.command_size) { + printk(BIOS_ERR, "TPM: Command size is too big.\n"); + return -1; + } + + if (control_area.response_size < max_response) { + printk(BIOS_ERR, "TPM: Response size could be too big.\n"); + return -1; + } + + cur_loc = crb_activate_locality(); + + // Check if CMD bit is cleared. + rc = crb_wait_for_reg32(CRB_REG(0, CRB_REG_START), 250, CRB_REG_START_START, 0x0); + if (rc) { + printk(BIOS_ERR, "TPM: Error - Cmd Bit not cleared.\n"); + return -1; + } + + if (crb_switch_to_ready()) + return -1; + + // Write to Command Buffer + memcpy(control_area.command_bfr, tpm2_command, command_size); + + // Write Start Bit + write8(CRB_REG(cur_loc, CRB_REG_START), 0x1); + + // Poll for Response + rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_START), 3500, CRB_REG_START_START, 0); + if (rc) { + printk(BIOS_DEBUG, "TPM: Command Timed out.\n"); + return -1; + } + + // Check for errors + rc = crb_wait_for_reg32(CRB_REG(cur_loc, CRB_REG_STATUS), 200, CRB_REG_STATUS_ERROR, 0); + if (rc) { + printk(BIOS_DEBUG, "TPM: Command errored.\n"); + return -1; + } + + // Get Response Length + uint32_t length = be32_to_cpu(read32(control_area.response_bfr + 2)); + + /* Response has to have at least 6 bytes */ + if (length < 6) + return 1; + + // Copy Response + memcpy(tpm2_response, control_area.response_bfr, length); + + if (crb_switch_to_ready()) { + printk(BIOS_DEBUG, "TPM: Can not transition into ready state again.\n"); + return -1; + } + + return length; +} + +/* + * tp2_get_info + * + * Returns information about the TPM + * + */ +void tpm2_get_info(struct tpm2_info *tpm2_info) +{ + uint64_t interfaceReg = read64(CRB_REG(cur_loc, CRB_REG_INTF_ID)); + + tpm2_info->vendor_id = (interfaceReg >> 48) & 0xFFFF; + tpm2_info->device_id = (interfaceReg >> 32) & 0xFFFF; + tpm2_info->revision = (interfaceReg >> 24) & 0xFF; +} diff --git a/src/drivers/crb/tpm.h b/src/drivers/crb/tpm.h new file mode 100644 index 0000000..9bbed19 --- /dev/null +++ b/src/drivers/crb/tpm.h @@ -0,0 +1,70 @@ +/* + * Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * This is a driver for a Command Response Buffer Interface + */ + +/* CRB driver */ +/* address of locality 0 (CRB) */ +#define TPM_CRB_BASE_ADDRESS CONFIG_CRB_TPM_BASE_ADDRESS + +#define CRB_REG(LOCTY, REG) \ + (void *)(CONFIG_CRB_TPM_BASE_ADDRESS + (LOCTY << 12) + REG) + +/* hardware registers */ +#define CRB_REG_LOC_STATE 0x00 +#define CRB_REG_LOC_CTRL 0x08 +#define CRB_REG_LOC_STS 0x0C + +/* LOC_CTRL BIT MASKS */ +#define LOC_CTRL_REQ_ACCESS 0x01 + +/* LOC STATE BIT MASKS */ +#define LOC_STATE_LOC_ASSIGN 0x02 +#define LOC_STATE_REG_VALID_STS 0x80 + +/* LOC STS BIT MASKS */ +#define LOC_STS_GRANTED 0x01 + +#define CRB_REG_INTF_ID 0x30 +#define CRB_REG_REQUEST 0x40 +#define CRB_REG_STATUS 0x44 +#define CRB_REG_CANCEL 0x48 +#define CRB_REG_START 0x4C +#define CRB_REG_INT_CTRL 0x50 +#define CRB_REG_CMD_SIZE 0x58 +#define CRB_REG_CMD_ADDR 0x5C +#define CRB_REG_RESP_SIZE 0x64 +#define CRB_REG_RESP_ADDR 0x68 + +/* CRB INTF BIT MASK */ +#define CRB_INTF_REG_CAP_CRB (1<<14) +#define CRB_INTF_REG_INTF_SEL (1<<17) +#define CRB_INTF_REG_INTF_LOCK (1<<19) + + +/*REQUEST Register related */ +#define CRB_REG_REQUEST_CMD_RDY 0x01 +#define CRB_REG_REQUEST_GO_IDLE 0x02 + +/* STATUS Register related */ +#define CRB_REG_STATUS_ERROR 0x01 +#define CRB_REG_STATUS_IDLE 0x02 + +/* START Register related */ +#define CRB_REG_START_START 0x01 + +/* TPM Info Struct */ +struct tpm2_info { + uint16_t vendor_id; + uint16_t device_id; + uint16_t revision; +}; + + +int tpm2_init(void); +void tpm2_get_info(struct tpm2_info *tpm2_info); +size_t tpm2_process_command(const void *tpm2_command, size_t command_size, + void *tpm2_response, size_t max_response); diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig index e6414d3..3af6d69 100644 --- a/src/security/tpm/Kconfig +++ b/src/security/tpm/Kconfig @@ -28,7 +28,7 @@ default y if MAINBOARD_HAS_TPM2 || USER_TPM2 depends on MAINBOARD_HAS_I2C_TPM_GENERIC || MAINBOARD_HAS_LPC_TPM \ || MAINBOARD_HAS_I2C_TPM_ATMEL || MAINBOARD_HAS_I2C_TPM_CR50 \ - || MAINBOARD_HAS_SPI_TPM_CR50 + || MAINBOARD_HAS_SPI_TPM_CR50 || MAINBOARD_HAS_CRB_TPM
config MAINBOARD_HAS_TPM1 bool @@ -58,7 +58,7 @@ bool "2.0" depends on MAINBOARD_HAS_I2C_TPM_GENERIC || MAINBOARD_HAS_LPC_TPM \ || MAINBOARD_HAS_I2C_TPM_ATMEL || MAINBOARD_HAS_I2C_TPM_CR50 \ - || MAINBOARD_HAS_SPI_TPM_CR50 + || MAINBOARD_HAS_SPI_TPM_CR50 || MAINBOARD_HAS_CRB_TPM help Enable this option to enable TPM 2.0 support in coreboot.