Skip to content

Commit f2fc7d3

Browse files
authored
Merge pull request #580 from decaday/feat/set-msplim
cortex-m-rt: Add optional MSPLIM initialization, fix vector table size on armv8m
2 parents f97bfe8 + 77449e5 commit f2fc7d3

File tree

4 files changed

+42
-9
lines changed

4 files changed

+42
-9
lines changed

cortex-m-rt/CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
- Add `set_msplim` feature to conditionally set the MSPLIM register at device
11+
reset ([#580]).
12+
1013
## [v0.7.5]
1114

1215
- Fix incorrect dependency on cortex-m-rt-macros in v0.7.4 which led to

cortex-m-rt/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ required-features = ["device"]
4545
device = []
4646
set-sp = []
4747
set-vtor = []
48+
set-msplim = []
4849
zero-init-ram = []
4950
paint-stack = []
5051

cortex-m-rt/build.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,37 @@ INCLUDE device.x"#
4343
};
4444

4545
println!("cargo:rustc-check-cfg=cfg(armv6m)");
46+
println!("cargo:rustc-check-cfg=cfg(armv7em)");
4647
println!("cargo:rustc-check-cfg=cfg(armv7m)");
4748
println!("cargo:rustc-check-cfg=cfg(armv8m)");
49+
println!("cargo:rustc-check-cfg=cfg(armv8m_base)");
50+
println!("cargo:rustc-check-cfg=cfg(armv8m_main)");
4851
println!("cargo:rustc-check-cfg=cfg(cortex_m)");
4952
println!("cargo:rustc-check-cfg=cfg(has_fpu)");
5053

5154
let max_int_handlers = if target.starts_with("thumbv6m-") {
5255
println!("cargo:rustc-cfg=cortex_m");
5356
println!("cargo:rustc-cfg=armv6m");
5457
32
55-
} else if target.starts_with("thumbv7m-") || target.starts_with("thumbv7em-") {
58+
} else if target.starts_with("thumbv7m-") {
5659
println!("cargo:rustc-cfg=cortex_m");
5760
println!("cargo:rustc-cfg=armv7m");
5861
240
59-
} else if target.starts_with("thumbv8m") {
62+
} else if target.starts_with("thumbv7em-") {
63+
println!("cargo:rustc-cfg=cortex_m");
64+
println!("cargo:rustc-cfg=armv7m");
65+
println!("cargo:rustc-cfg=armv7em");
66+
240
67+
} else if target.starts_with("thumbv8m.base") {
68+
println!("cargo:rustc-cfg=cortex_m");
69+
println!("cargo:rustc-cfg=armv8m");
70+
println!("cargo:rustc-cfg=armv8m_base");
71+
240
72+
} else if target.starts_with("thumbv8m.main") {
6073
println!("cargo:rustc-cfg=cortex_m");
6174
println!("cargo:rustc-cfg=armv8m");
62-
496
75+
println!("cargo:rustc-cfg=armv8m_main");
76+
480
6377
} else {
6478
// Non ARM target. We assume you're just testing the syntax.
6579
// This value seems as good as any.

cortex-m-rt/src/lib.rs

+21-6
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,13 @@
187187
//! required, but some bootloaders do not set VTOR before jumping to application code, leading to
188188
//! your main function executing but interrupt handlers not being used.
189189
//!
190+
//! ## `set-msplim`
191+
//!
192+
//! If this feature is enabled, the main stack pointer limit register (MSPLIM) is initialized in
193+
//! the reset handler to the `_stack_end` value from the linker script. This feature is only
194+
//! available on ARMv8-M Mainline and helps enforce stack limits by defining the lowest valid
195+
//! stack address.
196+
//!
190197
//! ## `zero-init-ram`
191198
//!
192199
//! If this feature is enabled, RAM is initialized with zeros during startup from the `_ram_start`
@@ -266,7 +273,8 @@
266273
//!
267274
//! - `__INTERRUPTS`. This is the device specific interrupt portion of the vector table; its exact
268275
//! size depends on the target device but if the `"device"` feature has not been enabled it will
269-
//! have a size of 32 vectors (on ARMv6-M), 240 vectors (on ARMv7-M) or 496 vectors (on ARMv8-M).
276+
//! have a size of 32 vectors (on ARMv6-M), 240 vectors (on ARMv7-M, ARMv8-M Baseline) or 480
277+
//! vectors (on ARMv8-M Mainline).
270278
//! This array is located after `__EXCEPTIONS` in the `.vector_table` section.
271279
//!
272280
//! - `__pre_init`. This is a function to be run before RAM is initialized. It defaults to an empty
@@ -544,6 +552,13 @@ cfg_global_asm! {
544552
ldr r1, =__vector_table
545553
str r1, [r0]",
546554

555+
// If enabled, set the Main Stack Pointer Limit (MSPLIM) to the end of the stack.
556+
// This feature is only available on ARMv8-M Mainline, where it helps enforce stack limits
557+
// by defining the lowest valid stack address.
558+
#[cfg(all(armv8m_main, feature = "set-msplim"))]
559+
"ldr r0, =_stack_end
560+
msr MSPLIM, r0",
561+
547562
// Run user pre-init code which must be executed immediately after startup, before the
548563
// potentially time-consuming memory initialisation takes place.
549564
// Example use cases include disabling default watchdogs or enabling RAM.
@@ -1245,7 +1260,7 @@ pub static __EXCEPTIONS: [Vector; 14] = [
12451260

12461261
// If we are not targeting a specific device we bind all the potential device specific interrupts
12471262
// to the default handler
1248-
#[cfg(all(any(not(feature = "device"), test), not(armv6m), not(armv8m)))]
1263+
#[cfg(all(any(not(feature = "device"), test), not(armv6m), not(armv8m_main)))]
12491264
#[doc(hidden)]
12501265
#[cfg_attr(cortex_m, link_section = ".vector_table.interrupts")]
12511266
#[no_mangle]
@@ -1257,18 +1272,18 @@ pub static __INTERRUPTS: [unsafe extern "C" fn(); 240] = [{
12571272
DefaultHandler
12581273
}; 240];
12591274

1260-
// ARMv8-M can have up to 496 device specific interrupts
1261-
#[cfg(all(not(feature = "device"), armv8m))]
1275+
// ARMv8-M Mainline can have up to 480 device specific interrupts
1276+
#[cfg(all(not(feature = "device"), armv8m_main))]
12621277
#[doc(hidden)]
12631278
#[cfg_attr(cortex_m, link_section = ".vector_table.interrupts")]
12641279
#[no_mangle]
1265-
pub static __INTERRUPTS: [unsafe extern "C" fn(); 496] = [{
1280+
pub static __INTERRUPTS: [unsafe extern "C" fn(); 480] = [{
12661281
extern "C" {
12671282
fn DefaultHandler();
12681283
}
12691284

12701285
DefaultHandler
1271-
}; 496];
1286+
}; 480];
12721287

12731288
// ARMv6-M can only have a maximum of 32 device specific interrupts
12741289
#[cfg(all(not(feature = "device"), armv6m))]

0 commit comments

Comments
 (0)