From 442626c7ebac822ba5ae6fb4da05d1b44bc4717a Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Wed, 18 Jun 2025 12:26:36 +0200 Subject: [PATCH 01/40] samples: drivers: mbox: switch nrf54h20 cpuapp and cpurad remotes Switch which board is the remote in the test case for mbox communication between nrf54h20dk/nrf54h20/cpuapp and nrf54h20dk/nrf54h20/cpurad, making cpurad the remote instead. This is done to prepare the sample for executing with IronSide SE, where using cpurad as the main board doesn't make as much sense, since cpuapp has to start cpurad. Signed-off-by: Jonathan Nilsen --- samples/drivers/mbox/CMakeLists.txt | 1 - samples/drivers/mbox/Kconfig.sysbuild | 1 - .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 0 samples/drivers/mbox/remote/CMakeLists.txt | 2 +- .../boards/nrf54h20dk_nrf54h20_cpurad.overlay | 0 samples/drivers/mbox/sample.yaml | 12 +++++++----- .../mbox/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf | 1 + 7 files changed, 9 insertions(+), 8 deletions(-) rename samples/drivers/mbox/{remote => }/boards/nrf54h20dk_nrf54h20_cpuapp.overlay (100%) rename samples/drivers/mbox/{ => remote}/boards/nrf54h20dk_nrf54h20_cpurad.overlay (100%) create mode 100644 samples/drivers/mbox/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf diff --git a/samples/drivers/mbox/CMakeLists.txt b/samples/drivers/mbox/CMakeLists.txt index 696b2317aa7cc..828b676a89a58 100644 --- a/samples/drivers/mbox/CMakeLists.txt +++ b/samples/drivers/mbox/CMakeLists.txt @@ -24,7 +24,6 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR CONFIG_BOARD_ESP32_DEVKITC_ESP32_PROCPU OR CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_PROCPU OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR - CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD OR CONFIG_BOARD_NRF54L09PDK_NRF54L09_CPUAPP OR CONFIG_BOARD_NRF54L15DK_NRF54L15_CPUAPP OR CONFIG_BOARD_NRF54L20PDK_NRF54L20_CPUAPP OR diff --git a/samples/drivers/mbox/Kconfig.sysbuild b/samples/drivers/mbox/Kconfig.sysbuild index 97402056c14ec..5582b2cf41e95 100644 --- a/samples/drivers/mbox/Kconfig.sysbuild +++ b/samples/drivers/mbox/Kconfig.sysbuild @@ -18,7 +18,6 @@ config REMOTE_BOARD default "lpcxpresso55s69/lpc55s69/cpu1" if $(BOARD) = "lpcxpresso55s69" default "frdm_mcxn947/mcxn947/cpu1" if $(BOARD) = "frdm_mcxn947" default "mcx_n9xx_evk/mcxn947/cpu1" if $(BOARD) = "mcx_n9xx_evk" - default "nrf54h20dk/nrf54h20/cpuapp" if "$(BOARD)${BOARD_QUALIFIERS}" = "nrf54h20dk/nrf54h20/cpurad" default "nrf54l09pdk/nrf54l09/cpuflpr" if $(BOARD) = "nrf54l09pdk" default "nrf54l15dk/nrf54l15/cpuflpr" if $(BOARD) = "nrf54l15dk" default "nrf54l20pdk/nrf54l20/cpuflpr" if $(BOARD) = "nrf54l20pdk" diff --git a/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp.overlay similarity index 100% rename from samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpuapp.overlay rename to samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpuapp.overlay diff --git a/samples/drivers/mbox/remote/CMakeLists.txt b/samples/drivers/mbox/remote/CMakeLists.txt index 48df8f0cb5b2e..25bbbac6f9598 100644 --- a/samples/drivers/mbox/remote/CMakeLists.txt +++ b/samples/drivers/mbox/remote/CMakeLists.txt @@ -23,7 +23,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET OR CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_APPCPU OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUFLPR OR - CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR + CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD OR CONFIG_BOARD_NRF54L09PDK_NRF54L09_CPUFLPR OR CONFIG_BOARD_NRF54L15DK_NRF54L15_CPUFLPR OR CONFIG_BOARD_NRF54L20PDK_NRF54L20_CPUFLPR OR diff --git a/samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpurad.overlay b/samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay similarity index 100% rename from samples/drivers/mbox/boards/nrf54h20dk_nrf54h20_cpurad.overlay rename to samples/drivers/mbox/remote/boards/nrf54h20dk_nrf54h20_cpurad.overlay diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index 1aee77b1c677a..3725276416a6b 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -60,19 +60,21 @@ tests: - "Ping \\(on channel 16\\)" - "Pong \\(on channel 14\\)" - sample.drivers.mbox.nrf54h20_rad_app: + sample.drivers.mbox.nrf54h20_app_rad: platform_allow: - - nrf54h20dk/nrf54h20/cpurad + - nrf54h20dk/nrf54h20/cpuapp integration_platforms: - - nrf54h20dk/nrf54h20/cpurad + - nrf54h20dk/nrf54h20/cpuapp + extra_args: + - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpurad.conf sysbuild: true harness: console harness_config: type: multi_line ordered: false regex: - - "Ping \\(on channel 18\\)" - - "Pong \\(on channel 12\\)" + - "Ping \\(on channel 12\\)" + - "Pong \\(on channel 18\\)" sample.drivers.mbox.nrf54l: platform_allow: diff --git a/samples/drivers/mbox/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf b/samples/drivers/mbox/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf new file mode 100644 index 0000000000000..dd863e78d9933 --- /dev/null +++ b/samples/drivers/mbox/sysbuild/nrf54h20dk_nrf54h20_cpurad.conf @@ -0,0 +1 @@ +SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpurad" From 2b519183f4764ff02633c20849a294c7fe7e40fc Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Tue, 24 Jun 2025 06:12:36 +0200 Subject: [PATCH 02/40] tests: boards: nrf: nrfs: Build main image for app core only Update this multi-core test to always run the `main` and `remote` images on cpuapp and cpurad respectively. This is to prepare the test for running with IronSide SE, in which case keeping cpurad as the main board target wouldn't make as much sense, because cpurad would have to be started by cpuapp. Signed-off-by: Grzegorz Swiderski --- tests/boards/nrf/nrfs/Kconfig.sysbuild | 1 - tests/boards/nrf/nrfs/testcase.yaml | 2 -- 2 files changed, 3 deletions(-) diff --git a/tests/boards/nrf/nrfs/Kconfig.sysbuild b/tests/boards/nrf/nrfs/Kconfig.sysbuild index f281257725fc6..6cc7dc9575af3 100644 --- a/tests/boards/nrf/nrfs/Kconfig.sysbuild +++ b/tests/boards/nrf/nrfs/Kconfig.sysbuild @@ -6,4 +6,3 @@ source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" config REMOTE_BOARD string default "$(BOARD)/nrf54h20/cpurad" if SOC_NRF54H20_CPUAPP - default "$(BOARD)/nrf54h20/cpuapp" if SOC_NRF54H20_CPURAD diff --git a/tests/boards/nrf/nrfs/testcase.yaml b/tests/boards/nrf/nrfs/testcase.yaml index 315c3cf7f375c..d1974f00d7c0d 100644 --- a/tests/boards/nrf/nrfs/testcase.yaml +++ b/tests/boards/nrf/nrfs/testcase.yaml @@ -1,10 +1,8 @@ common: platform_allow: - nrf54h20dk/nrf54h20/cpuapp - - nrf54h20dk/nrf54h20/cpurad integration_platforms: - nrf54h20dk/nrf54h20/cpuapp - - nrf54h20dk/nrf54h20/cpurad tags: - nrfs harness: ztest From ce7bcc4d4c4f571bd55aeb32e7e653f1c3852e9e Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Wed, 11 Jun 2025 11:07:04 +0200 Subject: [PATCH 03/40] boards: nrf54h20dk: Merge iron variants into the base variants This replaces the legacy SDFW compatible board configuration with the IronSide SE compatible one, thus removing support for running samples and tests on nRF54H20 devices with the old firmware. All applications are expected to work on `nrf54h20dk/nrf54h20/cpuapp` out of the box. For other board targets, all applications are expected to boot, but may require additional peripheral configuration in UICR. Build system support for the new UICR format is to be added separately. Co-authored-by: Jonathan Nilsen Signed-off-by: Jonathan Nilsen Signed-off-by: Grzegorz Swiderski --- boards/nordic/nrf54h20dk/Kconfig.defconfig | 28 +++-- boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk | 8 +- boards/nordic/nrf54h20dk/board.cmake | 7 +- boards/nordic/nrf54h20dk/board.yml | 4 - .../nrf54h20dk_nrf54h20-ipc_conf.dtsi | 8 +- .../nrf54h20dk_nrf54h20-ipc_conf_iron.dtsi | 30 ----- .../nrf54h20dk_nrf54h20-memory_map.dtsi | 98 ++++++++--------- .../nrf54h20dk_nrf54h20-memory_map_iron.dtsi | 104 ------------------ .../nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 27 +++-- .../nrf54h20dk_nrf54h20_cpuapp_defconfig | 2 - .../nrf54h20dk_nrf54h20_cpuapp_iron.dts | 45 -------- ...nrf54h20dk_nrf54h20_cpuapp_iron_0_9_0.yaml | 25 ----- .../nrf54h20dk_nrf54h20_cpuapp_iron_defconfig | 29 ----- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts | 11 +- .../nrf54h20dk_nrf54h20_cpurad_iron.dts | 29 ----- ...nrf54h20dk_nrf54h20_cpurad_iron_0_9_0.yaml | 20 ---- .../nrf54h20dk_nrf54h20_cpurad_iron_defconfig | 28 ----- dts/vendor/nordic/nrf54h20.dtsi | 4 - .../nordic/nrf_ironside/update/README.rst | 6 +- .../nordic/nrf_ironside/update/sample.yaml | 4 +- .../nrf54h20dk_nrf54h20_cpuapp_iron.overlay | 3 - samples/drivers/mbox/sample.yaml | 1 + .../nrf54h20dk_nrf54h20_cpuapp_iron.overlay | 8 -- .../subsys/mgmt/mcumgr/smp_svr/sample.yaml | 2 +- .../nrf54h20dk_nrf54h20_cpuapp_iron.conf | 4 - samples/sysbuild/hello_world/sample.yaml | 10 +- .../nrf54h20dk_nrf54h20_cpurad_iron.conf | 1 - scripts/west_commands/runners/nrf_common.py | 6 +- soc/nordic/ironside/Kconfig | 4 +- soc/nordic/nrf54h/Kconfig | 4 +- .../nrf54h/Kconfig.defconfig.nrf54h20_cpuapp | 3 - .../nrf54h/Kconfig.defconfig.nrf54h20_cpurad | 3 - soc/nordic/nrf54h/Kconfig.soc | 5 - tests/boards/nrf/nrfs/prj.conf | 2 + .../nrf54h20dk_nrf54h20_cpuapp_iron.overlay | 6 - .../nrf54h20dk_nrf54h20_cpuapp_iron.conf | 2 - .../nrf54h20dk_nrf54h20_cpuapp_iron.overlay | 8 -- tests/subsys/ipc/ipc_sessions/testcase.yaml | 1 + 38 files changed, 115 insertions(+), 475 deletions(-) delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf_iron.dtsi delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map_iron.dtsi delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron.dts delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_0_9_0.yaml delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_defconfig delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron.dts delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_0_9_0.yaml delete mode 100644 boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_defconfig delete mode 100644 samples/drivers/counter/alarm/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay delete mode 100644 samples/drivers/watchdog/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay delete mode 100644 samples/sysbuild/hello_world/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf delete mode 100644 samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad_iron.conf delete mode 100644 tests/drivers/adc/adc_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay delete mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf delete mode 100644 tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay diff --git a/boards/nordic/nrf54h20dk/Kconfig.defconfig b/boards/nordic/nrf54h20dk/Kconfig.defconfig index 4023f3b023206..74d20fc82fbc6 100644 --- a/boards/nordic/nrf54h20dk/Kconfig.defconfig +++ b/boards/nordic/nrf54h20dk/Kconfig.defconfig @@ -9,28 +9,26 @@ config BT_HCI_IPC config MAX_THREAD_BYTES default 3 if USERSPACE -endif # BOARD_NRF54H20DK_NRF54H20_CPUAPP - -if BOARD_NRF54H20DK_NRF54H20_CPURAD - -config MAX_THREAD_BYTES - default 3 if USERSPACE - -endif # BOARD_NRF54H20DK_NRF54H20_CPURAD - -if BOARD_NRF54H20DK_NRF54H20_CPUAPP_IRON - config ROM_START_OFFSET default 0x800 if BOOTLOADER_MCUBOOT +if !USE_DT_CODE_PARTITION + +# Application core firmware must start at this offset when not using MCUboot. +# However, the default 'zephyr,code-partition' in DT is set for MCUboot. config FLASH_LOAD_OFFSET - default 0x2c000 if !USE_DT_CODE_PARTITION + default $(dt_nodelabel_reg_addr_hex,cpuapp_boot_partition) -endif # BOARD_NRF54H20DK_NRF54H20_CPUAPP_IRON +endif # !USE_DT_CODE_PARTITION -if BOARD_NRF54H20DK_NRF54H20_CPURAD_IRON +endif # BOARD_NRF54H20DK_NRF54H20_CPUAPP + +if BOARD_NRF54H20DK_NRF54H20_CPURAD + +config MAX_THREAD_BYTES + default 3 if USERSPACE config ROM_START_OFFSET default 0x800 if BOOTLOADER_MCUBOOT -endif # BOARD_NRF54H20DK_NRF54H20_CPURAD_IRON +endif # BOARD_NRF54H20DK_NRF54H20_CPURAD diff --git a/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk b/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk index c509f968db6d8..62ad7a0d21c19 100644 --- a/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk +++ b/boards/nordic/nrf54h20dk/Kconfig.nrf54h20dk @@ -2,13 +2,9 @@ # SPDX-License-Identifier: Apache-2.0 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 || \ - BOARD_NRF54H20DK_NRF54H20_CPURAD_IRON) + select SOC_NRF54H20_CPUAPP if BOARD_NRF54H20DK_NRF54H20_CPUAPP + select SOC_NRF54H20_CPURAD if BOARD_NRF54H20DK_NRF54H20_CPURAD 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 || \ - BOARD_NRF54H20DK_NRF54H20_CPURAD_IRON) diff --git a/boards/nordic/nrf54h20dk/board.cmake b/boards/nordic/nrf54h20dk/board.cmake index 093155e932223..b9383042b0c7e 100644 --- a/boards/nordic/nrf54h20dk/board.cmake +++ b/boards/nordic/nrf54h20dk/board.cmake @@ -2,10 +2,7 @@ include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) -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_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD) if(CONFIG_SOC_NRF54H20_CPUAPP) set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuapp.JLinkScript) else() @@ -17,7 +14,7 @@ if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR endif() if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUFLPR) - if(CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR) + if(CONFIG_SOC_NRF54H20_CPUPPR) set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuppr.JLinkScript) else() set(JLINKSCRIPTFILE ${CMAKE_CURRENT_LIST_DIR}/support/nrf54h20_cpuflpr.JLinkScript) diff --git a/boards/nordic/nrf54h20dk/board.yml b/boards/nordic/nrf54h20dk/board.yml index a54cf1ae549f5..2d3d40c20e0bb 100644 --- a/boards/nordic/nrf54h20dk/board.yml +++ b/boards/nordic/nrf54h20dk/board.yml @@ -9,10 +9,6 @@ board: cpucluster: cpuppr - name: xip 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-ipc_conf.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi index 94cda5e8ee2e8..f31d909b6f94a 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf.dtsi @@ -7,17 +7,17 @@ / { ipc { cpusec_cpuapp_ipc: ipc-1-2 { - compatible = "zephyr,ipc-icmsg"; + compatible = "nordic,ironside-call"; status = "disabled"; - dcache-alignment = <32>; + memory-region = <&cpusec_cpuapp_ipc_shm>; mboxes = <&cpusec_bellboard 12>, <&cpuapp_bellboard 0>; }; cpusec_cpurad_ipc: ipc-1-3 { - compatible = "zephyr,ipc-icmsg"; + compatible = "nordic,ironside-call"; status = "disabled"; - dcache-alignment = <32>; + memory-region = <&cpusec_cpurad_ipc_shm>; mboxes = <&cpusec_bellboard 18>, <&cpurad_bellboard 0>; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf_iron.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf_iron.dtsi deleted file mode 100644 index a44db40538d26..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-ipc_conf_iron.dtsi +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* This file is to be merged with the original ipc_conf.dtsi in the future. */ - -/ { - ipc { - /delete-node/ ipc-1-2; - /delete-node/ ipc-1-3; - - cpusec_cpuapp_ipc: ipc-1-2 { - compatible = "nordic,ironside-call"; - memory-region = <&cpusec_cpuapp_ipc_shm>; - mboxes = <&cpusec_bellboard 12>, - <&cpuapp_bellboard 0>; - status = "disabled"; - }; - - cpusec_cpurad_ipc: ipc-1-3 { - compatible = "nordic,ironside-call"; - memory-region = <&cpusec_cpurad_ipc_shm>; - mboxes = <&cpusec_bellboard 18>, - <&cpurad_bellboard 0>; - status = "disabled"; - }; - }; -}; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi index f293740255400..cd595d6cd5dde 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi @@ -16,14 +16,6 @@ #size-cells = <1>; ranges = <0x0 0x2f010000 0x41000>; - cpusec_cpuapp_ipc_shm: memory@0 { - reg = <0x0 DT_SIZE_K(2)>; - }; - - cpuapp_cpusec_ipc_shm: memory@800 { - reg = <0x800 DT_SIZE_K(2)>; - }; - cpuapp_data: memory@1000 { reg = <0x1000 DT_SIZE_K(256)>; }; @@ -37,14 +29,6 @@ #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0x2f051000 0x1000>; - - cpusec_cpurad_ipc_shm: memory@0 { - reg = <0x0 DT_SIZE_K(2)>; - }; - - cpurad_cpusec_ipc_shm: memory@800 { - reg = <0x800 DT_SIZE_K(2)>; - }; }; etr_buf_ram0x_region: memory@2f0be000 { @@ -81,20 +65,44 @@ }; }; - cpuapp_cpusys_ipc_shm: memory@2f88fce0 { - reg = <0x2f88fce0 0x80>; + cpuapp_cpusys_ipc_shm: memory@2f88f600 { + reg = <0x2f88f600 0x80>; + }; + + cpusys_cpuapp_ipc_shm: memory@2f88f680 { + reg = <0x2f88f680 0x80>; + }; + + cpurad_cpusys_ipc_shm: memory@2f88f700 { + reg = <0x2f88f700 0x80>; }; - cpusys_cpuapp_ipc_shm: memory@2f88fd60 { - reg = <0x2f88fd60 0x80>; + cpusys_cpurad_ipc_shm: memory@2f88f780 { + reg = <0x2f88f780 0x80>; }; - cpurad_cpusys_ipc_shm: memory@2f88fe00 { - reg = <0x2f88fe00 0x80>; + cpusec_cpurad_ipc_shm: memory@2f88f800 { + reg = <0x2f88f800 0x80>; }; - cpusys_cpurad_ipc_shm: memory@2f88fe80 { - reg = <0x2f88fe80 0x80>; + cpurad_ironside_se_event_report: memory@2f88f880 { + reg = <0x2f88f880 0x100>; + }; + + cpurad_ironside_se_boot_report: memory@2f88f980 { + reg = <0x2f88f980 0x200>; + }; + + cpusec_cpuapp_ipc_shm: memory@2f88fb80 { + reg = <0x2f88fb80 0x80>; + }; + + cpuapp_ironside_se_event_report: memory@2f88fc00 { + reg = <0x2f88fc00 0x100>; + }; + + cpuapp_ironside_se_boot_report: memory@2f88fd00 { + reg = <0x2f88fd00 0x200>; }; /* @@ -187,27 +195,21 @@ }; &mram1x { - cpurad_rx_partitions: cpurad-rx-partitions { - compatible = "nordic,owned-partitions", "fixed-partitions"; - status = "disabled"; - nordic,access = ; + partitions { + compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; - cpurad_slot0_partition: partition@54000 { - reg = <0x54000 DT_SIZE_K(256)>; + cpuapp_boot_partition: partition@2c000 { + reg = <0x2c000 DT_SIZE_K(64)>; }; - }; - cpuapp_rx_partitions: cpuapp-rx-partitions { - compatible = "nordic,owned-partitions", "fixed-partitions"; - status = "disabled"; - nordic,access = ; - #address-cells = <1>; - #size-cells = <1>; + cpuapp_slot0_partition: partition@3c000 { + reg = <0x3c000 DT_SIZE_K(336)>; + }; - cpuapp_slot0_partition: partition@94000 { - reg = <0x94000 DT_SIZE_K(320)>; + cpurad_slot0_partition: partition@90000 { + reg = <0x90000 DT_SIZE_K(336)>; }; cpuppr_code_partition: partition@e4000 { @@ -217,21 +219,17 @@ cpuflpr_code_partition: partition@f4000 { reg = <0xf4000 DT_SIZE_K(48)>; }; - }; - cpuapp_rw_partitions: cpuapp-rw-partitions { - compatible = "nordic,owned-partitions", "fixed-partitions"; - status = "disabled"; - nordic,access = ; - #address-cells = <1>; - #size-cells = <1>; + cpuapp_slot1_partition: partition@100000 { + reg = <0x100000 DT_SIZE_K(336)>; + }; - dfu_partition: partition@100000 { - reg = < 0x100000 DT_SIZE_K(908) >; + cpurad_slot1_partition: partition@154000 { + reg = <0x154000 DT_SIZE_K(336)>; }; - storage_partition: partition@1e3000 { - reg = < 0x1e3000 DT_SIZE_K(40) >; + storage_partition: partition@1a8000 { + reg = <0x1a8000 DT_SIZE_K(40)>; }; }; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map_iron.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map_iron.dtsi deleted file mode 100644 index 2977e83758b40..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map_iron.dtsi +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* This file is to be merged with the original memory_map.dtsi in the future. - * The following nodes will be replaced: - */ -/delete-node/ &cpuapp_cpusec_ipc_shm; -/delete-node/ &cpuapp_cpusys_ipc_shm; -/delete-node/ &cpurad_cpusec_ipc_shm; -/delete-node/ &cpurad_cpusys_ipc_shm; -/delete-node/ &cpusec_cpuapp_ipc_shm; -/delete-node/ &cpusec_cpurad_ipc_shm; -/delete-node/ &cpusys_cpuapp_ipc_shm; -/delete-node/ &cpusys_cpurad_ipc_shm; -/delete-node/ &cpuapp_rw_partitions; -/delete-node/ &cpuapp_rx_partitions; -/delete-node/ &cpurad_rx_partitions; - -/ { - reserved-memory { - cpuapp_cpusys_ipc_shm: memory@2f88f600 { - reg = <0x2f88f600 0x80>; - }; - - cpusys_cpuapp_ipc_shm: memory@2f88f680 { - reg = <0x2f88f680 0x80>; - }; - - cpurad_cpusys_ipc_shm: memory@2f88f700 { - reg = <0x2f88f700 0x80>; - }; - - cpusys_cpurad_ipc_shm: memory@2f88f780 { - reg = <0x2f88f780 0x80>; - }; - - cpusec_cpurad_ipc_shm: memory@2f88f800 { - reg = <0x2f88f800 0x80>; - }; - - cpurad_ironside_se_event_report: memory@2f88f880 { - reg = <0x2f88f880 0x100>; - }; - - cpurad_ironside_se_boot_report: memory@2f88f980 { - reg = <0x2f88f980 0x200>; - }; - - cpusec_cpuapp_ipc_shm: memory@2f88fb80 { - reg = <0x2f88fb80 0x80>; - }; - - cpuapp_ironside_se_event_report: memory@2f88fc00 { - reg = <0x2f88fc00 0x100>; - }; - - cpuapp_ironside_se_boot_report: memory@2f88fd00 { - reg = <0x2f88fd00 0x200>; - }; - }; -}; - -&mram1x { - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - cpuapp_boot_partition: partition@2c000 { - reg = <0x2c000 DT_SIZE_K(64)>; - }; - - cpuapp_slot0_partition: partition@3c000 { - reg = <0x3c000 DT_SIZE_K(336)>; - }; - - cpurad_slot0_partition: partition@90000 { - reg = <0x90000 DT_SIZE_K(336)>; - }; - - cpuppr_code_partition: partition@e4000 { - reg = <0xe4000 DT_SIZE_K(64)>; - }; - - cpuflpr_code_partition: partition@f4000 { - reg = <0xf4000 DT_SIZE_K(48)>; - }; - - cpuapp_slot1_partition: partition@100000 { - reg = <0x100000 DT_SIZE_K(336)>; - }; - - cpurad_slot1_partition: partition@154000 { - reg = <0x154000 DT_SIZE_K(336)>; - }; - - storage_partition: partition@1a8000 { - reg = <0x1a8000 DT_SIZE_K(40)>; - }; - }; -}; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 9cbc9035d4f88..16c573d127e1f 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -18,10 +18,11 @@ chosen { zephyr,console = &uart136; - zephyr,code-partition = &cpuapp_slot0_partition; + zephyr,code-partition = &slot0_partition; zephyr,flash = &mram1x; zephyr,sram = &cpuapp_data; zephyr,shell-uart = &uart136; + zephyr,uart-mcumgr = &uart136; zephyr,ieee802154 = &cpuapp_ieee802154; zephyr,bt-hci = &bt_hci_ipc0; nordic,802154-spinel-ipc = &ipc0; @@ -145,8 +146,6 @@ &cpusec_cpuapp_ipc { status = "okay"; mbox-names = "tx", "rx"; - tx-region = <&cpuapp_cpusec_ipc_shm>; - rx-region = <&cpusec_cpuapp_ipc_shm>; }; &cpusec_bellboard { @@ -190,12 +189,26 @@ ipc0: &cpuapp_cpurad_ipc { status = "okay"; }; -&cpuapp_rx_partitions { - status = "okay"; +ironside_se_boot_report: &cpuapp_ironside_se_boot_report {}; + +boot_partition: &cpuapp_boot_partition { + label = "mcuboot"; }; -&cpuapp_rw_partitions { - status = "okay"; +slot0_partition: &cpuapp_slot0_partition { + label = "image-0"; +}; + +slot1_partition: &cpuapp_slot1_partition { + label = "image-1"; +}; + +slot2_partition: &cpurad_slot0_partition { + label = "image-2"; +}; + +slot3_partition: &cpurad_slot1_partition { + label = "image-3"; }; &cpuppr_vpr { diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_defconfig b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_defconfig index e1ba596d13581..70bb6a24c9c0b 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_defconfig +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_defconfig @@ -8,8 +8,6 @@ CONFIG_SERIAL=y CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y -CONFIG_USE_DT_CODE_PARTITION=y - # Enable MPU CONFIG_ARM_MPU=y diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron.dts deleted file mode 100644 index e822cf2c91199..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron.dts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "nrf54h20dk_nrf54h20_cpuapp.dts" -#include "nrf54h20dk_nrf54h20-ipc_conf_iron.dtsi" -#include "nrf54h20dk_nrf54h20-memory_map_iron.dtsi" - -/delete-node/ &cpusec_cpurad_ipc; - -/ { - chosen { - zephyr,code-partition = &slot0_partition; - zephyr,uart-mcumgr = &uart136; - }; -}; - -&cpusec_cpuapp_ipc { - mbox-names = "tx", "rx"; - status = "okay"; -}; - -ironside_se_boot_report: &cpuapp_ironside_se_boot_report {}; - -boot_partition: &cpuapp_boot_partition { - label = "mcuboot"; -}; - -slot0_partition: &cpuapp_slot0_partition { - label = "image-0"; -}; - -slot1_partition: &cpuapp_slot1_partition { - label = "image-1"; -}; - -slot2_partition: &cpurad_slot0_partition { - label = "image-2"; -}; - -slot3_partition: &cpurad_slot1_partition { - label = "image-3"; -}; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_0_9_0.yaml deleted file mode 100644 index 563a8b4ac1b77..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_0_9_0.yaml +++ /dev/null @@ -1,25 +0,0 @@ -# Copyright (c) 2025 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -identifier: nrf54h20dk/nrf54h20/cpuapp/iron -name: nRF54H20-DK-nRF54H20-Application (IronSide compatible) (revision 0.9.0) -type: mcu -arch: arm -toolchain: - - gnuarmemb - - xtools - - zephyr -sysbuild: true -ram: 256 -flash: 480 -supported: - - adc - - can - - counter - - gpio - - i2c - - pwm - - retained_mem - - spi - - watchdog - - usbd diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_defconfig b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_defconfig deleted file mode 100644 index 01f3bec393219..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_iron_defconfig +++ /dev/null @@ -1,29 +0,0 @@ -# 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 - -# 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 - -# Enable GPIO -CONFIG_GPIO=y - -# UICR generation is not supported, and when reintroduced will not use nrf-regtool. -CONFIG_NRF_REGTOOL_GENERATE_UICR=n diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index ebeb2aeeafffb..2813d5b11741c 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -24,6 +24,7 @@ zephyr,flash = &mram1x; zephyr,sram = &cpurad_ram0; zephyr,shell-uart = &uart135; + zephyr,uart-mcumgr = &uart135; zephyr,ieee802154 = &cpurad_ieee802154; zephyr,bt-hci-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; @@ -62,8 +63,6 @@ &cpusec_cpurad_ipc { status = "okay"; mbox-names = "tx", "rx"; - tx-region = <&cpurad_cpusec_ipc_shm>; - rx-region = <&cpusec_cpurad_ipc_shm>; }; &cpusec_bellboard { @@ -90,8 +89,12 @@ ipc0: &cpuapp_cpurad_ipc { status = "okay"; }; -&cpurad_rx_partitions { - status = "okay"; +slot0_partition: &cpurad_slot0_partition { + label = "image-0"; +}; + +slot1_partition: &cpurad_slot1_partition { + label = "image-1"; }; &grtc { diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron.dts deleted file mode 100644 index 16b599f554e49..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron.dts +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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" - -/ { - chosen { - zephyr,code-partition = &cpurad_slot0_partition; - zephyr,uart-mcumgr = &uart135; - }; -}; - -&cpusec_cpurad_ipc { - mbox-names = "tx", "rx"; - status = "okay"; -}; - -slot0_partition: &cpurad_slot0_partition { - label = "image-0"; -}; - -slot1_partition: &cpurad_slot1_partition { - label = "image-1"; -}; 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 deleted file mode 100644 index 034b9f7e27dd4..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_0_9_0.yaml +++ /dev/null @@ -1,20 +0,0 @@ -# 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: 336 -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 deleted file mode 100644 index 0ee0a96f99d79..0000000000000 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_iron_defconfig +++ /dev/null @@ -1,28 +0,0 @@ -# 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/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 042725a16171d..46e566cbbfe1e 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -152,10 +152,6 @@ reserved-memory { #address-cells = <1>; #size-cells = <1>; - - suit_storage_partition: memory@e1ed000 { - reg = <0xe1ed000 DT_SIZE_K(20)>; - }; }; clocks { diff --git a/samples/boards/nordic/nrf_ironside/update/README.rst b/samples/boards/nordic/nrf_ironside/update/README.rst index af72d23f3917a..484d97d0adda3 100644 --- a/samples/boards/nordic/nrf_ironside/update/README.rst +++ b/samples/boards/nordic/nrf_ironside/update/README.rst @@ -25,8 +25,8 @@ The update procedure works as follows: Once the operation has completed, you can read the boot report to verify that the update has taken place. -Building and running the application for nrf54h20dk/nrf54h20/cpuapp/iron -************************************************************************ +Building and running the application for nrf54h20dk/nrf54h20/cpuapp +******************************************************************* .. note:: You can use this application only when there is already a version of IronSide SE installed on the device. @@ -55,7 +55,7 @@ Building and running the application for nrf54h20dk/nrf54h20/cpuapp/iron .. zephyr-app-commands:: :zephyr-app: samples/boards/nordic/nrf_ironside/update - :board: nrf54h20dk/nrf54h20/cpuapp/iron + :board: nrf54h20dk/nrf54h20/cpuapp :goals: flash #. Trigger a reset: diff --git a/samples/boards/nordic/nrf_ironside/update/sample.yaml b/samples/boards/nordic/nrf_ironside/update/sample.yaml index cc127d9eb6dd2..3a5d9477da2fb 100644 --- a/samples/boards/nordic/nrf_ironside/update/sample.yaml +++ b/samples/boards/nordic/nrf_ironside/update/sample.yaml @@ -5,8 +5,8 @@ common: build_only: true tags: nrf_ironside integration_platforms: - - nrf54h20dk/nrf54h20/cpuapp/iron + - nrf54h20dk/nrf54h20/cpuapp tests: sample.boards.nordic.nrf_ironside.update: - platform_allow: nrf54h20dk/nrf54h20/cpuapp/iron + platform_allow: nrf54h20dk/nrf54h20/cpuapp diff --git a/samples/drivers/counter/alarm/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay b/samples/drivers/counter/alarm/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay deleted file mode 100644 index f65b4dd3b0ba0..0000000000000 --- a/samples/drivers/counter/alarm/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay +++ /dev/null @@ -1,3 +0,0 @@ -/* SPDX-License-Identifier: Apache-2.0 */ - -#include "nrf54h20dk_nrf54h20_common.dtsi" diff --git a/samples/drivers/mbox/sample.yaml b/samples/drivers/mbox/sample.yaml index 3725276416a6b..a0c8b9b89ace1 100644 --- a/samples/drivers/mbox/sample.yaml +++ b/samples/drivers/mbox/sample.yaml @@ -66,6 +66,7 @@ tests: integration_platforms: - nrf54h20dk/nrf54h20/cpuapp extra_args: + - mbox_CONFIG_SOC_NRF54H20_CPURAD_ENABLE=y - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpurad.conf sysbuild: true harness: console diff --git a/samples/drivers/watchdog/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay b/samples/drivers/watchdog/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay deleted file mode 100644 index 102abfc8ef27b..0000000000000 --- a/samples/drivers/watchdog/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -&wdt010 { - status = "okay"; -}; diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml index 8ede9b77d07b5..fd6194cdc4f18 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml +++ b/samples/subsys/mgmt/mcumgr/smp_svr/sample.yaml @@ -88,7 +88,7 @@ tests: - mimxrt685_evk/mimxrt685s/cm33 - rd_rw612_bga - nrf52840dk/nrf52840 - - nrf54h20dk/nrf54h20/cpuapp/iron + - nrf54h20dk/nrf54h20/cpuapp - pinnacle_100_dvk - mg100 integration_platforms: diff --git a/samples/sysbuild/hello_world/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf b/samples/sysbuild/hello_world/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf deleted file mode 100644 index ca2bc07e4f29e..0000000000000 --- a/samples/sysbuild/hello_world/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf +++ /dev/null @@ -1,4 +0,0 @@ -# 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 c8ca9cbe4c0d5..e638594c634ea 100644 --- a/samples/sysbuild/hello_world/sample.yaml +++ b/samples/sysbuild/hello_world/sample.yaml @@ -25,13 +25,9 @@ tests: - nrf54h20dk/nrf54h20/cpuapp integration_platforms: - 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 - + extra_args: + - SB_CONF_FILE=sysbuild/nrf54h20dk_nrf54h20_cpurad.conf + - hello_world_CONFIG_SOC_NRF54H20_CPURAD_ENABLE=y 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 deleted file mode 100644 index 8d4a230adbe1f..0000000000000 --- a/samples/sysbuild/hello_world/sysbuild/nrf54h20dk_nrf54h20_cpurad_iron.conf +++ /dev/null @@ -1 +0,0 @@ -SB_CONFIG_REMOTE_BOARD="nrf54h20dk/nrf54h20/cpurad/iron" diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index a6af477c61a9b..e081865377208 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -379,7 +379,7 @@ def program_hex(self): ) if self.erase: - if self.build_conf.get('CONFIG_SOC_NRF54H20_IRON'): + if self.family == 'nrf54h': self.exec_op('erase', kind='all') else: self.exec_op('erase', core='Application', kind='all') @@ -464,8 +464,8 @@ def program_hex(self): self.logger.debug(f'Erase modes: chip:{erase_arg} ext_mem:' f'{ext_mem_erase_opt}') - # Temp hack while waiting for NRF54H20_IRON support for Network in nrfutil - if self.build_conf.get('CONFIG_SOC_NRF54H20_IRON') and core == "Network": + # Temp hack while waiting for nrfutil Network support for NRF54H20 with IronSide + if self.family == 'nrf54h' and core == 'Network': core = "Application" self.op_program(self.hex_, erase_arg, ext_mem_erase_opt, defer=True, core=core) diff --git a/soc/nordic/ironside/Kconfig b/soc/nordic/ironside/Kconfig index 12cd1e70eb07e..59f63f4c022bb 100644 --- a/soc/nordic/ironside/Kconfig +++ b/soc/nordic/ironside/Kconfig @@ -3,7 +3,7 @@ config NRF_IRONSIDE bool - depends on SOC_NRF54H20_IRON || SOC_NRF9280_IRON + depends on SOC_NRF54H20 || SOC_NRF9280_IRON help This is selected by drivers interacting with Nordic IronSide firmware. @@ -28,7 +28,7 @@ config NRF_IRONSIDE_CALL_INIT_PRIORITY endif # NRF_IRONSIDE_CALL menu "Nordic IronSide services" - depends on SOC_NRF54H20_IRON || SOC_NRF9280_IRON + depends on SOC_NRF54H20 || SOC_NRF9280_IRON config NRF_IRONSIDE_CPUCONF_SERVICE bool "IronSide CPUCONF service" diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index c0e619cd1e2d9..fb29407e5723c 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -10,6 +10,7 @@ config SOC_SERIES_NRF54HX select SOC_EARLY_INIT_HOOK if ARM select SOC_LATE_INIT_HOOK if SOC_NRF54H20_CPURAD_ENABLE select NRF_PLATFORM_HALTIUM + select EXPERIMENTAL if MCUBOOT config SOC_NRF54H20_CPUAPP_COMMON bool @@ -88,6 +89,3 @@ config SOC_NRF54H20_CPUFLPR rsource "bicr/Kconfig" rsource "gpd/Kconfig" - -config SOC_NRF54H20_IRON - select EXPERIMENTAL if MCUBOOT diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp index 595cc2d388602..69bde826ba41b 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -8,9 +8,6 @@ if SOC_NRF54H20_CPUAPP config NUM_IRQS default 471 -config NRF_REGTOOL_GENERATE_UICR - default y - config SHELL_BACKEND_SERIAL default n if NRF_ETR_SHELL diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad index 1fffdeae6d2e3..8f86835b92c51 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -8,9 +8,6 @@ if SOC_NRF54H20_CPURAD config NUM_IRQS default 471 -config NRF_REGTOOL_GENERATE_UICR - default y - config PM default y diff --git a/soc/nordic/nrf54h/Kconfig.soc b/soc/nordic/nrf54h/Kconfig.soc index 62d5293bfe327..459854e13b2dc 100644 --- a/soc/nordic/nrf54h/Kconfig.soc +++ b/soc/nordic/nrf54h/Kconfig.soc @@ -33,10 +33,5 @@ config SOC_NRF54H20_CPUFLPR help nRF54H20 CPUFLPR -config SOC_NRF54H20_IRON - bool - help - Indicates that local domain firmware is compatible with Nordic IronSide SE. - config SOC default "nrf54h20" if SOC_NRF54H20 diff --git a/tests/boards/nrf/nrfs/prj.conf b/tests/boards/nrf/nrfs/prj.conf index c1a01949d601a..ee3da6976c4e6 100644 --- a/tests/boards/nrf/nrfs/prj.conf +++ b/tests/boards/nrf/nrfs/prj.conf @@ -19,3 +19,5 @@ CONFIG_LOG=y CONFIG_LOG_MODE_IMMEDIATE=n CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y + +CONFIG_SOC_NRF54H20_CPURAD_ENABLE=y diff --git a/tests/drivers/adc/adc_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay b/tests/drivers/adc/adc_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay deleted file mode 100644 index 0e01ff40bb9e8..0000000000000 --- a/tests/drivers/adc/adc_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright (c) 2025 Nordic Semiconductor - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "nrf54h20dk_nrf54h20_common.dtsi" diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf b/tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf deleted file mode 100644 index 45e31e2fae422..0000000000000 --- a/tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.conf +++ /dev/null @@ -1,2 +0,0 @@ -# Disable dcache -CONFIG_DCACHE=n diff --git a/tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay b/tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay deleted file mode 100644 index 102abfc8ef27b..0000000000000 --- a/tests/drivers/watchdog/wdt_basic_api/boards/nrf54h20dk_nrf54h20_cpuapp_iron.overlay +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright 2025 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -&wdt010 { - status = "okay"; -}; diff --git a/tests/subsys/ipc/ipc_sessions/testcase.yaml b/tests/subsys/ipc/ipc_sessions/testcase.yaml index f76a61b8d68e4..a4d34a394dd8f 100644 --- a/tests/subsys/ipc/ipc_sessions/testcase.yaml +++ b/tests/subsys/ipc/ipc_sessions/testcase.yaml @@ -20,6 +20,7 @@ tests: - nrf54h20dk/nrf54h20/cpuapp extra_args: - CONFIG_IPC_TEST_SKIP_CORE_RESET=y + - CONFIG_SOC_NRF54H20_CPURAD_ENABLE=y sample.ipc.ipc_sessions.nrf54h20dk_cpuapp_cpuppr: platform_allow: - nrf54h20dk/nrf54h20/cpuapp From 0a3b2f4d5330a6b2e107af199411d14c57721f99 Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Wed, 11 Jun 2025 11:07:04 +0200 Subject: [PATCH 04/40] boards: nrf54h20dk: Limit app core FLASH_LOAD_SIZE CONFIG_USE_DT_CODE_PARTITION had to be disabled to add MCUboot support. As a result, CONFIG_FLASH_LOAD_SIZE was left at zero, which means that the linker would claim all available MRAM for the app core. For now, we can't allow that, because the default nRF54H20 DK memory map divides MRAM between multiple cores in order to support various samples. Signed-off-by: Grzegorz Swiderski --- boards/nordic/nrf54h20dk/Kconfig.defconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/nordic/nrf54h20dk/Kconfig.defconfig b/boards/nordic/nrf54h20dk/Kconfig.defconfig index 74d20fc82fbc6..d2ac190fd1781 100644 --- a/boards/nordic/nrf54h20dk/Kconfig.defconfig +++ b/boards/nordic/nrf54h20dk/Kconfig.defconfig @@ -19,6 +19,13 @@ if !USE_DT_CODE_PARTITION config FLASH_LOAD_OFFSET default $(dt_nodelabel_reg_addr_hex,cpuapp_boot_partition) +# This is meant to span 'cpuapp_boot_partition' and 'cpuapp_slot0_partition' +# in the default memory map. +config FLASH_LOAD_SIZE + default $(add_hex, $(dt_nodelabel_reg_addr_hex,cpuapp_slot0_partition), \ + $(dt_nodelabel_reg_size_hex,cpuapp_slot0_partition), \ + -$(dt_nodelabel_reg_addr_hex,cpuapp_boot_partition)) + endif # !USE_DT_CODE_PARTITION endif # BOARD_NRF54H20DK_NRF54H20_CPUAPP From 1d9704a1ef35b9aec02b6f07c4248036a3e2835d Mon Sep 17 00:00:00 2001 From: Grzegorz Swiderski Date: Wed, 11 Jun 2025 11:07:04 +0200 Subject: [PATCH 05/40] modules: hal_nordic: Remove nrf-regtool support for nRF54H nrf-regtool will not be used as part of IronSide SE compatible builds. It will remain in use for the nRF92 series, until that too undergoes a switch from SDFW to IronSide SE. Signed-off-by: Grzegorz Swiderski --- modules/hal_nordic/Kconfig.nrf_regtool | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/hal_nordic/Kconfig.nrf_regtool b/modules/hal_nordic/Kconfig.nrf_regtool index 396ec2050a052..12f7a53f471cc 100644 --- a/modules/hal_nordic/Kconfig.nrf_regtool +++ b/modules/hal_nordic/Kconfig.nrf_regtool @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 menu "nrf-regtool options" - depends on SOC_SERIES_NRF54HX || SOC_SERIES_NRF92X + depends on SOC_SERIES_NRF92X config NRF_REGTOOL_GENERATE_UICR bool "Generate UICR" From b35158bf9de90280eee9e3e96a5b465ce0dd86b9 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Wed, 18 Jun 2025 11:46:57 +0200 Subject: [PATCH 06/40] boards: nordic: update nrf54h20dk memory map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update memory map to be compatible with latest IronSide. 180kB MRAM is reserved. Co-authored-by: Håkon Amundsen Signed-off-by: Håkon Amundsen Signed-off-by: Jonathan Nilsen --- .../nrf54h20dk_nrf54h20-memory_map.dtsi | 22 +++++++++---------- .../nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml | 2 +- .../nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi index cd595d6cd5dde..7f568005a2259 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi @@ -200,16 +200,16 @@ #address-cells = <1>; #size-cells = <1>; - cpuapp_boot_partition: partition@2c000 { - reg = <0x2c000 DT_SIZE_K(64)>; + cpuapp_boot_partition: partition@30000 { + reg = <0x30000 DT_SIZE_K(64)>; }; - cpuapp_slot0_partition: partition@3c000 { - reg = <0x3c000 DT_SIZE_K(336)>; + cpuapp_slot0_partition: partition@40000 { + reg = <0x40000 DT_SIZE_K(328)>; }; - cpurad_slot0_partition: partition@90000 { - reg = <0x90000 DT_SIZE_K(336)>; + cpurad_slot0_partition: partition@92000 { + reg = <0x92000 DT_SIZE_K(328)>; }; cpuppr_code_partition: partition@e4000 { @@ -221,15 +221,15 @@ }; cpuapp_slot1_partition: partition@100000 { - reg = <0x100000 DT_SIZE_K(336)>; + reg = <0x100000 DT_SIZE_K(328)>; }; - cpurad_slot1_partition: partition@154000 { - reg = <0x154000 DT_SIZE_K(336)>; + cpurad_slot1_partition: partition@152000 { + reg = <0x152000 DT_SIZE_K(328)>; }; - storage_partition: partition@1a8000 { - reg = <0x1a8000 DT_SIZE_K(40)>; + storage_partition: partition@1a4000 { + reg = <0x1a4000 DT_SIZE_K(40)>; }; }; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml index 1884ce0a4d0d3..832689be8e1d1 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml @@ -10,7 +10,7 @@ toolchain: - zephyr sysbuild: true ram: 256 -flash: 296 +flash: 392 supported: - adc - can diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml index de557fcc2cdbb..8567494d1e3aa 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad_0_9_0.yaml @@ -10,7 +10,7 @@ toolchain: - zephyr sysbuild: true ram: 192 -flash: 256 +flash: 328 supported: - counter - gpio From 41647d2fa8b6b7c29e20ed6ac6dc4e797ed2e934 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Fri, 20 Jun 2025 10:52:01 +0200 Subject: [PATCH 07/40] boards: nordic: nrf54h20dk: refactor RAM memory map Refactor the default RAM memory map on nrf54h20dk: Removes use of "nordic,owned-memory" which is no longer needed on nrf54h20. Reserved memory nodes that were under "nordic,owned-memory" have been moved directly under reserved-memory. The memory shared between cpuapp-cpusec and cpurad-cpusec in RAM0x is no longer used with IronSide, since IPC buffers toward the secure domain are at new fixed locations. The cpuapp_data region has been expanded to fill the available space in RAM0x when removing these shared memory regions. Signed-off-by: Jonathan Nilsen --- .../nrf54h20dk_nrf54h20-memory_map.dtsi | 135 +++++------------- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 12 -- .../nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml | 2 +- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts | 8 -- dts/vendor/nordic/nrf54h20.dtsi | 1 - .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 5 - .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 4 - .../soc/nrf54h20_cpuapp.overlay | 4 - .../nordic-ppr/soc/nrf54h20_cpuapp.overlay | 4 - .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 8 -- .../boards/nrf54h20dk_nrf54h20_cpuapp.overlay | 4 - 11 files changed, 34 insertions(+), 153 deletions(-) delete mode 100644 tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi index 7f568005a2259..aa6ebc629cc27 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi @@ -7,62 +7,20 @@ / { reserved-memory { - cpuapp_ram0x_region: memory@2f010000 { - compatible = "nordic,owned-memory"; - reg = <0x2f010000 DT_SIZE_K(260)>; - status = "disabled"; - nordic,access = ; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2f010000 0x41000>; - - cpuapp_data: memory@1000 { - reg = <0x1000 DT_SIZE_K(256)>; - }; + cpuapp_data: memory@2f000000 { + reg = <0x2f000000 DT_SIZE_K(760)>; }; - cpurad_ram0x_region: memory@2f051000 { - compatible = "nordic,owned-memory"; - reg = <0x2f051000 DT_SIZE_K(4)>; - status = "disabled"; - nordic,access = ; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2f051000 0x1000>; - }; - - etr_buf_ram0x_region: memory@2f0be000 { - compatible = "nordic,owned-memory"; + etr_buffer: memory@2f0be000 { reg = <0x2f0be000 DT_SIZE_K(4)>; - status = "disabled"; - nordic,access = ; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2f0be000 0x1000>; - - /* TODO In future move this region to cpuapp_ram0x_region. */ - etr_buffer: memory@0 { - reg = <0x0 DT_SIZE_K(4)>; - }; }; - cpuapp_cpurad_ram0x_region: memory@2f0bf000 { - compatible = "nordic,owned-memory"; - reg = <0x2f0bf000 DT_SIZE_K(4)>; - status = "disabled"; - nordic,access = , - ; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2f0bf000 0x1000>; - - cpuapp_cpurad_ipc_shm: memory@0 { - reg = <0x0 DT_SIZE_K(2)>; - }; + cpuapp_cpurad_ipc_shm: memory@2f0bf000 { + reg = <0x2f0bf000 DT_SIZE_K(2)>; + }; - cpurad_cpuapp_ipc_shm: memory@800 { - reg = <0x800 DT_SIZE_K(2)>; - }; + cpurad_cpuapp_ipc_shm: memory@2f0bf800 { + reg = <0x2f0bf800 DT_SIZE_K(2)>; }; cpuapp_cpusys_ipc_shm: memory@2f88f600 { @@ -105,80 +63,53 @@ reg = <0x2f88fd00 0x200>; }; - /* - * NOTE: FLPR has a direct bridge with RAM21 that bypasses MPC. - * This means that when this region is marked as non-executable, - * only FLPR can execute code from it. - */ - ram21_region: memory@2f890000 { - compatible = "nordic,owned-memory"; - status = "disabled"; - reg = <0x2f890000 DT_SIZE_K(64)>; - nordic,access = ; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2f890000 0x10000>; - - cpuflpr_code_data: memory@0 { - reg = <0x0 DT_SIZE_K(46)>; - }; - - cpuapp_cpuflpr_ipc_shm: memory@b800 { - reg = <0xb800 DT_SIZE_K(1)>; - }; + cpuflpr_code_data: memory@2f890000 { + reg = <0x2f890000 DT_SIZE_K(46)>; + }; - cpuflpr_cpuapp_ipc_shm: memory@bc00 { - reg = <0xbc00 DT_SIZE_K(1)>; - }; + cpuapp_cpuflpr_ipc_shm: memory@2f89b800 { + reg = <0x2f89b800 DT_SIZE_K(1)>; + }; - dma_fast_region: memory@c000 { - compatible = "zephyr,memory-region"; - reg = <0xc000 DT_SIZE_K(16)>; - status = "disabled"; - #memory-region-cells = <0>; - zephyr,memory-region = "DMA_RAM21"; - zephyr,memory-attr = <( DT_MEM_DMA | DT_MEM_CACHEABLE )>; - }; + cpuflpr_cpuapp_ipc_shm: memory@2f89bc00 { + reg = <0x2f89bc00 DT_SIZE_K(1)>; }; - cpuppr_ram3x_region: memory@2fc00000 { - compatible = "nordic,owned-memory"; - reg = <0x2fc00000 DT_SIZE_K(64)>; + dma_fast_region: memory@2f89c000 { + compatible = "zephyr,memory-region"; + reg = <0x2f89c000 DT_SIZE_K(16)>; status = "disabled"; - nordic,access = ; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x0 0x2fc00000 0x10000>; + #memory-region-cells = <0>; + zephyr,memory-region = "DMA_RAM21"; + zephyr,memory-attr = <( DT_MEM_DMA | DT_MEM_CACHEABLE )>; + }; - cpuppr_code_data: memory@0 { - reg = <0x0 DT_SIZE_K(62)>; - }; + cpuppr_code_data: memory@2fc00000 { + reg = <0x2fc00000 DT_SIZE_K(62)>; + }; - cpuapp_cpuppr_ipc_shm: memory@f800 { - reg = <0xf800 DT_SIZE_K(1)>; - }; + cpuapp_cpuppr_ipc_shm: memory@2fc0f800 { + reg = <0x2fc0f800 DT_SIZE_K(1)>; + }; - cpuppr_cpuapp_ipc_shm: memory@fc00 { - reg = <0xfc00 DT_SIZE_K(1)>; - }; + cpuppr_cpuapp_ipc_shm: memory@2fc0fc00 { + reg = <0x2fc0fc00 DT_SIZE_K(1)>; }; cpuapp_dma_region: memory@2fc12000 { - compatible = "nordic,owned-memory", "zephyr,memory-region"; + compatible = "zephyr,memory-region"; reg = <0x2fc12000 DT_SIZE_K(4)>; status = "disabled"; #memory-region-cells = <0>; - nordic,access = ; zephyr,memory-region = "DMA_RAM3x_APP"; zephyr,memory-attr = <( DT_MEM_DMA )>; }; cpurad_dma_region: memory@2fc13000 { - compatible = "nordic,owned-memory", "zephyr,memory-region"; + compatible = "zephyr,memory-region"; reg = <0x2fc13000 DT_SIZE_K(1)>; status = "disabled"; #memory-region-cells = <0>; - nordic,access = ; zephyr,memory-region = "DMA_RAM3x_RAD"; zephyr,memory-attr = <( DT_MEM_DMA )>; }; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 16c573d127e1f..47255b0c9947c 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -109,18 +109,6 @@ }; }; -&cpuapp_ram0x_region { - status = "okay"; -}; - -&etr_buf_ram0x_region { - status = "okay"; -}; - -&ram21_region { - status = "okay"; -}; - &cpuapp_bellboard { status = "okay"; interrupts = <96 NRF_DEFAULT_IRQ_PRIORITY>; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml index 832689be8e1d1..4e82987d28e59 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp_0_9_0.yaml @@ -9,7 +9,7 @@ toolchain: - gnuarmemb - zephyr sysbuild: true -ram: 256 +ram: 760 flash: 392 supported: - adc diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index 2813d5b11741c..5473d9a7405ad 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -36,14 +36,6 @@ }; }; -&cpuapp_cpurad_ram0x_region { - status = "okay"; -}; - -&cpurad_ram0x_region { - status = "okay"; -}; - &cpurad_bellboard { status = "okay"; interrupts = <96 NRF_DEFAULT_IRQ_PRIORITY>; diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 46e566cbbfe1e..98a915613ef2a 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -14,7 +14,6 @@ #include #include #include -#include #include /delete-node/ &sw_pwm; diff --git a/samples/application_development/code_relocation_nocopy/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/application_development/code_relocation_nocopy/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index ab53f12725d77..98d67e2ad082b 100644 --- a/samples/application_development/code_relocation_nocopy/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/samples/application_development/code_relocation_nocopy/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -1,10 +1,5 @@ -&cpuapp_ram0x_region { - nordic,access = ; -}; - &xip_region { status = "okay"; - nordic,access = ; }; &mx25uw63 { diff --git a/samples/boards/nordic/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/samples/boards/nordic/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index bf5ba18d20442..970377c4d8962 100644 --- a/samples/boards/nordic/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/samples/boards/nordic/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -7,10 +7,6 @@ status = "okay"; }; -&cpuppr_ram3x_region { - status = "okay"; -}; - &cpuflpr_vpr { status = "okay"; }; diff --git a/snippets/nordic-ppr-xip/soc/nrf54h20_cpuapp.overlay b/snippets/nordic-ppr-xip/soc/nrf54h20_cpuapp.overlay index 4d02921660b54..2d884a3455a2d 100644 --- a/snippets/nordic-ppr-xip/soc/nrf54h20_cpuapp.overlay +++ b/snippets/nordic-ppr-xip/soc/nrf54h20_cpuapp.overlay @@ -3,10 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -&cpuppr_ram3x_region { - status = "okay"; -}; - &cpuppr_vpr { execution-memory = <&cpuppr_code_partition>; /delete-property/ source-memory; diff --git a/snippets/nordic-ppr/soc/nrf54h20_cpuapp.overlay b/snippets/nordic-ppr/soc/nrf54h20_cpuapp.overlay index 75128f42a13f7..ae635c9ca9b68 100644 --- a/snippets/nordic-ppr/soc/nrf54h20_cpuapp.overlay +++ b/snippets/nordic-ppr/soc/nrf54h20_cpuapp.overlay @@ -3,10 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -&cpuppr_ram3x_region { - status = "okay"; -}; - &uart135 { status = "reserved"; }; diff --git a/tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay deleted file mode 100644 index ad84324a3e940..0000000000000 --- a/tests/arch/common/ramfunc/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ /dev/null @@ -1,8 +0,0 @@ -/* - * Copyright (c) 2024 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -&cpuapp_ram0x_region { - nordic,access = ; -}; diff --git a/tests/boards/nrf/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/boards/nrf/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay index bf5ba18d20442..970377c4d8962 100644 --- a/tests/boards/nrf/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay +++ b/tests/boards/nrf/coresight_stm/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -7,10 +7,6 @@ status = "okay"; }; -&cpuppr_ram3x_region { - status = "okay"; -}; - &cpuflpr_vpr { status = "okay"; }; From d073fa54ff8260acbb7d43c25b8670e9e6303643 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Wed, 18 Jun 2025 11:55:27 +0200 Subject: [PATCH 08/40] dts: nordic: update UICR definition on nrf54h20 With IronSide SE there is only one defined UICR which is at the location of the APPLICATION UICR. Update the devicetree definition accordingly, and use the "nordic,nrf-uicr" compatible on the node since the domain distinction added by the v2 compatible is no longer relevant. Signed-off-by: Jonathan Nilsen --- dts/vendor/nordic/nrf54h20.dtsi | 11 ++--------- soc/nordic/validate_base_addresses.c | 4 ++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 98a915613ef2a..21b8056ff040f 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -226,13 +226,12 @@ write-block-size = <16>; }; - cpuapp_uicr: uicr@fff8000 { - compatible = "nordic,nrf-uicr-v2"; + uicr: uicr@fff8000 { + compatible = "nordic,nrf-uicr"; reg = <0xfff8000 DT_SIZE_K(2)>; #address-cells = <1>; #size-cells = <1>; ranges = <0x0 0xfff8000 DT_SIZE_K(2)>; - domain = <2>; bicr: bicr@7b0 { compatible = "nordic,nrf-bicr"; @@ -240,12 +239,6 @@ }; }; - cpurad_uicr: uicr@fffa000 { - compatible = "nordic,nrf-uicr-v2"; - reg = <0xfffa000 DT_SIZE_K(2)>; - domain = <3>; - }; - ficr: ficr@fffe000 { compatible = "nordic,nrf-ficr"; reg = <0xfffe000 DT_SIZE_K(2)>; diff --git a/soc/nordic/validate_base_addresses.c b/soc/nordic/validate_base_addresses.c index e065aa7ccffd1..2b974147dca5c 100644 --- a/soc/nordic/validate_base_addresses.c +++ b/soc/nordic/validate_base_addresses.c @@ -336,7 +336,11 @@ CHECK_DT_REG(uart134, NRF_UARTE134); CHECK_DT_REG(uart135, NRF_UARTE135); CHECK_DT_REG(uart136, NRF_UARTE136); CHECK_DT_REG(uart137, NRF_UARTE137); +#if !defined(CONFIG_SOC_SERIES_NRF54HX) CHECK_DT_REG(uicr, NRF_UICR); +#else +CHECK_DT_REG(uicr, NRF_APPLICATION_UICR); +#endif CHECK_DT_REG(cpuapp_uicr, NRF_APPLICATION_UICR); CHECK_DT_REG(bicr, NRF_APPLICATION_BICR); CHECK_DT_REG(cpurad_uicr, NRF_RADIOCORE_UICR); From 22ca348242f9e69d98c4502e8a8093fe2204ed64 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Wed, 18 Jun 2025 12:02:39 +0200 Subject: [PATCH 09/40] soc: nordic: add IronSide SE compatible UICR support Add support for generating UICR and associated artifacts in a format compatible with IronSide SE, to be used for Nordic SoCs in the Haltium family. The main feature added with this is the ability to configure certain global domain peripherals that are managed by the secure domain through setting UICR.PERIPHCONF. This register points at a blob of (register address, register value) pairs which are loaded into the peripherals by IronSide SE ahead of the application boot. The added helper macros in uicr.h can be used to add register configurations to the PERIPHCONF. Entries added through these macros are then extracted by a script, post-processed and placed in a blob located at specific part of MRAM. A default PERIPHCONF configuration has been added for the nrf54h20 soc to support the standard BLE use case (matching the configuration in the soc devicetree). Signed-off-by: Jonathan Nilsen --- .../nrf54h20dk_nrf54h20-memory_map.dtsi | 4 + soc/nordic/common/CMakeLists.txt | 4 + soc/nordic/common/Kconfig | 1 + soc/nordic/common/uicr/CMakeLists.txt | 36 ++ soc/nordic/common/uicr/Kconfig | 31 ++ soc/nordic/common/uicr/gen_uicr.py | 270 +++++++++++++++ soc/nordic/common/uicr/uicr.h | 308 ++++++++++++++++++ soc/nordic/common/uicr/uicr.ld | 11 + soc/nordic/nrf54h/CMakeLists.txt | 1 + soc/nordic/nrf54h/uicr_periphconf_table.c | 52 +++ 10 files changed, 718 insertions(+) create mode 100644 soc/nordic/common/uicr/CMakeLists.txt create mode 100644 soc/nordic/common/uicr/Kconfig create mode 100644 soc/nordic/common/uicr/gen_uicr.py create mode 100644 soc/nordic/common/uicr/uicr.h create mode 100644 soc/nordic/common/uicr/uicr.ld create mode 100644 soc/nordic/nrf54h/uicr_periphconf_table.c diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi index aa6ebc629cc27..b6a53955c60e3 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20-memory_map.dtsi @@ -162,5 +162,9 @@ storage_partition: partition@1a4000 { reg = <0x1a4000 DT_SIZE_K(40)>; }; + + periphconf_partition: partition@1ae000 { + reg = <0x1ae000 DT_SIZE_K(8)>; + }; }; }; diff --git a/soc/nordic/common/CMakeLists.txt b/soc/nordic/common/CMakeLists.txt index ac75d0838696d..825be4842fb72 100644 --- a/soc/nordic/common/CMakeLists.txt +++ b/soc/nordic/common/CMakeLists.txt @@ -3,6 +3,10 @@ add_subdirectory_ifdef(CONFIG_RISCV_CORE_NORDIC_VPR vpr) +if(CONFIG_NRF_PERIPHCONF_SECTION OR CONFIG_NRF_HALTIUM_GENERATE_UICR) + add_subdirectory(uicr) +endif() + # Let SystemInit() be called in place of soc_reset_hook() by default. zephyr_linker_symbol(SYMBOL soc_reset_hook EXPR "@SystemInit@") diff --git a/soc/nordic/common/Kconfig b/soc/nordic/common/Kconfig index 059274fd299f8..782d9452b6771 100644 --- a/soc/nordic/common/Kconfig +++ b/soc/nordic/common/Kconfig @@ -49,3 +49,4 @@ source "subsys/logging/Kconfig.template.log_config" endif # MRAM_LATENCY rsource "vpr/Kconfig" +rsource "uicr/Kconfig" diff --git a/soc/nordic/common/uicr/CMakeLists.txt b/soc/nordic/common/uicr/CMakeLists.txt new file mode 100644 index 0000000000000..0bde6b47f5766 --- /dev/null +++ b/soc/nordic/common/uicr/CMakeLists.txt @@ -0,0 +1,36 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_NRF_PERIPHCONF_SECTION) + zephyr_linker_sources(SECTIONS uicr.ld) +endif() + +if(CONFIG_NRF_HALTIUM_GENERATE_UICR) + if(CONFIG_NRF_PERIPHCONF_SECTION) + set(in_periphconf_elf_arg + --in-periphconf-elf $ + ) + endif() + + if(CONFIG_NRF_HALTIUM_UICR_PERIPHCONF) + set(periphconf_hex_file ${PROJECT_BINARY_DIR}/periphconf.hex) + set(out_periphconf_hex_arg + --out-periphconf-hex ${periphconf_hex_file} + ) + list(APPEND optional_byproducts ${periphconf_hex_file}) + endif() + + set(uicr_hex_file ${PROJECT_BINARY_DIR}/uicr.hex) + set_property(GLOBAL APPEND PROPERTY extra_post_build_commands + COMMAND ${CMAKE_COMMAND} -E env PYTHONPATH=${ZEPHYR_BASE}/scripts/dts/python-devicetree/src + ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/gen_uicr.py + --in-config ${DOTCONFIG} + --in-edt-pickle ${EDT_PICKLE} + ${in_periphconf_elf_arg} + ${out_periphconf_hex_arg} + --out-uicr-hex ${uicr_hex_file} + ) + set_property(GLOBAL APPEND PROPERTY extra_post_build_byproducts + ${uicr_hex_file} ${optional_byproducts} + ) +endif() diff --git a/soc/nordic/common/uicr/Kconfig b/soc/nordic/common/uicr/Kconfig new file mode 100644 index 0000000000000..f132510a7a5d0 --- /dev/null +++ b/soc/nordic/common/uicr/Kconfig @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config NRF_HALTIUM_GENERATE_UICR + bool "Generate UICR file" + depends on SOC_NRF54H20_CPUAPP + default y + help + Generate UICR HEX file. + +if NRF_HALTIUM_GENERATE_UICR + +config NRF_HALTIUM_UICR_PERIPHCONF + bool "Initialize global domain peripherals" + default y + help + Generates a blob containing static global domain peripheral initialization + values extracted from the build artifacts, and configures UICR.PERIPHCONF + to point at the blob. The initialization values are then loaded ahead of + ahead of the application boot. + +endif + +config NRF_PERIPHCONF_SECTION + bool "Populate global peripheral initialization section" + default y if SOC_NRF54H20_CPUAPP + depends on LINKER_DEVNULL_SUPPORT + imply LINKER_DEVNULL_MEMORY + help + Include static global domain peripheral initialization values from the + build in a dedicated section in the devnull region. diff --git a/soc/nordic/common/uicr/gen_uicr.py b/soc/nordic/common/uicr/gen_uicr.py new file mode 100644 index 0000000000000..50f96eab566f7 --- /dev/null +++ b/soc/nordic/common/uicr/gen_uicr.py @@ -0,0 +1,270 @@ +""" +Copyright (c) 2025 Nordic Semiconductor ASA +SPDX-License-Identifier: Apache-2.0 +""" + +from __future__ import annotations + +import argparse +import ctypes as c +import math +import pickle +import re +import sys +from collections import defaultdict +from itertools import groupby + +from elftools.elf.elffile import ELFFile +from intelhex import IntelHex + +# Name of the ELF section containing PERIPHCONF entries. +# Must match the name used in the linker script. +PERIPHCONF_SECTION = "uicr_periphconf_entry" + +# Expected nodelabel of the UICR devicetree node, used to extract its location from the devicetree. +UICR_NODELABEL = "uicr" +# Nodelabel of the PERIPHCONF devicetree node, used to extract its location from the devicetree. +PERIPHCONF_NODELABEL = "periphconf_partition" + +# Common values for representing enabled/disabled in the UICR format. +ENABLED_VALUE = 0xFFFF_FFFF +DISABLED_VALUE = 0xBD23_28A8 + + +class ScriptError(RuntimeError): ... + + +class PeriphconfEntry(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("regptr", c.c_uint32), + ("value", c.c_uint32), + ] + + +PERIPHCONF_ENTRY_SIZE = c.sizeof(PeriphconfEntry) + + +class Approtect(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("APPLICATION", c.c_uint32), + ("RADIOCORE", c.c_uint32), + ("RESERVED", c.c_uint32), + ("CORESIGHT", c.c_uint32), + ] + + +class Protectedmem(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("ENABLE", c.c_uint32), + ("SIZE4KB", c.c_uint32), + ] + + +class Recovery(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("ENABLE", c.c_uint32), + ("PROCESSOR", c.c_uint32), + ("INITSVTOR", c.c_uint32), + ("SIZE4KB", c.c_uint32), + ] + + +class Its(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("ENABLE", c.c_uint32), + ("ADDRESS", c.c_uint32), + ("APPLICATIONSIZE", c.c_uint32), + ("RADIOCORESIZE", c.c_uint32), + ] + + +class Periphconf(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("ENABLE", c.c_uint32), + ("ADDRESS", c.c_uint32), + ("MAXCOUNT", c.c_uint32), + ] + + +class Mpcconf(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("ENABLE", c.c_uint32), + ("ADDRESS", c.c_uint32), + ("MAXCOUNT", c.c_uint32), + ] + + +class Uicr(c.LittleEndianStructure): + _pack_ = 1 + _fields_ = [ + ("VERSION", c.c_uint32), + ("RESERVED", c.c_uint32), + ("LOCK", c.c_uint32), + ("RESERVED1", c.c_uint32), + ("APPROTECT", Approtect), + ("ERASEPROTECT", c.c_uint32), + ("PROTECTEDMEM", Protectedmem), + ("RECOVERY", Recovery), + ("ITS", Its), + ("RESERVED2", c.c_uint32 * 7), + ("PERIPHCONF", Periphconf), + ("MPCCONF", Mpcconf), + ] + + +def main() -> None: + parser = argparse.ArgumentParser( + allow_abbrev=False, + description=( + "Generate artifacts for the UICR and associated configuration blobs from application " + "build outputs. User Information Configuration Registers (UICR), in the context of " + "certain Nordic SoCs, are used to configure system resources, like memory and " + "peripherals, and to protect the device in various ways." + ), + ) + parser.add_argument( + "--in-config", + required=True, + type=argparse.FileType("r"), + help="Path to the .config file from the application build", + ) + parser.add_argument( + "--in-edt-pickle", + required=True, + type=argparse.FileType("rb"), + help="Path to the edt.pickle file from the application build", + ) + parser.add_argument( + "--in-periphconf-elf", + dest="in_periphconf_elfs", + default=[], + action="append", + type=argparse.FileType("rb"), + help=( + "Path to an ELF file to extract PERIPHCONF data from. Can be provided multiple times. " + "The PERIPHCONF data from each ELF file is combined in a single list which is sorted " + "by ascending address and cleared of duplicate entries." + ), + ) + parser.add_argument( + "--out-uicr-hex", + required=True, + type=argparse.FileType("w", encoding="utf-8"), + help="Path to write the generated UICR HEX file to", + ) + parser.add_argument( + "--out-periphconf-hex", + default=None, + type=argparse.FileType("w", encoding="utf-8"), + help="Path to write the generated PERIPHCONF HEX file to", + ) + args = parser.parse_args() + + try: + init_values = DISABLED_VALUE.to_bytes(4, "little") * (c.sizeof(Uicr) // 4) + uicr = Uicr.from_buffer_copy(init_values) + + kconfig_str = args.in_config.read() + kconfig = parse_kconfig(kconfig_str) + + edt = pickle.load(args.in_edt_pickle) + + try: + periphconf_partition = edt.label2node[PERIPHCONF_NODELABEL] + except LookupError as e: + raise ScriptError( + "Failed to find a PERIPHCONF partition in the devicetree. " + f"Expected a DT node with label '{PERIPHCONF_NODELABEL}'." + ) from e + + flash_base_address = periphconf_partition.flash_controller.regs[0].addr + periphconf_address = flash_base_address + periphconf_partition.regs[0].addr + periphconf_size = periphconf_partition.regs[0].size + + periphconf_combined = extract_and_combine_periphconfs(args.in_periphconf_elfs) + padding_len = periphconf_size - len(periphconf_combined) + periphconf_final = periphconf_combined + bytes([0xFF for _ in range(padding_len)]) + + if kconfig.get("CONFIG_NRF_HALTIUM_UICR_PERIPHCONF") == "y": + uicr.PERIPHCONF.ENABLE = ENABLED_VALUE + uicr.PERIPHCONF.ADDRESS = periphconf_address + uicr.PERIPHCONF.MAXCOUNT = math.floor(periphconf_size / 8) + + try: + uicr_node = edt.label2node[UICR_NODELABEL] + except LookupError as e: + raise ScriptError( + "Failed to find UICR node in the devicetree. " + f"Expected a DT node with label '{UICR_NODELABEL}'." + ) from e + + uicr_hex = IntelHex() + uicr_hex.frombytes(bytes(uicr), offset=uicr_node.regs[0].addr) + + uicr_hex.write_hex_file(args.out_uicr_hex) + + if args.out_periphconf_hex is not None: + periphconf_hex = IntelHex() + periphconf_hex.frombytes(periphconf_final, offset=periphconf_address) + periphconf_hex.write_hex_file(args.out_periphconf_hex) + + except ScriptError as e: + print(f"Error: {e!s}") + sys.exit(1) + + +def extract_and_combine_periphconfs(elf_files: list[argparse.FileType]) -> bytes: + combined_periphconf = [] + + for in_file in elf_files: + elf = ELFFile(in_file) + conf_section = elf.get_section_by_name(PERIPHCONF_SECTION) + if conf_section is None: + continue + + conf_section_data = conf_section.data() + num_entries = len(conf_section_data) // PERIPHCONF_ENTRY_SIZE + periphconf = (PeriphconfEntry * num_entries).from_buffer_copy(conf_section_data) + combined_periphconf.extend(periphconf) + + combined_periphconf.sort(key=lambda e: e.regptr) + deduplicated_periphconf = [] + + for regptr, regptr_entries in groupby(combined_periphconf, key=lambda e: e.regptr): + entries = list(regptr_entries) + if len(entries) > 1: + unique_values = {e.value for e in entries} + if len(unique_values) > 1: + raise ScriptError( + f"PERIPHCONF has conflicting values for register 0x{regptr:09_x}: " + + ", ".join([f"0x{val:09_x}" for val in unique_values]) + ) + deduplicated_periphconf.append(entries[0]) + + final_periphconf = (PeriphconfEntry * len(deduplicated_periphconf))() + for i, entry in enumerate(deduplicated_periphconf): + final_periphconf[i] = entry + + return bytes(final_periphconf) + + +def parse_kconfig(content: str) -> dict[str, str | None]: + result = defaultdict(None) + match_iter = re.finditer( + r"^(?P(SB_)?CONFIG_[^=\s]+)=(?P[^\s#])+$", content, re.MULTILINE + ) + for match in match_iter: + result[match["config"]] = match["value"] + + return result + + +if __name__ == "__main__": + main() diff --git a/soc/nordic/common/uicr/uicr.h b/soc/nordic/common/uicr/uicr.h new file mode 100644 index 0000000000000..7ceb12429e221 --- /dev/null +++ b/soc/nordic/common/uicr/uicr.h @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef SOC_NORDIC_COMMON_UICR_UICR_H_ +#define SOC_NORDIC_COMMON_UICR_UICR_H_ + +#include +#include +#include +#include +#include + +/** Entry in the PERIPHCONF table. */ +struct uicr_periphconf_entry { + /** Register pointer. */ + uint32_t regptr; + /** Register value. */ + uint32_t value; +} __packed; + +/** @brief Add an entry to the PERIPHCONF table section. + * + * This should typically not be used directly. + * Prefer to use one of the higher level macros. + */ +#define UICR_PERIPHCONF_ADD(_regptr, _value) \ + static STRUCT_SECTION_ITERABLE(uicr_periphconf_entry, \ + _UICR_PERIPHCONF_ENTRY_NAME(__COUNTER__)) = { \ + .regptr = (_regptr), \ + .value = (_value), \ + } + +#define _UICR_PERIPHCONF_ENTRY_NAME(_id) __UICR_PERIPHCONF_ENTRY_NAME(_id) +#define __UICR_PERIPHCONF_ENTRY_NAME(_id) _uicr_periphconf_entry_##_id + +/** @brief Add a PERIPHCONF entry for a SPU PERIPH[n].PERM register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Peripheral slave index on the bus (PERIPH[n] register index). + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _dmasec If true, set DMASEC to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_PERIPH_PERM_SET(_spu, _index, _secattr, _dmasec, _ownerid) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->PERIPH[(_index)].PERM, \ + (uint32_t)((((_ownerid) << SPU_PERIPH_PERM_OWNERID_Pos) & \ + SPU_PERIPH_PERM_OWNERID_Msk) | \ + (((_secattr) ? SPU_PERIPH_PERM_SECATTR_Secure \ + : SPU_PERIPH_PERM_SECATTR_NonSecure) \ + << SPU_PERIPH_PERM_SECATTR_Pos) | \ + (((_dmasec) ? SPU_PERIPH_PERM_DMASEC_Secure \ + : SPU_PERIPH_PERM_DMASEC_NonSecure) \ + << SPU_PERIPH_PERM_DMASEC_Pos) | \ + (SPU_PERIPH_PERM_LOCK_Locked << SPU_PERIPH_PERM_LOCK_Pos))) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.IPCT.CH[n] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Feature index. + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_IPCT_CH_SET(_spu, _index, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.IPCT.CH[_index], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.IPCT.INTERRUPT[n] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Feature index. + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_IPCT_INTERRUPT_SET(_spu, _index, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.IPCT.INTERRUPT[_index], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.DPPIC.CH[n] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Feature index. + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_DPPIC_CH_SET(_spu, _index, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.DPPIC.CH[_index], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.DPPIC.CHG[n] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Register index. + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_DPPIC_CHG_SET(_spu, _index, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.DPPIC.CHG[_index], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GPIOTE[n].CH[m] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Feature index (GPIOTE[n] register index). + * @param _subindex Feature subindex (CH[m] register index). + * @param _secattr If true, set the SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_GPIOTE_CH_SET(_spu, _index, _subindex, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD( \ + (uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GPIOTE[_index].CH[_subindex], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GPIOTE.INTERRUPT[n] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Feature index. + * @param _subindex Feature subindex. + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_GPIOTE_INTERRUPT_SET(_spu, _index, _subindex, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD( \ + (uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GPIOTE[_index].INTERRUPT[_subindex], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GPIO[n].PIN[m] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Feature index. + * @param _subindex Feature subindex. + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_GPIO_PIN_SET(_spu, _index, _subindex, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD( \ + (uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GPIO[_index].PIN[_subindex], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/** @brief Add a PERIPHCONF entry for a SPU FEATURE.GRTC.CC[n] register value. + * + * @param _spu Global domain SPU instance address. + * @param _index Feature index. + * @param _secattr If true, set SECATTR to secure, otherwise set it to non-secure. + * @param _ownerid OWNERID field value. + */ +#define UICR_SPU_FEATURE_GRTC_CC_SET(_spu, _index, _secattr, _ownerid) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_SPU_Type *)(_spu))->FEATURE.GRTC.CC[_index], \ + _UICR_SPU_FEATURE_VAL(_secattr, _ownerid)) + +/* Common macro for encoding a SPU FEATURE.* register value. + * Note that the MDK SPU_FEATURE_IPCT_CH_ macros are used for all since all the FEATURE registers + * have the same layout with different naming. + */ +#define _UICR_SPU_FEATURE_VAL(_secattr, _ownerid) \ + (uint32_t)((((_ownerid) << SPU_FEATURE_IPCT_CH_OWNERID_Pos) & \ + SPU_FEATURE_IPCT_CH_OWNERID_Msk) | \ + (((_secattr) ? SPU_FEATURE_IPCT_CH_SECATTR_Secure \ + : SPU_FEATURE_IPCT_CH_SECATTR_NonSecure) \ + << SPU_FEATURE_IPCT_CH_SECATTR_Pos) | \ + (SPU_FEATURE_IPCT_CH_LOCK_Locked << SPU_FEATURE_IPCT_CH_LOCK_Pos)) + +/** @brief Add PERIPHCONF entries for configuring IPCMAP CHANNEL.SOURCE[n] and CHANNEL.SINK[n]. + * + * @param _index CHANNEL.SOURCE[n]/CHANNEL.SINK[n] register index. + * @param _source_domain DOMAIN field value in CHANNEL[n].SOURCE. + * @param _source_ch SOURCE field value in CHANNEL[n].SOURCE. + * @param _sink_domain DOMAIN field value in CHANNEL[n].SINK. + * @param _sink_ch SINK field value in CHANNEL[n].SINK. + */ +#define UICR_IPCMAP_CHANNEL_CFG(_index, _source_domain, _source_ch, _sink_domain, _sink_ch) \ + UICR_IPCMAP_CHANNEL_SOURCE_SET(_index, _source_domain, _source_ch, 1); \ + UICR_IPCMAP_CHANNEL_SINK_SET(_index, _sink_domain, _sink_ch) + +#define UICR_IPCMAP_CHANNEL_SOURCE_SET(_index, _domain, _ch, _enable) \ + UICR_PERIPHCONF_ADD((uint32_t)&NRF_IPCMAP->CHANNEL[(_index)].SOURCE, \ + (uint32_t)((((_domain) << IPCMAP_CHANNEL_SOURCE_DOMAIN_Pos) & \ + IPCMAP_CHANNEL_SOURCE_DOMAIN_Msk) | \ + (((_ch) << IPCMAP_CHANNEL_SOURCE_SOURCE_Pos) & \ + IPCMAP_CHANNEL_SOURCE_SOURCE_Msk) | \ + (((_enable) ? IPCMAP_CHANNEL_SOURCE_ENABLE_Enabled \ + : IPCMAP_CHANNEL_SOURCE_ENABLE_Disabled) \ + << IPCMAP_CHANNEL_SOURCE_ENABLE_Pos))) + +#define UICR_IPCMAP_CHANNEL_SINK_SET(_index, _domain, _ch) \ + UICR_PERIPHCONF_ADD((uint32_t)&NRF_IPCMAP->CHANNEL[(_index)].SINK, \ + (uint32_t)((((_domain) << IPCMAP_CHANNEL_SINK_DOMAIN_Pos) & \ + IPCMAP_CHANNEL_SINK_DOMAIN_Msk) | \ + (((_ch) << IPCMAP_CHANNEL_SINK_SINK_Pos) & \ + IPCMAP_CHANNEL_SINK_SINK_Msk))) + +/** @brief Add a PERIPHCONF entry for an IRQMAP IRQ[n].SINK register value. + * + * @param _irqnum IRQ number (IRQ[n] register index). + * @param _processor Processor to route the interrupt to (PROCESSORID field value). + */ +#define UICR_IRQMAP_IRQ_SINK_SET(_irqnum, _processor) \ + UICR_PERIPHCONF_ADD((uint32_t)&NRF_IRQMAP->IRQ[(_irqnum)].SINK, \ + (uint32_t)(((_processor) << IRQMAP_IRQ_SINK_PROCESSORID_Pos) & \ + IRQMAP_IRQ_SINK_PROCESSORID_Msk)) + +/** @brief Add a PERIPHCONF entry for configuring a GPIO PIN_CNF[n] CTRLSEL field value. + * + * @param _gpio GPIO instance address. + * @param _pin Pin number (PIN_CNF[n] register index). + * @param _ctrlsel CTRLSEL field value. + */ +#define UICR_GPIO_PIN_CNF_CTRLSEL_SET(_gpio, _pin, _ctrlsel) \ + UICR_PERIPHCONF_ADD( \ + (uint32_t)&((NRF_GPIO_Type *)(_gpio))->PIN_CNF[(_pin)], \ + ((GPIO_PIN_CNF_ResetValue) | \ + (uint32_t)(((_ctrlsel) << GPIO_PIN_CNF_CTRLSEL_Pos) & GPIO_PIN_CNF_CTRLSEL_Msk))) + +/** @brief Add a PERIPHCONF entry for a PPIB SUBSCRIBE_SEND[n] register. + * + * @param _ppib Global domain PPIB instance address. + * @param _ppib_ch PPIB channel number. + */ +#define UICR_PPIB_SUBSCRIBE_SEND_ENABLE(_ppib, _ppib_ch) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_PPIB_Type *)(_ppib))->SUBSCRIBE_SEND[(_ppib_ch)], \ + (uint32_t)PPIB_SUBSCRIBE_SEND_EN_Msk) + +/** @brief Add a PERIPHCONF entry for a PPIB PUBLISH_RECEIVE[n] register. + * + * @param _ppib Global domain PPIB instance address. + * @param _ppib_ch PPIB channel number. + */ +#define UICR_PPIB_PUBLISH_RECEIVE_ENABLE(_ppib, _ppib_ch) \ + UICR_PERIPHCONF_ADD((uint32_t)&((NRF_PPIB_Type *)(_ppib))->PUBLISH_RECEIVE[(_ppib_ch)], \ + (uint32_t)PPIB_PUBLISH_RECEIVE_EN_Msk) + +/* The definitions below are not currently available in the MDK but are needed for the macros + * above. When they are, this can be deleted. + */ +#ifndef IPCMAP_CHANNEL_SOURCE_SOURCE_Msk + +typedef struct { + __IOM uint32_t SOURCE; + __IOM uint32_t SINK; +} NRF_IPCMAP_CHANNEL_Type; + +#define IPCMAP_CHANNEL_SOURCE_SOURCE_Pos (0UL) +#define IPCMAP_CHANNEL_SOURCE_SOURCE_Msk (0xFUL << IPCMAP_CHANNEL_SOURCE_SOURCE_Pos) +#define IPCMAP_CHANNEL_SOURCE_DOMAIN_Pos (8UL) +#define IPCMAP_CHANNEL_SOURCE_DOMAIN_Msk (0xFUL << IPCMAP_CHANNEL_SOURCE_DOMAIN_Pos) +#define IPCMAP_CHANNEL_SOURCE_ENABLE_Pos (31UL) +#define IPCMAP_CHANNEL_SOURCE_ENABLE_Disabled (0x0UL) +#define IPCMAP_CHANNEL_SOURCE_ENABLE_Enabled (0x1UL) +#define IPCMAP_CHANNEL_SINK_SINK_Pos (0UL) +#define IPCMAP_CHANNEL_SINK_SINK_Msk (0xFUL << IPCMAP_CHANNEL_SINK_SINK_Pos) +#define IPCMAP_CHANNEL_SINK_DOMAIN_Pos (8UL) +#define IPCMAP_CHANNEL_SINK_DOMAIN_Msk (0xFUL << IPCMAP_CHANNEL_SINK_DOMAIN_Pos) + +typedef struct { + __IM uint32_t RESERVED[256]; + __IOM NRF_IPCMAP_CHANNEL_Type CHANNEL[16]; +} NRF_IPCMAP_Type; + +#endif /* IPCMAP_CHANNEL_SOURCE_SOURCE_Msk */ + +#ifndef NRF_IPCMAP +#define NRF_IPCMAP ((NRF_IPCMAP_Type *)0x5F923000UL) +#endif + +#ifndef IRQMAP_IRQ_SINK_PROCESSORID_Msk + +typedef struct { + __IOM uint32_t SINK; +} NRF_IRQMAP_IRQ_Type; + +#define IRQMAP_IRQ_SINK_PROCESSORID_Pos (8UL) +#define IRQMAP_IRQ_SINK_PROCESSORID_Msk (0xFUL << IRQMAP_IRQ_SINK_PROCESSORID_Pos) + +typedef struct { + __IM uint32_t RESERVED[256]; + __IOM NRF_IRQMAP_IRQ_Type IRQ[480]; +} NRF_IRQMAP_Type; + +#endif /* IRQMAP_IRQ_SINK_PROCESSORID_Msk */ + +#ifndef NRF_IRQMAP +#define NRF_IRQMAP ((NRF_IRQMAP_Type *)0x5F924000UL) +#endif /* NRF_IRQMAP */ + +#ifndef GPIO_PIN_CNF_CTRLSEL_Pos + +#define GPIO_PIN_CNF_CTRLSEL_Pos (28UL) +#define GPIO_PIN_CNF_CTRLSEL_Msk (0x7UL << GPIO_PIN_CNF_CTRLSEL_Pos) +#define GPIO_PIN_CNF_CTRLSEL_Min (0x0UL) +#define GPIO_PIN_CNF_CTRLSEL_Max (0x7UL) +#define GPIO_PIN_CNF_CTRLSEL_GPIO (0x0UL) +#define GPIO_PIN_CNF_CTRLSEL_VPR (0x1UL) +#define GPIO_PIN_CNF_CTRLSEL_GRC (0x1UL) +#define GPIO_PIN_CNF_CTRLSEL_SecureDomain (0x2UL) +#define GPIO_PIN_CNF_CTRLSEL_PWM (0x2UL) +#define GPIO_PIN_CNF_CTRLSEL_I3C (0x2UL) +#define GPIO_PIN_CNF_CTRLSEL_Serial (0x3UL) +#define GPIO_PIN_CNF_CTRLSEL_HSSPI (0x3UL) +#define GPIO_PIN_CNF_CTRLSEL_RadioCore (0x4UL) +#define GPIO_PIN_CNF_CTRLSEL_EXMIF (0x4UL) +#define GPIO_PIN_CNF_CTRLSEL_CELL (0x4UL) +#define GPIO_PIN_CNF_CTRLSEL_DTB (0x6UL) +#define GPIO_PIN_CNF_CTRLSEL_TND (0x7UL) + +#endif /* GPIO_PIN_CNF_CTRLSEL_Pos */ + +#endif /* SOC_NORDIC_COMMON_UICR_UICR_H_ */ diff --git a/soc/nordic/common/uicr/uicr.ld b/soc/nordic/common/uicr/uicr.ld new file mode 100644 index 0000000000000..210495b1c66c2 --- /dev/null +++ b/soc/nordic/common/uicr/uicr.ld @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +SECTION_PROLOGUE(uicr_periphconf_entry,(COPY),SUBALIGN(Z_LINK_ITERABLE_SUBALIGN)) +{ + Z_LINK_ITERABLE(uicr_periphconf_entry); +} GROUP_ROM_LINK_IN(DEVNULL_REGION, DEVNULL_REGION) diff --git a/soc/nordic/nrf54h/CMakeLists.txt b/soc/nordic/nrf54h/CMakeLists.txt index 23c1cab1e77a5..a7deb7d66de2b 100644 --- a/soc/nordic/nrf54h/CMakeLists.txt +++ b/soc/nordic/nrf54h/CMakeLists.txt @@ -9,6 +9,7 @@ if(CONFIG_ARM) endif() zephyr_library_sources_ifdef(CONFIG_PM_S2RAM pm_s2ram.c) +zephyr_library_sources_ifdef(CONFIG_NRF_PERIPHCONF_SECTION uicr_periphconf_table.c) zephyr_include_directories(.) diff --git a/soc/nordic/nrf54h/uicr_periphconf_table.c b/soc/nordic/nrf54h/uicr_periphconf_table.c new file mode 100644 index 0000000000000..bf7f85402a603 --- /dev/null +++ b/soc/nordic/nrf54h/uicr_periphconf_table.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#define SPU131_ADDR (0x5F920000UL) +#define SPU133_ADDR (0x5F990000UL) +#define PPIB130_ADDR (0x5f925000UL) +#define PPIB133_ADDR (0x5f99d000UL) + +/* GRTC channels used by the radio core. */ +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 8, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 9, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 10, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 11, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 12, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 13, true, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 14, true, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_GRTC_CC_SET(SPU133_ADDR, 15, true, NRF_OWNER_RADIOCORE); + +/* DPPIC130 channels used by the radio core. */ +UICR_SPU_FEATURE_DPPIC_CH_SET(SPU131_ADDR, 0, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_DPPIC_CH_SET(SPU131_ADDR, 2, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_DPPIC_CH_SET(SPU131_ADDR, 3, false, NRF_OWNER_RADIOCORE); + +/* DPPIC132 channels used by the radio core. */ +UICR_SPU_FEATURE_DPPIC_CH_SET(SPU133_ADDR, 0, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_DPPIC_CH_SET(SPU133_ADDR, 2, false, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_DPPIC_CH_SET(SPU133_ADDR, 3, false, NRF_OWNER_RADIOCORE); + +/* Link (DPPIC130 ch.0) <== (DPPIC132 ch.0) */ +UICR_PPIB_PUBLISH_RECEIVE_ENABLE(PPIB130_ADDR, 8); +UICR_PPIB_SUBSCRIBE_SEND_ENABLE(PPIB133_ADDR, 0); + +/* Link (DPPIC130 ch.2) <== (DPPIC132 ch.2) */ +UICR_PPIB_PUBLISH_RECEIVE_ENABLE(PPIB130_ADDR, 10); +UICR_PPIB_SUBSCRIBE_SEND_ENABLE(PPIB133_ADDR, 2); + +/* Link (DPPIC130 ch.3) ==> (DPPIC132 ch.3) */ +UICR_PPIB_SUBSCRIBE_SEND_ENABLE(PPIB130_ADDR, 11); +UICR_PPIB_PUBLISH_RECEIVE_ENABLE(PPIB133_ADDR, 3); + +/* IPCT channels used by the radio core. */ +UICR_SPU_FEATURE_IPCT_CH_SET(SPU131_ADDR, 0, true, NRF_OWNER_RADIOCORE); +UICR_SPU_FEATURE_IPCT_CH_SET(SPU131_ADDR, 2, true, NRF_OWNER_RADIOCORE); + +/* Cross-domain mapping of the IPCT channels. */ +UICR_IPCMAP_CHANNEL_CFG(0, NRF_DOMAIN_RADIOCORE, 2, NRF_DOMAIN_GLOBALSLOW, 2); +UICR_IPCMAP_CHANNEL_CFG(1, NRF_DOMAIN_GLOBALSLOW, 0, NRF_DOMAIN_RADIOCORE, 0); +UICR_IPCMAP_CHANNEL_CFG(2, NRF_DOMAIN_GLOBALSLOW, 2, NRF_DOMAIN_RADIOCORE, 2); From 81f054fd9db733e90e1ae135f0a985b38c868b09 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Wed, 4 Jun 2025 18:04:43 +0200 Subject: [PATCH 10/40] west: runners: nrf: Program UICR/PERIPHCONF artifacts if present Program the new UICR and PERIPHCONF artifacts if they are generated. These are required for the application to operate properly if they are in use. Signed-off-by: Jonathan Nilsen --- scripts/west_commands/runners/nrf_common.py | 26 ++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index e081865377208..ba1d0dfdc323c 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -369,9 +369,9 @@ def program_hex(self): if self.family in ('nrf54h', 'nrf92'): erase_arg = 'ERASE_NONE' - generated_uicr = self.build_conf.getboolean('CONFIG_NRF_REGTOOL_GENERATE_UICR') + regtool_generated_uicr = self.build_conf.getboolean('CONFIG_NRF_REGTOOL_GENERATE_UICR') - if generated_uicr and not self.hex_get_uicrs().get(core): + if regtool_generated_uicr and not self.hex_get_uicrs().get(core): raise RuntimeError( f"Expected a UICR to be contained in: {self.hex_}\n" "Please ensure that the correct version of nrf-regtool is " @@ -434,7 +434,27 @@ def program_hex(self): core='Application', ) - if not self.erase and generated_uicr: + if self.build_conf.getboolean("CONFIG_NRF_HALTIUM_GENERATE_UICR"): + zephyr_build_dir = Path(self.cfg.build_dir) / 'zephyr' + + self.op_program( + str(zephyr_build_dir / 'uicr.hex'), + 'ERASE_NONE', + None, + defer=True, + core='Application', + ) + + if self.build_conf.getboolean("CONFIG_NRF_HALTIUM_UICR_PERIPHCONF"): + self.op_program( + str(zephyr_build_dir / 'periphconf.hex'), + 'ERASE_NONE', + None, + defer=True, + core='Application', + ) + + if not self.erase and regtool_generated_uicr: self.exec_op('erase', core=core, kind='uicr') else: if self.erase: From d4de11cac242082b4d698eab430ea49a80c8b8e6 Mon Sep 17 00:00:00 2001 From: Jonathan Nilsen Date: Wed, 18 Jun 2025 12:09:48 +0200 Subject: [PATCH 11/40] west: runners: nrf: don't recover twice on nrf54h Update the recover mechanism for nrf54h to only call recover once. Using nrfutil device recover with both --core Network and --core Application is redundant with IronSide SE as both of these map to the same operation which does a full erase of the device MRAM. Additionally, recovering twice in a row specifically in a nrfutil batch file (which is used by this runner implementation) triggers some odd behavior with the current latest version of nrfutil device + IronSide SE, which can cause the device to enter a reset loop and appear unresponsive and preventing 'west flash --recover' from working properly. Signed-off-by: Jonathan Nilsen --- scripts/west_commands/runners/nrf_common.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/west_commands/runners/nrf_common.py b/scripts/west_commands/runners/nrf_common.py index ba1d0dfdc323c..a7401084ef31e 100644 --- a/scripts/west_commands/runners/nrf_common.py +++ b/scripts/west_commands/runners/nrf_common.py @@ -320,8 +320,7 @@ def recover_target(self): # recover operation unlocks the core and then flashes a small image that # keeps the debug access port open, recovering the network core last # would result in that small image being deleted from the app core. - # In the case of the 54H, the order is indifferent. - if self.family in ('nrf53', 'nrf54h', 'nrf92'): + if self.family in ('nrf53', 'nrf92'): self.exec_op('recover', core='Network') self.exec_op('recover') From 77ced78608c63505e4853cddabf2f62e2aadbf0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Amundsen?= Date: Mon, 23 Jun 2025 07:09:46 +0200 Subject: [PATCH 12/40] soc: nrf54h: don't boot radio core if VTOR is not programmed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Booting the radio core when it is not programmed will typically cause a reset loop. This can happen when programming multiple images to a device, and the app core image is programmed before the radio core. With this change we avoid the reset loop in that case. Signed-off-by: Håkon Amundsen --- soc/nordic/nrf54h/Kconfig | 7 +++++++ soc/nordic/nrf54h/soc.c | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/soc/nordic/nrf54h/Kconfig b/soc/nordic/nrf54h/Kconfig index fb29407e5723c..268c8db7bacc9 100644 --- a/soc/nordic/nrf54h/Kconfig +++ b/soc/nordic/nrf54h/Kconfig @@ -78,6 +78,13 @@ config SOC_NRF54H20_CPURAD_ENABLE Radiocore, and also power will be requested to the Radiocore subsystem. The Radiocore will then start executing instructions. +config SOC_NRF54H20_CPURAD_ENABLE_CHECK_VTOR + bool "Check VTOR before booting Radio core" + default y + depends on SOC_NRF54H20_CPURAD_ENABLE + help + Verify that VTOR is not 0xFFFFFFFF before booting the Radiocore. + config SOC_NRF54H20_CPURAD select SOC_NRF54H20_CPURAD_COMMON diff --git a/soc/nordic/nrf54h/soc.c b/soc/nordic/nrf54h/soc.c index 0c43c61757209..66a97a482122f 100644 --- a/soc/nordic/nrf54h/soc.c +++ b/soc/nordic/nrf54h/soc.c @@ -178,6 +178,13 @@ void soc_late_init_hook(void) DT_REG_ADDR(DT_NODELABEL_CPURAD_SLOT0_PARTITION) + CONFIG_ROM_START_OFFSET); + if (IS_ENABLED(CONFIG_SOC_NRF54H20_CPURAD_ENABLE_CHECK_VTOR) && + sys_read32((mem_addr_t)radiocore_address) == 0xFFFFFFFFUL) { + LOG_ERR("Radiocore is not programmed, it will not be started"); + + return; + } + /* Don't wait as this is not yet supported. */ bool cpu_wait = false; From f61908a668027d851de881ad15be9d12f0b783c2 Mon Sep 17 00:00:00 2001 From: Mirko Covizzi Date: Tue, 1 Jul 2025 16:44:18 +0200 Subject: [PATCH 13/40] scripts: requirements-base: pin patool to >=2.0.0 This resolves an issue on MacOS where `west sdk install` would fail when extracting a `.tar.xz` package due to the command line options selected by patool. Signed-off-by: Mirko Covizzi --- scripts/requirements-base.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/requirements-base.txt b/scripts/requirements-base.txt index 2b35d3df097cf..efa58d8c19d77 100644 --- a/scripts/requirements-base.txt +++ b/scripts/requirements-base.txt @@ -17,7 +17,7 @@ pykwalify canopen packaging progress -patool +patool>=2.0.0 psutil>=5.6.6 pylink-square pyserial From e6df62eb0f12796c4bc66139e71ba557bad8adf1 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 1 Jul 2025 16:42:26 +0300 Subject: [PATCH 14/40] doc: release-notes: Add wifi information to 4.2 Add information about hostap IPC mechanism change that can save up to 6-8 kB memory when using native wifi stack. Signed-off-by: Jukka Rissanen --- doc/releases/release-notes-4.2.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releases/release-notes-4.2.rst b/doc/releases/release-notes-4.2.rst index bdebeee4c5485..6f917c9077e3a 100644 --- a/doc/releases/release-notes-4.2.rst +++ b/doc/releases/release-notes-4.2.rst @@ -216,6 +216,7 @@ New APIs and options * :kconfig:option:`CONFIG_WIFI_USAGE_MODE` * Added a new section to the Wi-Fi Management documentation (``doc/connectivity/networking/api/wifi.rst``) with step-by-step instructions for generating test certificates for Wi-Fi using FreeRADIUS scripts. This helps users reproduce the process for their own test environments. + * Changed the hostap IPC mechanism from socketpair to k_fifo. Depending on the enabled Wi-Fi configuration options, this can save up to 6-8 kB memory when using native Wi-Fi stack. * Power management From 9f48c34095348965ad9dc19af86345e795d376ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Cab=C3=A9?= Date: Tue, 1 Jul 2025 13:56:47 +0200 Subject: [PATCH 15/40] doc: project_roles: enhance maintainer responsibilities re: CoC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Emphasize the role of maintainers in upholding the project's code of conduct and fostering an inclusive environment for all. Signed-off-by: Benjamin Cabé --- doc/project/project_roles.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/project/project_roles.rst b/doc/project/project_roles.rst index 46b6b1f2376d6..7c3a8158311d8 100644 --- a/doc/project/project_roles.rst +++ b/doc/project/project_roles.rst @@ -137,7 +137,9 @@ in addition to those listed for Contributors and Collaborators: the TSC * Responsibility to ensure all contributions of the project have been reviewed within reasonable time. -* Responsibility to enforce the code of conduct. +* Responsibility to enforce the Code of Conduct. As leaders in the community, + maintainers are expected to be role models in upholding the project's code + of conduct and creating a welcoming and inclusive environment for everyone. * Responsibility to triage static analysis issues in their code area. See :ref:`static_analysis`. From ae80559f9999855236449b2f36c7e8925742bf6f Mon Sep 17 00:00:00 2001 From: Jiawei Yang Date: Tue, 1 Jul 2025 18:04:43 +0800 Subject: [PATCH 16/40] Bluetooth: HFP: Fail to get Bluetooth Profile Descriptor List In HFP PTS, cases run fail with the log 'Bluetooth Profile Descriptor List UUID (0x111E) is missing'. With this patch, the affected cases can pass correctly. Signed-off-by: Jiawei Yang --- subsys/bluetooth/host/classic/hfp_ag.c | 19 ++++++++++++------- subsys/bluetooth/host/classic/hfp_hf.c | 19 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/subsys/bluetooth/host/classic/hfp_ag.c b/subsys/bluetooth/host/classic/hfp_ag.c index ccdd68d65fad8..281bc78602f00 100644 --- a/subsys/bluetooth/host/classic/hfp_ag.c +++ b/subsys/bluetooth/host/classic/hfp_ag.c @@ -130,15 +130,20 @@ static struct bt_sdp_attribute hfp_ag_attrs[] = { ), BT_SDP_LIST( BT_SDP_ATTR_PROFILE_DESC_LIST, - BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8), BT_SDP_DATA_ELEM_LIST( { - BT_SDP_TYPE_SIZE(BT_SDP_UUID16), - BT_SDP_ARRAY_16(BT_SDP_HANDSFREE_SVCLASS) - }, - { - BT_SDP_TYPE_SIZE(BT_SDP_UINT16), - BT_SDP_ARRAY_16(0x0109) + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_SDP_HANDSFREE_SVCLASS) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(0x0109) + }, + ) }, ) ), diff --git a/subsys/bluetooth/host/classic/hfp_hf.c b/subsys/bluetooth/host/classic/hfp_hf.c index 842b5f594997b..40f6523f44b84 100644 --- a/subsys/bluetooth/host/classic/hfp_hf.c +++ b/subsys/bluetooth/host/classic/hfp_hf.c @@ -127,15 +127,20 @@ static struct bt_sdp_attribute hfp_attrs[] = { ), BT_SDP_LIST( BT_SDP_ATTR_PROFILE_DESC_LIST, - BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 8), BT_SDP_DATA_ELEM_LIST( { - BT_SDP_TYPE_SIZE(BT_SDP_UUID16), - BT_SDP_ARRAY_16(BT_SDP_HANDSFREE_SVCLASS) - }, - { - BT_SDP_TYPE_SIZE(BT_SDP_UINT16), - BT_SDP_ARRAY_16(0x0109) + BT_SDP_TYPE_SIZE_VAR(BT_SDP_SEQ8, 6), + BT_SDP_DATA_ELEM_LIST( + { + BT_SDP_TYPE_SIZE(BT_SDP_UUID16), + BT_SDP_ARRAY_16(BT_SDP_HANDSFREE_SVCLASS) + }, + { + BT_SDP_TYPE_SIZE(BT_SDP_UINT16), + BT_SDP_ARRAY_16(0x0109) + }, + ) }, ) ), From 335a0f4fcf292bb02783aeda62bbb5981609b7c4 Mon Sep 17 00:00:00 2001 From: Jan Behrens Date: Tue, 1 Jul 2025 10:48:24 +0200 Subject: [PATCH 17/40] boards: shields: Fixes Stepper 19 Click GPIO Expander Replaces TI TCA9538 with NXP PCA9538. Also adds additional links to the readme. Signed-off-by: Jan Behrens --- .../mikroe_stepper_19_click/doc/index.rst | 16 +++++++++------- .../mikroe_stepper_19_click.overlay | 8 ++++---- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/boards/shields/mikroe_stepper_19_click/doc/index.rst b/boards/shields/mikroe_stepper_19_click/doc/index.rst index 938697699d0f3..42fd0d42fa60c 100644 --- a/boards/shields/mikroe_stepper_19_click/doc/index.rst +++ b/boards/shields/mikroe_stepper_19_click/doc/index.rst @@ -6,13 +6,9 @@ MikroElektronika Stepper 19 Click Overview ******** -Stepper 19 Click shield has a TI DRV8424 stepper driver accessed via GPIO and -a TI TCA9538 GPIO expander accessed via I2C. Some DRV8424 pins are accessed +The MikroElektronika `Stepper 19 Click`_ shield has a `TI DRV8424`_ stepper driver accessed via +GPIO and a `NXP PCA9538A`_ GPIO expander accessed via I2C. Some DRV8424 pins are accessed via the GPIO expander. -The DRV8424 uses by default the work-queue timing source, but that can be changed. - -More information about the shield can be found at -`Mikroe Stepper 19 click`_. .. figure:: stepper_19_click.webp :align: center @@ -41,5 +37,11 @@ References .. target-notes:: -.. _Mikroe Stepper 19 click: +.. _Stepper 19 Click: https://www.mikroe.com/stepper-19-click + +.. _TI DRV8424: + https://www.ti.com/product/DRV8424 + +.. _NXP PCA9538A: + https://www.nxp.com/products/interfaces/ic-spi-i3c-interface-devices/general-purpose-i-o-gpio/low-voltage-8-bit-ic-bus-i-o-port-with-interrupt-and-reset:PCA9538A diff --git a/boards/shields/mikroe_stepper_19_click/mikroe_stepper_19_click.overlay b/boards/shields/mikroe_stepper_19_click/mikroe_stepper_19_click.overlay index 48cb3cb607a99..df5b9a73b0f00 100644 --- a/boards/shields/mikroe_stepper_19_click/mikroe_stepper_19_click.overlay +++ b/boards/shields/mikroe_stepper_19_click/mikroe_stepper_19_click.overlay @@ -12,9 +12,9 @@ &mikrobus_i2c { status = "okay"; - tca9538a_mikroe_stepper_19_click: tca9538a@70 { + pca9538a_mikroe_stepper_19_click: pca9538a@70 { status = "okay"; - compatible = "ti,tca9538"; + compatible = "nxp,pca9538"; reg = <0x70>; @@ -45,7 +45,7 @@ sleep-gpios = <&mikrobus_header 1 GPIO_ACTIVE_LOW>; en-gpios = <&mikrobus_header 2 0>; fault-gpios = <&mikrobus_header 7 GPIO_ACTIVE_LOW>; - m0-gpios = <&tca9538a_mikroe_stepper_19_click 0 0>; - m1-gpios = <&tca9538a_mikroe_stepper_19_click 1 0>; + m0-gpios = <&pca9538a_mikroe_stepper_19_click 0 0>; + m1-gpios = <&pca9538a_mikroe_stepper_19_click 1 0>; }; }; From e0a33bf013641e955352205438020b76d3553055 Mon Sep 17 00:00:00 2001 From: Hake Huang Date: Tue, 1 Jul 2025 17:29:12 +0000 Subject: [PATCH 18/40] boards: dts: mimxrt1160_evk_cm4: sram shall not be put to ocram as in mbox cases the ocram is used as code area, so shall not be used as sram again. this is a typo introduced by aec0355380e20ba5ea4cdf98d476a7113a138673 fixing: #82841 Signed-off-by: Hake Huang --- boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts index d86251aebf818..7496dce5b2dbe 100644 --- a/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts +++ b/boards/nxp/mimxrt1160_evk/mimxrt1160_evk_mimxrt1166_cm4.dts @@ -20,7 +20,7 @@ * sram region is changed and DMA is in use, you will * encounter issues! */ - zephyr,sram = &ocram; + zephyr,sram = &sram1; zephyr,console = &lpuart1; zephyr,shell-uart = &lpuart1; zephyr,flash-controller = &is25wp128; From 5d41d366e410ed8c048c9b8602a20212933fe0f3 Mon Sep 17 00:00:00 2001 From: Erwan Gouriou Date: Tue, 1 Jul 2025 11:29:05 +0200 Subject: [PATCH 19/40] boards: stm32n6570_dk: Update doc and migration guide. Clarify expectations about the recently modified default variant of the board. Update migration guide to warn existing users about the change. Signed-off-by: Erwan Gouriou --- boards/st/stm32n6570_dk/doc/index.rst | 5 +++-- doc/releases/migration-guide-4.2.rst | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/boards/st/stm32n6570_dk/doc/index.rst b/boards/st/stm32n6570_dk/doc/index.rst index 4a2db0d7da6f7..b8cc79be79cd6 100644 --- a/boards/st/stm32n6570_dk/doc/index.rst +++ b/boards/st/stm32n6570_dk/doc/index.rst @@ -182,9 +182,10 @@ Board variants Three variants are available with STM32N6570_DK: - Default variant. Available as a chainloaded application which should be loaded by a - Boot Loader, it has access to the whole AXISRAM1 and AXISRAM2 regions. + bootloader, it has access to the whole AXISRAM1 and AXISRAM2 regions. It is expected to + be built using ``--sysbuild`` option exclusively. - ``fsbl``: First Stage Boot Loader (FSBL) which is available as an application loaded by the - Boot ROM and flashed using ST-Link. This is typically a Boot Loader image. It runs + Boot ROM and flashed using ST-Link. This is typically a bootloader image. It runs in RAM LOAD mode on second half of AXISRAM2. 511K are available for the whole image. - ``sb``: First Stage Boot Loader - Serial Boot. Equivalent to the FSBL image, but could be loaded using USB and doesn't require switching the bootpins. This is the most practical diff --git a/doc/releases/migration-guide-4.2.rst b/doc/releases/migration-guide-4.2.rst index b67ed2c8a0e12..49814e86616d3 100644 --- a/doc/releases/migration-guide-4.2.rst +++ b/doc/releases/migration-guide-4.2.rst @@ -88,6 +88,12 @@ Boards instead of ``openocd.board.cmake``. The ``openocd-stm32.board.cmake`` file extends the default OpenOCD runner with manufacturer-specific configuration like STM32 mass erase commands. +* STM32N6570-DK boards's default variant (``stm32n6570_dk/stm32n657xx``) is now supposed to be a + chainloaded application and should be built using ``--sysbuild``. The old default, + which built applications to run as First Stage BootLoader, is now available as a dedicated + variant (``stm32n6570_dk/stm32n657xx/fsbl``) that must be selected explicitly. + See board documentation for more information about these variants. + Device Drivers and Devicetree ***************************** From aa4c10389d878e77bb0a8333b264614bbc313db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karol=20Laso=C5=84czyk?= Date: Tue, 1 Jul 2025 10:56:11 +0200 Subject: [PATCH 20/40] snippets: nordic-flpr: Fix nRF54LM20A memory layout MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes wrongly set memory space for FLPR core. Signed-off-by: Karol Lasończyk --- .../nordic-flpr/soc/nrf54lm20a_cpuapp.overlay | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/snippets/nordic-flpr/soc/nrf54lm20a_cpuapp.overlay b/snippets/nordic-flpr/soc/nrf54lm20a_cpuapp.overlay index 1d36ba5ac4882..071241cf03d7c 100644 --- a/snippets/nordic-flpr/soc/nrf54lm20a_cpuapp.overlay +++ b/snippets/nordic-flpr/soc/nrf54lm20a_cpuapp.overlay @@ -9,22 +9,27 @@ #address-cells = <1>; #size-cells = <1>; - cpuflpr_code_partition: image@1ed000 { + cpuflpr_code_partition: image@1e5000 { /* FLPR core code partition */ - reg = <0x1ed000 DT_SIZE_K(64)>; + reg = <0x1e5000 DT_SIZE_K(96)>; }; }; - cpuflpr_sram_code_data: memory@2006fc00 { + cpuflpr_sram_code_data: memory@20067c00 { compatible = "mmio-sram"; - reg = <0x2006fc00 DT_SIZE_K(64)>; + reg = <0x20067c00 DT_SIZE_K(96)>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x2006fc00 0x10000>; + ranges = <0x0 0x20067c00 DT_SIZE_K(96)>; }; }; }; +&cpuapp_sram { + reg = <0x20000000 DT_SIZE_K(415)>; + ranges = <0x0 0x20000000 DT_SIZE_K(415)>; +}; + &uart30 { status = "reserved"; }; From 7c9bdb7dccb66bb9ddf58d81bad1939268364284 Mon Sep 17 00:00:00 2001 From: Abhinav Kulkarni Date: Tue, 1 Jul 2025 04:43:58 +0000 Subject: [PATCH 21/40] boards: shields: nxp_m2_wifi_bt: doc: Update doc Updated shield document for NXP's m2 modules. Signed-off-by: Abhinav Kulkarni --- boards/shields/nxp_m2_wifi_bt/doc/index.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/boards/shields/nxp_m2_wifi_bt/doc/index.rst b/boards/shields/nxp_m2_wifi_bt/doc/index.rst index 2e28ae83377f4..fb0db5f797d4f 100644 --- a/boards/shields/nxp_m2_wifi_bt/doc/index.rst +++ b/boards/shields/nxp_m2_wifi_bt/doc/index.rst @@ -38,8 +38,9 @@ To use the shield, below requirements needs to be satisfied. Integration Platform ******************** -This shield is validated and tested for use with the host platform listed below. It can be used with -other host platforms, but the functionality is not guaranteed. +This shield is validated and tested for use with the host platform listed below. +While the shield can be used with other host platforms, other combinations +are not actively tested or validated. - :zephyr:board:`mimxrt1060_evk` Rev-C. From 22a43bbd3d31312ad764c6140c47363bf86d5798 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 30 Jun 2025 16:28:52 +0200 Subject: [PATCH 22/40] shields: st_b_cams_imx_mb1854: set sensor conf if DCMIPP is enabled Instead of having a conf file for all variants of STM32N6570_DK, set the necessary settings for any platform which has DCMIPP enabled. Signed-off-by: Alain Volmat --- .../st_b_cams_imx_mb1854/Kconfig.defconfig | 17 +++++++++++++++++ .../boards/stm32n6570_dk.conf | 3 --- .../boards/stm32n6570_dk_stm32n657xx_sb.conf | 3 --- 3 files changed, 17 insertions(+), 6 deletions(-) create mode 100644 boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig delete mode 100644 boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk.conf delete mode 100644 boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk_stm32n657xx_sb.conf diff --git a/boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig b/boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig new file mode 100644 index 0000000000000..ce0297675d285 --- /dev/null +++ b/boards/shields/st_b_cams_imx_mb1854/Kconfig.defconfig @@ -0,0 +1,17 @@ +# ST_B_CAMS_IMX_MB1854 configuration + +# Copyright (c) 2025 STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +if VIDEO_STM32_DCMIPP + +config VIDEO_STM32_DCMIPP_SENSOR_PIXEL_FORMAT + default "pRAA" + +config VIDEO_STM32_DCMIPP_SENSOR_WIDTH + default 2592 + +config VIDEO_STM32_DCMIPP_SENSOR_HEIGHT + default 1944 + +endif # VIDEO_STM32_DCMIPP diff --git a/boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk.conf b/boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk.conf deleted file mode 100644 index f89907f917235..0000000000000 --- a/boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_VIDEO_STM32_DCMIPP_SENSOR_PIXEL_FORMAT="pRAA" -CONFIG_VIDEO_STM32_DCMIPP_SENSOR_WIDTH=2592 -CONFIG_VIDEO_STM32_DCMIPP_SENSOR_HEIGHT=1944 diff --git a/boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk_stm32n657xx_sb.conf b/boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk_stm32n657xx_sb.conf deleted file mode 100644 index f89907f917235..0000000000000 --- a/boards/shields/st_b_cams_imx_mb1854/boards/stm32n6570_dk_stm32n657xx_sb.conf +++ /dev/null @@ -1,3 +0,0 @@ -CONFIG_VIDEO_STM32_DCMIPP_SENSOR_PIXEL_FORMAT="pRAA" -CONFIG_VIDEO_STM32_DCMIPP_SENSOR_WIDTH=2592 -CONFIG_VIDEO_STM32_DCMIPP_SENSOR_HEIGHT=1944 From eb75dd18695e8b837dcd7e076d480ef937077859 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 30 Jun 2025 16:30:50 +0200 Subject: [PATCH 23/40] samples: video: capture: add conf for stm32n6570_dk fsbl Add the board conf file for the stm32n6570_dk in its fsbl variant. Signed-off-by: Alain Volmat --- .../capture/boards/stm32n6570_dk_stm32n657xx_fsbl.conf | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 samples/drivers/video/capture/boards/stm32n6570_dk_stm32n657xx_fsbl.conf diff --git a/samples/drivers/video/capture/boards/stm32n6570_dk_stm32n657xx_fsbl.conf b/samples/drivers/video/capture/boards/stm32n6570_dk_stm32n657xx_fsbl.conf new file mode 100644 index 0000000000000..4cb5c1c804e02 --- /dev/null +++ b/samples/drivers/video/capture/boards/stm32n6570_dk_stm32n657xx_fsbl.conf @@ -0,0 +1,6 @@ +CONFIG_VIDEO_FRAME_WIDTH=800 +CONFIG_VIDEO_FRAME_HEIGHT=480 +CONFIG_VIDEO_PIXEL_FORMAT="RGBP" +CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=800000 +CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=2 +CONFIG_MAIN_STACK_SIZE=2048 From 926f3026aac8f73da2cab39f3bf6f8b6fd201483 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 30 Jun 2025 16:38:53 +0200 Subject: [PATCH 24/40] samples: video: capture_to_lvgl: add stm32n6570_dk/fsbl conf Add the conf file for the stm32n6570_dk in its FSBL variant Signed-off-by: Alain Volmat --- .../boards/stm32n6570_dk_stm32n657xx_fsbl.conf | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 samples/drivers/video/capture_to_lvgl/boards/stm32n6570_dk_stm32n657xx_fsbl.conf diff --git a/samples/drivers/video/capture_to_lvgl/boards/stm32n6570_dk_stm32n657xx_fsbl.conf b/samples/drivers/video/capture_to_lvgl/boards/stm32n6570_dk_stm32n657xx_fsbl.conf new file mode 100644 index 0000000000000..8920fa813a2b2 --- /dev/null +++ b/samples/drivers/video/capture_to_lvgl/boards/stm32n6570_dk_stm32n657xx_fsbl.conf @@ -0,0 +1,5 @@ +CONFIG_VIDEO_WIDTH=800 +CONFIG_VIDEO_HEIGHT=480 +CONFIG_VIDEO_BUFFER_POOL_SZ_MAX=800000 +CONFIG_VIDEO_BUFFER_POOL_NUM_MAX=2 +CONFIG_MAIN_STACK_SIZE=4096 From 1d3fcdde54fe3424b9fb73e4ac83957fb7a2e599 Mon Sep 17 00:00:00 2001 From: Alain Volmat Date: Mon, 30 Jun 2025 16:50:09 +0200 Subject: [PATCH 25/40] samples: video: capture_to_lvgl: add crop/compose support Demonstrate the crop/compose API by introducing 4 new CONFIG options in order to define the crop area. Moreover, if the selection API is available and if the targetted size is different from the current crop size, then try to apply a compose in order to reach the targetted format size. Signed-off-by: Alain Volmat --- samples/drivers/video/capture_to_lvgl/Kconfig | 26 +++++++++++ .../drivers/video/capture_to_lvgl/src/main.c | 45 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/samples/drivers/video/capture_to_lvgl/Kconfig b/samples/drivers/video/capture_to_lvgl/Kconfig index edff9ffbc3708..0a675d24b47be 100644 --- a/samples/drivers/video/capture_to_lvgl/Kconfig +++ b/samples/drivers/video/capture_to_lvgl/Kconfig @@ -7,6 +7,32 @@ mainmenu "Video capture to LVGL sample application" menu "Video capture configuration" +config VIDEO_SOURCE_CROP_LEFT + int "Crop area left value" + default 0 + help + Left value of the crop area within the video source. + +config VIDEO_SOURCE_CROP_TOP + int "Crop area top value" + default 0 + help + Top value of the crop area within the video source. + +config VIDEO_SOURCE_CROP_WIDTH + int "Crop area width value" + default 0 + help + Width value of the crop area within the video source. + If set to 0, the crop is not applied. + +config VIDEO_SOURCE_CROP_HEIGHT + int "Crop area height value" + default 0 + help + Height value of the crop area within the video source. + If set to 0, the crop is not applied. + config VIDEO_WIDTH int "Define the width of the video" default 320 diff --git a/samples/drivers/video/capture_to_lvgl/src/main.c b/samples/drivers/video/capture_to_lvgl/src/main.c index 69b39b3904b82..020397cbf61c6 100644 --- a/samples/drivers/video/capture_to_lvgl/src/main.c +++ b/samples/drivers/video/capture_to_lvgl/src/main.c @@ -31,8 +31,12 @@ int main(void) struct video_format fmt; struct video_caps caps; enum video_buf_type type = VIDEO_BUF_TYPE_OUTPUT; + struct video_selection sel = { + .type = VIDEO_BUF_TYPE_OUTPUT, + }; size_t bsize; int i = 0; + int err; display_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); if (!device_is_ready(display_dev)) { @@ -74,11 +78,50 @@ int main(void) return 0; } + /* Set the crop setting if necessary */ +#if CONFIG_VIDEO_SOURCE_CROP_WIDTH && CONFIG_VIDEO_SOURCE_CROP_HEIGHT + sel.target = VIDEO_SEL_TGT_CROP; + sel.rect.left = CONFIG_VIDEO_SOURCE_CROP_LEFT; + sel.rect.top = CONFIG_VIDEO_SOURCE_CROP_TOP; + sel.rect.width = CONFIG_VIDEO_SOURCE_CROP_WIDTH; + sel.rect.height = CONFIG_VIDEO_SOURCE_CROP_HEIGHT; + if (video_set_selection(video_dev, &sel)) { + LOG_ERR("Unable to set selection crop"); + return 0; + } + LOG_INF("Selection crop set to (%u,%u)/%ux%u", + sel.rect.left, sel.rect.top, sel.rect.width, sel.rect.height); +#endif + /* Set format */ fmt.width = CONFIG_VIDEO_WIDTH; fmt.height = CONFIG_VIDEO_HEIGHT; fmt.pixelformat = VIDEO_PIX_FMT_RGB565; + /* + * Check (if possible) if targeted size is same as crop + * and if compose is necessary + */ + sel.target = VIDEO_SEL_TGT_CROP; + err = video_get_selection(video_dev, &sel); + if (err < 0 && err != -ENOSYS) { + LOG_ERR("Unable to get selection crop"); + return 0; + } + + if (err == 0 && (sel.rect.width != fmt.width || sel.rect.height != fmt.height)) { + sel.target = VIDEO_SEL_TGT_COMPOSE; + sel.rect.left = 0; + sel.rect.top = 0; + sel.rect.width = fmt.width; + sel.rect.height = fmt.height; + err = video_set_selection(video_dev, &sel); + if (err < 0 && err != -ENOSYS) { + LOG_ERR("Unable to set selection compose"); + return 0; + } + } + if (video_set_format(video_dev, &fmt)) { LOG_ERR("Unable to set up video format"); return 0; @@ -142,8 +185,6 @@ int main(void) /* Grab video frames */ vbuf->type = type; while (1) { - int err; - err = video_dequeue(video_dev, &vbuf, K_FOREVER); if (err) { LOG_ERR("Unable to dequeue video buf"); From 0d2656121af5e7e9bba54e3b890423b401b1f313 Mon Sep 17 00:00:00 2001 From: Phi Bang Nguyen Date: Mon, 30 Jun 2025 16:39:27 +0200 Subject: [PATCH 26/40] samples: video: capture: Add condition for test pattern test Add condition to do the test pattern fixture test only if the test pattern control was successfully set. Signed-off-by: Phi Bang Nguyen --- samples/drivers/video/capture/src/main.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/samples/drivers/video/capture/src/main.c b/samples/drivers/video/capture/src/main.c index 5e07318b08531..d2131219c5647 100644 --- a/samples/drivers/video/capture/src/main.c +++ b/samples/drivers/video/capture/src/main.c @@ -246,6 +246,7 @@ int main(void) /* Set controls */ struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = 1}; + int tp_set_ret = -ENOTSUP; if (IS_ENABLED(CONFIG_VIDEO_CTRL_HFLIP)) { video_set_ctrl(video_dev, &ctrl); @@ -258,7 +259,7 @@ int main(void) if (IS_ENABLED(CONFIG_TEST)) { ctrl.id = VIDEO_CID_TEST_PATTERN; - video_set_ctrl(video_dev, &ctrl); + tp_set_ret = video_set_ctrl(video_dev, &ctrl); } #if DT_HAS_CHOSEN(zephyr_display) @@ -320,7 +321,9 @@ int main(void) frame++, vbuf->bytesused, vbuf->timestamp); #ifdef CONFIG_TEST - if (is_colorbar_ok(vbuf->buffer, fmt)) { + if (tp_set_ret < 0) { + LOG_DBG("Test pattern control was not successful. Skip test"); + } else if (is_colorbar_ok(vbuf->buffer, fmt)) { LOG_DBG("Pattern OK!\n"); } #endif From ec81351463c68b4f899e54918be4d8d919890ee5 Mon Sep 17 00:00:00 2001 From: Phi Bang Nguyen Date: Wed, 2 Jul 2025 23:38:47 +0200 Subject: [PATCH 27/40] samples: video: capture: Enable deferred logging Immediate log mode may use a lot of stack and hence may cause some stack overflow on some boards. Enable deferred log mode to have the least impact on the application. Signed-off-by: Phi Bang Nguyen --- samples/drivers/video/capture/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/samples/drivers/video/capture/prj.conf b/samples/drivers/video/capture/prj.conf index f8b221d5a776a..360778bc420f0 100644 --- a/samples/drivers/video/capture/prj.conf +++ b/samples/drivers/video/capture/prj.conf @@ -5,3 +5,4 @@ CONFIG_PRINTK=y CONFIG_LOG=y CONFIG_DISPLAY=y CONFIG_REQUIRES_FLOAT_PRINTF=y +CONFIG_LOG_MODE_DEFERRED=y From d1a80bf948fc0a734ec9fa0e231d9314f03afd1d Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 27 Jun 2025 14:28:52 +0530 Subject: [PATCH 28/40] modules: nrf_wifi: Implement new Raw TX APIs The new raw TX handling relies on these APIs, so, implement them for Zephyr shim. Signed-off-by: Chaitanya Tata --- modules/nrf_wifi/os/shim.c | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/modules/nrf_wifi/os/shim.c b/modules/nrf_wifi/os/shim.c index 2bb706125a1cb..df460d5ab53ee 100644 --- a/modules/nrf_wifi/os/shim.c +++ b/modules/nrf_wifi/os/shim.c @@ -299,6 +299,9 @@ struct nwb { void (*cleanup_cb)(); unsigned char priority; bool chksum_done; +#ifdef CONFIG_NRF70_RAW_DATA_TX + void *raw_tx_hdr; +#endif /* CONFIG_NRF70_RAW_DATA_TX */ #ifdef CONFIG_NRF_WIFI_ZERO_COPY_TX struct net_pkt *pkt; #endif @@ -424,6 +427,55 @@ static void zep_shim_nbuf_set_chksum_done(void *nbuf, unsigned char chksum_done) nwb->chksum_done = (bool)chksum_done; } +#ifdef CONFIG_NRF70_RAW_DATA_TX +static void *zep_shim_nbuf_set_raw_tx_hdr(void *nbuf, unsigned short raw_hdr_len) +{ + struct nwb *nwb = (struct nwb *)nbuf; + + if (!nwb) { + LOG_ERR("%s: Received network buffer is NULL", __func__); + return NULL; + } + + nwb->raw_tx_hdr = zep_shim_nbuf_data_get(nwb); + if (!nwb->raw_tx_hdr) { + LOG_ERR("%s: Unable to set raw Tx header in network buffer", __func__); + return NULL; + } + + zep_shim_nbuf_data_pull(nwb, raw_hdr_len); + + return nwb->raw_tx_hdr; +} + +static void *zep_shim_nbuf_get_raw_tx_hdr(void *nbuf) +{ + struct nwb *nwb = (struct nwb *)nbuf; + + if (!nwb) { + LOG_ERR("%s: Received network buffer is NULL", __func__); + return NULL; + } + + return nwb->raw_tx_hdr; +} + +static bool zep_shim_nbuf_is_raw_tx(void *nbuf) +{ + struct nwb *nwb = (struct nwb *)nbuf; + + if (!nwb) { + LOG_ERR("%s: Received network buffer is NULL", __func__); + return false; + } + + return (nwb->raw_tx_hdr != NULL); +} +#endif /* CONFIG_NRF70_RAW_DATA_TX */ + + + + #include #include @@ -1216,6 +1268,11 @@ const struct nrf_wifi_osal_ops nrf_wifi_os_zep_ops = { .nbuf_get_priority = zep_shim_nbuf_get_priority, .nbuf_get_chksum_done = zep_shim_nbuf_get_chksum_done, .nbuf_set_chksum_done = zep_shim_nbuf_set_chksum_done, +#ifdef CONFIG_NRF70_RAW_DATA_TX + .nbuf_set_raw_tx_hdr = zep_shim_nbuf_set_raw_tx_hdr, + .nbuf_get_raw_tx_hdr = zep_shim_nbuf_get_raw_tx_hdr, + .nbuf_is_raw_tx = zep_shim_nbuf_is_raw_tx, +#endif /* CONFIG_NRF70_RAW_DATA_TX */ .tasklet_alloc = zep_shim_work_alloc, .tasklet_free = zep_shim_work_free, From f2644cf4700b67dbf8e0264273d9faa301fcf6e3 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 30 Jun 2025 02:15:45 +0530 Subject: [PATCH 29/40] manifest: nrf_wifi: Pull new raw TX handling Fixes the issue of leave the packets in the pending queue till a new TX comes. Signed-off-by: Chaitanya Tata --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index fe8253bfa2f22..3dd26629dd790 100644 --- a/west.yml +++ b/west.yml @@ -328,7 +328,7 @@ manifest: revision: 6e5961223f81aa2707c555db138819a5c1b7942c path: modules/bsim_hw_models/nrf_hw_models - name: nrf_wifi - revision: 7cb2f44f46dfc86e4f97477ee90022944e138dd8 + revision: 52286f111b4765e0dd40f43124e7bb5c14758dff path: modules/lib/nrf_wifi - name: open-amp revision: c30a6d8b92fcebdb797fc1a7698e8729e250f637 From 7475f5e0a50b22964c3829dd6f614e70691a99df Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Wed, 25 Jun 2025 15:36:00 +0200 Subject: [PATCH 30/40] Bluetooth: Controller: nRF54Lx: Flash sync restrict to one iteration Write operations are not constant time on nRF54Lx SoCs and depend on the previous value present versus new value to be written. Hence, perform no more than one iteration. Signed-off-by: Vinayak Kariappa Chettimada --- .../controller/flash/soc_flash_nrf_ticker.c | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/controller/flash/soc_flash_nrf_ticker.c b/subsys/bluetooth/controller/flash/soc_flash_nrf_ticker.c index 5286fb4a993b2..32b908a5ab05e 100644 --- a/subsys/bluetooth/controller/flash/soc_flash_nrf_ticker.c +++ b/subsys/bluetooth/controller/flash/soc_flash_nrf_ticker.c @@ -250,14 +250,24 @@ void nrf_flash_sync_get_timestamp_begin(void) bool nrf_flash_sync_check_time_limit(uint32_t iteration) { - uint32_t ticks_diff; + if (IS_ENABLED(CONFIG_SOC_COMPATIBLE_NRF54LX)) { + /* Write operations are not constant time depending on the previous value present + * versus new value to be written. Hence, perform no more than one iteration. + */ + + ARG_UNUSED(iteration); - ticks_diff = ticker_ticks_diff_get(ticker_ticks_now_get(), - _ticker_sync_context.ticks_begin); - if (ticks_diff + ticks_diff/iteration > - HAL_TICKER_US_TO_TICKS(_ticker_sync_context.slot)) { return true; - } + } else { + uint32_t ticks_diff; - return false; + ticks_diff = ticker_ticks_diff_get(ticker_ticks_now_get(), + _ticker_sync_context.ticks_begin); + if (ticks_diff + ticks_diff/iteration > + HAL_TICKER_US_TO_TICKS(_ticker_sync_context.slot)) { + return true; + } + + return false; + } } From c7c56b8a82afd72d20d10850496d2de997164678 Mon Sep 17 00:00:00 2001 From: Vinayak Kariappa Chettimada Date: Fri, 27 Jun 2025 16:02:54 +0200 Subject: [PATCH 31/40] Bluetooth: Controller: Fix peripheral role assertion on conn update Fix peripheral role assertion during connection update and simultaneous flash operations. prepare_cb: Actual EVENT_OVERHEAD_START_US = 6149 This happens due to instant latency at connection update where the ticks_at_expire was in the past. Signed-off-by: Vinayak Kariappa Chettimada --- subsys/bluetooth/controller/ll_sw/ull_conn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index c6dd93efd8ec1..fa4eb269e7b20 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -2363,7 +2363,7 @@ void ull_conn_update_parameters(struct ll_conn *conn, uint8_t is_cu_proc, uint8_ periodic_us = conn_interval_us; conn_interval_old_us = conn_interval_old * conn_interval_unit_old; - latency_upd = conn_interval_old_us / conn_interval_us; + latency_upd = DIV_ROUND_UP(conn_interval_old_us, conn_interval_us); conn_interval_new_us = latency_upd * conn_interval_us; if (conn_interval_new_us > conn_interval_old_us) { ticks_at_expire += HAL_TICKER_US_TO_TICKS( From 342c19f73a322986238e9d9f0f8c3e8a0ee9edf5 Mon Sep 17 00:00:00 2001 From: David Leach Date: Mon, 9 Jun 2025 12:21:54 -0500 Subject: [PATCH 32/40] drivers: watchdog: Add enableWait setting for wdt_mcux_imx_wdog When WDT_OPT_PAUSE_IN_SLEEP option is passed in set enableWait flag in addition to the enableStop. Fixes #86437 Signed-off-by: David Leach --- drivers/watchdog/wdt_mcux_imx_wdog.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/wdt_mcux_imx_wdog.c b/drivers/watchdog/wdt_mcux_imx_wdog.c index 99a6cea0a706b..79115fb383fe1 100644 --- a/drivers/watchdog/wdt_mcux_imx_wdog.c +++ b/drivers/watchdog/wdt_mcux_imx_wdog.c @@ -41,14 +41,27 @@ static int mcux_wdog_setup(const struct device *dev, uint8_t options) return -EINVAL; } + /* + * WDT_OPT_PAUSE_IN_SLEEP is a bit tricky because depending on + * the frequency the platform is running at and the wdog timeout + * value relative to the sleep time, the system may wakeup enough + * to keep system time accurate enough on timer rollovers. During + * this time, the wdog will start ticking again so you can + * possibly still have the wdog expire. + * + */ + data->wdog_config.workMode.enableWait = + (options & WDT_OPT_PAUSE_IN_SLEEP) == 0U; + data->wdog_config.workMode.enableStop = (options & WDT_OPT_PAUSE_IN_SLEEP) == 0U; data->wdog_config.workMode.enableDebug = (options & WDT_OPT_PAUSE_HALTED_BY_DBG) == 0U; + LOG_DBG("Setup the watchdog: options: %d", options); + WDOG_Init(base, &data->wdog_config); - LOG_DBG("Setup the watchdog"); return 0; } From 1e6887d1c513e9d293308fa4c8113d944e348b40 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Wed, 5 Mar 2025 16:39:00 -0800 Subject: [PATCH 33/40] bluetooth: fix bug when destroying tx queue buffers on disconnect Channel tx_queue purging on disconnect was inconsistently handled by the different channels: iso, l2cap, l2cap_br. iso channels handled purging in the tx_data_pull hook. l2cap and l2cap_br did the purging in channel delete functions and did not expect tx_data_pull to be called for a disconnected channel. Their data_pull functions could return a ptr to a net_buf that was still on the tx_queue, which is problematic when the conn tx_processor unrefs the returned buffer resulting in multiple calls to the buf destroy function. To make things consistent and correct, remove the code that tries to purge tx_queues in the tx_processor and only do purging in the channels themselves when they are deleted/disconnected. Also refactor and clarify referencing of the net_buf returned by tx_data_pull. It was confusing who had a reference and when, which could vary depending on the length of the original buffer. There are three cases: the buffer length is less than the tx.mps, greater the mps but less than the mtu so requiring segementation but not fragmentation, or greater than both mps and mtu so requiring both segmentation and fragmentation. The conn layer would increase the refcnt if the length was greater than the mtu, but not have any awareness of whether the net_buf was still on the tx_queue or not. Now it is the tx_data_pull callbacks responsibitity to increment the reference count if it is returning a pointer to a net_buf that it is still keeping on the tx_queue for segmentation purposes. The conn layer will now always transfer that reference into a fragment view and not conditional it on the length relative to the mtu, and always decrement the reference to the parent when the fragment is destroyed. So there is no risk of decrementing a reference to a net buf that might still be on a tx_queue, which simplifies error handling in particular. Also add error handling paths for when asserts are not enabled. Signed-off-by: Mike J. Chen --- subsys/bluetooth/host/classic/l2cap_br.c | 16 +++- subsys/bluetooth/host/conn.c | 111 ++++++++--------------- subsys/bluetooth/host/conn_internal.h | 14 ++- subsys/bluetooth/host/iso.c | 31 ++++--- subsys/bluetooth/host/l2cap.c | 30 +++--- 5 files changed, 98 insertions(+), 104 deletions(-) diff --git a/subsys/bluetooth/host/classic/l2cap_br.c b/subsys/bluetooth/host/classic/l2cap_br.c index 742c3a38ab6a2..61979b810bf98 100644 --- a/subsys/bluetooth/host/classic/l2cap_br.c +++ b/subsys/bluetooth/host/classic/l2cap_br.c @@ -1592,6 +1592,8 @@ struct net_buf *l2cap_br_data_pull(struct bt_conn *conn, size_t amount, size_t * return NULL; } + __ASSERT_NO_MSG(conn->state == BT_CONN_CONNECTED); + struct bt_l2cap_br_chan *br_chan; br_chan = CONTAINER_OF(pdu_ready, struct bt_l2cap_br_chan, _pdu_ready); @@ -1609,13 +1611,15 @@ struct net_buf *l2cap_br_data_pull(struct bt_conn *conn, size_t amount, size_t * __ASSERT(tx_pdu, "signaled ready but no PDUs in the TX queue"); - struct net_buf *pdu = CONTAINER_OF(tx_pdu, struct net_buf, node); + struct net_buf *q_pdu = CONTAINER_OF(tx_pdu, struct net_buf, node); - if (bt_buf_has_view(pdu)) { - LOG_ERR("already have view on %p", pdu); + if (bt_buf_has_view(q_pdu)) { + LOG_ERR("already have view on %p", q_pdu); return NULL; } + struct net_buf *pdu = net_buf_ref(q_pdu); + /* We can't interleave ACL fragments from different channels for the * same ACL conn -> we have to wait until a full L2 PDU is transferred * before switching channels. @@ -1623,13 +1627,15 @@ struct net_buf *l2cap_br_data_pull(struct bt_conn *conn, size_t amount, size_t * bool last_frag = amount >= pdu->len; if (last_frag) { - LOG_DBG("last frag, removing %p", pdu); + LOG_DBG("last frag, removing %p", q_pdu); __maybe_unused bool found; - found = sys_slist_find_and_remove(&br_chan->_pdu_tx_queue, &pdu->node); + found = sys_slist_find_and_remove(&br_chan->_pdu_tx_queue, &q_pdu->node); __ASSERT_NO_MSG(found); + net_buf_unref(q_pdu); + LOG_DBG("chan %p done", br_chan); lower_data_ready(br_chan); diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 0c34dc0b6160f..9e9f18c040a04 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -649,7 +649,7 @@ static bool is_acl_conn(struct bt_conn *conn) } static int send_buf(struct bt_conn *conn, struct net_buf *buf, - size_t len, void *cb, void *ud) + size_t len, bt_conn_tx_cb_t cb, void *ud) { struct net_buf *frag = NULL; struct bt_conn_tx *tx = NULL; @@ -659,13 +659,15 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf, if (buf->len == 0) { __ASSERT_NO_MSG(0); - return -EMSGSIZE; + err = -EMSGSIZE; + goto error_return; } if (bt_buf_has_view(buf)) { __ASSERT_NO_MSG(0); - return -EIO; + err = -EIO; + goto error_return; } LOG_DBG("conn %p buf %p len %zu buf->len %u cb %p ud %p", @@ -680,7 +682,8 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf, */ __ASSERT(0, "No controller bufs"); - return -ENOMEM; + err = -ENOMEM; + goto error_return; } /* Allocate and set the TX context */ @@ -689,8 +692,9 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf, /* See big comment above */ if (!tx) { __ASSERT(0, "No TX context"); - - return -ENOMEM; + k_sem_give(bt_conn_get_pkts(conn)); + err = -ENOMEM; + goto error_return; } tx->cb = cb; @@ -698,18 +702,17 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf, uint16_t frag_len = MIN(conn_mtu(conn), len); - __ASSERT_NO_MSG(buf->ref == 1); + /* Check that buf->ref is 1 or 2. It would be 1 if this + * was the only reference (e.g. buf was removed + * from the conn tx_queue). It would be 2 if the + * tx_data_pull kept it on the tx_queue for segmentation. + */ + __ASSERT_NO_MSG((buf->ref == 1) || (buf->ref == 2)); - if (buf->len > frag_len) { - LOG_DBG("keep %p around", buf); - frag = get_data_frag(net_buf_ref(buf), frag_len); - } else { - LOG_DBG("move %p ref in", buf); - /* Move the ref into `frag` for the last TX. That way `buf` will - * get destroyed when `frag` is destroyed. - */ - frag = get_data_frag(buf, frag_len); - } + /* The reference is always transferred to the frag, so when + * the frag is destroyed, the parent reference is decremented. + */ + frag = get_data_frag(buf, frag_len); /* Caller is supposed to check we have all resources to send */ __ASSERT_NO_MSG(frag != NULL); @@ -723,7 +726,7 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf, conn->next_is_frag = false; } - LOG_DBG("send frag: buf %p len %d", buf, frag_len); + LOG_DBG("send frag: buf %p len %d", frag, frag_len); /* At this point, the buffer is either a fragment or a full HCI packet. * The flags are also valid. @@ -766,15 +769,26 @@ static int send_buf(struct bt_conn *conn, struct net_buf *buf, */ net_buf_unref(frag); - /* `buf` might not get destroyed right away, and its `tx` - * pointer will still be reachable. Make sure that we don't try - * to use the destroyed context later. + /* `buf` might not get destroyed right away because it may + * still be on a conn tx_queue, and its `tx` pointer will still + * be reachable. Make sure that we don't try to use the + * destroyed context later. */ conn_tx_destroy(conn, tx); k_sem_give(bt_conn_get_pkts(conn)); /* Merge HCI driver errors */ return -EIO; + +error_return: + /* Runtime handling of fatal errors when ASSERTS are disabled. + * Unref the buf and invoke callback with the error. + */ + net_buf_unref(buf); + if (cb) { + cb(conn, ud, err); + } + return err; } static struct k_poll_signal conn_change = @@ -956,8 +970,8 @@ struct bt_conn *get_conn_ready(void) sys_slist_remove(&bt_dev.le.conn_ready, prev, &conn->_conn_ready); (void)atomic_set(&conn->_conn_ready_lock, 0); - /* Append connection to list if it still has data */ - if (conn->has_data(conn)) { + /* Append connection to list if it is connected and still has data */ + if (conn->has_data(conn) && (conn->state == BT_CONN_CONNECTED)) { LOG_DBG("appending %p to back of TX queue", conn); bt_conn_data_ready(conn); } @@ -985,30 +999,6 @@ static void acl_get_and_clear_cb(struct bt_conn *conn, struct net_buf *buf, } #endif /* defined(CONFIG_BT_CONN) */ -/* Acts as a "null-routed" bt_send(). This fn will decrease the refcount of - * `buf` and call the user callback with an error code. - */ -static void destroy_and_callback(struct bt_conn *conn, - struct net_buf *buf, - bt_conn_tx_cb_t cb, - void *ud) -{ - if (!cb) { - conn->get_and_clear_cb(conn, buf, &cb, &ud); - } - - LOG_DBG("pop: cb %p userdata %p", cb, ud); - - /* bt_send() would've done an unref. Do it here also, so the buffer is - * hopefully destroyed and the user callback can allocate a new one. - */ - net_buf_unref(buf); - - if (cb) { - cb(conn, ud, -ESHUTDOWN); - } -} - static volatile bool _suspend_tx; #if defined(CONFIG_BT_TESTING) @@ -1051,17 +1041,7 @@ void bt_conn_tx_processor(void) if (conn->state != BT_CONN_CONNECTED) { LOG_WRN("conn %p: not connected", conn); - - /* Call the user callbacks & destroy (final-unref) the buffers - * we were supposed to send. - */ - buf = conn->tx_data_pull(conn, SIZE_MAX, &buf_len); - while (buf) { - destroy_and_callback(conn, buf, cb, ud); - buf = conn->tx_data_pull(conn, SIZE_MAX, &buf_len); - } - - goto exit; + goto raise_and_exit; } /* now that we are guaranteed resources, we can pull data from the upper @@ -1095,25 +1075,12 @@ void bt_conn_tx_processor(void) int err = send_buf(conn, buf, buf_len, cb, ud); if (err) { - /* -EIO means `unrecoverable error`. It can be an assertion that - * failed or an error from the HCI driver. - * - * -ENOMEM means we thought we had all the resources to send the - * buf (ie. TX context + controller buffer) but one of them was - * not available. This is likely due to a failure of - * assumption, likely that we have been pre-empted somehow and - * that `tx_processor()` has been re-entered. - * - * In both cases, we destroy the buffer and mark the connection - * as dead. - */ LOG_ERR("Fatal error (%d). Disconnecting %p", err, conn); - destroy_and_callback(conn, buf, cb, ud); bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - goto exit; } +raise_and_exit: /* Always kick the TX work. It will self-suspend if it doesn't get * resources or there is nothing left to send. */ diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 41f396a1aeed5..909c0ebd22ef0 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -288,10 +288,22 @@ struct bt_conn { #endif /* Callback into the higher-layers (L2CAP / ISO) to return a buffer for - * sending `amount` of bytes to HCI. + * sending `amount` of bytes to HCI. Will only be called when + * the state is connected. The higher-layer is responsible for purging + * the remaining buffers on disconnect. * * Scheduling from which channel to pull (e.g. for L2CAP) is done at the * upper layer's discretion. + * + * Details about the returned net_buf when it is not NULL: + * - If the net_buf->len <= *length, then the net_buf has been removed + * from the tx_queue of the connection and the caller is now the + * owner of the only reference to the net_buf. + * - Otherwise, the net_buf is still on the tx_queue of the connection, + * and the callback has incremented the reference count to account + * for it having a reference still. + * - The caller must consume *length bytes from the net_buf before + * calling this function again. */ struct net_buf * (*tx_data_pull)(struct bt_conn *conn, size_t amount, diff --git a/subsys/bluetooth/host/iso.c b/subsys/bluetooth/host/iso.c index eb6eaa7835045..a59158a43d31a 100644 --- a/subsys/bluetooth/host/iso.c +++ b/subsys/bluetooth/host/iso.c @@ -454,10 +454,18 @@ void bt_iso_connected(struct bt_conn *iso) static void bt_iso_chan_disconnected(struct bt_iso_chan *chan, uint8_t reason) { const uint8_t conn_type = chan->iso->iso.info.type; + struct net_buf *buf; + LOG_DBG("%p, reason 0x%02x", chan, reason); __ASSERT(chan->iso != NULL, "NULL conn for iso chan %p", chan); + /* release buffers from tx_queue */ + while ((buf = k_fifo_get(&chan->iso->iso.txq, K_NO_WAIT))) { + __ASSERT_NO_MSG(!bt_buf_has_view(buf)); + net_buf_unref(buf); + } + bt_iso_chan_set_state(chan, BT_ISO_STATE_DISCONNECTED); bt_conn_set_state(chan->iso, BT_CONN_DISCONNECT_COMPLETE); @@ -775,7 +783,8 @@ void bt_iso_recv(struct bt_conn *iso, struct net_buf *buf, uint8_t flags) static bool iso_has_data(struct bt_conn *conn) { #if defined(CONFIG_BT_ISO_TX) - return !k_fifo_is_empty(&conn->iso.txq); + return ((conn->iso.chan->state == BT_ISO_STATE_CONNECTED) && + !k_fifo_is_empty(&conn->iso.txq)); #else /* !CONFIG_BT_ISO_TX */ return false; #endif /* CONFIG_BT_ISO_TX */ @@ -789,9 +798,9 @@ static struct net_buf *iso_data_pull(struct bt_conn *conn, size_t amount, size_t /* Leave the PDU buffer in the queue until we have sent all its * fragments. */ - struct net_buf *frag = k_fifo_peek_head(&conn->iso.txq); + struct net_buf *q_frag = k_fifo_peek_head(&conn->iso.txq); - if (!frag) { + if (!q_frag) { BT_ISO_DATA_DBG("signaled ready but no frag available"); /* Service other connections */ bt_tx_irq_raise(); @@ -799,13 +808,10 @@ static struct net_buf *iso_data_pull(struct bt_conn *conn, size_t amount, size_t return NULL; } - if (conn->iso.chan->state != BT_ISO_STATE_CONNECTED) { - __maybe_unused struct net_buf *b = k_fifo_get(&conn->iso.txq, K_NO_WAIT); + __ASSERT_NO_MSG(conn->state == BT_CONN_CONNECTED); + if (conn->iso.chan->state != BT_ISO_STATE_CONNECTED) { LOG_DBG("channel has been disconnected"); - __ASSERT_NO_MSG(b == frag); - - net_buf_unref(b); /* Service other connections */ bt_tx_irq_raise(); @@ -813,7 +819,7 @@ static struct net_buf *iso_data_pull(struct bt_conn *conn, size_t amount, size_t return NULL; } - if (bt_buf_has_view(frag)) { + if (bt_buf_has_view(q_frag)) { /* This should not happen. conn.c should wait until the view is * destroyed before requesting more data. */ @@ -821,13 +827,16 @@ static struct net_buf *iso_data_pull(struct bt_conn *conn, size_t amount, size_t return NULL; } + struct net_buf *frag = net_buf_ref(q_frag); bool last_frag = amount >= frag->len; if (last_frag) { - __maybe_unused struct net_buf *b = k_fifo_get(&conn->iso.txq, K_NO_WAIT); + q_frag = k_fifo_get(&conn->iso.txq, K_NO_WAIT); BT_ISO_DATA_DBG("last frag, pop buf"); - __ASSERT_NO_MSG(b == frag); + __ASSERT_NO_MSG(q_frag == frag); + + net_buf_unref(q_frag); } *length = frag->len; diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 433eb8faef092..ac6fc60dbad6a 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -83,11 +83,6 @@ NET_BUF_POOL_FIXED_DEFINE(disc_pool, 1, #define l2cap_remove_ident(conn, ident) __l2cap_lookup_ident(conn, ident, true) static sys_slist_t servers = SYS_SLIST_STATIC_INIT(&servers); - -static void l2cap_tx_buf_destroy(struct bt_conn *conn, struct net_buf *buf, int err) -{ - net_buf_unref(buf); -} #endif /* CONFIG_BT_L2CAP_DYNAMIC_CHANNEL */ /* L2CAP signalling channel specific context */ @@ -257,6 +252,7 @@ void bt_l2cap_chan_del(struct bt_l2cap_chan *chan) { const struct bt_l2cap_chan_ops *ops = chan->ops; struct bt_l2cap_le_chan *le_chan = BT_L2CAP_LE_CHAN(chan); + struct net_buf *buf; LOG_DBG("conn %p chan %p", chan->conn, chan); @@ -269,9 +265,7 @@ void bt_l2cap_chan_del(struct bt_l2cap_chan *chan) /* Remove buffers on the PDU TX queue. We can't do that in * `l2cap_chan_destroy()` as it is not called for fixed channels. */ - while (chan_has_data(le_chan)) { - struct net_buf *buf = k_fifo_get(&le_chan->tx_queue, K_NO_WAIT); - + while ((buf = k_fifo_get(&le_chan->tx_queue, K_NO_WAIT))) { net_buf_unref(buf); } @@ -919,20 +913,22 @@ struct net_buf *l2cap_data_pull(struct bt_conn *conn, * For SDUs we do the same, we keep it in the queue until all the * segments have been sent, adding the PDU headers just-in-time. */ - struct net_buf *pdu = k_fifo_peek_head(&lechan->tx_queue); + struct net_buf *fifo_pdu = k_fifo_peek_head(&lechan->tx_queue); /* We don't have anything to send for the current channel. We could * however have something to send on another channel that is attached to * the same ACL connection. Re-trigger the TX processor: it will call us * again and this time we will select another channel to pull data from. */ - if (!pdu) { + if (!fifo_pdu) { bt_tx_irq_raise(); return NULL; } - if (bt_buf_has_view(pdu)) { - LOG_ERR("already have view on %p", pdu); + __ASSERT_NO_MSG(conn->state == BT_CONN_CONNECTED); + + if (bt_buf_has_view(fifo_pdu)) { + LOG_ERR("already have view on %p", fifo_pdu); return NULL; } @@ -946,6 +942,8 @@ struct net_buf *l2cap_data_pull(struct bt_conn *conn, return NULL; } + struct net_buf *pdu = net_buf_ref(fifo_pdu); + /* Add PDU header */ if (lechan->_pdu_remaining == 0) { struct bt_l2cap_hdr *hdr; @@ -975,9 +973,11 @@ struct net_buf *l2cap_data_pull(struct bt_conn *conn, if (last_frag && last_seg) { LOG_DBG("last frag of last seg, dequeuing %p", pdu); - __maybe_unused struct net_buf *b = k_fifo_get(&lechan->tx_queue, K_NO_WAIT); + fifo_pdu = k_fifo_get(&lechan->tx_queue, K_NO_WAIT); - __ASSERT_NO_MSG(b == pdu); + __ASSERT_NO_MSG(fifo_pdu == pdu); + + net_buf_unref(fifo_pdu); } if (last_frag && L2CAP_LE_CID_IS_DYN(lechan->tx.cid)) { @@ -2290,7 +2290,7 @@ static void l2cap_chan_shutdown(struct bt_l2cap_chan *chan) /* Remove buffers on the TX queue */ while ((buf = k_fifo_get(&le_chan->tx_queue, K_NO_WAIT))) { - l2cap_tx_buf_destroy(chan->conn, buf, -ESHUTDOWN); + net_buf_unref(buf); } /* Remove buffers on the RX queue */ From 72f75bd3c8003ce20f07340c2ff6a463be768d40 Mon Sep 17 00:00:00 2001 From: "Mike J. Chen" Date: Mon, 9 Jun 2025 16:10:44 -0700 Subject: [PATCH 34/40] tests: bsim: add early disconnect tests for iso and l2cap Add early_disconnect test cases for iso/cis and l2cap/stress to test the bluetooth stack handling of disconnects while transmit is still in progress. Signed-off-by: Mike J. Chen --- tests/bsim/bluetooth/host/iso/cis/prj.conf | 1 + .../bluetooth/host/iso/cis/src/cis_central.c | 18 +- .../host/iso/cis/src/cis_peripheral.c | 36 ++++ .../cis/tests_scripts/cis_early_disconnect.sh | 29 +++ .../stress/overlay-early-disconnect.conf | 1 + .../bluetooth/host/l2cap/stress/src/main.c | 203 +++++++++++++++++- .../bluetooth/host/l2cap/stress/testcase.yaml | 4 + .../tests_scripts/l2cap_early_disconnect.sh | 47 ++++ 8 files changed, 327 insertions(+), 12 deletions(-) create mode 100755 tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis_early_disconnect.sh create mode 100644 tests/bsim/bluetooth/host/l2cap/stress/overlay-early-disconnect.conf create mode 100755 tests/bsim/bluetooth/host/l2cap/stress/tests_scripts/l2cap_early_disconnect.sh diff --git a/tests/bsim/bluetooth/host/iso/cis/prj.conf b/tests/bsim/bluetooth/host/iso/cis/prj.conf index 4ad0a0fd319ae..06f0282329678 100644 --- a/tests/bsim/bluetooth/host/iso/cis/prj.conf +++ b/tests/bsim/bluetooth/host/iso/cis/prj.conf @@ -16,6 +16,7 @@ CONFIG_BT_ISO_TX_MTU=200 CONFIG_BT_ISO_RX_MTU=200 CONFIG_BT_ISO_LOG_LEVEL_DBG=y +CONFIG_NET_BUF_POOL_USAGE=y # Controller Connected ISO configs CONFIG_BT_CTLR_CENTRAL_ISO=y diff --git a/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c b/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c index dc7d46100a9eb..e3b6ee9284fe0 100644 --- a/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c +++ b/tests/bsim/bluetooth/host/iso/cis/src/cis_central.c @@ -154,6 +154,11 @@ static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason) err = bt_iso_remove_data_path(chan, BT_HCI_DATAPATH_DIR_HOST_TO_CTLR); TEST_ASSERT(err == 0, "Failed to remove ISO data path: %d", err); + + if (seq_num < 100) { + printk("Channel disconnected early, bumping seq_num to 1000 to end test\n"); + seq_num = 1000; + } } static void sdu_sent_cb(struct bt_iso_chan *chan) @@ -462,9 +467,16 @@ static void test_main(void) k_sleep(K_USEC(interval_us)); } - disconnect_cis(); - disconnect_acl(); - terminate_cig(); + if (seq_num == 100) { + disconnect_cis(); + disconnect_acl(); + terminate_cig(); + } + + /* check that all buffers returned to pool */ + TEST_ASSERT(atomic_get(&tx_pool.avail_count) == ENQUEUE_COUNT, + "tx_pool has non returned buffers, should be %u but is %u", + ENQUEUE_COUNT, atomic_get(&tx_pool.avail_count)); TEST_PASS("Test passed"); } diff --git a/tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c b/tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c index 96b8865c1f4ee..e8b3ff37a9d5f 100644 --- a/tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c +++ b/tests/bsim/bluetooth/host/iso/cis/src/cis_peripheral.c @@ -35,6 +35,9 @@ static const struct bt_data ad[] = { }; static struct bt_iso_chan iso_chan; +static size_t disconnect_after_recv_cnt; +static size_t iso_recv_cnt; + /** Print data as d_0 d_1 d_2 ... d_(n-2) d_(n-1) d_(n) to show the 3 first and 3 last octets * * Examples: @@ -72,14 +75,26 @@ static void iso_print_data(uint8_t *data, size_t data_len) printk("\t %s\n", data_str); } +static void disconnect_device(struct bt_conn *conn, void *data) +{ + int err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + + TEST_ASSERT(!err, "Failed to initate disconnect (err %d)", err); +} + static void iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info, struct net_buf *buf) { + iso_recv_cnt++; if (info->flags & BT_ISO_FLAGS_VALID) { printk("Incoming data channel %p len %u\n", chan, buf->len); iso_print_data(buf->data, buf->len); SET_FLAG(flag_data_received); } + if (disconnect_after_recv_cnt && (iso_recv_cnt >= disconnect_after_recv_cnt)) { + printk("Disconnecting\n"); + bt_conn_foreach(BT_CONN_TYPE_LE, disconnect_device, NULL); + } } static void iso_connected(struct bt_iso_chan *chan) @@ -189,12 +204,33 @@ static void test_main(void) } } +static void test_main_early_disconnect(void) +{ + init(); + + disconnect_after_recv_cnt = 10; + + while (true) { + adv_connect(); + bt_testlib_conn_wait_free(); + + if (IS_FLAG_SET(flag_data_received)) { + TEST_PASS("Test passed"); + } + } +} + static const struct bst_test_instance test_def[] = { { .test_id = "peripheral", .test_descr = "Peripheral", .test_main_f = test_main, }, + { + .test_id = "peripheral_early_disconnect", + .test_descr = "Peripheral that tests early disconnect", + .test_main_f = test_main_early_disconnect, + }, BSTEST_END_MARKER, }; diff --git a/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis_early_disconnect.sh b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis_early_disconnect.sh new file mode 100755 index 0000000000000..bac2c2e82a11a --- /dev/null +++ b/tests/bsim/bluetooth/host/iso/cis/tests_scripts/cis_early_disconnect.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +# Copyright (c) 2025 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +# Tests cleanup within the ble stack for ISO connections when +# peripheral disconnects early while the central still has +# buffers queued for sending. Using the base code, which +# has the central sending 100 ISO packets, the peripheral +# triggers a disconnect after receiving 10 packets. +# The central checks that all tx_pool buffers have been +# returned to the pool after the disconnect. +simulation_id="iso_cis_early_disconnect" +verbosity_level=2 +EXECUTE_TIMEOUT=120 + +cd ${BSIM_OUT_PATH}/bin + +Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_iso_cis_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central + +Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_iso_cis_prj_conf \ + -v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral_early_disconnect + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ + -D=2 -sim_length=30e6 $@ + +wait_for_background_jobs diff --git a/tests/bsim/bluetooth/host/l2cap/stress/overlay-early-disconnect.conf b/tests/bsim/bluetooth/host/l2cap/stress/overlay-early-disconnect.conf new file mode 100644 index 0000000000000..94dfb1ed30d05 --- /dev/null +++ b/tests/bsim/bluetooth/host/l2cap/stress/overlay-early-disconnect.conf @@ -0,0 +1 @@ +CONFIG_BT_L2CAP_SEG_RECV=y diff --git a/tests/bsim/bluetooth/host/l2cap/stress/src/main.c b/tests/bsim/bluetooth/host/l2cap/stress/src/main.c index d05f4e4f0a745..a411354bb791c 100644 --- a/tests/bsim/bluetooth/host/l2cap/stress/src/main.c +++ b/tests/bsim/bluetooth/host/l2cap/stress/src/main.c @@ -17,6 +17,7 @@ #include #include "babblekit/testcase.h" #include "babblekit/flags.h" +#include "bsim_args_runner.h" #define LOG_MODULE_NAME main #include @@ -31,6 +32,18 @@ DEFINE_FLAG_STATIC(flag_l2cap_connected); #define SDU_LEN 3000 #define RESCHEDULE_DELAY K_MSEC(100) +/* The early_disconnect test has the peripheral disconnect at various + * times: + * + * Peripheral 1: disconnects after all 20 SDUs as before + * Peripheral 2: disconnects immediately before receiving anything + * Peripheral 3: disconnects after receiving first SDU + * Peripheral 4: disconnects after receiving first PDU in second SDU + * Peripheral 5: disconnects after receiving third PDU in third SDU + * Peripheral 6: disconnects atfer receiving tenth PDU in tenth SDU + */ +static unsigned int device_nbr; + static void sdu_destroy(struct net_buf *buf) { LOG_DBG("%p", buf); @@ -56,7 +69,7 @@ NET_BUF_POOL_DEFINE(sdu_rx_pool, 8, rx_destroy); static uint8_t tx_data[SDU_LEN]; -static uint16_t rx_cnt; +static uint16_t sdu_rx_cnt; static uint8_t disconnect_counter; struct test_ctx { @@ -138,10 +151,66 @@ void sent_cb(struct bt_l2cap_chan *chan) continue_sending(ctx); } +#ifdef CONFIG_BT_L2CAP_SEG_RECV +static void disconnect_device_no_wait(struct bt_conn *conn, void *data) +{ + int err; + + err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + TEST_ASSERT(!err, "Failed to initate disconnect (err %d)", err); + + UNSET_FLAG(is_connected); +} + +static void seg_recv_cb(struct bt_l2cap_chan *chan, size_t sdu_len, off_t seg_offset, + struct net_buf_simple *seg) +{ + static size_t pdu_rx_cnt; + + if ((seg_offset + seg->len) == sdu_len) { + /* last segment/PDU of a SDU */ + LOG_DBG("len %d", seg->len); + sdu_rx_cnt++; + pdu_rx_cnt = 0; + } else { + LOG_DBG("SDU %u, pdu %u at seg_offset %u, len %u", + sdu_rx_cnt, pdu_rx_cnt, seg_offset, seg->len); + pdu_rx_cnt++; + } + + /* Verify SDU data matches TX'd data. */ + int pos = memcmp(seg->data, &tx_data[seg_offset], seg->len); + + if (pos != 0) { + LOG_ERR("RX data doesn't match TX: pos %d", seg_offset); + LOG_HEXDUMP_ERR(seg->data, seg->len, "RX data"); + LOG_HEXDUMP_INF(tx_data, seg->len, "TX data"); + + for (uint16_t p = 0; p < seg->len; p++) { + __ASSERT(seg->data[p] == tx_data[p + seg_offset], + "Failed rx[%d]=%x != expect[%d]=%x", + p, seg->data[p], p, tx_data[p + seg_offset]); + } + } + + if (((device_nbr == 4) && (sdu_rx_cnt >= 1) && (pdu_rx_cnt == 1)) || + ((device_nbr == 5) && (sdu_rx_cnt >= 2) && (pdu_rx_cnt == 3)) || + ((device_nbr == 6) && (sdu_rx_cnt >= 9) && (pdu_rx_cnt == 10))) { + LOG_INF("disconnecting after receiving PDU %u of SDU %u", + pdu_rx_cnt - 1, sdu_rx_cnt); + bt_conn_foreach(BT_CONN_TYPE_LE, disconnect_device_no_wait, NULL); + return; + } + + if (is_connected) { + bt_l2cap_chan_give_credits(chan, 1); + } +} +#else /* CONFIG_BT_L2CAP_SEG_RECV */ int recv_cb(struct bt_l2cap_chan *chan, struct net_buf *buf) { LOG_DBG("len %d", buf->len); - rx_cnt++; + sdu_rx_cnt++; /* Verify SDU data matches TX'd data. */ int pos = memcmp(buf->data, tx_data, buf->len); @@ -160,6 +229,7 @@ int recv_cb(struct bt_l2cap_chan *chan, struct net_buf *buf) return 0; } +#endif /* CONFIG_BT_L2CAP_SEG_RECV */ void l2cap_chan_connected_cb(struct bt_l2cap_chan *l2cap_chan) { @@ -167,25 +237,41 @@ void l2cap_chan_connected_cb(struct bt_l2cap_chan *l2cap_chan) CONTAINER_OF(l2cap_chan, struct bt_l2cap_le_chan, chan); SET_FLAG(flag_l2cap_connected); - LOG_DBG("%x (tx mtu %d mps %d) (tx mtu %d mps %d)", + LOG_DBG("%x (tx mtu %d mps %d cr %ld) (tx mtu %d mps %d cr %ld)", l2cap_chan, chan->tx.mtu, chan->tx.mps, + atomic_get(&chan->tx.credits), chan->rx.mtu, - chan->rx.mps); + chan->rx.mps, + atomic_get(&chan->rx.credits)); } -void l2cap_chan_disconnected_cb(struct bt_l2cap_chan *chan) +void l2cap_chan_disconnected_cb(struct bt_l2cap_chan *l2cap_chan) { UNSET_FLAG(flag_l2cap_connected); - LOG_DBG("%p", chan); + LOG_DBG("%p", l2cap_chan); + for (int i = 0; i < L2CAP_CHANS; i++) { + if (&contexts[i].le_chan == CONTAINER_OF(l2cap_chan, + struct bt_l2cap_le_chan, chan)) { + if (contexts[i].tx_left > 0) { + LOG_INF("setting tx_left to 0 because of disconnect"); + contexts[i].tx_left = 0; + } + break; + } + } } static struct bt_l2cap_chan_ops ops = { .connected = l2cap_chan_connected_cb, .disconnected = l2cap_chan_disconnected_cb, .alloc_buf = alloc_buf_cb, +#ifdef CONFIG_BT_L2CAP_SEG_RECV + .seg_recv = seg_recv_cb, +#else .recv = recv_cb, +#endif .sent = sent_cb, }; @@ -234,6 +320,10 @@ int server_accept_cb(struct bt_conn *conn, struct bt_l2cap_server *server, memset(le_chan, 0, sizeof(*le_chan)); le_chan->chan.ops = &ops; le_chan->rx.mtu = SDU_LEN; +#ifdef CONFIG_BT_L2CAP_SEG_RECV + le_chan->rx.mps = BT_L2CAP_RX_MTU; + le_chan->rx.credits = CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA; +#endif *chan = &le_chan->chan; return 0; @@ -335,15 +425,93 @@ static void test_peripheral_main(void) LOG_DBG("Registered server PSM %x", psm); LOG_DBG("Peripheral waiting for transfer completion"); - while (rx_cnt < SDU_NUM) { + while (sdu_rx_cnt < SDU_NUM) { + k_msleep(100); + } + + bt_conn_foreach(BT_CONN_TYPE_LE, disconnect_device, NULL); + + WAIT_FOR_FLAG_UNSET(is_connected); + LOG_INF("Total received: %d", sdu_rx_cnt); + + /* check that all buffers returned to pool */ + TEST_ASSERT(atomic_get(&sdu_tx_pool.avail_count) == CONFIG_BT_MAX_CONN, + "sdu_tx_pool has non returned buffers, should be %u but is %u", + CONFIG_BT_MAX_CONN, atomic_get(&sdu_tx_pool.avail_count)); + TEST_ASSERT(atomic_get(&sdu_rx_pool.avail_count) == CONFIG_BT_MAX_CONN, + "sdu_rx_pool has non returned buffers, should be %u but is %u", + CONFIG_BT_MAX_CONN, atomic_get(&sdu_rx_pool.avail_count)); + + TEST_PASS("L2CAP STRESS Peripheral passed"); +} + +static void test_peripheral_early_disconnect_main(void) +{ + device_nbr = bsim_args_get_global_device_nbr(); + LOG_DBG("*L2CAP STRESS EARLY DISCONNECT Peripheral started*"); + int err; + + /* Prepare tx_data */ + for (size_t i = 0; i < sizeof(tx_data); i++) { + tx_data[i] = (uint8_t)i; + } + + err = bt_enable(NULL); + if (err) { + TEST_FAIL("Can't enable Bluetooth (err %d)", err); + return; + } + + LOG_DBG("Peripheral Bluetooth initialized."); + LOG_DBG("Connectable advertising..."); + err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, NULL, 0, NULL, 0); + if (err) { + TEST_FAIL("Advertising failed to start (err %d)", err); + return; + } + + LOG_DBG("Advertising started."); + LOG_DBG("Peripheral waiting for connection..."); + WAIT_FOR_FLAG(is_connected); + LOG_DBG("Peripheral Connected."); + + int psm = l2cap_server_register(BT_SECURITY_L1); + + LOG_DBG("Registered server PSM %x", psm); + + if (device_nbr == 2) { + LOG_INF("disconnecting before receiving any SDU"); + k_msleep(1000); + goto disconnect; + } + + LOG_DBG("Peripheral waiting for transfer completion"); + while (sdu_rx_cnt < SDU_NUM) { + if ((device_nbr == 3) && (sdu_rx_cnt >= 1)) { + LOG_INF("disconnecting after receiving SDU %u", sdu_rx_cnt); + break; + } + k_msleep(100); + if (!is_connected) { + goto done; + } } +disconnect: bt_conn_foreach(BT_CONN_TYPE_LE, disconnect_device, NULL); +done: + WAIT_FOR_FLAG_UNSET(is_connected); - LOG_INF("Total received: %d", rx_cnt); + LOG_INF("Total received: %d", sdu_rx_cnt); - TEST_ASSERT(rx_cnt == SDU_NUM, "Did not receive expected no of SDUs"); + /* check that all buffers returned to pool */ + TEST_ASSERT(atomic_get(&sdu_tx_pool.avail_count) == CONFIG_BT_MAX_CONN, + "sdu_tx_pool has non returned buffers, should be %u but is %u", + CONFIG_BT_MAX_CONN, atomic_get(&sdu_tx_pool.avail_count)); + TEST_ASSERT(atomic_get(&sdu_rx_pool.avail_count) == CONFIG_BT_MAX_CONN, + "sdu_rx_pool has non returned buffers, should be %u but is %u", + CONFIG_BT_MAX_CONN, atomic_get(&sdu_rx_pool.avail_count)); TEST_PASS("L2CAP STRESS Peripheral passed"); } @@ -405,6 +573,10 @@ static void connect_l2cap_channel(struct bt_conn *conn, void *data) le_chan->chan.ops = &ops; le_chan->rx.mtu = SDU_LEN; +#ifdef CONFIG_BT_L2CAP_SEG_RECV + le_chan->rx.mps = BT_L2CAP_RX_MTU; + le_chan->rx.credits = CONFIG_BT_BUF_ACL_RX_COUNT_EXTRA; +#endif UNSET_FLAG(flag_l2cap_connected); @@ -461,6 +633,14 @@ static void test_central_main(void) } LOG_DBG("All peripherals disconnected."); + /* check that all buffers returned to pool */ + TEST_ASSERT(atomic_get(&sdu_tx_pool.avail_count) == CONFIG_BT_MAX_CONN, + "sdu_tx_pool has non returned buffers, should be %u but is %u", + CONFIG_BT_MAX_CONN, atomic_get(&sdu_tx_pool.avail_count)); + TEST_ASSERT(atomic_get(&sdu_rx_pool.avail_count) == CONFIG_BT_MAX_CONN, + "sdu_rx_pool has non returned buffers, should be %u but is %u", + CONFIG_BT_MAX_CONN, atomic_get(&sdu_rx_pool.avail_count)); + TEST_PASS("L2CAP STRESS Central passed"); } @@ -470,6 +650,11 @@ static const struct bst_test_instance test_def[] = { .test_descr = "Peripheral L2CAP STRESS", .test_main_f = test_peripheral_main }, + { + .test_id = "peripheral_early_disconnect", + .test_descr = "Peripheral L2CAP STRESS EARLY DISCONNECT", + .test_main_f = test_peripheral_early_disconnect_main, + }, { .test_id = "central", .test_descr = "Central L2CAP STRESS", diff --git a/tests/bsim/bluetooth/host/l2cap/stress/testcase.yaml b/tests/bsim/bluetooth/host/l2cap/stress/testcase.yaml index f872f5873dae8..8fbe85a3b646c 100644 --- a/tests/bsim/bluetooth/host/l2cap/stress/testcase.yaml +++ b/tests/bsim/bluetooth/host/l2cap/stress/testcase.yaml @@ -10,6 +10,10 @@ tests: bluetooth.host.l2cap.stress: harness_config: bsim_exe_name: tests_bsim_bluetooth_host_l2cap_stress_prj_conf + bluetooth.host.l2cap.stress_early_disconnect: + harness_config: + bsim_exe_name: tests_bsim_bluetooth_host_l2cap_stress_prj_conf_overlay-early-disc_conf + extra_args: EXTRA_CONF_FILE="overlay-early-disconnect.conf" bluetooth.host.l2cap.stress_nofrag: harness_config: bsim_exe_name: tests_bsim_bluetooth_host_l2cap_stress_prj_conf_overlay-nofrag_conf diff --git a/tests/bsim/bluetooth/host/l2cap/stress/tests_scripts/l2cap_early_disconnect.sh b/tests/bsim/bluetooth/host/l2cap/stress/tests_scripts/l2cap_early_disconnect.sh new file mode 100755 index 0000000000000..8741839e762f7 --- /dev/null +++ b/tests/bsim/bluetooth/host/l2cap/stress/tests_scripts/l2cap_early_disconnect.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Copyright (c) 2025 Google LLC +# SPDX-License-Identifier: Apache-2.0 + +source ${ZEPHYR_BASE}/tests/bsim/sh_common.source + +# Tests cleanup within the ble stack for L2CAP connections when +# peripheral disconnects early while the central still has +# buffers queued for sending. Using the base code, which +# has the central sending 20 SDUs to 6 different peripherals, +# the test has the peripherals disconnect as follows: +# +# Peripheral 1: disconnects after all 20 SDUs as before +# Peripheral 2: disconnects immediately before receiving anything +# Peripheral 3: disconnects after receiving first SDU +# Peripheral 4: disconnects after receiving first PDU in second SDU +# Peripheral 5: disconnects after receiving third PDU in third SDU +# Peripheral 6: disconnects atfer receiving tenth PDU in tenth SDU +# +# The central and peripherals check that all tx_pool and rx_pool +# buffers have been returned after the disconnect. +simulation_id="l2cap_stress_early_disconnect" +verbosity_level=2 +EXECUTE_TIMEOUT=240 + +bsim_exe=./bs_${BOARD_TS}_tests_bsim_bluetooth_host_l2cap_stress_prj_conf_overlay-early-disc_conf + +cd ${BSIM_OUT_PATH}/bin + +Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -rs=43 + +Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=1 \ + -testid=peripheral_early_disconnect -rs=42 +Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=2 \ + -testid=peripheral_early_disconnect -rs=10 +Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=3 \ + -testid=peripheral_early_disconnect -rs=23 +Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=4 \ + -testid=peripheral_early_disconnect -rs=7884 +Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=5 \ + -testid=peripheral_early_disconnect -rs=230 +Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=6 \ + -testid=peripheral_early_disconnect -rs=9 + +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=7 -sim_length=400e6 $@ + +wait_for_background_jobs From 1a2d5c3448098b194ea9c810f90645d7992fd06b Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 29 May 2025 13:31:12 +0000 Subject: [PATCH 35/40] scripts: do_not_merge: add some debug prints Log the PR link and labels, may come in handy for troubleshooting down the road. Signed-off-by: Fabio Baltieri --- scripts/ci/do_not_merge.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/ci/do_not_merge.py b/scripts/ci/do_not_merge.py index ccaa806bfeb2e..a22b4271ad6c2 100755 --- a/scripts/ci/do_not_merge.py +++ b/scripts/ci/do_not_merge.py @@ -42,7 +42,11 @@ def main(argv): repo = gh.get_repo("zephyrproject-rtos/zephyr") pr = repo.get_pull(args.pull_request) + print(f"pr: {pr.html_url}") + for label in pr.get_labels(): + print(f"label: {label.name}") + if label.name in DNM_LABELS: print(f"Pull request is labeled as \"{label.name}\".") print("This workflow fails so that the pull request cannot be merged.") From 38d55be4b0a8cc312cd6caad6fcbb13525054eac Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 29 May 2025 13:36:13 +0000 Subject: [PATCH 36/40] scripts: do_not_merge: integrate the empty body check in the python file No point spreading the logic around, the python file already has the data, check it there. Signed-off-by: Fabio Baltieri --- .github/workflows/pr_metadata_check.yml | 10 ---------- scripts/ci/do_not_merge.py | 13 +++++++++++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.github/workflows/pr_metadata_check.yml b/.github/workflows/pr_metadata_check.yml index 8f26af73a05ea..412903c2a0383 100644 --- a/.github/workflows/pr_metadata_check.yml +++ b/.github/workflows/pr_metadata_check.yml @@ -37,13 +37,3 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | ./scripts/ci/do_not_merge.py -p "${{ github.event.pull_request.number }}" - - empty_pr_description: - if: ${{ github.event.pull_request.body == '' }} - name: PR Description - runs-on: ubuntu-24.04 - steps: - - name: Check for PR description - run: | - echo "Pull request description cannot be empty." - exit 1 diff --git a/scripts/ci/do_not_merge.py b/scripts/ci/do_not_merge.py index a22b4271ad6c2..a93b373a01a0a 100755 --- a/scripts/ci/do_not_merge.py +++ b/scripts/ci/do_not_merge.py @@ -44,13 +44,22 @@ def main(argv): print(f"pr: {pr.html_url}") + fail = False + for label in pr.get_labels(): print(f"label: {label.name}") if label.name in DNM_LABELS: print(f"Pull request is labeled as \"{label.name}\".") - print("This workflow fails so that the pull request cannot be merged.") - sys.exit(1) + fail = True + + if not pr.body: + print("Pull request is description is empty.") + fail = True + + if fail: + print("This workflow fails so that the pull request cannot be merged.") + sys.exit(1) if __name__ == "__main__": From 7029ec9f567dca228b3e3b50c46f4f0f0905b1d2 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 29 May 2025 13:58:37 +0000 Subject: [PATCH 37/40] scripts: do_not_merge: wait for manifest before checking Seems like github relabel rerun is susceptible to race conditions and may not rerun the label check script if the manifest workflow runs at the same time. Delay the check to explicitly wait until the currently checked sha had a successful manifest run. Signed-off-by: Fabio Baltieri --- scripts/ci/do_not_merge.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/scripts/ci/do_not_merge.py b/scripts/ci/do_not_merge.py index a93b373a01a0a..d35aed8cbc819 100755 --- a/scripts/ci/do_not_merge.py +++ b/scripts/ci/do_not_merge.py @@ -4,8 +4,10 @@ # SPDX-License-Identifier: Apache-2.0 import argparse +import datetime import os import sys +import time import github @@ -31,6 +33,30 @@ def parse_args(argv): return parser.parse_args(argv) +WAIT_FOR_WORKFLOWS = set({"Manifest"}) +WAIT_FOR_DELAY_S = 60 + + +def workflow_delay(repo, pr): + print(f"PR is at {pr.head.sha}") + + while True: + runs = repo.get_workflow_runs(head_sha=pr.head.sha) + + completed = set() + for run in runs: + print(f"{run.name}: {run.status} {run.conclusion} {run.html_url}") + if run.status == "completed" and run.conclusion == "success": + completed.add(run.name) + + if WAIT_FOR_WORKFLOWS.issubset(completed): + return + + ts = datetime.datetime.now() + print(f"wait: {ts} completed={completed}") + time.sleep(WAIT_FOR_DELAY_S) + + def main(argv): args = parse_args(argv) @@ -42,6 +68,8 @@ def main(argv): repo = gh.get_repo("zephyrproject-rtos/zephyr") pr = repo.get_pull(args.pull_request) + workflow_delay(repo, pr) + print(f"pr: {pr.html_url}") fail = False From fa90a7ce1942c0e9caa56984465650c5849a4eb0 Mon Sep 17 00:00:00 2001 From: Fabio Baltieri Date: Thu, 29 May 2025 14:04:45 +0000 Subject: [PATCH 38/40] ci: pr_metadata_check: run the script in unbuffered mode Makes it easier to debug since there's stuff handling race conditions now. Signed-off-by: Fabio Baltieri --- .github/workflows/pr_metadata_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_metadata_check.yml b/.github/workflows/pr_metadata_check.yml index 412903c2a0383..3e862321e9691 100644 --- a/.github/workflows/pr_metadata_check.yml +++ b/.github/workflows/pr_metadata_check.yml @@ -36,4 +36,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - ./scripts/ci/do_not_merge.py -p "${{ github.event.pull_request.number }}" + python -u scripts/ci/do_not_merge.py -p "${{ github.event.pull_request.number }}" From d5ee43a1cb9341837c80d98e653f579fe95f57d4 Mon Sep 17 00:00:00 2001 From: Nazar Palamar Date: Sat, 24 May 2025 10:23:40 +0300 Subject: [PATCH 39/40] drivers: wifi: AIROC: Added missed whd_bus_spi_protocol - add whd_bus_spi_protocol Signed-off-by: Nazar Palamar --- modules/hal_infineon/wifi-host-driver/CMakeLists.txt | 3 ++- west.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/hal_infineon/wifi-host-driver/CMakeLists.txt b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt index 1004f8535cce6..46db1319b8690 100644 --- a/modules/hal_infineon/wifi-host-driver/CMakeLists.txt +++ b/modules/hal_infineon/wifi-host-driver/CMakeLists.txt @@ -59,7 +59,8 @@ zephyr_library_sources(${hal_wifi_dir}/WHD/${whd_wifi_ver}/src/whd_wifi_p2p.c) # src/bus_protocols zephyr_library_sources(${hal_wifi_dir}/WHD/${whd_wifi_ver}/src/bus_protocols/whd_bus.c) zephyr_library_sources(${hal_wifi_dir}/WHD/${whd_wifi_ver}/src/bus_protocols/whd_bus_common.c) -zephyr_library_sources(${hal_wifi_dir}/WHD/${whd_wifi_ver}/src/bus_protocols/whd_bus_sdio_protocol.c) +zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SDIO ${hal_wifi_dir}/WHD/${whd_wifi_ver}/src/bus_protocols/whd_bus_sdio_protocol.c) +zephyr_library_sources_ifdef(CONFIG_AIROC_WIFI_BUS_SPI ${hal_wifi_dir}/WHD/${whd_wifi_ver}/src/bus_protocols/whd_bus_spi_protocol.c) # resources/resource_imp zephyr_library_sources(${hal_wifi_dir}/WHD/${whd_wifi_ver}/resources/resource_imp/whd_resources.c) diff --git a/west.yml b/west.yml index 3dd26629dd790..a6fb40716cea2 100644 --- a/west.yml +++ b/west.yml @@ -185,7 +185,7 @@ manifest: groups: - hal - name: hal_infineon - revision: 0fe4f3aee9c8f7002996a94d91299b2c28d6a8fa + revision: 1030915af885cffc8cedc49a62291dd279a9e81e path: modules/hal/infineon groups: - hal From 62bb93a0a69a7e4b1fd649536a8575f572cbc301 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20St=C4=99pnicki?= Date: Thu, 26 Jun 2025 12:43:55 +0200 Subject: [PATCH 40/40] drivers: clock control: ironside dvfs hsfll MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extended clock control driver to support new DVFS service from IronSide secure domain. Added new compatible nrf-iron-hsfll-local which can be used to enable new DVFS service support in local domain. Signed-off-by: Łukasz Stępnicki --- drivers/clock_control/CMakeLists.txt | 1 + drivers/clock_control/Kconfig.nrf | 20 ++ .../clock_control_nrf_iron_hsfll_local.c | 244 ++++++++++++++++++ .../clock/nordic,nrf-iron-hsfll-local.yaml | 59 +++++ dts/vendor/nordic/nrf54h20.dtsi | 2 +- 5 files changed, 325 insertions(+), 1 deletion(-) create mode 100644 drivers/clock_control/clock_control_nrf_iron_hsfll_local.c create mode 100644 dts/bindings/clock/nordic,nrf-iron-hsfll-local.yaml diff --git a/drivers/clock_control/CMakeLists.txt b/drivers/clock_control/CMakeLists.txt index 18b6025df6c7c..8c04aa03b3ebe 100644 --- a/drivers/clock_control/CMakeLists.txt +++ b/drivers/clock_control/CMakeLists.txt @@ -53,6 +53,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF2_COMMON clock_cont zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_FLL16M clock_control_nrf_fll16m.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF54H_HFXO clock_control_nrf54h_hfxo.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_HSFLL_LOCAL clock_control_nrf_hsfll_local.c) +zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL clock_control_nrf_iron_hsfll_local.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_LFCLK clock_control_nrf_lfclk.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NRF_AUXPLL clock_control_nrf_auxpll.c) zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_BOUFFALOLAB_BL60X clock_control_bl60x.c) diff --git a/drivers/clock_control/Kconfig.nrf b/drivers/clock_control/Kconfig.nrf index 76ff68bff4a66..a051ebd62b021 100644 --- a/drivers/clock_control/Kconfig.nrf +++ b/drivers/clock_control/Kconfig.nrf @@ -287,6 +287,26 @@ config CLOCK_CONTROL_NRF_HSFLL_LOCAL_NRFS_DVFS_TIMEOUT_MS endif # CLOCK_CONTROL_NRF_HSFLL_LOCAL +config CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL + bool "NRF IronSide HSFLL LOCAL driver support" + depends on DT_HAS_NORDIC_NRF_IRON_HSFLL_LOCAL_ENABLED + select NRF_IRONSIDE_DVFS_SERVICE + select CLOCK_CONTROL_NRF2_COMMON + default y + +if CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL + +config CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL_REQ_LOW_FREQ + bool "Local domain scale down after init" + help + Request the lowest operating point after DVFS initialization. + +config CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL_DVFS_TIMEOUT_MS + int "Timeout waiting for dvfs request to complete" + default 2000 + +endif # CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL + config CLOCK_CONTROL_NRF_LFCLK bool "NRF LFCLK driver support" depends on DT_HAS_NORDIC_NRF_LFCLK_ENABLED diff --git a/drivers/clock_control/clock_control_nrf_iron_hsfll_local.c b/drivers/clock_control/clock_control_nrf_iron_hsfll_local.c new file mode 100644 index 0000000000000..78bec1d839e01 --- /dev/null +++ b/drivers/clock_control/clock_control_nrf_iron_hsfll_local.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_nrf_iron_hsfll_local + +#include "clock_control_nrf2_common.h" +#include +#include + +#include +LOG_MODULE_DECLARE(clock_control_nrf2, CONFIG_CLOCK_CONTROL_LOG_LEVEL); + +BUILD_ASSERT(DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT) == 1, "multiple instances not supported"); + +#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +#include + +#define HSFLL_FREQ_LOW MHZ(64) +#define HSFLL_FREQ_MEDLOW MHZ(128) +#define HSFLL_FREQ_HIGH MHZ(320) + +#define IRONSIDE_DVFS_TIMEOUT K_MSEC(CONFIG_CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL_DVFS_TIMEOUT_MS) + +/* Clock options sorted from lowest to highest frequency */ +static const struct clock_options { + uint32_t frequency; + enum ironside_dvfs_oppoint setting; +} clock_options[] = { + { + .frequency = HSFLL_FREQ_LOW, + .setting = IRONSIDE_DVFS_OPP_LOW, + }, + { + .frequency = HSFLL_FREQ_MEDLOW, + .setting = IRONSIDE_DVFS_OPP_MEDLOW, + }, + { + .frequency = HSFLL_FREQ_HIGH, + .setting = IRONSIDE_DVFS_OPP_HIGH, + }, +}; + +struct hsfll_dev_data { + STRUCT_CLOCK_CONFIG(hsfll, ARRAY_SIZE(clock_options)) clk_cfg; + struct k_timer timer; +}; + +static void hsfll_update_timeout_handler(struct k_timer *timer) +{ + struct hsfll_dev_data *dev_data = CONTAINER_OF(timer, struct hsfll_dev_data, timer); + + clock_config_update_end(&dev_data->clk_cfg, -ETIMEDOUT); +} + +static void hsfll_work_handler(struct k_work *work) +{ + struct hsfll_dev_data *dev_data = CONTAINER_OF(work, struct hsfll_dev_data, clk_cfg.work); + enum ironside_dvfs_oppoint required_setting; + uint8_t to_activate_idx; + int rc; + + to_activate_idx = clock_config_update_begin(work); + required_setting = clock_options[to_activate_idx].setting; + + k_timer_start(&dev_data->timer, IRONSIDE_DVFS_TIMEOUT, K_NO_WAIT); + + /* Request the DVFS service to change the OPP point. */ + rc = ironside_dvfs_change_oppoint(required_setting); + k_timer_stop(&dev_data->timer); + clock_config_update_end(&dev_data->clk_cfg, rc); +} + +static int hsfll_resolve_spec_to_idx(const struct nrf_clock_spec *req_spec) +{ + uint32_t req_frequency; + + if (req_spec->accuracy || req_spec->precision) { + LOG_ERR("invalid specification of accuracy or precision"); + return -EINVAL; + } + + req_frequency = req_spec->frequency == NRF_CLOCK_CONTROL_FREQUENCY_MAX + ? HSFLL_FREQ_HIGH + : req_spec->frequency; + + for (int i = 0; i < ARRAY_SIZE(clock_options); ++i) { + if (req_frequency > clock_options[i].frequency) { + continue; + } + + return i; + } + + LOG_ERR("invalid frequency"); + return -EINVAL; +} + +static void hsfll_get_spec_by_idx(uint8_t idx, struct nrf_clock_spec *spec) +{ + spec->frequency = clock_options[idx].frequency; + spec->accuracy = 0; + spec->precision = 0; +} + +static struct onoff_manager *hsfll_get_mgr_by_idx(const struct device *dev, uint8_t idx) +{ + struct hsfll_dev_data *dev_data = dev->data; + + return &dev_data->clk_cfg.onoff[idx].mgr; +} + +static struct onoff_manager *hsfll_find_mgr_by_spec(const struct device *dev, + const struct nrf_clock_spec *spec) +{ + int idx; + + if (!spec) { + return hsfll_get_mgr_by_idx(dev, 0); + } + + idx = hsfll_resolve_spec_to_idx(spec); + return idx < 0 ? NULL : hsfll_get_mgr_by_idx(dev, idx); +} +#endif /* CONFIG_NRF_IRONSIDE_DVFS_SERVICE */ + +static int api_request_hsfll(const struct device *dev, const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ +#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE + struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec); + + if (mgr) { + return clock_config_request(mgr, cli); + } + + return -EINVAL; +#else + return -ENOTSUP; +#endif +} + +static int api_release_hsfll(const struct device *dev, const struct nrf_clock_spec *spec) +{ +#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE + struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec); + + if (mgr) { + return onoff_release(mgr); + } + + return -EINVAL; +#else + return -ENOTSUP; +#endif +} + +static int api_cancel_or_release_hsfll(const struct device *dev, const struct nrf_clock_spec *spec, + struct onoff_client *cli) +{ +#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE + struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec); + + if (mgr) { + return onoff_cancel_or_release(mgr, cli); + } + + return -EINVAL; +#else + return -ENOTSUP; +#endif +} + +static int api_resolve_hsfll(const struct device *dev, const struct nrf_clock_spec *req_spec, + struct nrf_clock_spec *res_spec) +{ +#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE + int idx; + + idx = hsfll_resolve_spec_to_idx(req_spec); + if (idx < 0) { + return -EINVAL; + } + + hsfll_get_spec_by_idx(idx, res_spec); + return 0; +#else + return -ENOTSUP; +#endif +} + +static int hsfll_init(const struct device *dev) +{ +#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE + struct hsfll_dev_data *dev_data = dev->data; + int rc; + + rc = clock_config_init(&dev_data->clk_cfg, ARRAY_SIZE(dev_data->clk_cfg.onoff), + hsfll_work_handler); + if (rc < 0) { + return rc; + } + + k_timer_init(&dev_data->timer, hsfll_update_timeout_handler, NULL); + +#endif + + return 0; +} + +static DEVICE_API(nrf_clock_control, hsfll_drv_api) = { + .std_api = { + .on = api_nosys_on_off, + .off = api_nosys_on_off, + }, + .request = api_request_hsfll, + .release = api_release_hsfll, + .cancel_or_release = api_cancel_or_release_hsfll, + .resolve = api_resolve_hsfll, +}; + +#ifdef CONFIG_NRF_IRONSIDE_DVFS_SERVICE +static struct hsfll_dev_data hsfll_data; +#endif + +#ifdef CONFIG_CLOCK_CONTROL_NRF_IRON_HSFLL_LOCAL_REQ_LOW_FREQ +static int dvfs_low_init(void) +{ + static const k_timeout_t timeout = IRONSIDE_DVFS_TIMEOUT; + static const struct device *hsfll_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_NODELABEL(cpu))); + static const struct nrf_clock_spec clk_spec = {.frequency = HSFLL_FREQ_LOW}; + + return nrf_clock_control_request_sync(hsfll_dev, &clk_spec, timeout); +} + +SYS_INIT(dvfs_low_init, APPLICATION, 0); +#endif + +DEVICE_DT_INST_DEFINE(0, hsfll_init, NULL, + COND_CODE_1(CONFIG_NRF_IRONSIDE_DVFS_SERVICE, + (&hsfll_data), + (NULL)), NULL, PRE_KERNEL_1, + CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &hsfll_drv_api); diff --git a/dts/bindings/clock/nordic,nrf-iron-hsfll-local.yaml b/dts/bindings/clock/nordic,nrf-iron-hsfll-local.yaml new file mode 100644 index 0000000000000..65769fb107f72 --- /dev/null +++ b/dts/bindings/clock/nordic,nrf-iron-hsfll-local.yaml @@ -0,0 +1,59 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + Nordic nRF local HSFLL with IronSide DVFS support + + The local HSFLL mixed-mode IP generates several clock frequencies in the range + from 64 MHz to 400 MHz (in steps of 16 MHz). + + Usage example: + + hsfll: clock@deadbeef { + compatible = "nordic,nrf-hsfll-local"; + reg = <0xdeadbeef 0x1000>; + clocks = <&fll16m>; + clock-frequency = ; + nordic,ficrs = <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_VSUP>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_COARSE_0>, + <&ficr NRF_FICR_TRIM_APPLICATION_HSFLL_TRIM_FINE_0>; + nordic,ficr-names = "vsup", "coarse", "fine"; + }; + + Required FICR entries are for VSUP, COARSE and FINE trim values. + +compatible: "nordic,nrf-iron-hsfll-local" + +include: [base.yaml, fixed-clock.yaml, nordic-nrf-ficr-client.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + clock-frequency: + enum: + - 64000000 + - 80000000 + - 96000000 + - 112000000 + - 128000000 + - 144000000 + - 160000000 + - 176000000 + - 192000000 + - 208000000 + - 224000000 + - 240000000 + - 256000000 + - 272000000 + - 288000000 + - 304000000 + - 320000000 + - 336000000 + - 352000000 + - 368000000 + - 384000000 + - 400000000 diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 21b8056ff040f..2c26c70aa1e67 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -268,7 +268,7 @@ ranges = <0x0 0x52000000 0x1000000>; cpuapp_hsfll: clock@d000 { - compatible = "nordic,nrf-hsfll-local"; + compatible = "nordic,nrf-iron-hsfll-local"; #clock-cells = <0>; reg = <0xd000 0x1000>; clocks = <&fll16m>;