blob: 10169912b7f2e614e180d025aa61810c3664a62d [file] [log] [blame]
Rafal Jaworowski8993e542007-07-27 14:43:59 +02001/*
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 *
Wolfgang Denk1a459662013-07-08 09:37:19 +02007 * SPDX-License-Identifier: GPL-2.0+
Rafal Jaworowski8993e542007-07-27 14:43:59 +02008 *
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>
Mike Frysingere39bf1e2010-02-08 15:30:16 -050018#include <kgdb.h>
Rafal Jaworowski8993e542007-07-27 14:43:59 +020019#include <asm/processor.h>
20
21DECLARE_GLOBAL_DATA_PTR;
22
23extern unsigned long search_exception_table(unsigned long);
24
Becky Bruce9b124a62008-05-14 13:09:51 -050025/*
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())
Rafal Jaworowski8993e542007-07-27 14:43:59 +020032
33/*
34 * Trap & Exception support
35 */
36
Kim Phillips20051f22012-10-29 13:34:29 +000037static void print_backtrace(unsigned long *sp)
Rafal Jaworowski8993e542007-07-27 14:43:59 +020038{
39 int cnt = 0;
40 unsigned long i;
41
Kim Phillips20051f22012-10-29 13:34:29 +000042 puts("Call backtrace: ");
Rafal Jaworowski8993e542007-07-27 14:43:59 +020043 while (sp) {
44 if ((uint)sp > END_OF_MEM)
45 break;
46
47 i = sp[1];
48 if (cnt++ % 7 == 0)
Kim Phillips20051f22012-10-29 13:34:29 +000049 putc('\n');
50 printf("%08lX ", i);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020051 if (cnt > 32) break;
52 sp = (unsigned long *) *sp;
53 }
Kim Phillips20051f22012-10-29 13:34:29 +000054 putc('\n');
Rafal Jaworowski8993e542007-07-27 14:43:59 +020055}
56
Kim Phillips20051f22012-10-29 13:34:29 +000057void show_regs(struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +020058{
59 int i;
60
Kim Phillips20051f22012-10-29 13:34:29 +000061 printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
Rafal Jaworowski8993e542007-07-27 14:43:59 +020062 regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
Kim Phillips20051f22012-10-29 13:34:29 +000063 printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
Rafal Jaworowski8993e542007-07-27 14:43:59 +020064 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
Kim Phillips20051f22012-10-29 13:34:29 +000069 putc('\n');
Rafal Jaworowski8993e542007-07-27 14:43:59 +020070 for (i = 0; i < 32; i++) {
71 if ((i % 8) == 0) {
Kim Phillips20051f22012-10-29 13:34:29 +000072 printf("GPR%02d: ", i);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020073 }
74
Kim Phillips20051f22012-10-29 13:34:29 +000075 printf("%08lX ", regs->gpr[i]);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020076 if ((i % 8) == 7) {
Kim Phillips20051f22012-10-29 13:34:29 +000077 putc('\n');
Rafal Jaworowski8993e542007-07-27 14:43:59 +020078 }
79 }
80}
81
82
Kim Phillips20051f22012-10-29 13:34:29 +000083static void _exception(int signr, struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +020084{
Kim Phillips20051f22012-10-29 13:34:29 +000085 show_regs(regs);
86 print_backtrace((unsigned long *)regs->gpr[1]);
87 panic("Exception at pc %lx signal %d", regs->nip, signr);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020088}
89
90
Kim Phillips20051f22012-10-29 13:34:29 +000091void MachineCheckException(struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +020092{
Kim Phillips20051f22012-10-29 13:34:29 +000093 unsigned long fixup = search_exception_table(regs->nip);
Rafal Jaworowski8993e542007-07-27 14:43:59 +020094
Kim Phillips20051f22012-10-29 13:34:29 +000095 if (fixup) {
Rafal Jaworowski8993e542007-07-27 14:43:59 +020096 regs->nip = fixup;
97 return;
98 }
99
Wolfgang Denkafaac862007-08-12 14:27:39 +0200100#ifdef CONFIG_CMD_KGDB
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200101 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
102 return;
103#endif
104
Kim Phillips20051f22012-10-29 13:34:29 +0000105 puts("Machine check.\nCaused by (from msr): ");
106 printf("regs %p ", regs);
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200107 switch (regs->msr & 0x00FF0000) {
108 case (0x80000000 >> 10):
Kim Phillips20051f22012-10-29 13:34:29 +0000109 puts("Instruction cache parity signal\n");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200110 break;
111 case (0x80000000 >> 11):
Kim Phillips20051f22012-10-29 13:34:29 +0000112 puts("Data cache parity signal\n");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200113 break;
114 case (0x80000000 >> 12):
Kim Phillips20051f22012-10-29 13:34:29 +0000115 puts("Machine check signal\n");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200116 break;
117 case (0x80000000 >> 13):
Kim Phillips20051f22012-10-29 13:34:29 +0000118 puts("Transfer error ack signal\n");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200119 break;
120 case (0x80000000 >> 14):
Kim Phillips20051f22012-10-29 13:34:29 +0000121 puts("Data parity signal\n");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200122 break;
123 case (0x80000000 >> 15):
Kim Phillips20051f22012-10-29 13:34:29 +0000124 puts("Address parity signal\n");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200125 break;
126 default:
Kim Phillips20051f22012-10-29 13:34:29 +0000127 puts("Unknown values in msr\n");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200128 }
Kim Phillips20051f22012-10-29 13:34:29 +0000129 show_regs(regs);
130 print_backtrace((unsigned long *)regs->gpr[1]);
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200131
Kim Phillips20051f22012-10-29 13:34:29 +0000132 panic("machine check");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200133}
134
Kim Phillips20051f22012-10-29 13:34:29 +0000135void AlignmentException(struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200136{
Wolfgang Denkafaac862007-08-12 14:27:39 +0200137#ifdef CONFIG_CMD_KGDB
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200138 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
139 return;
140#endif
Kim Phillips20051f22012-10-29 13:34:29 +0000141 show_regs(regs);
142 print_backtrace((unsigned long *)regs->gpr[1]);
143 panic("Alignment Exception");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200144}
145
Kim Phillips20051f22012-10-29 13:34:29 +0000146void ProgramCheckException(struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200147{
Wolfgang Denkafaac862007-08-12 14:27:39 +0200148#ifdef CONFIG_CMD_KGDB
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200149 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
150 return;
151#endif
Kim Phillips20051f22012-10-29 13:34:29 +0000152 show_regs(regs);
153 print_backtrace((unsigned long *)regs->gpr[1]);
154 panic("Program Check Exception");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200155}
156
Kim Phillips20051f22012-10-29 13:34:29 +0000157void SoftEmuException(struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200158{
Wolfgang Denkafaac862007-08-12 14:27:39 +0200159#ifdef CONFIG_CMD_KGDB
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200160 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
161 return;
162#endif
Kim Phillips20051f22012-10-29 13:34:29 +0000163 show_regs(regs);
164 print_backtrace((unsigned long *)regs->gpr[1]);
165 panic("Software Emulation Exception");
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200166}
167
168
Kim Phillips20051f22012-10-29 13:34:29 +0000169void UnknownException(struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200170{
Wolfgang Denkafaac862007-08-12 14:27:39 +0200171#ifdef CONFIG_CMD_KGDB
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200172 if (debugger_exception_handler && (*debugger_exception_handler)(regs))
173 return;
174#endif
Kim Phillips20051f22012-10-29 13:34:29 +0000175 printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200176 regs->nip, regs->msr, regs->trap);
Kim Phillips20051f22012-10-29 13:34:29 +0000177 _exception(0, regs);
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200178}
179
Wolfgang Denkafaac862007-08-12 14:27:39 +0200180#ifdef CONFIG_CMD_BEDBUG
Kim Phillips20051f22012-10-29 13:34:29 +0000181extern void do_bedbug_breakpoint(struct pt_regs *);
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200182#endif
183
Kim Phillips20051f22012-10-29 13:34:29 +0000184void DebugException(struct pt_regs *regs)
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200185{
Kim Phillips20051f22012-10-29 13:34:29 +0000186 printf("Debugger trap at @ %lx\n", regs->nip);
187 show_regs(regs);
Wolfgang Denkafaac862007-08-12 14:27:39 +0200188#ifdef CONFIG_CMD_BEDBUG
Kim Phillips20051f22012-10-29 13:34:29 +0000189 do_bedbug_breakpoint(regs);
Rafal Jaworowski8993e542007-07-27 14:43:59 +0200190#endif
191}