traps.c revision 36b841288656b9b30b5d2add2fd136ac7eab5867
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 3070f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#include <linux/bug.h> 311f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/uaccess.h> 321f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/interrupt.h> 331f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/module.h> 341f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/kallsyms.h> 35d31c5ab147e0b17b9ec0daa5e4d1fc0bd6b19974Bryan Wu#include <linux/fs.h> 368feae13110d60cc6287afabc2887366b0eb226c2David Howells#include <linux/rbtree.h> 371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/traps.h> 381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/cacheflush.h> 39f4585a08479a730fb809606b8ee327a5398c117cMike Frysinger#include <asm/cplb.h> 40e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger#include <asm/dma.h> 411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/blackfin.h> 421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/irq_handler.h> 43d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz#include <linux/irq.h> 44669b792c77bbc30e9f4d9c95dbc918dc348c49c2Robin Getz#include <asm/trace.h> 45226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#include <asm/fixed_code.h> 461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu# include <linux/kgdb.h> 49226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 50226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() \ 51226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 52a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang kgdb_handle_exception(trapnr, sig, info.si_code, fp); \ 53226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 54226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() \ 55226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 56226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (kgdb_connected) \ 57226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz CHK_DEBUGGER_TRAP(); \ 58226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 59226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#else 60226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() do { } while (0) 61226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) 621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 649f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 654ee1c45337e7b529eed644c6f62399d797dcbc10Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 669f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#define verbose_printk(fmt, arg...) \ 679f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(fmt, ##arg) 689f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#else 699f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#define verbose_printk(fmt, arg...) \ 709f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz ({ if (0) printk(fmt, ##arg); 0; }) 719f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 729f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 7381f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) 7481f7f45606812f1d15d618c2646d0f33ca111f87Robin Getzu32 last_seqstat; 7581f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#ifdef CONFIG_DEBUG_MMRS_MODULE 7681f7f45606812f1d15d618c2646d0f33ca111f87Robin GetzEXPORT_SYMBOL(last_seqstat); 7781f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#endif 7881f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#endif 7981f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz 801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Initiate the event table handler */ 811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid __init trap_init(void) 821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu bfin_write_EVT3(trap); 851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 88226eb1ef523a33c66193bc319a92c647e47311d4Robin Getzstatic void decode_address(char *buf, unsigned long address) 891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 909f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct task_struct *p; 921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct mm_struct *mm; 93885be03b069131d242506f0f717d38659b2bdb6cRobin Getz unsigned long flags, offset; 94904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); 958feae13110d60cc6287afabc2887366b0eb226c2David Howells struct rb_node *n; 961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KALLSYMS 988a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger unsigned long symsize; 991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu const char *symname; 1001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *modname; 1011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *delim = ":"; 1021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char namebuf[128]; 10318070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger#endif 10418070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger 10518070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger buf += sprintf(buf, "<0x%08lx> ", address); 1061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 10718070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger#ifdef CONFIG_KALLSYMS 1081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* look up the address and see if we are in kernel space */ 1091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 1101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (symname) { 1121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* yeah! kernel space! */ 1131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!modname) 1141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu modname = delim = ""; 11518070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger sprintf(buf, "{ %s%s%s%s + 0x%lx }", 11618070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger delim, modname, delim, symname, 11718070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger (unsigned long)offset); 118885be03b069131d242506f0f717d38659b2bdb6cRobin Getz return; 1191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 1211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 122226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { 12318070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger /* Problem in fixed code section? */ 12418070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger strcat(buf, "/* Maybe fixed code section */"); 12518070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger return; 12618070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger 12718070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger } else if (address < CONFIG_BOOT_LOAD) { 12818070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger /* Problem somewhere before the kernel start address */ 12918070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger strcat(buf, "/* Maybe null pointer? */"); 13018070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger return; 13118070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger 13218070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger } else if (address >= COREMMR_BASE) { 13318070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger strcat(buf, "/* core mmrs */"); 13418070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger return; 13518070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger 13618070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger } else if (address >= SYSMMR_BASE) { 13718070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger strcat(buf, "/* system mmrs */"); 138226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 139226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 14018070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger } else if (address >= L1_ROM_START && address < L1_ROM_START + L1_ROM_LENGTH) { 14118070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger strcat(buf, "/* on-chip L1 ROM */"); 142226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 143226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 144226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* looks like we're off in user-land, so let's walk all the 1461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * mappings of all our processes and see if we can't be a whee 1471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * bit more specific 1481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 149885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_lock_irqsave(&tasklist_lock, flags); 1501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu for_each_process(p) { 151904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz mm = (in_atomic ? p->mm : get_task_mm(p)); 1521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!mm) 1531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu continue; 1541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1558feae13110d60cc6287afabc2887366b0eb226c2David Howells for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { 1568feae13110d60cc6287afabc2887366b0eb226c2David Howells struct vm_area_struct *vma; 1578feae13110d60cc6287afabc2887366b0eb226c2David Howells 1588feae13110d60cc6287afabc2887366b0eb226c2David Howells vma = rb_entry(n, struct vm_area_struct, vm_rb); 1591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (address >= vma->vm_start && address < vma->vm_end) { 161cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck char _tmpbuf[256]; 1621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *name = p->comm; 1631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct file *file = vma->vm_file; 164cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck 1656a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper if (file) { 1666a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper char *d_name = d_path(&file->f_path, _tmpbuf, 167cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck sizeof(_tmpbuf)); 1686a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper if (!IS_ERR(d_name)) 1696a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper name = d_name; 1706a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper } 1711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1728a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger /* FLAT does not have its text aligned to the start of 1738a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger * the map while FDPIC ELF does ... 1748a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger */ 1757f1c906808a36630990d83d872935c079b76595bRobin Getz 1767f1c906808a36630990d83d872935c079b76595bRobin Getz /* before we can check flat/fdpic, we need to 1777f1c906808a36630990d83d872935c079b76595bRobin Getz * make sure current is valid 1787f1c906808a36630990d83d872935c079b76595bRobin Getz */ 1797f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 1807f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3)) { 1817f1c906808a36630990d83d872935c079b76595bRobin Getz if (current->mm && 1827f1c906808a36630990d83d872935c079b76595bRobin Getz (address > current->mm->start_code) && 1837f1c906808a36630990d83d872935c079b76595bRobin Getz (address < current->mm->end_code)) 1847f1c906808a36630990d83d872935c079b76595bRobin Getz offset = address - current->mm->start_code; 1857f1c906808a36630990d83d872935c079b76595bRobin Getz else 1867f1c906808a36630990d83d872935c079b76595bRobin Getz offset = (address - vma->vm_start) + 1877f1c906808a36630990d83d872935c079b76595bRobin Getz (vma->vm_pgoff << PAGE_SHIFT); 1887f1c906808a36630990d83d872935c079b76595bRobin Getz 18918070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger sprintf(buf, "[ %s + 0x%lx ]", name, offset); 1907f1c906808a36630990d83d872935c079b76595bRobin Getz } else 19118070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger sprintf(buf, "[ %s vma:0x%lx-0x%lx]", 19218070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger name, vma->vm_start, vma->vm_end); 1937f1c906808a36630990d83d872935c079b76595bRobin Getz 194904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 195885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 1967f1c906808a36630990d83d872935c079b76595bRobin Getz 19718070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger if (buf[0] == '\0') 19818070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger sprintf(buf, "[ %s ] dynamic memory", name); 199f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 200885be03b069131d242506f0f717d38659b2bdb6cRobin Getz goto done; 2011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 2021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 203904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 204885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 2051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 2061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* we were unable to find this address anywhere */ 20818070dd6692a35bec266ed9ea559c24da4fdeeefMike Frysinger sprintf(buf, "/* kernel dynamic memory */"); 209885be03b069131d242506f0f717d38659b2bdb6cRobin Getz 210885be03b069131d242506f0f717d38659b2bdb6cRobin Getzdone: 211885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_unlock_irqrestore(&tasklist_lock, flags); 2129f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#else 2139f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz sprintf(buf, " "); 2149f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 2151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 2161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2172ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getzasmlinkage void double_fault_c(struct pt_regs *fp) 2182ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz{ 219a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 220a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz int j; 221a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz trace_buffer_save(j); 222a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz#endif 223a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz 224226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 225226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 2269f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 227ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches printk(KERN_EMERG "Double Fault\n"); 2280c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT 2290c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { 2308f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang unsigned int cpu = smp_processor_id(); 2310c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz char buf[150]; 2328f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].retx); 2330c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", 2348f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang (unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf); 2358f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); 2360c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); 2378f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].icplb_fault_addr); 2380c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); 2390c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz 2400c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz decode_address(buf, fp->retx); 2418f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang printk(KERN_NOTICE "The instruction at %s caused a double exception\n", buf); 2420c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz } else 2430c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz#endif 2440c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz { 2450c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz dump_bfin_process(fp); 2460c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz dump_bfin_mem(fp); 2470c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz show_regs(fp); 248a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz dump_bfin_trace_buffer(); 2490c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz } 2509f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 251d8804adf52f5991388fa9af77428e4cc7768059dMike Frysinger panic("Double Fault - unrecoverable event"); 2522ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 2532ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz} 2542ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 25582bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysingerstatic int kernel_mode_regs(struct pt_regs *regs) 25682bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger{ 25782bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger return regs->ipend & 0xffc0; 25882bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger} 25982bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger 2601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage void trap_c(struct pt_regs *fp) 2611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 262518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 263518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j; 264518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 2658f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 2668f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang unsigned int cpu = smp_processor_id(); 2678f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang#endif 26882bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger const char *strerror = NULL; 269518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int sig = 0; 2701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu siginfo_t info; 2711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; 2721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 273226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz trace_buffer_save(j); 27481f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) 27581f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz last_seqstat = (u32)fp->seqstat; 27681f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#endif 277226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 278226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Important - be very careful dereferncing pointers - will lead to 279226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * double faults if the stack has become corrupt 280226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz */ 281226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 2821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* trap_c() will be called for exceptions. During exceptions 2831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * processing, the pc value should be set with retx value. 2841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * With this change we can cleanup some code in signal.c- TODO 2851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 2861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu fp->orig_pc = fp->retx; 2871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", 2881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trapnr, fp->ipend, fp->pc, fp->retx); */ 2891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* send the appropriate signal to the user program */ 2911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (trapnr) { 2921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* This table works in conjuction with the one in ./mach-common/entry.S 2941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some exceptions are handled there (in assembly, in exception space) 2951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some are handled here, (in C, in interrupt space) 2961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some, like CPLB, are handled in both, where the normal path is 2971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * handled in assembly/exception space, and the error path is handled 2981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * here 2991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 3001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 3011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x00 - Linux Syscall, getting here is an error */ 3021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x01 - userspace gdb breakpoint, handled here */ 3031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT01: 3041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_ILLTRAP; 3051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 3061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 3071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a breakpoint in kernel space */ 30882bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger if (kernel_mode_regs(fp)) 3096510a20e1b1a3a5703429a09d03adf44882ae373Mike Frysinger goto traps_done; 3101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3129401e618c8f70920f34893946239e24d40a3519aMike Frysinger /* 0x03 - User Defined, userspace stack overflow */ 3131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT03: 3141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = SEGV_STACKFLOW; 3151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 31682bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x03(KERN_NOTICE); 317a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 31927707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang /* 0x02 - KGDB initial connection and break signal trap */ 32027707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang case VEC_EXCPT02: 32127707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang#ifdef CONFIG_KGDB 32227707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang info.si_code = TRAP_ILLTRAP; 32327707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang sig = SIGTRAP; 32427707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang CHK_DEBUGGER_TRAP(); 3256510a20e1b1a3a5703429a09d03adf44882ae373Mike Frysinger goto traps_done; 32627707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang#endif 3275c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x04 - User Defined */ 3285c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x05 - User Defined */ 3295c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x06 - User Defined */ 3305c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x07 - User Defined */ 3315c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x08 - User Defined */ 3325c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x09 - User Defined */ 3335c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0A - User Defined */ 3345c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0B - User Defined */ 3355c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0C - User Defined */ 3365c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0D - User Defined */ 3375c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0E - User Defined */ 3385c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0F - User Defined */ 33927707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang /* If we got here, it is most likely that someone was trying to use a 3405c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * custom exception handler, and it is not actually installed properly 3415c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz */ 3425c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz case VEC_EXCPT04 ... VEC_EXCPT15: 3435c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz info.si_code = ILL_ILLPARAOP; 3445c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz sig = SIGILL; 34582bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x04(KERN_NOTICE); 3465c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz CHK_DEBUGGER_TRAP_MAYBE(); 3475c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz break; 3481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x10 HW Single step, handled here */ 3491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_STEP: 3501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_STEP; 3511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 3521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 3531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a single step in kernel space */ 35482bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger if (kernel_mode_regs(fp)) 3556510a20e1b1a3a5703429a09d03adf44882ae373Mike Frysinger goto traps_done; 3561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x11 - Trace Buffer Full, handled here */ 3591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_OVFLOW: 3601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_TRACEFLOW; 3611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 36282bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x11(KERN_NOTICE); 363a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x12 - Reserved, Caught by default */ 3661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x13 - Reserved, Caught by default */ 3671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x14 - Reserved, Caught by default */ 3681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x15 - Reserved, Caught by default */ 3691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x16 - Reserved, Caught by default */ 3701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x17 - Reserved, Caught by default */ 3711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x18 - Reserved, Caught by default */ 3721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x19 - Reserved, Caught by default */ 3731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1A - Reserved, Caught by default */ 3741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1B - Reserved, Caught by default */ 3751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1C - Reserved, Caught by default */ 3761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1D - Reserved, Caught by default */ 3771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1E - Reserved, Caught by default */ 3781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1F - Reserved, Caught by default */ 3791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x20 - Reserved, Caught by default */ 3801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x21 - Undefined Instruction, handled here */ 3811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNDEF_I: 38270f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#ifdef CONFIG_BUG 38370f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger if (kernel_mode_regs(fp)) { 38470f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger switch (report_bug(fp->pc, fp)) { 38570f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger case BUG_TRAP_TYPE_NONE: 38670f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger break; 38770f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger case BUG_TRAP_TYPE_WARN: 38870f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger dump_bfin_trace_buffer(); 38970f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger fp->pc += 2; 39070f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger goto traps_done; 39170f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger case BUG_TRAP_TYPE_BUG: 39270f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger /* call to panic() will dump trace, and it is 39370f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger * off at this point, so it won't be clobbered 39470f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger */ 39570f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger panic("BUG()"); 39670f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger } 39770f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger } 39870f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#endif 3991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLOPC; 4001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 40182bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x21(KERN_NOTICE); 402a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x22 - Illegal Instruction Combination, handled here */ 4051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILGAL_I: 4061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLPARAOP; 4071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 40882bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x22(KERN_NOTICE); 409a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 411f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x23 - Data CPLB protection violation, handled here */ 4121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_VL: 4131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 41436b841288656b9b30b5d2add2fd136ac7eab5867Graf Yang sig = SIGSEGV; 41582bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x23(KERN_NOTICE); 416a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x24 - Data access misaligned, handled here */ 4191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_D: 4201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 42282bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x24(KERN_NOTICE); 423a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x25 - Unrecoverable Event, handled here */ 4261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNCOV: 4271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLEXCPT; 4281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 42982bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x25(KERN_NOTICE); 430a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, 4331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu error case is handled here */ 4341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_M: 4351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 43782bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x26(KERN_NOTICE); 4381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ 4401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_MHIT: 4411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 4421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 443c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 4448f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (cpu_pda[cpu].dcplb_fault_addr < FIXED_CODE_START) 44582bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE "NULL pointer access\n"; 446c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 4471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 44882bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x27(KERN_NOTICE); 449a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x28 - Emulation Watchpoint, handled here */ 4521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_WATCH: 4531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_WATCHPT; 4541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 455569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz pr_debug(EXC_0x28(KERN_DEBUG)); 4561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 4571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a watchpoint in kernel space */ 45882bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger if (kernel_mode_regs(fp)) 4596510a20e1b1a3a5703429a09d03adf44882ae373Mike Frysinger goto traps_done; 4601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 4611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_BF535 4631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Instruction fetch access error (535 only) */ 4641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */ 4651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_OPFETCH; 4661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 46782bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE "BF535: VEC_ISTRU_VL\n"; 468a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else 4711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Reserved, Caught by default */ 4721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 4731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2A - Instruction fetch misaligned, handled here */ 4741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_I: 4751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 47782bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x2A(KERN_NOTICE); 478a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 480f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x2B - Instruction CPLB protection violation, handled here */ 4811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_VL: 4821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 483f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz sig = SIGBUS; 48482bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x2B(KERN_NOTICE); 485a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ 4881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_M: 4891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MISS; 4901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 49182bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x2C(KERN_NOTICE); 4921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2D - Instruction CPLB Multiple Hits, handled here */ 4941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_MHIT: 4951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 4961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 497c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 4988f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (cpu_pda[cpu].icplb_fault_addr < FIXED_CODE_START) 49982bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE "Jump to NULL address\n"; 500c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 5011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 50282bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x2D(KERN_NOTICE); 503a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 5041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 5051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2E - Illegal use of Supervisor Resource, handled here */ 5061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILL_RES: 5071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_PRVOPC; 5081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 50982bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE EXC_0x2E(KERN_NOTICE); 510a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 5111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 5121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2F - Reserved, Caught by default */ 5131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x30 - Reserved, Caught by default */ 5141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x31 - Reserved, Caught by default */ 5151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x32 - Reserved, Caught by default */ 5161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x33 - Reserved, Caught by default */ 5171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x34 - Reserved, Caught by default */ 5181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x35 - Reserved, Caught by default */ 5191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x36 - Reserved, Caught by default */ 5201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x37 - Reserved, Caught by default */ 5211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x38 - Reserved, Caught by default */ 5221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x39 - Reserved, Caught by default */ 5231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3A - Reserved, Caught by default */ 5241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3B - Reserved, Caught by default */ 5251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3C - Reserved, Caught by default */ 5261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3D - Reserved, Caught by default */ 5271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3E - Reserved, Caught by default */ 5281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3F - Reserved, Caught by default */ 52913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case VEC_HWERR: 53013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 53113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 53213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz switch (fp->seqstat & SEQSTAT_HWERRCAUSE) { 53313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* System MMR Error */ 53413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): 53513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 53613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 53782bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE HWC_x2(KERN_NOTICE); 53813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 53913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* External Memory Addressing Error */ 54013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): 54113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRERR; 54213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 54382bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE HWC_x3(KERN_NOTICE); 54413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 54513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* Performance Monitor Overflow */ 54613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_PERF_FLOW): 54782bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger strerror = KERN_NOTICE HWC_x12(KERN_NOTICE); 54813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 54913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* RAISE 5 instruction */ 55013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_RAISE_5): 55113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_x18(KERN_NOTICE)); 55213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 55313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz default: /* Reserved */ 55413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_default(KERN_NOTICE)); 55513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 55613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz } 557a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 55813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 5595c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 5605c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * We should be handling all known exception types above, 5615c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * if we get here we hit a reserved one, so panic 5625c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz */ 5631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu default: 5645c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz info.si_code = ILL_ILLPARAOP; 5655c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz sig = SIGILL; 5669f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", 5671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu (fp->seqstat & SEQSTAT_EXCAUSE)); 568a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 5691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 5701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 5711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 572226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz BUG_ON(sig == 0); 573226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 57482bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger /* If the fault was caused by a kernel thread, or interrupt handler 57582bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger * we will kernel panic, so the system reboots. 57682bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger */ 57782bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger if (kernel_mode_regs(fp) || (current && !current->mm)) { 57882bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger console_verbose(); 57982bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger oops_in_progress = 1; 58082bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger } 58182bd1d7d45a69c54fb6beedb78ccb1c7d308dd93Mike Frysinger 582226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (sig != SIGTRAP) { 58315627bd35c6f02d159e0cb41d287dcba3a23a135Mike Frysinger if (strerror) 58415627bd35c6f02d159e0cb41d287dcba3a23a135Mike Frysinger verbose_printk(strerror); 58515627bd35c6f02d159e0cb41d287dcba3a23a135Mike Frysinger 58649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 587b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 58849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 589226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 590226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Print out the trace buffer if it makes sense */ 591226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE 592226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M) 5939f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "No trace since you do not have " 594ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n\n"); 595226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz else 596226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 597226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz dump_bfin_trace_buffer(); 598f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 599226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (oops_in_progress) { 600f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the current kernel stack */ 601ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches verbose_printk(KERN_NOTICE "Kernel Stack\n"); 602f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(current, NULL); 603aee3a29240ad167ad7875d859506d8bb90431c70Robin Getz print_modules(); 604226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_ACCESS_CHECK 6059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Please turn on " 60690c7f4686f82aef875aadf8e5c9c1a9465e5143bRobin Getz "CONFIG_ACCESS_CHECK\n"); 607226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 6081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu panic("Kernel exception"); 609f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 6104ee1c45337e7b529eed644c6f62399d797dcbc10Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 6119f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz unsigned long *stack; 612f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the user space stack */ 613f09630bff51daaf427968c61c0f2370c64148e06Robin Getz stack = (unsigned long *)rdusp(); 6149f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Userspace Stack\n"); 615f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(NULL, stack); 6169f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 617226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 6181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 619fb322915a05804a3a153f714f2f08e4c32ce84c7Robin Getz 6206a01f230339321292cf065551f8cf55361052461Yi Li#ifdef CONFIG_IPIPE 6216a01f230339321292cf065551f8cf55361052461Yi Li if (!ipipe_trap_notify(fp->seqstat & 0x3f, fp)) 6226a01f230339321292cf065551f8cf55361052461Yi Li#endif 6236a01f230339321292cf065551f8cf55361052461Yi Li { 6246a01f230339321292cf065551f8cf55361052461Yi Li info.si_signo = sig; 6256a01f230339321292cf065551f8cf55361052461Yi Li info.si_errno = 0; 6266a01f230339321292cf065551f8cf55361052461Yi Li info.si_addr = (void __user *)fp->pc; 6276a01f230339321292cf065551f8cf55361052461Yi Li force_sig_info(sig, &info, current); 6286a01f230339321292cf065551f8cf55361052461Yi Li } 6291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 6300e4edcf0b0f7d96c4be7788b13bee82e4d3ba0ceRobin Getz if ((ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) || 631f574a76a3b19848ac61814756716e26f85f2c3f7Robin Getz (ANOMALY_05000281 && trapnr == VEC_HWERR) || 632f574a76a3b19848ac61814756716e26f85f2c3f7Robin Getz (ANOMALY_05000189 && (trapnr == VEC_CPLB_I_VL || trapnr == VEC_CPLB_VL))) 6330acad8dfee6bde7e246a95a52f864a8eee777ed8Robin Getz fp->pc = SAFE_USER_INSTRUCTION; 6340acad8dfee6bde7e246a95a52f864a8eee777ed8Robin Getz 6356510a20e1b1a3a5703429a09d03adf44882ae373Mike Frysinger traps_done: 6361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(j); 6371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 6381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 6391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Typical exception handling routines */ 6401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 641518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) 642518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 643f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 644f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Similar to get_user, do some address checking, then dereference 645f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Return true on sucess, false on bad address 646f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 6479f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic bool get_instruction(unsigned short *val, unsigned short *address) 648f09630bff51daaf427968c61c0f2370c64148e06Robin Getz{ 649e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger unsigned long addr = (unsigned long)address; 650f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 651f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Check for odd addresses */ 652f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr & 0x1) 653f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 654f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 655e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger /* MMR region will never have instructions */ 656e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger if (addr >= SYSMMR_BASE) 657f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 658f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 659e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger switch (bfin_mem_access_type(addr, 2)) { 660e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger case BFIN_MEM_ACCESS_CORE: 661e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger case BFIN_MEM_ACCESS_CORE_ONLY: 662e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger *val = *address; 663e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger return true; 664e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger case BFIN_MEM_ACCESS_DMA: 665e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger dma_memcpy(val, address, 2); 666e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger return true; 667e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger case BFIN_MEM_ACCESS_ITEST: 668e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger isram_memcpy(val, address, 2); 669e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger return true; 670e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger default: /* invalid access */ 671e56e03b0cfeb997a4be9ad874c193824364942e0Mike Frysinger return false; 672f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 673f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 674f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 67536f649a55aa3ad1e2196403ba95a652f9900bc50Mike Frysinger/* 676d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * decode the instruction if we are printing out the trace, as it 677d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * makes things easier to follow, without running it through objdump 678d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * These are the normal instructions which cause change of flow, which 679d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * would be at the source of the trace buffer 680d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz */ 68136f649a55aa3ad1e2196403ba95a652f9900bc50Mike Frysinger#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) 6829f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic void decode_instruction(unsigned short *address) 683d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz{ 684d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short opcode; 685d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 686d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (get_instruction(&opcode, address)) { 687d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (opcode == 0x0010) 6889f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTS"); 689d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0011) 6909f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTI"); 691d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0012) 6929f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTX"); 6930be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0013) 6940be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("RTN"); 6950be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0014) 6960be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("RTE"); 6970be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0025) 6980be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("EMUEXCPT"); 6990be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0040 && opcode <= 0x0047) 7000be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("STI R%i", opcode & 7); 701d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0050 && opcode <= 0x0057) 7029f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP (P%i)", opcode & 7); 703d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0060 && opcode <= 0x0067) 7049f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL (P%i)", opcode & 7); 705d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0070 && opcode <= 0x0077) 7069f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL (PC+P%i)", opcode & 7); 707d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0080 && opcode <= 0x0087) 7089f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP (PC+P%i)", opcode & 7); 7090be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode >= 0x0090 && opcode <= 0x009F) 7100be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("RAISE 0x%x", opcode & 0xF); 7110be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode >= 0x00A0 && opcode <= 0x00AF) 7120be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("EXCPT 0x%x", opcode & 0xF); 713d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) 7149f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("IF !CC JUMP"); 715d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) 7169f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("IF CC JUMP"); 717d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x2000 && opcode <= 0x2fff) 7189f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP.S"); 719d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe080 && opcode <= 0xe0ff) 7209f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("LSETUP"); 721d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe200 && opcode <= 0xe2ff) 7229f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP.L"); 723d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe300 && opcode <= 0xe3ff) 7249f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL pcrel"); 725d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else 7269f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("0x%04x", opcode); 727d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz } 728d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 729d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz} 7309f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 731d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 7321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_bfin_trace_buffer(void) 7331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 7349f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 735518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 736518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int tflags, i = 0; 737226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz char buf[150]; 738d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short *addr; 739518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 740518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j, index; 741518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 742518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 7431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 7441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 745226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "Hardware Trace:\n"); 746518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 747d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 748d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); 749d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#endif 750d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 7511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { 752518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { 753226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, (unsigned long)bfin_read_TBUF()); 754226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 755f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned short *)bfin_read_TBUF(); 756f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned long)addr); 757f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 758d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction(addr); 759f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 7601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 7611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 7621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 763518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 764518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (trace_buff_offset) 765d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz index = trace_buff_offset / 4; 766518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz else 767518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 768518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 769518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; 770518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz while (j) { 771226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 772226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 773518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 774518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0 ) 775518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 776226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 777d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 778d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction((unsigned short *)software_trace_buff[index]); 779d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("\n"); 780518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 781518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0) 782518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 783518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j--; 784518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz i++; 785518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz } 786518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 787518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 7881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 789518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 7909f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 7911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 7921394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_bfin_trace_buffer); 7931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 79470f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#ifdef CONFIG_BUG 79570f12567ac9aca9c2f242ae060d7de245904889eMike Frysingerint is_valid_bugaddr(unsigned long addr) 79670f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger{ 79770f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger unsigned short opcode; 79870f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger 79970f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger if (!get_instruction(&opcode, (unsigned short *)addr)) 80070f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger return 0; 80170f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger 80270f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger return opcode == BFIN_BUG_OPCODE; 80370f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger} 80470f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#endif 80570f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger 806f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 807f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Checks to see if the address pointed to is either a 808f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * 16-bit CALL instruction, or a 32-bit CALL instruction 809f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 8109f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic bool is_bfin_call(unsigned short *addr) 8111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 812f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short opcode = 0, *ins_addr; 813f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)addr; 8141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 815f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 816f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 8171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 818f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if ((opcode >= 0x0060 && opcode <= 0x0067) || 819f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (opcode >= 0x0070 && opcode <= 0x0077)) 820f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 821f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 822f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 823f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 824f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 8251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 826f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (opcode >= 0xE300 && opcode <= 0xE3FF) 827f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 828f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 829f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 830f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 831f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 8329f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 8331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid show_stack(struct task_struct *task, unsigned long *stack) 8341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 8359f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_PRINTK 836f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int *addr, *endstack, *fp = 0, *frame; 837f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short *ins_addr; 838f09630bff51daaf427968c61c0f2370c64148e06Robin Getz char buf[150]; 839f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int i, j, ret_addr, frame_no = 0; 8401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 841f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 842f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * If we have been passed a specific stack, use that one otherwise 843f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * if we have been passed a task structure, use that, otherwise 844f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * use the stack of where the variable "stack" exists 8451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 8461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 847f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (stack == NULL) { 848f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (task) { 849f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* We know this is a kernel stack, so this is the start/end */ 8501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)task->thread.ksp; 851f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); 852f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 853f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* print out the existing stack info */ 8541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)&stack; 855f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 856f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 857f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 858f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 859f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 8609f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(KERN_NOTICE "Stack info:\n"); 861f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)stack); 8629f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); 8639f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 864a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz if (!access_ok(VERIFY_READ, stack, (unsigned int)endstack - (unsigned int)stack)) { 865a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz printk(KERN_NOTICE "Invalid stack pointer\n"); 866a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz return; 867a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz } 868a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz 869f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First thing is to look for a frame pointer */ 870881eb621fc191e58fa638c533073683be2b63c24Jie Zhang for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { 871f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1) 872f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 873f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 874f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 875f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (is_bfin_call(ins_addr)) 876f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 877f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 878f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 879f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Let's check to see if it is a frame pointer */ 880881eb621fc191e58fa638c533073683be2b63c24Jie Zhang while (fp >= (addr - 1) && fp < endstack 881881eb621fc191e58fa638c533073683be2b63c24Jie Zhang && fp && ((unsigned int) fp & 0x3) == 0) 882f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*fp; 883f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp == 0 || fp == endstack) { 884f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 885f09630bff51daaf427968c61c0f2370c64148e06Robin Getz break; 886f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 887f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = 0; 888f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 8891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 890f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 891f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = fp; 892b339dc79b49841eff0aeecfc444cbb7b26007649Jie Zhang printk(KERN_NOTICE " FP: (0x%p)\n", fp); 893f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 894f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = 0; 8951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 896f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 897f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Now that we think we know where things are, we 898f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * walk the stack again, this time printing things out 899f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * incase there is no frame pointer, we still look for 900f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * valid return addresses 901f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 9021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 903f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First time print out data, next time, print out symbols */ 904f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (j = 0; j <= 1; j++) { 905f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 906f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE "Return addresses in stack:\n"); 907f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 908f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); 909f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 910f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = frame; 911f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no = 0; 912f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 913f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; 914407505dc01ac2b4f2944cd3c6a0c02473ffb869eSonic Zhang addr < endstack; addr++, i++) { 915f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 916f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = 0; 917f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && i % 8 == 0) 918ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches printk(KERN_NOTICE "%p:",addr); 919f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 920f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* if it is an odd address, or zero, just skip it */ 921f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1 || !*addr) 922f09630bff51daaf427968c61c0f2370c64148e06Robin Getz goto print; 923f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 924f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 925f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 926f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Go back one instruction, and see if it is a CALL */ 927f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 928f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = is_bfin_call(ins_addr); 929f09630bff51daaf427968c61c0f2370c64148e06Robin Getz print: 930f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && stack == (unsigned long *)addr) 931f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("[%08x]", *addr); 932f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (ret_addr) 933f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) { 934f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)*addr); 935f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (frame == addr) { 936f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); 937f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 938f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 939f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " address : %s\n", buf); 940f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 941f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("<%08x>", *addr); 942f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (fp == addr) { 943f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 944f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = addr+1; 945f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 946f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("(%08x)", *addr); 947f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 948f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*addr; 949f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no++; 950f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 951f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else if (!j) 952f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(" %08x ", *addr); 953f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 954f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j) 955f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 9561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 9579f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 9581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 959bc569f1a77199926be97ba6266dbea27768264dfPhilippe GerumEXPORT_SYMBOL(show_stack); 9601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 9611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_stack(void) 9621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 9631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long stack; 964518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 9651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int tflags; 966518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 9671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 9681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_bfin_trace_buffer(); 9691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu show_stack(current, &stack); 9701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 9711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 9721394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_stack); 9731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 97449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid dump_bfin_process(struct pt_regs *fp) 9751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 9769f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 97749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger /* We should be able to look at fp->ipend, but we don't push it on the 97849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger * stack all the time, so do this until we fix that */ 97949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger unsigned int context = bfin_read_IPEND(); 98049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 98149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger if (oops_in_progress) 9829f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); 98349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 984b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) 9859f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "HW Error context\n"); 986b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz else if (context & 0x0020) 9879f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Deferred Exception context\n"); 98849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x3FC0) 9899f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Interrupt context\n"); 99049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x4000) 9919f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); 99249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x8000) 9939f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Kernel process context\n"); 99449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 9959a62ca40fd793742f92565104c6b44319af8c282Robin Getz /* Because we are crashing, and pointers could be bad, we check things 9969a62ca40fd793742f92565104c6b44319af8c282Robin Getz * pretty closely before we use them 9979a62ca40fd793742f92565104c6b44319af8c282Robin Getz */ 9987f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 9997f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3) && current->pid) { 10009f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); 10019a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (current->comm >= (char *)FIXED_CODE_START) 10029f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n", 10039a62ca40fd793742f92565104c6b44319af8c282Robin Getz current->comm, current->pid); 10049a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 10059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "COMM= invalid\n"); 10069a62ca40fd793742f92565104c6b44319af8c282Robin Getz 10078f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu); 10089a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) 1009ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches verbose_printk(KERN_NOTICE 1010ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" 1011ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches " BSS = 0x%p-0x%p USER-STACK = 0x%p\n\n", 10129a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_code, 10139a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_code, 10149a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_data, 10159a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 10169a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 10179a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->brk, 10189a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_stack); 10199a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 10209f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "invalid mm\n"); 102149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger } else 1022ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches verbose_printk(KERN_NOTICE 1023ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches "No Valid process in current context\n"); 10249f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 102549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 1026226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1027b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getzvoid dump_bfin_mem(struct pt_regs *fp) 102849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 10299f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 1030b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz unsigned short *addr, *erraddr, val = 0, err = 0; 1031b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz char sti = 0, buf[6]; 10321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 10335d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt erraddr = (void *)fp->pc; 1034b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 10359f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); 1036b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1037b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; 1038b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; 1039b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr++) { 1040b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (!((unsigned long)addr & 0xF)) 1041ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches verbose_printk(KERN_NOTICE "0x%p: ", addr); 1042b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 10437d98c881eed9e19767bc77ffd650d0041b4f41ecRobin Getz if (!get_instruction(&val, addr)) { 1044b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val = 0; 1045b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "????"); 1046b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 1047b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "%04x", val); 1048b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1049b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr == erraddr) { 10509f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("[%s]", buf); 1051b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz err = val; 1052b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 10539f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(" %s ", buf); 1054b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1055b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Do any previous instructions turn on interrupts? */ 1056b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr <= erraddr && /* in the past */ 1057b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */ 1058b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val == 0x017b)) /* [SP++] = RETI */ 1059b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sti = 1; 1060b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 1061b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 10629f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n"); 1063b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1064b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Hardware error interrupts can be deferred */ 1065b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && 1066b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz oops_in_progress)){ 10679f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); 10681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifndef CONFIG_DEBUG_HWERR 1069ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches verbose_printk(KERN_NOTICE 1070ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches"The remaining message may be meaningless\n" 1071ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches"You should enable CONFIG_DEBUG_HWERR to get a better idea where it came from\n"); 1072b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#else 1073b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* If we are handling only one peripheral interrupt 1074b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * and current mm and pid are valid, and the last error 1075b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * was in that user space process's text area 1076b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * print it out - because that is where the problem exists 1077b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz */ 1078b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) && 1079b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (current->pid && current->mm)) { 1080b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* And the last RETI points to the current userspace context */ 1081b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((fp + 1)->pc >= current->mm->start_code && 1082b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (fp + 1)->pc <= current->mm->end_code) { 10839f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "It might be better to look around here : \n"); 10849f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1085b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz show_regs(fp + 1); 10869f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1087b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 10881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1089b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#endif 1090b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 10919f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 109249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 109349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 109449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid show_regs(struct pt_regs *fp) 109549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 10969f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 109749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger char buf [150]; 1098d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz struct irqaction *action; 1099d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz unsigned int i; 11002f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz unsigned long flags = 0; 11018f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang unsigned int cpu = smp_processor_id(); 11022f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); 1103226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 11049ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "\n"); 11059ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz if (CPUID != bfin_cpuid()) 11069ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " 11079ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz "but running on:0x%04x (Rev %d)\n", 11089ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); 11099ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11109ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", 11119ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz CPU, bfin_compiled_revid()); 11129ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11139ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz if (bfin_compiled_revid() != bfin_revid()) 11149ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk("(Detected 0.%d)", bfin_revid()); 11159ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11169ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", 11179ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz get_cclk()/1000000, get_sclk()/1000000, 11189ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz#ifdef CONFIG_MPU 11199ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz "mpu on" 11209ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz#else 11219ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz "mpu off" 11229ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz#endif 11239ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz ); 11249ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11259ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "%s", linux_banner); 11269ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 1127ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz verbose_printk(KERN_NOTICE "\nSEQUENCER STATUS:\t\t%s\n", print_tainted()); 1128ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx IMASK: %04lx SYSCFG: %04lx\n", 1129ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz (long)fp->seqstat, fp->ipend, cpu_pda[smp_processor_id()].ex_imask, fp->syscfg); 1130ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz if (fp->ipend & EVT_IRPTEN) 1131ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz verbose_printk(KERN_NOTICE " Global Interrupts Disabled (IPEND[4])\n"); 1132ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG13 | EVT_IVG12 | EVT_IVG11 | 1133ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz EVT_IVG10 | EVT_IVG9 | EVT_IVG8 | EVT_IVG7 | EVT_IVTMR))) 1134ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz verbose_printk(KERN_NOTICE " Peripheral interrupts masked off\n"); 1135ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz if (!(cpu_pda[smp_processor_id()].ex_imask & (EVT_IVG15 | EVT_IVG14))) 1136ae4f073c40bf677b03826262e6022b4a251fe437Robin Getz verbose_printk(KERN_NOTICE " Kernel interrupts masked off\n"); 11371d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { 11389f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", 11391d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); 11401d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz#ifdef EBIU_ERRMST 11411d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz /* If the error was from the EBIU, print it out */ 11421d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { 11439f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", 11441d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz bfin_read_EBIU_ERRMST()); 11459f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", 11461d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz bfin_read_EBIU_ERRADD()); 11471d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz } 11481d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz#endif 11491d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz } 11509f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", 115113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz fp->seqstat & SEQSTAT_EXCAUSE); 11522f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz for (i = 2; i <= 15 ; i++) { 1153d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & (1 << i)) { 11542f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz if (i != 4) { 11552f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz decode_address(buf, bfin_read32(EVT0 + 4*i)); 11562f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); 11572f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz } else 11582f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz verbose_printk(KERN_NOTICE " interrupts disabled\n"); 1159d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1160d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1161d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1162d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz /* if no interrupts are going off, don't print this out */ 1163d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & ~0x3F) { 1164d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (i = 0; i < (NR_IRQS - 1); i++) { 11652f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz if (!in_atomic) 11662f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz spin_lock_irqsave(&irq_desc[i].lock, flags); 11672f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz 1168d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz action = irq_desc[i].action; 1169d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (!action) 1170d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz goto unlock; 1171d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1172d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 11739f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); 1174d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (action = action->next; action; action = action->next) { 1175d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 11769f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(", %s", buf); 1177d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 11789f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n"); 1179d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getzunlock: 11802f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz if (!in_atomic) 11812f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz spin_unlock_irqrestore(&irq_desc[i].lock, flags); 1182d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1183d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1184c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 1185226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rete); 11869f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETE: %s\n", buf); 1187226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retn); 11889f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETN: %s\n", buf); 1189226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retx); 11909f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETX: %s\n", buf); 1191226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rets); 11929f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETS: %s\n", buf); 119349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger decode_address(buf, fp->pc); 11949f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " PC : %s\n", buf); 1195c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 119613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && 119713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { 11988f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); 11999f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); 12008f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].icplb_fault_addr); 12019f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); 1202226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 1203226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1204ad361c9884e809340f6daca80d56a9e9c871690aJoe Perches verbose_printk(KERN_NOTICE "PROCESSOR STATE:\n"); 12059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", 1206c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r0, fp->r1, fp->r2, fp->r3); 12079f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", 1208c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r4, fp->r5, fp->r6, fp->r7); 12099f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", 1210c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->p0, fp->p1, fp->p2, fp->p3); 12119f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", 1212226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->p4, fp->p5, fp->fp, (long)fp); 12139f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", 1214c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb0, fp->lt0, fp->lc0); 12159f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", 1216c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb1, fp->lt1, fp->lc1); 12179f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", 1218c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b0, fp->l0, fp->m0, fp->i0); 12199f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", 1220c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b1, fp->l1, fp->m1, fp->i1); 12219f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", 1222c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b2, fp->l2, fp->m2, fp->i2); 12239f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", 1224c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b3, fp->l3, fp->m3, fp->i3); 12259f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", 1226226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->a0w, fp->a0x, fp->a1w, fp->a1x); 1227c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 12289f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", 1229c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz rdusp(), fp->astat); 12301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12319f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n"); 12329f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 12331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 12341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 12361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); 12371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 12381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12398f65873e47784a390949f0d61e5692dbf2a8253eGraf Yangstatic DEFINE_SPINLOCK(bfin_spinlock_lock); 12408f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang 12418f65873e47784a390949f0d61e5692dbf2a8253eGraf Yangasmlinkage int sys_bfin_spinlock(int *p) 12421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 12438f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang int ret, tmp = 0; 12441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12458f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang spin_lock(&bfin_spinlock_lock); /* This would also hold kernel preemption. */ 12468f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang ret = get_user(tmp, p); 12478f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (likely(ret == 0)) { 12488f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (unlikely(tmp)) 12491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu ret = 1; 12508f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang else 12518f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang put_user(1, p); 12521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 12538f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang spin_unlock(&bfin_spinlock_lock); 12541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return ret; 12551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 12561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12571ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_request_exception(unsigned int exception, void (*handler)(void)) 12581ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 12591ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 12601ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12611ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 12621ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 12631ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12641ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 12651ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12661ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != ex_replaceable) 12671ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 12681ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12691ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = handler; 12701ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12711ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 12721ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 12731ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_request_exception); 12741ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12751ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_free_exception(unsigned int exception, void (*handler)(void)) 12761ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 12771ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 12781ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12791ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 12801ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 12811ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12821ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 12831ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12841ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != handler) 12851ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 12861ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12871ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = ex_replaceable; 12881ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12891ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 12901ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 12911ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_free_exception); 12921ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid panic_cplb_error(int cplb_panic, struct pt_regs *fp) 12941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 12951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (cplb_panic) { 12961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_UNLOCKED: 12971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "All CPLBs are locked\n"); 12981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 12991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_PROT_VIOL: 13001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 13011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_ADDR_MATCH: 13021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 13031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_UNKNOWN_ERR: 13041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "Unknown CPLB Exception\n"); 13051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 13061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 13071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1308226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 1309226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 131049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 1311b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 131249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 13131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_stack(); 1314d8804adf52f5991388fa9af77428e4cc7768059dMike Frysinger panic("Unrecoverable event"); 13151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 1316