aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/amd/picasso/Kconfig12
-rw-r--r--src/soc/amd/picasso/Makefile.inc1
-rw-r--r--src/soc/amd/picasso/bootblock/bootblock.c9
-rw-r--r--src/soc/amd/picasso/include/soc/psp_transfer.h8
-rw-r--r--src/soc/amd/picasso/psp_verstage/psp_verstage.c22
-rw-r--r--src/soc/amd/picasso/psp_verstage/psp_verstage.h1
6 files changed, 51 insertions, 2 deletions
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig
index 1b83000d32..642935ffef 100644
--- a/src/soc/amd/picasso/Kconfig
+++ b/src/soc/amd/picasso/Kconfig
@@ -505,6 +505,18 @@ config VBOOT_STARTS_BEFORE_BOOTBLOCK
Runs verstage on the PSP. Only available on
certain Chrome OS branded parts from AMD.
+config CMOS_RECOVERY_BYTE
+ hex
+ default 0x51
+ depends on VBOOT_STARTS_BEFORE_BOOTBLOCK
+ help
+ If the workbuf is not passed from the PSP to coreboot, set the
+ recovery flag and reboot. The PSP will read this byte, mark the
+ recovery request in VBNV, and reset the system into recovery mode.
+
+ This is the byte before the default first byte used by VBNV
+ (0x26 + 0x0E - 1)
+
if VBOOT_SLOTS_RW_AB && VBOOT_STARTS_BEFORE_BOOTBLOCK
config RWA_REGION_ONLY
diff --git a/src/soc/amd/picasso/Makefile.inc b/src/soc/amd/picasso/Makefile.inc
index f11d895144..c12b1af5d0 100644
--- a/src/soc/amd/picasso/Makefile.inc
+++ b/src/soc/amd/picasso/Makefile.inc
@@ -22,6 +22,7 @@ bootblock-y += tsc_freq.c
bootblock-y += gpio.c
bootblock-y += smi_util.c
bootblock-y += config.c
+bootblock-y += reset.c
romstage-y += i2c.c
romstage-y += romstage.c
diff --git a/src/soc/amd/picasso/bootblock/bootblock.c b/src/soc/amd/picasso/bootblock/bootblock.c
index 556fbad5fc..470002789f 100644
--- a/src/soc/amd/picasso/bootblock/bootblock.c
+++ b/src/soc/amd/picasso/bootblock/bootblock.c
@@ -2,6 +2,7 @@
#include <stdint.h>
#include <symbols.h>
+#include <amdblocks/reset.h>
#include <bootblock_common.h>
#include <console/console.h>
#include <cpu/x86/cache.h>
@@ -9,6 +10,8 @@
#include <cpu/amd/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/amd/mtrr.h>
+#include <pc80/mc146818rtc.h>
+#include <soc/psp_transfer.h>
#include <soc/southbridge.h>
#include <soc/i2c.h>
#include <amdblocks/amd_pci_mmconf.h>
@@ -135,7 +138,11 @@ void bootblock_soc_init(void)
printk(BIOS_DEBUG, "Signature: %#08x\n", *(uint32_t *)_vboot2_work);
- die("Halting.\n");
+ cmos_init(0);
+ cmos_write(CMOS_RECOVERY_MAGIC_VAL, CMOS_RECOVERY_BYTE);
+ warm_reset();
+ } else {
+ cmos_write(0x00, CMOS_RECOVERY_BYTE);
}
#endif
diff --git a/src/soc/amd/picasso/include/soc/psp_transfer.h b/src/soc/amd/picasso/include/soc/psp_transfer.h
index 6a43b55a6c..0996f64d58 100644
--- a/src/soc/amd/picasso/include/soc/psp_transfer.h
+++ b/src/soc/amd/picasso/include/soc/psp_transfer.h
@@ -3,6 +3,14 @@
#ifndef PSP_VERSTAGE_PSP_TRANSFER_H
#define PSP_VERSTAGE_PSP_TRANSFER_H
+# if (CONFIG_CMOS_RECOVERY_BYTE != 0)
+# define CMOS_RECOVERY_BYTE CONFIG_CMOS_RECOVERY_BYTE
+# elif CONFIG(VBOOT_STARTS_BEFORE_BOOTBLOCK)
+# error "Must set CONFIG_CMOS_RECOVERY_BYTE"
+# endif
+
+#define CMOS_RECOVERY_MAGIC_VAL 0x96
+
#define TRANSFER_INFO_SIZE 64
#define TIMESTAMP_BUFFER_SIZE 0x200
diff --git a/src/soc/amd/picasso/psp_verstage/psp_verstage.c b/src/soc/amd/picasso/psp_verstage/psp_verstage.c
index 55687976df..005c8b0ac9 100644
--- a/src/soc/amd/picasso/psp_verstage/psp_verstage.c
+++ b/src/soc/amd/picasso/psp_verstage/psp_verstage.c
@@ -5,10 +5,11 @@
#include <bl_uapp/bl_syscall_public.h>
#include <boot_device.h>
#include <cbfs.h>
-#include <commonlib/region.h>
#include <console/console.h>
#include <fmap.h>
+#include <pc80/mc146818rtc.h>
#include <soc/psp_transfer.h>
+#include <security/vboot/vbnv.h>
#include <security/vboot/misc.h>
#include <security/vboot/symbols.h>
#include <security/vboot/vboot_common.h>
@@ -35,6 +36,22 @@ static void reboot_into_recovery(struct vb2_context *ctx, uint32_t subcode)
vboot_reboot();
}
+static uint32_t check_cmos_recovery(void)
+{
+ /* Only reset if cmos is valid */
+ if (vbnv_cmos_failed())
+ return 0;
+
+ /* If the byte is set, clear it, then return error to reboot */
+ if (cmos_read(CMOS_RECOVERY_BYTE) == CMOS_RECOVERY_MAGIC_VAL) {
+ cmos_write(0x00, CMOS_RECOVERY_BYTE);
+ printk(BIOS_DEBUG, "Reboot into recovery requested by coreboot\n");
+ return POSTCODE_CMOS_RECOVERY;
+ }
+
+ return 0;
+}
+
static uintptr_t locate_amdfw(const char *name, struct region_device *rdev)
{
struct cbfsf fh;
@@ -216,6 +233,9 @@ void Main(void)
vb2api_relocate(_vboot2_work, _vboot2_work, VB2_FIRMWARE_WORKBUF_RECOMMENDED_SIZE,
&ctx);
+ retval = check_cmos_recovery();
+ if (retval)
+ goto err;
post_code(POSTCODE_SAVE_BUFFERS);
retval = save_buffers(&ctx);
diff --git a/src/soc/amd/picasso/psp_verstage/psp_verstage.h b/src/soc/amd/picasso/psp_verstage/psp_verstage.h
index 3c7574d82b..ef5c452500 100644
--- a/src/soc/amd/picasso/psp_verstage/psp_verstage.h
+++ b/src/soc/amd/picasso/psp_verstage/psp_verstage.h
@@ -31,6 +31,7 @@
#define POSTCODE_UPDATE_PSP_BIOS_DIR_ERROR 0xC7
#define POSTCODE_FMAP_REGION_MISSING 0xC8
#define POSTCODE_AMD_FW_MISSING 0xC9
+#define POSTCODE_CMOS_RECOVERY 0xCA
#define POSTCODE_UNMAP_SPI_ROM 0xF0
#define POSTCODE_UNMAP_FCH_DEVICES 0xF1