Philipp Deppenwiese has uploaded this change for review. ( https://review.coreboot.org/29194
Change subject: security/tpm: Add generalized ACPI table generation ......................................................................
security/tpm: Add generalized ACPI table generation
* Move ACPI table generation from TPM bus drivers to security/tpm/acpi * Update TPPI interface implementation
Change-Id: I2afdf4872566353284ab7734205a3bea738a6e0e Signed-off-by: Philipp Deppenwiese zaolin@das-labor.org --- M src/drivers/i2c/tpm/Makefile.inc D src/drivers/i2c/tpm/chip.c M src/drivers/pc80/tpm/tis.c M src/drivers/spi/acpi/acpi.c M src/security/tpm/Makefile.inc 5 files changed, 11 insertions(+), 480 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/94/29194/1
diff --git a/src/drivers/i2c/tpm/Makefile.inc b/src/drivers/i2c/tpm/Makefile.inc index e24a66d..3c91bc0 100644 --- a/src/drivers/i2c/tpm/Makefile.inc +++ b/src/drivers/i2c/tpm/Makefile.inc @@ -18,4 +18,4 @@ verstage-$(CONFIG_MAINBOARD_HAS_I2C_TPM_CR50) += cr50.c bootblock-$(CONFIG_MAINBOARD_HAS_I2C_TPM_CR50) += cr50.c
-ramstage-$(CONFIG_DRIVER_I2C_TPM_ACPI) += chip.c +ramstage-$(CONFIG_DRIVER_I2C_TPM_ACPI) += acpi.c diff --git a/src/drivers/i2c/tpm/chip.c b/src/drivers/i2c/tpm/chip.c deleted file mode 100644 index 3dbe811..0000000 --- a/src/drivers/i2c/tpm/chip.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2016 Google Inc. - * - * 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/acpi_device.h> -#include <arch/acpigen.h> -#include <console/console.h> -#include <device/i2c_simple.h> -#include <device/device.h> -#include <device/path.h> -#include <stdint.h> -#include <string.h> -#include "tpm.h" -#include "chip.h" - -static void i2c_tpm_fill_ssdt(struct device *dev) -{ - struct drivers_i2c_tpm_config *config = dev->chip_info; - const char *scope = acpi_device_scope(dev); - struct acpi_i2c i2c = { - .address = dev->path.i2c.device, - .mode_10bit = dev->path.i2c.mode_10bit, - .speed = config->speed ? : I2C_SPEED_FAST, - .resource = scope, - }; - - if (!dev->enabled || !scope) - return; - - if (!config->hid) { - printk(BIOS_ERR, "%s: ERROR: HID required\n", dev_path(dev)); - return; - } - - /* Device */ - acpigen_write_scope(scope); - acpigen_write_device(acpi_device_name(dev)); - acpigen_write_name_string("_HID", config->hid); - acpigen_write_name_integer("_UID", config->uid); - acpigen_write_name_string("_DDN", dev->chip_ops->name); - acpigen_write_STA(acpi_device_status(dev)); - - /* Resources */ - acpigen_write_name("_CRS"); - acpigen_write_resourcetemplate_header(); - acpi_device_write_i2c(&i2c); - if (config->irq_gpio.pin_count) - acpi_device_write_gpio(&config->irq_gpio); - else - acpi_device_write_interrupt(&config->irq); - - acpigen_write_resourcetemplate_footer(); - - acpigen_pop_len(); /* Device */ - acpigen_pop_len(); /* Scope */ - - printk(BIOS_INFO, "%s: %s at %s\n", acpi_device_path(dev), - dev->chip_ops->name, dev_path(dev)); -} - -static const char *i2c_tpm_acpi_name(const struct device *dev) -{ - return "TPMI"; -} - -static struct device_operations i2c_tpm_ops = { - .read_resources = DEVICE_NOOP, - .set_resources = DEVICE_NOOP, - .enable_resources = DEVICE_NOOP, - .acpi_name = &i2c_tpm_acpi_name, - .acpi_fill_ssdt_generator = &i2c_tpm_fill_ssdt, -}; - -static void i2c_tpm_enable(struct device *dev) -{ - struct drivers_i2c_tpm_config *config = dev->chip_info; - - dev->ops = &i2c_tpm_ops; - - if (config && config->desc) { - dev->name = config->desc; - } -} - -struct chip_operations drivers_i2c_tpm_ops = { - CHIP_NAME("I2C TPM") - .enable_dev = &i2c_tpm_enable -}; diff --git a/src/drivers/pc80/tpm/tis.c b/src/drivers/pc80/tpm/tis.c index 8c01ac3..7df9785 100644 --- a/src/drivers/pc80/tpm/tis.c +++ b/src/drivers/pc80/tpm/tis.c @@ -27,15 +27,13 @@ #include <string.h> #include <delay.h> #include <arch/io.h> -#include <arch/acpi.h> -#include <arch/acpigen.h> -#include <arch/acpi_device.h> #include <device/device.h> #include <console/console.h> #include <security/tpm/tis.h> #include <arch/early_variables.h> #include <device/pnp.h> #include "chip.h" +#include <security/tpm/acpi.h>
#define PREFIX "lpc_tpm: " /* TCG Physical Presence Interface */ @@ -782,207 +780,11 @@ } }
-#if IS_ENABLED(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 (IS_ENABLED(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(struct device *dev) -{ - const char *path = acpi_device_path(dev->bus->dev); - u32 arg; - - if (!path) { - path = "\_SB_.PCI0.LPCB"; - printk(BIOS_DEBUG, "Using default TPM ACPI path: '%s'\n", path); - } - - /* Device */ - acpigen_write_scope(path); - acpigen_write_device(acpi_device_name(dev)); - - acpigen_write_name("_HID"); - acpigen_emit_eisaid("PNP0C31"); - - acpigen_write_name("_CID"); - acpigen_emit_eisaid("PNP0C31"); - - acpigen_write_name_integer("_UID", 1); - - u32 did_vid = tpm_read_did_vid(0); - if (did_vid > 0 && did_vid < 0xffffffff) - acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_ON); - else - acpigen_write_STA(ACPI_STATUS_DEVICE_ALL_OFF); - - u16 port = dev->path.pnp.port; - - /* Resources */ - acpigen_write_name("_CRS"); - acpigen_write_resourcetemplate_header(); - acpigen_write_mem32fixed(1, CONFIG_TPM_TIS_BASE_ADDRESS, 0x5000); - acpigen_write_io16(port, port, 1, 2, 1); - - if (CONFIG_TPM_PIRQ) { - /* - * PIRQ: Update interrupt vector with configured PIRQ - * Active-Low Level-Triggered Shared - */ - struct acpi_irq tpm_irq_a = ACPI_IRQ_LEVEL_LOW(CONFIG_TPM_PIRQ); - acpi_device_write_interrupt(&tpm_irq_a); - } else if (tpm_read_int_vector(0) > 0) { - u8 int_vec = tpm_read_int_vector(0); - u8 int_pol = tpm_read_int_polarity(0); - struct acpi_irq tpm_irq = ACPI_IRQ_LEVEL_LOW(int_vec); - - if (int_pol & 1) - tpm_irq.polarity = ACPI_IRQ_ACTIVE_LOW; - else - tpm_irq.polarity = ACPI_IRQ_ACTIVE_HIGH; - - if (int_pol & 2) - tpm_irq.mode = ACPI_IRQ_EDGE_TRIGGERED; - else - tpm_irq.mode = ACPI_IRQ_LEVEL_TRIGGERED; - - acpi_device_write_interrupt(&tpm_irq); - } - - acpigen_write_resourcetemplate_footer(); - - if (!IS_ENABLED(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)); - } - acpigen_pop_len(); /* Device */ - acpigen_pop_len(); /* Scope */ - - printk(BIOS_INFO, "%s.%s: %s %s\n", path, acpi_device_name(dev), - dev->chip_ops->name, dev_path(dev)); -} - -static const char *lpc_tpm_acpi_name(const struct device *dev) -{ - return "TPM"; -} -#endif - static struct device_operations lpc_tpm_ops = { .read_resources = &lpc_tpm_read_resources, .set_resources = &lpc_tpm_set_resources, -#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) - .acpi_name = &lpc_tpm_acpi_name, - .acpi_fill_ssdt_generator = &lpc_tpm_fill_ssdt, -#endif + .acpi_name = &tpm_acpi_name, + .acpi_fill_ssdt_generator = &tpm_ssdt_generator, };
static struct pnp_info pnp_dev_info[] = { diff --git a/src/drivers/spi/acpi/acpi.c b/src/drivers/spi/acpi/acpi.c index cf75f9e..e1940c8 100644 --- a/src/drivers/spi/acpi/acpi.c +++ b/src/drivers/spi/acpi/acpi.c @@ -23,190 +23,14 @@ #include <stdint.h> #include <string.h> #include "chip.h" - -static int spi_acpi_get_bus(const struct device *dev) -{ - struct device *spi_dev; - struct device_operations *ops; - - if (!dev->bus || !dev->bus->dev) - return -1; - - spi_dev = dev->bus->dev; - ops = spi_dev->ops; - - if (ops && ops->ops_spi_bus && - ops->ops_spi_bus->dev_to_bus) - return ops->ops_spi_bus->dev_to_bus(spi_dev); - - return -1; -} - -static bool spi_acpi_add_gpios_to_crs(struct drivers_spi_acpi_config *config) -{ - /* - * Return false if: - * 1. Request to explicitly disable export of GPIOs in CRS, or - * 2. Both reset and enable GPIOs are not provided. - */ - if (config->disable_gpio_export_in_crs || - ((config->reset_gpio.pin_count == 0) && - (config->enable_gpio.pin_count == 0))) - return false; - - return true; -} - -static int spi_acpi_write_gpio(struct acpi_gpio *gpio, int *curr_index) -{ - int ret = -1; - - if (gpio->pin_count == 0) - return ret; - - acpi_device_write_gpio(gpio); - ret = *curr_index; - (*curr_index)++; - - return ret; -} - -static void spi_acpi_fill_ssdt_generator(struct device *dev) -{ - struct drivers_spi_acpi_config *config = dev->chip_info; - const char *scope = acpi_device_scope(dev); - const char *path = acpi_device_path(dev); - struct acpi_spi spi = { - .device_select = dev->path.spi.cs, - .speed = config->speed ? : 1 * MHz, - .resource = scope, - .device_select_polarity = SPI_POLARITY_LOW, - .wire_mode = SPI_4_WIRE_MODE, - .data_bit_length = 8, - .clock_phase = SPI_CLOCK_PHASE_FIRST, - .clock_polarity = SPI_POLARITY_LOW, - }; - int curr_index = 0; - int irq_gpio_index = -1; - int reset_gpio_index = -1; - int enable_gpio_index = -1; - - if (!dev->enabled || !scope) - return; - - if (spi_acpi_get_bus(dev) == -1) { - printk(BIOS_ERR, "%s: ERROR: Cannot get bus for device.\n", - dev_path(dev)); - return; - } - - if (!config->hid) { - printk(BIOS_ERR, "%s: ERROR: HID required.\n", dev_path(dev)); - return; - } - - /* Device */ - acpigen_write_scope(scope); - acpigen_write_device(acpi_device_name(dev)); - acpigen_write_name_string("_HID", config->hid); - if (config->cid) - acpigen_write_name_string("_CID", config->cid); - acpigen_write_name_integer("_UID", config->uid); - if (config->desc) - acpigen_write_name_string("_DDN", config->desc); - acpigen_write_STA(acpi_device_status(dev)); - - /* Resources */ - acpigen_write_name("_CRS"); - acpigen_write_resourcetemplate_header(); - acpi_device_write_spi(&spi); - - /* Use either Interrupt() or GpioInt() */ - if (config->irq_gpio.pin_count) - irq_gpio_index = spi_acpi_write_gpio(&config->irq_gpio, - &curr_index); - else - acpi_device_write_interrupt(&config->irq); - - /* Add enable/reset GPIOs if needed */ - if (spi_acpi_add_gpios_to_crs(config)) { - reset_gpio_index = spi_acpi_write_gpio(&config->reset_gpio, - &curr_index); - enable_gpio_index = spi_acpi_write_gpio(&config->enable_gpio, - &curr_index); - } - acpigen_write_resourcetemplate_footer(); - - /* Wake capabilities */ - if (config->wake) { - acpigen_write_name_integer("_S0W", 4); - acpigen_write_PRW(config->wake, 3); - }; - - /* Write device properties if needed */ - if (config->compat_string || irq_gpio_index >= 0 || - reset_gpio_index >= 0 || enable_gpio_index >= 0) { - struct acpi_dp *dsd = acpi_dp_new_table("_DSD"); - if (config->compat_string) - acpi_dp_add_string(dsd, "compatible", - config->compat_string); - if (irq_gpio_index >= 0) - acpi_dp_add_gpio(dsd, "irq-gpios", path, - irq_gpio_index, 0, - config->irq_gpio.polarity); - if (reset_gpio_index >= 0) - acpi_dp_add_gpio(dsd, "reset-gpios", path, - reset_gpio_index, 0, - config->reset_gpio.polarity); - if (enable_gpio_index >= 0) - acpi_dp_add_gpio(dsd, "enable-gpios", path, - enable_gpio_index, 0, - config->enable_gpio.polarity); - acpi_dp_write(dsd); - } - - /* Power Resource */ - if (config->has_power_resource) { - const struct acpi_power_res_params power_res_params = { - &config->reset_gpio, - config->reset_delay_ms, - config->reset_off_delay_ms, - &config->enable_gpio, - config->enable_delay_ms, - config->enable_off_delay_ms, - &config->stop_gpio, - config->stop_delay_ms, - config->stop_off_delay_ms - }; - acpi_device_add_power_res(&power_res_params); - } - - acpigen_pop_len(); /* Device */ - acpigen_pop_len(); /* Scope */ - - printk(BIOS_INFO, "%s: %s at %s\n", path, - config->desc ? : dev->chip_ops->name, dev_path(dev)); -} - -static const char *spi_acpi_name(const struct device *dev) -{ - struct drivers_spi_acpi_config *config = dev->chip_info; - static char name[5]; - - if (config->name) - return config->name; - - snprintf(name, sizeof(name), "S%03.3X", spi_acpi_get_bus(dev)); - name[4] = '\0'; - return name; -} +#include <security/tpm/acpi.h>
static struct device_operations spi_acpi_ops = { .read_resources = DEVICE_NOOP, .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, - .acpi_name = &spi_acpi_name, - .acpi_fill_ssdt_generator = &spi_acpi_fill_ssdt_generator, + .acpi_name = &tpm_acpi_name, + .acpi_fill_ssdt_generator = &tpm_ssdt_generator, };
static void spi_acpi_enable(struct device *dev) diff --git a/src/security/tpm/Makefile.inc b/src/security/tpm/Makefile.inc index 34ead8f..cf65aa2 100644 --- a/src/security/tpm/Makefile.inc +++ b/src/security/tpm/Makefile.inc @@ -18,6 +18,8 @@ verstage-$(CONFIG_VBOOT) += tspi/tspi.c tspi/log.c postcar-$(CONFIG_VBOOT) += tspi/tspi.c tspi/log.c
+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi/acpi.c + endif # CONFIG_TPM1
ifeq ($(CONFIG_TPM2),y) @@ -42,4 +44,6 @@ verstage-$(CONFIG_VBOOT) += tspi/tspi.c tspi/log.c postcar-$(CONFIG_VBOOT) += tspi/tspi.c tspi/log.c
+ramstage-$(CONFIG_HAVE_ACPI_TABLES) += acpi/acpi.c + endif # CONFIG_TPM2