Skip to content

Commit 44567f6

Browse files
authored
Save/restore coprocessor state on stack (#2057)
* Whitespace * Save and restore coprocessor enable state
1 parent c5e342a commit 44567f6

File tree

1 file changed

+72
-69
lines changed
  • xtensa-lx-rt/src/exception

1 file changed

+72
-69
lines changed

xtensa-lx-rt/src/exception/asm.rs

Lines changed: 72 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ use crate::cfg_asm;
1111
// Additionally there is a chunk of memory reserved for spilled registers.
1212
global_asm!(
1313
"
14-
.set XT_STK_PC, 0
15-
.set XT_STK_PS, 4
16-
.set XT_STK_A0, 8
17-
.equ XT_STK_A1, 12
18-
.set XT_STK_A2, 16
19-
.set XT_STK_A3, 20
20-
.set XT_STK_A4, 24
21-
.set XT_STK_A5, 28
22-
.set XT_STK_A6, 32
23-
.set XT_STK_A7, 36
24-
.set XT_STK_A8, 40
25-
.set XT_STK_A9, 44
26-
.set XT_STK_A10, 48
27-
.set XT_STK_A11, 52
28-
.set XT_STK_A12, 56
29-
.set XT_STK_A13, 60
30-
.set XT_STK_A14, 64
31-
.set XT_STK_A15, 68
32-
.set XT_STK_SAR, 72
14+
.set XT_STK_PC, 0
15+
.set XT_STK_PS, 4
16+
.set XT_STK_A0, 8
17+
.equ XT_STK_A1, 12
18+
.set XT_STK_A2, 16
19+
.set XT_STK_A3, 20
20+
.set XT_STK_A4, 24
21+
.set XT_STK_A5, 28
22+
.set XT_STK_A6, 32
23+
.set XT_STK_A7, 36
24+
.set XT_STK_A8, 40
25+
.set XT_STK_A9, 44
26+
.set XT_STK_A10, 48
27+
.set XT_STK_A11, 52
28+
.set XT_STK_A12, 56
29+
.set XT_STK_A13, 60
30+
.set XT_STK_A14, 64
31+
.set XT_STK_A15, 68
32+
.set XT_STK_SAR, 72
3333
.set XT_STK_EXCCAUSE, 76
3434
.set XT_STK_EXCVADDR, 80
3535
.set XT_STK_LBEG, 84 // Registers for Loop Option
@@ -66,6 +66,7 @@ global_asm!(
6666
.set XT_STK_F14, 208
6767
.set XT_STK_F15, 212
6868
.set XT_STK_TMP, 216
69+
.set XT_STK_CPENABLE, 220
6970
7071
.set XT_STK_FRMSZ, 256 // needs to be multiple of 16 and enough additional free space
7172
// for the registers spilled to the stack (max 8 registers / 0x20 bytes)
@@ -126,6 +127,8 @@ unsafe extern "C" fn save_context() {
126127
#[cfg(all(XCHAL_HAVE_CP, not(feature = "float-save-restore")))]
127128
"
128129
/* Disable coprocessor, any use of floats in ISRs will cause an exception unless float-save-restore feature is enabled */
130+
rsr a3, CPENABLE
131+
s32i a3, sp, +XT_STK_CPENABLE
129132
movi a3, 0
130133
wsr a3, CPENABLE
131134
rsync
@@ -177,11 +180,11 @@ unsafe extern "C" fn save_context() {
177180
#[cfg(all(feature = "float-save-restore", XCHAL_HAVE_DFP_ACCEL))]
178181
"
179182
// Double Precision Accelerator Option
180-
rur a3, f64r_lo
183+
rur a3, f64r_lo
181184
s32i a3, sp, +XT_STK_F64R_LO
182185
rur a3, f64r_hi
183186
s32i a3, sp, +XT_STK_F64R_HI
184-
rur a3, f64s
187+
rur a3, f64s
185188
s32i a3, sp, +XT_STK_F64S
186189
",
187190
#[cfg(all(feature = "float-save-restore", XCHAL_HAVE_FP))]
@@ -226,7 +229,7 @@ unsafe extern "C" fn save_context() {
226229
// used as a temporary by this code, the temporary value would get stored
227230
// onto the stack, instead of the real value.
228231
//
229-
232+
230233
rsr a2, PS // to be restored after SPILL_REGISTERS
231234
movi a0, PS_INTLEVEL_MASK
232235
and a3, a2, a0 // get the current INTLEVEL
@@ -237,11 +240,11 @@ unsafe extern "C" fn save_context() {
237240
or a3, a3, a0
238241
wsr a3, ps
239242
rsr a0, EPC1
240-
243+
241244
addmi sp, sp, +XT_STK_FRMSZ // go back to spill register region
242245
SPILL_REGISTERS
243246
addmi sp, sp, -XT_STK_FRMSZ // return the current stack pointer
244-
247+
245248
wsr a2, PS // restore to the value at entry
246249
rsync
247250
wsr a0, EPC1
@@ -288,9 +291,9 @@ global_asm!(
288291
// file on an LX6 core (ESP-32) I'm measuring 145 cycles to spill
289292
// registers with this vs. 279 (!) to do it with
290293
// xthal_spill_windows().
291-
294+
292295
.macro SPILL_REGISTERS
293-
and a12, a12, a12
296+
and a12, a12, a12
294297
rotw 3
295298
and a12, a12, a12
296299
rotw 3
@@ -311,10 +314,10 @@ global_asm!(
311314
addmi sp, sp, -XT_STK_FRMSZ // only allow multiple of 256
312315
313316
s32i a0, sp, +XT_STK_A1 // save interruptee's A1/SP
314-
s32e a0, sp, -12 // for debug backtrace
317+
s32e a0, sp, -12 // for debug backtrace
315318
316319
.ifc \level,1
317-
rsr a0, PS
320+
rsr a0, PS
318321
s32i a0, sp, +XT_STK_PS // save interruptee's PS
319322
320323
rsr a0, EXCCAUSE
@@ -323,15 +326,15 @@ global_asm!(
323326
s32i a0, sp, +XT_STK_EXCVADDR
324327
.else
325328
rsr a0, EPS\level
326-
s32i a0, sp, +XT_STK_PS // save interruptee's PS
329+
s32i a0, sp, +XT_STK_PS // save interruptee's PS
327330
.endif
328331
329-
rsr a0, EPC\level
330-
s32i a0, sp, +XT_STK_PC // save interruptee's PC
331-
s32e a0, sp, -16 // for debug backtrace
332+
rsr a0, EPC\level
333+
s32i a0, sp, +XT_STK_PC // save interruptee's PC
334+
s32e a0, sp, -16 // for debug backtrace
332335
333-
rsr a0, EXCSAVE\level
334-
s32i a0, sp, +XT_STK_A0 // save interruptee's A0
336+
rsr a0, EXCSAVE\level
337+
s32i a0, sp, +XT_STK_A0 // save interruptee's A0
335338
336339
call0 save_context
337340
@@ -429,8 +432,8 @@ unsafe extern "C" fn restore_context() {
429432
",
430433
#[cfg(all(XCHAL_HAVE_CP, not(feature = "float-save-restore")))]
431434
"
432-
/* Re-enable coprocessor(s) after ISR */
433-
movi a3, 8 /* XCHAL_CP_MAXCFG */
435+
/* Restore coprocessor state after ISR */
436+
l32i a3, sp, +XT_STK_CPENABLE
434437
wsr a3, CPENABLE
435438
rsync
436439
",
@@ -458,26 +461,26 @@ unsafe extern "C" fn restore_context() {
458461
global_asm!(
459462
r#"
460463
.macro RESTORE_CONTEXT level:req
461-
462-
// Restore context and return
464+
465+
// Restore context and return
463466
call0 restore_context
464467
465468
.ifc \level,1
466-
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
469+
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
467470
wsr a0, PS
468-
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
471+
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
469472
wsr a0, EPC\level
470473
.else
471-
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
474+
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
472475
wsr a0, EPS\level
473-
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
474-
wsr a0, EPC\level
475-
.endif
476-
477-
l32i a0, sp, +XT_STK_A0 // retrieve interruptee's A0
478-
l32i sp, sp, +XT_STK_A1 // remove exception frame
479-
rsync // ensure PS and EPC written
480-
476+
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
477+
wsr a0, EPC\level
478+
.endif
479+
480+
l32i a0, sp, +XT_STK_A0 // retrieve interruptee's A0
481+
l32i sp, sp, +XT_STK_A1 // remove exception frame
482+
rsync // ensure PS and EPC written
483+
481484
.endm
482485
"#
483486
);
@@ -518,8 +521,8 @@ unsafe extern "C" fn __default_naked_exception() {
518521
519522
.RestoreContext:
520523
RESTORE_CONTEXT 1
521-
522-
rfe // PS.EXCM is cleared
524+
525+
rfe // PS.EXCM is cleared
523526
",
524527
options(noreturn)
525528
)
@@ -539,44 +542,44 @@ unsafe extern "C" fn __default_naked_double_exception() {
539542
"
540543
mov a0, a1 // save a1/sp
541544
addmi sp, sp, -XT_STK_FRMSZ // only allow multiple of 256
542-
545+
543546
s32i a0, sp, +XT_STK_A1 // save interruptee's A1/SP
544-
s32e a0, sp, -12 // for debug backtrace
545-
546-
rsr a0, PS
547+
s32e a0, sp, -12 // for debug backtrace
548+
549+
rsr a0, PS
547550
s32i a0, sp, +XT_STK_PS // save interruptee's PS
548-
551+
549552
rsr a0, EXCCAUSE
550553
s32i a0, sp, +XT_STK_EXCCAUSE
551554
rsr a0, EXCVADDR
552555
s32i a0, sp, +XT_STK_EXCVADDR
553-
554-
rsr a0, DEPC
555-
s32i a0, sp, +XT_STK_PC // save interruptee's PC
556-
s32e a0, sp, -16 // for debug backtrace
557-
556+
557+
rsr a0, DEPC
558+
s32i a0, sp, +XT_STK_PC // save interruptee's PC
559+
s32e a0, sp, -16 // for debug backtrace
560+
558561
rsr a0, EXCSAVE7 // ok to reuse EXCSAVE7 for double exception as long as
559562
// double exception is not in first couple of instructions
560563
// of level 7 handler
561-
s32i a0, sp, +XT_STK_A0 // save interruptee's A0
562-
564+
s32i a0, sp, +XT_STK_A0 // save interruptee's A0
565+
563566
call0 save_context
564567
565568
l32i a6, sp, +XT_STK_EXCCAUSE // put cause in a6 = a2 in callee
566569
mov a7, sp // put address of save frame in a7=a3 in callee
567570
call4 __exception // call handler <= actual call!
568571
569-
// Restore context and return
572+
// Restore context and return
570573
call0 restore_context
571574
572-
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
575+
l32i a0, sp, +XT_STK_PS // retrieve interruptee's PS
573576
wsr a0, PS
574-
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
577+
l32i a0, sp, +XT_STK_PC // retrieve interruptee's PC
575578
wsr a0, EPC1
576579
577-
l32i a0, sp, +XT_STK_A0 // retrieve interruptee's A0
578-
l32i sp, sp, +XT_STK_A1 // remove exception frame
579-
rsync // ensure PS and EPC written
580+
l32i a0, sp, +XT_STK_A0 // retrieve interruptee's A0
581+
l32i sp, sp, +XT_STK_A1 // remove exception frame
582+
rsync // ensure PS and EPC written
580583
581584
rfde
582585
",

0 commit comments

Comments
 (0)