diff options
Diffstat (limited to 'arch/arm/vfp/vfphw.S')
-rw-r--r-- | arch/arm/vfp/vfphw.S | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S index e51e6679c40..d4b7b229631 100644 --- a/arch/arm/vfp/vfphw.S +++ b/arch/arm/vfp/vfphw.S @@ -65,6 +65,7 @@ @ r2 = faulted PC+4 @ r9 = successful return @ r10 = vfp_state union +@ r11 = CPU number @ lr = failure return .globl vfp_support_entry @@ -79,7 +80,7 @@ vfp_support_entry: DBGSTR1 "enable %x", r10 ldr r3, last_VFP_context_address orr r1, r1, #FPEXC_ENABLE @ user FPEXC has the enable bit set - ldr r4, [r3] @ last_VFP_context pointer + ldr r4, [r3, r11, lsl #2] @ last_VFP_context pointer bic r5, r1, #FPEXC_EXCEPTION @ make sure exceptions are disabled cmp r4, r10 beq check_for_exception @ we are returning to the same @@ -91,7 +92,9 @@ vfp_support_entry: @ exceptions, so we can get at the @ rest of it +#ifndef CONFIG_SMP @ Save out the current registers to the old thread state + @ No need for SMP since this is not done lazily DBGSTR1 "save old state %p", r4 cmp r4, #0 @@ -105,10 +108,11 @@ vfp_support_entry: stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2 @ and point r4 at the word at the @ start of the register dump +#endif no_old_VFP_process: DBGSTR1 "load state %p", r10 - str r10, [r3] @ update the last_VFP_context pointer + str r10, [r3, r11, lsl #2] @ update the last_VFP_context pointer @ Load the saved state back into the VFP VFPFLDMIA r10 @ reload the working registers while @ FPEXC is in a safe state @@ -162,6 +166,24 @@ process_exception: @ required. If not, the user code will @ retry the faulted instruction +#ifdef CONFIG_SMP + .globl vfp_save_state + .type vfp_save_state, %function +vfp_save_state: + @ Save the current VFP state + @ r0 - save location + @ r1 - FPEXC + DBGSTR1 "save VFP state %p", r0 + VFPFMRX r2, FPSCR @ current status + VFPFMRX r3, FPINST @ FPINST (always there, rev0 onwards) + tst r1, #FPEXC_FPV2 @ is there an FPINST2 to read? + VFPFMRX r12, FPINST2, NE @ FPINST2 if needed - avoids reading + @ nonexistant reg on rev0 + VFPFSTMIA r0 @ save the working registers + stmia r0, {r1, r2, r3, r12} @ save FPEXC, FPSCR, FPINST, FPINST2 + mov pc, lr +#endif + last_VFP_context_address: .word last_VFP_context |