summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/amd/common/psp_verstage/Kconfig9
-rw-r--r--src/soc/amd/common/psp_verstage/include/psp_verstage.h3
-rw-r--r--src/soc/amd/common/psp_verstage/psp_verstage.c56
3 files changed, 62 insertions, 6 deletions
diff --git a/src/soc/amd/common/psp_verstage/Kconfig b/src/soc/amd/common/psp_verstage/Kconfig
index 834abaaa5f..6cac8b70ed 100644
--- a/src/soc/amd/common/psp_verstage/Kconfig
+++ b/src/soc/amd/common/psp_verstage/Kconfig
@@ -5,3 +5,12 @@ config PSP_VERSTAGE_CCP_DMA
Configure PSP Verstage to use Crypto Co-processor (CCP) DMA while
accessing the boot device. Select it on platforms which supports
using CCP DMA to access the boot device.
+
+config PSP_INIT_TPM_ON_S0I3_RESUME
+ bool
+ depends on TPM2 && VBOOT_STARTS_BEFORE_BOOTBLOCK
+ default VBOOT_STARTS_BEFORE_BOOTBLOCK
+ help
+ If the TPM is reset while in S0i3, it must be reinitialized
+ during s0i3 resume. This must be performed in PSP verstage since
+ coreboot is otherwise not involved with s0i3 resume.
diff --git a/src/soc/amd/common/psp_verstage/include/psp_verstage.h b/src/soc/amd/common/psp_verstage/include/psp_verstage.h
index ef8a9da951..606b6a69cd 100644
--- a/src/soc/amd/common/psp_verstage/include/psp_verstage.h
+++ b/src/soc/amd/common/psp_verstage/include/psp_verstage.h
@@ -20,6 +20,7 @@
#define POSTCODE_EARLY_INIT 0x02
#define POSTCODE_LATE_INIT 0x03
#define POSTCODE_VERSTAGE_MAIN 0x04
+#define POSTCODE_VERSTAGE_S0I3_RESUME 0x05
#define POSTCODE_SAVE_BUFFERS 0x0E
#define POSTCODE_UPDATE_BOOT_REGION 0x0F
@@ -36,6 +37,8 @@
#define POSTCODE_AMD_FW_MISSING 0xC9
#define POSTCODE_CMOS_RECOVERY 0xCA
#define POSTCODE_EARLY_INIT_ERROR 0xCB
+#define POSTCODE_INIT_TPM_FAILED 0xCC
+
#define POSTCODE_UNMAP_SPI_ROM 0xF0
#define POSTCODE_UNMAP_FCH_DEVICES 0xF1
diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c
index 71f07c0417..2e3d09d3a2 100644
--- a/src/soc/amd/common/psp_verstage/psp_verstage.c
+++ b/src/soc/amd/common/psp_verstage/psp_verstage.c
@@ -12,6 +12,8 @@
#include <pc80/mc146818rtc.h>
#include <soc/iomap.h>
#include <soc/psp_transfer.h>
+#include <security/tpm/tspi.h>
+#include <security/tpm/tss.h>
#include <security/vboot/vbnv.h>
#include <security/vboot/misc.h>
#include <security/vboot/symbols.h>
@@ -206,11 +208,42 @@ static uint32_t save_buffers(struct vb2_context **ctx)
return 0;
}
+/*
+ * S0i3 resume in PSP verstage is a special case. The FSDL is restoring mostly
+ * everything, so do the minimum necessary here. Unlike normal boot, subsequent
+ * coreboot stages are not run after s0i3 verstage.
+ * If the TPM is reset in S0i3, it must be re-initialized here.
+ */
+static void psp_verstage_s0i3_resume(void)
+{
+ uint32_t rv;
+
+ post_code(POSTCODE_VERSTAGE_S0I3_RESUME);
+
+ printk(BIOS_DEBUG, "Entering PSP verstage S0i3 resume\n");
+
+ if (!CONFIG(PSP_INIT_TPM_ON_S0I3_RESUME))
+ return;
+
+ rv = tpm_setup(true);
+ if (rv != TPM_SUCCESS) {
+ printk(BIOS_ERR, "tpm_setup failed rv:%d\n", rv);
+ reboot_into_recovery(vboot_get_context(), POSTCODE_INIT_TPM_FAILED);
+ }
+
+ rv = tlcl_disable_platform_hierarchy();
+ if (rv != TPM_SUCCESS) {
+ printk(BIOS_ERR, "tlcl_disable_platform_hierarchy failed rv:%d\n", rv);
+ reboot_into_recovery(vboot_get_context(), POSTCODE_INIT_TPM_FAILED);
+ }
+}
+
void Main(void)
{
uint32_t retval;
struct vb2_context *ctx = NULL;
void *boot_dev_base;
+ uint32_t bootmode;
/*
* Do not use printk() before console_init()
@@ -247,18 +280,29 @@ void Main(void)
/* mainboard_tpm_init may check board_id, so make sure espi is ready first */
verstage_mainboard_tpm_init();
- printk(BIOS_DEBUG, "calling verstage_mainboard_early_init\n");
- verstage_mainboard_early_init();
-
- svc_write_postcode(POSTCODE_LATE_INIT);
- fch_io_enable_legacy_io();
-
printk(BIOS_DEBUG, "calling verstage_soc_aoac_init\n");
verstage_soc_aoac_init();
printk(BIOS_DEBUG, "calling verstage_soc_i2c_init\n");
verstage_soc_i2c_init();
+ /*
+ * S0i3 resume in PSP verstage is a special case, handle it separately.
+ * Make sure TPM i2c is ready first.
+ */
+ svc_get_boot_mode(&bootmode);
+ if (bootmode == PSP_BOOT_MODE_S0i3_RESUME) {
+ psp_verstage_s0i3_resume();
+ unmap_fch_devices();
+ svc_exit(0);
+ }
+
+ printk(BIOS_DEBUG, "calling verstage_mainboard_early_init\n");
+ verstage_mainboard_early_init();
+
+ svc_write_postcode(POSTCODE_LATE_INIT);
+ fch_io_enable_legacy_io();
+
printk(BIOS_DEBUG, "calling verstage_soc_spi_init\n");
verstage_soc_spi_init();