diff options
-rw-r--r-- | src/soc/amd/picasso/Kconfig | 12 | ||||
-rw-r--r-- | src/soc/amd/picasso/Makefile.inc | 1 | ||||
-rw-r--r-- | src/soc/amd/picasso/bootblock/bootblock.c | 9 | ||||
-rw-r--r-- | src/soc/amd/picasso/include/soc/psp_transfer.h | 8 | ||||
-rw-r--r-- | src/soc/amd/picasso/psp_verstage/psp_verstage.c | 22 | ||||
-rw-r--r-- | src/soc/amd/picasso/psp_verstage/psp_verstage.h | 1 |
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 |