[Concept,15/18] sysreset: Support a hot reset

Message ID 20250902152158.2285264-16-sjg@u-boot.org
State New
Headers
Series efi: Improve integration of the app with a Shim environment |

Commit Message

Simon Glass Sept. 2, 2025, 3:21 p.m. UTC
  From: Simon Glass <sjg@chromium.org>

In some cases we may wish to return back to the program which started
U-Boot. Add the concept of a 'hot' reset, to support this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/boot.c                          |  1 +
 doc/usage/cmd/reset.rst             |  3 +++
 drivers/sysreset/sysreset-uclass.c  | 15 +++++++++++++--
 drivers/sysreset/sysreset_sandbox.c |  1 +
 include/sysreset.h                  |  3 +++
 test/dm/sysreset.c                  |  2 ++
 6 files changed, 23 insertions(+), 2 deletions(-)
  

Patch

diff --git a/cmd/boot.c b/cmd/boot.c
index 23496cafdf5..832ad08c319 100644
--- a/cmd/boot.c
+++ b/cmd/boot.c
@@ -60,6 +60,7 @@  U_BOOT_CMD(
 	reset, 2, 0,	do_reset,
 	"Perform RESET of the CPU",
 	"- cold boot without level specifier\n"
+	"reset -h - hotreset if implemented\n"
 	"reset -w - warm reset if implemented"
 );
 
diff --git a/doc/usage/cmd/reset.rst b/doc/usage/cmd/reset.rst
index 126db21cdb8..3a43db204e5 100644
--- a/doc/usage/cmd/reset.rst
+++ b/doc/usage/cmd/reset.rst
@@ -22,6 +22,9 @@  DDR and peripherals, on some boards also resets external PMIC.
 -w
     Do warm WARM, reset CPU but keep peripheral/DDR/PMIC active.
 
+-h
+    Do a hot reset, if supported, which returns back to the program which
+    started U-Boot.
 
 Return value
 ------------
diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c
index 536ac727142..db81c9b5779 100644
--- a/drivers/sysreset/sysreset-uclass.c
+++ b/drivers/sysreset/sysreset-uclass.c
@@ -125,8 +125,19 @@  int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
 	if (argc > 2)
 		return CMD_RET_USAGE;
 
-	if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'w') {
-		reset_type = SYSRESET_WARM;
+	if (argc == 2 && argv[1][0] == '-') {
+		int type = argv[1][1];
+
+		switch (type) {
+		case 'h':
+			reset_type = SYSRESET_HOT;
+			break;
+		case 'w':
+			reset_type = SYSRESET_WARM;
+			break;
+		default:
+			return CMD_RET_USAGE;
+		}
 	}
 
 	printf("resetting ...\n");
diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c
index 93179f90bbb..522050eb4bf 100644
--- a/drivers/sysreset/sysreset_sandbox.c
+++ b/drivers/sysreset/sysreset_sandbox.c
@@ -65,6 +65,7 @@  static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type)
 			return -EACCES;
 		sandbox_exit();
 	case SYSRESET_POWER:
+	case SYSRESET_HOT:
 		if (!state->sysreset_allowed[type])
 			return -EACCES;
 		sandbox_exit();
diff --git a/include/sysreset.h b/include/sysreset.h
index ff20abdeed3..f231d4e8bc4 100644
--- a/include/sysreset.h
+++ b/include/sysreset.h
@@ -21,6 +21,9 @@  enum sysreset_t {
 	SYSRESET_POWER,
 	/** @SYSRESET_POWER_OFF: turn off power */
 	SYSRESET_POWER_OFF,
+	/** @SYSRESET_HOT: exit out of U-Boot (e.g. from EFI app) */
+	SYSRESET_HOT,
+
 	/** @SYSRESET_COUNT: number of available reset types */
 	SYSRESET_COUNT,
 };
diff --git a/test/dm/sysreset.c b/test/dm/sysreset.c
index 8431aaa0a9e..a30d035b9a6 100644
--- a/test/dm/sysreset.c
+++ b/test/dm/sysreset.c
@@ -76,10 +76,12 @@  static int dm_test_sysreset_walk(struct unit_test_state *uts)
 	state->sysreset_allowed[SYSRESET_COLD] = false;
 	state->sysreset_allowed[SYSRESET_POWER] = false;
 	state->sysreset_allowed[SYSRESET_POWER_OFF] = false;
+	state->sysreset_allowed[SYSRESET_HOT] = false;
 	ut_asserteq(-EACCES, sysreset_walk(SYSRESET_WARM));
 	ut_asserteq(-EACCES, sysreset_walk(SYSRESET_COLD));
 	ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER));
 	ut_asserteq(-EACCES, sysreset_walk(SYSRESET_POWER_OFF));
+	ut_asserteq(-EACCES, sysreset_walk(SYSRESET_HOT));
 
 	/*
 	 * Enable cold system reset - this should make cold system reset work,