diff options
Diffstat (limited to 'target/linux/generic-2.6/patches-2.6.30')
| -rw-r--r-- | target/linux/generic-2.6/patches-2.6.30/990-fix_feroceon_vfp_handling.patch | 70 | 
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  | 
