Skip to content

Commit 63f4e7f

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 2df96dc commit 63f4e7f

File tree

4 files changed

+84
-5
lines changed

4 files changed

+84
-5
lines changed

boot/zephyr/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Copyright (c) 2017-2020 Linaro Limited
22
# Copyright (c) 2020 Arm Limited
33
# Copyright (c) 2023 Nordic Semiconductor ASA
4+
# Copyright (c) 2025 Siemens Mobility GmbH
45
#
56
# SPDX-License-Identifier: Apache-2.0
67
#
@@ -340,7 +341,7 @@ config BOOT_SIGNATURE_KEY_FILE
340341

341342
config MCUBOOT_CLEANUP_ARM_CORE
342343
bool "Perform core cleanup before chain-load the application"
343-
depends on CPU_CORTEX_M
344+
depends on CPU_CORTEX_M || CPU_CORTEX_R5
344345
default y
345346
help
346347
This option instructs MCUboot to perform a clean-up of a set of

boot/zephyr/arm_cleanup.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,38 @@
11
/*
22
* Copyright (c) 2020 Nordic Semiconductor ASA
3+
* Copyright (c) 2025 Siemens Mobility GmbH
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
67

8+
#include <stdint.h>
9+
#include <zephyr/irq.h>
10+
#include "zephyr/sys/util_macro.h"
711
#include <zephyr/toolchain.h>
812

13+
#ifdef CONFIG_CPU_CORTEX_M
914
#include <cmsis_core.h>
15+
#endif
1016
#if CONFIG_CPU_HAS_NXP_MPU
1117
#include <fsl_sysmpu.h>
1218
#endif
1319

14-
void cleanup_arm_nvic(void) {
20+
#ifndef CONFIG_CPU_CORTEX_M
21+
22+
#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER
23+
extern void z_soc_irq_eoi(unsigned int irq);
24+
#else
25+
#include <zephyr/drivers/interrupt_controller/gic.h>
26+
#endif
27+
28+
#endif /* CONFIG_CPU_CORTEX_M */
29+
30+
void cleanup_arm_interrupts(void) {
1531
/* Allow any pending interrupts to be recognized */
1632
__ISB();
1733
__disable_irq();
1834

35+
#ifdef CONFIG_CPU_CORTEX_M
1936
/* Disable NVIC interrupts */
2037
for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) {
2138
NVIC->ICER[i] = 0xFFFFFFFF;
@@ -24,11 +41,27 @@ void cleanup_arm_nvic(void) {
2441
for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICPR); i++) {
2542
NVIC->ICPR[i] = 0xFFFFFFFF;
2643
}
44+
#else
45+
46+
for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
47+
irq_disable(i);
48+
}
49+
50+
for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
51+
#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER
52+
z_soc_irq_eoi(i);
53+
#else
54+
arm_gic_eoi(i);
55+
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
56+
}
57+
58+
#endif /* CONFIG_CPU_CORTEX_M */
2759
}
2860

2961
#if CONFIG_CPU_HAS_ARM_MPU
3062
__weak void z_arm_clear_arm_mpu_config(void)
3163
{
64+
#ifdef CONFIG_CPU_CORTEX_M
3265
int i;
3366

3467
int num_regions =
@@ -37,6 +70,32 @@ __weak void z_arm_clear_arm_mpu_config(void)
3770
for (i = 0; i < num_regions; i++) {
3871
ARM_MPU_ClrRegion(i);
3972
}
73+
#else
74+
uint8_t i;
75+
uint8_t num_regions;
76+
uint32_t mpu_type_register;
77+
78+
// disable MPU
79+
__asm__(
80+
" mrc p15, 0, r0, c1, c0, 0\n"
81+
" bic r0, #1\n"
82+
" mcr p15, 0, r0, c1, c0, 0\n"
83+
" isb\n"
84+
::: "r0");
85+
86+
// the number of MPU regions is stored in bits 15:8 of the MPU type register
87+
__asm__ volatile("mrc p15, 0, %0, c0, c0, 4\n" : "=r" (mpu_type_register) ::);
88+
num_regions = (uint8_t) ((mpu_type_register >> 8) & BIT_MASK(8));
89+
90+
for (i = 0; i < num_regions; ++i) {
91+
// select region in the MPU and clear the region size field
92+
__asm__ volatile(
93+
" mov r0, #0\n"
94+
" mcr p15, 0, %0, c6, c2, 0\n"
95+
" mcr p15, 0, r0, c6, c1, 2\n"
96+
:: "r" (i) : "r0");
97+
}
98+
#endif /* CONFIG_CPU_CORTEX_M */
4099
}
41100
#elif CONFIG_CPU_HAS_NXP_MPU
42101
__weak void z_arm_clear_arm_mpu_config(void)

boot/zephyr/include/arm_cleanup.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
/*
33
* Copyright (c) 2020 Nordic Semiconductor ASA
4+
* Copyright (c) 2025 Siemens Mobility GmbH
45
*
56
* SPDX-License-Identifier: Apache-2.0
67
*/
@@ -11,7 +12,7 @@
1112
/**
1213
* Cleanup interrupt priority and interupt enable registers.
1314
*/
14-
void cleanup_arm_nvic(void);
15+
void cleanup_arm_interrupts(void);
1516

1617
#if defined(CONFIG_CPU_HAS_ARM_MPU) || defined(CONFIG_CPU_HAS_NXP_MPU)
1718
/**

boot/zephyr/main.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
#include <zephyr/cache.h>
3333
#endif
3434

35-
#if defined(CONFIG_ARM)
35+
#if defined(CONFIG_CPU_CORTEX_M)
3636
#include <cmsis_core.h>
3737
#endif
3838

@@ -201,7 +201,7 @@ static void do_boot(struct boot_rsp *rsp)
201201
usb_disable();
202202
#endif
203203
#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
204-
cleanup_arm_nvic(); /* cleanup NVIC registers */
204+
cleanup_arm_interrupts(); /* disable and acknowledge all interrupts */
205205

206206
#if defined(CONFIG_BOOT_DISABLE_CACHES)
207207
/* Flush and disable instruction/data caches before chain-loading the application */
@@ -249,8 +249,26 @@ static void do_boot(struct boot_rsp *rsp)
249249
#endif
250250

251251
#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
252+
#ifdef CONFIG_CPU_CORTEX_M
252253
__set_CONTROL(0x00); /* application will configures core on its own */
253254
__ISB();
255+
#else
256+
/* set mode to supervisor and A, I and F bit as described in the
257+
* Cortex R5 TRM */
258+
__asm__ volatile(
259+
" mrs r0, CPSR\n"
260+
/* change mode bits to supervisor */
261+
" bic r0, #0x1f\n"
262+
" orr r0, #0x13\n"
263+
/* set the A, I and F bit */
264+
" mov r1, #0b111\n"
265+
" lsl r1, #0x6\n"
266+
" orr r0, r1\n"
267+
268+
" msr CPSR, r0\n"
269+
::: "r0", "r1");
270+
#endif /* CONFIG_CPU_CORTEX_M */
271+
254272
#endif
255273
#if CONFIG_MCUBOOT_CLEANUP_RAM
256274
__asm__ volatile (

0 commit comments

Comments
 (0)