Skip to content

Commit be93d43

Browse files
boot: zephyr: Add support for Cortex-R cleanup before final jump
Add code to cleanup the Cortex-R processor state to the reset configuration and disable + acknowledge all interrupts before entering the booted application. Signed-off-by: Mika Braunschweig <[email protected]>
1 parent 420a2f9 commit be93d43

File tree

6 files changed

+105
-7
lines changed

6 files changed

+105
-7
lines changed

boot/zephyr/CMakeLists.txt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -439,9 +439,17 @@ if(CONFIG_BOOT_ENCRYPTION_KEY_FILE AND NOT CONFIG_BOOT_ENCRYPTION_KEY_FILE STREQ
439439
endif()
440440

441441
if(CONFIG_MCUBOOT_CLEANUP_ARM_CORE)
442-
zephyr_library_sources(
443-
${BOOT_DIR}/zephyr/arm_cleanup.c
444-
)
442+
# ARM Cortex-M
443+
zephyr_library_sources_ifdef(
444+
CONFIG_CPU_CORTEX_M
445+
${BOOT_DIR}/zephyr/cleanup/arm_cortex_m.c
446+
)
447+
448+
# ARM Cortex-R
449+
zephyr_library_sources_ifdef(
450+
CONFIG_ARMV7_R
451+
${BOOT_DIR}/zephyr/cleanup/arm_cortex_r.c
452+
)
445453
endif()
446454

447455
if(CONFIG_MCUBOOT_BOOT_BANNER)

boot/zephyr/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ config BOOT_SIGNATURE_KEY_FILE
344344

345345
config MCUBOOT_CLEANUP_ARM_CORE
346346
bool "Perform core cleanup before chain-load the application"
347-
depends on CPU_CORTEX_M
347+
depends on CPU_CORTEX_M || ARMV7_R
348348
default y
349349
help
350350
This option instructs MCUboot to perform a clean-up of a set of

boot/zephyr/arm_cleanup.c renamed to boot/zephyr/cleanup/arm_cortex_m.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
#include <fsl_sysmpu.h>
1212
#endif
1313

14-
void cleanup_arm_nvic(void) {
14+
15+
void cleanup_arm_interrupts(void)
16+
{
1517
/* Allow any pending interrupts to be recognized */
1618
__ISB();
1719
__disable_irq();

boot/zephyr/cleanup/arm_cortex_r.c

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
* Copyright (c) 2025 Siemens Mobility GmbH
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
#include <stdint.h>
9+
#include <zephyr/irq.h>
10+
#include <zephyr/sys/util_macro.h>
11+
#include <zephyr/toolchain.h>
12+
13+
#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER
14+
extern void z_soc_irq_eoi(unsigned int irq);
15+
#else
16+
#include <zephyr/drivers/interrupt_controller/gic.h>
17+
#endif
18+
19+
#define READ_COPROCESSOR_REGISTER(out, coproc, opc1, crn, crm, opc2) \
20+
__asm__ volatile("mrc " #coproc ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 "\n" : "=r" (out) ::);
21+
22+
#define WRITE_COPROCESSOR_REGISTER(in, coproc, opc1, crn, crm, opc2) \
23+
__asm__ volatile("mcr " #coproc ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 "\n" :: "r" (in) :)
24+
25+
void cleanup_arm_interrupts(void)
26+
{
27+
/* Allow any pending interrupts to be recognized */
28+
__ISB();
29+
__disable_irq();
30+
31+
for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
32+
irq_disable(i);
33+
}
34+
35+
for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
36+
#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER
37+
z_soc_irq_eoi(i);
38+
#else
39+
arm_gic_eoi(i);
40+
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
41+
}
42+
}
43+
44+
#if CONFIG_CPU_HAS_ARM_MPU
45+
__weak void z_arm_clear_arm_mpu_config(void)
46+
{
47+
uint8_t i;
48+
uint8_t num_regions;
49+
uint32_t mpu_type_register;
50+
51+
/* Disable MPU */
52+
uint32_t val;
53+
READ_COPROCESSOR_REGISTER(val, p15, 0, c1, c0, 0);
54+
val &= ~BIT(0);
55+
__DSB();
56+
57+
WRITE_COPROCESSOR_REGISTER(val, p15, 0, c1, c0, 0);
58+
__ISB();
59+
60+
/* The number of MPU regions is stored in bits 15:8 of the MPU type register */
61+
READ_COPROCESSOR_REGISTER(mpu_type_register, p15, 0, c0, c0, 4);
62+
num_regions = (uint8_t) ((mpu_type_register >> 8) & BIT_MASK(8));
63+
64+
for (i = 0; i < num_regions; ++i) {
65+
/* Select region in the MPU and clear the region size field */
66+
WRITE_COPROCESSOR_REGISTER(i, p15, 0, c6, c2, 0);
67+
WRITE_COPROCESSOR_REGISTER(0, p15, 0, c6, c1, 2);
68+
}
69+
}
70+
#endif

boot/zephyr/include/arm_cleanup.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
/**
1212
* Cleanup interrupt priority and interupt enable registers.
1313
*/
14-
void cleanup_arm_nvic(void);
14+
void cleanup_arm_interrupts(void);
1515

1616
#if defined(CONFIG_CPU_HAS_ARM_MPU) || defined(CONFIG_CPU_HAS_NXP_SYSMPU)
1717
/**

boot/zephyr/main.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ static void do_boot(struct boot_rsp *rsp)
195195
usb_disable();
196196
#endif
197197
#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
198-
cleanup_arm_nvic(); /* cleanup NVIC registers */
198+
cleanup_arm_interrupts(); /* Disable and acknowledge all interrupts */
199199

200200
#if defined(CONFIG_BOOT_DISABLE_CACHES)
201201
/* Flush and disable instruction/data caches before chain-loading the application */
@@ -243,8 +243,26 @@ static void do_boot(struct boot_rsp *rsp)
243243
#endif
244244

245245
#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
246+
#ifdef CONFIG_CPU_CORTEX_M
246247
__set_CONTROL(0x00); /* application will configures core on its own */
247248
__ISB();
249+
#else
250+
/* Set mode to supervisor and A, I and F bit as described in the
251+
* Cortex R5 TRM */
252+
__asm__ volatile(
253+
" mrs r0, CPSR\n"
254+
/* change mode bits to supervisor */
255+
" bic r0, #0x1f\n"
256+
" orr r0, #0x13\n"
257+
/* set the A, I and F bit */
258+
" mov r1, #0b111\n"
259+
" lsl r1, #0x6\n"
260+
" orr r0, r1\n"
261+
262+
" msr CPSR, r0\n"
263+
::: "r0", "r1");
264+
#endif /* CONFIG_CPU_CORTEX_M */
265+
248266
#endif
249267
#if CONFIG_MCUBOOT_CLEANUP_RAM
250268
__asm__ volatile (

0 commit comments

Comments
 (0)