From b1880198643efdf34f0a220e9ce2dd3b3a3eb096 Mon Sep 17 00:00:00 2001 From: decaday Date: Wed, 12 Feb 2025 15:40:26 +0800 Subject: [PATCH 1/2] cortex-m-rt: Add optional MSPLIM initialization for ARMv8-M Mainline --- cortex-m-rt/CHANGELOG.md | 3 +++ cortex-m-rt/Cargo.toml | 1 + cortex-m-rt/build.rs | 18 ++++++++++++++++-- cortex-m-rt/src/lib.rs | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cortex-m-rt/CHANGELOG.md b/cortex-m-rt/CHANGELOG.md index c8ab92c9..b85dcb9c 100644 --- a/cortex-m-rt/CHANGELOG.md +++ b/cortex-m-rt/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +- Add `set_msplim` feature to conditionally set the MSPLIM register at device + reset ([#580]). + ## [v0.7.5] - Fix incorrect dependency on cortex-m-rt-macros in v0.7.4 which led to diff --git a/cortex-m-rt/Cargo.toml b/cortex-m-rt/Cargo.toml index eaa84df0..377a8d5d 100644 --- a/cortex-m-rt/Cargo.toml +++ b/cortex-m-rt/Cargo.toml @@ -45,6 +45,7 @@ required-features = ["device"] device = [] set-sp = [] set-vtor = [] +set-msplim = [] zero-init-ram = [] paint-stack = [] diff --git a/cortex-m-rt/build.rs b/cortex-m-rt/build.rs index 9575a537..0215769a 100644 --- a/cortex-m-rt/build.rs +++ b/cortex-m-rt/build.rs @@ -43,8 +43,11 @@ INCLUDE device.x"# }; println!("cargo:rustc-check-cfg=cfg(armv6m)"); + println!("cargo:rustc-check-cfg=cfg(armv7em)"); println!("cargo:rustc-check-cfg=cfg(armv7m)"); println!("cargo:rustc-check-cfg=cfg(armv8m)"); + println!("cargo:rustc-check-cfg=cfg(armv8m_base)"); + println!("cargo:rustc-check-cfg=cfg(armv8m_main)"); println!("cargo:rustc-check-cfg=cfg(cortex_m)"); println!("cargo:rustc-check-cfg=cfg(has_fpu)"); @@ -52,13 +55,24 @@ INCLUDE device.x"# println!("cargo:rustc-cfg=cortex_m"); println!("cargo:rustc-cfg=armv6m"); 32 - } else if target.starts_with("thumbv7m-") || target.starts_with("thumbv7em-") { + } else if target.starts_with("thumbv7m-") { println!("cargo:rustc-cfg=cortex_m"); println!("cargo:rustc-cfg=armv7m"); 240 - } else if target.starts_with("thumbv8m") { + } else if target.starts_with("thumbv7em-") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv7m"); + println!("cargo:rustc-cfg=armv7em"); + 240 + } else if target.starts_with("thumbv8m.base") { + println!("cargo:rustc-cfg=cortex_m"); + println!("cargo:rustc-cfg=armv8m"); + println!("cargo:rustc-cfg=armv8m_base"); + 496 + } else if target.starts_with("thumbv8m.main") { println!("cargo:rustc-cfg=cortex_m"); println!("cargo:rustc-cfg=armv8m"); + println!("cargo:rustc-cfg=armv8m_main"); 496 } else { // Non ARM target. We assume you're just testing the syntax. diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs index 2874f1ac..45db62f7 100644 --- a/cortex-m-rt/src/lib.rs +++ b/cortex-m-rt/src/lib.rs @@ -187,6 +187,13 @@ //! required, but some bootloaders do not set VTOR before jumping to application code, leading to //! your main function executing but interrupt handlers not being used. //! +//! ## `set-msplim` +//! +//! If this feature is enabled, the main stack pointer limit register (MSPLIM) is initialized in +//! the reset handler to the `_stack_end` value from the linker script. This feature is only +//! available on ARMv8-M Mainline and helps enforce stack limits by defining the lowest valid +//! stack address. +//! //! ## `zero-init-ram` //! //! If this feature is enabled, RAM is initialized with zeros during startup from the `_ram_start` @@ -544,6 +551,13 @@ cfg_global_asm! { ldr r1, =__vector_table str r1, [r0]", + // If enabled, set the Main Stack Pointer Limit (MSPLIM) to the end of the stack. + // This feature is only available on ARMv8-M Mainline, where it helps enforce stack limits + // by defining the lowest valid stack address. + #[cfg(all(armv8m_main, feature = "set-msplim"))] + "ldr r0, =_stack_end + msr MSPLIM, r0", + // Run user pre-init code which must be executed immediately after startup, before the // potentially time-consuming memory initialisation takes place. // Example use cases include disabling default watchdogs or enabling RAM. From 77449e5453f260b547b30341c210825ddcc95372 Mon Sep 17 00:00:00 2001 From: decaday Date: Wed, 12 Feb 2025 16:55:37 +0800 Subject: [PATCH 2/2] cortex-m-rt: Fix max_int_handlers on armv8m Fixed interrupt count for Cortex-M23 (ARMv8-M Baseline, 240) and Cortex-M33 (ARMv8-M Mainline, 480) based on the technical reference manual. The original value of 496 referred to the entire vector table length, with exceptions length already included in the assert check. --- cortex-m-rt/build.rs | 4 ++-- cortex-m-rt/src/lib.rs | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/cortex-m-rt/build.rs b/cortex-m-rt/build.rs index 0215769a..344ff872 100644 --- a/cortex-m-rt/build.rs +++ b/cortex-m-rt/build.rs @@ -68,12 +68,12 @@ INCLUDE device.x"# println!("cargo:rustc-cfg=cortex_m"); println!("cargo:rustc-cfg=armv8m"); println!("cargo:rustc-cfg=armv8m_base"); - 496 + 240 } else if target.starts_with("thumbv8m.main") { println!("cargo:rustc-cfg=cortex_m"); println!("cargo:rustc-cfg=armv8m"); println!("cargo:rustc-cfg=armv8m_main"); - 496 + 480 } else { // Non ARM target. We assume you're just testing the syntax. // This value seems as good as any. diff --git a/cortex-m-rt/src/lib.rs b/cortex-m-rt/src/lib.rs index 45db62f7..2aaeadde 100644 --- a/cortex-m-rt/src/lib.rs +++ b/cortex-m-rt/src/lib.rs @@ -273,7 +273,8 @@ //! //! - `__INTERRUPTS`. This is the device specific interrupt portion of the vector table; its exact //! size depends on the target device but if the `"device"` feature has not been enabled it will -//! have a size of 32 vectors (on ARMv6-M), 240 vectors (on ARMv7-M) or 496 vectors (on ARMv8-M). +//! have a size of 32 vectors (on ARMv6-M), 240 vectors (on ARMv7-M, ARMv8-M Baseline) or 480 +//! vectors (on ARMv8-M Mainline). //! This array is located after `__EXCEPTIONS` in the `.vector_table` section. //! //! - `__pre_init`. This is a function to be run before RAM is initialized. It defaults to an empty @@ -1259,7 +1260,7 @@ pub static __EXCEPTIONS: [Vector; 14] = [ // If we are not targeting a specific device we bind all the potential device specific interrupts // to the default handler -#[cfg(all(any(not(feature = "device"), test), not(armv6m), not(armv8m)))] +#[cfg(all(any(not(feature = "device"), test), not(armv6m), not(armv8m_main)))] #[doc(hidden)] #[cfg_attr(cortex_m, link_section = ".vector_table.interrupts")] #[no_mangle] @@ -1271,18 +1272,18 @@ pub static __INTERRUPTS: [unsafe extern "C" fn(); 240] = [{ DefaultHandler }; 240]; -// ARMv8-M can have up to 496 device specific interrupts -#[cfg(all(not(feature = "device"), armv8m))] +// ARMv8-M Mainline can have up to 480 device specific interrupts +#[cfg(all(not(feature = "device"), armv8m_main))] #[doc(hidden)] #[cfg_attr(cortex_m, link_section = ".vector_table.interrupts")] #[no_mangle] -pub static __INTERRUPTS: [unsafe extern "C" fn(); 496] = [{ +pub static __INTERRUPTS: [unsafe extern "C" fn(); 480] = [{ extern "C" { fn DefaultHandler(); } DefaultHandler -}; 496]; +}; 480]; // ARMv6-M can only have a maximum of 32 device specific interrupts #[cfg(all(not(feature = "device"), armv6m))]