1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <common.h>
31#include <kgdb.h>
32#include <asm/processor.h>
33
34DECLARE_GLOBAL_DATA_PTR;
35
36extern unsigned long search_exception_table(unsigned long);
37
38
39
40
41
42
43extern ulong get_effective_memsize(void);
44#define END_OF_MEM (gd->bd->bi_memstart + get_effective_memsize())
45
46
47
48
49
50static void print_backtrace(unsigned long *sp)
51{
52 int cnt = 0;
53 unsigned long i;
54
55 puts("Call backtrace: ");
56 while (sp) {
57 if ((uint)sp > END_OF_MEM)
58 break;
59
60 i = sp[1];
61 if (cnt++ % 7 == 0)
62 putc('\n');
63 printf("%08lX ", i);
64 if (cnt > 32) break;
65 sp = (unsigned long *) *sp;
66 }
67 putc('\n');
68}
69
70void show_regs(struct pt_regs *regs)
71{
72 int i;
73
74 printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
75 regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
76 printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
77 regs->msr, regs->msr & MSR_EE ? 1 : 0, regs->msr & MSR_PR ? 1 : 0,
78 regs->msr & MSR_FP ? 1 : 0,regs->msr & MSR_ME ? 1 : 0,
79 regs->msr & MSR_IR ? 1 : 0,
80 regs->msr & MSR_DR ? 1 : 0);
81
82 putc('\n');
83 for (i = 0; i < 32; i++) {
84 if ((i % 8) == 0) {
85 printf("GPR%02d: ", i);
86 }
87
88 printf("%08lX ", regs->gpr[i]);
89 if ((i % 8) == 7) {
90 putc('\n');
91 }
92 }
93}
94
95
96static void _exception(int signr, struct pt_regs *regs)
97{
98 show_regs(regs);
99 print_backtrace((unsigned long *)regs->gpr[1]);
100 panic("Exception at pc %lx signal %d", regs->nip, signr);
101}
102
103
104void MachineCheckException(struct pt_regs *regs)
105{
106 unsigned long fixup = search_exception_table(regs->nip);
107
108 if (fixup) {
109 regs->nip = fixup;
110 return;
111 }
112
113#ifdef CONFIG_CMD_KGDB
114 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
115 return;
116#endif
117
118 puts("Machine check.\nCaused by (from msr): ");
119 printf("regs %p ", regs);
120 switch (regs->msr & 0x00FF0000) {
121 case (0x80000000 >> 10):
122 puts("Instruction cache parity signal\n");
123 break;
124 case (0x80000000 >> 11):
125 puts("Data cache parity signal\n");
126 break;
127 case (0x80000000 >> 12):
128 puts("Machine check signal\n");
129 break;
130 case (0x80000000 >> 13):
131 puts("Transfer error ack signal\n");
132 break;
133 case (0x80000000 >> 14):
134 puts("Data parity signal\n");
135 break;
136 case (0x80000000 >> 15):
137 puts("Address parity signal\n");
138 break;
139 default:
140 puts("Unknown values in msr\n");
141 }
142 show_regs(regs);
143 print_backtrace((unsigned long *)regs->gpr[1]);
144
145 panic("machine check");
146}
147
148void AlignmentException(struct pt_regs *regs)
149{
150#ifdef CONFIG_CMD_KGDB
151 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
152 return;
153#endif
154 show_regs(regs);
155 print_backtrace((unsigned long *)regs->gpr[1]);
156 panic("Alignment Exception");
157}
158
159void ProgramCheckException(struct pt_regs *regs)
160{
161#ifdef CONFIG_CMD_KGDB
162 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
163 return;
164#endif
165 show_regs(regs);
166 print_backtrace((unsigned long *)regs->gpr[1]);
167 panic("Program Check Exception");
168}
169
170void SoftEmuException(struct pt_regs *regs)
171{
172#ifdef CONFIG_CMD_KGDB
173 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
174 return;
175#endif
176 show_regs(regs);
177 print_backtrace((unsigned long *)regs->gpr[1]);
178 panic("Software Emulation Exception");
179}
180
181
182void UnknownException(struct pt_regs *regs)
183{
184#ifdef CONFIG_CMD_KGDB
185 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
186 return;
187#endif
188 printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
189 regs->nip, regs->msr, regs->trap);
190 _exception(0, regs);
191}
192
193#ifdef CONFIG_CMD_BEDBUG
194extern void do_bedbug_breakpoint(struct pt_regs *);
195#endif
196
197void DebugException(struct pt_regs *regs)
198{
199 printf("Debugger trap at @ %lx\n", regs->nip);
200 show_regs(regs);
201#ifdef CONFIG_CMD_BEDBUG
202 do_bedbug_breakpoint(regs);
203#endif
204}
205