security/tpm: Add a Kconfig to disregard INVALID_POSTINIT on startup

There are use cases where TPM has already been set up in a previous
stage, e.g. TXT or when a CPU reset without a platform reset happens.
If this is the case the TPM startup will return a
INVALID_POSTINIT (return code 0x26). This adds a Kconfig to allow
platforms to disregard that return code.

Change-Id: I238b30866f78608c414de877b05a73cf8fdb9bbd
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/36027
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Julius Werner <jwerner@chromium.org>
diff --git a/src/security/tpm/Kconfig b/src/security/tpm/Kconfig
index 3af6d69..95c0bb9 100644
--- a/src/security/tpm/Kconfig
+++ b/src/security/tpm/Kconfig
@@ -93,4 +93,13 @@
 	  to work around a race-condition-related issue, possibly
 	  caused by ill-programmed TPM firmware.
 
+config TPM_STARTUP_IGNORE_POSTINIT
+	bool
+	help
+	  Select this to ignore POSTINIT INVALID return codes on TPM
+	  startup. This is useful on platforms where a previous stage
+	  issued a TPM startup. Examples of use cases are Intel TXT
+	  or VBOOT on the Intel Nehalem northbridge which issues a
+	  CPU-only reset during the romstage.
+
 endmenu # Trusted Platform Module (tpm)
diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c
index 4698a4d..966b8b7 100644
--- a/src/security/tpm/tspi/tspi.c
+++ b/src/security/tpm/tspi/tspi.c
@@ -141,6 +141,11 @@
 	}
 
 	result = tlcl_startup();
+	if (CONFIG(TPM_STARTUP_IGNORE_POSTINIT)
+	    && result == TPM_E_INVALID_POSTINIT) {
+		printk(BIOS_DEBUG, "TPM: ignoring invalid POSTINIT\n");
+		result = TPM_SUCCESS;
+	}
 	if (result != TPM_SUCCESS) {
 		printk(BIOS_ERR, "TPM: Can't run startup command.\n");
 		return tpm_setup_epilogue(result);