summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/device/root_device.c2
-rw-r--r--src/include/reset.h38
-rw-r--r--src/lib/Kconfig7
-rw-r--r--src/lib/prog_loaders.c3
-rw-r--r--src/lib/reset.c24
-rw-r--r--src/security/vboot/Kconfig2
-rw-r--r--src/security/vboot/vboot_common.c3
-rw-r--r--src/vendorcode/google/chromeos/watchdog.c2
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();
}