 f27d6e1723
			
		
	
	
	f27d6e1723
	
	
	
		
			
			Commit d3f79584a8 ("ARM: cleanup undefined instruction entry code")
improved the register scheduling when handling undefined instructions.
A side effect of this is that r5 is now used as a temporary, whilst the
VFP probing code relies on r5 containing a non-zero value when VFP is
not supported.
This patch fixes the VFP detection code so that we don't rely on the
contents of r5. Without this patch, Linux dies loudly on CPUs without
VFP support.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
		
	
			
		
			
				
	
	
		
			71 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
	
		
			1.8 KiB
			
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  *  linux/arch/arm/vfp/entry.S
 | |
|  *
 | |
|  *  Copyright (C) 2004 ARM Limited.
 | |
|  *  Written by Deep Blue Solutions Limited.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or modify
 | |
|  * it under the terms of the GNU General Public License version 2 as
 | |
|  * published by the Free Software Foundation.
 | |
|  */
 | |
| #include <asm/thread_info.h>
 | |
| #include <asm/vfpmacros.h>
 | |
| #include "../kernel/entry-header.S"
 | |
| 
 | |
| @ VFP entry point.
 | |
| @
 | |
| @  r0  = instruction opcode (32-bit ARM or two 16-bit Thumb)
 | |
| @  r2  = PC value to resume execution after successful emulation
 | |
| @  r9  = normal "successful" return address
 | |
| @  r10 = this threads thread_info structure
 | |
| @  lr  = unrecognised instruction return address
 | |
| @  IRQs disabled.
 | |
| @
 | |
| ENTRY(do_vfp)
 | |
| #ifdef CONFIG_PREEMPT_COUNT
 | |
| 	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
 | |
| 	add	r11, r4, #1		@ increment it
 | |
| 	str	r11, [r10, #TI_PREEMPT]
 | |
| #endif
 | |
| 	enable_irq
 | |
|  	ldr	r4, .LCvfp
 | |
| 	ldr	r11, [r10, #TI_CPU]	@ CPU number
 | |
| 	add	r10, r10, #TI_VFPSTATE	@ r10 = workspace
 | |
| 	ldr	pc, [r4]		@ call VFP entry point
 | |
| ENDPROC(do_vfp)
 | |
| 
 | |
| ENTRY(vfp_null_entry)
 | |
| #ifdef CONFIG_PREEMPT_COUNT
 | |
| 	get_thread_info	r10
 | |
| 	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
 | |
| 	sub	r11, r4, #1		@ decrement it
 | |
| 	str	r11, [r10, #TI_PREEMPT]
 | |
| #endif
 | |
| 	mov	pc, lr
 | |
| ENDPROC(vfp_null_entry)
 | |
| 
 | |
| 	.align	2
 | |
| .LCvfp:
 | |
| 	.word	vfp_vector
 | |
| 
 | |
| @ This code is called if the VFP does not exist. It needs to flag the
 | |
| @ failure to the VFP initialisation code.
 | |
| 
 | |
| 	__INIT
 | |
| ENTRY(vfp_testing_entry)
 | |
| #ifdef CONFIG_PREEMPT_COUNT
 | |
| 	get_thread_info	r10
 | |
| 	ldr	r4, [r10, #TI_PREEMPT]	@ get preempt count
 | |
| 	sub	r11, r4, #1		@ decrement it
 | |
| 	str	r11, [r10, #TI_PREEMPT]
 | |
| #endif
 | |
| 	ldr	r0, VFP_arch_address
 | |
| 	str	r0, [r0]		@ set to non-zero value
 | |
| 	mov	pc, r9			@ we have handled the fault
 | |
| ENDPROC(vfp_testing_entry)
 | |
| 
 | |
| 	.align	2
 | |
| VFP_arch_address:
 | |
| 	.word	VFP_arch
 | |
| 
 | |
| 	__FINIT
 |