Commit efa35cf12d914d4caba942acd5a6c45f217de302

Authored by Grzegorz Bernacki
Committed by Stefan Roese
1 parent 725671ccd2

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>

Showing 21 changed files with 319 additions and 267 deletions Side-by-side Diff

cpu/ppc4xx/config.mk
... ... @@ -22,6 +22,14 @@
22 22 #
23 23  
24 24 PLATFORM_RELFLAGS += -fPIC -ffixed-r14 -meabi -fno-strict-aliasing
  25 +PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -ffixed-r29 -mstring -msoft-float
25 26  
26   -PLATFORM_CPPFLAGS += -DCONFIG_4xx -ffixed-r2 -ffixed-r29 -mstring -Wa,-m405 -mcpu=405 -msoft-float
  27 +cfg=$(shell grep configs $(TOPDIR)/include/config.h | sed 's/.*<\(configs.*\)>/\1/')
  28 +is440=$(shell grep CONFIG_440 $(TOPDIR)/include/$(cfg))
  29 +
  30 +ifneq (,$(findstring CONFIG_440,$(is440)))
  31 +PLATFORM_CPPFLAGS += -Wa,-m440 -mcpu=440
  32 +else
  33 +PLATFORM_CPPFLAGS += -Wa,-m405 -mcpu=405
  34 +endif
... ... @@ -294,11 +294,13 @@
294 294 mtspr ivor7,r1 /* Floating point unavailable */
295 295 li r1,0x0c00
296 296 mtspr ivor8,r1 /* System call */
297   - li r1,0x1000
298   - mtspr ivor10,r1 /* Decrementer (PIT for 440) */
299   - li r1,0x1400
300   - mtspr ivor13,r1 /* Data TLB error */
  297 + li r1,0x0a00
  298 + mtspr ivor9,r1 /* Auxiliary Processor unavailable */
  299 + li r1,0x0900
  300 + mtspr ivor10,r1 /* Decrementer */
301 301 li r1,0x1300
  302 + mtspr ivor13,r1 /* Data TLB error */
  303 + li r1,0x1400
302 304 mtspr ivor14,r1 /* Instr TLB error */
303 305 li r1,0x2000
304 306 mtspr ivor15,r1 /* Debug */
305 307  
306 308  
... ... @@ -503,12 +505,82 @@
503 505 .ascii " (", __DATE__, " - ", __TIME__, ")"
504 506 .ascii CONFIG_IDENT_STRING, "\0"
505 507  
506   -/*
507   - * Maybe this should be moved somewhere else because the current
508   - * location (0x100) is where the CriticalInput Execption should be.
509   - */
510 508 . = EXC_OFF_SYS_RESET
  509 + .globl _start_of_vectors
  510 +_start_of_vectors:
  511 +
  512 +/* Critical input. */
  513 + CRIT_EXCEPTION(0x100, CritcalInput, UnknownException)
  514 +
  515 +#ifdef CONFIG_440
  516 +/* Machine check */
  517 + MCK_EXCEPTION(0x200, MachineCheck, MachineCheckException)
  518 +#else
  519 + CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
  520 +#endif /* CONFIG_440 */
  521 +
  522 +/* Data Storage exception. */
  523 + STD_EXCEPTION(0x300, DataStorage, UnknownException)
  524 +
  525 +/* Instruction Storage exception. */
  526 + STD_EXCEPTION(0x400, InstStorage, UnknownException)
  527 +
  528 +/* External Interrupt exception. */
  529 + STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
  530 +
  531 +/* Alignment exception. */
  532 + . = 0x600
  533 +Alignment:
  534 + EXCEPTION_PROLOG(SRR0, SRR1)
  535 + mfspr r4,DAR
  536 + stw r4,_DAR(r21)
  537 + mfspr r5,DSISR
  538 + stw r5,_DSISR(r21)
  539 + addi r3,r1,STACK_FRAME_OVERHEAD
  540 + li r20,MSR_KERNEL
  541 + rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  542 + lwz r6,GOT(transfer_to_handler)
  543 + mtlr r6
  544 + blrl
  545 +.L_Alignment:
  546 + .long AlignmentException - _start + _START_OFFSET
  547 + .long int_return - _start + _START_OFFSET
  548 +
  549 +/* Program check exception */
  550 + . = 0x700
  551 +ProgramCheck:
  552 + EXCEPTION_PROLOG(SRR0, SRR1)
  553 + addi r3,r1,STACK_FRAME_OVERHEAD
  554 + li r20,MSR_KERNEL
  555 + rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  556 + lwz r6,GOT(transfer_to_handler)
  557 + mtlr r6
  558 + blrl
  559 +.L_ProgramCheck:
  560 + .long ProgramCheckException - _start + _START_OFFSET
  561 + .long int_return - _start + _START_OFFSET
  562 +
  563 +#ifdef CONFIG_440
  564 + STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
  565 + STD_EXCEPTION(0x900, Decrementer, DecrementerPITException)
  566 + STD_EXCEPTION(0xa00, APU, UnknownException)
  567 +#endif
  568 + STD_EXCEPTION(0xc00, SystemCall, UnknownException)
  569 +
  570 +#ifdef CONFIG_440
  571 + STD_EXCEPTION(0x1300, DataTLBError, UnknownException)
  572 + STD_EXCEPTION(0x1400, InstructionTLBError, UnknownException)
  573 +#else
  574 + STD_EXCEPTION(0x1000, PIT, DecrementerPITException)
  575 + STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
  576 + STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
