From ee3b89eeed412bf430a1dd111503e569f40d9a65 Mon Sep 17 00:00:00 2001 From: Adam Kondraciuk Date: Tue, 7 Oct 2025 11:16:18 +0200 Subject: [PATCH 1/8] Revert "[nrf noup] soc/nordic/nrf54h20/pm_s2ram: extend mcuboot_resume_s" This reverts commit bbfecc3539562c83c6116e7adaa7501c6d1d8d51. Signed-off-by: Adam Kondraciuk --- .../nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 12 ++++++------ soc/nordic/nrf54h/pm_s2ram.h | 1 - 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index ac69d47a0c5..914b434d40e 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -345,23 +345,23 @@ zephyr_udc0: &usbhs { /* Trim this RAM block for making room on all run-time common S2RAM cpu context. */ &cpuapp_ram0 { - reg = <0x22000000 (DT_SIZE_K(32) - 56)>; - ranges = <0x0 0x22000000 (0x8000 - 0x38)>; + reg = <0x22000000 (DT_SIZE_K(32) - 52)>; + ranges = <0x0 0x22000000 (0x8000 - 0x34)>; }; / { soc { /* temporary stack for S2RAM resume logic */ - pm_s2ram_stack: cpuapp_s2ram_stack@22007fc8 { + pm_s2ram_stack: cpuapp_s2ram_stack@22007fcc { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fc8 16>; + reg = <0x22007fcc 16>; zephyr,memory-region = "pm_s2ram_stack"; }; /* run-time common mcuboot S2RAM support section */ - mcuboot_s2ram: cpuapp_s2ram@22007fd8 { + mcuboot_s2ram: cpuapp_s2ram@22007fdc { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fd8 8>; + reg = <0x22007fdc 4>; zephyr,memory-region = "mcuboot_s2ram_context"; }; diff --git a/soc/nordic/nrf54h/pm_s2ram.h b/soc/nordic/nrf54h/pm_s2ram.h index 01c098ea431..0906010cbe0 100644 --- a/soc/nordic/nrf54h/pm_s2ram.h +++ b/soc/nordic/nrf54h/pm_s2ram.h @@ -14,7 +14,6 @@ struct mcuboot_resume_s { uint32_t magic; /* magic value to identify valid structure */ - uint32_t slot_info; }; /** From e5e482876f943b1124deff8c6ad2a0a25d44e731 Mon Sep 17 00:00:00 2001 From: Adam Kondraciuk Date: Tue, 30 Sep 2025 16:09:18 +0200 Subject: [PATCH 2/8] Revert "[nrf noup] soc/nordic/nrf54h/pm_s2ram: S2RAM resume hardening" This reverts commit a41a6314e19952459f7185217ee26c556fd334bd. Signed-off-by: Adam Kondraciuk --- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 15 ++++----------- soc/nordic/nrf54h/pm_s2ram.c | 14 -------------- soc/nordic/nrf54h/pm_s2ram.h | 6 ------ 3 files changed, 4 insertions(+), 31 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 914b434d40e..8bcde5c55de 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -345,26 +345,19 @@ zephyr_udc0: &usbhs { /* Trim this RAM block for making room on all run-time common S2RAM cpu context. */ &cpuapp_ram0 { - reg = <0x22000000 (DT_SIZE_K(32) - 52)>; - ranges = <0x0 0x22000000 (0x8000 - 0x34)>; + reg = <0x22000000 (DT_SIZE_K(32) - 48)>; + ranges = <0x0 0x22000000 (0x8000 - 0x30)>; }; / { soc { /* temporary stack for S2RAM resume logic */ - pm_s2ram_stack: cpuapp_s2ram_stack@22007fcc { + pm_s2ram_stack: cpuapp_s2ram_stack@22007fd0 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fcc 16>; + reg = <0x22007fd0 16>; zephyr,memory-region = "pm_s2ram_stack"; }; - /* run-time common mcuboot S2RAM support section */ - mcuboot_s2ram: cpuapp_s2ram@22007fdc { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fdc 4>; - zephyr,memory-region = "mcuboot_s2ram_context"; - }; - /* run-time common S2RAM cpu context RAM */ pm_s2ram: cpuapp_s2ram@22007fe0 { compatible = "zephyr,memory-region", "mmio-sram"; diff --git a/soc/nordic/nrf54h/pm_s2ram.c b/soc/nordic/nrf54h/pm_s2ram.c index 6916e488472..221293c5b82 100644 --- a/soc/nordic/nrf54h/pm_s2ram.c +++ b/soc/nordic/nrf54h/pm_s2ram.c @@ -219,24 +219,10 @@ static void fpu_restore(_fpu_context_t *backup) #endif /* !defined(CONFIG_FPU_SHARING) */ #endif /* defined(CONFIG_FPU) */ -#if DT_NODE_EXISTS(DT_NODELABEL(mcuboot_s2ram)) &&\ - DT_NODE_HAS_COMPAT(DT_NODELABEL(mcuboot_s2ram), zephyr_memory_region) -/* Linker section name is given by `zephyr,memory-region` property of - * `zephyr,memory-region` compatible DT node with nodelabel `mcuboot_s2ram`. - */ -__attribute__((section(DT_PROP(DT_NODELABEL(mcuboot_s2ram), zephyr_memory_region)))) -volatile struct mcuboot_resume_s _mcuboot_resume; - -#define SET_MCUBOOT_RESUME_MAGIC() _mcuboot_resume.magic = MCUBOOT_S2RAM_RESUME_MAGIC -#else -#define SET_MCUBOOT_RESUME_MAGIC() -#endif - int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off) { int ret; - SET_MCUBOOT_RESUME_MAGIC(); scb_save(&backup_data.scb_context); #if defined(CONFIG_FPU) #if !defined(CONFIG_FPU_SHARING) diff --git a/soc/nordic/nrf54h/pm_s2ram.h b/soc/nordic/nrf54h/pm_s2ram.h index 0906010cbe0..565afad6ca1 100644 --- a/soc/nordic/nrf54h/pm_s2ram.h +++ b/soc/nordic/nrf54h/pm_s2ram.h @@ -10,12 +10,6 @@ #ifndef _ZEPHYR_SOC_ARM_NORDIC_NRF_PM_S2RAM_H_ #define _ZEPHYR_SOC_ARM_NORDIC_NRF_PM_S2RAM_H_ -#define MCUBOOT_S2RAM_RESUME_MAGIC 0x75832419 - -struct mcuboot_resume_s { - uint32_t magic; /* magic value to identify valid structure */ -}; - /** * @brief Save CPU state on suspend * From 1ec241b8fc3d7c5e8f1495045e5e881d0185f430 Mon Sep 17 00:00:00 2001 From: Adam Kondraciuk Date: Tue, 30 Sep 2025 16:09:33 +0200 Subject: [PATCH 3/8] Revert "[nrf fromlist] boards: Define pm_s2ram_stack for nRF54H20" This reverts commit cdc11bd5ef41488c5904d3ca147cd0907ce483e0. Signed-off-by: Adam Kondraciuk --- .../nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 8bcde5c55de..1c6d46a60ad 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -345,19 +345,12 @@ zephyr_udc0: &usbhs { /* Trim this RAM block for making room on all run-time common S2RAM cpu context. */ &cpuapp_ram0 { - reg = <0x22000000 (DT_SIZE_K(32) - 48)>; - ranges = <0x0 0x22000000 (0x8000 - 0x30)>; + reg = <0x22000000 (DT_SIZE_K(32) - 32)>; + ranges = <0x0 0x22000000 (0x8000 - 0x20)>; }; / { soc { - /* temporary stack for S2RAM resume logic */ - pm_s2ram_stack: cpuapp_s2ram_stack@22007fd0 { - compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fd0 16>; - zephyr,memory-region = "pm_s2ram_stack"; - }; - /* run-time common S2RAM cpu context RAM */ pm_s2ram: cpuapp_s2ram@22007fe0 { compatible = "zephyr,memory-region", "mmio-sram"; From 3e6c33f51dbed7e3217776926fd23c5b6c09dc4a Mon Sep 17 00:00:00 2001 From: Adam Kondraciuk Date: Wed, 16 Jul 2025 09:37:23 +0200 Subject: [PATCH 4/8] [nrf fromtree] soc: nordic: nrf54h: Implement idle with cache retained state Add new idle state with cache retention enabled. Signed-off-by: Adam Kondraciuk (cherry picked from commit 6f7a1834d52bc6a860d92a2777692ea5de582f50) --- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 13 +++-- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts | 17 +++++++ dts/vendor/nordic/nrf54h20.dtsi | 12 +++-- soc/nordic/nrf54h/CMakeLists.txt | 5 ++ .../nrf54h/Kconfig.defconfig.nrf54h20_cpuapp | 3 ++ .../nrf54h/Kconfig.defconfig.nrf54h20_cpurad | 3 ++ soc/nordic/nrf54h/power.c | 50 +++++++++++++++---- soc/nordic/nrf54h/soc.c | 42 +++++++++------- soc/nordic/nrf54h/soc.h | 7 +++ 9 files changed, 116 insertions(+), 36 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 1c6d46a60ad..83c539778ba 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -343,14 +343,21 @@ zephyr_udc0: &usbhs { status = "okay"; }; -/* Trim this RAM block for making room on all run-time common S2RAM cpu context. */ +/* Trim this RAM block for power management related features. */ &cpuapp_ram0 { - reg = <0x22000000 (DT_SIZE_K(32) - 32)>; - ranges = <0x0 0x22000000 (0x8000 - 0x20)>; + reg = <0x22000000 (DT_SIZE_K(32) - 256)>; + ranges = <0x0 0x22000000 (0x8000 - 0x100)>; }; / { soc { + /* cache control functions - must be executed from local SRAM */ + pm_ramfunc: cpuapp_s2ram@22007f00 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x22007f00 192>; + zephyr,memory-region = "PMLocalRamfunc"; + }; + /* run-time common S2RAM cpu context RAM */ pm_s2ram: cpuapp_s2ram@22007fe0 { compatible = "zephyr,memory-region", "mmio-sram"; diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts index 7f0da1291e8..a8c588268b3 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpurad.dts @@ -123,3 +123,20 @@ slot1_partition: &cpurad_slot1_partition { zephyr_udc0: &usbhs { status = "disabled"; }; + +/* Trim this RAM block for power management related features. */ +&cpurad_ram0 { + reg = <0x23000000 (DT_SIZE_K(192) - 192)>; + ranges = <0x0 0x23000000 (0x30000 - 0xC0)>; +}; + +/ { + soc { + /* cache control functions - must be executed from RAM */ + pm_ramfunc: cpurad_s2ram@2302ff40 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x2302ff80 192>; + zephyr,memory-region = "PMLocalRamfunc"; + }; + }; +}; diff --git a/dts/vendor/nordic/nrf54h20.dtsi b/dts/vendor/nordic/nrf54h20.dtsi index 4644cb383ec..56b807fafd4 100644 --- a/dts/vendor/nordic/nrf54h20.dtsi +++ b/dts/vendor/nordic/nrf54h20.dtsi @@ -31,7 +31,7 @@ device_type = "cpu"; clocks = <&cpuapp_hsfll>; clock-frequency = ; - cpu-power-states = <&idle_cache_disabled &s2ram>; + cpu-power-states = <&idle_cache_retained &idle_cache_disabled &s2ram>; }; cpurad: cpu@3 { @@ -40,7 +40,7 @@ device_type = "cpu"; clocks = <&cpurad_hsfll>; clock-frequency = ; - cpu-power-states = <&idle_cache_disabled>; + cpu-power-states = <&idle_cache_retained &idle_cache_disabled>; }; cpuppr: cpu@d { @@ -130,7 +130,13 @@ power-states { // substate-id = <0>; is reserved for "idle", cache powered on - // substate-id = <1>; is reserved for "idle-cache-retained" + idle_cache_retained: idle_cache_retained { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + substate-id = <1>; + min-residency-us = <700>; + exit-latency-us = <5>; + }; idle_cache_disabled: idle_cache_disabled { compatible = "zephyr,power-state"; power-state-name = "suspend-to-idle"; diff --git a/soc/nordic/nrf54h/CMakeLists.txt b/soc/nordic/nrf54h/CMakeLists.txt index fed4307214d..25e4796a416 100644 --- a/soc/nordic/nrf54h/CMakeLists.txt +++ b/soc/nordic/nrf54h/CMakeLists.txt @@ -5,6 +5,11 @@ if(CONFIG_ARM) zephyr_library_sources(soc.c) if(CONFIG_PM OR CONFIG_POWEROFF) zephyr_library_sources(power.c) + zephyr_code_relocate( + FILES power.c + FILTER ".*\\.cache_retain_and_sleep" + LOCATION PMLocalRamfunc_TEXT + ) endif() endif() diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp index 0cdc2276040..f2e0343d635 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -14,4 +14,7 @@ config SHELL_BACKEND_SERIAL config POWER_DOMAIN default y +config CODE_DATA_RELOCATION + default y if PM || POWEROFF + endif # SOC_NRF54H20_CPUAPP diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad index b3f5216c8f9..31687c2a544 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpurad @@ -14,4 +14,7 @@ config PM config POWER_DOMAIN default y +config CODE_DATA_RELOCATION + default y if PM || POWEROFF + endif # SOC_NRF54H20_CPURAD diff --git a/soc/nordic/nrf54h/power.c b/soc/nordic/nrf54h/power.c index e1263be0d0e..3a23a605060 100644 --- a/soc/nordic/nrf54h/power.c +++ b/soc/nordic/nrf54h/power.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -87,18 +88,43 @@ void nrf_poweroff(void) CODE_UNREACHABLE; } -static void s2idle_enter(uint8_t substate_id) +static __attribute__((__used__, noinline)) void cache_retain_and_sleep(void) { + nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_SAVE); + nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_SAVE); + while (nrf_cache_busy_check(NRF_DCACHE) || + nrf_cache_busy_check(NRF_ICACHE)) { + + } + + __set_BASEPRI(0); + __ISB(); + __DSB(); + __WFI(); + + nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_RESTORE); + nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_RESTORE); + while (nrf_cache_busy_check(NRF_DCACHE) || + nrf_cache_busy_check(NRF_ICACHE)) { + + } +} + +void s2idle_enter(uint8_t substate_id) +{ +#if !defined(CONFIG_SOC_NRF54H20_CPURAD) + soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_MAIN); +#endif switch (substate_id) { case 0: /* Substate for idle with cache powered on - not implemented yet. */ break; - case 1: /* Substate for idle with cache retained - not implemented yet. */ - break; + case 1: /* Substate for idle with cache retained. */ + soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0); + nrf_soc_memconf_retain_set(true); + cache_retain_and_sleep(); + return; case 2: /* Substate for idle with cache disabled. */ -#if !defined(CONFIG_SOC_NRF54H20_CPURAD) - soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_MAIN); -#endif common_suspend(); break; default: /* Unknown substate. */ @@ -117,17 +143,19 @@ static void s2idle_exit(uint8_t substate_id) case 0: /* Substate for idle with cache powered on - not implemented yet. */ break; - case 1: /* Substate for idle with cache retained - not implemented yet. */ + case 1: /* Substate for idle with cache retained. */ + nrf_soc_memconf_retain_set(false); break; case 2: /* Substate for idle with cache disabled. */ nrf_power_up_cache(); - common_resume(); -#if !defined(CONFIG_SOC_NRF54H20_CPURAD) - soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN); -#endif + break; default: /* Unknown substate. */ return; } + common_resume(); +#if !defined(CONFIG_SOC_NRF54H20_CPURAD) + soc_lrcconf_poweron_release(&soc_node, NRF_LRCCONF_POWER_MAIN); +#endif } #if defined(CONFIG_PM_S2RAM) diff --git a/soc/nordic/nrf54h/soc.c b/soc/nordic/nrf54h/soc.c index c996bc93e1b..6692425f674 100644 --- a/soc/nordic/nrf54h/soc.c +++ b/soc/nordic/nrf54h/soc.c @@ -61,6 +61,26 @@ sys_snode_t soc_node; ADDRESS_DOMAIN_Msk | \ ADDRESS_BUS_Msk))) +void nrf_soc_memconf_retain_set(bool enable) +{ + uint32_t ret_mask = BIT(RAMBLOCK_RET_BIT_ICACHE) | BIT(RAMBLOCK_RET_BIT_DCACHE); + + nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, ret_mask, enable); + nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, ret_mask, enable); + +#if defined(RAMBLOCK_RET2_MASK) + ret_mask = 0; +#if defined(RAMBLOCK_RET2_BIT_ICACHE) + ret_mask |= BIT(RAMBLOCK_RET2_BIT_ICACHE); +#endif +#if defined(RAMBLOCK_RET2_BIT_DCACHE) + ret_mask |= BIT(RAMBLOCK_RET2_BIT_DCACHE); +#endif + nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 0, ret_mask, enable); + nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 1, ret_mask, enable); +#endif /* defined(RAMBLOCK_RET2_MASK) */ +} + static void power_domain_init(void) { /* @@ -76,28 +96,12 @@ static void power_domain_init(void) soc_lrcconf_poweron_request(&soc_node, NRF_LRCCONF_POWER_DOMAIN_0); nrf_lrcconf_poweron_force_set(NRF_LRCCONF010, NRF_LRCCONF_POWER_MAIN, false); - - nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_BIT_ICACHE, false); - nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_BIT_DCACHE, false); - nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_BIT_ICACHE, false); - nrf_memconf_ramblock_ret_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_BIT_DCACHE, false); -#if defined(RAMBLOCK_RET2_BIT_ICACHE) - nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_BIT_ICACHE, false); - nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_BIT_ICACHE, false); -#endif -#if defined(RAMBLOCK_RET2_BIT_DCACHE) - nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_BIT_DCACHE, false); - nrf_memconf_ramblock_ret2_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_BIT_DCACHE, false); -#endif + nrf_soc_memconf_retain_set(false); nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET_MASK, true); nrf_memconf_ramblock_ret_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET_MASK, true); #if defined(RAMBLOCK_RET2_MASK) - /* - * TODO: Use nrf_memconf_ramblock_ret2_mask_enable_set() function - * when will be provided by HAL. - */ - NRF_MEMCONF->POWER[0].RET2 = RAMBLOCK_RET2_MASK; - NRF_MEMCONF->POWER[1].RET2 = RAMBLOCK_RET2_MASK; + nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 0, RAMBLOCK_RET2_MASK, true); + nrf_memconf_ramblock_ret2_mask_enable_set(NRF_MEMCONF, 1, RAMBLOCK_RET2_MASK, true); #endif } diff --git a/soc/nordic/nrf54h/soc.h b/soc/nordic/nrf54h/soc.h index 566c07a8c2c..69c22e52bd1 100644 --- a/soc/nordic/nrf54h/soc.h +++ b/soc/nordic/nrf54h/soc.h @@ -36,4 +36,11 @@ #define RAMBLOCK_RET2_BIT_DCACHE MEMCONF_POWER_RET2_MEM7_Pos #endif +/** + * @brief Enable or disable the retention for cache RAM blocks. + * + * @param enable True if the retention is to be enabled, false otherwise. + */ +void nrf_soc_memconf_retain_set(bool enable); + #endif /* SOC_ARM_NORDIC_NRF_NRF54H_SOC_H_ */ From c3b863dba5bedf594e150b9645fad6076388fff8 Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Tue, 16 Sep 2025 11:31:37 +0200 Subject: [PATCH 5/8] [nrf fromlist] boards: Define pm_s2ram_stack for nRF54H20 Add the definition of pm_s2ram_stack memory region for nRF54H20. Upstream PR #: 95914 Signed-off-by: Tomasz Chyrowicz (cherry picked from commit c2748343ba324b7b5b1acd5598494eb8ee5b4e9a) --- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 83c539778ba..731e0ae78fa 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -358,6 +358,13 @@ zephyr_udc0: &usbhs { zephyr,memory-region = "PMLocalRamfunc"; }; + /* temporary stack for S2RAM resume logic */ + pm_s2ram_stack: cpuapp_s2ram_stack@22007fd0 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x22007fd0 16>; + zephyr,memory-region = "pm_s2ram_stack"; + }; + /* run-time common S2RAM cpu context RAM */ pm_s2ram: cpuapp_s2ram@22007fe0 { compatible = "zephyr,memory-region", "mmio-sram"; From 4b02cccc271b372a6f664d015e2c0d1870646a1e Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Fri, 5 Sep 2025 18:11:52 +0200 Subject: [PATCH 6/8] [nrf noup] soc/nordic/nrf54h/pm_s2ram: S2RAM resume hardening Added support for hardening decision on resume from S2RAM by MCUboot bootloader. Application sets additional variable to MCUBOOT_S2RAM_RESUME_MAGIC which allows the bootloader to doublecheck. Signed-off-by: Andrzej Puzdrowski (cherry picked from commit d4bb1c6b9f1c941480a457b18ae36c9bdf49faa7) --- .../nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 13 ++++++++++--- soc/nordic/nrf54h/pm_s2ram.c | 14 ++++++++++++++ soc/nordic/nrf54h/pm_s2ram.h | 6 ++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index 731e0ae78fa..b6f14c53a61 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -359,14 +359,21 @@ zephyr_udc0: &usbhs { }; /* temporary stack for S2RAM resume logic */ - pm_s2ram_stack: cpuapp_s2ram_stack@22007fd0 { + pm_s2ram_stack: cpuapp_s2ram_stack@22007fcc { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fd0 16>; + reg = <0x22007fcc 16>; zephyr,memory-region = "pm_s2ram_stack"; }; + /* run-time common mcuboot S2RAM support section */ + mcuboot_s2ram: cpuapp_s2ram@22007fdc { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x22007fdc 4>; + zephyr,memory-region = "mcuboot_s2ram_context"; + }; + /* run-time common S2RAM cpu context RAM */ - pm_s2ram: cpuapp_s2ram@22007fe0 { + pm_s2ram: cpuapp_s2ram@22007fe0 { compatible = "zephyr,memory-region", "mmio-sram"; reg = <0x22007fe0 32>; zephyr,memory-region = "pm_s2ram_context"; diff --git a/soc/nordic/nrf54h/pm_s2ram.c b/soc/nordic/nrf54h/pm_s2ram.c index 221293c5b82..6916e488472 100644 --- a/soc/nordic/nrf54h/pm_s2ram.c +++ b/soc/nordic/nrf54h/pm_s2ram.c @@ -219,10 +219,24 @@ static void fpu_restore(_fpu_context_t *backup) #endif /* !defined(CONFIG_FPU_SHARING) */ #endif /* defined(CONFIG_FPU) */ +#if DT_NODE_EXISTS(DT_NODELABEL(mcuboot_s2ram)) &&\ + DT_NODE_HAS_COMPAT(DT_NODELABEL(mcuboot_s2ram), zephyr_memory_region) +/* Linker section name is given by `zephyr,memory-region` property of + * `zephyr,memory-region` compatible DT node with nodelabel `mcuboot_s2ram`. + */ +__attribute__((section(DT_PROP(DT_NODELABEL(mcuboot_s2ram), zephyr_memory_region)))) +volatile struct mcuboot_resume_s _mcuboot_resume; + +#define SET_MCUBOOT_RESUME_MAGIC() _mcuboot_resume.magic = MCUBOOT_S2RAM_RESUME_MAGIC +#else +#define SET_MCUBOOT_RESUME_MAGIC() +#endif + int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off) { int ret; + SET_MCUBOOT_RESUME_MAGIC(); scb_save(&backup_data.scb_context); #if defined(CONFIG_FPU) #if !defined(CONFIG_FPU_SHARING) diff --git a/soc/nordic/nrf54h/pm_s2ram.h b/soc/nordic/nrf54h/pm_s2ram.h index 565afad6ca1..0906010cbe0 100644 --- a/soc/nordic/nrf54h/pm_s2ram.h +++ b/soc/nordic/nrf54h/pm_s2ram.h @@ -10,6 +10,12 @@ #ifndef _ZEPHYR_SOC_ARM_NORDIC_NRF_PM_S2RAM_H_ #define _ZEPHYR_SOC_ARM_NORDIC_NRF_PM_S2RAM_H_ +#define MCUBOOT_S2RAM_RESUME_MAGIC 0x75832419 + +struct mcuboot_resume_s { + uint32_t magic; /* magic value to identify valid structure */ +}; + /** * @brief Save CPU state on suspend * From 222e16408e1b9c21a2ada34c83d7626aec410c33 Mon Sep 17 00:00:00 2001 From: Andrzej Puzdrowski Date: Tue, 30 Sep 2025 14:48:14 +0200 Subject: [PATCH 7/8] [nrf noup] soc/nordic/nrf54h20/pm_s2ram: extend mcuboot_resume_s nrf_squash! [nrf noup] soc/nordic/nf54h/pm_s2ram: S2RAM resume hardening Extended mcuboot_resume_s suture by slot_info field intended to be used by MCUboot for recognize proper boot slot in direct-xp mode. Signed-off-by: Andrzej Puzdrowski --- boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts | 8 ++++---- soc/nordic/nrf54h/pm_s2ram.h | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts index b6f14c53a61..9bf42dab7d5 100644 --- a/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts +++ b/boards/nordic/nrf54h20dk/nrf54h20dk_nrf54h20_cpuapp.dts @@ -359,16 +359,16 @@ zephyr_udc0: &usbhs { }; /* temporary stack for S2RAM resume logic */ - pm_s2ram_stack: cpuapp_s2ram_stack@22007fcc { + pm_s2ram_stack: cpuapp_s2ram_stack@22007fc8 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fcc 16>; + reg = <0x22007fc8 16>; zephyr,memory-region = "pm_s2ram_stack"; }; /* run-time common mcuboot S2RAM support section */ - mcuboot_s2ram: cpuapp_s2ram@22007fdc { + mcuboot_s2ram: cpuapp_s2ram@22007fd8 { compatible = "zephyr,memory-region", "mmio-sram"; - reg = <0x22007fdc 4>; + reg = <0x22007fd8 8>; zephyr,memory-region = "mcuboot_s2ram_context"; }; diff --git a/soc/nordic/nrf54h/pm_s2ram.h b/soc/nordic/nrf54h/pm_s2ram.h index 0906010cbe0..01c098ea431 100644 --- a/soc/nordic/nrf54h/pm_s2ram.h +++ b/soc/nordic/nrf54h/pm_s2ram.h @@ -14,6 +14,7 @@ struct mcuboot_resume_s { uint32_t magic; /* magic value to identify valid structure */ + uint32_t slot_info; }; /** From f759ee8ddab543eab3c4a6b9620881b31231657e Mon Sep 17 00:00:00 2001 From: Adam Kondraciuk Date: Wed, 1 Oct 2025 16:27:50 +0200 Subject: [PATCH 8/8] [nrf fromlist] soc: nordic: nrf54h: Disable code relocation for MCUBOOT MCUBOOT requires LTO to be enabled, while using code relocation forces switching it off. When `__ramfunc` is used, LTO can also be used. Then the `cache_retain_and_sleep` function will work correctly, but slightly slower. Upstream PR #: 97094 Signed-off-by: Adam Kondraciuk --- soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp | 2 +- soc/nordic/nrf54h/power.c | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp index f2e0343d635..674b5433c14 100644 --- a/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp +++ b/soc/nordic/nrf54h/Kconfig.defconfig.nrf54h20_cpuapp @@ -15,6 +15,6 @@ config POWER_DOMAIN default y config CODE_DATA_RELOCATION - default y if PM || POWEROFF + default y if (PM || POWEROFF) && !MCUBOOT endif # SOC_NRF54H20_CPUAPP diff --git a/soc/nordic/nrf54h/power.c b/soc/nordic/nrf54h/power.c index 3a23a605060..c72cb6e834e 100644 --- a/soc/nordic/nrf54h/power.c +++ b/soc/nordic/nrf54h/power.c @@ -88,7 +88,12 @@ void nrf_poweroff(void) CODE_UNREACHABLE; } -static __attribute__((__used__, noinline)) void cache_retain_and_sleep(void) +#if CONFIG_MCUBOOT +static __ramfunc +#else +static __attribute__((__used__, noinline)) +#endif +void cache_retain_and_sleep(void) { nrf_cache_task_trigger(NRF_DCACHE, NRF_CACHE_TASK_SAVE); nrf_cache_task_trigger(NRF_ICACHE, NRF_CACHE_TASK_SAVE);