diff options
author | 2020-12-02 14:09:33 +0000 | |
---|---|---|
committer | 2020-12-02 14:18:24 +0000 | |
commit | 3b184eaa0abf147d607f918985bdffd6abe31a51 (patch) | |
tree | a6d563deedb3abb80fdbe9426d7cda310b8569fd | |
parent | 3a3a812f53d9bb66f3fe042a514f813734eac4c6 (diff) | |
download | cortex-m-3b184eaa0abf147d607f918985bdffd6abe31a51.tar.gz cortex-m-3b184eaa0abf147d607f918985bdffd6abe31a51.tar.zst cortex-m-3b184eaa0abf147d607f918985bdffd6abe31a51.zip |
asm.bootstrap: only set CONTROL.SPSEL, mark as divergent
-rw-r--r-- | asm/inline.rs | 22 | ||||
-rw-r--r-- | asm/lib.rs | 4 | ||||
-rw-r--r-- | bin/thumbv6m-none-eabi-lto.a | bin | 15792 -> 15860 bytes | |||
-rw-r--r-- | bin/thumbv6m-none-eabi.a | bin | 18540 -> 18580 bytes | |||
-rw-r--r-- | bin/thumbv7em-none-eabi-lto.a | bin | 19992 -> 20004 bytes | |||
-rw-r--r-- | bin/thumbv7em-none-eabi.a | bin | 22952 -> 23008 bytes | |||
-rw-r--r-- | bin/thumbv7em-none-eabihf-lto.a | bin | 20896 -> 20868 bytes | |||
-rw-r--r-- | bin/thumbv7em-none-eabihf.a | bin | 24040 -> 24096 bytes | |||
-rw-r--r-- | bin/thumbv7m-none-eabi-lto.a | bin | 18744 -> 18796 bytes | |||
-rw-r--r-- | bin/thumbv7m-none-eabi.a | bin | 21784 -> 21840 bytes | |||
-rw-r--r-- | bin/thumbv8m.base-none-eabi-lto.a | bin | 19056 -> 19136 bytes | |||
-rw-r--r-- | bin/thumbv8m.base-none-eabi.a | bin | 22240 -> 22280 bytes | |||
-rw-r--r-- | bin/thumbv8m.main-none-eabi-lto.a | bin | 23504 -> 23504 bytes | |||
-rw-r--r-- | bin/thumbv8m.main-none-eabi.a | bin | 27608 -> 27664 bytes | |||
-rw-r--r-- | bin/thumbv8m.main-none-eabihf-lto.a | bin | 24460 -> 24388 bytes | |||
-rw-r--r-- | bin/thumbv8m.main-none-eabihf.a | bin | 28656 -> 28712 bytes | |||
-rw-r--r-- | src/asm.rs | 24 |
17 files changed, 30 insertions, 20 deletions
diff --git a/asm/inline.rs b/asm/inline.rs index bba5e6e..f2014f8 100644 --- a/asm/inline.rs +++ b/asm/inline.rs @@ -182,17 +182,23 @@ pub unsafe fn __sh_syscall(mut nr: u32, arg: u32) -> u32 { nr } -/// Bootstrap: ensure we are using the main stack, then write `msp` to MSP and jump to `rv`. +/// Set CONTROL.SPSEL to 0, write `msp` to MSP, branch to `rv`. #[inline(always)] -pub unsafe fn __bootstrap(msp: u32, rv: u32) { +pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! { asm!( - "msr CONTROL, {}", + "mrs {tmp}, CONTROL", + "bics {tmp}, {spsel}", + "msr CONTROL, {tmp}", "isb", - "msr MSP, {}", - "bx {}", - in(reg) 0, - in(reg) msp, - in(reg) rv, + "msr MSP, {msp}", + "bx {rv}", + // `out(reg) _` is not permitted in a `noreturn` asm! call, + // so instead use `in(reg) 0` and don't restore it afterwards. + tmp = in(reg) 0, + spsel = in(reg) 2, + msp = in(reg) msp, + rv = in(reg) rv, + options(noreturn), ); } @@ -69,11 +69,11 @@ shims! { fn __psp_r() -> u32; fn __psp_w(val: u32); fn __sev(); - fn __udf(); + fn __udf() -> !; fn __wfe(); fn __wfi(); fn __sh_syscall(nr: u32, arg: u32) -> u32; - fn __bootstrap(msp: u32, rv: u32); + fn __bootstrap(msp: u32, rv: u32) -> !; } // v7m *AND* v8m.main, but *NOT* v8m.base diff --git a/bin/thumbv6m-none-eabi-lto.a b/bin/thumbv6m-none-eabi-lto.a Binary files differindex bdb5314..f3858a0 100644 --- a/bin/thumbv6m-none-eabi-lto.a +++ b/bin/thumbv6m-none-eabi-lto.a diff --git a/bin/thumbv6m-none-eabi.a b/bin/thumbv6m-none-eabi.a Binary files differindex fcc94c0..571396b 100644 --- a/bin/thumbv6m-none-eabi.a +++ b/bin/thumbv6m-none-eabi.a diff --git a/bin/thumbv7em-none-eabi-lto.a b/bin/thumbv7em-none-eabi-lto.a Binary files differindex 50e8f0f..51e02c6 100644 --- a/bin/thumbv7em-none-eabi-lto.a +++ b/bin/thumbv7em-none-eabi-lto.a diff --git a/bin/thumbv7em-none-eabi.a b/bin/thumbv7em-none-eabi.a Binary files differindex 7bc58b8..d6ccf53 100644 --- a/bin/thumbv7em-none-eabi.a +++ b/bin/thumbv7em-none-eabi.a diff --git a/bin/thumbv7em-none-eabihf-lto.a b/bin/thumbv7em-none-eabihf-lto.a Binary files differindex 57c1c9e..cc52e63 100644 --- a/bin/thumbv7em-none-eabihf-lto.a +++ b/bin/thumbv7em-none-eabihf-lto.a diff --git a/bin/thumbv7em-none-eabihf.a b/bin/thumbv7em-none-eabihf.a Binary files differindex adbe047..aea284d 100644 --- a/bin/thumbv7em-none-eabihf.a +++ b/bin/thumbv7em-none-eabihf.a diff --git a/bin/thumbv7m-none-eabi-lto.a b/bin/thumbv7m-none-eabi-lto.a Binary files differindex 0697bff..85720da 100644 --- a/bin/thumbv7m-none-eabi-lto.a +++ b/bin/thumbv7m-none-eabi-lto.a diff --git a/bin/thumbv7m-none-eabi.a b/bin/thumbv7m-none-eabi.a Binary files differindex 4e5b062..d9cf989 100644 --- a/bin/thumbv7m-none-eabi.a +++ b/bin/thumbv7m-none-eabi.a diff --git a/bin/thumbv8m.base-none-eabi-lto.a b/bin/thumbv8m.base-none-eabi-lto.a Binary files differindex 600c26e..37e74a9 100644 --- a/bin/thumbv8m.base-none-eabi-lto.a +++ b/bin/thumbv8m.base-none-eabi-lto.a diff --git a/bin/thumbv8m.base-none-eabi.a b/bin/thumbv8m.base-none-eabi.a Binary files differindex a53abee..0660245 100644 --- a/bin/thumbv8m.base-none-eabi.a +++ b/bin/thumbv8m.base-none-eabi.a diff --git a/bin/thumbv8m.main-none-eabi-lto.a b/bin/thumbv8m.main-none-eabi-lto.a Binary files differindex 2a761ef..4312c64 100644 --- a/bin/thumbv8m.main-none-eabi-lto.a +++ b/bin/thumbv8m.main-none-eabi-lto.a diff --git a/bin/thumbv8m.main-none-eabi.a b/bin/thumbv8m.main-none-eabi.a Binary files differindex 0e2a886..59affcc 100644 --- a/bin/thumbv8m.main-none-eabi.a +++ b/bin/thumbv8m.main-none-eabi.a diff --git a/bin/thumbv8m.main-none-eabihf-lto.a b/bin/thumbv8m.main-none-eabihf-lto.a Binary files differindex 98326e8..62fcad3 100644 --- a/bin/thumbv8m.main-none-eabihf-lto.a +++ b/bin/thumbv8m.main-none-eabihf-lto.a diff --git a/bin/thumbv8m.main-none-eabihf.a b/bin/thumbv8m.main-none-eabihf.a Binary files differindex 667cce9..f7795d1 100644 --- a/bin/thumbv8m.main-none-eabihf.a +++ b/bin/thumbv8m.main-none-eabihf.a @@ -165,7 +165,7 @@ pub unsafe fn bx_ns(addr: u32) { call_asm!(__bxns(addr: u32)); } -/// Semihosing syscall. +/// Semihosting syscall. /// /// This method is used by cortex-m-semihosting to provide semihosting syscalls. #[inline] @@ -175,15 +175,20 @@ pub unsafe fn sh_syscall(nr: u32, arg: u32) -> u32 { /// Bootstrap. /// -/// Sets the active stack to the main stack, updates the main stack pointer to `msp`, -/// then jumps execution to the address in `rv`. -/// Writes `msp` to the MSP special register, then jumps to the address in `rv`. +/// Clears CONTROL.SPSEL (setting the main stack to be the active stack), +/// updates the main stack pointer to the address in `msp`, then jumps +/// to the address in `rv`. +/// +/// # Safety +/// +/// `msp` and `rv` must point to valid stack memory and executable code, +/// respectively. #[inline] pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! { + // Ensure thumb mode is set. + let rv = (rv as u32) | 1; let msp = msp as u32; - let rv = rv as u32; - call_asm!(__bootstrap(msp: u32, rv: u32)); - core::hint::unreachable_unchecked(); + call_asm!(__bootstrap(msp: u32, rv: u32) -> !); } /// Bootload. @@ -191,14 +196,13 @@ pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! { /// Reads the initial stack pointer value and reset vector from /// the provided vector table address, sets the active stack to /// the main stack, sets the main stack pointer to the new initial -/// stack pointer view, then jumps to the reset vector. +/// stack pointer, then jumps to the reset vector. /// /// # Safety /// /// The provided `vector_table` must point to a valid vector /// table, with a valid stack pointer as the first word and -/// a valid reset vector (in thumb mode, with the least significant -/// bit cleared) as the second word. +/// a valid reset vector as the second word. #[inline] pub unsafe fn bootload(vector_table: *const u32) -> ! { let msp = core::ptr::read_volatile(vector_table); |