-
Notifications
You must be signed in to change notification settings - Fork 177
Add helper function to enter unprivileged mode #608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
adamgreig
merged 11 commits into
rust-embedded:master
from
thejpster:add-unprivileged-mode
Oct 6, 2025
+212
−17
Merged
Changes from 10 commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
0fe6c4c
Put asm in unsafe block.
thejpster 3acafb3
Enter Unprivileged needs an extern "C" fn
thejpster 27e4745
Add an object you can use to hold the PSP stack.
thejpster 4233ce4
Explain the lint
thejpster 176c74d
Fix PSP example code.
thejpster 7699eef
Update the functions for using the PSP
thejpster 521ebcb
Fixes for Rust 1.61 (the MSRV)
thejpster a951c1f
Fixed the assembly to work on ARMv6-M too.
thejpster 14e748f
Use const control register code instead of magic numbers.
thejpster ecf5ddc
Set the PSPLIM when switching to the PSP on Armv8-M Mainline.
thejpster 155ab85
Update cortex-m/src/psp.rs
adamgreig File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
//! Process Stack Pointer support | ||
|
||
// This is a useful lint for functions like 'asm::wfi()' but it's not a useful | ||
// lint here. | ||
#![allow(clippy::missing_inline_in_public_items)] | ||
|
||
use core::{ | ||
cell::UnsafeCell, | ||
sync::atomic::{AtomicBool, Ordering}, | ||
}; | ||
|
||
/// Represents access to a [`Stack`] | ||
pub struct StackHandle(*mut u32, usize); | ||
|
||
impl StackHandle { | ||
/// Get the pointer to the top of the stack | ||
pub fn top(&mut self) -> *mut u32 { | ||
// SAFETY: The stack was this big when we constructed the handle | ||
unsafe { self.0.add(self.1) } | ||
} | ||
|
||
/// Get the pointer to the top of the stack | ||
pub fn bottom(&mut self) -> *mut u32 { | ||
self.0 | ||
} | ||
} | ||
|
||
/// A stack you can use as your Process Stack (PSP) | ||
/// | ||
/// The const-param N is the size **in 32-bit words** | ||
#[repr(align(8), C)] | ||
pub struct Stack<const N: usize> { | ||
space: UnsafeCell<[u32; N]>, | ||
taken: AtomicBool, | ||
} | ||
|
||
impl<const N: usize> Stack<N> { | ||
/// Const-initialise a Stack | ||
/// | ||
/// Use a turbofish to specify the size, like: | ||
/// | ||
/// ```rust | ||
/// # use cortex_m::psp::Stack; | ||
/// static PSP_STACK: Stack::<4096> = Stack::new(); | ||
/// fn example() { | ||
/// let handle = PSP_STACK.take_handle(); | ||
/// // ... | ||
/// } | ||
/// ``` | ||
pub const fn new() -> Stack<N> { | ||
Stack { | ||
space: UnsafeCell::new([0; N]), | ||
taken: AtomicBool::new(false), | ||
} | ||
} | ||
|
||
/// Return the top of the stack | ||
pub fn take_handle(&self) -> StackHandle { | ||
if self.taken.load(Ordering::Acquire) { | ||
panic!("Cannot get two handles to one stack!"); | ||
} | ||
self.taken.store(true, Ordering::Release); | ||
|
||
let start = self.space.get() as *mut u32; | ||
StackHandle(start, N) | ||
} | ||
} | ||
|
||
unsafe impl<const N: usize> Sync for Stack<N> {} | ||
|
||
impl<const N: usize> core::default::Default for Stack<N> { | ||
fn default() -> Self { | ||
Stack::new() | ||
} | ||
} | ||
|
||
/// Switch to unprivileged mode running on the Process Stack Pointer (PSP) | ||
/// | ||
/// In Unprivileged Mode, code can no longer perform privileged operations, | ||
/// such as disabling interrupts. | ||
/// | ||
#[cfg(cortex_m)] | ||
pub fn switch_to_unprivileged_psp(mut psp_stack: StackHandle, function: extern "C" fn() -> !) -> ! { | ||
// set the stack limit | ||
#[cfg(armv8m_main)] | ||
unsafe { | ||
crate::register::psplim::write(psp_stack.bottom() as u32); | ||
} | ||
// do the switch | ||
unsafe { | ||
crate::asm::enter_unprivileged_psp(psp_stack.top(), function); | ||
} | ||
} | ||
|
||
/// Switch to running on the Process Stack Pointer (PSP), but remain in privileged mode | ||
#[cfg(cortex_m)] | ||
pub fn switch_to_privileged_psp(mut psp_stack: StackHandle, function: extern "C" fn() -> !) -> ! { | ||
// set the stack limit | ||
#[cfg(armv8m_main)] | ||
unsafe { | ||
crate::register::psplim::write(psp_stack.bottom() as u32); | ||
} | ||
// do the switch | ||
unsafe { | ||
crate::asm::enter_privileged_psp(psp_stack.top(), function); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.