[coreboot-gerrit] Change in coreboot[master]: security/tpm: Add generalized ACPI table generation

Philipp Deppenwiese (Code Review) gerrit at coreboot.org
Fri Oct 19 14:21:06 CEST 2018


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 at 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

-- 
To view, visit https://review.coreboot.org/29194
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2afdf4872566353284ab7734205a3bea738a6e0e
Gerrit-Change-Number: 29194
Gerrit-PatchSet: 1
Gerrit-Owner: Philipp Deppenwiese <zaolin.daisuki at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20181019/f70226cd/attachment-0001.html>


More information about the coreboot-gerrit mailing list