summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/vendorcode/google/chromeos/Kconfig11
-rw-r--r--src/vendorcode/google/chromeos/Makefile.inc1
-rw-r--r--src/vendorcode/google/chromeos/cse_board_reset.c38
3 files changed, 50 insertions, 0 deletions
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index f48069ff86..0528d00fea 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -92,5 +92,16 @@ config CHROMEOS_DSM_CALIB
to ACPI DSD table in device driver. These parameters will be applied by kernel driver
through device property at boot.
+config CHROMEOS_CSE_BOARD_RESET_OVERRIDE
+ bool
+ default n
+ depends on SOC_INTEL_CSE_LITE_SKU
+ help
+ On some boards that run old firmware version in cr50, Embedded Controller (EC) needs
+ to trigger the cold reset of Application Processor (AP) when CSE jumps from RO to RW
+ so that cr50 resets the TPM state. This is required on boards where the cr50 firmware
+ does not understand the new cr50 strap config (applicable only to boards using strap
+ config 0xe). Enabling this config will help to override the default global reset.
+
endif # CHROMEOS
endmenu
diff --git a/src/vendorcode/google/chromeos/Makefile.inc b/src/vendorcode/google/chromeos/Makefile.inc
index a25700f8bb..b429d6b14a 100644
--- a/src/vendorcode/google/chromeos/Makefile.inc
+++ b/src/vendorcode/google/chromeos/Makefile.inc
@@ -10,6 +10,7 @@ ramstage-$(CONFIG_HAVE_REGULATORY_DOMAIN) += wrdd.c
ramstage-$(CONFIG_USE_SAR) += sar.c
ramstage-$(CONFIG_CHROMEOS_DSM_CALIB) += dsm_calib.c
ramstage-$(CONFIG_TPM_CR50) += cr50_enable_update.c
+ramstage-$(CONFIG_CHROMEOS_CSE_BOARD_RESET_OVERRIDE) += cse_board_reset.c
bootblock-y += watchdog.c
verstage-y += watchdog.c
diff --git a/src/vendorcode/google/chromeos/cse_board_reset.c b/src/vendorcode/google/chromeos/cse_board_reset.c
new file mode 100644
index 0000000000..6034f0d14c
--- /dev/null
+++ b/src/vendorcode/google/chromeos/cse_board_reset.c
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <arch/cache.h>
+#include <arch/io.h>
+#include <cf9_reset.h>
+#include <console/console.h>
+#include <drivers/spi/tpm/tpm.h>
+#include <ec/google/chromeec/ec.h>
+#include <halt.h>
+#include <intelblocks/cse.h>
+#include <security/tpm/tss.h>
+
+void cse_board_reset(void)
+{
+ struct cr50_firmware_version version;
+
+ /* Initialize TPM and get the cr50 firmware version. */
+ tlcl_lib_init();
+ cr50_get_firmware_version(&version);
+ /*
+ * Cr50 firmware versions 0.[3|4].20 or newer support strap config 0xe where PLTRST from
+ * AP is connected to cr50's PLTRST# signal. So return immediately and trigger a
+ * global reset.
+ */
+ if (version.epoch != 0 || version.major > 4 ||
+ (version.major >= 3 && version.minor >= 20))
+ return;
+
+ printk(BIOS_INFO, "Initiating request to EC to trigger cold reset\n");
+ /*
+ * Clean the data cache and set the full reset bit, so that when EC toggles
+ * SYS_RESET# pin, AP makes a trip to S5 and then to S0.
+ */
+ dcache_clean_all();
+ outb(FULL_RST, RST_CNT);
+ if (!google_chromeec_ap_reset())
+ halt();
+}