-
Notifications
You must be signed in to change notification settings - Fork 175
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
base: master
Are you sure you want to change the base?
Conversation
Avoids future unsafe-in-unsafe warning,.
The function pointer is branched to by assembly, so we're relying on a certain ABI.
https://github.com/thejpster/psp-example/blob/main/src/main.rs contains an example showing how to use it. |
cortex-m/src/psp.rs
Outdated
|
||
/// Switch to running on the PSP | ||
#[cfg(cortex_m)] | ||
pub fn switch_to_psp<const N: usize>(psp_stack: &Stack<N>, function: extern "C" fn() -> !) -> ! { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if switch_to_psp
is the best name, given a) it's a function inside the psp
module already so you'll end up with psp::switch_to_psp()
and b) it also enters unprivileged mode. Maybe it could be a method on Stack
like run()
or run_unprivileged()
or something? Not hugely worried but it's the only thing that jumped out at me from the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, right. It seems CONTROL.nPRIV (select Privileged or Unprivileged Mode) and CONTROL.SPSEL (select Main Stack Pointer or Process Stack Pointer) are orthogonal to each other.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
Line 197 in a3ff54b
pub unsafe fn enter_unprivileged(psp: *const u32, entry: fn() -> !) -> ! { |
enter_unprivileged_with_psp()
and then this function can be psp::enter_unprivileged()
, leaving space for some future psp::switch_stack(psp_stack: &Stack)
.
Now offers both Priv and Unpriv modes, and has a handle to represent ownership of a static Stack object. The load/store check on `Stack::taken` is not perfectly thread safe, but it's probably good enough and doing better requires a critical-section or CAS atomics.
Updated the demo to match |
The asm is not Armv6-M compatible but inline(always) hides the issue and allows the code to build. See https://rust.godbolt.org/z/sYWMGah8b and #t-compiler > inline(always) caused inline assembly to not get checked |
Until I added another function that called the broken function anyway, then it suddently noticed the assembly was wrong |
Turns out we don't check the assembly inside inline(asm) functions until the function is actually called (or referenced).
Tested with https://github.com/thejpster/psp-example $ cargo run --bin unpriv_demo
Compiling cortex-m v0.7.7 (https://github.com/thejpster/cortex-m?branch=add-unprivileged-mode#ef8164b7)
Compiling cortex-m-rt v0.7.5 (https://github.com/thejpster/cortex-m?branch=add-unprivileged-mode#ef8164b7)
Compiling cortex-m-rt-macros v0.7.5 (https://github.com/thejpster/cortex-m?branch=add-unprivileged-mode#ef8164b7)
Compiling defmt-semihosting v0.3.0
Compiling psp-example v0.1.0 (/home/jonathan/Documents/github/thejpster/psp-example)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.45s
Running `/home/jonathan/Documents/github/thejpster/psp-example/./qemu-run.sh target/thumbv7em-none-eabihf/debug/unpriv_demo`
ELF_BINARY=target/thumbv7em-none-eabihf/debug/unpriv_demo
Running on '-cpu cortex-m4 -machine mps2-an386'...
------------------------------------------------------------------------
[INFO ] Using MSP. addr(x) = 203fffc4 (bin/unpriv_demo.rs:17)
[INFO ] PSP stack is at 20000000..20004000 (bin/unpriv_demo.rs:23)
[INFO ] Got SVCall, ptr=20003fec (bin/unpriv_demo.rs:62)
[INFO ] Got SVCall, ptr=20003ff0 (bin/unpriv_demo.rs:62)
[INFO ] Got SVCall, ptr=00000000 (bin/unpriv_demo.rs:62)
[INFO ] Got exit request, leaving now! (bin/unpriv_demo.rs:64)
------------------------------------------------------------------------
$ cargo run --bin priv_demo
Compiling psp-example v0.1.0 (/home/jonathan/Documents/github/thejpster/psp-example)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.07s
Running `/home/jonathan/Documents/github/thejpster/psp-example/./qemu-run.sh target/thumbv7em-none-eabihf/debug/priv_demo`
ELF_BINARY=target/thumbv7em-none-eabihf/debug/priv_demo
Running on '-cpu cortex-m4 -machine mps2-an386'...
------------------------------------------------------------------------
[INFO ] Hello! (bin/priv_demo.rs:14)
[INFO ] Using MSP. addr(x) = 203fffc0 (bin/priv_demo.rs:15)
[INFO ] PSP stack is at 20000000..20004000 (bin/priv_demo.rs:20)
[INFO ] User mode, ptr=203fff74 (bin/priv_demo.rs:31)
------------------------------------------------------------------------ |
Adds a data type for managing a PSP stack, and a function to enter PSP mode using it