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}