traps.c revision d8f66c8c1ea8e948483ee4739ad91120f5f7de51
11394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/*
21394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * File:         arch/blackfin/kernel/traps.c
31394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Based on:
41394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Author:       Hamish Macdonald
51394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu *
61394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Created:
71394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Description:  uses S/W interrupt 15 for the system calls
81394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu *
91394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Modified:
101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu *               Copyright 2004-2006 Analog Devices Inc.
111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu *
121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Bugs:         Enter bugs at http://blackfin.uclinux.org/
131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu *
141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * This program is free software; you can redistribute it and/or modify
151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * it under the terms of the GNU General Public License as published by
161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * the Free Software Foundation; either version 2 of the License, or
171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * (at your option) any later version.
181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu *
191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * This program is distributed in the hope that it will be useful,
201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * but WITHOUT ANY WARRANTY; without even the implied warranty of
211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * GNU General Public License for more details.
231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu *
241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * You should have received a copy of the GNU General Public License
251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * along with this program; if not, see the file COPYING, or write
261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * to the Free Software Foundation, Inc.,
271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */
291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
301f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/uaccess.h>
311f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/interrupt.h>
321f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/module.h>
331f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/kallsyms.h>
34d31c5ab147e0b17b9ec0daa5e4d1fc0bd6b19974Bryan Wu#include <linux/fs.h>
351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/traps.h>
361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/cacheflush.h>
371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/blackfin.h>
381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/irq_handler.h>
39d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz#include <linux/irq.h>
40669b792c77bbc30e9f4d9c95dbc918dc348c49c2Robin Getz#include <asm/trace.h>
41226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#include <asm/fixed_code.h>
421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB
441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu# include <linux/debugger.h>
451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu# include <linux/kgdb.h>
46226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
47226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() \
48226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	do { \
49226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		CHK_DEBUGGER(trapnr, sig, info.si_code, fp, ); \
50226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	} while (0)
51226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() \
52226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	do { \
53226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		if (kgdb_connected) \
54226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			CHK_DEBUGGER_TRAP(); \
55226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	} while (0)
56226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#else
57226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() do { } while (0)
58226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0)
591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Initiate the event table handler */
621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid __init trap_init(void)
631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	CSYNC();
651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	bfin_write_EVT3(trap);
661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	CSYNC();
671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuint kstack_depth_to_print = 48;
701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
71226eb1ef523a33c66193bc319a92c647e47311d4Robin Getzstatic void decode_address(char *buf, unsigned long address)
721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	struct vm_list_struct *vml;
741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	struct task_struct *p;
751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	struct mm_struct *mm;
76885be03b069131d242506f0f717d38659b2bdb6cRobin Getz	unsigned long flags, offset;
77885be03b069131d242506f0f717d38659b2bdb6cRobin Getz	unsigned int in_exception = bfin_read_IPEND() & 0x10;
781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KALLSYMS
808a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger	unsigned long symsize;
811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	const char *symname;
821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	char *modname;
831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	char *delim = ":";
841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	char namebuf[128];
851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* look up the address and see if we are in kernel space */
871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf);
881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	if (symname) {
901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		/* yeah! kernel space! */
911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (!modname)
921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			modname = delim = "";
93226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }",
941f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger		              (void *)address, delim, modname, delim, symname,
951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		              (unsigned long)offset);
96885be03b069131d242506f0f717d38659b2bdb6cRobin Getz		return;
971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
1001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
101226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	/* Problem in fixed code section? */
102226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	if (address >= FIXED_CODE_START && address < FIXED_CODE_END) {
103226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address);
104226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		return;
105226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	}
106226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
107226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	/* Problem somewhere before the kernel start address */
108226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	if (address < CONFIG_BOOT_LOAD) {
109226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address);
110226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		return;
111226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	}
112226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
1131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* looks like we're off in user-land, so let's walk all the
1141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * mappings of all our processes and see if we can't be a whee
1151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * bit more specific
1161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 */
117885be03b069131d242506f0f717d38659b2bdb6cRobin Getz	write_lock_irqsave(&tasklist_lock, flags);
1181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	for_each_process(p) {
119885be03b069131d242506f0f717d38659b2bdb6cRobin Getz		mm = (in_exception ? p->mm : get_task_mm(p));
1201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (!mm)
1211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			continue;
1221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
1231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		vml = mm->context.vmlist;
1241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		while (vml) {
1251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			struct vm_area_struct *vma = vml->vma;
1261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
1271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			if (address >= vma->vm_start && address < vma->vm_end) {
1281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu				char *name = p->comm;
1291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu				struct file *file = vma->vm_file;
1301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu				if (file) {
1311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu					char _tmpbuf[256];
1321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu					name = d_path(file->f_dentry,
1331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu					              file->f_vfsmnt,
1341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu					              _tmpbuf,
1351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu					              sizeof(_tmpbuf));
1361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu				}
1371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
1388a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger				/* FLAT does not have its text aligned to the start of
1398a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger				 * the map while FDPIC ELF does ...
1408a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger				 */
1418a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger				if (current->mm &&
1428a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger				    (address > current->mm->start_code) &&
1438a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger				    (address < current->mm->end_code))
1448a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger					offset = address - current->mm->start_code;
1458a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger				else
1468a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger					offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT);
1478a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger
148226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz				sprintf(buf, "<0x%p> [ %s + 0x%lx ]",
149885be03b069131d242506f0f717d38659b2bdb6cRobin Getz					(void *)address, name, offset);
150885be03b069131d242506f0f717d38659b2bdb6cRobin Getz				if (!in_exception)
151885be03b069131d242506f0f717d38659b2bdb6cRobin Getz					mmput(mm);
152885be03b069131d242506f0f717d38659b2bdb6cRobin Getz				goto done;
1531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			}
1541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
1551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			vml = vml->next;
1561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		}
157885be03b069131d242506f0f717d38659b2bdb6cRobin Getz		if (!in_exception)
158885be03b069131d242506f0f717d38659b2bdb6cRobin Getz			mmput(mm);
1591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
1601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
1611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* we were unable to find this address anywhere */
1624a589e1ef67fdb2d5fa783117da8dc7cba576af4Robin Getz	sprintf(buf, "<0x%p> /* unknown address */", (void *)address);
163885be03b069131d242506f0f717d38659b2bdb6cRobin Getz
164885be03b069131d242506f0f717d38659b2bdb6cRobin Getzdone:
165885be03b069131d242506f0f717d38659b2bdb6cRobin Getz	write_unlock_irqrestore(&tasklist_lock, flags);
1661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
1671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
1682ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getzasmlinkage void double_fault_c(struct pt_regs *fp)
1692ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz{
170226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	console_verbose();
171226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	oops_in_progress = 1;
1722ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz	printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n");
17349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	dump_bfin_process(fp);
17449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	dump_bfin_mem((void *)fp->retx);
17549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	show_regs(fp);
1762ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz	panic("Double Fault - unrecoverable event\n");
1772ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz
1782ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz}
1792ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz
1801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage void trap_c(struct pt_regs *fp)
1811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
182518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
183518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	int j;
184518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif
185518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	int sig = 0;
1861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	siginfo_t info;
1871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE;
1881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
189226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	trace_buffer_save(j);
190226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
191226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	/* Important - be very careful dereferncing pointers - will lead to
192226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	 * double faults if the stack has become corrupt
193226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	 */
194226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
195226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	/* If the fault was caused by a kernel thread, or interrupt handler
196226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	 * we will kernel panic, so the system reboots.
197226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	 * If KGDB is enabled, don't set this for kernel breakpoints
198226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	*/
199226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	if ((bfin_read_IPEND() & 0xFFC0)
2001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB
201226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		&& trapnr != VEC_EXCPT02
2021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
203226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	){
204226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		console_verbose();
205226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		oops_in_progress = 1;
206226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	} else if (current) {
207226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		if (current->mm == NULL) {
208226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			console_verbose();
209226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			oops_in_progress = 1;
210226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		}
211226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	}
2121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
2131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* trap_c() will be called for exceptions. During exceptions
2141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * processing, the pc value should be set with retx value.
2151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * With this change we can cleanup some code in signal.c- TODO
2161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 */
2171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	fp->orig_pc = fp->retx;
2181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n",
2191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		trapnr, fp->ipend, fp->pc, fp->retx); */
2201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
2211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* send the appropriate signal to the user program */
2221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	switch (trapnr) {
2231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
2241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* This table works in conjuction with the one in ./mach-common/entry.S
2251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * Some exceptions are handled there (in assembly, in exception space)
2261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * Some are handled here, (in C, in interrupt space)
2271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * Some, like CPLB, are handled in both, where the normal path is
2281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * handled in assembly/exception space, and the error path is handled
2291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * here
2301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 */
2311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
2321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x00 - Linux Syscall, getting here is an error */
2331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x01 - userspace gdb breakpoint, handled here */
2341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_EXCPT01:
2351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = TRAP_ILLTRAP;
2361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGTRAP;
2371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP_MAYBE();
2381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		/* Check if this is a breakpoint in kernel space */
2391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (fp->ipend & 0xffc0)
2401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			return;
2411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		else
2421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			break;
2431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB
2441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_EXCPT02 :		 /* gdb connection */
2451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = TRAP_ILLTRAP;
2461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGTRAP;
2471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
2481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		return;
2491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else
2501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x02 - User Defined, Caught by default */
2511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
2529401e618c8f70920f34893946239e24d40a3519aMike Frysinger	/* 0x03 - User Defined, userspace stack overflow */
2531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_EXCPT03:
2541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = SEGV_STACKFLOW;
2551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGSEGV;
256569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x03(KERN_NOTICE));
2571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
2581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
2599401e618c8f70920f34893946239e24d40a3519aMike Frysinger	/* 0x04 - User Defined, Caught by default */
2601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x05 - User Defined, Caught by default */
2611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x06 - User Defined, Caught by default */
2621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x07 - User Defined, Caught by default */
2631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x08 - User Defined, Caught by default */
2641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x09 - User Defined, Caught by default */
2651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x0A - User Defined, Caught by default */
2661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x0B - User Defined, Caught by default */
2671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x0C - User Defined, Caught by default */
2681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x0D - User Defined, Caught by default */
2691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x0E - User Defined, Caught by default */
2701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x0F - User Defined, Caught by default */
2711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x10 HW Single step, handled here */
2721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_STEP:
2731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = TRAP_STEP;
2741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGTRAP;
2751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP_MAYBE();
2761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		/* Check if this is a single step in kernel space */
2771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (fp->ipend & 0xffc0)
2781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			return;
2791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		else
2801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			break;
2811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x11 - Trace Buffer Full, handled here */
2821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_OVFLOW:
2831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = TRAP_TRACEFLOW;
2841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGTRAP;
285569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x11(KERN_NOTICE));
2861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
2871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
2881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x12 - Reserved, Caught by default */
2891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x13 - Reserved, Caught by default */
2901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x14 - Reserved, Caught by default */
2911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x15 - Reserved, Caught by default */
2921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x16 - Reserved, Caught by default */
2931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x17 - Reserved, Caught by default */
2941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x18 - Reserved, Caught by default */
2951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x19 - Reserved, Caught by default */
2961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x1A - Reserved, Caught by default */
2971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x1B - Reserved, Caught by default */
2981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x1C - Reserved, Caught by default */
2991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x1D - Reserved, Caught by default */
3001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x1E - Reserved, Caught by default */
3011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x1F - Reserved, Caught by default */
3021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x20 - Reserved, Caught by default */
3031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x21 - Undefined Instruction, handled here */
3041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_UNDEF_I:
3051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_ILLOPC;
3061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGILL;
307569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x21(KERN_NOTICE));
3081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x22 - Illegal Instruction Combination, handled here */
3111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_ILGAL_I:
3121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_ILLPARAOP;
3131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGILL;
314569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x22(KERN_NOTICE));
3151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
317f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz	/* 0x23 - Data CPLB protection violation, handled here */
3181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_CPLB_VL:
3191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_CPLB_VI;
320f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz		sig = SIGBUS;
321569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x23(KERN_NOTICE));
3221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x24 - Data access misaligned, handled here */
3251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_MISALI_D:
3261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = BUS_ADRALN;
3271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGBUS;
328569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x24(KERN_NOTICE));
3291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x25 - Unrecoverable Event, handled here */
3321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_UNCOV:
3331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_ILLEXCPT;
3341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGILL;
335569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x25(KERN_NOTICE));
3361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr,
3391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		error case is handled here */
3401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_CPLB_M:
3411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = BUS_ADRALN;
3421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGBUS;
343569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x26(KERN_NOTICE));
3441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */
3471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_CPLB_MHIT:
3481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_CPLB_MULHIT;
3491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
3501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGSEGV;
351226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "NULL pointer access (probably)\n");
3521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else
3531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGILL;
354569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x27(KERN_NOTICE));
3551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
3561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x28 - Emulation Watchpoint, handled here */
3591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_WATCH:
3601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = TRAP_WATCHPT;
3611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGTRAP;
362569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		pr_debug(EXC_0x28(KERN_DEBUG));
3631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP_MAYBE();
3641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		/* Check if this is a watchpoint in kernel space */
3651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (fp->ipend & 0xffc0)
3661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			return;
3671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		else
3681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			break;
3691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_BF535
3701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x29 - Instruction fetch access error (535 only) */
3711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_ISTRU_VL:      /* ADSP-BF535 only (MH) */
3721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = BUS_OPFETCH;
3731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGBUS;
374226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n");
3751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else
3781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x29 - Reserved, Caught by default */
3791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
3801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x2A - Instruction fetch misaligned, handled here */
3811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_MISALI_I:
3821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = BUS_ADRALN;
3831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGBUS;
384569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE));
3851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
387f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz	/* 0x2B - Instruction CPLB protection violation, handled here */
3881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_CPLB_I_VL:
3891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_CPLB_VI;
390f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz		sig = SIGBUS;
391569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE));
3921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
3931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
3941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */
3951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_CPLB_I_M:
3961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_CPLB_MISS;
3971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGBUS;
398569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE));
3991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
4001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
4011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x2D - Instruction CPLB Multiple Hits, handled here */
4021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_CPLB_I_MHIT:
4031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_CPLB_MULHIT;
4041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO
4051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGSEGV;
406226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "Jump to address 0 - 0x0fff\n");
4071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else
4081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGILL;
409569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE));
4101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
4111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
4121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
4131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x2E - Illegal use of Supervisor Resource, handled here */
4141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case VEC_ILL_RES:
4151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = ILL_PRVOPC;
4161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGILL;
417569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz		printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE));
4181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
4191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
4201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x2F - Reserved, Caught by default */
4211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x30 - Reserved, Caught by default */
4221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x31 - Reserved, Caught by default */
4231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x32 - Reserved, Caught by default */
4241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x33 - Reserved, Caught by default */
4251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x34 - Reserved, Caught by default */
4261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x35 - Reserved, Caught by default */
4271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x36 - Reserved, Caught by default */
4281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x37 - Reserved, Caught by default */
4291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x38 - Reserved, Caught by default */
4301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x39 - Reserved, Caught by default */
4311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x3A - Reserved, Caught by default */
4321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x3B - Reserved, Caught by default */
4331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x3C - Reserved, Caught by default */
4341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x3D - Reserved, Caught by default */
4351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x3E - Reserved, Caught by default */
4361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* 0x3F - Reserved, Caught by default */
43713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz	case VEC_HWERR:
43813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		info.si_code = BUS_ADRALN;
43913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		sig = SIGBUS;
44013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		switch (fp->seqstat & SEQSTAT_HWERRCAUSE) {
44113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		/* System MMR Error */
44213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR):
44313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			info.si_code = BUS_ADRALN;
44413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			sig = SIGBUS;
44513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			printk(KERN_NOTICE HWC_x2(KERN_NOTICE));
44613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			break;
44713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		/* External Memory Addressing Error */
44813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR):
44913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			info.si_code = BUS_ADRERR;
45013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			sig = SIGBUS;
45113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			printk(KERN_NOTICE HWC_x3(KERN_NOTICE));
45213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			break;
45313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		/* Performance Monitor Overflow */
45413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		case (SEQSTAT_HWERRCAUSE_PERF_FLOW):
45513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			printk(KERN_NOTICE HWC_x12(KERN_NOTICE));
45613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			break;
45713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		/* RAISE 5 instruction */
45813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		case (SEQSTAT_HWERRCAUSE_RAISE_5):
45913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			printk(KERN_NOTICE HWC_x18(KERN_NOTICE));
46013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			break;
46113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		default:        /* Reserved */
46213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			printk(KERN_NOTICE HWC_default(KERN_NOTICE));
46313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			break;
46413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		}
46513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		CHK_DEBUGGER_TRAP();
46613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		break;
4671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	default:
4681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		info.si_code = TRAP_ILLTRAP;
4691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		sig = SIGTRAP;
4701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n",
4711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			(fp->seqstat & SEQSTAT_EXCAUSE));
4721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		CHK_DEBUGGER_TRAP();
4731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
4741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
4751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
476226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	BUG_ON(sig == 0);
477226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
478226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	if (sig != SIGTRAP) {
4791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		unsigned long stack;
48049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		dump_bfin_process(fp);
48113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		/* Is it an interrupt, or an exception? */
48213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		if (trapnr == VEC_HWERR)
48313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			dump_bfin_mem((void *)fp->pc);
48413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		else
48513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz			dump_bfin_mem((void *)fp->retx);
48649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		show_regs(fp);
487226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
488226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		/* Print out the trace buffer if it makes sense */
489226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE
490226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M)
491226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			printk(KERN_NOTICE "No trace since you do not have "
492226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz				"CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n"
493226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz				KERN_NOTICE "\n");
494226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		else
495226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif
496226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			dump_bfin_trace_buffer();
4971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		show_stack(current, &stack);
498226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		if (oops_in_progress) {
499226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_ACCESS_CHECK
50090c7f4686f82aef875aadf8e5c9c1a9465e5143bRobin Getz			printk(KERN_EMERG "Please turn on "
50190c7f4686f82aef875aadf8e5c9c1a9465e5143bRobin Getz			       "CONFIG_ACCESS_CHECK\n");
502226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif
5031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			panic("Kernel exception");
504226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		}
5051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
506fb322915a05804a3a153f714f2f08e4c32ce84c7Robin Getz
507ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz	info.si_signo = sig;
508ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz	info.si_errno = 0;
509ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz	info.si_addr = (void *)fp->pc;
510ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz	force_sig_info(sig, &info, current);
5111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
5121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	trace_buffer_restore(j);
5131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	return;
5141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
5151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
5161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Typical exception handling routines	*/
5171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
518518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1)
519518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz
5201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_bfin_trace_buffer(void)
5211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
522518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
523518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	int tflags, i = 0;
524226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	char buf[150];
525518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
526518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	int j, index;
527518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif
528518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz
5291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	trace_buffer_save(tflags);
5301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
531226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "Hardware Trace:\n");
532518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz
5331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) {
534518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) {
535226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			decode_address(buf, (unsigned long)bfin_read_TBUF());
536226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			printk(KERN_NOTICE "%4i Target : %s\n", i, buf);
537226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			decode_address(buf, (unsigned long)bfin_read_TBUF());
538226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			printk(KERN_NOTICE "     Source : %s\n", buf);
5391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		}
5401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
5411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
542518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND
543518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	if (trace_buff_offset)
544518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		index = trace_buff_offset/4 - 1;
545518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	else
546518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		index = EXPAND_LEN;
547518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz
548518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128;
549518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	while (j) {
550226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		decode_address(buf, software_trace_buff[index]);
551226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "%4i Target : %s\n", i, buf);
552518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		index -= 1;
553518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		if (index < 0 )
554518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz			index = EXPAND_LEN;
555226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		decode_address(buf, software_trace_buff[index]);
556226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "     Source : %s\n", buf);
557518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		index -= 1;
558518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		if (index < 0)
559518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz			index = EXPAND_LEN;
560518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		j--;
561518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz		i++;
562518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz	}
563518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif
564518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz
5651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	trace_buffer_restore(tflags);
566518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif
5671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
5681394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_bfin_trace_buffer);
5691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
5701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wustatic void show_trace(struct task_struct *tsk, unsigned long *sp)
5711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
5721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	unsigned long addr;
5731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
574226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "\n" KERN_NOTICE "Call Trace:\n");
5751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
5761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	while (!kstack_end(sp)) {
5771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		addr = *sp++;
5781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		/*
5791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		 * If the address is either in the text segment of the
5801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		 * kernel, or in the region which contains vmalloc'ed
5811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		 * memory, it *may* be the address of a calling
5821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		 * routine; if so, print it so that someone tracing
5831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		 * down the cause of the crash will be able to figure
5841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		 * out the call path that was taken.
5851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		 */
5861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (kernel_text_address(addr))
5871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			print_ip_sym(addr);
5881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
5891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
590226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "\n");
5911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
5921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
5931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid show_stack(struct task_struct *task, unsigned long *stack)
5941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
5951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	unsigned long *endstack, addr;
5961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	int i;
5971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
5981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	/* Cannot call dump_bfin_trace_buffer() here as show_stack() is
5991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 * called externally in some places in the kernel.
6001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	 */
6011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
6021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	if (!stack) {
6031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (task)
6041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			stack = (unsigned long *)task->thread.ksp;
6051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		else
6061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			stack = (unsigned long *)&stack;
6071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
6081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
6091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	addr = (unsigned long)stack;
6101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	endstack = (unsigned long *)PAGE_ALIGN(addr);
6111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
612226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "Stack from %08lx:", (unsigned long)stack);
6131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	for (i = 0; i < kstack_depth_to_print; i++) {
6141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (stack + 1 > endstack)
6151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			break;
6161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (i % 8 == 0)
617226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			printk("\n" KERN_NOTICE "       ");
6181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		printk(" %08lx", *stack++);
6191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
620226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk("\n");
6211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
6221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	show_trace(task, stack);
6231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
6241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
6251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_stack(void)
6261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
6271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	unsigned long stack;
628518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON
6291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	int tflags;
630518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif
6311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	trace_buffer_save(tflags);
6321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	dump_bfin_trace_buffer();
6331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	show_stack(current, &stack);
6341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	trace_buffer_restore(tflags);
6351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
6361394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_stack);
6371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
63849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid dump_bfin_process(struct pt_regs *fp)
6391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
64049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	/* We should be able to look at fp->ipend, but we don't push it on the
64149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	 * stack all the time, so do this until we fix that */
64249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	unsigned int context = bfin_read_IPEND();
64349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger
64449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	if (oops_in_progress)
64549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_EMERG "Kernel OOPS in progress\n");
64649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger
64749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	if (context & 0x0020)
64849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "Deferred excecption or HW Error context\n");
64949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	else if (context & 0x3FC0)
65049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "Interrupt context\n");
65149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	else if (context & 0x4000)
65249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "Deferred Interrupt context\n");
65349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	else if (context & 0x8000)
65449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "Kernel process context\n");
65549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger
65649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	if (current->pid && current->mm) {
65749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "CURRENT PROCESS:\n");
65849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "COMM=%s PID=%d\n",
65949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			current->comm, current->pid);
66049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger
66149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "TEXT = 0x%p-0x%p  DATA = 0x%p-0x%p\n"
66249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			KERN_NOTICE "BSS = 0x%p-0x%p   USER-STACK = 0x%p\n"
66349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			KERN_NOTICE "\n",
66449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			(void *)current->mm->start_code,
66549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			(void *)current->mm->end_code,
66649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			(void *)current->mm->start_data,
66749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			(void *)current->mm->end_data,
66849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			(void *)current->mm->end_data,
66949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			(void *)current->mm->brk,
67049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger			(void *)current->mm->start_stack);
67149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	} else
67249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		printk(KERN_NOTICE "\n" KERN_NOTICE
67349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger		     "No Valid process in current context\n");
67449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger}
675226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
67649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid dump_bfin_mem(void *retaddr)
67749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{
6781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
679226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	if (retaddr >= (void *)FIXED_CODE_START  && retaddr < (void *)physical_mem_end
6801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#if L1_CODE_LENGTH != 0
6811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	    /* FIXME: Copy the code out of L1 Instruction SRAM through dma
6821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	       memcpy.  */
6831f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger	    && !(retaddr >= (void *)L1_CODE_START
6841f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger	         && retaddr < (void *)(L1_CODE_START + L1_CODE_LENGTH))
6851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
6861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	) {
687c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		int i = ((unsigned int)retaddr & 0xFFFFFFF0) - 32;
6881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		unsigned short x = 0;
689226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "return address: [0x%p]; contents of:", retaddr);
6901f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger		for (; i < ((unsigned int)retaddr & 0xFFFFFFF0) + 32; i += 2) {
6911f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger			if (!(i & 0xF))
692226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz				printk("\n" KERN_NOTICE "0x%08x: ", i);
693c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz
694c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz			if (get_user(x, (unsigned short *)i))
6951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu				break;
6961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifndef CONFIG_DEBUG_HWERR
6971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			/* If one of the last few instructions was a STI
698d2d50aa97d695d83ccb2341488d977e8cfe36555Simon Arlott			 * it is likely that the error occured awhile ago
699226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			 * and we just noticed. This only happens in kernel
700226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			 * context, which should mean an oops is happening
7011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			 */
702226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz			if (oops_in_progress && x >= 0x0040 && x <= 0x0047 && i <= 0)
70313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz				printk(KERN_EMERG "\n"
70413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz					KERN_EMERG "WARNING : You should reconfigure"
705c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz					" the kernel to turn on\n"
70613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz					KERN_EMERG " 'Hardware error interrupt debugging'\n"
70713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz					KERN_EMERG " The rest of this error is meanless\n");
7081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
7091f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger			if (i == (unsigned int)retaddr)
710c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz				printk("[%04x]", x);
711c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz			else
712c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz				printk(" %04x ", x);
7131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		}
714226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk("\n");
7151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	} else
716226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk("\n" KERN_NOTICE
7176a3f0b460cea79f08683cef1862d686a887efd8cRobin Getz			"Cannot look at the [PC] <%p> for it is"
7186a3f0b460cea79f08683cef1862d686a887efd8cRobin Getz			" in unreadable memory - sorry\n", retaddr);
71949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger}
72049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger
72149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid show_regs(struct pt_regs *fp)
72249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{
72349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	char buf [150];
724d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	struct irqaction *action;
725d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	unsigned int i;
726d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	unsigned long flags;
727226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
728226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\n");
729226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " SEQSTAT: %08lx  IPEND: %04lx  SYSCFG: %04lx\n",
730226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		(long)fp->seqstat, fp->ipend, fp->syscfg);
73113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz	printk(KERN_NOTICE "  HWERRCAUSE: 0x%lx\n",
73213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		(fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14);
73313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz	printk(KERN_NOTICE "  EXCAUSE   : 0x%lx\n",
73413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz		fp->seqstat & SEQSTAT_EXCAUSE);
735d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	for (i = 6; i <= 15 ; i++) {
736d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz		if (fp->ipend & (1 << i)) {
737d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			decode_address(buf, bfin_read32(EVT0 + 4*i));
738d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			printk(KERN_NOTICE "  physical IVG%i asserted : %s\n", i, buf);
739d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz		}
740d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	}
741d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz
742d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	/* if no interrupts are going off, don't print this out */
743d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	if (fp->ipend & ~0x3F) {
744d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz		for (i = 0; i < (NR_IRQS - 1); i++) {
745d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			spin_lock_irqsave(&irq_desc[i].lock, flags);
746d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			action = irq_desc[i].action;
747d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			if (!action)
748d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz				goto unlock;
749d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz
750d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			decode_address(buf, (unsigned int)action->handler);
751d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			printk(KERN_NOTICE "  logical irq %3d mapped  : %s", i, buf);
752d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			for (action = action->next; action; action = action->next) {
753d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz				decode_address(buf, (unsigned int)action->handler);
754d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz				printk(", %s", buf);
755d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			}
756d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			printk("\n");
757d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getzunlock:
758d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz			spin_unlock_irqrestore(&irq_desc[i].lock, flags);
759d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz		}
760d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz	}
761c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz
762226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	decode_address(buf, fp->rete);
763226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " RETE: %s\n", buf);
764226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	decode_address(buf, fp->retn);
765226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " RETN: %s\n", buf);
766226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	decode_address(buf, fp->retx);
767226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " RETX: %s\n", buf);
768226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	decode_address(buf, fp->rets);
769226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " RETS: %s\n", buf);
77049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	decode_address(buf, fp->pc);
77113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz	printk(KERN_NOTICE " PC  : %s\n", buf);
772c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz
77313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz	if (((long)fp->seqstat &  SEQSTAT_EXCAUSE) &&
77413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz	    (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) {
775226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		decode_address(buf, bfin_read_DCPLB_FAULT_ADDR());
776226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf);
777226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		decode_address(buf, bfin_read_ICPLB_FAULT_ADDR());
778226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf);
779226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	}
780226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
781226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n");
782226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " R0 : %08lx    R1 : %08lx    R2 : %08lx    R3 : %08lx\n",
783c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->r0, fp->r1, fp->r2, fp->r3);
784226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " R4 : %08lx    R5 : %08lx    R6 : %08lx    R7 : %08lx\n",
785c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->r4, fp->r5, fp->r6, fp->r7);
786226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " P0 : %08lx    P1 : %08lx    P2 : %08lx    P3 : %08lx\n",
787c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->p0, fp->p1, fp->p2, fp->p3);
788226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " P4 : %08lx    P5 : %08lx    FP : %08lx    SP : %08lx\n",
789226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		fp->p4, fp->p5, fp->fp, (long)fp);
790226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " LB0: %08lx    LT0: %08lx    LC0: %08lx\n",
791c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->lb0, fp->lt0, fp->lc0);
792226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " LB1: %08lx    LT1: %08lx    LC1: %08lx\n",
793c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->lb1, fp->lt1, fp->lc1);
794226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " B0 : %08lx    L0 : %08lx    M0 : %08lx    I0 : %08lx\n",
795c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->b0, fp->l0, fp->m0, fp->i0);
796226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " B1 : %08lx    L1 : %08lx    M1 : %08lx    I1 : %08lx\n",
797c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->b1, fp->l1, fp->m1, fp->i1);
798226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " B2 : %08lx    L2 : %08lx    M2 : %08lx    I2 : %08lx\n",
799c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->b2, fp->l2, fp->m2, fp->i2);
800226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE " B3 : %08lx    L3 : %08lx    M3 : %08lx    I3 : %08lx\n",
801c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		fp->b3, fp->l3, fp->m3, fp->i3);
802226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "A0.w: %08lx   A0.x: %08lx   A1.w: %08lx   A1.x: %08lx\n",
803226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz		fp->a0w, fp->a0x, fp->a1w, fp->a1x);
804c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz
805226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "USP : %08lx  ASTAT: %08lx\n",
806c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz		rdusp(), fp->astat);
8071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
808226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	printk(KERN_NOTICE "\n");
8091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
8101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
8111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1
8121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text));
8131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif
8141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
8151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock)
8161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
8171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	int ret = 0;
8181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	int tmp = 0;
8191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
8201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	local_irq_disable();
8211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	ret = get_user(tmp, spinlock);
8221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	if (ret == 0) {
8231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		if (tmp)
8241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu			ret = 1;
8251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		tmp = 1;
8261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		put_user(tmp, spinlock);
8271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
8281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	local_irq_enable();
8291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	return ret;
8301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
8311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
8321ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_request_exception(unsigned int exception, void (*handler)(void))
8331ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{
8341ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	void (*curr_handler)(void);
8351ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8361ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	if (exception > 0x3F)
8371ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger		return -EINVAL;
8381ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8391ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	curr_handler = ex_table[exception];
8401ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8411ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	if (curr_handler != ex_replaceable)
8421ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger		return -EBUSY;
8431ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8441ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	ex_table[exception] = handler;
8451ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8461ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	return 0;
8471ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger}
8481ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_request_exception);
8491ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8501ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_free_exception(unsigned int exception, void (*handler)(void))
8511ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{
8521ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	void (*curr_handler)(void);
8531ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8541ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	if (exception > 0x3F)
8551ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger		return -EINVAL;
8561ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8571ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	curr_handler = ex_table[exception];
8581ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8591ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	if (curr_handler != handler)
8601ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger		return -EBUSY;
8611ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8621ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	ex_table[exception] = ex_replaceable;
8631ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8641ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger	return 0;
8651ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger}
8661ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_free_exception);
8671ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger
8681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid panic_cplb_error(int cplb_panic, struct pt_regs *fp)
8691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{
8701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	switch (cplb_panic) {
8711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case CPLB_NO_UNLOCKED:
8721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		printk(KERN_EMERG "All CPLBs are locked\n");
8731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
8741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case CPLB_PROT_VIOL:
8751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		return;
8761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case CPLB_NO_ADDR_MATCH:
8771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		return;
8781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	case CPLB_UNKNOWN_ERR:
8791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		printk(KERN_EMERG "Unknown CPLB Exception\n");
8801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu		break;
8811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	}
8821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu
883226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz	oops_in_progress = 1;
884226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz
8851f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger	printk(KERN_EMERG "DCPLB_FAULT_ADDR=%p\n", (void *)bfin_read_DCPLB_FAULT_ADDR());
8861f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger	printk(KERN_EMERG "ICPLB_FAULT_ADDR=%p\n", (void *)bfin_read_ICPLB_FAULT_ADDR());
88749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	dump_bfin_process(fp);
88849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	dump_bfin_mem((void *)fp->retx);
88949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger	show_regs(fp);
8901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	dump_stack();
8911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu	panic("Unrecoverable event\n");
8921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu}
893