ppc4xx: Clean up 440 exceptions handling

- Introduced dedicated switches for building 440 and 405 images required
  for 440-specific machine instructions like 'rfmci' etc.

- Exception vectors moved to the proper location (_start moved away from
  the critical exception handler space, which it occupied)

- CriticalInput now serviced (with default handler)

- MachineCheck properly serviced (added a dedicated handler and return
  subroutine)

- Overall cleanup of exceptions declared with STD_EXCEPTION macro (unused,
  unhandled and those not relevant for 4xx were eliminated)

- Eliminated Linux leftovers, removed dead code

Signed-off-by: Grzegorz Bernacki <gjb@semihalf.com>
Signed-off-by: Rafal Jaworowski <raj@semihalf.com>
Signed-off-by: Stefan Roese <sr@denx.de>
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 78d0042..e135220 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -294,11 +294,13 @@
 	mtspr	ivor7,r1	/* Floating point unavailable */
 	li	r1,0x0c00
 	mtspr	ivor8,r1	/* System call */
-	li	r1,0x1000
-	mtspr	ivor10,r1	/* Decrementer (PIT for 440) */
-	li	r1,0x1400
-	mtspr	ivor13,r1	/* Data TLB error */
+	li	r1,0x0a00
+	mtspr   ivor9,r1	/* Auxiliary Processor unavailable */
+	li	r1,0x0900
+	mtspr	ivor10,r1	/* Decrementer */
 	li	r1,0x1300
+	mtspr	ivor13,r1	/* Data TLB error */
+	li	r1,0x1400
 	mtspr	ivor14,r1	/* Instr TLB error */
 	li	r1,0x2000
 	mtspr	ivor15,r1	/* Debug */
@@ -503,11 +505,81 @@
 	.ascii " (", __DATE__, " - ", __TIME__, ")"
 	.ascii CONFIG_IDENT_STRING, "\0"
 
-/*
- * Maybe this should be moved somewhere else because the current
- * location (0x100) is where the CriticalInput Execption should be.
- */
 	. = EXC_OFF_SYS_RESET
+	.globl	_start_of_vectors
+_start_of_vectors:
+
+/* Critical input. */
+	CRIT_EXCEPTION(0x100, CritcalInput, UnknownException)
+
+#ifdef CONFIG_440
+/* Machine check */
+        MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+#else
+        CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+#endif /* CONFIG_440 */
+
+/* Data Storage exception. */
+	STD_EXCEPTION(0x300, DataStorage, UnknownException)
+
+/* Instruction Storage exception. */
+	STD_EXCEPTION(0x400, InstStorage, UnknownException)
+
+/* External Interrupt exception. */
+	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
+
+/* Alignment exception. */
+	. = 0x600
+Alignment:
+	EXCEPTION_PROLOG(SRR0, SRR1)
+	mfspr	r4,DAR
+	stw	r4,_DAR(r21)
+	mfspr	r5,DSISR
+	stw	r5,_DSISR(r21)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_Alignment:
+	.long	AlignmentException - _start + _START_OFFSET
+	.long	int_return - _start + _START_OFFSET
+
+/* Program check exception */
+	. = 0x700
+ProgramCheck:
+	EXCEPTION_PROLOG(SRR0, SRR1)
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
+	lwz	r6,GOT(transfer_to_handler)
+	mtlr	r6
+	blrl
+.L_ProgramCheck:
+	.long	ProgramCheckException - _start + _START_OFFSET
+	.long	int_return - _start + _START_OFFSET
+
+#ifdef CONFIG_440
+	STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
+	STD_EXCEPTION(0x900, Decrementer, DecrementerPITException)
+	STD_EXCEPTION(0xa00, APU, UnknownException)
+#endif	
+	STD_EXCEPTION(0xc00, SystemCall, UnknownException)
+
+#ifdef CONFIG_440
+	STD_EXCEPTION(0x1300, DataTLBError, UnknownException)
+	STD_EXCEPTION(0x1400, InstructionTLBError, UnknownException)
+#else
+	STD_EXCEPTION(0x1000, PIT, DecrementerPITException)
+	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
+	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
+#endif
+	CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
+
+	.globl	_end_of_vectors
+_end_of_vectors:
+	. = _START_OFFSET
 #endif
 	.globl	_start
 _start:
@@ -1017,107 +1089,6 @@
 
 
 #ifndef CONFIG_NAND_SPL
