Skip to content

Commit 8f347b7

Browse files
authored
Merge pull request #594 from kevinbube/new/enter_unprivileged_fn
Add enter_unprivileged() function
2 parents 9632980 + 0ea4eff commit 8f347b7

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

cortex-m/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
88
## [Unreleased]
99

1010
- MSRV is 1.61 to match cortex-m-rt crate
11+
- Add `enter_unprivileged` function to switch to unprivileged mode (on the Process Stack, or `PSP`)
1112

1213
## [v0.7.7] - 2023-01-03
1314

cortex-m/src/asm.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,39 @@ 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 code,
184+
/// respectively.
185+
/// * `psp` must be 8 bytes aligned and point to stack top as stack grows
186+
/// towards lower addresses.
187+
/// * The size of the stack provided here must be large enough for your
188+
/// program - stack overflows are obviously UB. If your processor supports
189+
/// it, you may wish to set the `PSPLIM` register to guard against this.
190+
#[cfg(cortex_m)]
191+
#[inline(always)]
192+
pub unsafe fn enter_unprivileged(psp: *const u32, entry: fn() -> !) -> ! {
193+
core::arch::asm!(
194+
"mrs {tmp}, CONTROL",
195+
"orr {tmp}, #3",
196+
"msr PSP, {psp}",
197+
"msr CONTROL, {tmp}",
198+
"isb",
199+
"bx {ent}",
200+
tmp = in(reg) 0,
201+
psp = in(reg) psp,
202+
ent = in(reg) entry,
203+
options(noreturn, nomem, nostack)
204+
);
205+
}
206+
174207
/// Bootstrap.
175208
///
176209
/// Clears CONTROL.SPSEL (setting the main stack to be the active stack),

0 commit comments

Comments
 (0)