Skip to content

Commit 7fa0f80

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 <mika.braunschweig@siemens.com>
1 parent e410429 commit 7fa0f80

File tree

4 files changed

+91
-5
lines changed

4 files changed

+91
-5
lines changed

boot/zephyr/Kconfig

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

341341
config MCUBOOT_CLEANUP_ARM_CORE
342342
bool "Perform core cleanup before chain-load the application"
343-
depends on CPU_CORTEX_M
343+
depends on CPU_CORTEX_M || CPU_CORTEX_R5
344344
default y
345345
help
346346
This option instructs MCUboot to perform a clean-up of a set of

boot/zephyr/arm_cleanup.c

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,49 @@
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+
/* Macros for inline assembly to improve readability */
31+
#ifdef CONFIG_CPU_CORTEX_R5
32+
33+
#define READ_COPROCESSOR_REGISTER(out, coproc, opc1, crn, crm, opc2) \
34+
__asm__ volatile("mrc " #coproc ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 "\n" : "=r" (out) ::);
35+
36+
#define WRITE_COPROCESSOR_REGISTER(in, coproc, opc1, crn, crm, opc2) \
37+
__asm__ volatile("mcr " #coproc ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 "\n" :: "r" (in) :)
38+
39+
#endif /* CONFIG_CPU_CORTEX_R5 */
40+
41+
void cleanup_arm_interrupts(void) {
1542
/* Allow any pending interrupts to be recognized */
1643
__ISB();
1744
__disable_irq();
1845

46+
#ifdef CONFIG_CPU_CORTEX_M
1947
/* Disable NVIC interrupts */
2048
for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) {
2149
NVIC->ICER[i] = 0xFFFFFFFF;
@@ -24,11 +52,27 @@ void cleanup_arm_nvic(void) {
2452
for (uint8_t i = 0; i < ARRAY_SIZE(NVIC->ICPR); i++) {
2553
NVIC->ICPR[i] = 0xFFFFFFFF;
2654
}
55+
#else
56+
57+
for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
58+
irq_disable(i);
59+
}
60+
61+
for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
62+
#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER
63+
z_soc_irq_eoi(i);
64+
#else
65+
arm_gic_eoi(i);
66+
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
67+
}
68+
69+
#endif /* CONFIG_CPU_CORTEX_M */
2770
}
2871

2972
#if CONFIG_CPU_HAS_ARM_MPU
3073
__weak void z_arm_clear_arm_mpu_config(void)
3174
{
75+
#ifdef CONFIG_CPU_CORTEX_M
3276
int i;
3377

3478
int num_regions =
@@ -37,6 +81,30 @@ __weak void z_arm_clear_arm_mpu_config(void)
3781
for (i = 0; i < num_regions; i++) {
3882
ARM_MPU_ClrRegion(i);
3983
}
84+
#else
85+
uint8_t i;
86+
uint8_t num_regions;
87+
uint32_t mpu_type_register;
88+
89+
/* Disable MPU */
90+
uint32_t val;
91+
READ_COPROCESSOR_REGISTER(val, p15, 0, c1, c0, 0);
92+
val &= ~BIT(0);
93+
__DSB();
94+
95+
WRITE_COPROCESSOR_REGISTER(val, p15, 0, c1, c0, 0);
96+
__ISB();
97+
98+
/* The number of MPU regions is stored in bits 15:8 of the MPU type register */
99+
READ_COPROCESSOR_REGISTER(mpu_type_register, p15, 0, c0, c0, 4);
100+
num_regions = (uint8_t) ((mpu_type_register >> 8) & BIT_MASK(8));
101+
102+
for (i = 0; i < num_regions; ++i) {
103+
/* Select region in the MPU and clear the region size field */
104+
WRITE_COPROCESSOR_REGISTER(i, p15, 0, c6, c2, 0);
105+
WRITE_COPROCESSOR_REGISTER(0, p15, 0, c6, c1, 2);
106+
}
107+
#endif /* CONFIG_CPU_CORTEX_M */
40108
}
41109
#elif CONFIG_CPU_HAS_NXP_MPU
42110
__weak void z_arm_clear_arm_mpu_config(void)

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_MPU)
1717
/**

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)