mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 21:44:27 -04: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
 |