aboutsummaryrefslogtreecommitdiff
path: root/asm/inline.rs
diff options
context:
space:
mode:
authorGravatar bors[bot] <26634292+bors[bot]@users.noreply.github.com> 2020-12-02 15:19:30 +0000
committerGravatar GitHub <noreply@github.com> 2020-12-02 15:19:30 +0000
commit038396e6f944fb8697e2d4ecbd88cfca9d16b90e (patch)
tree7eb1e4514b8159b7e1657626dc27a45131b227b9 /asm/inline.rs
parentd34b1ce3eda92777ba9bafe2fca96e1985ec6d72 (diff)
parent64842461ba4caa384487ae52cbe15a4f3834b4b4 (diff)
downloadcortex-m-038396e6f944fb8697e2d4ecbd88cfca9d16b90e.tar.gz
cortex-m-038396e6f944fb8697e2d4ecbd88cfca9d16b90e.tar.zst
cortex-m-038396e6f944fb8697e2d4ecbd88cfca9d16b90e.zip
Merge #299
299: Expose __syscall and add new bootstrap method r=jonas-schievink a=adamgreig We added `__syscall` in the new inline asm, but did not expose it in the crate API, and the cortex-m-semihosting crate can't use it directly because the pre-built binaries would contain duplicate symbols (#271). This PR renames it to `__sh_syscall` (since we could imagine other different syscalls; this one is explicitly semihosting with the `bkpt 0xAB`) and exposes it in `cortex_m::asm::sh_syscall`. This PR also adds the new methods discussed in #297 to permit sound bootstrapping, either from an MSP and RV or a vector table address. Co-authored-by: Adam Greig <adam@adamgreig.com>
Diffstat (limited to 'asm/inline.rs')
-rw-r--r--asm/inline.rs22
1 files changed, 21 insertions, 1 deletions
diff --git a/asm/inline.rs b/asm/inline.rs
index f6a3ebb..f2014f8 100644
--- a/asm/inline.rs
+++ b/asm/inline.rs
@@ -177,11 +177,31 @@ pub unsafe fn __wfi() {
/// Semihosting syscall.
#[inline(always)]
-pub unsafe fn __syscall(mut nr: u32, arg: u32) -> u32 {
+pub unsafe fn __sh_syscall(mut nr: u32, arg: u32) -> u32 {
asm!("bkpt #0xab", inout("r0") nr, in("r1") arg);
nr
}
+/// Set CONTROL.SPSEL to 0, write `msp` to MSP, branch to `rv`.
+#[inline(always)]
+pub unsafe fn __bootstrap(msp: u32, rv: u32) -> ! {
+ asm!(
+ "mrs {tmp}, CONTROL",
+ "bics {tmp}, {spsel}",
+ "msr CONTROL, {tmp}",
+ "isb",
+ "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),
+ );
+}
+
// v7m *AND* v8m.main, but *NOT* v8m.base
#[cfg(any(armv7m, armv8m_main))]
pub use self::v7m::*;