511 577 #endif
  578 + CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
  579 +
  580 + .globl _end_of_vectors
  581 +_end_of_vectors:
  582 + . = _START_OFFSET
  583 +#endif
512 584 .globl _start
513 585 _start:
514 586  
... ... @@ -1017,107 +1089,6 @@
1017 1089  
1018 1090  
1019 1091 #ifndef CONFIG_NAND_SPL
1020   -/*****************************************************************************/
1021   - .globl _start_of_vectors
1022   -_start_of_vectors:
1023   -
1024   -#if 0
1025   -/*TODO Fixup _start above so we can do this*/
1026   -/* Critical input. */
1027   - CRIT_EXCEPTION(0x100, CritcalInput, CritcalInputException)
1028   -#endif
1029   -
1030   -/* Machine check */
1031   - CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
1032   -
1033   -/* Data Storage exception. */
1034   - STD_EXCEPTION(0x300, DataStorage, UnknownException)
1035   -
1036   -/* Instruction Storage exception. */
1037   - STD_EXCEPTION(0x400, InstStorage, UnknownException)
1038   -
1039   -/* External Interrupt exception. */
1040   - STD_EXCEPTION(0x500, ExtInterrupt, external_interrupt)
1041   -
1042   -/* Alignment exception. */
1043   - . = 0x600
1044   -Alignment:
1045   - EXCEPTION_PROLOG
1046   - mfspr r4,DAR
1047   - stw r4,_DAR(r21)
1048   - mfspr r5,DSISR
1049   - stw r5,_DSISR(r21)
1050   - addi r3,r1,STACK_FRAME_OVERHEAD
1051   - li r20,MSR_KERNEL
1052   - rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
1053   - lwz r6,GOT(transfer_to_handler)
1054   - mtlr r6
1055   - blrl
1056   -.L_Alignment:
1057   - .long AlignmentException - _start + EXC_OFF_SYS_RESET
1058   - .long int_return - _start + EXC_OFF_SYS_RESET
1059   -
1060   -/* Program check exception */
1061   - . = 0x700
1062   -ProgramCheck:
1063   - EXCEPTION_PROLOG
1064   - addi r3,r1,STACK_FRAME_OVERHEAD
1065   - li r20,MSR_KERNEL
1066   - rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
1067   - lwz r6,GOT(transfer_to_handler)
1068   - mtlr r6
1069   - blrl
1070   -.L_ProgramCheck:
1071   - .long ProgramCheckException - _start + EXC_OFF_SYS_RESET
1072   - .long int_return - _start + EXC_OFF_SYS_RESET
1073   -
1074   - /* No FPU on MPC8xx. This exception is not supposed to happen.
1075   - */
1076   - STD_EXCEPTION(0x800, FPUnavailable, UnknownException)
1077   -
1078   - /* I guess we could implement decrementer, and may have
1079   - * to someday for timekeeping.
1080   - */
1081   - STD_EXCEPTION(0x900, Decrementer, timer_interrupt)
1082   - STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
1083   - STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
1084   - STD_EXCEPTION(0xc00, SystemCall, UnknownException)
1085   - STD_EXCEPTION(0xd00, SingleStep, UnknownException)
1086   -
1087   - STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
1088   - STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
1089   -
1090   - /* On the MPC8xx, this is a software emulation interrupt. It occurs
1091   - * for all unimplemented and illegal instructions.
1092   - */
1093   - STD_EXCEPTION(0x1000, PIT, PITException)
1094   -
1095   - STD_EXCEPTION(0x1100, InstructionTLBMiss, UnknownException)
1096   - STD_EXCEPTION(0x1200, DataTLBMiss, UnknownException)
1097   - STD_EXCEPTION(0x1300, InstructionTLBError, UnknownException)
1098   - STD_EXCEPTION(0x1400, DataTLBError, UnknownException)
1099   -
1100   - STD_EXCEPTION(0x1500, Reserved5, UnknownException)
1101   - STD_EXCEPTION(0x1600, Reserved6, UnknownException)
1102   - STD_EXCEPTION(0x1700, Reserved7, UnknownException)
1103   - STD_EXCEPTION(0x1800, Reserved8, UnknownException)
1104   - STD_EXCEPTION(0x1900, Reserved9, UnknownException)
1105   - STD_EXCEPTION(0x1a00, ReservedA, UnknownException)
1106   - STD_EXCEPTION(0x1b00, ReservedB, UnknownException)
1107   -
1108   - STD_EXCEPTION(0x1c00, DataBreakpoint, UnknownException)
1109   - STD_EXCEPTION(0x1d00, InstructionBreakpoint, UnknownException)
1110   - STD_EXCEPTION(0x1e00, PeripheralBreakpoint, UnknownException)
1111   - STD_EXCEPTION(0x1f00, DevPortBreakpoint, UnknownException)
1112   -
1113   - CRIT_EXCEPTION(0x2000, DebugBreakpoint, DebugException )
1114   -
1115   - .globl _end_of_vectors
1116   -_end_of_vectors:
1117   -
1118   -
1119   - . = 0x2100
1120   -
1121 1092 /*
1122 1093 * This code finishes saving the registers to the exception frame
1123 1094 * and jumps to the appropriate handler for the exception.
1124 1095  
... ... @@ -1133,28 +1104,12 @@
1133 1104 SAVE_4GPRS(8, r21)
1134 1105 SAVE_8GPRS(12, r21)
1135 1106 SAVE_8GPRS(24, r21)
1136   -#if 0
1137   - andi. r23,r23,MSR_PR
1138   - mfspr r23,SPRG3 /* if from user, fix up tss.regs */
1139   - beq 2f
1140   - addi r24,r1,STACK_FRAME_OVERHEAD
1141   - stw r24,PT_REGS(r23)
1142   -2: addi r2,r23,-TSS /* set r2 to current */
1143   - tovirt(r2,r2,r23)
1144   -#endif
1145 1107 mflr r23
1146 1108 andi. r24,r23,0x3f00 /* get vector offset */
1147 1109 stw r24,TRAP(r21)
1148 1110 li r22,0
1149 1111 stw r22,RESULT(r21)
1150 1112 mtspr SPRG2,r22 /* r1 is now kernel sp */
1151   -#if 0
1152   - addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
1153   - cmplw 0,r1,r2
1154   - cmplw 1,r1,r24
1155   - crand 1,1,4
1156   - bgt stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
1157   -#endif
1158 1113 lwz r24,0(r23) /* virtual address of handler */
1159 1114 lwz r23,4(r23) /* where to go when done */
1160 1115 mtspr SRR0,r24
1161 1116  
... ... @@ -1215,16 +1170,64 @@
1215 1170 REST_GPR(31, r1)
1216 1171 lwz r2,_NIP(r1) /* Restore environment */
1217 1172 lwz r0,_MSR(r1)
1218   - mtspr 990,r2 /* SRR2 */
1219   - mtspr 991,r0 /* SRR3 */
  1173 + mtspr csrr0,r2
  1174 + mtspr csrr1,r0
