mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
71 lines
2.5 KiB
Diff
71 lines
2.5 KiB
Diff
|
From: Catalin Marinas <catalin.marinas@arm.com>
|
||
|
Date: Sat, 30 May 2009 13:00:18 +0000 (+0100)
|
||
|
Subject: Fix the VFP handling on the Feroceon CPU
|
||
|
X-Git-Url: http://www.linux-arm.org/git?p=linux-2.6.git;a=commitdiff_plain;h=85d6943af50537d3aec58b967ffbd3fec88453e9;hp=26584853a44c58f3d6ac7360d697a2ddcd1a3efa
|
||
|
|
||
|
Fix the VFP handling on the Feroceon CPU
|
||
|
|
||
|
This CPU generates synchronous VFP exceptions in a non-standard way -
|
||
|
the FPEXC.EX bit set but without the FPSCR.IXE bit being set like in the
|
||
|
VFP subarchitecture 1 or just the FPEXC.DEX bit like in VFP
|
||
|
subarchitecture 2. The main problem is that the faulty instruction
|
||
|
(which needs to be emulated in software) will be restarted several times
|
||
|
(normally until a context switch disables the VFP). This patch ensures
|
||
|
that the VFP exception is treated as synchronous.
|
||
|
|
||
|
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
|
||
|
Cc: Nicolas Pitre <nico@cam.org>
|
||
|
---
|
||
|
|
||
|
--- a/arch/arm/vfp/vfphw.S
|
||
|
+++ b/arch/arm/vfp/vfphw.S
|
||
|
@@ -100,6 +100,7 @@ ENTRY(vfp_support_entry)
|
||
|
beq no_old_VFP_process
|
||
|
VFPFSTMIA r4, r5 @ save the working registers
|
||
|
VFPFMRX r5, FPSCR @ current status
|
||
|
+#ifndef CONFIG_CPU_FEROCEON
|
||
|
tst r1, #FPEXC_EX @ is there additional state to save?
|
||
|
beq 1f
|
||
|
VFPFMRX r6, FPINST @ FPINST (only if FPEXC.EX is set)
|
||
|
@@ -107,6 +108,7 @@ ENTRY(vfp_support_entry)
|
||
|
beq 1f
|
||
|
VFPFMRX r8, FPINST2 @ FPINST2 if needed (and present)
|
||
|
1:
|
||
|
+#endif
|
||
|
stmia r4, {r1, r5, r6, r8} @ save FPEXC, FPSCR, FPINST, FPINST2
|
||
|
@ and point r4 at the word at the
|
||
|
@ start of the register dump
|
||
|
@@ -119,6 +121,7 @@ no_old_VFP_process:
|
||
|
VFPFLDMIA r10, r5 @ reload the working registers while
|
||
|
@ FPEXC is in a safe state
|
||
|
ldmia r10, {r1, r5, r6, r8} @ load FPEXC, FPSCR, FPINST, FPINST2
|
||
|
+#ifndef CONFIG_CPU_FEROCEON
|
||
|
tst r1, #FPEXC_EX @ is there additional state to restore?
|
||
|
beq 1f
|
||
|
VFPFMXR FPINST, r6 @ restore FPINST (only if FPEXC.EX is set)
|
||
|
@@ -126,6 +129,7 @@ no_old_VFP_process:
|
||
|
beq 1f
|
||
|
VFPFMXR FPINST2, r8 @ FPINST2 if needed (and present)
|
||
|
1:
|
||
|
+#endif
|
||
|
VFPFMXR FPSCR, r5 @ restore status
|
||
|
|
||
|
check_for_exception:
|
||
|
--- a/arch/arm/vfp/vfpmodule.c
|
||
|
+++ b/arch/arm/vfp/vfpmodule.c
|
||
|
@@ -253,12 +253,14 @@ void VFP_bounce(u32 trigger, u32 fpexc,
|
||
|
}
|
||
|
|
||
|
if (fpexc & FPEXC_EX) {
|
||
|
+#ifndef CONFIG_CPU_FEROCEON
|
||
|
/*
|
||
|
* Asynchronous exception. The instruction is read from FPINST
|
||
|
* and the interrupted instruction has to be restarted.
|
||
|
*/
|
||
|
trigger = fmrx(FPINST);
|
||
|
regs->ARM_pc -= 4;
|
||
|
+#endif
|
||
|
} else if (!(fpexc & FPEXC_DEX)) {
|
||
|
/*
|
||
|
* Illegal combination of bits. It can be caused by an
|