Commit 443a848c authored by Paul Mackerras's avatar Paul Mackerras Committed by Linus Torvalds
Browse files

[PATCH] ppc32: refactor FPU exception handling



Moved common FPU exception handling code out of head.S so it can be used by
several of the sub-architectures that might of a full PowerPC FPU.

Also, uses new CONFIG_PPC_FPU define to fix alignment exception handling
for floating point load/store instructions to only occur if we have a
hardware FPU.

Signed-off-by: default avatarJason McMullan <jason.mcmullan@timesys.com>
Signed-off-by: default avatarKumar Gala <kumar.gala@freescale.com>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent f1c55dea
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ choice

config 6xx
	bool "6xx/7xx/74xx/52xx/82xx/83xx"
	select PPC_FPU
	help
	  There are four types of PowerPC chips supported.  The more common
	  types (601, 603, 604, 740, 750, 7400), the Motorola embedded
@@ -86,6 +87,9 @@ config E500

endchoice

config PPC_FPU
	bool

config BOOKE
	bool
	depends on E500
+1 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ head-$(CONFIG_FSL_BOOKE) := arch/ppc/kernel/head_fsl_booke.o

head-$(CONFIG_6xx)		+= arch/ppc/kernel/idle_6xx.o
head-$(CONFIG_POWER4)		+= arch/ppc/kernel/idle_power4.o
head-$(CONFIG_PPC_FPU)		+= arch/ppc/kernel/fpu.o

core-y				+= arch/ppc/kernel/ arch/ppc/platforms/ \
				   arch/ppc/mm/ arch/ppc/lib/ arch/ppc/syslib/
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
extra-$(CONFIG_8xx)		:= head_8xx.o
extra-$(CONFIG_6xx)		+= idle_6xx.o
extra-$(CONFIG_POWER4)		+= idle_power4.o
extra-$(CONFIG_PPC_FPU)		+= fpu.o
extra-y				+= vmlinux.lds

obj-y				:= entry.o traps.o irq.o idle.o time.o misc.o \
+8 −0
Original line number Diff line number Diff line
@@ -368,16 +368,24 @@ fix_alignment(struct pt_regs *regs)

	/* Single-precision FP load and store require conversions... */
	case LD+F+S:
#ifdef CONFIG_PPC_FPU
		preempt_disable();
		enable_kernel_fp();
		cvt_fd(&data.f, &data.d, &current->thread.fpscr);
		preempt_enable();
#else
		return 0;
#endif
		break;
	case ST+F+S:
#ifdef CONFIG_PPC_FPU
		preempt_disable();
		enable_kernel_fp();
		cvt_df(&data.d, &data.f, &current->thread.fpscr);
		preempt_enable();
#else
		return 0;
#endif
		break;
	}

+59 −0
Original line number Diff line number Diff line
@@ -563,6 +563,65 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
	addi	r1,r1,INT_FRAME_SIZE
	blr

	.globl	fast_exception_return
fast_exception_return:
#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
	andi.	r10,r9,MSR_RI		/* check for recoverable interrupt */
	beq	1f			/* if not, we've got problems */
#endif

2:	REST_4GPRS(3, r11)
	lwz	r10,_CCR(r11)
	REST_GPR(1, r11)
	mtcr	r10
	lwz	r10,_LINK(r11)
	mtlr	r10
	REST_GPR(10, r11)
	mtspr	SPRN_SRR1,r9
	mtspr	SPRN_SRR0,r12
	REST_GPR(9, r11)
	REST_GPR(12, r11)
	lwz	r11,GPR11(r11)
	SYNC
	RFI

#if !(defined(CONFIG_4xx) || defined(CONFIG_BOOKE))
/* check if the exception happened in a restartable section */
1:	lis	r3,exc_exit_restart_end@ha
	addi	r3,r3,exc_exit_restart_end@l
	cmplw	r12,r3
	bge	3f
	lis	r4,exc_exit_restart@ha
	addi	r4,r4,exc_exit_restart@l
	cmplw	r12,r4
	blt	3f
	lis	r3,fee_restarts@ha
	tophys(r3,r3)
	lwz	r5,fee_restarts@l(r3)
	addi	r5,r5,1
	stw	r5,fee_restarts@l(r3)
	mr	r12,r4		/* restart at exc_exit_restart */
	b	2b

	.comm	fee_restarts,4

/* aargh, a nonrecoverable interrupt, panic */
/* aargh, we don't know which trap this is */
/* but the 601 doesn't implement the RI bit, so assume it's OK */
3:
BEGIN_FTR_SECTION
	b	2b
END_FTR_SECTION_IFSET(CPU_FTR_601)
	li	r10,-1
	stw	r10,TRAP(r11)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	lis	r10,MSR_KERNEL@h
	ori	r10,r10,MSR_KERNEL@l
	bl	transfer_to_handler_full
	.long	nonrecoverable_exception
	.long	ret_from_except
#endif

	.globl	sigreturn_exit
sigreturn_exit:
	subi	r1,r3,STACK_FRAME_OVERHEAD
Loading