1220 1175 lwz r0,GPR0(r1)
1221 1176 lwz r2,GPR2(r1)
1222 1177 lwz r1,GPR1(r1)
1223 1178 SYNC
1224 1179 rfci
1225 1180  
1226   -/* Cache functions.
1227   -*/
  1181 +#ifdef CONFIG_440
  1182 +mck_return:
  1183 + mfmsr r28 /* Disable interrupts */
  1184 + li r4,0
  1185 + ori r4,r4,MSR_EE
  1186 + andc r28,r28,r4
  1187 + SYNC /* Some chip revs need this... */
  1188 + mtmsr r28
  1189 + SYNC
  1190 + lwz r2,_CTR(r1)
  1191 + lwz r0,_LINK(r1)
  1192 + mtctr r2
  1193 + mtlr r0
  1194 + lwz r2,_XER(r1)
  1195 + lwz r0,_CCR(r1)
  1196 + mtspr XER,r2
  1197 + mtcrf 0xFF,r0
  1198 + REST_10GPRS(3, r1)
  1199 + REST_10GPRS(13, r1)
  1200 + REST_8GPRS(23, r1)
  1201 + REST_GPR(31, r1)
  1202 + lwz r2,_NIP(r1) /* Restore environment */
  1203 + lwz r0,_MSR(r1)
  1204 + mtspr mcsrr0,r2
  1205 + mtspr mcsrr1,r0
  1206 + lwz r0,GPR0(r1)
  1207 + lwz r2,GPR2(r1)
  1208 + lwz r1,GPR1(r1)
  1209 + SYNC
  1210 + rfmci
  1211 +#endif /* CONFIG_440 */
  1212 +
  1213 +
  1214 +/*
  1215 + * Cache functions.
  1216 + *
  1217 + * NOTE: currently the 440s run with dcache _disabled_ once relocated to DRAM,
  1218 + * although for some cache-ralated calls stubs have to be provided to satisfy
  1219 + * symbols resolution.
  1220 + *
  1221 + */
  1222 +#ifdef CONFIG_440
  1223 + .globl dcache_disable
  1224 +dcache_disable:
  1225 + blr
  1226 +
  1227 + .globl dcache_status
  1228 +dcache_status:
  1229 + blr
  1230 +#else
1228 1231 flush_dcache:
1229 1232 addis r9,r0,0x0002 /* set mask for EE and CE msr bits */
1230 1233 ori r9,r9,0x8000
1231 1234  
... ... @@ -1303,24 +1306,13 @@
1303 1306 mfdccr r3
1304 1307 srwi r3, r3, 31 /* >>31 => select bit 0 */
1305 1308 blr
  1309 +#endif
1306 1310  
1307 1311 .globl get_pvr
1308 1312 get_pvr:
1309 1313 mfspr r3, PVR
1310 1314 blr
1311 1315  
1312   -#if !defined(CONFIG_440)
1313   - .globl wr_pit
1314   -wr_pit:
1315   - mtspr pit, r3
1316   - blr
1317   -#endif
1318   -
1319   - .globl wr_tcr
1320   -wr_tcr:
1321   - mtspr tcr, r3
1322   - blr
1323   -
1324 1316 /*------------------------------------------------------------------------------- */
1325 1317 /* Function: out16 */
1326 1318 /* Description: Output 16 bits */
... ... @@ -1518,7 +1510,7 @@
1518 1510 * initialization, now running from RAM.
1519 1511 */
1520 1512  
1521   - addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET
  1513 + addi r0, r10, in_ram - _start + _START_OFFSET