-/*****************************************************************************/
-	.globl	_start_of_vectors
-_start_of_vectors:
-
-#if 0
-/*TODO Fixup _start above so we can do this*/
-/* Critical input. */
-	CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
-#endif
-
-/* Machine check */
-	CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
-
-/* Data Storage exception. */
-	STD_EXCEPTION(0x300, DataStorage, UnknownException)
-
-/* Instruction Storage exception. */
-	STD_EXCEPTION(0x400, InstStorage, UnknownException)
-
-/* External Interrupt exception. */
-	STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
-
-/* Alignment exception. */
-	. = 0x600
-Alignment:
-	EXCEPTION_PROLOG
-	mfspr	r4,DAR
-	stw	r4,_DAR(r21)
-	mfspr	r5,DSISR
-	stw	r5,_DSISR(r21)
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r20,MSR_KERNEL
-	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
-	lwz	r6,GOT(transfer_to_handler)
-	mtlr	r6
-	blrl
-.L_Alignment:
-	.long	AlignmentException - _start + EXC_OFF_SYS_RESET
-	.long	int_return - _start + EXC_OFF_SYS_RESET
-
-/* Program check exception */
-	. = 0x700
-ProgramCheck:
-	EXCEPTION_PROLOG
-	addi	r3,r1,STACK_FRAME_OVERHEAD
-	li	r20,MSR_KERNEL
-	rlwimi	r20,r23,0,16,16		/* copy EE bit from saved MSR */
-	lwz	r6,GOT(transfer_to_handler)
-	mtlr	r6
-	blrl
-.L_ProgramCheck:
-	.long	ProgramCheckException - _start + EXC_OFF_SYS_RESET
-	.long	int_return - _start + EXC_OFF_SYS_RESET
-
-	/* No FPU on MPC8xx.  This exception is not supposed to happen.
-	*/
-	STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
-
-	/* I guess we could implement decrementer, and may have
-	 * to someday for timekeeping.
-	 */
-	STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
-	STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
-	STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
-	STD_EXCEPTION(0xc00, SystemCall, UnknownException)
-	STD_EXCEPTION(0xd00, SingleStep, UnknownException)
-
-	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
-	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
-
-	/* On the MPC8xx, this is a software emulation interrupt.  It occurs
-	 * for all unimplemented and illegal instructions.
-	 */
-	STD_EXCEPTION(0x1000, PIT, PITException)
-
-	STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
-	STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
-	STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
-	STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
-
-	STD_EXCEPTION(0x1500, Reserved5, UnknownException)
-	STD_EXCEPTION(0x1600, Reserved6, UnknownException)
-	STD_EXCEPTION(0x1700, Reserved7, UnknownException)
-	STD_EXCEPTION(0x1800, Reserved8, UnknownException)
-	STD_EXCEPTION(0x1900, Reserved9, UnknownException)
-	STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
-	STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
-
-	STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
-	STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
-	STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
-	STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
-
-	CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
-
-	.globl	_end_of_vectors
-_end_of_vectors:
-
-
-	. = 0x2100
-
 /*
  * This code finishes saving the registers to the exception frame
  * and jumps to the appropriate handler for the exception.
@@ -1133,28 +1104,12 @@
 	SAVE_4GPRS(8, r21)
 	SAVE_8GPRS(12, r21)
 	SAVE_8GPRS(24, r21)
-#if 0
-	andi.	r23,r23,MSR_PR
-	mfspr	r23,SPRG3		/* if from user, fix up tss.regs */
-	beq	2f
-	addi	r24,r1,STACK_FRAME_OVERHEAD
-	stw	r24,PT_REGS(r23)
-2:	addi	r2,r23,-TSS		/* set r2 to current */
-	tovirt(r2,r2,r23)
-#endif
 	mflr	r23
 	andi.	r24,r23,0x3f00		/* get vector offset */
 	stw	r24,TRAP(r21)
 	li	r22,0
 	stw	r22,RESULT(r21)
 	mtspr	SPRG2,r22		/* r1 is now kernel sp */
-#if 0
-	addi	r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
-	cmplw	0,r1,r2
-	cmplw	1,r1,r24
-	crand	1,1,4
-	bgt	stack_ovf		/* if r2 < r1 < r2+TASK_STRUCT_SIZE */
-#endif
 	lwz	r24,0(r23)		/* virtual address of handler */
 	lwz	r23,4(r23)		/* where to go when done */
 	mtspr	SRR0,r24
@@ -1215,16 +1170,64 @@
 	REST_GPR(31, r1)
 	lwz	r2,_NIP(r1)	/* Restore environment */
 	lwz	r0,_MSR(r1)
-	mtspr	990,r2		/* SRR2 */
-	mtspr	991,r0		/* SRR3 */
+        mtspr   csrr0,r2
+        mtspr   csrr1,r0
 	lwz	r0,GPR0(r1)
 	lwz	r2,GPR2(r1)
 	lwz	r1,GPR1(r1)
 	SYNC
 	rfci
 
