aboutsummaryrefslogtreecommitdiff
path: root/src
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 /src
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 'src')
-rw-r--r--src/asm.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/asm.rs b/src/asm.rs
index 8f23aa9..297198b 100644
--- a/src/asm.rs
+++ b/src/asm.rs
@@ -164,3 +164,48 @@ pub fn ttat(addr: *mut u32) -> u32 {
pub unsafe fn bx_ns(addr: u32) {
call_asm!(__bxns(addr: u32));
}
+
+/// Semihosting syscall.
+///
+/// This method is used by cortex-m-semihosting to provide semihosting syscalls.
+#[inline]
+pub unsafe fn semihosting_syscall(nr: u32, arg: u32) -> u32 {
+ call_asm!(__sh_syscall(nr: u32, arg: u32) -> u32)
+}
+
+/// Bootstrap.
+///
+/// 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;
+ call_asm!(__bootstrap(msp: u32, rv: u32) -> !);
+}
+
+/// Bootload.
+///
+/// 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, 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 as the second word.
+#[inline]
+pub unsafe fn bootload(vector_table: *const u32) -> ! {
+ let msp = core::ptr::read_volatile(vector_table);
+ let rv = core::ptr::read_volatile(vector_table.offset(1));
+ bootstrap(msp as *const u32, rv as *const u32);
+}