Rob Barnes has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/58870 )
Change subject: soc/amd/psp_verstage: Init TPM on S0i3 resume ......................................................................
soc/amd/psp_verstage: Init TPM on S0i3 resume
Add option to initialize the TPM in PSP verstage during s0i3 resume. This is needed if the TPM is reset in s0i3. The PSP is handling restoring everything else, so only the minimum TPM initialize is done.
BUG=b:200578885 TEST=Multiple cycles of S0i3 suspend resume BRANCH=None
Change-Id: Ie511928da6a8b4be62621fd2c4c31a8d1e724d48 Signed-off-by: Rob Barnes robbarnes@google.com --- M src/soc/amd/cezanne/Kconfig M src/soc/amd/common/psp_verstage/include/psp_verstage.h M src/soc/amd/common/psp_verstage/psp_verstage.c M src/vendorcode/google/chromeos/Kconfig 4 files changed, 63 insertions(+), 1 deletion(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/70/58870/1
diff --git a/src/soc/amd/cezanne/Kconfig b/src/soc/amd/cezanne/Kconfig index 46e6017..c3eef3f 100644 --- a/src/soc/amd/cezanne/Kconfig +++ b/src/soc/amd/cezanne/Kconfig @@ -389,6 +389,15 @@ help Add psp_verstage signature token to the build & PSP Directory Table
+config PSP_INIT_TPM_ON_S0I3_RESUME + bool + default y + depends on TPM2 && VBOOT_STARTS_BEFORE_BOOTBLOCK + help + If the TPM is reset while in S0i3, it must be restored during s0i3 + resume. This must be performed in PSP verstage since coreboot is + otherwise not involved with s0i3 resume. + endmenu
config VBOOT 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 be6b23d..6f240ee 100644 --- a/src/soc/amd/common/psp_verstage/include/psp_verstage.h +++ b/src/soc/amd/common/psp_verstage/include/psp_verstage.h @@ -23,6 +23,8 @@ #define POSTCODE_SAVE_BUFFERS 0x0E #define POSTCODE_UPDATE_BOOT_REGION 0x0F
+#define POSTCODE_VERSTAGE_S0I3_RESUME 0x10 + #define POSTCODE_DEFAULT_BUFFER_SIZE_NOTICE 0xC0 #define POSTCODE_WORKBUF_RESIZE_WARNING 0xC1 #define POSTCODE_WORKBUF_SAVE_ERROR 0xC2 @@ -34,6 +36,7 @@ #define POSTCODE_FMAP_REGION_MISSING 0xC8 #define POSTCODE_AMD_FW_MISSING 0xC9 #define POSTCODE_CMOS_RECOVERY 0xCA +#define POSTCODE_INIT_TPM_FAILED 0xCB
#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 5c59c4f..1b4ab52 100644 --- a/src/soc/amd/common/psp_verstage/psp_verstage.c +++ b/src/soc/amd/common/psp_verstage/psp_verstage.c @@ -5,14 +5,18 @@ #include <amdblocks/acpimmio.h> #include <bl_uapp/bl_syscall_public.h> #include <boot_device.h> +#include <bootstate.h> #include <cbfs.h> #include <console/console.h> #include <fmap.h> #include <pc80/mc146818rtc.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> +#include <security/vboot/tpm_common.h> #include <security/vboot/vboot_common.h> #include <arch/stages.h> #include <stdarg.h> @@ -196,10 +200,44 @@ return 0; }
+/** + * S0i3 resume in PSP verstage is a special case. The PSP is restoring + * everything except the TPM. So do the minimum needed to re-initialize the TPM. + */ +static uint32_t psp_verstage_s0i3_resume(void) +{ + uint32_t rv = 0; + + post_code(POSTCODE_VERSTAGE_S0I3_RESUME); + + if (!CONFIG(PSP_INIT_TPM_ON_S0I3_RESUME)) + return rv; + + printk(BIOS_DEBUG, "Entering PSP verstage S0i3 resume\n"); + + rv = tpm_setup(true); + if (rv != TPM_SUCCESS) { + printk(BIOS_ERR, "tpm_setup failed rv:%d\n", rv); + return POSTCODE_INIT_TPM_FAILED; + } + + if (CONFIG(CHROMEOS_DISABLE_PLATFORM_HIERARCHY_ON_RESUME)) { + rv = tlcl_disable_platform_hierarchy(); + if (rv != TPM_SUCCESS) { + printk(BIOS_ERR, "tlcl_disable_platform_hierarchy failed rv:%d\n", rv); + return POSTCODE_INIT_TPM_FAILED; + } + } + + return rv; +} + void Main(void) { uint32_t retval; struct vb2_context *ctx = NULL; + uint32_t bootmode; +
/* * Do not use printk() before console_init() @@ -230,6 +268,18 @@
post_code(POSTCODE_VERSTAGE_MAIN);
+ svc_get_boot_mode(&bootmode); + + /* S0i3 resume in PSP verstage is a special case. */ + if (bootmode == PSP_BOOT_MODE_S0i3_RESUME) { + retval = psp_verstage_s0i3_resume(); + if(retval) + reboot_into_recovery(ctx, retval); + post_code(POSTCODE_UNMAP_FCH_DEVICES); + unmap_fch_devices(); + svc_exit(retval); + } + vboot_run_logic();
ctx = vboot_get_context(); diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig index 605b09e..3f2d6a1 100644 --- a/src/vendorcode/google/chromeos/Kconfig +++ b/src/vendorcode/google/chromeos/Kconfig @@ -44,7 +44,7 @@ config CHROMEOS_DISABLE_PLATFORM_HIERARCHY_ON_RESUME bool default y - depends on TPM2 && RESUME_PATH_SAME_AS_BOOT + depends on TPM2 help Disable the platform heirarchy on resume path if the firmware is involved in resume. The hierarchy is disabled prior to jumping