1522 1514 mtlr r0
1523 1515 blr /* NEVER RETURNS! */
1524 1516  
... ... @@ -1588,7 +1580,7 @@
1588 1580 */
1589 1581 .globl trap_init
1590 1582 trap_init:
1591   - lwz r7, GOT(_start)
  1583 + lwz r7, GOT(_start_of_vectors)
1592 1584 lwz r8, GOT(_end_of_vectors)
1593 1585  
1594 1586 li r9, 0x100 /* reset vector always at 0x100 */
1595 1587  
1596 1588  
1597 1589  
1598 1590  
1599 1591  
... ... @@ -1608,35 +1600,48 @@
1608 1600 /*
1609 1601 * relocate `hdlr' and `int_return' entries
1610 1602 */
1611   - li r7, .L_MachineCheck - _start + EXC_OFF_SYS_RESET
1612   - li r8, Alignment - _start + EXC_OFF_SYS_RESET
  1603 + li r7, .L_MachineCheck - _start + _START_OFFSET
  1604 + li r8, Alignment - _start + _START_OFFSET
1613 1605 2:
1614 1606 bl trap_reloc
1615   - addi r7, r7, 0x100 /* next exception vector */
  1607 + addi r7, r7, 0x100 /* next exception vector */
1616 1608 cmplw 0, r7, r8
1617 1609 blt 2b
1618 1610  
1619   - li r7, .L_Alignment - _start + EXC_OFF_SYS_RESET
  1611 + li r7, .L_Alignment - _start + _START_OFFSET
1620 1612 bl trap_reloc
1621 1613  
1622   - li r7, .L_ProgramCheck - _start + EXC_OFF_SYS_RESET
  1614 + li r7, .L_ProgramCheck - _start + _START_OFFSET
1623 1615 bl trap_reloc
1624 1616  
1625   - li r7, .L_FPUnavailable - _start + EXC_OFF_SYS_RESET
1626   - li r8, SystemCall - _start + EXC_OFF_SYS_RESET
1627   -3:
1628   - bl trap_reloc
1629   - addi r7, r7, 0x100 /* next exception vector */
1630   - cmplw 0, r7, r8
1631   - blt 3b
  1617 +#ifdef CONFIG_440
  1618 + li r7, .L_FPUnavailable - _start + _START_OFFSET
  1619 + bl trap_reloc
1632 1620  
1633   - li r7, .L_SingleStep - _start + EXC_OFF_SYS_RESET
1634   - li r8, _end_of_vectors - _start + EXC_OFF_SYS_RESET
1635   -4:
1636   - bl trap_reloc
1637   - addi r7, r7, 0x100 /* next exception vector */
1638   - cmplw 0, r7, r8
1639   - blt 4b
  1621 + li r7, .L_Decrementer - _start + _START_OFFSET
  1622 + bl trap_reloc
  1623 +
  1624 + li r7, .L_APU - _start + _START_OFFSET
  1625 + bl trap_reloc
  1626 +
  1627 + li r7, .L_InstructionTLBError - _start + _START_OFFSET
  1628 + bl trap_reloc
  1629 +
  1630 + li r7, .L_DataTLBError - _start + _START_OFFSET
  1631 + bl trap_reloc
  1632 +#else /* CONFIG_440 */
  1633 + li r7, .L_PIT - _start + _START_OFFSET
  1634 + bl trap_reloc
  1635 +
  1636 + li r7, .L_InstructionTLBMiss - _start + _START_OFFSET
  1637 + bl trap_reloc
  1638 +
  1639 + li r7, .L_DataTLBMiss - _start + _START_OFFSET
  1640 + bl trap_reloc
  1641 +#endif /* CONFIG_440 */
  1642 +
  1643 + li r7, .L_DebugBreakpoint - _start + _START_OFFSET
  1644 + bl trap_reloc
1640 1645  
1641 1646 #if !defined(CONFIG_440)
1642 1647 addi r7,r0,0x1000 /* set ME bit (Machine Exceptions) */
... ... @@ -36,6 +36,8 @@
36 36 #include <command.h>
37 37 #include <asm/processor.h>
38 38  
  39 +DECLARE_GLOBAL_DATA_PTR;
  40 +
39 41 #if (CONFIG_COMMANDS & CFG_CMD_KGDB)
40 42 int (*debugger_exception_handler)(struct pt_regs *) = 0;
41 43 #endif
42 44  
... ... @@ -45,9 +47,8 @@
45 47  
46 48 /* THIS NEEDS CHANGING to use the board info structure.
47 49 */
48   -#define END_OF_MEM 0x00400000
  50 +#define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
