diff options
author | Christian Walter <christian.walter@9elements.com> | 2019-07-05 19:46:30 +0200 |
---|---|---|
committer | Philipp Deppenwiese <zaolin.daisuki@gmail.com> | 2019-07-31 10:58:36 +0000 |
commit | 7706a04c603474400234cc72a27a61070845eca2 (patch) | |
tree | d1c5c05697f415ba825e4b3ab63a4277c36f458e /src/drivers/crb/tis.c | |
parent | c703814e951376bef0945934dccff9158d54db7d (diff) | |
download | coreboot-7706a04c603474400234cc72a27a61070845eca2.tar.xz |
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>
Diffstat (limited to 'src/drivers/crb/tis.c')
-rw-r--r-- | src/drivers/crb/tis.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/src/drivers/crb/tis.c b/src/drivers/crb/tis.c new file mode 100644 index 0000000000..c110151766 --- /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__ */ |