diff options
Diffstat (limited to 'src/drivers')
-rw-r--r-- | src/drivers/pc80/tpm/tis.c | 128 | ||||
-rw-r--r-- | src/drivers/tpm/Makefile.inc | 2 | ||||
-rw-r--r-- | src/drivers/tpm/ppi_stub.c | 133 | ||||
-rw-r--r-- | src/drivers/tpm/tpm_ppi.h | 58 |
4 files changed, 199 insertions, 122 deletions
diff --git a/src/drivers/pc80/tpm/tis.c b/src/drivers/pc80/tpm/tis.c index 27d238ce75..48e529ad9f 100644 --- a/src/drivers/pc80/tpm/tis.c +++ b/src/drivers/pc80/tpm/tis.c @@ -21,13 +21,11 @@ #include <console/console.h> #include <security/tpm/tis.h> #include <device/pnp.h> +#include <drivers/tpm/tpm_ppi.h> #include "chip.h" #define PREFIX "lpc_tpm: " -/* TCG Physical Presence Interface */ -#define TPM_PPI_UUID "3dddfaa6-361b-4eb4-a424-8d10089d1653" -/* TCG Memory Clear Interface */ -#define TPM_MCI_UUID "376054ed-cc13-4675-901c-4756d7f2d45d" + /* coreboot wrapper for TPM driver (start) */ #define TPM_DEBUG(fmt, args...) \ if (CONFIG(DEBUG_TPM)) { \ @@ -777,104 +775,9 @@ static void lpc_tpm_set_resources(struct device *dev) } #if CONFIG(HAVE_ACPI_TABLES) - -static void tpm_ppi_func0_cb(void *arg) -{ - /* Functions 1-8. */ - u8 buf[] = {0xff, 0x01}; - acpigen_write_return_byte_buffer(buf, 2); -} - -static void tpm_ppi_func1_cb(void *arg) -{ - if (CONFIG(TPM2)) - /* Interface version: 2.0 */ - acpigen_write_return_string("2.0"); - else - /* Interface version: 1.2 */ - acpigen_write_return_string("1.2"); -} - -static void tpm_ppi_func2_cb(void *arg) -{ - /* Submit operations: drop on the floor and return success. */ - acpigen_write_return_byte(0); -} - -static void tpm_ppi_func3_cb(void *arg) -{ - /* Pending operation: none. */ - acpigen_emit_byte(RETURN_OP); - acpigen_write_package(2); - acpigen_write_byte(0); - acpigen_write_byte(0); - acpigen_pop_len(); -} -static void tpm_ppi_func4_cb(void *arg) -{ - /* Pre-OS transition method: reboot. */ - acpigen_write_return_byte(2); -} -static void tpm_ppi_func5_cb(void *arg) -{ - /* Operation response: no operation executed. */ - acpigen_emit_byte(RETURN_OP); - acpigen_write_package(3); - acpigen_write_byte(0); - acpigen_write_byte(0); - acpigen_write_byte(0); - acpigen_pop_len(); -} -static void tpm_ppi_func6_cb(void *arg) -{ - /* - * Set preferred user language: deprecated and must return 3 aka - * "not implemented". - */ - acpigen_write_return_byte(3); -} -static void tpm_ppi_func7_cb(void *arg) -{ - /* Submit operations: deny. */ - acpigen_write_return_byte(3); -} -static void tpm_ppi_func8_cb(void *arg) -{ - /* All actions are forbidden. */ - acpigen_write_return_byte(1); -} -static void (*tpm_ppi_callbacks[])(void *) = { - tpm_ppi_func0_cb, - tpm_ppi_func1_cb, - tpm_ppi_func2_cb, - tpm_ppi_func3_cb, - tpm_ppi_func4_cb, - tpm_ppi_func5_cb, - tpm_ppi_func6_cb, - tpm_ppi_func7_cb, - tpm_ppi_func8_cb, -}; - -static void tpm_mci_func0_cb(void *arg) -{ - /* Function 1. */ - acpigen_write_return_singleton_buffer(0x3); -} -static void tpm_mci_func1_cb(void *arg) -{ - /* Just return success. */ - acpigen_write_return_byte(0); -} - -static void (*tpm_mci_callbacks[])(void *) = { - tpm_mci_func0_cb, - tpm_mci_func1_cb, -}; - static void lpc_tpm_fill_ssdt(const struct device *dev) { const char *path = acpi_device_path(dev->bus->dev); - u32 arg; if (!path) { path = "\\_SB_.PCI0.LPCB"; @@ -938,31 +841,12 @@ static void lpc_tpm_fill_ssdt(const struct device *dev) acpi_device_write_interrupt(&tpm_irq); } + acpigen_write_resourcetemplate_footer(); - if (!CONFIG(CHROMEOS)) { - /* - * _DSM method - */ - struct dsm_uuid ids[] = { - /* Physical presence interface. - * This is used to submit commands like "Clear TPM" to - * be run at next reboot provided that user confirms - * them. Spec allows user to cancel all commands and/or - * configure BIOS to reject commands. So we pretend that - * user did just this: cancelled everything. If user - * really wants to clear TPM the only option now is to - * do it manually in payload. - */ - DSM_UUID(TPM_PPI_UUID, &tpm_ppi_callbacks[0], - ARRAY_SIZE(tpm_ppi_callbacks), (void *) &arg), - /* Memory clearing on boot: just a dummy. */ - DSM_UUID(TPM_MCI_UUID, &tpm_mci_callbacks[0], - ARRAY_SIZE(tpm_mci_callbacks), (void *) &arg), - }; - - acpigen_write_dsm_uuid_arr(ids, ARRAY_SIZE(ids)); - } + if (!CONFIG(CHROMEOS)) + tpm_ppi_acpi_fill_ssdt(dev); + acpigen_pop_len(); /* Device */ acpigen_pop_len(); /* Scope */ diff --git a/src/drivers/tpm/Makefile.inc b/src/drivers/tpm/Makefile.inc index 4e80600ddf..5fc4632912 100644 --- a/src/drivers/tpm/Makefile.inc +++ b/src/drivers/tpm/Makefile.inc @@ -1 +1,3 @@ ramstage-$(CONFIG_TPM_INIT) += tpm.c + +ramstage-$(CONFIG_HAVE_ACPI_TABLES) += ppi_stub.c diff --git a/src/drivers/tpm/ppi_stub.c b/src/drivers/tpm/ppi_stub.c new file mode 100644 index 0000000000..11bd07e10a --- /dev/null +++ b/src/drivers/tpm/ppi_stub.c @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <types.h> +#include <stddef.h> +#include <acpi/acpi.h> +#include <acpi/acpigen.h> +#include <acpi/acpi_device.h> + +#include "tpm_ppi.h" + +static void tpm_ppi_func0_cb(void *arg) +{ + /* Functions 1-8. */ + u8 buf[] = {0xff, 0x01}; + acpigen_write_return_byte_buffer(buf, sizeof(buf)); +} + +static void tpm_ppi_func1_cb(void *arg) +{ + if (CONFIG(TPM2)) + /* Interface version: 2.0 */ + acpigen_write_return_string("2.0"); + else + /* Interface version: 1.2 */ + acpigen_write_return_string("1.2"); +} + +static void tpm_ppi_func2_cb(void *arg) +{ + /* Submit operations: drop on the floor and return success. */ + acpigen_write_return_byte(PPI2_RET_SUCCESS); +} + +static void tpm_ppi_func3_cb(void *arg) +{ + /* Pending operation: none. */ + acpigen_emit_byte(RETURN_OP); + acpigen_write_package(2); + acpigen_write_byte(0); + acpigen_write_byte(0); + acpigen_pop_len(); +} + +static void tpm_ppi_func4_cb(void *arg) +{ + /* Pre-OS transition method: reboot. */ + acpigen_write_return_byte(2); +} + +static void tpm_ppi_func5_cb(void *arg) +{ + /* Operation response: no operation executed. */ + acpigen_emit_byte(RETURN_OP); + acpigen_write_package(3); + acpigen_write_byte(0); + acpigen_write_byte(0); + acpigen_write_byte(0); + acpigen_pop_len(); +} + +static void tpm_ppi_func6_cb(void *arg) +{ + /* + * Set preferred user language: deprecated and must return 3 AKA + * "not implemented". + */ + acpigen_write_return_byte(PPI6_RET_NOT_IMPLEMENTED); +} + +static void tpm_ppi_func7_cb(void *arg) +{ + /* Submit operations: deny. */ + acpigen_write_return_byte(PPI7_RET_BLOCKED_BY_FIRMWARE); +} + +static void tpm_ppi_func8_cb(void *arg) +{ + /* All actions are forbidden. */ + acpigen_write_return_byte(PPI8_RET_FIRMWARE_ONLY); +} + +static void (*tpm_ppi_callbacks[])(void *) = { + tpm_ppi_func0_cb, + tpm_ppi_func1_cb, + tpm_ppi_func2_cb, + tpm_ppi_func3_cb, + tpm_ppi_func4_cb, + tpm_ppi_func5_cb, + tpm_ppi_func6_cb, + tpm_ppi_func7_cb, + tpm_ppi_func8_cb, +}; + +static void tpm_mci_func0_cb(void *arg) +{ + /* Function 1. */ + acpigen_write_return_singleton_buffer(0x3); +} +static void tpm_mci_func1_cb(void *arg) +{ + /* Just return success. */ + acpigen_write_return_byte(0); +} + +static void (*tpm_mci_callbacks[])(void *) = { + tpm_mci_func0_cb, + tpm_mci_func1_cb, +}; + +void tpm_ppi_acpi_fill_ssdt(const struct device *dev) +{ + /* + * _DSM method + */ + struct dsm_uuid ids[] = { + /* Physical presence interface. + * This is used to submit commands like "Clear TPM" to + * be run at next reboot provided that user confirms + * them. Spec allows user to cancel all commands and/or + * configure BIOS to reject commands. So we pretend that + * user did just this: cancelled everything. If user + * really wants to clear TPM the only option now is to + * do it manually in payload. + */ + DSM_UUID(TPM_PPI_UUID, tpm_ppi_callbacks, + ARRAY_SIZE(tpm_ppi_callbacks), NULL), + /* Memory clearing on boot: just a dummy. */ + DSM_UUID(TPM_MCI_UUID, tpm_mci_callbacks, + ARRAY_SIZE(tpm_mci_callbacks), NULL), + }; + + acpigen_write_dsm_uuid_arr(ids, ARRAY_SIZE(ids)); +} diff --git a/src/drivers/tpm/tpm_ppi.h b/src/drivers/tpm/tpm_ppi.h new file mode 100644 index 0000000000..7662386575 --- /dev/null +++ b/src/drivers/tpm/tpm_ppi.h @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _TPM_PPI_H_ +#define _TPM_PPI_H_ + +#include <device/device.h> + +#if CONFIG(HAVE_ACPI_TABLES) +void tpm_ppi_acpi_fill_ssdt(const struct device *dev); +#else +static inline void tpm_ppi_acpi_fill_ssdt(const struct device *dev) +{ +} +#endif + + +/* Return codes */ +/* Function 2 */ +#define PPI2_RET_SUCCESS 0 +#define PPI2_RET_NOT_SUPPORTED 1 +#define PPI2_RET_GENERAL_FAILURE 2 + +/* Function 3 */ +#define PPI3_RET_SUCCESS 0 +#define PPI3_RET_GENERAL_FAILURE 1 + +/* Function 4 */ +#define PPI4_RET_NONE 0 +#define PPI4_RET_SHUTDOWN 1 +#define PPI4_RET_REBOOT 2 +#define PPI4_RET_OS_VENDOR_SPECIFIC 3 + +/* Function 5 */ +#define PPI5_RET_SUCCESS 0 +#define PPI5_RET_GENERAL_FAILURE 1 + +/* Function 6 */ +#define PPI6_RET_NOT_IMPLEMENTED 3 + +/* Function 7 */ +#define PPI7_RET_SUCCESS 0 +#define PPI7_RET_NOT_IMPLEMENTED 1 +#define PPI7_RET_GENERAL_FAILURE 2 +#define PPI7_RET_BLOCKED_BY_FIRMWARE 3 + +/* Function 8 */ +#define PPI8_RET_NOT_IMPLEMENTED 0 +#define PPI8_RET_FIRMWARE_ONLY 1 +#define PPI8_RET_BLOCKED_FOR_OS_BY_FW 2 +#define PPI8_RET_ALLOWED_WITH_PP 3 +#define PPI8_RET_ALLOWED 4 + +/* TCG Physical Presence Interface */ +#define TPM_PPI_UUID "3dddfaa6-361b-4eb4-a424-8d10089d1653" +/* TCG Memory Clear Interface */ +#define TPM_MCI_UUID "376054ed-cc13-4675-901c-4756d7f2d45d" + +#endif /* _TPM_PPI_H_ */ |