diff --git a/boot/zephyr/CMakeLists.txt b/boot/zephyr/CMakeLists.txt index cfc9a243a..ce55effbb 100644 --- a/boot/zephyr/CMakeLists.txt +++ b/boot/zephyr/CMakeLists.txt @@ -491,6 +491,10 @@ zephyr_library_sources( ) endif() +if(CONFIG_SOC_NRF54H20_PM_S2RAM_OVERRIDE) + zephyr_library_sources(${BOOT_DIR}/zephyr/nrf54h20_custom_s2ram.c) +endif() + if(CONFIG_MCUBOOT_BOOT_BANNER) # Replace Zephyr's boot banner with the MCUboot one zephyr_sources(kernel/banner.c) diff --git a/boot/zephyr/nrf54h20_custom_s2ram.c b/boot/zephyr/nrf54h20_custom_s2ram.c new file mode 100644 index 000000000..7b70e22fe --- /dev/null +++ b/boot/zephyr/nrf54h20_custom_s2ram.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "pm_s2ram.h" +#include "power.h" + +#include +#include + +#include "bootutil/fault_injection_hardening.h" + +#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; +#else +#error "mcuboot resume support section not defined in dts" +#endif + +#define FIXED_PARTITION_ADDR(node_label) \ + (DT_REG_ADDR(DT_NODELABEL(node_label)) + \ + COND_CODE_0(DT_FIXED_PARTITION_EXISTS(DT_NODELABEL(node_label)), (0), \ + (DT_REG_ADDR(DT_GPARENT(DT_NODELABEL(node_label)))))) + + +int soc_s2ram_suspend(pm_s2ram_system_off_fn_t system_off) +{ + (void)(system_off); + return -1; +} + +void pm_s2ram_mark_set(void) +{ + /* empty */ +} + +struct arm_vector_table { + uint32_t msp; + uint32_t reset; +}; + +/* This could be read from slot's image_header.ih_hdr_size, but immediate value + * is much faster to reach + */ +#define APP_EXE_START_OFFSET 0x800 /* nRF54H20 */ + +bool pm_s2ram_mark_check_and_clear(void) +{ + uint32_t reset_reason = nrf_resetinfo_resetreas_local_get(NRF_RESETINFO); + + if (reset_reason != NRF_RESETINFO_RESETREAS_LOCAL_UNRETAINED_MASK) { + /* Normal boot */ + return false; + } + + /* S2RAM resume expected, do doublecheck */ + if (mcuboot_resume.magic == MCUBOOT_S2RAM_RESUME_MAGIC) { + /* clear magic to avoid accidental reuse */ + mcuboot_resume.magic = 0; + } else { + /* magic not valid, normal boot */ + goto resume_failed; + } + + /* s2ram boot */ + struct arm_vector_table *vt; + vt = (struct arm_vector_table *) + (FIXED_PARTITION_ADDR(slot0_partition) + APP_EXE_START_OFFSET); + + /* Jump to application */ + __asm__ volatile ( + /* vt->reset -> r0 */ + " mov r0, %0\n" + /* vt->msp -> r1 */ + " mov r1, %1\n" + /* set stack pointer */ + " msr msp, r1\n" + /* jump to reset vector of an app */ + " bx r0\n" + : + : "r" (vt->reset), "r" (vt->msp) + : "r0", "r1", "memory" + ); + +resume_failed: + FIH_PANIC; + + return true; +} diff --git a/boot/zephyr/socs/nrf54h20_cpuapp.conf b/boot/zephyr/socs/nrf54h20_cpuapp.conf new file mode 100644 index 000000000..09ccb19b2 --- /dev/null +++ b/boot/zephyr/socs/nrf54h20_cpuapp.conf @@ -0,0 +1,13 @@ +# Copyright (c) 2025 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Configuration which is needed for supporting resume the application execution +# after suspend to RAM (S2RAM) requested by the application. +# MCUboot does not support S2RAM itself, but serves as an immediate actor while waking up +# from suspension. +CONFIG_PM=y +CONFIG_PM_S2RAM=y +CONFIG_PM_S2RAM_CUSTOM_MARKING=y +CONFIG_SOC_NRF54H20_PM_S2RAM_OVERRIDE=y