Skip to content

Commit 4a1c82f

Browse files
committed
Expose __syscall and add new bootstrap method
1 parent 5910cbe commit 4a1c82f

File tree

4 files changed

+63
-2
lines changed

4 files changed

+63
-2
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- New assembly methods `asm::sh_syscall`, `asm::bootstrap`, and
13+
`asm::bootload`.
14+
1015
## [v0.7.0] - 2020-11-09
1116

1217
### Added

asm/inline.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,11 +177,25 @@ pub unsafe fn __wfi() {
177177

178178
/// Semihosting syscall.
179179
#[inline(always)]
180-
pub unsafe fn __syscall(mut nr: u32, arg: u32) -> u32 {
180+
pub unsafe fn __sh_syscall(mut nr: u32, arg: u32) -> u32 {
181181
asm!("bkpt #0xab", inout("r0") nr, in("r1") arg);
182182
nr
183183
}
184184

185+
/// Bootstrap: ensure we are using the main stack, then write `msp` to MSP and jump to `rv`.
186+
#[inline(always)]
187+
pub unsafe fn __bootstrap(msp: u32, rv: u32) {
188+
asm!(
189+
"msr CONTROL, {}",
190+
"isb",
191+
"msr MSP, {}",
192+
"bx {}",
193+
in(reg) 0,
194+
in(reg) msp,
195+
in(reg) rv,
196+
);
197+
}
198+
185199
// v7m *AND* v8m.main, but *NOT* v8m.base
186200
#[cfg(any(armv7m, armv8m_main))]
187201
pub use self::v7m::*;

asm/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ shims! {
7272
fn __udf();
7373
fn __wfe();
7474
fn __wfi();
75-
fn __syscall(nr: u32, arg: u32) -> u32;
75+
fn __sh_syscall(nr: u32, arg: u32) -> u32;
76+
fn __bootstrap(msp: u32, rv: u32);
7677
}
7778

7879
// v7m *AND* v8m.main, but *NOT* v8m.base

src/asm.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,44 @@ pub fn ttat(addr: *mut u32) -> u32 {
164164
pub unsafe fn bx_ns(addr: u32) {
165165
call_asm!(__bxns(addr: u32));
166166
}
167+
168+
/// Semihosing syscall.
169+
///
170+
/// This method is used by cortex-m-semihosting to provide semihosting syscalls.
171+
#[inline]
172+
pub unsafe fn sh_syscall(nr: u32, arg: u32) -> u32 {
173+
call_asm!(__sh_syscall(nr: u32, arg: u32) -> u32)
174+
}
175+
176+
/// Bootstrap.
177+
///
178+
/// Sets the active stack to the main stack, updates the main stack pointer to `msp`,
179+
/// then jumps execution to the address in `rv`.
180+
/// Writes `msp` to the MSP special register, then jumps to the address in `rv`.
181+
#[inline]
182+
pub unsafe fn bootstrap(msp: *const u32, rv: *const u32) -> ! {
183+
let msp = msp as u32;
184+
let rv = rv as u32;
185+
call_asm!(__bootstrap(msp: u32, rv: u32));
186+
core::hint::unreachable_unchecked();
187+
}
188+
189+
/// Bootload.
190+
///
191+
/// Reads the initial stack pointer value and reset vector from
192+
/// the provided vector table address, sets the active stack to
193+
/// the main stack, sets the main stack pointer to the new initial
194+
/// stack pointer view, then jumps to the reset vector.
195+
///
196+
/// # Safety
197+
///
198+
/// The provided `vector_table` must point to a valid vector
199+
/// table, with a valid stack pointer as the first word and
200+
/// a valid reset vector (in thumb mode, with the least significant
201+
/// bit cleared) as the second word.
202+
#[inline]
203+
pub unsafe fn bootload(vector_table: *const u32) -> ! {
204+
let msp = core::ptr::read_volatile(vector_table);
205+
let rv = core::ptr::read_volatile(vector_table.offset(1));
206+
bootstrap(msp as *const u32, rv as *const u32);
207+
}

0 commit comments

Comments
 (0)