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