Skip to content

Commit f26be34

Browse files
committed
Add enter_unprivileged() function
This adds a function to switch to program stack and unprivileged mode. Fixes rust-embedded#583
1 parent d55d343 commit f26be34

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

cortex-m/src/asm.rs

+28
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,34 @@ pub unsafe fn semihosting_syscall(mut nr: u32, arg: u32) -> u32 {
244244
nr
245245
}
246246

247+
/// Switch to unprivileged mode.
248+
///
249+
/// Sets CONTROL.SPSEL (setting the program stack to be the active
250+
/// stack) and CONTROL.nPRIV (setting unprivileged mode), updates the
251+
/// program stack pointer to the address in `psp`, then jumps to the
252+
/// address in `entry`.
253+
///
254+
/// # Safety
255+
///
256+
/// `psp` and `entry` must point to valid stack memory and executable
257+
/// code, respectively. `psp` must be 8 bytes aligned.
258+
#[cfg(cortex_m)]
259+
#[inline(always)]
260+
pub unsafe fn enter_unprivileged(psp: *const u32, entry: fn() -> !) -> ! {
261+
asm!(
262+
"mrs {tmp}, CONTROL",
263+
"orr {tmp}, #2",
264+
"msr PSP, {psp}",
265+
"msr CONTROL, {tmp}",
266+
"isb",
267+
"bx {ent}",
268+
tmp = in(reg) 0,
269+
psp = in(reg) psp,
270+
ent = in(reg) entry,
271+
options(noreturn, nomem, nostack)
272+
);
273+
}
274+
247275
/// Bootstrap.
248276
///
249277
/// Clears CONTROL.SPSEL (setting the main stack to be the active stack),

0 commit comments

Comments
 (0)