Skip to content

Commit 539bce1

Browse files
kevinbubejonathanpallant
authored andcommitted
Add enter_unprivileged() function
This adds a function to switch to program stack and unprivileged mode. Fixes #583
1 parent 9632980 commit 539bce1

File tree

1 file changed

+29
-0
lines changed

1 file changed

+29
-0
lines changed

cortex-m/src/asm.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,35 @@ pub unsafe fn semihosting_syscall(nr: u32, arg: u32) -> u32 {
171171
call_asm!(__sh_syscall(nr: u32, arg: u32) -> u32)
172172
}
173173

174+
/// Switch to unprivileged mode.
175+
///
176+
/// Sets CONTROL.SPSEL (setting the program stack to be the active
177+
/// stack) and CONTROL.nPRIV (setting unprivileged mode), updates the
178+
/// program stack pointer to the address in `psp`, then jumps to the
179+
/// address in `entry`.
180+
///
181+
/// # Safety
182+
///
183+
/// `psp` and `entry` must point to valid stack memory and executable
184+
/// code, respectively. `psp` must be 8 bytes aligned and point to
185+
/// stack top as stack grows towards lower addresses.
186+
#[cfg(cortex_m)]
187+
#[inline(always)]
188+
pub unsafe fn enter_unprivileged(psp: *const u32, entry: fn() -> !) -> ! {
189+
asm!(
190+
"mrs {tmp}, CONTROL",
191+
"orr {tmp}, #3",
192+
"msr PSP, {psp}",
193+
"msr CONTROL, {tmp}",
194+
"isb",
195+
"bx {ent}",
196+
tmp = in(reg) 0,
197+
psp = in(reg) psp,
198+
ent = in(reg) entry,
199+
options(noreturn, nomem, nostack)
200+
);
201+
}
202+
174203
/// Bootstrap.
175204
///
176205
/// Clears CONTROL.SPSEL (setting the main stack to be the active stack),

0 commit comments

Comments
 (0)