diff options
-rw-r--r-- | src/device/root_device.c | 2 | ||||
-rw-r--r-- | src/include/reset.h | 38 | ||||
-rw-r--r-- | src/lib/Kconfig | 7 | ||||
-rw-r--r-- | src/lib/prog_loaders.c | 3 | ||||
-rw-r--r-- | src/lib/reset.c | 24 | ||||
-rw-r--r-- | src/security/vboot/Kconfig | 2 | ||||
-rw-r--r-- | src/security/vboot/vboot_common.c | 3 | ||||
-rw-r--r-- | src/vendorcode/google/chromeos/watchdog.c | 2 |
8 files changed, 73 insertions, 8 deletions
diff --git a/src/device/root_device.c b/src/device/root_device.c index b0b6712ebb..e006bf9137 100644 --- a/src/device/root_device.c +++ b/src/device/root_device.c @@ -147,7 +147,7 @@ static void root_dev_scan_bus(struct device *bus) static void root_dev_reset(struct bus *bus) { printk(BIOS_INFO, "Resetting board...\n"); - hard_reset(); + board_reset(); } #if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES) diff --git a/src/include/reset.h b/src/include/reset.h index cf9d5744b2..fe6328d2d9 100644 --- a/src/include/reset.h +++ b/src/include/reset.h @@ -1,7 +1,43 @@ #ifndef RESET_H #define RESET_H -/* Generic reset functions. Call from code that wants to trigger a reset. */ +/* + * Generic board reset function. Call from common code that + * wants to trigger a reset. + */ +__noreturn void board_reset(void); +/* + * SoC or board specific implementation of the board reset. + * + * Implementations shall meet the following criteria: + * + * o For vboot support, the TPM MUST be reset. + * + * o All SoC/chipset blocks SHOULD be reset except for those + * that are intentionally meant to survive reset (e.g. tomb- + * stone registers and that sort of stuff). + * + * o All external SoC pins SHOULD return to power-on reset values. + * + * o The CPU MUST resume execution from power-on reset vector + * (same as cold boot). + * + * o Other board components (e.g. PCI, SDIO and stuff) SHOULD + * be reset. + * + * o USB SHOULD be power-cycled. + * + * o Board components that are intended to be fully independent + * from SoC (e.g. EC and EC-attached devices, the Cr50 on + * Chromebooks) SHOULD NOT be reset. + * + * General recommendations: + * + * o DRAM SHOULD NOT lose power if possible. + * + * o Reset time SHOULD be minimized + */ +void do_board_reset(void); /* Super-hard reset specific to some Intel SoCs. */ __noreturn void global_reset(void); diff --git a/src/lib/Kconfig b/src/lib/Kconfig index eb4c16eb51..2f10c1ccdf 100644 --- a/src/lib/Kconfig +++ b/src/lib/Kconfig @@ -1,3 +1,10 @@ +config MISSING_BOARD_RESET + bool + help + Selected by boards that don't provide a do_board_reset() + implementation. This activates a stub that logs the missing + board reset and halts execution. + config NO_EDID_FILL_FB bool default y if !MAINBOARD_DO_NATIVE_VGA_INIT diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c index e3ddce0a5c..883dbdc7ec 100644 --- a/src/lib/prog_loaders.c +++ b/src/lib/prog_loaders.c @@ -84,8 +84,7 @@ static void ramstage_cache_invalid(void) { printk(BIOS_ERR, "ramstage cache invalid.\n"); if (IS_ENABLED(CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE)) { - hard_reset(); - halt(); + board_reset(); } } diff --git a/src/lib/reset.c b/src/lib/reset.c index d8284210c4..283f72c2bf 100644 --- a/src/lib/reset.c +++ b/src/lib/reset.c @@ -18,6 +18,30 @@ #include <halt.h> #include <reset.h> +__noreturn void board_reset(void) +{ + printk(BIOS_INFO, "%s() called!\n", __func__); + dcache_clean_all(); + do_board_reset(); + halt(); +} + +#if IS_ENABLED(CONFIG_MISSING_BOARD_RESET) +void do_board_reset(void) +{ + printk(BIOS_CRIT, "No board_reset implementation, hanging...\n"); +} +#else +/* + * Fall back to hard_reset() for a regression free transition. + * FIXME: Remove after everything is converted to board_reset(). + */ +__weak void do_board_reset(void) +{ + hard_reset(); +} +#endif + __noreturn static void __hard_reset(void) { if (IS_ENABLED(CONFIG_HAVE_HARD_RESET)) do_hard_reset(); diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig index e13101b6be..af7578e630 100644 --- a/src/security/vboot/Kconfig +++ b/src/security/vboot/Kconfig @@ -18,7 +18,7 @@ config VBOOT bool "Verify firmware with vboot." default n select VBOOT_MOCK_SECDATA if !TPM1 && !TPM2 - depends on HAVE_HARD_RESET + depends on HAVE_HARD_RESET || !MISSING_BOARD_RESET help Enabling VBOOT will use vboot to verify the components of the firmware (stages, payload, etc). diff --git a/src/security/vboot/vboot_common.c b/src/security/vboot/vboot_common.c index 901f126ca4..8b02da04c7 100644 --- a/src/security/vboot/vboot_common.c +++ b/src/security/vboot/vboot_common.c @@ -129,6 +129,5 @@ void vboot_reboot(void) if (IS_ENABLED(CONFIG_CONSOLE_CBMEM_DUMP_TO_UART)) cbmem_dump_console(); vboot_platform_prepare_reboot(); - hard_reset(); - die("failed to reboot"); + board_reset(); } diff --git a/src/vendorcode/google/chromeos/watchdog.c b/src/vendorcode/google/chromeos/watchdog.c index fdaa17761a..61619ce0f9 100644 --- a/src/vendorcode/google/chromeos/watchdog.c +++ b/src/vendorcode/google/chromeos/watchdog.c @@ -52,5 +52,5 @@ void reboot_from_watchdog(void) { printk(BIOS_INFO, "Last reset was watchdog, reboot again to reset TPM!\n"); mark_watchdog_tombstone(); - hard_reset(); + board_reset(); } |