embedded_threads/arch/
cortex_m.rs

1use core::arch::asm;
2pub use cortex_m::interrupt::{self, CriticalSection, Mutex};
3use cortex_m::peripheral::SCB;
4
5use crate::sched;
6
7pub fn schedule() {
8    SCB::set_pendsv();
9    cortex_m::asm::isb();
10}
11
12#[inline(always)]
13pub(crate) fn start_threading(next_sp: usize) {
14    unsafe {
15        asm!(
16            "
17            msr psp, r1 // set new thread's SP to PSP
18            svc 0       // SVC 0 handles switching
19            ",
20        in("r1")next_sp);
21    }
22}
23
24#[naked]
25#[no_mangle]
26#[allow(non_snake_case)]
27unsafe extern "C" fn SVCall() {
28    asm!(
29        "
30            movw LR, #0xFFFd
31            movt LR, #0xFFFF
32            bx lr
33            ",
34        options(noreturn)
35    );
36}
37
38#[naked]
39#[no_mangle]
40#[allow(non_snake_case)]
41unsafe extern "C" fn PendSV() {
42    asm!(
43        "
44            mrs r0, psp
45            cpsid i
46            bl {sched}
47            cpsie i
48            cmp r0, #0
49            /* label rules:
50             * - number only
51             * - no combination of *only* [01]
52             * - add f or b for 'next matching forward/backward'
53             * so let's use '99' forward ('99f')
54             */
55            beq 99f
56            stmia r0, {{r4-r11}}
57            ldmia r1, {{r4-r11}}
58            msr.n psp, r2
59            99:
60            movw LR, #0xFFFd
61            movt LR, #0xFFFF
62            bx LR
63            ",
64        sched = sym sched,
65        options(noreturn)
66    );
67}