Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions boot/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
97 changes: 97 additions & 0 deletions boot/zephyr/nrf54h20_custom_s2ram.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdbool.h>
#include <zephyr/arch/common/pm_s2ram.h>
#include <hal/nrf_resetinfo.h>
#include "pm_s2ram.h"
#include "power.h"

#include <zephyr/devicetree.h>
#include <zephyr/storage/flash_map.h>

#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 */
Comment on lines +50 to +53
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by how much? Why can't it just be read?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by the time needed to access word which encodes heder size of 0x800 in MRAM. No much, but always a dozen CPU cycles for reaching data which are expected to be a constant value. Rationale in sentence above.


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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't this need volatile to avoid the LTO issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no - content of pointed data is non-volatile during function execution.

vt = (struct arm_vector_table *)
(FIXED_PARTITION_ADDR(slot0_partition) + APP_EXE_START_OFFSET);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(non blocking) this will not work with direct-xip

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we know - direct-xip not supported.


/* 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;
}
13 changes: 13 additions & 0 deletions boot/zephyr/socs/nrf54h20_cpuapp.conf
Original file line number Diff line number Diff line change
@@ -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