diff --git a/asm.s b/asm.s index 50a3fa56..c1953c67 100644 --- a/asm.s +++ b/asm.s @@ -17,3 +17,17 @@ HardFaultTrampoline: 0: mrs r0, PSP b HardFault + + # ARMv6-M leaves LR in an unknown state on Reset + # this trampoline sets LR before it's pushed onto the stack by Reset + .section .PreResetTrampoline, "ax" + .global PreResetTrampoline + # .type and .thumb_func are both required; otherwise its Thumb bit does not + # get set and an invalid vector table is generated + .type PreResetTrampoline,%function + .thumb_func +PreResetTrampoline: + # set LR to the initial value used by the ARMv7-M (0xFFFF_FFFF) + ldr r0,=0xffffffff + mov lr,r0 + b Reset diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a index 6a6a5470..28e2ec7f 100644 Binary files a/bin/thumbv6m-none-eabi.a and b/bin/thumbv6m-none-eabi.a differ diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a index 51d9aef4..8d9a9eb8 100644 Binary files a/bin/thumbv7em-none-eabi.a and b/bin/thumbv7em-none-eabi.a differ diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a index 51d9aef4..8d9a9eb8 100644 Binary files a/bin/thumbv7em-none-eabihf.a and b/bin/thumbv7em-none-eabihf.a differ diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a index dc37fbf0..504c0c87 100644 Binary files a/bin/thumbv7m-none-eabi.a and b/bin/thumbv7m-none-eabi.a differ diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a index dda8dcc7..067ead6e 100644 Binary files a/bin/thumbv8m.base-none-eabi.a and b/bin/thumbv8m.base-none-eabi.a differ diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a index ab500f4c..85851fdb 100644 Binary files a/bin/thumbv8m.main-none-eabi.a and b/bin/thumbv8m.main-none-eabi.a differ diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a index ab500f4c..85851fdb 100644 Binary files a/bin/thumbv8m.main-none-eabihf.a and b/bin/thumbv8m.main-none-eabihf.a differ diff --git a/link.x.in b/link.x.in index 30d4af10..5a277e27 100644 --- a/link.x.in +++ b/link.x.in @@ -85,6 +85,10 @@ SECTIONS /* ### .text */ .text _stext : { + /* place these 2 close to each other or the `b` instruction will fail to link */ + *(.PreResetTrampoline); + *(.Reset); + *(.text .text.*); *(.HardFaultTrampoline); *(.HardFault.*); diff --git a/src/lib.rs b/src/lib.rs index 85d94965..1f95dc2d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -482,9 +482,17 @@ pub fn heap_start() -> *mut u32 { #[doc(hidden)] #[link_section = ".vector_table.reset_vector"] #[no_mangle] +#[cfg(not(armv6m))] pub static __RESET_VECTOR: unsafe extern "C" fn() -> ! = Reset; #[doc(hidden)] +#[link_section = ".vector_table.reset_vector"] +#[no_mangle] +#[cfg(armv6m)] +pub static __RESET_VECTOR: unsafe extern "C" fn() -> ! = PreResetTrampoline; + +#[doc(hidden)] +#[link_section = ".Reset"] #[no_mangle] pub unsafe extern "C" fn Reset() -> ! { extern "C" { @@ -600,6 +608,9 @@ pub enum Exception { } extern "C" { + #[cfg(armv6m)] + fn PreResetTrampoline() -> !; + fn NonMaskableInt(); fn HardFaultTrampoline(); diff --git a/tests/compile-fail/interrupt-invalid.rs b/tests/compile-fail/interrupt-invalid.rs index e915518f..63e1147a 100644 --- a/tests/compile-fail/interrupt-invalid.rs +++ b/tests/compile-fail/interrupt-invalid.rs @@ -19,4 +19,4 @@ enum interrupt { // NOTE this looks a bit better when using a device crate: // "no variant named `foo` found for type `stm32f30x::Interrupt` in the current scope" #[interrupt] -fn foo() {} //~ ERROR no variant or associated item named `foo` found for type `interrupt` in the current scope +fn foo() {} //~ ERROR no variant or associated item named `foo` found for enum `interrupt` in the current scope