Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/36027 )
Change subject: nb/intel/nehalem: Add a VBOOT TPM init workaround ......................................................................
nb/intel/nehalem: Add a VBOOT TPM init workaround
nb/intel/nehalem needs to issue a CPU reset during the raminit. On this reset the platform is not reset however, which includes the TPM. To avoid initializing the TPM twice add an function to inform VBOOT to skip the TPM initialization.
Change-Id: I238b30866f78608c414de877b05a73cf8fdb9bbd Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/northbridge/intel/nehalem/Kconfig M src/northbridge/intel/nehalem/Makefile.inc M src/northbridge/intel/nehalem/raminit.c A src/northbridge/intel/nehalem/vboot_quirk.c M src/security/vboot/Kconfig M src/security/vboot/tpm_common.c M src/security/vboot/tpm_common.h 7 files changed, 49 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/27/36027/1
diff --git a/src/northbridge/intel/nehalem/Kconfig b/src/northbridge/intel/nehalem/Kconfig index a88d4c9..6afcbc5 100644 --- a/src/northbridge/intel/nehalem/Kconfig +++ b/src/northbridge/intel/nehalem/Kconfig @@ -29,6 +29,7 @@ select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_SEPARATE_VERSTAGE + select VBOOT_ROMSTAGE_CPU_RESET_QUIRK_WORKAROUND
config MMCONF_BUS_NUMBER int diff --git a/src/northbridge/intel/nehalem/Makefile.inc b/src/northbridge/intel/nehalem/Makefile.inc index 225f0ce..eef49e2 100644 --- a/src/northbridge/intel/nehalem/Makefile.inc +++ b/src/northbridge/intel/nehalem/Makefile.inc @@ -17,6 +17,8 @@
bootblock-y += bootblock.c
+verstage-y += vboot_quirk.c + ramstage-y += memmap.c ramstage-y += northbridge.c ramstage-y += smi.c diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index b9d407a..8f4eee5 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -4241,6 +4241,7 @@ if (x2ca8 == 0) { MCHBAR8_AND(0x2ca8, ~3); MCHBAR8(0x2ca8) = MCHBAR8(0x2ca8) + 4; // "+" or "|"? + /* This issues a CPU reset without resetting the platform */ MCHBAR32_OR(0x1af0, 0x10); halt(); } diff --git a/src/northbridge/intel/nehalem/vboot_quirk.c b/src/northbridge/intel/nehalem/vboot_quirk.c new file mode 100644 index 0000000..aa04916 --- /dev/null +++ b/src/northbridge/intel/nehalem/vboot_quirk.c @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * 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 <security/vboot/tpm_common.h> +#include "nehalem.h" + +/* + * The raminit needs to issue a CPU reset. On this reset the platform is not + * reset however, which includes the TPM. To avoid initializing the TPM twice + * this informs VBOOT to skip the TPM initialization. The raminit uses the + * MCHBAR8(0x2ca8) sticky scratchpad register to keep track if it's on the first + * or second boot. + */ +int cpu_was_reset(void) +{ + if (MCHBAR16(0x2ca8) != 0) + return 1; + return 0; +} diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig index d6d74ca..cf15d86 100644 --- a/src/security/vboot/Kconfig +++ b/src/security/vboot/Kconfig @@ -139,6 +139,13 @@ or the romstage and runs as part of that stage (cf. related options VBOOT_STARTS_IN_BOOTBLOCK/_ROMSTAGE and VBOOT_RETURN_FROM_VERSTAGE).
+config VBOOT_ROMSTAGE_CPU_RESET_QUIRK_WORKAROUND + bool + help + Some platforms need to reset the CPU, but not the platform as part of + their initialization. The result is that the TPM is already initialized + when VBOOT runs the second time. Select this to workaround this. + config VBOOT_RETURN_FROM_VERSTAGE bool default n diff --git a/src/security/vboot/tpm_common.c b/src/security/vboot/tpm_common.c index 0a211c5..232aea3 100644 --- a/src/security/vboot/tpm_common.c +++ b/src/security/vboot/tpm_common.c @@ -23,6 +23,10 @@ { uint32_t result;
+ if (CONFIG(VBOOT_ROMSTAGE_CPU_RESET_QUIRK_WORKAROUND)) + if (cpu_was_reset()) + return TPM_SUCCESS; + result = tpm_setup(ctx->flags & VB2_CONTEXT_S3_RESUME); if (result == TPM_E_MUST_REBOOT) ctx->flags |= VB2_CONTEXT_SECDATA_WANTS_REBOOT; diff --git a/src/security/vboot/tpm_common.h b/src/security/vboot/tpm_common.h index e1faa0c..e913c78 100644 --- a/src/security/vboot/tpm_common.h +++ b/src/security/vboot/tpm_common.h @@ -13,6 +13,9 @@
#if CONFIG(TPM1) || CONFIG(TPM2)
+#include <stdint.h> +#include <vb2_api.h> + /* Start of the root of trust */ uint32_t vboot_setup_tpm(struct vb2_context *ctx);
@@ -20,6 +23,8 @@ vb2_error_t vboot_extend_pcr(struct vb2_context *ctx, int pcr, enum vb2_pcr_digest which_digest);
+int cpu_was_reset(void); + #else
#define vboot_setup_tpm(ctx) 0