49 51  
50   -
51 52 static __inline__ void set_tsr(unsigned long val)
52 53 {
53 54 #if defined(CONFIG_440)
54 55  
55 56  
56 57  
... ... @@ -88,29 +89,29 @@
88 89 void
89 90 print_backtrace(unsigned long *sp)
90 91 {
91   - int cnt = 0;
92   - unsigned long i;
  92 + int cnt = 0;
  93 + unsigned long i;
93 94  
94   - printf("Call backtrace: ");
95   - while (sp) {
96   - if ((uint)sp > END_OF_MEM)
97   - break;
  95 + printf("Call backtrace: ");
  96 + while (sp) {
  97 + if ((uint)sp > END_OF_MEM)
  98 + break;
98 99  
99   - i = sp[1];
100   - if (cnt++ % 7 == 0)
101   - printf("\n");
102   - printf("%08lX ", i);
103   - if (cnt > 32) break;
104   - sp = (unsigned long *)*sp;
105   - }
106   - printf("\n");
  100 + i = sp[1];
  101 + if (cnt++ % 7 == 0)
  102 + printf("\n");
  103 + printf("%08lX ", i);
  104 + if (cnt > 32) break;
  105 + sp = (unsigned long *)*sp;
  106 + }
  107 + printf("\n");
107 108 }
108 109  
109 110 void show_regs(struct pt_regs * regs)
110 111 {
111 112 int i;
112 113  
113   - printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
  114 + printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DEAR: %08lX\n",
114 115 regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
115 116 printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
116 117 regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
117 118  
... ... @@ -139,14 +140,14 @@
139 140 {
140 141 show_regs(regs);
141 142 print_backtrace((unsigned long *)regs->gpr[1]);
142   - panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
  143 + panic("Exception");
143 144 }
144 145  
145 146 void
146 147 MachineCheckException(struct pt_regs *regs)
147 148 {
148   - unsigned long fixup;
149   -
  149 + unsigned long fixup, val;
  150 +
150 151 /* Probing PCI using config cycles cause this exception
151 152 * when a device is not present. Catch it and return to
152 153 * the PCI exception handler.
153 154  
154 155  
... ... @@ -161,26 +162,50 @@
161 162 return;
162 163 #endif
163 164  
164   - printf("Machine check in kernel mode.\n");
  165 + printf("Machine Check Exception.\n");
165 166 printf("Caused by (from msr): ");
166   - printf("regs %p ",regs);
167   - switch( regs->msr & 0x000F0000) {
168   - case (0x80000000>>12):
169   - printf("Machine check signal - probably due to mm fault\n"
170   - "with mmu off\n");
171   - break;
172   - case (0x80000000>>13):
173   - printf("Transfer error ack signal\n");
174   - break;
175   - case (0x80000000>>14):
176   - printf("Data parity signal\n");
177   - break;
178   - case (0x80000000>>15):
179   - printf("Address parity signal\n");
180   - break;
181   - default:
182   - printf("Unknown values in msr\n");
  167 + printf("regs %p ", regs);
  168 +
  169 + val = get_esr();
  170 +
  171 +#if !defined(CONFIG_440)
  172 + if (val& ESR_IMCP) {
  173 + printf("Instruction");
  174 + mtspr(ESR, val & ~ESR_IMCP);
  175 + } else
  176 + printf("Data");
  177 + printf(" machine check.\n");
  178 +
  179 +#elif defined(CONFIG_440)
  180 + if (val& ESR_IMCP){
  181 + printf("Instruction Synchronous Machine Check exception\n");
  182 + mtspr(SPRN_ESR, val & ~ESR_IMCP);
183 183 }
  184 + else {
  185 + val = mfspr(MCSR);
  186 + if (val & MCSR_IB)
  187 + printf("Instruction Read PLB Error\n");
  188 + if (val & MCSR_DRB)
  189 + printf("Data Read PLB Error\n");
  190 + if (val & MCSR_DWB)
  191 + printf("Data Write PLB Error\n");
  192 + if (val & MCSR_TLBP)
  193 + printf("TLB Parity Error\n");
  194 + if (val & MCSR_ICP){
  195 + /*flush_instruction_cache(); */
  196 + printf("I-Cache Parity Error\n");
  197 + }
  198 + if (val & MCSR_DCSP)
  199 + printf("D-Cache Search Parity Error\n");
  200 + if (val & MCSR_DCFP)
  201 + printf("D-Cache Flush Parity Error\n");
  202 + if (val & MCSR_IMPE)
  203 + printf("Machine Check exception is imprecise\n");
  204 +
  205 + /* Clear MCSR */
  206 + mtspr(SPRN_MCSR, val);
  207 + }
  208 +#endif
184 209 show_regs(regs);
185 210 print_backtrace((unsigned long *)regs->gpr[1]);
186 211 panic("machine check");
... ... @@ -224,7 +249,7 @@
224 249 }
225 250  
226 251 void
227   -PITException(struct pt_regs *regs)
  252 +DecrementerPITException(struct pt_regs *regs)
