Skip to content

Add Cortex-R support #2261

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
14 changes: 11 additions & 3 deletions boot/zephyr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -439,9 +439,17 @@ if(CONFIG_BOOT_ENCRYPTION_KEY_FILE AND NOT CONFIG_BOOT_ENCRYPTION_KEY_FILE STREQ
endif()

if(CONFIG_MCUBOOT_CLEANUP_ARM_CORE)
zephyr_library_sources(
${BOOT_DIR}/zephyr/arm_cleanup.c
)
# ARM Cortex-M
zephyr_library_sources_ifdef(
CONFIG_CPU_CORTEX_M
${BOOT_DIR}/zephyr/cleanup/arm_cortex_m.c
)

# ARM Cortex-R
zephyr_library_sources_ifdef(
CONFIG_ARMV7_R
${BOOT_DIR}/zephyr/cleanup/arm_cortex_r.c
)
endif()

if(CONFIG_MCUBOOT_BOOT_BANNER)
Expand Down
2 changes: 1 addition & 1 deletion boot/zephyr/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ config BOOT_SIGNATURE_KEY_FILE

config MCUBOOT_CLEANUP_ARM_CORE
bool "Perform core cleanup before chain-load the application"
depends on CPU_CORTEX_M
depends on CPU_CORTEX_M || ARMV7_R
default y
help
This option instructs MCUboot to perform a clean-up of a set of
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
#include <fsl_sysmpu.h>
#endif

void cleanup_arm_nvic(void) {

void cleanup_arm_interrupts(void)
{
/* Allow any pending interrupts to be recognized */
__ISB();
__disable_irq();
Expand Down
70 changes: 70 additions & 0 deletions boot/zephyr/cleanup/arm_cortex_r.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2020 Nordic Semiconductor ASA
* Copyright (c) 2025 Siemens Mobility GmbH
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <stdint.h>
#include <zephyr/irq.h>
#include <zephyr/sys/util_macro.h>
#include <zephyr/toolchain.h>

#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER
extern void z_soc_irq_eoi(unsigned int irq);
#else
#include <zephyr/drivers/interrupt_controller/gic.h>
#endif

#define READ_COPROCESSOR_REGISTER(out, coproc, opc1, crn, crm, opc2) \
__asm__ volatile("mrc " #coproc ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 "\n" : "=r" (out) ::);

#define WRITE_COPROCESSOR_REGISTER(in, coproc, opc1, crn, crm, opc2) \
__asm__ volatile("mcr " #coproc ", " #opc1 ", %0, " #crn ", " #crm ", " #opc2 "\n" :: "r" (in) :)

void cleanup_arm_interrupts(void)
{
/* Allow any pending interrupts to be recognized */
__ISB();
__disable_irq();

for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
irq_disable(i);
}

for (unsigned int i = 0; i < CONFIG_NUM_IRQS; ++i) {
#ifdef CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER
z_soc_irq_eoi(i);
#else
arm_gic_eoi(i);
#endif /* CONFIG_ARM_CUSTOM_INTERRUPT_CONTROLLER */
}
}

#if CONFIG_CPU_HAS_ARM_MPU
__weak void z_arm_clear_arm_mpu_config(void)
{
uint8_t i;
uint8_t num_regions;
uint32_t mpu_type_register;

/* Disable MPU */
uint32_t val;
READ_COPROCESSOR_REGISTER(val, p15, 0, c1, c0, 0);
val &= ~BIT(0);
__DSB();

WRITE_COPROCESSOR_REGISTER(val, p15, 0, c1, c0, 0);
__ISB();

/* The number of MPU regions is stored in bits 15:8 of the MPU type register */
READ_COPROCESSOR_REGISTER(mpu_type_register, p15, 0, c0, c0, 4);
num_regions = (uint8_t) ((mpu_type_register >> 8) & BIT_MASK(8));

for (i = 0; i < num_regions; ++i) {
/* Select region in the MPU and clear the region size field */
WRITE_COPROCESSOR_REGISTER(i, p15, 0, c6, c2, 0);
WRITE_COPROCESSOR_REGISTER(0, p15, 0, c6, c1, 2);
}
}
#endif
2 changes: 1 addition & 1 deletion boot/zephyr/include/arm_cleanup.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/**
* Cleanup interrupt priority and interupt enable registers.
*/
void cleanup_arm_nvic(void);
void cleanup_arm_interrupts(void);

#if defined(CONFIG_CPU_HAS_ARM_MPU) || defined(CONFIG_CPU_HAS_NXP_SYSMPU)
/**
Expand Down
48 changes: 46 additions & 2 deletions boot/zephyr/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Copyright (c) 2020 Arm Limited
* Copyright (c) 2021-2023 Nordic Semiconductor ASA
* Copyright (c) 2025 Aerlync Labs Inc.
* Copyright (c) 2025 Siemens Mobility GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -32,7 +33,7 @@
#include <zephyr/cache.h>
#endif

#if defined(CONFIG_ARM)
#if defined(CONFIG_CPU_CORTEX_M)
#include <cmsis_core.h>
#endif

Expand Down Expand Up @@ -142,8 +143,19 @@ extern void *_vector_table_pointer;
#endif

struct arm_vector_table {
#ifdef CONFIG_CPU_CORTEX_M
uint32_t msp;
uint32_t reset;
#else
uint32_t reset;
uint32_t undef_instruction;
uint32_t svc;
uint32_t abort_prefetch;
uint32_t abort_data;
uint32_t reserved;
uint32_t irq;
uint32_t fiq;
#endif
};

static void do_boot(struct boot_rsp *rsp)
Expand Down Expand Up @@ -183,7 +195,7 @@ static void do_boot(struct boot_rsp *rsp)
usb_disable();
#endif
#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
cleanup_arm_nvic(); /* cleanup NVIC registers */
cleanup_arm_interrupts(); /* Disable and acknowledge all interrupts */

#if defined(CONFIG_BOOT_DISABLE_CACHES)
/* Flush and disable instruction/data caches before chain-loading the application */
Expand Down Expand Up @@ -226,10 +238,31 @@ static void do_boot(struct boot_rsp *rsp)
#endif
#endif /* CONFIG_BOOT_INTR_VEC_RELOC */

#ifdef CONFIG_CPU_CORTEX_M
__set_MSP(vt->msp);
#endif

#if CONFIG_MCUBOOT_CLEANUP_ARM_CORE
#ifdef CONFIG_CPU_CORTEX_M
__set_CONTROL(0x00); /* application will configures core on its own */
__ISB();
#else

Choose a reason for hiding this comment

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

I am good with it as it is but can we do #ifdef CONFIG_ARMV7_R here just to make the use case clearer. Same with other #elses as well?

/* Set mode to supervisor and A, I and F bit as described in the
* Cortex R5 TRM */
__asm__ volatile(
" mrs r0, CPSR\n"
/* change mode bits to supervisor */
" bic r0, #0x1f\n"
" orr r0, #0x13\n"
/* set the A, I and F bit */
" mov r1, #0b111\n"
" lsl r1, #0x6\n"
" orr r0, r1\n"

" msr CPSR, r0\n"
::: "r0", "r1");
#endif /* CONFIG_CPU_CORTEX_M */

#endif
#if CONFIG_MCUBOOT_CLEANUP_RAM
__asm__ volatile (
Expand Down Expand Up @@ -257,7 +290,18 @@ static void do_boot(struct boot_rsp *rsp)
: "r0", "r1", "r2", "r3", "memory"
);
#else

#ifdef CONFIG_CPU_CORTEX_M
((void (*)(void))vt->reset)();
#else
/* Some ARM CPUs like the Cortex-R5 can run in thumb mode but reset into ARM
* mode (depending on a CPU signal configurations). To do the switch into ARM
* mode, if needed, an explicit branch with exchange instruction set
* instruction is needed
*/
__asm__("bx %0\n" : : "r" (&vt->reset));
#endif

#endif
}

Expand Down
1 change: 1 addition & 0 deletions docs/release-notes.d/add-cortex-r-support-00-basic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Added support for booting Cortex-R5 images
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add support for cleaning up the Cortex-R core before final jumping
Loading