summaryrefslogtreecommitdiffstats
path: root/target/linux
diff options
context:
space:
mode:
authorkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-06-01 12:45:50 +0000
committerkaloz <kaloz@3c298f89-4303-0410-b956-a3cf2f4a3e73>2009-06-01 12:45:50 +0000
commite13225ef04bf7b6f2e247a1f5ec3d227ec16e74d (patch)
tree6b8f13369206b35a91d5cacb0cf05e2ba3164627 /target/linux
parent347bbc9497477f6b58f6aa7f857c68383130d9c9 (diff)
fix VFP handling on feroceon cores
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@16246 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux')
-rw-r--r--target/linux/generic-2.6/patches-2.6.30/990-fix_feroceon_vfp_handling.patch70
1 files changed, 70 insertions, 0 deletions
diff --git a/target/linux/generic-2.6/patches-2.6.30/990-fix_feroceon_vfp_handling.patch b/target/linux/generic-2.6/patches-2.6.30/990-fix_feroceon_vfp_handling.patch
new file mode 100644
index 000000000..0ee18f02b
--- /dev/null
+++ b/target/linux/generic-2.6/patches-2.6.30/990-fix_feroceon_vfp_handling.patch
@@ -0,0 +1,70 @@
+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