soc/amd/common/psp_verstage: Report previous boot status

Add support to report previous PSP boot failure to verified boot. This
is required specifically on mainboards where the signed AMDFW blobs are
excluded from vboot verification.

BUG=b:242825052
TEST=Build Skyrim BIOS image and boot to OS in Skyrim. Corrupt either
one of SIGNED_AMDFW_A/B sections or both the sections to ensure that the
appropriate FW slot is chosen.

Cq-Depend: chromium:4064425
Change-Id: Iada0ec7c373db75765ba42cb531b16c2236b6cc3
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/70382
Reviewed-by: Yu-Ping Wu <yupingso@google.com>
Reviewed-by: Raul Rangel <rrangel@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/soc/amd/common/psp_verstage/psp_verstage.c b/src/soc/amd/common/psp_verstage/psp_verstage.c
index 4e28324..969c1c0 100644
--- a/src/soc/amd/common/psp_verstage/psp_verstage.c
+++ b/src/soc/amd/common/psp_verstage/psp_verstage.c
@@ -3,6 +3,7 @@
 #include "psp_verstage.h"
 
 #include <amdblocks/acpimmio.h>
+#include <bl_uapp/bl_errorcodes_public.h>
 #include <bl_uapp/bl_syscall_public.h>
 #include <boot_device.h>
 #include <cbfs.h>
@@ -136,6 +137,25 @@
 	return 0;
 }
 
+static void report_prev_boot_status_to_vboot(void)
+{
+	uint32_t boot_status = 0;
+	int ret;
+	struct vb2_context *ctx = vboot_get_context();
+
+	/* Already in recovery mode. No need to report previous boot status. */
+	if (ctx->flags & VB2_CONTEXT_RECOVERY_MODE)
+		return;
+
+	ret = svc_get_prev_boot_status(&boot_status);
+	if (ret != BL_OK || boot_status) {
+		printk(BIOS_ERR, "PSPFW failure in previous boot: %d:%#8x\n", ret, boot_status);
+		vbnv_init();
+		vb2api_previous_boot_fail(ctx, VB2_RECOVERY_FW_VENDOR_BLOB,
+					  boot_status ? (int)boot_status : ret);
+	}
+}
+
 /*
  * Save workbuf (and soon memory console and timestamps) to the bootloader to pass
  * back to coreboot.
@@ -288,6 +308,8 @@
 	verstage_mainboard_init();
 
 	post_code(POSTCODE_VERSTAGE_MAIN);
+	if (CONFIG(SEPARATE_SIGNED_PSPFW))
+		report_prev_boot_status_to_vboot();
 
 	vboot_run_logic();