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) */