@@ -105,7 +105,7 @@ impl State {
105
105
// Safety: Only the port can call this method
106
106
let msp_top = unsafe { System :: interrupt_stack_top ( ) } ;
107
107
108
- llvm_asm ! ( "
108
+ pp_asm ! ( "
109
109
# Reset MSP to the top of the stack, effectively discarding the
110
110
# current context. Beyond this point, this code is considered to be
111
111
# running in the idle task.
@@ -116,9 +116,11 @@ impl State {
116
116
# TODO: Set MSPLIM on Armv8-M
117
117
118
118
# Release CPU Lock
119
- # TODO: Choose the appropriate method based on `CPU_LOCK_PRIORITY_MASK`
120
- mov 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
+ " } "
122
124
cpsie i
123
125
"
124
126
:
@@ -154,13 +156,13 @@ impl State {
154
156
// Pend PendSV
155
157
cortex_m:: peripheral:: SCB :: set_pendsv ( ) ;
156
158
157
- llvm_asm ! ( "
159
+ pp_asm ! ( "
158
160
# Activate the idle task's context by switching the current SP to
159
161
# MSP.
160
162
# `running_task` is `None` at this point, so the processor state
161
163
# will be consistent with `running_task` after this operation.
162
164
mrs r0, control
163
- bic r0, #2
165
+ subs r0, #2
164
166
msr control, r0
165
167
166
168
# Transfer the control to the idle task. We have pended PendSV, so
@@ -171,9 +173,17 @@ impl State {
171
173
# - `CONTROL.SPSEL == 0` (we just set it)
172
174
# - Thread mode (because `exit_and_dispatch` is called in a task
173
175
# 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
+ " }
177
187
:
178
188
: "X" ( Self :: idle_task:: <System > as unsafe extern fn ( ) -> !)
179
189
:
@@ -216,7 +226,7 @@ impl State {
216
226
unsafe { State :: leave_cpu_lock_inner :: < System > ( ) } ;
217
227
}
218
228
219
- llvm_asm ! ( "
229
+ pp_asm ! ( "
220
230
# Save the context of the previous task
221
231
#
222
232
# [r0 = &running_task, r4-r11 = context, lr = EXC_RETURN]
@@ -233,15 +243,32 @@ impl State {
233
243
#
234
244
# [r0 = &running_task]
235
245
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
+ " } "
238
253
mrs r2, psp
239
254
mrs r3, control
240
- sub r2, #40
241
- str r2, [r1]
242
- stm r2, {r4-r11}
243
- str lr, [r2, 32]
244
- str r3, [r2, 36]
255
+ subs r2, #40
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
+ " } "
245
272
246
273
# Choose the next task to run
247
274
ChooseTask:
@@ -272,20 +299,46 @@ impl State {
272
299
#
273
300
# [r4-r11 = context, lr = EXC_RETURN]
274
301
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
- add 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
+ " } "
283
329
msr psp, r2
284
330
bx lr
285
331
286
332
RestoreIdleTask:
287
- mov 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
+ " } "
289
342
msr control, r0
290
343
"
291
344
:
@@ -302,13 +355,15 @@ impl State {
302
355
303
356
#[ inline( always) ]
304
357
unsafe fn enter_cpu_lock_inner < System : PortInstance > ( ) {
358
+ #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
305
359
if System :: CPU_LOCK_PRIORITY_MASK > 0 {
306
360
// Set `BASEPRI` to `CPU_LOCK_PRIORITY_MASK`
307
361
unsafe { cortex_m:: register:: basepri:: write ( System :: CPU_LOCK_PRIORITY_MASK ) } ;
308
- } else {
309
- // Set `PRIMASK` to `1`
310
- cortex_m:: interrupt:: disable ( ) ;
362
+ return ;
311
363
}
364
+
365
+ // Set `PRIMASK` to `1`
366
+ cortex_m:: interrupt:: disable ( ) ;
312
367
}
313
368
314
369
#[ inline( always) ]
@@ -318,13 +373,15 @@ impl State {
318
373
319
374
#[ inline( always) ]
320
375
unsafe fn leave_cpu_lock_inner < System : PortInstance > ( ) {
376
+ #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
321
377
if System :: CPU_LOCK_PRIORITY_MASK > 0 {
322
378
// Set `BASEPRI` to `0` (no masking)
323
379
unsafe { cortex_m:: register:: basepri:: write ( 0 ) } ;
324
- } else {
325
- // Set `PRIMASK` to `0`
326
- unsafe { cortex_m:: interrupt:: enable ( ) } ;
380
+ return ;
327
381
}
382
+
383
+ // Set `PRIMASK` to `0`
384
+ unsafe { cortex_m:: interrupt:: enable ( ) } ;
328
385
}
329
386
330
387
pub unsafe fn initialize_task_state < System : PortInstance > (
@@ -396,11 +453,12 @@ impl State {
396
453
397
454
#[ inline( always) ]
398
455
pub fn is_cpu_lock_active < System : PortInstance > ( & self ) -> bool {
456
+ #[ cfg( not( any( armv6m, armv8m_base) ) ) ]
399
457
if System :: CPU_LOCK_PRIORITY_MASK > 0 {
400
- cortex_m:: register:: basepri:: read ( ) != 0
401
- } else {
402
- cortex_m:: register:: primask:: read ( ) . is_inactive ( )
458
+ return cortex_m:: register:: basepri:: read ( ) != 0 ;
403
459
}
460
+
461
+ cortex_m:: register:: primask:: read ( ) . is_inactive ( )
404
462
}
405
463
406
464
pub fn is_task_context < System : PortInstance > ( & self ) -> bool {
@@ -540,15 +598,17 @@ pub union InterruptHandler {
540
598
defined : constance:: kernel:: cfg:: InterruptHandlerFn ,
541
599
}
542
600
543
- pub type InterruptHandlerTable = [ InterruptHandler ; 240 ] ;
601
+ const NUM_INTERRUPTS : usize = if cfg ! ( armv6m) { 32 } else { 240 } ;
602
+
603
+ pub type InterruptHandlerTable = [ InterruptHandler ; NUM_INTERRUPTS ] ;
544
604
545
605
/// Used by `use_port!`
546
606
pub const fn make_interrupt_handler_table < System : PortInstance > ( ) -> InterruptHandlerTable
547
607
where
548
608
// FIXME: Work-around for <https://github.com/rust-lang/rust/issues/43475>
549
609
System :: TaskReadyQueue : core:: borrow:: BorrowMut < [ StaticListHead < TaskCb < System > > ] > ,
550
610
{
551
- let mut table = [ InterruptHandler { undefined : 0 } ; 240 ] ;
611
+ let mut table = [ InterruptHandler { undefined : 0 } ; NUM_INTERRUPTS ] ;
552
612
let mut i = 0 ;
553
613
554
614
// FIXME: Work-around for `for` being unsupported in `const fn`
@@ -579,3 +639,13 @@ where
579
639
580
640
table
581
641
}
642
+
643
+ /// Used by `use_port!`
644
+ pub const fn validate < System : PortInstance > ( ) {
645
+ #[ cfg( any( armv6m, armv8m_base) ) ]
646
+ assert ! (
647
+ System :: CPU_LOCK_PRIORITY_MASK == 0 ,
648
+ "`CPU_LOCK_PRIORITY_MASK` must be zero because the target architecture \
649
+ does not have a BASEPRI register"
650
+ ) ;
651
+ }
0 commit comments