Skip to content

Commit fb53bc2

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

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

cortex-m/src/asm.rs

+29
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,35 @@ 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 and point to
258+
/// stack top as stack grows towards lower addresses.
259+
#[cfg(cortex_m)]
260+
#[inline(always)]
261+
pub unsafe fn enter_unprivileged(psp: *const u32, entry: fn() -> !) -> ! {
262+
asm!(
263+
"mrs {tmp}, CONTROL",
264+
"orr {tmp}, #3",
265+
"msr PSP, {psp}",
266+
"msr CONTROL, {tmp}",
267+
"isb",
268+
"bx {ent}",
269+
tmp = in(reg) 0,
270+
psp = in(reg) psp,
271+
ent = in(reg) entry,
272+
options(noreturn, nomem, nostack)
273+
);
274+
}
275+
247276
/// Bootstrap.
248277
///
249278
/// Clears CONTROL.SPSEL (setting the main stack to be the active stack),

0 commit comments

Comments
 (0)