Skip to content

Commit 67e95fe

Browse files
committed
feat(port_arm_m): support Armv6-M
1 parent 70e411b commit 67e95fe

File tree

5 files changed

+381
-28
lines changed

5 files changed

+381
-28
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Constance is a proof-of-concept of a static RTOS that utilizes Rust's compile-ti
2323
| :--------------- | :-------------- | :----------------- |
2424
| ☑︎ Tasks |`Mutex` | ☑︎ `std` (Hosted) |
2525
| ☑︎ Hunks |`RwLock` | ☑︎ Armv7-M (no FPU) |
26-
| ☑︎ Wait Objects |`Once` | |
26+
| ☑︎ Wait Objects |`Once` | ☑︎ Armv6-M |
2727
| ☑︎ Timeouts | ☐ Logger | |
2828
| ☐ Semaphores | ☐ C API | |
2929
| ☑︎ Event Groups | | |

src/constance_port_arm_m/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![feature(external_doc)]
22
#![feature(const_fn)]
33
#![feature(llvm_asm)]
4+
#![feature(decl_macro)]
45
#![feature(const_panic)]
56
#![feature(const_generics)]
67
#![feature(slice_ptr_len)]

src/constance_port_arm_m/src/threading.rs

Lines changed: 82 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ impl State {
105105
// Safety: Only the port can call this method
106106
let msp_top = unsafe { System::interrupt_stack_top() };
107107

108-
llvm_asm!("
108+
pp_asm!("
109109
# Reset MSP to the top of the stack, effectively discarding the
110110
# current context. Beyond this point, this code is considered to be
111111
# running in the idle task.
@@ -116,9 +116,11 @@ impl State {
116116
# TODO: Set MSPLIM on Armv8-M
117117
118118
# Release CPU Lock
119-
# TODO: Choose the appropriate method based on `CPU_LOCK_PRIORITY_MASK`
120-
movs r0, #0
121-
msr basepri, r0
119+
# TODO: Choose the appropriate method based on `CPU_LOCK_PRIORITY_MASK` "
120+
if cfg!(not(any(armv6m, armv8m_base))) { "
121+
movs r0, #0
122+
msr basepri, r0
123+
" } "
122124
cpsie i
123125
"
124126
:
@@ -154,7 +156,7 @@ impl State {
154156
// Pend PendSV
155157
cortex_m::peripheral::SCB::set_pendsv();
156158

157-
llvm_asm!("
159+
pp_asm!("
158160
# Activate the idle task's context by switching the current SP to
159161
# MSP.
160162
# `running_task` is `None` at this point, so the processor state
@@ -171,9 +173,17 @@ impl State {
171173
# - `CONTROL.SPSEL == 0` (we just set it)
172174
# - Thread mode (because `exit_and_dispatch` is called in a task
173175
# context),
174-
# - CPU Lock active (`exit_and_dispatch`'s requirement)
175-
b $0
176-
"
176+
# - CPU Lock active (`exit_and_dispatch`'s requirement) "
177+
if cfg!(armv6m) { "
178+
ldr r0, IdleTaskConst
179+
bx r0
180+
181+
.align 2
182+
IdleTaskConst:
183+
.word $0
184+
" } else { "
185+
b $0
186+
" }
177187
:
178188
: "X"(Self::idle_task::<System> as unsafe extern fn() -> !)
179189
:
@@ -216,7 +226,7 @@ impl State {
216226
unsafe { State::leave_cpu_lock_inner::<System>() };
217227
}
218228

219-
llvm_asm!("
229+
pp_asm!("
220230
# Save the context of the previous task
221231
#
222232
# [r0 = &running_task, r4-r11 = context, lr = EXC_RETURN]
@@ -233,15 +243,32 @@ impl State {
233243
#
234244
# [r0 = &running_task]
235245
236-
ldr r1, [r0]
237-
cbz r1, ChooseTask
246+
ldr r1, [r0] "
247+
if cfg!(armv6m) { "
248+
cmp r1, #0
249+
beq ChooseTask
250+
" } else { "
251+
cbz r1, ChooseTask
252+
" } "
238253
mrs r2, psp
239254
mrs r3, control
240255
subs r2, #40
241-
str r2, [r1]
242-
stm r2, {r4-r11}
243-
str lr, [r2, 32]
244-
str r3, [r2, 36]
256+
str r2, [r1] "
257+
if cfg!(any(armv6m, armv8m_base)) { "
258+
stm r2!, {r4-r7}
259+
mov r4, r8
260+
mov r5, r9
261+
mov r6, r10
262+
mov r7, r11
263+
stm r2!, {r4-r7}
264+
mov r4, lr
265+
str r4, [r2]
266+
str r3, [r2, 4]
267+
" } else { "
268+
stm r2, {r4-r11}
269+
str lr, [r2, 32]
270+
str r3, [r2, 36]
271+
" } "
245272
246273
# Choose the next task to run
247274
ChooseTask:
@@ -272,20 +299,46 @@ impl State {
272299
#
273300
# [r4-r11 = context, lr = EXC_RETURN]
274301
275-
ldr r1, [r0]
276-
cbz r1, RestoreIdleTask
277-
ldr r2, [r1]
278-
ldr lr, [r2, 32]
279-
ldr r3, [r2, 36]
280-
msr control, r3
281-
ldmia r2, {r4-r11}
282-
adds r2, #40
302+
ldr r1, [r0] "
303+
if cfg!(armv6m) { "
304+
cmp r1, #0
305+
beq RestoreIdleTask
306+
" } else { "
307+
cbz r1, RestoreIdleTask
308+
" } "
309+
ldr r2, [r1] "
310+
if cfg!(any(armv6m, armv8m_base)) { "
311+
adds r2, #16
312+
ldmia r2!, {r4-r7}
313+
mov r8, r4
314+
mov r9, r5
315+
mov r10, r6
316+
mov r11, r7
317+
subs r2, #32
318+
ldmia r2!, {r4-r7}
319+
adds r2, #16
320+
ldmia r2!, {r0, r3}
321+
mov lr, r0
322+
" } else { "
323+
ldr lr, [r2, 32]
324+
ldr r3, [r2, 36]
325+
msr control, r3
326+
ldmia r2, {r4-r11}
327+
adds r2, #40
328+
" } "
283329
msr psp, r2
284330
bx lr
285331
286332
RestoreIdleTask:
287-
movs r0, #0
288-
mov lr, #0xfffffff9
333+
movs r0, #0 "
334+
if cfg!(any(armv6m, armv8m_base)) { "
335+
# 0x00000006 = !0xfffffff9
336+
movs r1, #6
337+
mvns r1, r1
338+
mov lr, r1
339+
" } else { "
340+
mov lr, #0xfffffff9
341+
" } "
289342
msr control, r0
290343
"
291344
:
@@ -545,15 +598,17 @@ pub union InterruptHandler {
545598
defined: constance::kernel::cfg::InterruptHandlerFn,
546599
}
547600

548-
pub type InterruptHandlerTable = [InterruptHandler; 240];
601+
const NUM_INTERRUPTS: usize = if cfg!(armv6m) { 32 } else { 240 };
602+
603+
pub type InterruptHandlerTable = [InterruptHandler; NUM_INTERRUPTS];
549604

550605
/// Used by `use_port!`
551606
pub const fn make_interrupt_handler_table<System: PortInstance>() -> InterruptHandlerTable
552607
where
553608
// FIXME: Work-around for <https://github.com/rust-lang/rust/issues/43475>
554609
System::TaskReadyQueue: core::borrow::BorrowMut<[StaticListHead<TaskCb<System>>]>,
555610
{
556-
let mut table = [InterruptHandler { undefined: 0 }; 240];
611+
let mut table = [InterruptHandler { undefined: 0 }; NUM_INTERRUPTS];
557612
let mut i = 0;
558613

559614
// FIXME: Work-around for `for` being unsupported in `const fn`

src/constance_port_arm_m/src/utils.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
//! otherwise. It's exposed only because it's needed by macros.
55
use core::marker::PhantomData;
66

7+
#[macro_use]
8+
mod pptext;
9+
710
/// Conditional type
811
macro_rules! If {
912
( if ($cond:expr) { $t:ty } else { $f:ty } ) => {

0 commit comments

Comments
 (0)