|
@@ -196,7 +196,7 @@
|
|
|
msr cpsr_c, \rtemp @ switch back to the SVC mode
|
|
|
.endm
|
|
|
|
|
|
-#ifndef CONFIG_THUMB2_KERNEL
|
|
|
+
|
|
|
.macro svc_exit, rpsr, irq = 0
|
|
|
.if \irq != 0
|
|
|
@ IRQs already off
|
|
@@ -215,6 +215,9 @@
|
|
|
blne trace_hardirqs_off
|
|
|
#endif
|
|
|
.endif
|
|
|
+
|
|
|
+#ifndef CONFIG_THUMB2_KERNEL
|
|
|
+ @ ARM mode SVC restore
|
|
|
msr spsr_cxsf, \rpsr
|
|
|
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
|
|
|
@ We must avoid clrex due to Cortex-A15 erratum #830321
|
|
@@ -222,6 +225,20 @@
|
|
|
strex r1, r2, [r0] @ clear the exclusive monitor
|
|
|
#endif
|
|
|
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
|
|
|
+#else
|
|
|
+ @ Thumb mode SVC restore
|
|
|
+ ldr lr, [sp, #S_SP] @ top of the stack
|
|
|
+ ldrd r0, r1, [sp, #S_LR] @ calling lr and pc
|
|
|
+
|
|
|
+ @ We must avoid clrex due to Cortex-A15 erratum #830321
|
|
|
+ strex r2, r1, [sp, #S_LR] @ clear the exclusive monitor
|
|
|
+
|
|
|
+ stmdb lr!, {r0, r1, \rpsr} @ calling lr and rfe context
|
|
|
+ ldmia sp, {r0 - r12}
|
|
|
+ mov sp, lr
|
|
|
+ ldr lr, [sp], #4
|
|
|
+ rfeia sp!
|
|
|
+#endif
|
|
|
.endm
|
|
|
|
|
|
@
|
|
@@ -241,6 +258,8 @@
|
|
|
@ on the stack remains correct).
|
|
|
@
|
|
|
.macro svc_exit_via_fiq
|
|
|
+#ifndef CONFIG_THUMB2_KERNEL
|
|
|
+ @ ARM mode restore
|
|
|
mov r0, sp
|
|
|
ldmib r0, {r1 - r14} @ abort is deadly from here onward (it will
|
|
|
@ clobber state restored below)
|
|
@@ -250,9 +269,26 @@
|
|
|
msr spsr_cxsf, r9
|
|
|
ldr r0, [r0, #S_R0]
|
|
|
ldmia r8, {pc}^
|
|
|
+#else
|
|
|
+ @ Thumb mode restore
|
|
|
+ add r0, sp, #S_R2
|
|
|
+ ldr lr, [sp, #S_LR]
|
|
|
+ ldr sp, [sp, #S_SP] @ abort is deadly from here onward (it will
|
|
|
+ @ clobber state restored below)
|
|
|
+ ldmia r0, {r2 - r12}
|
|
|
+ mov r1, #FIQ_MODE | PSR_I_BIT | PSR_F_BIT
|
|
|
+ msr cpsr_c, r1
|
|
|
+ sub r0, #S_R2
|
|
|
+ add r8, r0, #S_PC
|
|
|
+ ldmia r0, {r0 - r1}
|
|
|
+ rfeia r8
|
|
|
+#endif
|
|
|
.endm
|
|
|
|
|
|
+
|
|
|
.macro restore_user_regs, fast = 0, offset = 0
|
|
|
+#ifndef CONFIG_THUMB2_KERNEL
|
|
|
+ @ ARM mode restore
|
|
|
mov r2, sp
|
|
|
ldr r1, [r2, #\offset + S_PSR] @ get calling cpsr
|
|
|
ldr lr, [r2, #\offset + S_PC]! @ get pc
|
|
@@ -270,72 +306,16 @@
|
|
|
@ after ldm {}^
|
|
|
add sp, sp, #\offset + S_FRAME_SIZE
|
|
|
movs pc, lr @ return & move spsr_svc into cpsr
|
|
|
- .endm
|
|
|
-
|
|
|
-#else /* CONFIG_THUMB2_KERNEL */
|
|
|
- .macro svc_exit, rpsr, irq = 0
|
|
|
- .if \irq != 0
|
|
|
- @ IRQs already off
|
|
|
-#ifdef CONFIG_TRACE_IRQFLAGS
|
|
|
- @ The parent context IRQs must have been enabled to get here in
|
|
|
- @ the first place, so there's no point checking the PSR I bit.
|
|
|
- bl trace_hardirqs_on
|
|
|
-#endif
|
|
|
- .else
|
|
|
- @ IRQs off again before pulling preserved data off the stack
|
|
|
- disable_irq_notrace
|
|
|
-#ifdef CONFIG_TRACE_IRQFLAGS
|
|
|
- tst \rpsr, #PSR_I_BIT
|
|
|
- bleq trace_hardirqs_on
|
|
|
- tst \rpsr, #PSR_I_BIT
|
|
|
- blne trace_hardirqs_off
|
|
|
-#endif
|
|
|
- .endif
|
|
|
- ldr lr, [sp, #S_SP] @ top of the stack
|
|
|
- ldrd r0, r1, [sp, #S_LR] @ calling lr and pc
|
|
|
-
|
|
|
- @ We must avoid clrex due to Cortex-A15 erratum #830321
|
|
|
- strex r2, r1, [sp, #S_LR] @ clear the exclusive monitor
|
|
|
-
|
|
|
- stmdb lr!, {r0, r1, \rpsr} @ calling lr and rfe context
|
|
|
- ldmia sp, {r0 - r12}
|
|
|
- mov sp, lr
|
|
|
- ldr lr, [sp], #4
|
|
|
- rfeia sp!
|
|
|
- .endm
|
|
|
-
|
|
|
- @
|
|
|
- @ svc_exit_via_fiq - like svc_exit but switches to FIQ mode before exit
|
|
|
- @
|
|
|
- @ For full details see non-Thumb implementation above.
|
|
|
- @
|
|
|
- .macro svc_exit_via_fiq
|
|
|
- add r0, sp, #S_R2
|
|
|
- ldr lr, [sp, #S_LR]
|
|
|
- ldr sp, [sp, #S_SP] @ abort is deadly from here onward (it will
|
|
|
- @ clobber state restored below)
|
|
|
- ldmia r0, {r2 - r12}
|
|
|
- mov r1, #FIQ_MODE | PSR_I_BIT | PSR_F_BIT
|
|
|
- msr cpsr_c, r1
|
|
|
- sub r0, #S_R2
|
|
|
- add r8, r0, #S_PC
|
|
|
- ldmia r0, {r0 - r1}
|
|
|
- rfeia r8
|
|
|
- .endm
|
|
|
-
|
|
|
-#ifdef CONFIG_CPU_V7M
|
|
|
- /*
|
|
|
- * Note we don't need to do clrex here as clearing the local monitor is
|
|
|
- * part of each exception entry and exit sequence.
|
|
|
- */
|
|
|
- .macro restore_user_regs, fast = 0, offset = 0
|
|
|
+#elif defined(CONFIG_CPU_V7M)
|
|
|
+ @ V7M restore.
|
|
|
+ @ Note that we don't need to do clrex here as clearing the local
|
|
|
+ @ monitor is part of the exception entry and exit sequence.
|
|
|
.if \offset
|
|
|
add sp, #\offset
|
|
|
.endif
|
|
|
v7m_exception_slow_exit ret_r0 = \fast
|
|
|
- .endm
|
|
|
-#else /* ifdef CONFIG_CPU_V7M */
|
|
|
- .macro restore_user_regs, fast = 0, offset = 0
|
|
|
+#else
|
|
|
+ @ Thumb mode restore
|
|
|
mov r2, sp
|
|
|
load_user_sp_lr r2, r3, \offset + S_SP @ calling sp, lr
|
|
|
ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
|
|
@@ -353,9 +333,8 @@
|
|
|
.endif
|
|
|
add sp, sp, #S_FRAME_SIZE - S_SP
|
|
|
movs pc, lr @ return & move spsr_svc into cpsr
|
|
|
- .endm
|
|
|
-#endif /* ifdef CONFIG_CPU_V7M / else */
|
|
|
#endif /* !CONFIG_THUMB2_KERNEL */
|
|
|
+ .endm
|
|
|
|
|
|
/*
|
|
|
* Context tracking subsystem. Used to instrument transitions
|