traps.c revision 70f12567ac9aca9c2f242ae060d7de245904889e
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> 401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/blackfin.h> 411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/irq_handler.h> 42d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz#include <linux/irq.h> 43669b792c77bbc30e9f4d9c95dbc918dc348c49c2Robin Getz#include <asm/trace.h> 44226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#include <asm/fixed_code.h> 451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu# include <linux/kgdb.h> 48226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 49226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() \ 50226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 51a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang kgdb_handle_exception(trapnr, sig, info.si_code, fp); \ 52226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 53226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() \ 54226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 55226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (kgdb_connected) \ 56226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz CHK_DEBUGGER_TRAP(); \ 57226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 58226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#else 59226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() do { } while (0) 60226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) 611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 639f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 644ee1c45337e7b529eed644c6f62399d797dcbc10Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 659f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#define verbose_printk(fmt, arg...) \ 669f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(fmt, ##arg) 679f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#else 689f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#define verbose_printk(fmt, arg...) \ 699f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz ({ if (0) printk(fmt, ##arg); 0; }) 709f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 719f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 7281f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) 7381f7f45606812f1d15d618c2646d0f33ca111f87Robin Getzu32 last_seqstat; 7481f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#ifdef CONFIG_DEBUG_MMRS_MODULE 7581f7f45606812f1d15d618c2646d0f33ca111f87Robin GetzEXPORT_SYMBOL(last_seqstat); 7681f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#endif 7781f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#endif 7881f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz 791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Initiate the event table handler */ 801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid __init trap_init(void) 811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu bfin_write_EVT3(trap); 841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 87226eb1ef523a33c66193bc319a92c647e47311d4Robin Getzstatic void decode_address(char *buf, unsigned long address) 881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 899f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct task_struct *p; 911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct mm_struct *mm; 92885be03b069131d242506f0f717d38659b2bdb6cRobin Getz unsigned long flags, offset; 93904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); 948feae13110d60cc6287afabc2887366b0eb226c2David Howells struct rb_node *n; 951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KALLSYMS 978a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger unsigned long symsize; 981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu const char *symname; 991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *modname; 1001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *delim = ":"; 1011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char namebuf[128]; 1021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* look up the address and see if we are in kernel space */ 1041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 1051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (symname) { 1071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* yeah! kernel space! */ 1081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!modname) 1091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu modname = delim = ""; 110226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }", 1111f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger (void *)address, delim, modname, delim, symname, 1121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu (unsigned long)offset); 113885be03b069131d242506f0f717d38659b2bdb6cRobin Getz return; 1141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 1171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 118226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Problem in fixed code section? */ 119226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { 120226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address); 121226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 122226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 123226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 124226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Problem somewhere before the kernel start address */ 125226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (address < CONFIG_BOOT_LOAD) { 126226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address); 127226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 128226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 129226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* looks like we're off in user-land, so let's walk all the 1311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * mappings of all our processes and see if we can't be a whee 1321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * bit more specific 1331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 134885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_lock_irqsave(&tasklist_lock, flags); 1351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu for_each_process(p) { 136904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz mm = (in_atomic ? p->mm : get_task_mm(p)); 1371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!mm) 1381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu continue; 1391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1408feae13110d60cc6287afabc2887366b0eb226c2David Howells for (n = rb_first(&mm->mm_rb); n; n = rb_next(n)) { 1418feae13110d60cc6287afabc2887366b0eb226c2David Howells struct vm_area_struct *vma; 1428feae13110d60cc6287afabc2887366b0eb226c2David Howells 1438feae13110d60cc6287afabc2887366b0eb226c2David Howells vma = rb_entry(n, struct vm_area_struct, vm_rb); 1441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (address >= vma->vm_start && address < vma->vm_end) { 146cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck char _tmpbuf[256]; 1471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *name = p->comm; 1481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct file *file = vma->vm_file; 149cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck 1506a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper if (file) { 1516a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper char *d_name = d_path(&file->f_path, _tmpbuf, 152cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck sizeof(_tmpbuf)); 1536a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper if (!IS_ERR(d_name)) 1546a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper name = d_name; 1556a0bfff44e4aa4ee1721b3daa004d2039576c70dTim Pepper } 1561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1578a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger /* FLAT does not have its text aligned to the start of 1588a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger * the map while FDPIC ELF does ... 1598a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger */ 1607f1c906808a36630990d83d872935c079b76595bRobin Getz 1617f1c906808a36630990d83d872935c079b76595bRobin Getz /* before we can check flat/fdpic, we need to 1627f1c906808a36630990d83d872935c079b76595bRobin Getz * make sure current is valid 1637f1c906808a36630990d83d872935c079b76595bRobin Getz */ 1647f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 1657f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3)) { 1667f1c906808a36630990d83d872935c079b76595bRobin Getz if (current->mm && 1677f1c906808a36630990d83d872935c079b76595bRobin Getz (address > current->mm->start_code) && 1687f1c906808a36630990d83d872935c079b76595bRobin Getz (address < current->mm->end_code)) 1697f1c906808a36630990d83d872935c079b76595bRobin Getz offset = address - current->mm->start_code; 1707f1c906808a36630990d83d872935c079b76595bRobin Getz else 1717f1c906808a36630990d83d872935c079b76595bRobin Getz offset = (address - vma->vm_start) + 1727f1c906808a36630990d83d872935c079b76595bRobin Getz (vma->vm_pgoff << PAGE_SHIFT); 1737f1c906808a36630990d83d872935c079b76595bRobin Getz 1747f1c906808a36630990d83d872935c079b76595bRobin Getz sprintf(buf, "<0x%p> [ %s + 0x%lx ]", 1757f1c906808a36630990d83d872935c079b76595bRobin Getz (void *)address, name, offset); 1767f1c906808a36630990d83d872935c079b76595bRobin Getz } else 1777f1c906808a36630990d83d872935c079b76595bRobin Getz sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]", 1787f1c906808a36630990d83d872935c079b76595bRobin Getz (void *)address, name, 1797f1c906808a36630990d83d872935c079b76595bRobin Getz vma->vm_start, vma->vm_end); 1807f1c906808a36630990d83d872935c079b76595bRobin Getz 181904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 182885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 1837f1c906808a36630990d83d872935c079b76595bRobin Getz 184f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!strlen(buf)) 185f09630bff51daaf427968c61c0f2370c64148e06Robin Getz sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); 186f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 187885be03b069131d242506f0f717d38659b2bdb6cRobin Getz goto done; 1881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 190904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 191885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 1921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* we were unable to find this address anywhere */ 195f09630bff51daaf427968c61c0f2370c64148e06Robin Getz sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); 196885be03b069131d242506f0f717d38659b2bdb6cRobin Getz 197885be03b069131d242506f0f717d38659b2bdb6cRobin Getzdone: 198885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_unlock_irqrestore(&tasklist_lock, flags); 1999f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#else 2009f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz sprintf(buf, " "); 2019f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 2021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 2031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2042ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getzasmlinkage void double_fault_c(struct pt_regs *fp) 2052ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz{ 206a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 207a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz int j; 208a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz trace_buffer_save(j); 209a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz#endif 210a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz 211226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 212226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 2139f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 2142ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); 2150c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT 2160c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { 2178f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang unsigned int cpu = smp_processor_id(); 2180c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz char buf[150]; 2198f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].retx); 2200c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", 2218f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang (unsigned int)cpu_pda[cpu].seqstat & SEQSTAT_EXCAUSE, buf); 2228f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); 2230c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); 2248f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].icplb_fault_addr); 2250c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); 2260c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz 2270c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz decode_address(buf, fp->retx); 2288f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang printk(KERN_NOTICE "The instruction at %s caused a double exception\n", buf); 2290c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz } else 2300c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz#endif 2310c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz { 2320c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz dump_bfin_process(fp); 2330c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz dump_bfin_mem(fp); 2340c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz show_regs(fp); 235a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz dump_bfin_trace_buffer(); 2360c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz } 2379f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 238d8804adf52f5991388fa9af77428e4cc7768059dMike Frysinger panic("Double Fault - unrecoverable event"); 2392ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 2402ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz} 2412ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 2421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage void trap_c(struct pt_regs *fp) 2431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 244518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 245518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j; 246518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 2478f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 2488f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang unsigned int cpu = smp_processor_id(); 2498f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang#endif 250518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int sig = 0; 2511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu siginfo_t info; 2521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; 2531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 254226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz trace_buffer_save(j); 25581f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#if defined(CONFIG_DEBUG_MMRS) || defined(CONFIG_DEBUG_MMRS_MODULE) 25681f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz last_seqstat = (u32)fp->seqstat; 25781f7f45606812f1d15d618c2646d0f33ca111f87Robin Getz#endif 258226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 259226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Important - be very careful dereferncing pointers - will lead to 260226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * double faults if the stack has become corrupt 261226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz */ 262226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 263226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* If the fault was caused by a kernel thread, or interrupt handler 264226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * we will kernel panic, so the system reboots. 265226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * If KGDB is enabled, don't set this for kernel breakpoints 266226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz */ 267b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 268b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* TODO: check to see if we are in some sort of deferred HWERR 269b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * that we should be able to recover from, not kernel panic 270b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz */ 2716b5eace2f15b53d5a6849078d22e78db77625929Robin Getz if ((bfin_read_IPEND() & 0xFFC0) && (trapnr != VEC_STEP) 2721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 2736b5eace2f15b53d5a6849078d22e78db77625929Robin Getz && (trapnr != VEC_EXCPT02) 2741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 275226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz ){ 276226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 277226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 278226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } else if (current) { 279226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (current->mm == NULL) { 280226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 281226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 282226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 283226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 2841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* trap_c() will be called for exceptions. During exceptions 2861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * processing, the pc value should be set with retx value. 2871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * With this change we can cleanup some code in signal.c- TODO 2881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 2891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu fp->orig_pc = fp->retx; 2901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", 2911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trapnr, fp->ipend, fp->pc, fp->retx); */ 2921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* send the appropriate signal to the user program */ 2941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (trapnr) { 2951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* This table works in conjuction with the one in ./mach-common/entry.S 2971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some exceptions are handled there (in assembly, in exception space) 2981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some are handled here, (in C, in interrupt space) 2991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some, like CPLB, are handled in both, where the normal path is 3001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * handled in assembly/exception space, and the error path is handled 3011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * here 3021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 3031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 3041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x00 - Linux Syscall, getting here is an error */ 3051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x01 - userspace gdb breakpoint, handled here */ 3061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT01: 3071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_ILLTRAP; 3081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 3091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 3101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a breakpoint in kernel space */ 3111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 3121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 3131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3159401e618c8f70920f34893946239e24d40a3519aMike Frysinger /* 0x03 - User Defined, userspace stack overflow */ 3161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT03: 3171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = SEGV_STACKFLOW; 3181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 3199f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x03(KERN_NOTICE)); 320a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 32227707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang /* 0x02 - KGDB initial connection and break signal trap */ 32327707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang case VEC_EXCPT02: 32427707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang#ifdef CONFIG_KGDB 32527707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang info.si_code = TRAP_ILLTRAP; 32627707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang sig = SIGTRAP; 32727707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang CHK_DEBUGGER_TRAP(); 32827707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang return; 32927707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang#endif 3305c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x04 - User Defined */ 3315c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x05 - User Defined */ 3325c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x06 - User Defined */ 3335c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x07 - User Defined */ 3345c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x08 - User Defined */ 3355c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x09 - User Defined */ 3365c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0A - User Defined */ 3375c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0B - User Defined */ 3385c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0C - User Defined */ 3395c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0D - User Defined */ 3405c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0E - User Defined */ 3415c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0F - User Defined */ 34227707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang /* If we got here, it is most likely that someone was trying to use a 3435c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * custom exception handler, and it is not actually installed properly 3445c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz */ 3455c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz case VEC_EXCPT04 ... VEC_EXCPT15: 3465c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz info.si_code = ILL_ILLPARAOP; 3475c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz sig = SIGILL; 3489f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x04(KERN_NOTICE)); 3495c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz CHK_DEBUGGER_TRAP_MAYBE(); 3505c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz break; 3511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x10 HW Single step, handled here */ 3521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_STEP: 3531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_STEP; 3541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 3551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 3561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a single step in kernel space */ 3571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 3581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 3591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x11 - Trace Buffer Full, handled here */ 3621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_OVFLOW: 3631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_TRACEFLOW; 3641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 3659f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x11(KERN_NOTICE)); 366a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x12 - Reserved, Caught by default */ 3691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x13 - Reserved, Caught by default */ 3701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x14 - Reserved, Caught by default */ 3711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x15 - Reserved, Caught by default */ 3721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x16 - Reserved, Caught by default */ 3731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x17 - Reserved, Caught by default */ 3741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x18 - Reserved, Caught by default */ 3751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x19 - Reserved, Caught by default */ 3761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1A - Reserved, Caught by default */ 3771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1B - Reserved, Caught by default */ 3781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1C - Reserved, Caught by default */ 3791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1D - Reserved, Caught by default */ 3801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1E - Reserved, Caught by default */ 3811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1F - Reserved, Caught by default */ 3821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x20 - Reserved, Caught by default */ 3831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x21 - Undefined Instruction, handled here */ 3841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNDEF_I: 38570f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#ifdef CONFIG_BUG 38670f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger if (kernel_mode_regs(fp)) { 38770f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger switch (report_bug(fp->pc, fp)) { 38870f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger case BUG_TRAP_TYPE_NONE: 38970f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger break; 39070f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger case BUG_TRAP_TYPE_WARN: 39170f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger dump_bfin_trace_buffer(); 39270f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger fp->pc += 2; 39370f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger goto traps_done; 39470f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger case BUG_TRAP_TYPE_BUG: 39570f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger /* call to panic() will dump trace, and it is 39670f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger * off at this point, so it won't be clobbered 39770f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger */ 39870f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger panic("BUG()"); 39970f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger } 40070f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger } 40170f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#endif 4021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLOPC; 4031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 4049f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x21(KERN_NOTICE)); 405a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x22 - Illegal Instruction Combination, handled here */ 4081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILGAL_I: 4091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLPARAOP; 4101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 4119f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x22(KERN_NOTICE)); 412a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 414f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x23 - Data CPLB protection violation, handled here */ 4151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_VL: 4161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 417f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz sig = SIGBUS; 4189f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x23(KERN_NOTICE)); 419a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x24 - Data access misaligned, handled here */ 4221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_D: 4231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4259f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x24(KERN_NOTICE)); 426a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x25 - Unrecoverable Event, handled here */ 4291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNCOV: 4301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLEXCPT; 4311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 4329f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x25(KERN_NOTICE)); 433a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, 4361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu error case is handled here */ 4371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_M: 4381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4409f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x26(KERN_NOTICE)); 4411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ 4431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_MHIT: 4441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 4451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 446c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 4478f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (cpu_pda[cpu].dcplb_fault_addr < FIXED_CODE_START) 4489f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "NULL pointer access\n"); 449c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 4501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 4519f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); 452a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x28 - Emulation Watchpoint, handled here */ 4551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_WATCH: 4561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_WATCHPT; 4571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 458569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz pr_debug(EXC_0x28(KERN_DEBUG)); 4591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 4601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a watchpoint in kernel space */ 4611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 4621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 4631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 4641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_BF535 4661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Instruction fetch access error (535 only) */ 4671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */ 4681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_OPFETCH; 4691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4709f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n"); 471a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else 4741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Reserved, Caught by default */ 4751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 4761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2A - Instruction fetch misaligned, handled here */ 4771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_I: 4781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4809f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE)); 481a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 483f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x2B - Instruction CPLB protection violation, handled here */ 4841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_VL: 4851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 486f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz sig = SIGBUS; 4879f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE)); 488a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ 4911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_M: 4921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MISS; 4931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4949f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE)); 4951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2D - Instruction CPLB Multiple Hits, handled here */ 4971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_MHIT: 4981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 4991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 500c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 5018f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (cpu_pda[cpu].icplb_fault_addr < FIXED_CODE_START) 5029f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Jump to NULL address\n"); 503c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 5041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 5059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); 506a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 5071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 5081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2E - Illegal use of Supervisor Resource, handled here */ 5091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILL_RES: 5101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_PRVOPC; 5111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 5129f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE)); 513a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 5141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 5151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2F - Reserved, Caught by default */ 5161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x30 - Reserved, Caught by default */ 5171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x31 - Reserved, Caught by default */ 5181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x32 - Reserved, Caught by default */ 5191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x33 - Reserved, Caught by default */ 5201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x34 - Reserved, Caught by default */ 5211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x35 - Reserved, Caught by default */ 5221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x36 - Reserved, Caught by default */ 5231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x37 - Reserved, Caught by default */ 5241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x38 - Reserved, Caught by default */ 5251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x39 - Reserved, Caught by default */ 5261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3A - Reserved, Caught by default */ 5271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3B - Reserved, Caught by default */ 5281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3C - Reserved, Caught by default */ 5291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3D - Reserved, Caught by default */ 5301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3E - Reserved, Caught by default */ 5311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3F - Reserved, Caught by default */ 53213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case VEC_HWERR: 53313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 53413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 53513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz switch (fp->seqstat & SEQSTAT_HWERRCAUSE) { 53613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* System MMR Error */ 53713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): 53813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 53913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 5409f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE HWC_x2(KERN_NOTICE)); 54113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 54213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* External Memory Addressing Error */ 54313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): 54413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRERR; 54513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 5469f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE HWC_x3(KERN_NOTICE)); 54713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 54813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* Performance Monitor Overflow */ 54913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_PERF_FLOW): 5509f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE HWC_x12(KERN_NOTICE)); 55113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 55213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* RAISE 5 instruction */ 55313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_RAISE_5): 55413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_x18(KERN_NOTICE)); 55513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 55613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz default: /* Reserved */ 55713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_default(KERN_NOTICE)); 55813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 55913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz } 560a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 56113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 5625c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 5635c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * We should be handling all known exception types above, 5645c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * if we get here we hit a reserved one, so panic 5655c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz */ 5661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu default: 5675c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz oops_in_progress = 1; 5685c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz info.si_code = ILL_ILLPARAOP; 5695c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz sig = SIGILL; 5709f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", 5711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu (fp->seqstat & SEQSTAT_EXCAUSE)); 572a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 5731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 5741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 5751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 576226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz BUG_ON(sig == 0); 577226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 578226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (sig != SIGTRAP) { 57949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 580b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 58149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 582226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 583226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Print out the trace buffer if it makes sense */ 584226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE 585226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M) 5869f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "No trace since you do not have " 587226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n" 588226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz KERN_NOTICE "\n"); 589226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz else 590226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 591226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz dump_bfin_trace_buffer(); 592f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 593226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (oops_in_progress) { 594f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the current kernel stack */ 5959f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); 596f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(current, NULL); 597aee3a29240ad167ad7875d859506d8bb90431c70Robin Getz print_modules(); 598226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_ACCESS_CHECK 5999f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Please turn on " 60090c7f4686f82aef875aadf8e5c9c1a9465e5143bRobin Getz "CONFIG_ACCESS_CHECK\n"); 601226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 6021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu panic("Kernel exception"); 603f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 6044ee1c45337e7b529eed644c6f62399d797dcbc10Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 6059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz unsigned long *stack; 606f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the user space stack */ 607f09630bff51daaf427968c61c0f2370c64148e06Robin Getz stack = (unsigned long *)rdusp(); 6089f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Userspace Stack\n"); 609f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(NULL, stack); 6109f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 611226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 6121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 613fb322915a05804a3a153f714f2f08e4c32ce84c7Robin Getz 6146a01f230339321292cf065551f8cf55361052461Yi Li#ifdef CONFIG_IPIPE 6156a01f230339321292cf065551f8cf55361052461Yi Li if (!ipipe_trap_notify(fp->seqstat & 0x3f, fp)) 6166a01f230339321292cf065551f8cf55361052461Yi Li#endif 6176a01f230339321292cf065551f8cf55361052461Yi Li { 6186a01f230339321292cf065551f8cf55361052461Yi Li info.si_signo = sig; 6196a01f230339321292cf065551f8cf55361052461Yi Li info.si_errno = 0; 6206a01f230339321292cf065551f8cf55361052461Yi Li info.si_addr = (void __user *)fp->pc; 6216a01f230339321292cf065551f8cf55361052461Yi Li force_sig_info(sig, &info, current); 6226a01f230339321292cf065551f8cf55361052461Yi Li } 6231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 6240acad8dfee6bde7e246a95a52f864a8eee777ed8Robin Getz if (ANOMALY_05000461 && trapnr == VEC_HWERR && !access_ok(VERIFY_READ, fp->pc, 8)) 6250acad8dfee6bde7e246a95a52f864a8eee777ed8Robin Getz fp->pc = SAFE_USER_INSTRUCTION; 6260acad8dfee6bde7e246a95a52f864a8eee777ed8Robin Getz 6271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(j); 6281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 6291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 6301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 6311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Typical exception handling routines */ 6321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 633518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) 634518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 635f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 636f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Similar to get_user, do some address checking, then dereference 637f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Return true on sucess, false on bad address 638f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 6399f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic bool get_instruction(unsigned short *val, unsigned short *address) 640f09630bff51daaf427968c61c0f2370c64148e06Robin Getz{ 641f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 642f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned long addr; 643f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 644f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned long)address; 645f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 646f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Check for odd addresses */ 647f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr & 0x1) 648f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 649f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 650f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Check that things do not wrap around */ 651f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr > (addr + 2)) 652f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 653f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 654f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 655f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Since we are in exception context, we need to do a little address checking 656f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * We need to make sure we are only accessing valid memory, and 657f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * we don't read something in the async space that can hang forever 658f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 659f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || 66007aa7be5708afb3d9afa68f6f853c98e51bc64b3Mike Frysinger#if L2_LENGTH != 0 661f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || 662f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 663f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || 664f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_DATA_A_LENGTH != 0 665f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || 666f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 667f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_DATA_B_LENGTH != 0 668f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) || 669f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 670f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) || 671f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) && 672f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) || 673f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) && 674f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) || 675f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) && 676f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) || 677f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) && 678f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) { 679f09630bff51daaf427968c61c0f2370c64148e06Robin Getz *val = *address; 680f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 681f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 682f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 683f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_CODE_LENGTH != 0 684f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { 6859df10281e1c03b1c04d17f387bc59eb932c0bb87Robin Getz isram_memcpy(val, address, 2); 686f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 687f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 688f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 689f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 690f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 691f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 692f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 693f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 69436f649a55aa3ad1e2196403ba95a652f9900bc50Mike Frysinger/* 695d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * decode the instruction if we are printing out the trace, as it 696d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * makes things easier to follow, without running it through objdump 697d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * These are the normal instructions which cause change of flow, which 698d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * would be at the source of the trace buffer 699d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz */ 70036f649a55aa3ad1e2196403ba95a652f9900bc50Mike Frysinger#if defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_BFIN_HWTRACE_ON) 7019f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic void decode_instruction(unsigned short *address) 702d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz{ 703d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short opcode; 704d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 705d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (get_instruction(&opcode, address)) { 706d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (opcode == 0x0010) 7079f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTS"); 708d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0011) 7099f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTI"); 710d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0012) 7119f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTX"); 7120be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0013) 7130be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("RTN"); 7140be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0014) 7150be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("RTE"); 7160be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0025) 7170be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("EMUEXCPT"); 7180be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode == 0x0040 && opcode <= 0x0047) 7190be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("STI R%i", opcode & 7); 720d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0050 && opcode <= 0x0057) 7219f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP (P%i)", opcode & 7); 722d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0060 && opcode <= 0x0067) 7239f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL (P%i)", opcode & 7); 724d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0070 && opcode <= 0x0077) 7259f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL (PC+P%i)", opcode & 7); 726d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0080 && opcode <= 0x0087) 7279f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP (PC+P%i)", opcode & 7); 7280be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode >= 0x0090 && opcode <= 0x009F) 7290be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("RAISE 0x%x", opcode & 0xF); 7300be58939146f28394a04b61fec7e0676cdafa47eRobin Getz else if (opcode >= 0x00A0 && opcode <= 0x00AF) 7310be58939146f28394a04b61fec7e0676cdafa47eRobin Getz verbose_printk("EXCPT 0x%x", opcode & 0xF); 732d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) 7339f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("IF !CC JUMP"); 734d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) 7359f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("IF CC JUMP"); 736d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x2000 && opcode <= 0x2fff) 7379f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP.S"); 738d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe080 && opcode <= 0xe0ff) 7399f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("LSETUP"); 740d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe200 && opcode <= 0xe2ff) 7419f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP.L"); 742d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe300 && opcode <= 0xe3ff) 7439f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL pcrel"); 744d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else 7459f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("0x%04x", opcode); 746d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz } 747d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 748d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz} 7499f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 750d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 7511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_bfin_trace_buffer(void) 7521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 7539f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 754518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 755518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int tflags, i = 0; 756226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz char buf[150]; 757d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short *addr; 758518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 759518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j, index; 760518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 761518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 7621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 7631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 764226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "Hardware Trace:\n"); 765518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 766d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 767d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); 768d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#endif 769d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 7701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { 771518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { 772226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, (unsigned long)bfin_read_TBUF()); 773226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 774f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned short *)bfin_read_TBUF(); 775f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned long)addr); 776f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 777d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction(addr); 778f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 7791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 7801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 7811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 782518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 783518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (trace_buff_offset) 784d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz index = trace_buff_offset / 4; 785518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz else 786518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 787518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 788518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; 789518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz while (j) { 790226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 791226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 792518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 793518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0 ) 794518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 795226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 796d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 797d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction((unsigned short *)software_trace_buff[index]); 798d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("\n"); 799518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 800518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0) 801518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 802518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j--; 803518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz i++; 804518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz } 805518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 806518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 8071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 808518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 8099f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 8101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 8111394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_bfin_trace_buffer); 8121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 81370f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#ifdef CONFIG_BUG 81470f12567ac9aca9c2f242ae060d7de245904889eMike Frysingerint is_valid_bugaddr(unsigned long addr) 81570f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger{ 81670f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger unsigned short opcode; 81770f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger 81870f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger if (!get_instruction(&opcode, (unsigned short *)addr)) 81970f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger return 0; 82070f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger 82170f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger return opcode == BFIN_BUG_OPCODE; 82270f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger} 82370f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger#endif 82470f12567ac9aca9c2f242ae060d7de245904889eMike Frysinger 825f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 826f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Checks to see if the address pointed to is either a 827f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * 16-bit CALL instruction, or a 32-bit CALL instruction 828f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 8299f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic bool is_bfin_call(unsigned short *addr) 8301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 831f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short opcode = 0, *ins_addr; 832f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)addr; 8331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 834f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 835f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 8361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 837f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if ((opcode >= 0x0060 && opcode <= 0x0067) || 838f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (opcode >= 0x0070 && opcode <= 0x0077)) 839f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 840f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 841f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 842f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 843f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 8441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 845f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (opcode >= 0xE300 && opcode <= 0xE3FF) 846f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 847f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 848f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 849f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 850f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 8519f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 8521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid show_stack(struct task_struct *task, unsigned long *stack) 8531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 8549f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_PRINTK 855f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int *addr, *endstack, *fp = 0, *frame; 856f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short *ins_addr; 857f09630bff51daaf427968c61c0f2370c64148e06Robin Getz char buf[150]; 858f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int i, j, ret_addr, frame_no = 0; 8591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 860f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 861f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * If we have been passed a specific stack, use that one otherwise 862f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * if we have been passed a task structure, use that, otherwise 863f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * use the stack of where the variable "stack" exists 8641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 8651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 866f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (stack == NULL) { 867f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (task) { 868f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* We know this is a kernel stack, so this is the start/end */ 8691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)task->thread.ksp; 870f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); 871f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 872f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* print out the existing stack info */ 8731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)&stack; 874f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 875f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 876f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 877f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 878f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 8799f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(KERN_NOTICE "Stack info:\n"); 880f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)stack); 8819f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); 8829f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 883a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz if (!access_ok(VERIFY_READ, stack, (unsigned int)endstack - (unsigned int)stack)) { 884a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz printk(KERN_NOTICE "Invalid stack pointer\n"); 885a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz return; 886a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz } 887a0cab65642813b7990e1b4b2ab6ad92e171571f4Robin Getz 888f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First thing is to look for a frame pointer */ 889881eb621fc191e58fa638c533073683be2b63c24Jie Zhang for (addr = (unsigned int *)((unsigned int)stack & ~0xF); addr < endstack; addr++) { 890f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1) 891f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 892f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 893f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 894f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (is_bfin_call(ins_addr)) 895f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 896f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 897f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 898f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Let's check to see if it is a frame pointer */ 899881eb621fc191e58fa638c533073683be2b63c24Jie Zhang while (fp >= (addr - 1) && fp < endstack 900881eb621fc191e58fa638c533073683be2b63c24Jie Zhang && fp && ((unsigned int) fp & 0x3) == 0) 901f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*fp; 902f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp == 0 || fp == endstack) { 903f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 904f09630bff51daaf427968c61c0f2370c64148e06Robin Getz break; 905f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 906f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = 0; 907f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 9081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 909f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 910f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = fp; 911b339dc79b49841eff0aeecfc444cbb7b26007649Jie Zhang printk(KERN_NOTICE " FP: (0x%p)\n", fp); 912f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 913f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = 0; 9141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 915f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 916f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Now that we think we know where things are, we 917f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * walk the stack again, this time printing things out 918f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * incase there is no frame pointer, we still look for 919f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * valid return addresses 920f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 9211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 922f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First time print out data, next time, print out symbols */ 923f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (j = 0; j <= 1; j++) { 924f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 925f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE "Return addresses in stack:\n"); 926f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 927f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); 928f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 929f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = frame; 930f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no = 0; 931f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 932f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; 933f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr <= endstack; addr++, i++) { 934f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 935f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = 0; 936f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && i % 8 == 0) 937f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n" KERN_NOTICE "%p:",addr); 938f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 939f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* if it is an odd address, or zero, just skip it */ 940f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1 || !*addr) 941f09630bff51daaf427968c61c0f2370c64148e06Robin Getz goto print; 942f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 943f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 944f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 945f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Go back one instruction, and see if it is a CALL */ 946f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 947f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = is_bfin_call(ins_addr); 948f09630bff51daaf427968c61c0f2370c64148e06Robin Getz print: 949f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && stack == (unsigned long *)addr) 950f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("[%08x]", *addr); 951f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (ret_addr) 952f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) { 953f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)*addr); 954f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (frame == addr) { 955f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); 956f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 957f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 958f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " address : %s\n", buf); 959f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 960f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("<%08x>", *addr); 961f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (fp == addr) { 962f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 963f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = addr+1; 964f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 965f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("(%08x)", *addr); 966f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 967f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*addr; 968f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no++; 969f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 970f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else if (!j) 971f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(" %08x ", *addr); 972f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 973f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j) 974f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 9751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 9769f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 9771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 9781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 9791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_stack(void) 9801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 9811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long stack; 982518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 9831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int tflags; 984518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 9851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 9861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_bfin_trace_buffer(); 9871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu show_stack(current, &stack); 9881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 9891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 9901394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_stack); 9911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 99249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid dump_bfin_process(struct pt_regs *fp) 9931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 9949f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 99549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger /* We should be able to look at fp->ipend, but we don't push it on the 99649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger * stack all the time, so do this until we fix that */ 99749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger unsigned int context = bfin_read_IPEND(); 99849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 99949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger if (oops_in_progress) 10009f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); 100149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 1002b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) 10039f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "HW Error context\n"); 1004b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz else if (context & 0x0020) 10059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Deferred Exception context\n"); 100649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x3FC0) 10079f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Interrupt context\n"); 100849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x4000) 10099f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); 101049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x8000) 10119f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Kernel process context\n"); 101249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 10139a62ca40fd793742f92565104c6b44319af8c282Robin Getz /* Because we are crashing, and pointers could be bad, we check things 10149a62ca40fd793742f92565104c6b44319af8c282Robin Getz * pretty closely before we use them 10159a62ca40fd793742f92565104c6b44319af8c282Robin Getz */ 10167f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 10177f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3) && current->pid) { 10189f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); 10199a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (current->comm >= (char *)FIXED_CODE_START) 10209f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n", 10219a62ca40fd793742f92565104c6b44319af8c282Robin Getz current->comm, current->pid); 10229a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 10239f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "COMM= invalid\n"); 10249a62ca40fd793742f92565104c6b44319af8c282Robin Getz 10258f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang printk(KERN_NOTICE "CPU = %d\n", current_thread_info()->cpu); 10269a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) 10279f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" 10289a62ca40fd793742f92565104c6b44319af8c282Robin Getz KERN_NOTICE " BSS = 0x%p-0x%p USER-STACK = 0x%p\n" 10299a62ca40fd793742f92565104c6b44319af8c282Robin Getz KERN_NOTICE "\n", 10309a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_code, 10319a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_code, 10329a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_data, 10339a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 10349a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 10359a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->brk, 10369a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_stack); 10379a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 10389f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "invalid mm\n"); 103949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger } else 10409f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE 104149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger "No Valid process in current context\n"); 10429f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 104349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 1044226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1045b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getzvoid dump_bfin_mem(struct pt_regs *fp) 104649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 10479f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 1048b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz unsigned short *addr, *erraddr, val = 0, err = 0; 1049b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz char sti = 0, buf[6]; 10501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 10515d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt erraddr = (void *)fp->pc; 1052b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 10539f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); 1054b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1055b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; 1056b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; 1057b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr++) { 1058b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (!((unsigned long)addr & 0xF)) 10599f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n" KERN_NOTICE "0x%p: ", addr); 1060b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 10617d98c881eed9e19767bc77ffd650d0041b4f41ecRobin Getz if (!get_instruction(&val, addr)) { 1062b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val = 0; 1063b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "????"); 1064b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 1065b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "%04x", val); 1066b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1067b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr == erraddr) { 10689f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("[%s]", buf); 1069b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz err = val; 1070b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 10719f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(" %s ", buf); 1072b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1073b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Do any previous instructions turn on interrupts? */ 1074b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr <= erraddr && /* in the past */ 1075b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */ 1076b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val == 0x017b)) /* [SP++] = RETI */ 1077b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sti = 1; 1078b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 1079b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 10809f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n"); 1081b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1082b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Hardware error interrupts can be deferred */ 1083b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && 1084b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz oops_in_progress)){ 10859f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); 10861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifndef CONFIG_DEBUG_HWERR 10879f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "The remaining message may be meaningless\n" 1088b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a" 1089b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz " better idea where it came from\n"); 1090b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#else 1091b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* If we are handling only one peripheral interrupt 1092b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * and current mm and pid are valid, and the last error 1093b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * was in that user space process's text area 1094b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * print it out - because that is where the problem exists 1095b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz */ 1096b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) && 1097b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (current->pid && current->mm)) { 1098b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* And the last RETI points to the current userspace context */ 1099b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((fp + 1)->pc >= current->mm->start_code && 1100b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (fp + 1)->pc <= current->mm->end_code) { 11019f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "It might be better to look around here : \n"); 11029f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1103b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz show_regs(fp + 1); 11049f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1105b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 11061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1107b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#endif 1108b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 11099f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 111049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 111149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 111249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid show_regs(struct pt_regs *fp) 111349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 11149f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 111549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger char buf [150]; 1116d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz struct irqaction *action; 1117d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz unsigned int i; 11182f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz unsigned long flags = 0; 11198f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang unsigned int cpu = smp_processor_id(); 11202f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); 1121226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 11229ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "\n"); 11239ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz if (CPUID != bfin_cpuid()) 11249ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "Compiled for cpu family 0x%04x (Rev %d), " 11259ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz "but running on:0x%04x (Rev %d)\n", 11269ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz CPUID, bfin_compiled_revid(), bfin_cpuid(), bfin_revid()); 11279ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11289ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "ADSP-%s-0.%d", 11299ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz CPU, bfin_compiled_revid()); 11309ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11319ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz if (bfin_compiled_revid() != bfin_revid()) 11329ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk("(Detected 0.%d)", bfin_revid()); 11339ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11349ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(" %lu(MHz CCLK) %lu(MHz SCLK) (%s)\n", 11359ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz get_cclk()/1000000, get_sclk()/1000000, 11369ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz#ifdef CONFIG_MPU 11379ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz "mpu on" 11389ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz#else 11399ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz "mpu off" 11409ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz#endif 11419ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz ); 11429ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11439ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz verbose_printk(KERN_NOTICE "%s", linux_banner); 11449ba3c24f10c948dadac2ca91ed714dfbcedd61caRobin Getz 11459f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); 11469f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", 1147226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz (long)fp->seqstat, fp->ipend, fp->syscfg); 11481d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { 11499f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", 11501d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); 11511d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz#ifdef EBIU_ERRMST 11521d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz /* If the error was from the EBIU, print it out */ 11531d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { 11549f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", 11551d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz bfin_read_EBIU_ERRMST()); 11569f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", 11571d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz bfin_read_EBIU_ERRADD()); 11581d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz } 11591d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz#endif 11601d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz } 11619f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", 116213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz fp->seqstat & SEQSTAT_EXCAUSE); 11632f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz for (i = 2; i <= 15 ; i++) { 1164d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & (1 << i)) { 11652f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz if (i != 4) { 11662f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz decode_address(buf, bfin_read32(EVT0 + 4*i)); 11672f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); 11682f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz } else 11692f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz verbose_printk(KERN_NOTICE " interrupts disabled\n"); 1170d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1171d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1172d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1173d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz /* if no interrupts are going off, don't print this out */ 1174d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & ~0x3F) { 1175d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (i = 0; i < (NR_IRQS - 1); i++) { 11762f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz if (!in_atomic) 11772f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz spin_lock_irqsave(&irq_desc[i].lock, flags); 11782f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz 1179d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz action = irq_desc[i].action; 1180d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (!action) 1181d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz goto unlock; 1182d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1183d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 11849f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); 1185d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (action = action->next; action; action = action->next) { 1186d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 11879f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(", %s", buf); 1188d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 11899f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n"); 1190d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getzunlock: 11912f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz if (!in_atomic) 11922f95d5bd84bfbe8cf62cb1c4306354cfc139370bRobin Getz spin_unlock_irqrestore(&irq_desc[i].lock, flags); 1193d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1194d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1195c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 1196226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rete); 11979f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETE: %s\n", buf); 1198226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retn); 11999f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETN: %s\n", buf); 1200226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retx); 12019f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETX: %s\n", buf); 1202226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rets); 12039f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETS: %s\n", buf); 120449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger decode_address(buf, fp->pc); 12059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " PC : %s\n", buf); 1206c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 120713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && 120813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { 12098f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].dcplb_fault_addr); 12109f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); 12118f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang decode_address(buf, cpu_pda[cpu].icplb_fault_addr); 12129f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); 1213226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 1214226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 12159f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n"); 12169f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", 1217c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r0, fp->r1, fp->r2, fp->r3); 12189f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", 1219c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r4, fp->r5, fp->r6, fp->r7); 12209f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", 1221c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->p0, fp->p1, fp->p2, fp->p3); 12229f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", 1223226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->p4, fp->p5, fp->fp, (long)fp); 12249f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", 1225c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb0, fp->lt0, fp->lc0); 12269f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", 1227c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb1, fp->lt1, fp->lc1); 12289f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", 1229c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b0, fp->l0, fp->m0, fp->i0); 12309f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", 1231c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b1, fp->l1, fp->m1, fp->i1); 12329f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", 1233c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b2, fp->l2, fp->m2, fp->i2); 12349f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", 1235c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b3, fp->l3, fp->m3, fp->i3); 12369f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", 1237226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->a0w, fp->a0x, fp->a1w, fp->a1x); 1238c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 12399f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", 1240c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz rdusp(), fp->astat); 12411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12429f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n"); 12439f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 12441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 12451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 12471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); 12481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 12491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12508f65873e47784a390949f0d61e5692dbf2a8253eGraf Yangstatic DEFINE_SPINLOCK(bfin_spinlock_lock); 12518f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang 12528f65873e47784a390949f0d61e5692dbf2a8253eGraf Yangasmlinkage int sys_bfin_spinlock(int *p) 12531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 12548f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang int ret, tmp = 0; 12551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12568f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang spin_lock(&bfin_spinlock_lock); /* This would also hold kernel preemption. */ 12578f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang ret = get_user(tmp, p); 12588f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (likely(ret == 0)) { 12598f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang if (unlikely(tmp)) 12601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu ret = 1; 12618f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang else 12628f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang put_user(1, p); 12631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 12648f65873e47784a390949f0d61e5692dbf2a8253eGraf Yang spin_unlock(&bfin_spinlock_lock); 12651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return ret; 12661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 12671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 12681ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_request_exception(unsigned int exception, void (*handler)(void)) 12691ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 12701ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 12711ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12721ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 12731ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 12741ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12751ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 12761ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12771ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != ex_replaceable) 12781ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 12791ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12801ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = handler; 12811ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12821ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 12831ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 12841ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_request_exception); 12851ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12861ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_free_exception(unsigned int exception, void (*handler)(void)) 12871ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 12881ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 12891ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12901ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 12911ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 12921ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12931ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 12941ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12951ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != handler) 12961ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 12971ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12981ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = ex_replaceable; 12991ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 13001ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 13011ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 13021ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_free_exception); 13031ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 13041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid panic_cplb_error(int cplb_panic, struct pt_regs *fp) 13051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 13061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (cplb_panic) { 13071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_UNLOCKED: 13081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "All CPLBs are locked\n"); 13091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 13101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_PROT_VIOL: 13111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 13121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_ADDR_MATCH: 13131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 13141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_UNKNOWN_ERR: 13151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "Unknown CPLB Exception\n"); 13161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 13171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 13181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1319226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 1320226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 132149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 1322b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 132349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 13241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_stack(); 1325d8804adf52f5991388fa9af77428e4cc7768059dMike Frysinger panic("Unrecoverable event"); 13261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 1327