228 253 {
229 254 /*
230 255 * Reset PIT interrupt
include/asm-ppc/processor.h
... ... @@ -308,7 +308,7 @@
308 308 #define SPRN_SRR0 0x01A /* Save/Restore Register 0 */
309 309 #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */
310 310 #define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */
311   -#define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */
  311 +#define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */
312 312 #ifdef CONFIG_BOOKE
313 313 #define SPRN_SVR 0x3FF /* System Version Register */
314 314 #else
... ... @@ -451,6 +451,17 @@
451 451 #define SPRN_PID1 0x279 /* Process ID Register 1 */
452 452 #define SPRN_PID2 0x27a /* Process ID Register 2 */
453 453 #define SPRN_MCSR 0x23c /* Machine Check Syndrome register */
  454 +#ifdef CONFIG_440
  455 +#define MCSR_MCS 0x80000000 /* Machine Check Summary */
  456 +#define MCSR_IB 0x40000000 /* Instruction PLB Error */
  457 +#define MCSR_DRB 0x20000000 /* Data Read PLB Error */
  458 +#define MCSR_DWB 0x10000000 /* Data Write PLB Error */
  459 +#define MCSR_TLBP 0x08000000 /* TLB Parity Error */
  460 +#define MCSR_ICP 0x04000000 /* I-Cache Parity Error */
  461 +#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */
  462 +#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */
  463 +#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */
  464 +#endif
454 465 #define ESR_ST 0x00800000 /* Store Operation */
455 466  
456 467 #if defined(CONFIG_MPC86xx)
... ... @@ -544,6 +555,8 @@
544 555 #define SPRG7 SPRN_SPRG7
545 556 #define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */
546 557 #define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */
  558 +#define SRR2 SPRN_SRR2 /* Save and Restore Register 2 */
  559 +#define SRR3 SPRN_SRR3 /* Save and Restore Register 3 */
547 560 #define SVR SPRN_SVR /* System Version Register */
548 561 #define TBRL SPRN_TBRL /* Time Base Read Lower Register */
549 562 #define TBRU SPRN_TBRU /* Time Base Read Upper Register */
include/configs/CPCI440.h
... ... @@ -33,6 +33,7 @@
33 33 *----------------------------------------------------------------------*/
34 34 #define CONFIG_CPCI440 1 /* Board is ebony */
35 35 #define CONFIG_440GP 1 /* Specifc GP support */
  36 +#define CONFIG_440 1 /* ... PPC440 family */
36 37 #define CONFIG_4xx 1 /* ... PPC4xx family */
37 38 #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */
38 39 #undef CFG_DRAM_TEST /* Disable-takes long time! */
include/configs/KAREF.h
... ... @@ -38,6 +38,7 @@
38 38 *----------------------------------------------------------------------*/
39 39 #define CONFIG_KAREF 1 /* Board is Kamino Ref Variant */
40 40 #define CONFIG_440GX 1 /* Specifc GX support */
  41 +#define CONFIG_440 1 /* ... PPC440 family */
41 42 #define CONFIG_4xx 1 /* ... PPC4xx family */
42 43 #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */
43 44 #define CONFIG_MISC_INIT_F 1 /* Call board misc_init_f */
include/configs/METROBOX.h
... ... @@ -104,6 +104,7 @@
104 104 *----------------------------------------------------------------------*/
105 105 #define CONFIG_METROBOX 1 /* Board is Metrobox */
106 106 #define CONFIG_440GX 1 /* Specifc GX support */
  107 +#define CONFIG_440 1 /* ... PPC440 family */
107 108 #define CONFIG_4xx 1 /* ... PPC4xx family */
108 109 #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */
109 110 #define CONFIG_MISC_INIT_F 1 /* Call board misc_init_f */
include/configs/alpr.h
... ... @@ -29,6 +29,7 @@
29 29 *----------------------------------------------------------------------*/
30 30 #define CONFIG_ALPR 1 /* Board is ebony */
31 31 #define CONFIG_440GX 1 /* Specifc GX support */
  32 +#define CONFIG_440 1 /* ... PPC440 family */
32 33 #define CONFIG_4xx 1 /* ... PPC4xx family */
33 34 #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */
34 35 #define CONFIG_LAST_STAGE_INIT 1 /* call last_stage_init() */
include/configs/bamboo.h
... ... @@ -32,6 +32,7 @@
32 32 *----------------------------------------------------------------------*/
33 33 #define CONFIG_BAMBOO 1 /* Board is BAMBOO */
34 34 #define CONFIG_440EP 1 /* Specific PPC440EP support */
  35 +#define CONFIG_440 1 /* ... PPC440 family */
35 36 #define CONFIG_4xx 1 /* ... PPC4xx family */
36 37 #define CONFIG_SYS_CLK_FREQ 33333333 /* external freq to pll */
37 38  
include/configs/ebony.h
... ... @@ -32,6 +32,7 @@
32 32 *----------------------------------------------------------------------*/
33 33 #define CONFIG_EBONY 1 /* Board is ebony */
34 34 #define CONFIG_440GP 1 /* Specifc GP support */
  35 +#define CONFIG_440 1 /* ... PPC440 family */
35 36 #define CONFIG_4xx 1 /* ... PPC4xx family */
36 37 #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */
37 38 #undef CFG_DRAM_TEST /* Disable-takes long time! */
include/configs/katmai.h
... ... @@ -29,7 +29,7 @@
29 29  
30 30 #ifndef __CONFIG_H
31 31 #define __CONFIG_H
32   -
  32 +//#define DEBUG
33 33 /*-----------------------------------------------------------------------
34 34 * High Level Configuration Options
35 35 *----------------------------------------------------------------------*/
include/configs/ocotea.h
... ... @@ -41,6 +41,7 @@
41 41 *----------------------------------------------------------------------*/
42 42 #define CONFIG_OCOTEA 1 /* Board is ebony */
43 43 #define CONFIG_440GX 1 /* Specifc GX support */
  44 +#define CONFIG_440 1 /* ... PPC440 family */
44 45 #define CONFIG_4xx 1 /* ... PPC4xx family */
45 46 #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_pre_init */
46 47 #undef CFG_DRAM_TEST /* Disable-takes long time! */
include/configs/p3p440.h
... ... @@ -35,6 +35,7 @@
35 35 *----------------------------------------------------------------------*/
36 36 #define CONFIG_P3P440 1 /* Board is P3P440 */
37 37 #define CONFIG_440GP 1 /* Specifc GP support */
  38 +#define CONFIG_440 1 /* ... PPC440 family */
38 39 #define CONFIG_4xx 1 /* ... PPC4xx family */
39 40 #define CONFIG_BOARD_EARLY_INIT_F 1 /* Call board_early_init_f */
40 41 #define CONFIG_MISC_INIT_R 1 /* Call misc_init_r */
include/configs/pcs440ep.h
... ... @@ -32,6 +32,7 @@
32 32 *----------------------------------------------------------------------*/
33 33 #define CONFIG_PCS440EP 1 /* Board is PCS440EP */
34 34 #define CONFIG_440EP 1 /* Specific PPC440EP support */
  35 +#define CONFIG_440 1 /* ... PPC440 family */
35 36 #define CONFIG_4xx 1 /* ... PPC4xx family */
36 37 #define CONFIG_SYS_CLK_FREQ 33333333 /* external freq to pll */
37 38  
include/configs/sequoia.h
... ... @@ -37,6 +37,7 @@
37 37 #else
38 38 #define CONFIG_440GRX 1 /* Specific PPC440GRx */
39 39 #endif
  40 +#define CONFIG_440 1 /* ... PPC440 family */
40 41 #define CONFIG_4xx 1 /* ... PPC4xx family */
41 42 /* Detect Sequoia PLL input clock automatically via CPLD bit */
42 43 #define CONFIG_SYS_CLK_FREQ ((in8(CFG_BCSR_BASE + 3) & 0x80) ? \
include/configs/taishan.h
... ... @@ -30,6 +30,7 @@
30 30 *----------------------------------------------------------------------*/
31 31 #define CONFIG_TAISHAN 1 /* Board is taishan */
32 32 #define CONFIG_440GX 1 /* Specifc GX support */
  33 +#define CONFIG_440 1 /* ... PPC440 family */
33 34 #define CONFIG_4xx 1 /* ... PPC4xx family */
34 35 #undef CFG_DRAM_TEST /* Disable-takes long time! */
35 36 #define CONFIG_SYS_CLK_FREQ 33333333 /* external freq to pll */
include/configs/yosemite.h
... ... @@ -38,6 +38,7 @@
38 38 #define CONFIG_440GR 1 /* Specific PPC440GR support */
39 39 #define CONFIG_HOSTNAME yellowstone
40 40 #endif
  41 +#define CONFIG_440 1 /* ... PPC440 family */
41 42 #define CONFIG_4xx 1 /* ... PPC4xx family */
42 43 #define CONFIG_SYS_CLK_FREQ 66666666 /* external freq to pll */
43 44  
... ... @@ -27,6 +27,15 @@
27 27 /*--------------------------------------------------------------------- */
28 28 #define srr2 0x3de /* save/restore register 2 */
29 29 #define srr3 0x3df /* save/restore register 3 */
  30 +
  31 + /*
  32 + * 405 does not really have CSRR0/1 but SRR2/3 are used during critical
  33 + * exception for the exact same purposes - let's alias them and have a
  34 + * common handling in crit_return() and CRIT_EXCEPTION
  35 + */
  36 + #define csrr0 srr2
  37 + #define csrr1 srr3
  38 +
30 39 #define dbsr 0x3f0 /* debug status register */
31 40 #define dbcr0 0x3f2 /* debug control register 0 */
32 41 #define dbcr1 0x3bd /* debug control register 1 */
... ... @@ -82,10 +82,7 @@
82 82 #define ivor13 0x19d /* interrupt vector offset register 13 */
83 83 #define ivor14 0x19e /* interrupt vector offset register 14 */
84 84 #define ivor15 0x19f /* interrupt vector offset register 15 */
85   -#if defined(CONFIG_440GX) || \
86   - defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
87   - defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
88   - defined(CONFIG_440SP) || defined(CONFIG_440SPE)
  85 +#if defined(CONFIG_440)
89 86 #define mcsrr0 0x23a /* machine check save/restore register 0 */
90 87 #define mcsrr1 0x23b /* mahcine check save/restore register 1 */
91 88 #define mcsr 0x23c /* machine check status register */
... ... @@ -22,6 +22,7 @@
22 22 #ifndef __PPC4XX_H__
23 23 #define __PPC4XX_H__
24 24  
  25 +#define _START_OFFSET 0x2100
25 26  
26 27 #if defined(CONFIG_440)
27 28 #include <ppc440.h>
include/ppc_asm.tmpl
... ... @@ -217,7 +217,7 @@
217 217 * We assume sprg3 has the physical address of the current
218 218 * task's thread_struct.
219 219 */
220   -#define EXCEPTION_PROLOG \
  220 +#define EXCEPTION_PROLOG(reg1, reg2) \
221 221 mtspr SPRG0,r20; \
222 222 mtspr SPRG1,r21; \
223 223 mfcr r20; \
... ... @@ -235,8 +235,10 @@
235 235 stw r22,_CTR(r21); \
236 236 mfspr r20,XER; \
237 237 stw r20,_XER(r21); \
238   - mfspr r22,SRR0; \
239   - mfspr r23,SRR1; \
  238 + mfspr r20,DEAR; \
  239 + stw r20,_DAR(r21); \
  240 + mfspr r22,reg1; \
  241 + mfspr r23,reg2; \
240 242 stw r0,GPR0(r21); \
241 243 stw r1,GPR1(r21); \
242 244 stw r2,GPR2(r21); \
... ... @@ -249,41 +251,6 @@
249 251 */
250 252  
251 253 /*
252   - * Critical exception entry code. This is just like the other exception
253   - * code except that it uses SRR2 and SRR3 instead of SRR0 and SRR1.
254   - */
255   -#define CRITICAL_EXCEPTION_PROLOG \
256   - mtspr SPRG0,r20; \
257   - mtspr SPRG1,r21; \
258   - mfcr r20; \
259   - subi r21,r1,INT_FRAME_SIZE+STACK_UNDERHEAD; /* alloc exc. frame */\
260   - stw r20,_CCR(r21); /* save registers */ \
261   - stw r22,GPR22(r21); \
262   - stw r23,GPR23(r21); \
263   - mfspr r20,SPRG0; \
264   - stw r20,GPR20(r21); \
265   - mfspr r22,SPRG1; \
266   - stw r22,GPR21(r21); \
267   - mflr r20; \
268   - stw r20,_LINK(r21); \
269   - mfctr r22; \
270   - stw r22,_CTR(r21); \
271   - mfspr r20,XER; \
272   - stw r20,_XER(r21); \
273   - mfspr r22,990; /* SRR2 */ \
274   - mfspr r23,991; /* SRR3 */ \
275   - stw r0,GPR0(r21); \
276   - stw r1,GPR1(r21); \
277   - stw r2,GPR2(r21); \
278   - stw r1,0(r21); \
279   - mr r1,r21; /* set new kernel sp */ \
280   - SAVE_4GPRS(3, r21);
281   -/*
282   - * Note: code which follows this uses cr0.eq (set if from kernel),
283   - * r21, r22 (SRR2), and r23 (SRR3).
284   - */
285   -
286   -/*
287 254 * Exception vectors.
288 255 *
289 256 * The data words for `hdlr' and `int_return' are initialized with
290 257  
291 258  
292 259  
293 260  
... ... @@ -293,31 +260,46 @@
293 260 #define STD_EXCEPTION(n, label, hdlr) \
294 261 . = n; \
295 262 label: \
296   - EXCEPTION_PROLOG; \
  263 + EXCEPTION_PROLOG(SRR0, SRR1); \
297 264 lwz r3,GOT(transfer_to_handler); \
298 265 mtlr r3; \
299 266 addi r3,r1,STACK_FRAME_OVERHEAD; \
300 267 li r20,MSR_KERNEL; \
301 268 rlwimi r20,r23,0,25,25; \
302   - blrl ; \
  269 + blrl; \
303 270 .L_ ## label : \
304   - .long hdlr - _start + EXC_OFF_SYS_RESET; \
305   - .long int_return - _start + EXC_OFF_SYS_RESET
  271 + .long hdlr - _start + _START_OFFSET; \
  272 + .long int_return - _start + _START_OFFSET
306 273  
  274 +#define CRIT_EXCEPTION(n, label, hdlr) \
  275 + . = n; \
  276 +label: \
  277 + EXCEPTION_PROLOG(csrr0, csrr1); \
  278 + lwz r3,GOT(transfer_to_handler); \
  279 + mtlr r3; \
  280 + addi r3,r1,STACK_FRAME_OVERHEAD; \
  281 + li r20,(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)); \
  282 + rlwimi r20,r23,0,25,25; \
  283 + blrl; \
  284 +.L_ ## label : \
  285 + .long hdlr - _start + _START_OFFSET; \
  286 + .long crit_return - _start + _START_OFFSET
307 287  
308   -#define CRIT_EXCEPTION(n, label, hdlr) \
309   - . = n; \
310   -label: \
311   - CRITICAL_EXCEPTION_PROLOG; \
312   - lwz r3,GOT(transfer_to_handler); \
313   - mtlr r3; \
314   - addi r3,r1,STACK_FRAME_OVERHEAD; \
315   - li r20,(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)); \
316   - rlwimi r20,r23,0,25,25; \
317   - blrl ; \
318   -.L_ ## label : \
319   - .long hdlr - _start + EXC_OFF_SYS_RESET; \
320   - .long crit_return - _start + EXC_OFF_SYS_RESET
  288 +#ifdef CONFIG_440
  289 +#define MCK_EXCEPTION(n, label, hdlr) \
  290 + . = n; \
  291 +label: \
  292 + EXCEPTION_PROLOG(MCSRR0, MCSRR1); \
  293 + lwz r3,GOT(transfer_to_handler); \
  294 + mtlr r3; \
  295 + addi r3,r1,STACK_FRAME_OVERHEAD; \
  296 + li r20,(MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)); \
  297 + rlwimi r20,r23,0,25,25; \
  298 + blrl; \
  299 +.L_ ## label : \
  300 + .long hdlr - _start + _START_OFFSET; \
  301 + .long mck_return - _start + _START_OFFSET
  302 +#endif /* CONFIG_440 */
321 303  
322 304 #endif /* __PPC_ASM_TMPL__ */