+#ifdef CONFIG_440
+mck_return:
+        mfmsr   r28             /* Disable interrupts */
+        li      r4,0
+        ori     r4,r4,MSR_EE
+        andc    r28,r28,r4
+        SYNC                    /* Some chip revs need this... */
+        mtmsr   r28
+        SYNC
+        lwz     r2,_CTR(r1)
+        lwz     r0,_LINK(r1)
+        mtctr   r2
+        mtlr    r0
+        lwz     r2,_XER(r1)
+        lwz     r0,_CCR(r1)
+        mtspr   XER,r2
+        mtcrf   0xFF,r0
+        REST_10GPRS(3, r1)
+        REST_10GPRS(13, r1)
+        REST_8GPRS(23, r1)
+        REST_GPR(31, r1)
+        lwz     r2,_NIP(r1)     /* Restore environment */
+        lwz     r0,_MSR(r1)
+        mtspr   mcsrr0,r2
+        mtspr   mcsrr1,r0
+        lwz     r0,GPR0(r1)
+        lwz     r2,GPR2(r1)
+        lwz     r1,GPR1(r1)
+        SYNC
+        rfmci
+#endif /* CONFIG_440 */
+
+
+/*
+ * Cache functions.
+ *
+ * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
+ * although for some cache-ralated calls stubs have to be provided to satisfy
+ * symbols resolution.
+ *
+ */
+#ifdef CONFIG_440
+       .globl  dcache_disable
+dcache_disable:
+        blr
+
-/* Cache functions.
-*/
+        .globl  dcache_status
+dcache_status:
+        blr
+#else
 flush_dcache:
 	addis	r9,r0,0x0002		/* set mask for EE and CE msr bits */
 	ori	r9,r9,0x8000
@@ -1303,24 +1306,13 @@
 	mfdccr	r3
 	srwi	r3, r3, 31	/* >>31 => select bit 0 */
 	blr
+#endif
 
 	.globl get_pvr
 get_pvr:
 	mfspr	r3, PVR
 	blr
 
-#if !defined(CONFIG_440)
-	.globl wr_pit
-wr_pit:
-	mtspr	pit, r3
-	blr
-#endif
-
-	.globl wr_tcr
-wr_tcr:
-	mtspr	tcr, r3
-	blr
-
 /*------------------------------------------------------------------------------- */
 /* Function:	 out16 */
 /* Description:	 Output 16 bits */
@@ -1518,7 +1510,7 @@
  * initialization, now running from RAM.
  */
 
-	addi	r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
+	addi	r0, r10, in_ram - _start + _START_OFFSET
 	mtlr	r0
 	blr				/* NEVER RETURNS! */
 
@@ -1588,7 +1580,7 @@
 	 */
 	.globl	trap_init
 trap_init:
-	lwz	r7, GOT(_start)
+	lwz	r7, GOT(_start_of_vectors)
 	lwz	r8, GOT(_end_of_vectors)
 
 	li	r9, 0x100		/* reset vector always at 0x100 */
@@ -1608,35 +1600,48 @@
 	/*
 	 * relocate `hdlr' and `int_return' entries
 	 */
-	li	r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
-	li	r8, Alignment - _start + EXC_OFF_SYS_RESET
+	li	r7, .L_MachineCheck - _start + _START_OFFSET
+	li	r8, Alignment - _start + _START_OFFSET
 2:
 	bl	trap_reloc
-	addi	r7, r7, 0x100		/* next exception vector	*/
+	addi	r7, r7, 0x100		/* next exception vector */
 	cmplw	0, r7, r8
 	blt	2b
 
-	li	r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
+	li	r7, .L_Alignment - _start + _START_OFFSET
 	bl	trap_reloc
 
-	li	r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
+	li	r7, .L_ProgramCheck - _start + _START_OFFSET
 	bl	trap_reloc
 
-	li	r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
-	li	r8, SystemCall - _start + EXC_OFF_SYS_RESET
-3:
-	bl	trap_reloc
-	addi	r7, r7, 0x100		/* next exception vector	*/
-	cmplw	0, r7, r8
-	blt	3b
+#ifdef CONFIG_440
+	li	r7, .L_FPUnavailable - _start + _START_OFFSET
+        bl      trap_reloc
 
-	li	r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
-	li	r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
-4:
-	bl	trap_reloc
-	addi	r7, r7, 0x100		/* next exception vector	*/
-	cmplw	0, r7, r8
-	blt	4b
+	li	r7, .L_Decrementer - _start + _START_OFFSET
+        bl      trap_reloc
+
+	li	r7, .L_APU - _start + _START_OFFSET
+        bl      trap_reloc
+        
+	li      r7, .L_InstructionTLBError - _start + _START_OFFSET
+        bl      trap_reloc
+
+        li      r7, .L_DataTLBError - _start + _START_OFFSET
+        bl      trap_reloc
+#else /* CONFIG_440 */
+	li	r7, .L_PIT - _start + _START_OFFSET
+        bl      trap_reloc
+
+	li	r7, .L_InstructionTLBMiss - _start + _START_OFFSET
+        bl      trap_reloc
+
+	li	r7, .L_DataTLBMiss - _start + _START_OFFSET
+        bl      trap_reloc
+#endif /* CONFIG_440 */
+
+        li      r7, .L_DebugBreakpoint - _start + _START_OFFSET
+        bl      trap_reloc
 
 #if !defined(CONFIG_440)
 	addi	r7,r0,0x1000		/* set ME bit (Machine Exceptions) */