Skip to content

Commit 408cb7a

Browse files
committed
feat(port_arm_m): support FPU
1 parent 3c5b7ca commit 408cb7a

File tree

3 files changed

+43
-14
lines changed

3 files changed

+43
-14
lines changed

README.md

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

src/constance_port_arm_m/src/threading.rs

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -229,16 +229,23 @@ impl State {
229229
pp_asm!("
230230
# Save the context of the previous task
231231
#
232-
# [r0 = &running_task, r4-r11 = context, lr = EXC_RETURN]
232+
# [r0 = &running_task, r4-r11 = context,
233+
# s16-s31 = context, lr = EXC_RETURN]
233234
#
234235
# r1 = running_task
235236
# if r1.is_some() {
236-
# r2 = psp as *u32 - 10
237+
# let fpu_active = cfg!(has_fpu) && (lr & FType) == 0;
238+
# r2 = psp as *u32 - if fpu_active { 26 } else { 10 }
237239
# r1.port_task_state.sp = r2
238240
#
239241
# r2[0] = lr (EXC_RETURN)
240242
# r2[1] = control
241-
# r2[2..10] = {r4-r11}
243+
# r2 += 2;
244+
# if fpu_active {
245+
# r2[0..16] = {s16-s31}
246+
# r2 += 16;
247+
# }
248+
# r2[0..8] = {r4-r11}
242249
# }
243250
#
244251
# [r0 = &running_task]
@@ -252,7 +259,12 @@ impl State {
252259
" } "
253260
mrs r2, psp
254261
mrs r3, control
255-
subs r2, #40
262+
subs r2, #40 "
263+
if cfg!(has_fpu) { "
264+
tst lr, #0x10
265+
it eq
266+
subeq r2, #64
267+
" } "
256268
str r2, [r1] "
257269
if cfg!(any(armv6m, armv8m_base)) { "
258270
mov r1, lr
@@ -264,8 +276,12 @@ impl State {
264276
mov r7, r11
265277
stmia r2!, {r4-r7}
266278
" } else { "
267-
strd lr, r3, [r2], #8
268-
stmea r2, {r4-r11}
279+
strd lr, r3, [r2], #8 "
280+
if cfg!(has_fpu) { "
281+
it eq
282+
vstmiaeq r2!, {s16-s31}
283+
" } "
284+
stmia r2, {r4-r11}
269285
" } "
270286
271287
# Choose the next task to run
@@ -284,8 +300,17 @@ impl State {
284300
#
285301
# lr = r2[0]
286302
# control = r2[1]
287-
# {r4-r11} = r2[2..10]
288-
# psp = &r2[10]
303+
# r2 += 2;
304+
#
305+
# let fpu_active = cfg!(has_fpu) && (lr & FType) == 0;
306+
# if fpu_active {
307+
# {s16-s31} = r2[0..16]
308+
# r2 += 16;
309+
# }
310+
#
311+
# {r4-r11} = r2[0..8]
312+
# r2 += 8;
313+
# psp = r2
289314
# } else {
290315
# // The idle task only uses r0-r3, so we can skip most steps
291316
# // in this case
@@ -295,7 +320,7 @@ impl State {
295320
# execution uses the Main Stack.” */
296321
# }
297322
#
298-
# [r4-r11 = context, lr = EXC_RETURN]
323+
# [r4-r11 = context, s16-s31 = context, lr = EXC_RETURN]
299324
300325
ldr r1, [r0] "
301326
if cfg!(armv6m) { "
@@ -316,7 +341,12 @@ impl State {
316341
mov r10, r0
317342
mov r11, r1
318343
" } else { "
319-
ldrd lr, r3, [r2], #8
344+
ldrd lr, r3, [r2], #8 "
345+
if cfg!(has_fpu) { "
346+
tst lr, #0x10
347+
it eq
348+
vldmiaeq r2!, {s16-s31}
349+
" } "
320350
ldmia r2!, {r4-r11}
321351
" } "
322352
msr control, r3
@@ -429,7 +459,6 @@ impl State {
429459
// CONTROL: SPSEL = 1 (Use PSP)
430460
extra_ctx[1] = MaybeUninit::new(0x00000002);
431461
// TODO: Secure context (Armv8-M)
432-
// TODO: Floating point registers
433462
// TODO: PSPLIM
434463

435464
// R4-R11: Uninitialized

src/constance_port_arm_m_test_runner/src/targets.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ pub static TARGETS: &[(&str, &dyn Target)] = &[
4747
"qemu_mps2_an385_v6m",
4848
&OverrideTargetTriple("thumbv6m-none-eabi", QemuMps2An385),
4949
),
50+
// TODO: Add an emulated target of `thumbv7em-none-eabihf`
5051
];
5152

5253
pub struct NucleoF401re;
5354

5455
impl Target for NucleoF401re {
5556
fn target_triple(&self) -> &str {
56-
// TODO: use `eabihf` when FPU is supported by the Arm-M port
57-
"thumbv7em-none-eabi"
57+
"thumbv7em-none-eabihf"
5858
}
5959

6060
fn cargo_features(&self) -> &[&str] {

0 commit comments

Comments
 (0)