]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/powerpc/cpu/mpc512x/traps.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / arch / powerpc / cpu / mpc512x / traps.c
CommitLineData
8993e54b
RJ
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 *
1a459660 7 * SPDX-License-Identifier: GPL-2.0+
8993e54b
RJ
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>
e39bf1e2 18#include <kgdb.h>
8993e54b
RJ
19#include <asm/processor.h>
20
21DECLARE_GLOBAL_DATA_PTR;
22
23extern unsigned long search_exception_table(unsigned long);
24
9b124a68
BB
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 */
30extern ulong get_effective_memsize(void);
31#define END_OF_MEM (gd->bd->bi_memstart + get_effective_memsize())
8993e54b
RJ
32
33/*
34 * Trap & Exception support
35 */
36
20051f2a 37static void print_backtrace(unsigned long *sp)
8993e54b
RJ
38{
39 int cnt = 0;
40 unsigned long i;
41
20051f2a 42 puts("Call backtrace: ");
8993e54b
RJ
43 while (sp) {
44 if ((uint)sp > END_OF_MEM)
45 break;
46
47 i = sp[1];
48 if (cnt++ % 7 == 0)
20051f2a
KP
49 putc('\n');
50 printf("%08lX ", i);
8993e54b
RJ
51 if (cnt > 32) break;
52 sp = (unsigned long *) *sp;
53 }
20051f2a 54 putc('\n');
8993e54b
RJ
55}
56
20051f2a 57void show_regs(struct pt_regs *regs)
8993e54b
RJ
58{
59 int i;
60
20051f2a 61 printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
8993e54b 62 regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
20051f2a 63 printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
8993e54b
RJ
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
20051f2a 69 putc('\n');
8993e54b
RJ
70 for (i = 0; i < 32; i++) {
71 if ((i % 8) == 0) {
20051f2a 72 printf("GPR%02d: ", i);
8993e54b
RJ
73 }
74
20051f2a 75 printf("%08lX ", regs->gpr[i]);
8993e54b 76 if ((i % 8) == 7) {
20051f2a 77 putc('\n');
8993e54b
RJ
78 }
79 }
80}
81
82
20051f2a 83static void _exception(int signr, struct pt_regs *regs)
8993e54b 84{
20051f2a
KP
85 show_regs(regs);
86 print_backtrace((unsigned long *)regs->gpr[1]);
87 panic("Exception at pc %lx signal %d", regs->nip, signr);
8993e54b
RJ
88}
89
90
20051f2a 91void MachineCheckException(struct pt_regs *regs)
8993e54b 92{
20051f2a 93 unsigned long fixup = search_exception_table(regs->nip);
8993e54b 94
20051f2a 95 if (fixup) {
8993e54b
RJ
96 regs->nip = fixup;
97 return;
98 }
99
afaac86f 100#ifdef CONFIG_CMD_KGDB
8993e54b
RJ
101 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
102 return;
103#endif
104
20051f2a
KP
105 puts("Machine check.\nCaused by (from msr): ");
106 printf("regs %p ", regs);
8993e54b
RJ
107 switch (regs->msr & 0x00FF0000) {
108 case (0x80000000 >> 10):
20051f2a 109 puts("Instruction cache parity signal\n");
8993e54b
RJ
110 break;
111 case (0x80000000 >> 11):
20051f2a 112 puts("Data cache parity signal\n");
8993e54b
RJ
113 break;
114 case (0x80000000 >> 12):
20051f2a 115 puts("Machine check signal\n");
8993e54b
RJ
116 break;
117 case (0x80000000 >> 13):
20051f2a 118 puts("Transfer error ack signal\n");
8993e54b
RJ
119 break;
120 case (0x80000000 >> 14):
20051f2a 121 puts("Data parity signal\n");
8993e54b
RJ
122 break;
123 case (0x80000000 >> 15):
20051f2a 124 puts("Address parity signal\n");
8993e54b
RJ
125 break;
126 default:
20051f2a 127 puts("Unknown values in msr\n");
8993e54b 128 }
20051f2a
KP
129 show_regs(regs);
130 print_backtrace((unsigned long *)regs->gpr[1]);
8993e54b 131
20051f2a 132 panic("machine check");
8993e54b
RJ
133}
134
20051f2a 135void AlignmentException(struct pt_regs *regs)
8993e54b 136{
afaac86f 137#ifdef CONFIG_CMD_KGDB
8993e54b
RJ
138 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
139 return;
140#endif
20051f2a
KP
141 show_regs(regs);
142 print_backtrace((unsigned long *)regs->gpr[1]);
143 panic("Alignment Exception");
8993e54b
RJ
144}
145
20051f2a 146void ProgramCheckException(struct pt_regs *regs)
8993e54b 147{
afaac86f 148#ifdef CONFIG_CMD_KGDB
8993e54b
RJ
149 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
150 return;
151#endif
20051f2a
KP
152 show_regs(regs);
153 print_backtrace((unsigned long *)regs->gpr[1]);
154 panic("Program Check Exception");
8993e54b
RJ
155}
156
20051f2a 157void SoftEmuException(struct pt_regs *regs)
8993e54b 158{
afaac86f 159#ifdef CONFIG_CMD_KGDB
8993e54b
RJ
160 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
161 return;
162#endif
20051f2a
KP
163 show_regs(regs);
164 print_backtrace((unsigned long *)regs->gpr[1]);
165 panic("Software Emulation Exception");
8993e54b
RJ
166}
167
168
20051f2a 169void UnknownException(struct pt_regs *regs)
8993e54b 170{
afaac86f 171#ifdef CONFIG_CMD_KGDB
8993e54b
RJ
172 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
173 return;
174#endif
20051f2a 175 printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
8993e54b 176 regs->nip, regs->msr, regs->trap);
20051f2a 177 _exception(0, regs);
8993e54b
RJ
178}
179
afaac86f 180#ifdef CONFIG_CMD_BEDBUG
20051f2a 181extern void do_bedbug_breakpoint(struct pt_regs *);
8993e54b
RJ
182#endif
183
20051f2a 184void DebugException(struct pt_regs *regs)
8993e54b 185{
20051f2a
KP
186 printf("Debugger trap at @ %lx\n", regs->nip);
187 show_regs(regs);
afaac86f 188#ifdef CONFIG_CMD_BEDBUG
20051f2a 189 do_bedbug_breakpoint(regs);
8993e54b
RJ
190#endif
191}