Edward O'Callaghan has submitted this change. ( https://review.coreboot.org/c/coreboot/+/44646 )
Change subject: vendorcode/google/chromeos: Introduce helper for CSE board reset ......................................................................
vendorcode/google/chromeos: Introduce helper for CSE board reset
When CSE Lite jumps from RO to RW, certain boards need to request Embedded Controller (EC) to trigger cold reset of SoC. This change introduces a helper to override the default global reset.
BUG=None TEST=Ensure that Drawcia board boots to OS. Ensure that global reset is triggered when cr50 is running firmware versions newer than 0.0.22. On cr50 versions 0.0.22 or older, EC triggers cold reset of AP.
Change-Id: I8078e2436d1d58a650bf7b0cf38b5bb89a474187 Signed-off-by: Karthikeyan Ramasubramanian kramasub@google.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/44646 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Tim Wawrzynczak twawrzynczak@chromium.org Reviewed-by: Furquan Shaikh furquan@google.com Reviewed-by: Nick Vaccaro nvaccaro@google.com Reviewed-by: Edward O'Callaghan quasisec@chromium.org --- M src/vendorcode/google/chromeos/Kconfig M src/vendorcode/google/chromeos/Makefile.inc A src/vendorcode/google/chromeos/cse_board_reset.c 3 files changed, 50 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Furquan Shaikh: Looks good to me, approved Nick Vaccaro: Looks good to me, approved Tim Wawrzynczak: Looks good to me, approved Edward O'Callaghan: Looks good to me, approved
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig index f48069f..0528d00 100644 --- a/src/vendorcode/google/chromeos/Kconfig +++ b/src/vendorcode/google/chromeos/Kconfig @@ -92,5 +92,16 @@ 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 a25700f..b429d6b 100644 --- a/src/vendorcode/google/chromeos/Makefile.inc +++ b/src/vendorcode/google/chromeos/Makefile.inc @@ -10,6 +10,7 @@ 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 0000000..6034f0d --- /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(); +}