1769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn/*
2769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * OpenRISC traps.c
3769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *
4769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * Linux architectural port borrowing liberally from similar works of
5769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * others.  All original copyrights apply as per the original source
6769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * declaration.
7769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *
8769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * Modifications for the OpenRISC architecture:
9769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
10769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
11769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *
12769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *      This program is free software; you can redistribute it and/or
13769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *      modify it under the terms of the GNU General Public License
14769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *      as published by the Free Software Foundation; either version
15769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *      2 of the License, or (at your option) any later version.
16769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *
17769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *  Here we handle the break vectors not used by the system call
18769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *  mechanism, as well as some general stack/register dumping
19769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *  things.
20769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn *
21769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn */
22769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
23769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/init.h>
24769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/sched.h>
25769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/kernel.h>
26769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/module.h>
27769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/kmod.h>
28769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/string.h>
29769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/errno.h>
30769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/ptrace.h>
31769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/timer.h>
32769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/mm.h>
33769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <linux/kallsyms.h>
34769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <asm/uaccess.h>
35769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
36769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <asm/segment.h>
37769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <asm/io.h>
38769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#include <asm/pgtable.h>
39769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
40769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnextern char _etext, _stext;
41769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
42769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnint kstack_depth_to_print = 0x180;
43769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
44769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnstatic inline int valid_stack_ptr(struct thread_info *tinfo, void *p)
45769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
46769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	return p > (void *)tinfo && p < (void *)tinfo + THREAD_SIZE - 3;
47769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
48769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
49769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid show_trace(struct task_struct *task, unsigned long *stack)
50769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
51769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	struct thread_info *context;
52769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	unsigned long addr;
53769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
54769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	context = (struct thread_info *)
55769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	    ((unsigned long)stack & (~(THREAD_SIZE - 1)));
56769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
57769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	while (valid_stack_ptr(context, stack)) {
58769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		addr = *stack++;
59769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		if (__kernel_text_address(addr)) {
60769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			printk(" [<%08lx>]", addr);
61769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			print_symbol(" %s", addr);
62769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			printk("\n");
63769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		}
64769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
65769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk(" =======================\n");
66769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
67769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
68769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn/* displays a short stack trace */
69769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid show_stack(struct task_struct *task, unsigned long *esp)
70769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
71769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	unsigned long addr, *stack;
72769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	int i;
73769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
74769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	if (esp == NULL)
75769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		esp = (unsigned long *)&esp;
76769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
77769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	stack = esp;
78769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
79769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("Stack dump [0x%08lx]:\n", (unsigned long)esp);
80769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	for (i = 0; i < kstack_depth_to_print; i++) {
81769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		if (kstack_end(stack))
82769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			break;
83769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		if (__get_user(addr, stack)) {
84769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			/* This message matches "failing address" marked
85769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			   s390 in ksymoops, so lines containing it will
86769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			   not be filtered out by ksymoops.  */
87769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			printk("Failing address 0x%lx\n", (unsigned long)stack);
88769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			break;
89769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		}
90769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		stack++;
91769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
92769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		printk("sp + %02d: 0x%08lx\n", i * 4, addr);
93769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
94769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n");
95769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
96769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	show_trace(task, esp);
97769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
98769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	return;
99769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
100769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
101769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid show_trace_task(struct task_struct *tsk)
102769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
103769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	/*
104769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	 * TODO: SysRq-T trace dump...
105769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	 */
106769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
107769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
108769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn/*
109769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn * The architecture-independent backtrace generator
110769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn */
111769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid dump_stack(void)
112769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
113769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	unsigned long stack;
114769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
115769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	show_stack(current, &stack);
116769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
11701c4d33ac5ca7920f0e0f6b25bdfd3fa479fd973Richard WeinbergerEXPORT_SYMBOL(dump_stack);
118769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
119769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid show_registers(struct pt_regs *regs)
120769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
121769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	int i;
122769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	int in_kernel = 1;
123769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	unsigned long esp;
124769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
125769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	esp = (unsigned long)(&regs->sp);
126769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	if (user_mode(regs))
127769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		in_kernel = 0;
128769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
129769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("CPU #: %d\n"
130769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       "   PC: %08lx    SR: %08lx    SP: %08lx\n",
131769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       smp_processor_id(), regs->pc, regs->sr, regs->sp);
132769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
133769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]);
134769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",
135769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7]);
136769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n",
137769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[8], regs->gpr[9], regs->gpr[10], regs->gpr[11]);
138769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n",
139769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[12], regs->gpr[13], regs->gpr[14], regs->gpr[15]);
140769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n",
141769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[16], regs->gpr[17], regs->gpr[18], regs->gpr[19]);
142769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n",
143769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[20], regs->gpr[21], regs->gpr[22], regs->gpr[23]);
144769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n",
145769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]);
146769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n",
147769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]);
1486cbe5e95267449ea0b79c0b049342409949da3acJonas Bonn	printk("  RES: %08lx oGPR11: %08lx\n",
1496cbe5e95267449ea0b79c0b049342409949da3acJonas Bonn	       regs->gpr[11], regs->orig_gpr11);
150769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
151769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("Process %s (pid: %d, stackpage=%08lx)\n",
152769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       current->comm, current->pid, (unsigned long)current);
153769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	/*
154769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	 * When in-kernel, we also print out the stack and code at the
155769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	 * time of the fault..
156769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	 */
157769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	if (in_kernel) {
158769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
159769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		printk("\nStack: ");
160769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		show_stack(NULL, (unsigned long *)esp);
161769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
162769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		printk("\nCode: ");
163769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		if (regs->pc < PAGE_OFFSET)
164769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			goto bad;
165769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
166769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		for (i = -24; i < 24; i++) {
167769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			unsigned char c;
168769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			if (__get_user(c, &((unsigned char *)regs->pc)[i])) {
169769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnbad:
170769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn				printk(" Bad PC value.");
171769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn				break;
172769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			}
173769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
174769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			if (i == 0)
175769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn				printk("(%02x) ", c);
176769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			else
177769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn				printk("%02x ", c);
178769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		}
179769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
180769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n");
181769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
182769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
183769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid nommu_dump_state(struct pt_regs *regs,
184769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		      unsigned long ea, unsigned long vector)
185769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
186769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	int i;
187769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	unsigned long addr, stack = regs->sp;
188769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
189769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n\r[nommu_dump_state] :: ea %lx, vector %lx\n\r", ea, vector);
190769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
191769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("CPU #: %d\n"
192769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       "   PC: %08lx    SR: %08lx    SP: %08lx\n",
193769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       0, regs->pc, regs->sr, regs->sp);
194769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR00: %08lx GPR01: %08lx GPR02: %08lx GPR03: %08lx\n",
195769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       0L, regs->gpr[1], regs->gpr[2], regs->gpr[3]);
196769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR04: %08lx GPR05: %08lx GPR06: %08lx GPR07: %08lx\n",
197769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[4], regs->gpr[5], regs->gpr[6], regs->gpr[7]);
198769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR08: %08lx GPR09: %08lx GPR10: %08lx GPR11: %08lx\n",
199769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[8], regs->gpr[9], regs->gpr[10], regs->gpr[11]);
200769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR12: %08lx GPR13: %08lx GPR14: %08lx GPR15: %08lx\n",
201769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[12], regs->gpr[13], regs->gpr[14], regs->gpr[15]);
202769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR16: %08lx GPR17: %08lx GPR18: %08lx GPR19: %08lx\n",
203769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[16], regs->gpr[17], regs->gpr[18], regs->gpr[19]);
204769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR20: %08lx GPR21: %08lx GPR22: %08lx GPR23: %08lx\n",
205769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[20], regs->gpr[21], regs->gpr[22], regs->gpr[23]);
206769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR24: %08lx GPR25: %08lx GPR26: %08lx GPR27: %08lx\n",
207769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[24], regs->gpr[25], regs->gpr[26], regs->gpr[27]);
208769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("GPR28: %08lx GPR29: %08lx GPR30: %08lx GPR31: %08lx\n",
209769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       regs->gpr[28], regs->gpr[29], regs->gpr[30], regs->gpr[31]);
2106cbe5e95267449ea0b79c0b049342409949da3acJonas Bonn	printk("  RES: %08lx oGPR11: %08lx\n",
2116cbe5e95267449ea0b79c0b049342409949da3acJonas Bonn	       regs->gpr[11], regs->orig_gpr11);
212769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
213769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("Process %s (pid: %d, stackpage=%08lx)\n",
214769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       ((struct task_struct *)(__pa(current)))->comm,
215769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       ((struct task_struct *)(__pa(current)))->pid,
216769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       (unsigned long)current);
217769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
218769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\nStack: ");
219769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("Stack dump [0x%08lx]:\n", (unsigned long)stack);
220769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	for (i = 0; i < kstack_depth_to_print; i++) {
221769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		if (((long)stack & (THREAD_SIZE - 1)) == 0)
222769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			break;
223769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		stack++;
224769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
225769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		printk("%lx :: sp + %02d: 0x%08lx\n", stack, i * 4,
226769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		       *((unsigned long *)(__pa(stack))));
227769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
228769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n");
229769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
230769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("Call Trace:   ");
231769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	i = 1;
232769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	while (((long)stack & (THREAD_SIZE - 1)) != 0) {
233769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		addr = *((unsigned long *)__pa(stack));
234769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		stack++;
235769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
236769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		if (kernel_text_address(addr)) {
237769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			if (i && ((i % 6) == 0))
238769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn				printk("\n ");
239769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			printk(" [<%08lx>]", addr);
240769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			i++;
241769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		}
242769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
243769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n");
244769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
245769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\nCode: ");
246769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
247769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	for (i = -24; i < 24; i++) {
248769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		unsigned char c;
249769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		c = ((unsigned char *)(__pa(regs->pc)))[i];
250769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
251769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		if (i == 0)
252769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			printk("(%02x) ", c);
253769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		else
254769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn			printk("%02x ", c);
255769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
256769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n");
257769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
258769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
259769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn/* This is normally the 'Oops' routine */
260769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid die(const char *str, struct pt_regs *regs, long err)
261769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
262769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
263769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	console_verbose();
264769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n%s#: %04lx\n", str, err & 0xffff);
265769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	show_registers(regs);
266769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION
267769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("\n\nUNHANDLED_EXCEPTION: entering infinite loop\n");
268769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
269769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	/* shut down interrupts */
270769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	local_irq_disable();
271769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
272769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	__asm__ __volatile__("l.nop   1");
273769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	do {} while (1);
274769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn#endif
275769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	do_exit(SIGSEGV);
276769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
277769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
278769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn/* This is normally the 'Oops' routine */
279769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid die_if_kernel(const char *str, struct pt_regs *regs, long err)
280769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
281769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	if (user_mode(regs))
282769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		return;
283769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
284769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	die(str, regs, err);
285769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
286769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
287769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid unhandled_exception(struct pt_regs *regs, int ea, int vector)
288769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
289769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	printk("Unable to handle exception at EA =0x%x, vector 0x%x",
290769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	       ea, vector);
291769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	die("Oops", regs, 9);
292769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
293769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
294769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnvoid __init trap_init(void)
295769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
296769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	/* Nothing needs to be done */
297769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
298769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
299769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnasmlinkage void do_trap(struct pt_regs *regs, unsigned long address)
300769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
301769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	siginfo_t info;
302769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	memset(&info, 0, sizeof(info));
303769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	info.si_signo = SIGTRAP;
304769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	info.si_code = TRAP_TRACE;
305769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	info.si_addr = (void *)address;
306769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	force_sig_info(SIGTRAP, &info, current);
307769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
308769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	regs->pc += 4;
309769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
310769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
311769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnasmlinkage void do_unaligned_access(struct pt_regs *regs, unsigned long address)
312769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
313769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	siginfo_t info;
314769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
315769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	if (user_mode(regs)) {
316769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		/* Send a SIGSEGV */
317769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_signo = SIGSEGV;
318769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_errno = 0;
319769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		/* info.si_code has been set above */
320769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_addr = (void *)address;
321769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		force_sig_info(SIGSEGV, &info, current);
322769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	} else {
323769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		printk("KERNEL: Unaligned Access 0x%.8lx\n", address);
324769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		show_registers(regs);
325769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		die("Die:", regs, address);
326769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
327769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
328769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
329769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
330769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnasmlinkage void do_bus_fault(struct pt_regs *regs, unsigned long address)
331769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
332769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	siginfo_t info;
333769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
334769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	if (user_mode(regs)) {
335769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		/* Send a SIGBUS */
336769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_signo = SIGBUS;
337769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_errno = 0;
338769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_code = BUS_ADRERR;
339769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_addr = (void *)address;
340769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		force_sig_info(SIGBUS, &info, current);
341769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	} else {		/* Kernel mode */
342769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		printk("KERNEL: Bus error (SIGBUS) 0x%.8lx\n", address);
343769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		show_registers(regs);
344769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		die("Die:", regs, address);
345769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
346769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
347769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
348769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonnasmlinkage void do_illegal_instruction(struct pt_regs *regs,
349769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn				       unsigned long address)
350769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn{
351769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	siginfo_t info;
352769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn
353769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	if (user_mode(regs)) {
354769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		/* Send a SIGILL */
355769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_signo = SIGILL;
356769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_errno = 0;
357769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_code = ILL_ILLOPC;
358769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		info.si_addr = (void *)address;
359769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		force_sig_info(SIGBUS, &info, current);
360769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	} else {		/* Kernel mode */
361769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		printk("KERNEL: Illegal instruction (SIGILL) 0x%.8lx\n",
362769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		       address);
363769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		show_registers(regs);
364769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn		die("Die:", regs, address);
365769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn	}
366769a8a96229e6b2f1e3a2b3b38e27981f7fb9902Jonas Bonn}
367