diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm.rs | 45 | ||||
-rw-r--r-- | src/register/msp.rs | 1 |
2 files changed, 46 insertions, 0 deletions
@@ -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); +} diff --git a/src/register/msp.rs b/src/register/msp.rs index 2e8261e..bccc2ae 100644 --- a/src/register/msp.rs +++ b/src/register/msp.rs @@ -8,6 +8,7 @@ pub fn read() -> u32 { /// Writes `bits` to the CPU register #[inline] +#[deprecated = "calling this function invokes Undefined Behavior, consider asm::bootstrap as an alternative"] pub unsafe fn write(bits: u32) { call_asm!(__msp_w(bits: u32)); } |