Skip to content

Commit 377a18c

Browse files
SebastianBoecfriedt
authored andcommitted
soc: nordic: ironside: Add bootmode service
Added support for the IronSide bootmode service which allows requesting a reboot into secondary firmware boot mode. In this mode, the secondary configuration defined in UICR is applied instead of the primary one. The service provides the ironside_bootmode_secondary_reboot() function that can pass message data to the boot report of the CPU booted in the secondary boot mode. Signed-off-by: Sebastian Bøe <[email protected]>
1 parent 4c8c79d commit 377a18c

File tree

4 files changed

+131
-0
lines changed

4 files changed

+131
-0
lines changed

soc/nordic/ironside/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ zephyr_library()
66
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CALL call.c)
77
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_BOOT_REPORT boot_report.c)
88
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CPUCONF_SERVICE cpuconf.c)
9+
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_BOOTMODE_SERVICE bootmode.c)
910
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_TDD_SERVICE tdd.c)
1011
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_UPDATE_SERVICE update.c)
1112
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_DVFS_SERVICE dvfs.c)

soc/nordic/ironside/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ config NRF_IRONSIDE_BOOT_REPORT
5656
help
5757
Support for parsing the Boot Report populated by Nordic IronSide firmware.
5858

59+
config NRF_IRONSIDE_BOOTMODE_SERVICE
60+
bool "IronSide boot mode service"
61+
select NRF_IRONSIDE_CALL
62+
help
63+
Service used to reboot into secondary firmware boot mode.
64+
5965
config NRF_IRONSIDE_DVFS_SERVICE
6066
bool "IronSide DVFS service"
6167
depends on SOC_NRF54H20_CPUAPP

soc/nordic/ironside/bootmode.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <string.h>
7+
8+
#include <zephyr/sys/util.h>
9+
#include <nrf_ironside/bootmode.h>
10+
#include <nrf_ironside/call.h>
11+
12+
#define BOOT_MODE_SECONDARY (0x1)
13+
14+
BUILD_ASSERT(IRONSIDE_BOOTMODE_SERVICE_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS);
15+
16+
int ironside_bootmode_secondary_reboot(const uint8_t *msg, size_t msg_size)
17+
{
18+
int err;
19+
struct ironside_call_buf *buf;
20+
uint8_t *buf_msg;
21+
22+
if (msg_size > IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE) {
23+
return -IRONSIDE_BOOTMODE_ERROR_MESSAGE_TOO_LARGE;
24+
}
25+
26+
buf = ironside_call_alloc();
27+
28+
buf->id = IRONSIDE_CALL_ID_BOOTMODE_SERVICE_V1;
29+
30+
buf->args[IRONSIDE_BOOTMODE_SERVICE_MODE_IDX] = BOOT_MODE_SECONDARY;
31+
32+
buf_msg = (uint8_t *)&buf->args[IRONSIDE_BOOTMODE_SERVICE_MSG_0_IDX];
33+
34+
memset(buf_msg, 0, IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE);
35+
36+
if (msg_size > 0) {
37+
memcpy(buf_msg, msg, msg_size);
38+
}
39+
40+
ironside_call_dispatch(buf);
41+
42+
if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) {
43+
err = buf->args[IRONSIDE_BOOTMODE_SERVICE_RETCODE_IDX];
44+
} else {
45+
err = buf->status;
46+
}
47+
48+
ironside_call_release(buf);
49+
50+
return err;
51+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOTMODE_H_
7+
#define ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOTMODE_H_
8+
9+
#include <stdbool.h>
10+
#include <stdint.h>
11+
#include <stddef.h>
12+
13+
/**
14+
* @name Boot mode service error codes.
15+
* @{
16+
*/
17+
18+
/** Invalid/unsupported boot mode transition. */
19+
#define IRONSIDE_BOOTMODE_ERROR_UNSUPPORTED_MODE (1)
20+
/** Failed to reboot into the boot mode due to other activity preventing a reset. */
21+
#define IRONSIDE_BOOTMODE_ERROR_BUSY (2)
22+
/** The boot message is too large to fit in the buffer. */
23+
#define IRONSIDE_BOOTMODE_ERROR_MESSAGE_TOO_LARGE (3)
24+
25+
/**
26+
* @}
27+
*/
28+
29+
/* IronSide call identifiers with implicit versions. */
30+
#define IRONSIDE_CALL_ID_BOOTMODE_SERVICE_V1 5
31+
32+
enum {
33+
IRONSIDE_BOOTMODE_SERVICE_MODE_IDX,
34+
IRONSIDE_BOOTMODE_SERVICE_MSG_0_IDX,
35+
IRONSIDE_BOOTMODE_SERVICE_MSG_1_IDX,
36+
IRONSIDE_BOOTMODE_SERVICE_MSG_2_IDX,
37+
IRONSIDE_BOOTMODE_SERVICE_MSG_3_IDX,
38+
/* The last enum value is reserved for the number of arguments */
39+
IRONSIDE_BOOTMODE_SERVICE_NUM_ARGS,
40+
};
41+
42+
/* Maximum size of the message parameter. */
43+
#define IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE (4 * sizeof(uint32_t))
44+
45+
/* Index of the return code within the service buffer. */
46+
#define IRONSIDE_BOOTMODE_SERVICE_RETCODE_IDX (0)
47+
48+
/**
49+
* @brief Request a reboot into the secondary firmware boot mode.
50+
*
51+
* This invokes the IronSide SE boot mode service to restart the system into the secondary boot
52+
* mode. In this mode, the secondary configuration defined in UICR is applied instead of the
53+
* primary one. The system immediately reboots without a reply if the request succeeds.
54+
*
55+
* The given message data is passed to the boot report of the CPU booted in the secondary boot mode.
56+
*
57+
* @note This function does not return if the request is successful.
58+
* @note The device will boot into the secondary firmware instead of primary firmware.
59+
* @note The request does not fail if the secondary firmware is not defined.
60+
*
61+
* @param msg A message that can be placed in the cpu's boot report.
62+
* @param msg_size Size of the message in bytes.
63+
*
64+
* @retval 0 on success.
65+
* @retval -IRONSIDE_BOOTMODE_ERROR_UNSUPPORTED_MODE if the secondary boot mode is unsupported.
66+
* @retval -IRONSIDE_BOOTMODE_ERROR_BUSY if the reboot was blocked.
67+
* @retval -IRONSIDE_BOOTMODE_ERROR_MESSAGE_TOO_LARGE if msg_size is greater than
68+
* IRONSIDE_BOOTMODE_SERVICE_MSG_MAX_SIZE.
69+
* @retval Positive error status if reported by IronSide call (see error codes in @ref call.h).
70+
*/
71+
int ironside_bootmode_secondary_reboot(const uint8_t *msg, size_t msg_size);
72+
73+
#endif /* ZEPHYR_SOC_NORDIC_IRONSIDE_INCLUDE_NRF_IRONSIDE_BOOTMODE_H_ */

0 commit comments

Comments
 (0)