diff --git a/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk b/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk index de513858e9c..c509f968db6 100644 --- a/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk +++ b/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk @@ -4,9 +4,11 @@ config BOARD_NRF54H20DK select SOC_NRF54H20_CPUAPP if (BOARD_NRF54H20DK_NRF54H20_CPUAPP || \ BOARD_NRF54H20DK_NRF54H20_CPUAPP_IRON) - select SOC_NRF54H20_CPURAD if BOARD_NRF54H20DK_NRF54H20_CPURAD + select SOC_NRF54H20_CPURAD if (BOARD_NRF54H20DK_NRF54H20_CPURAD || \ + BOARD_NRF54H20DK_NRF54H20_CPURAD_IRON) select SOC_NRF54H20_CPUPPR if (BOARD_NRF54H20DK_NRF54H20_CPUPPR || \ BOARD_NRF54H20DK_NRF54H20_CPUPPR_XIP) select SOC_NRF54H20_CPUFLPR if (BOARD_NRF54H20DK_NRF54H20_CPUFLPR || \ BOARD_NRF54H20DK_NRF54H20_CPUFLPR_XIP) - select SOC_NRF54H20_IRON if BOARD_NRF54H20DK_NRF54H20_CPUAPP_IRON + select SOC_NRF54H20_IRON if (BOARD_NRF54H20DK_NRF54H20_CPUAPP_IRON || \ + BOARD_NRF54H20DK_NRF54H20_CPURAD_IRON) diff --git a/boards/nordic/nrf54h20dk/board.cmake b/boards/nordic/nrf54h20dk/board.cmake index 80963356dc9..093155e9322 100644 --- a/boards/nordic/nrf54h20dk/board.cmake +++ b/boards/nordic/nrf54h20dk/board.cmake @@ -2,8 +2,11 @@ include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) -if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD) - if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP) +if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR + CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD OR + CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP_IRON OR + CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD_IRON) + if(CONFIG_SOC_NRF54H20_CPUAPP) set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuapp.JLinkScript) else() set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpurad.JLinkScript) diff --git a/boards/nordic/nrf54h20dk/board.yml b/boards/nordic/nrf54h20dk/board.yml index 2009cc6130b..a54cf1ae549 100644 --- a/boards/nordic/nrf54h20dk/board.yml +++ b/boards/nordic/nrf54h20dk/board.yml @@ -11,6 +11,8 @@ board: cpucluster: cpuflpr - name: iron cpucluster: cpuapp + - name: iron + cpucluster: cpurad revision: format: major.minor.patch default: "0.9.0" diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron.dts new file mode 100644 index 00000000000..ecdbf56fbe3 --- /dev/null +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron.dts @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "nrf54h20dk_nrf54h20_cpurad.dts" +#include "nrf54h20dk_nrf54h20-ipc_conf_iron.dtsi" +#include "nrf54h20dk_nrf54h20-memory_map_iron.dtsi" + +/delete-node/ &cpusec_cpuapp_ipc; + +/ { + chosen { + zephyr,code-partition = &cpurad_slot0_partition; + zephyr,uart-mcumgr = &uart135; + }; +}; + + +&cpusec_cpurad_ipc { + mbox-names = "tx", "rx"; + status = "okay"; +}; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_0_9_0.yaml new file mode 100644 index 00000000000..398ea7b20a7 --- /dev/null +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_0_9_0.yaml @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +identifier: nrf54h20dk/nrf54h20/cpurad/iron +name: nRF54H20-DK-nRF54H20-Radio (IRONside SE compatible) (revision 0.9.0) +type: mcu +arch: arm +toolchain: + - gnuarmemb + - xtools + - zephyr +sysbuild: true +ram: 192 +flash: 256 +supported: + - counter + - gpio + - pwm + - retained_mem + - spi diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_defconfig b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_defconfig new file mode 100644 index 00000000000..0ee0a96f99d --- /dev/null +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_defconfig @@ -0,0 +1,28 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_USE_DT_CODE_PARTITION=y + +# Enable MPU +CONFIG_ARM_MPU=y + +# Enable hardware stack protection +CONFIG_HW_STACK_PROTECTION=y + +# MPU-based null-pointer dereferencing detection cannot be applied +# as the (0x0 - 0x400) region is unmapped for this target. +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y + +# Enable cache +CONFIG_CACHE_MANAGEMENT=y +CONFIG_EXTERNAL_CACHE=y + +# UICR generation is not supported, and when reintroduced will not use nrf-regtool. +CONFIG_NRF_REGTOOL_GENERATE_UICR=n diff --git a/drivers/firmware/nrf_ironside/CMakeLists.txt b/drivers/firmware/nrf_ironside/CMakeLists.txt index 90320c62df5..8f31acfef00 100644 --- a/drivers/firmware/nrf_ironside/CMakeLists.txt +++ b/drivers/firmware/nrf_ironside/CMakeLists.txt @@ -4,3 +4,5 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CALL call.c) + +zephyr_library_sources_ifdef(CONFIG_NRF_IRONSIDE_CPUCONF_SERVICE cpuconf.c) diff --git a/drivers/firmware/nrf_ironside/Kconfig b/drivers/firmware/nrf_ironside/Kconfig index adfdf97f648..b0f05966fcd 100644 --- a/drivers/firmware/nrf_ironside/Kconfig +++ b/drivers/firmware/nrf_ironside/Kconfig @@ -20,3 +20,15 @@ config NRF_IRONSIDE_CALL_INIT_PRIORITY but higher than the priority of any feature that selects NRF_IRONSIDE_CALL. endif # NRF_IRONSIDE_CALL + +menu "Nordic IRONside services" + depends on SOC_NRF54H20_IRON + +config NRF_IRONSIDE_CPUCONF_SERVICE + bool "IRONside CPUCONF service" + depends on SOC_NRF54H20_CPUAPP + select NRF_IRONSIDE_CALL + help + Service used to boot local domain cores. + +endmenu diff --git a/drivers/firmware/nrf_ironside/cpuconf.c b/drivers/firmware/nrf_ironside/cpuconf.c new file mode 100644 index 00000000000..6c1d61b244c --- /dev/null +++ b/drivers/firmware/nrf_ironside/cpuconf.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include + +#include + +#include +#include + +int ironside_cpuconf(NRF_PROCESSORID_Type cpu, void *vector_table, bool cpu_wait, uint8_t *msg, + size_t msg_size) +{ + int err; + struct ironside_call_buf *const buf = ironside_call_alloc(); + + buf->id = IRONSIDE_CALL_ID_CPUCONF_V0; + + buf->args[IRONSIDE_CPUCONF_SERVICE_CPU_IDX] = cpu; + buf->args[IRONSIDE_CPUCONF_SERVICE_VECTOR_TABLE_IDX] = (uint32_t)vector_table; + buf->args[IRONSIDE_CPUCONF_SERVICE_CPU_WAIT_IDX] = cpu_wait; + buf->args[IRONSIDE_CPUCONF_SERVICE_MSG_IDX] = (uint32_t)msg; + buf->args[IRONSIDE_CPUCONF_SERVICE_MSG_SIZE_IDX] = msg_size; + + ironside_call_dispatch(buf); + + if (buf->status == IRONSIDE_CALL_STATUS_RSP_SUCCESS) { + err = buf->args[IRONSIDE_CPUCONF_SERVICE_RETCODE_IDX]; + } else { + err = buf->status; + } + + ironside_call_release(buf); + + return err; +} diff --git a/dts/arm/nordic/nrf54h20_cpuapp.dtsi b/dts/arm/nordic/nrf54h20_cpuapp.dtsi index c56df42ddd5..15eac9c5d19 100644 --- a/dts/arm/nordic/nrf54h20_cpuapp.dtsi +++ b/dts/arm/nordic/nrf54h20_cpuapp.dtsi @@ -59,3 +59,7 @@ wdt011: &cpuapp_wdt011 {}; &grtc { interrupts = <109 NRF_DEFAULT_IRQ_PRIORITY>; }; + +&nfct { + compatible = "nordic,nrf-nfct-v2"; +}; diff --git a/dts/bindings/net/wireless/nordic,nrf-nfct-v2.yaml b/dts/bindings/net/wireless/nordic,nrf-nfct-v2.yaml new file mode 100644 index 00000000000..e6b34aff3ec --- /dev/null +++ b/dts/bindings/net/wireless/nordic,nrf-nfct-v2.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Nordic nRF family NFCT (Near Field Communication Tag) + +compatible: "nordic,nrf-nfct-v2" + +include: nordic,nrf-nfct.yaml + +properties: + nfct-pins-as-gpios: + type: boolean + description: | + When enabled this property will configure pins dedicated to NFCT + peripheral as regular GPIOs. This property must be applied in cpuapp + if NFCT pins are intended to be used as regular GPIOs by any core. + + NFC pins in nRF54H series: P2.10 and P2.11 diff --git a/include/zephyr/drivers/firmware/nrf_ironside/cpuconf.h b/include/zephyr/drivers/firmware/nrf_ironside/cpuconf.h new file mode 100644 index 00000000000..61c78f56b0c --- /dev/null +++ b/include/zephyr/drivers/firmware/nrf_ironside/cpuconf.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_CPUCONF_H_ +#define ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_CPUCONF_H_ + +#include + +#include + +/** + * @name CPUCONF service error codes. + * @{ + */ + +#define IRONSIDE_CPUCONF_ERROR_STARTING_CPU_FAILED 0x5eb0 +#define IRONSIDE_CPUCONF_ERROR_WRONG_CPU 0x5eb2 +#define IRONSIDE_CPUCONF_ERROR_MEM_ACCESS_NOT_PERMITTED 0x5eb1 +#define IRONSIDE_CPUCONF_ERROR_IRONSIDE_CALL_FAILED 0x5eb3 + +/** + * @} + */ + +#define IRONSIDE_CALL_ID_CPUCONF_V0 2 + +enum { + IRONSIDE_CPUCONF_SERVICE_CPU_IDX, + IRONSIDE_CPUCONF_SERVICE_VECTOR_TABLE_IDX, + IRONSIDE_CPUCONF_SERVICE_CPU_WAIT_IDX, + IRONSIDE_CPUCONF_SERVICE_MSG_IDX, + IRONSIDE_CPUCONF_SERVICE_MSG_SIZE_IDX, + /* The last enum value is reserved for the number of arguments */ + IRONSIDE_SE_CPUCONF_NUM_ARGS +}; + +/* IDX 0 is re-used by the error return code and the 'cpu' parameter. */ +#define IRONSIDE_CPUCONF_SERVICE_RETCODE_IDX 0 + +BUILD_ASSERT(IRONSIDE_SE_CPUCONF_NUM_ARGS <= NRF_IRONSIDE_CALL_NUM_ARGS); + +/** + * @brief Boot a local domain CPU + * + * @param cpu The CPU to be booted + * @param vector_table Pointer to the vector table used to boot the CPU. + * @param cpu_wait When this is true, the CPU will WAIT even if the CPU has clock. + * @param msg A message that can be placed in radiocore's boot report. + * @param msg_size Size of the message in bytes. + * + * @note cpu_wait is only intended to be enabled for debug purposes + * and it is only supported that a debugger resumes the CPU. + * + * @retval 0 on success or if the CPU has already booted. + * @retval -IRONSIDE_CPUCONF_ERROR_WRONG_CPU if cpu is unrecognized + * @retval -IRONSIDE_CPUCONF_ERROR_STARTING_CPU_FAILED if starting the CPU failed + * @retval -IRONSIDE_CPUCONF_ERROR_MEM_ACCESS_NOT_PERMITTED + * if the CPU does not have read access configured for the vector_table address + * @retval -IRONSIDE_CPUCONF_ERROR_IRONSIDE_CALL_FAILED The IRONside call failed. + */ +int ironside_cpuconf(NRF_PROCESSORID_Type cpu, void *vector_table, bool cpu_wait, uint8_t *msg, + size_t msg_size); + +#endif /* ZEPHYR_INCLUDE_ZEPHYR_DRIVERS_FIRMWARE_NRF_IRONSIDE_CPUCONF_H_ */ diff --git a/samples/sysbuild/hello_world/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf b/samples/sysbuild/hello_world/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf new file mode 100644 index 00000000000..ca2bc07e4f2 --- /dev/null +++ b/samples/sysbuild/hello_world/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_SOC_NRF54H20_CPURAD_ENABLE=y diff --git a/samples/sysbuild/hello_world/sample.yaml b/samples/sysbuild/hello_world/sample.yaml index 68eae58739c..7361a045c05 100644 --- a/samples/sysbuild/hello_world/sample.yaml +++ b/samples/sysbuild/hello_world/sample.yaml @@ -27,6 +27,11 @@ tests: - nrf54h20dk/nrf54h20/cpuapp extra_args: SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpurad.conf + sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpurad.iron: + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp/iron + extra_args: SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpurad_iron.conf + sample.sysbuild.hello_world.nrf54h20dk_cpuapp_cpuppr: platform_allow: - nrf54h20dk/nrf54h20/cpuapp diff --git a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad_iron.conf b/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad_iron.conf new file mode 100644 index 00000000000..8d4a230adbe --- /dev/null +++ b/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad_iron.conf @@ -0,0 +1 @@ +SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpurad/iron" diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index 57961c1b98f..1d896dbab50 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -7,6 +7,8 @@ config SOC_SERIES_NRF54HX select HAS_NRFS select HAS_NRFX select HAS_NORDIC_DRIVERS + select SOC_EARLY_INIT_HOOK if ARM + select SOC_LATE_INIT_HOOK if SOC_NRF54H20_CPURAD_ENABLE select NRF_PLATFORM_HALTIUM config SOC_NRF54H20_CPUAPP_COMMON @@ -63,6 +65,16 @@ config SOC_NRF54H20_CPURAD_COMMON select HAS_PM select HAS_POWEROFF +config SOC_NRF54H20_CPURAD_ENABLE + bool "Boot the nRF54H20 Radio core" + default y if NRF_802154_SER_HOST + depends on SOC_NRF54H20_CPUAPP + select NRF_IRONSIDE_CPUCONF_SERVICE + help + This will at application boot time enable clock to the + Radiocore, and also power will be requested to the Radiocore + subsystem. The Radiocore will then start executing instructions. + config SOC_NRF54H20_CPURAD select SOC_NRF54H20_CPURAD_COMMON diff --git a/soc/nordic/nrf54h/soc.c b/soc/nordic/nrf54h/soc.c index 43c84e1b9a7..efaab5a9137 100644 --- a/soc/nordic/nrf54h/soc.c +++ b/soc/nordic/nrf54h/soc.c @@ -18,9 +18,11 @@ #include #include #include +#include #include #include #include +#include LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); @@ -42,6 +44,8 @@ sys_snode_t soc_node; ADDRESS_DOMAIN_Msk | \ ADDRESS_BUS_Msk))) +#define dt_nodelabel_cpurad_slot0_partition DT_NODELABEL(cpurad_slot0_partition) + static void power_domain_init(void) { /* @@ -125,7 +129,7 @@ bool z_arm_on_enter_cpu_idle(void) } #endif -static int nordicsemi_nrf54h_init(void) +void soc_early_init_hook(void) { int err; @@ -137,9 +141,7 @@ static int nordicsemi_nrf54h_init(void) trim_hsfll(); err = dmm_init(); - if (err < 0) { - return err; - } + __ASSERT_NO_MSG(err >= 0); #if DT_NODE_HAS_STATUS_OKAY(DT_NODELABEL(ccm030)) /* DMASEC is set to non-secure by default, which prevents CCM from @@ -151,12 +153,37 @@ static int nordicsemi_nrf54h_init(void) nrf_spu_periph_perm_dmasec_set(spu, nrf_address_slave_get(ccm030_addr), true); #endif - return 0; + if (DT_NODE_HAS_STATUS(DT_NODELABEL(nfct), disabled) && + DT_PROP_OR(DT_NODELABEL(nfct), nfct_pins_as_gpios, 0)) { + nrf_nfct_pad_config_enable_set(NRF_NFCT, false); + } } +#if defined(CONFIG_SOC_NRF54H20_CPURAD_ENABLE) +void soc_late_init_hook(void) +{ + int err; + + /* The msg will be used for communication prior to IPC + * communication being set up. But at this moment no such + * communication is required. + */ + uint8_t *msg = NULL; + size_t msg_size = 0; + + void *radiocore_address = + (void *)(DT_REG_ADDR(DT_GPARENT(dt_nodelabel_cpurad_slot0_partition)) + + DT_REG_ADDR(dt_nodelabel_cpurad_slot0_partition)); + + /* Don't wait as this is not yet supported. */ + bool cpu_wait = false; + + err = ironside_cpuconf(NRF_PROCESSOR_RADIOCORE, radiocore_address, cpu_wait, msg, msg_size); + __ASSERT(err == 0, "err was %d", err); +} +#endif + void arch_busy_wait(uint32_t time_us) { nrfx_coredep_delay_us(time_us); } - -SYS_INIT(nordicsemi_nrf54h_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);