Skip to content

Conversation

thejpster
Copy link
Contributor

Adds a data type for managing a PSP stack, and a function to enter PSP mode using it

Avoids future unsafe-in-unsafe warning,.
The function pointer is branched to by assembly, so we're relying on a
certain ABI.
@thejpster
Copy link
Contributor Author

https://github.com/thejpster/psp-example/blob/main/src/main.rs contains an example showing how to use it.


/// 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() -> !) -> ! {
Copy link
Member

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.

Copy link
Contributor Author

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.

https://developer.arm.com/documentation/dui0646/c/The-Cortex-M7-Processor/Programmers-model/Core-registers?lang=en#BABIFGGB

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe

pub unsafe fn enter_unprivileged(psp: *const u32, entry: fn() -> !) -> ! {
should be called 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.
@thejpster
Copy link
Contributor Author

Updated the demo to match

@thejpster
Copy link
Contributor Author

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

@thejpster
Copy link
Contributor Author

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).
@thejpster
Copy link
Contributor Author

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)
------------------------------------------------------------------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants