sysreset: Support a hot reset

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>
This commit is contained in:
Simon Glass
2025-08-29 14:08:24 -06:00
parent a5f843f0f2
commit 9fdab58b86
6 changed files with 23 additions and 2 deletions

View File

@@ -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"
);

View File

@@ -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
------------

View File

@@ -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");

View File

@@ -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();

View File

@@ -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,
};

View File

@@ -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,