Skip to content

Commit 14a47cb

Browse files
SebastianBoekartben
authored andcommitted
drivers: firmware: nrf_ironside: add IRONside CPUCONF service
Add an IPC service API for booting local domain cores. Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no> Signed-off-by: Jonathan Nilsen <jonathan.nilsen@nordicsemi.no>
1 parent c0c4170 commit 14a47cb

File tree

4 files changed

+147
-0
lines changed

4 files changed

+147
-0
lines changed

drivers/firmware/nrf_ironside/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@
44
zephyr_library()
55

66
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CALL call.c)
7+
8+
zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CPUCONF_SERVICE cpuconf.c)

drivers/firmware/nrf_ironside/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,15 @@ config NRF_IRONSIDE_CALL_INIT_PRIORITY
2626
but higher than the priority of any feature that selects NRF_IRONSIDE_CALL.
2727

2828
endif # NRF_IRONSIDE_CALL
29+
30+
menu "Nordic IRONside services"
31+
depends on SOC_NRF54H20_IRON
32+
33+
config NRF_IRONSIDE_CPUCONF_SERVICE
34+
bool "IRONside CPUCONF service"
35+
depends on SOC_NRF54H20_CPUAPP
36+
select NRF_IRONSIDE_CALL
37+
help
38+
Service used to boot local domain cores.
39+
40+
endmenu
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include <stdint.h>
7+
#include <stdbool.h>
8+
9+
#include <zephyr/sys/util.h>
10+
#include <zephyr/kernel.h>
11+
12+
#include <zephyr/drivers/firmware/nrf_ironside/call.h>
13+
#include <zephyr/drivers/firmware/nrf_ironside/cpuconf.h>
14+
15+
#define CPU_PARAMS_CPU_OFFSET (0)
16+
#define CPU_PARAMS_CPU_MASK (0xF)
17+
#define CPU_PARAMS_WAIT_BIT BIT(4)
18+
19+
int ironside_cpuconf(NRF_PROCESSORID_Type cpu, const void *vector_table, bool cpu_wait,
20+
const uint8_t *msg, size_t msg_size)
21+
{
22+
int err;
23+
struct ironside_call_buf *buf;
24+
uint8_t *buf_msg;
25+
26+
if (msg_size > IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE) {
27+
return -IRONSIDE_CPUCONF_ERROR_MESSAGE_TOO_LARGE;
28+
}
29+
30+
buf = ironside_call_alloc();
31+
32+
buf->id = IRONSIDE_CALL_ID_CPUCONF_V0;
33+
34+
buf->args[IRONSIDE_CPUCONF_SERVICE_CPU_PARAMS_IDX] =
35+
(((uint32_t)cpu << CPU_PARAMS_CPU_OFFSET) & CPU_PARAMS_CPU_MASK) |
36+
(cpu_wait ? CPU_PARAMS_WAIT_BIT : 0);
37+
38+
buf->args[IRONSIDE_CPUCONF_SERVICE_VECTOR_TABLE_IDX] = (uint32_t)vector_table;
39+
40+
buf_msg = (uint8_t *)&buf->args[IRONSIDE_CPUCONF_SERVICE_MSG_0];
41+
if (msg_size > 0) {
42+
memcpy(buf_msg, msg, msg_size);
43+
}
44+
if (msg_size < IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE) {
45+
memset(&buf_msg[msg_size], 0, IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE - msg_size);
46+
}
47+
48+
ironside_call_dispatch(buf);
49+
50+
if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) {
51+
err = buf->args[IRONSIDE_CPUCONF_SERVICE_RETCODE_IDX];
52+
} else {
53+
err = buf->status;
54+
}
55+
56+
ironside_call_release(buf);
57+
58+
return err;
59+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2025 Nordic Semiconductor ASA
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_CPUCONF_H_
7+
#define ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_CPUCONF_H_
8+
9+
#include <stdbool.h>
10+
#include <stddef.h>
11+
#include <zephyr/drivers/firmware/nrf_ironside/call.h>
12+
#include <zephyr/toolchain/common.h>
13+
#include <nrf.h>
14+
15+
/**
16+
* @name CPUCONF service error codes.
17+
* @{
18+
*/
19+
20+
/** An invalid or unsupported processor ID was specified. */
21+
#define IRONSIDE_CPUCONF_ERROR_WRONG_CPU (1)
22+
/** The boot message is too large to fit in the buffer. */
23+
#define IRONSIDE_CPUCONF_ERROR_MESSAGE_TOO_LARGE (2)
24+
25+
/**
26+
* @}
27+
*/
28+
29+
#define IRONSIDE_CALL_ID_CPUCONF_V0 2
30+
31+
enum {
32+
IRONSIDE_CPUCONF_SERVICE_CPU_PARAMS_IDX,
33+
IRONSIDE_CPUCONF_SERVICE_VECTOR_TABLE_IDX,
34+
IRONSIDE_CPUCONF_SERVICE_MSG_0,
35+
IRONSIDE_CPUCONF_SERVICE_MSG_1,
36+
IRONSIDE_CPUCONF_SERVICE_MSG_2,
37+
IRONSIDE_CPUCONF_SERVICE_MSG_3,
38+
/* The last enum value is reserved for the number of arguments */
39+
IRONSIDE_CPUCONF_NUM_ARGS
40+
};
41+
42+
/* Maximum size of the CPUCONF message parameter. */
43+
#define IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE (4 * sizeof(uint32_t))
44+
45+
/* IDX 0 is re-used by the error return code and the 'cpu' parameter. */
46+
#define IRONSIDE_CPUCONF_SERVICE_RETCODE_IDX 0
47+
48+
BUILD_ASSERT(IRONSIDE_CPUCONF_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS);
49+
50+
/**
51+
* @brief Boot a local domain CPU
52+
*
53+
* @param cpu The CPU to be booted
54+
* @param vector_table Pointer to the vector table used to boot the CPU.
55+
* @param cpu_wait When this is true, the CPU will WAIT even if the CPU has clock.
56+
* @param msg A message that can be placed in radiocore's boot report.
57+
* @param msg_size Size of the message in bytes.
58+
*
59+
* @note cpu_wait is only intended to be enabled for debug purposes
60+
* and it is only supported that a debugger resumes the CPU.
61+
*
62+
* @note the call always sends IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE message bytes.
63+
* If the given msg_size is less than that, the remaining bytes are set to zero.
64+
*
65+
* @retval 0 on success or if the CPU has already booted.
66+
* @retval Positive non-0 error status if reported by IRONside call.
67+
* @retval -IRONSIDE_CPUCONF_ERROR_WRONG_CPU if cpu is unrecognized
68+
* @retval -IRONSIDE_CPUCONF_ERROR_MESSAGE_TOO_LARGE if msg_size is greater than
69+
* IRONSIDE_CPUCONF_SERVICE_MSG_MAX_SIZE.
70+
*/
71+
int ironside_cpuconf(NRF_PROCESSORID_Type cpu, const void *vector_table, bool cpu_wait,
72+
const uint8_t *msg, size_t msg_size);
73+
74+
#endif /* ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_CPUCONF_H_ */

0 commit comments

Comments
 (0)