traps.c revision 9f06c38fb230720371397a57faa24aa6e31b2c87
11394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* 21394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * File: arch/blackfin/kernel/traps.c 31394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Based on: 41394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Author: Hamish Macdonald 51394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 61394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Created: 71394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Description: uses S/W interrupt 15 for the system calls 81394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 91394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Modified: 101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Copyright 2004-2006 Analog Devices Inc. 111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Bugs: Enter bugs at http://blackfin.uclinux.org/ 131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * This program is free software; you can redistribute it and/or modify 151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * it under the terms of the GNU General Public License as published by 161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * the Free Software Foundation; either version 2 of the License, or 171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * (at your option) any later version. 181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * This program is distributed in the hope that it will be useful, 201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * but WITHOUT ANY WARRANTY; without even the implied warranty of 211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * GNU General Public License for more details. 231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * You should have received a copy of the GNU General Public License 251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * along with this program; if not, see the file COPYING, or write 261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * to the Free Software Foundation, Inc., 271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 301f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/uaccess.h> 311f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/interrupt.h> 321f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/module.h> 331f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger#include <linux/kallsyms.h> 34d31c5ab147e0b17b9ec0daa5e4d1fc0bd6b19974Bryan Wu#include <linux/fs.h> 351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/traps.h> 361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/cacheflush.h> 37f4585a08479a730fb809606b8ee327a5398c117cMike Frysinger#include <asm/cplb.h> 381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/blackfin.h> 391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#include <asm/irq_handler.h> 40d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz#include <linux/irq.h> 41669b792c77bbc30e9f4d9c95dbc918dc348c49c2Robin Getz#include <asm/trace.h> 42226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#include <asm/fixed_code.h> 431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu# include <linux/kgdb.h> 46226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 47226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() \ 48226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 49a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang kgdb_handle_exception(trapnr, sig, info.si_code, fp); \ 50226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 51226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() \ 52226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 53226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (kgdb_connected) \ 54226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz CHK_DEBUGGER_TRAP(); \ 55226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 56226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#else 57226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() do { } while (0) 58226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) 591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 619f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 629f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_VERBOSE_DEBUG 639f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#define verbose_printk(fmt, arg...) \ 649f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(fmt, ##arg) 659f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#else 669f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#define verbose_printk(fmt, arg...) \ 679f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz ({ if (0) printk(fmt, ##arg); 0; }) 689f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 699f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Initiate the event table handler */ 711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid __init trap_init(void) 721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu bfin_write_EVT3(trap); 751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 780c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz/* 790c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz * Used to save the RETX, SEQSTAT, I/D CPLB FAULT ADDR 800c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz * values across the transition from exception to IRQ5. 810c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz * We put these in L1, so they are going to be in a valid 820c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz * location during exception context 830c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz */ 840c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz__attribute__((l1_data)) 850c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getzunsigned long saved_retx, saved_seqstat, 860c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz saved_icplb_fault_addr, saved_dcplb_fault_addr; 875d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt 88226eb1ef523a33c66193bc319a92c647e47311d4Robin Getzstatic void decode_address(char *buf, unsigned long address) 891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 909f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct vm_list_struct *vml; 921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct task_struct *p; 931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct mm_struct *mm; 94885be03b069131d242506f0f717d38659b2bdb6cRobin Getz unsigned long flags, offset; 95904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); 961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KALLSYMS 988a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger unsigned long symsize; 991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu const char *symname; 1001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *modname; 1011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *delim = ":"; 1021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char namebuf[128]; 1031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* look up the address and see if we are in kernel space */ 1051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 1061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (symname) { 1081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* yeah! kernel space! */ 1091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!modname) 1101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu modname = delim = ""; 111226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }", 1121f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger (void *)address, delim, modname, delim, symname, 1131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu (unsigned long)offset); 114885be03b069131d242506f0f717d38659b2bdb6cRobin Getz return; 1151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 1181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 119226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Problem in fixed code section? */ 120226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { 121226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address); 122226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 123226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 124226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 125226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Problem somewhere before the kernel start address */ 126226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (address < CONFIG_BOOT_LOAD) { 127226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address); 128226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 129226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 130226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* looks like we're off in user-land, so let's walk all the 1321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * mappings of all our processes and see if we can't be a whee 1331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * bit more specific 1341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 135885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_lock_irqsave(&tasklist_lock, flags); 1361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu for_each_process(p) { 137904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz mm = (in_atomic ? p->mm : get_task_mm(p)); 1381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!mm) 1391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu continue; 1401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu vml = mm->context.vmlist; 1421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu while (vml) { 1431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct vm_area_struct *vma = vml->vma; 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 150cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck if (file) 151cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck name = d_path(&file->f_path, _tmpbuf, 152cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck sizeof(_tmpbuf)); 1531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1548a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger /* FLAT does not have its text aligned to the start of 1558a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger * the map while FDPIC ELF does ... 1568a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger */ 1577f1c906808a36630990d83d872935c079b76595bRobin Getz 1587f1c906808a36630990d83d872935c079b76595bRobin Getz /* before we can check flat/fdpic, we need to 1597f1c906808a36630990d83d872935c079b76595bRobin Getz * make sure current is valid 1607f1c906808a36630990d83d872935c079b76595bRobin Getz */ 1617f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 1627f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3)) { 1637f1c906808a36630990d83d872935c079b76595bRobin Getz if (current->mm && 1647f1c906808a36630990d83d872935c079b76595bRobin Getz (address > current->mm->start_code) && 1657f1c906808a36630990d83d872935c079b76595bRobin Getz (address < current->mm->end_code)) 1667f1c906808a36630990d83d872935c079b76595bRobin Getz offset = address - current->mm->start_code; 1677f1c906808a36630990d83d872935c079b76595bRobin Getz else 1687f1c906808a36630990d83d872935c079b76595bRobin Getz offset = (address - vma->vm_start) + 1697f1c906808a36630990d83d872935c079b76595bRobin Getz (vma->vm_pgoff << PAGE_SHIFT); 1707f1c906808a36630990d83d872935c079b76595bRobin Getz 1717f1c906808a36630990d83d872935c079b76595bRobin Getz sprintf(buf, "<0x%p> [ %s + 0x%lx ]", 1727f1c906808a36630990d83d872935c079b76595bRobin Getz (void *)address, name, offset); 1737f1c906808a36630990d83d872935c079b76595bRobin Getz } else 1747f1c906808a36630990d83d872935c079b76595bRobin Getz sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]", 1757f1c906808a36630990d83d872935c079b76595bRobin Getz (void *)address, name, 1767f1c906808a36630990d83d872935c079b76595bRobin Getz vma->vm_start, vma->vm_end); 1777f1c906808a36630990d83d872935c079b76595bRobin Getz 178904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 179885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 1807f1c906808a36630990d83d872935c079b76595bRobin Getz 181f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!strlen(buf)) 182f09630bff51daaf427968c61c0f2370c64148e06Robin Getz sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); 183f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 184885be03b069131d242506f0f717d38659b2bdb6cRobin Getz goto done; 1851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu vml = vml->next; 1881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 189904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 190885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 1911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* we were unable to find this address anywhere */ 194f09630bff51daaf427968c61c0f2370c64148e06Robin Getz sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); 195885be03b069131d242506f0f717d38659b2bdb6cRobin Getz 196885be03b069131d242506f0f717d38659b2bdb6cRobin Getzdone: 197885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_unlock_irqrestore(&tasklist_lock, flags); 1989f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#else 1999f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz sprintf(buf, " "); 2009f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 2011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 2021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2032ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getzasmlinkage void double_fault_c(struct pt_regs *fp) 2042ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz{ 205226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 206226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 2079f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 2082ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); 2090c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz#ifdef CONFIG_DEBUG_DOUBLEFAULT_PRINT 2100c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz if (((long)fp->seqstat & SEQSTAT_EXCAUSE) == VEC_UNCOV) { 2110c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz char buf[150]; 2120c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz decode_address(buf, saved_retx); 2130c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_EMERG "While handling exception (EXCAUSE = 0x%x) at %s:\n", 2140c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz (int)saved_seqstat & SEQSTAT_EXCAUSE, buf); 2150c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz decode_address(buf, saved_dcplb_fault_addr); 2160c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_NOTICE " DCPLB_FAULT_ADDR: %s\n", buf); 2170c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz decode_address(buf, saved_icplb_fault_addr); 2180c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_NOTICE " ICPLB_FAULT_ADDR: %s\n", buf); 2190c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz 2200c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz decode_address(buf, fp->retx); 2210c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz printk(KERN_NOTICE "The instruction at %s caused a double exception\n", 2220c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz buf); 2230c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz } else 2240c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz#endif 2250c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz { 2260c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz dump_bfin_process(fp); 2270c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz dump_bfin_mem(fp); 2280c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz show_regs(fp); 2290c7a6b2135c1bcb5139ca9ca87f292caafcb9410Robin Getz } 2309f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 2312ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz panic("Double Fault - unrecoverable event\n"); 2322ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 2332ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz} 2342ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 2351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage void trap_c(struct pt_regs *fp) 2361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 237518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 238518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j; 239518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 240518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int sig = 0; 2411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu siginfo_t info; 2421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; 2431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 244226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz trace_buffer_save(j); 245226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 246226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Important - be very careful dereferncing pointers - will lead to 247226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * double faults if the stack has become corrupt 248226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz */ 249226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 250226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* If the fault was caused by a kernel thread, or interrupt handler 251226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * we will kernel panic, so the system reboots. 252226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * If KGDB is enabled, don't set this for kernel breakpoints 253226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz */ 254b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 255b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* TODO: check to see if we are in some sort of deferred HWERR 256b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * that we should be able to recover from, not kernel panic 257b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz */ 2586b5eace2f15b53d5a6849078d22e78db77625929Robin Getz if ((bfin_read_IPEND() & 0xFFC0) && (trapnr != VEC_STEP) 2591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 2606b5eace2f15b53d5a6849078d22e78db77625929Robin Getz && (trapnr != VEC_EXCPT02) 2611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 262226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz ){ 263226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 264226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 265226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } else if (current) { 266226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (current->mm == NULL) { 267226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 268226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 269226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 270226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 2711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* trap_c() will be called for exceptions. During exceptions 2731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * processing, the pc value should be set with retx value. 2741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * With this change we can cleanup some code in signal.c- TODO 2751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 2761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu fp->orig_pc = fp->retx; 2771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", 2781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trapnr, fp->ipend, fp->pc, fp->retx); */ 2791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* send the appropriate signal to the user program */ 2811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (trapnr) { 2821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* This table works in conjuction with the one in ./mach-common/entry.S 2841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some exceptions are handled there (in assembly, in exception space) 2851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some are handled here, (in C, in interrupt space) 2861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some, like CPLB, are handled in both, where the normal path is 2871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * handled in assembly/exception space, and the error path is handled 2881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * here 2891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 2901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x00 - Linux Syscall, getting here is an error */ 2921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x01 - userspace gdb breakpoint, handled here */ 2931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT01: 2941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_ILLTRAP; 2951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 2961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 2971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a breakpoint in kernel space */ 2981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 2991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 3001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3029401e618c8f70920f34893946239e24d40a3519aMike Frysinger /* 0x03 - User Defined, userspace stack overflow */ 3031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT03: 3041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = SEGV_STACKFLOW; 3051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 3069f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x03(KERN_NOTICE)); 307a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 30927707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang /* 0x02 - KGDB initial connection and break signal trap */ 31027707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang case VEC_EXCPT02: 31127707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang#ifdef CONFIG_KGDB 31227707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang info.si_code = TRAP_ILLTRAP; 31327707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang sig = SIGTRAP; 31427707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang CHK_DEBUGGER_TRAP(); 31527707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang return; 31627707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang#endif 3175c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x04 - User Defined */ 3185c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x05 - User Defined */ 3195c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x06 - User Defined */ 3205c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x07 - User Defined */ 3215c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x08 - User Defined */ 3225c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x09 - User Defined */ 3235c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0A - User Defined */ 3245c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0B - User Defined */ 3255c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0C - User Defined */ 3265c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0D - User Defined */ 3275c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0E - User Defined */ 3285c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 0x0F - User Defined */ 32927707d3e43e3a9c53e75cd7769f3ef74b1d56625Sonic Zhang /* If we got here, it is most likely that someone was trying to use a 3305c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * custom exception handler, and it is not actually installed properly 3315c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz */ 3325c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz case VEC_EXCPT04 ... VEC_EXCPT15: 3335c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz info.si_code = ILL_ILLPARAOP; 3345c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz sig = SIGILL; 3359f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x04(KERN_NOTICE)); 3365c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz CHK_DEBUGGER_TRAP_MAYBE(); 3375c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz break; 3381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x10 HW Single step, handled here */ 3391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_STEP: 3401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_STEP; 3411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 3421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 3431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a single step in kernel space */ 3441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 3451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 3461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x11 - Trace Buffer Full, handled here */ 3491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_OVFLOW: 3501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_TRACEFLOW; 3511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 3529f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x11(KERN_NOTICE)); 353a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x12 - Reserved, Caught by default */ 3561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x13 - Reserved, Caught by default */ 3571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x14 - Reserved, Caught by default */ 3581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x15 - Reserved, Caught by default */ 3591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x16 - Reserved, Caught by default */ 3601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x17 - Reserved, Caught by default */ 3611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x18 - Reserved, Caught by default */ 3621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x19 - Reserved, Caught by default */ 3631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1A - Reserved, Caught by default */ 3641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1B - Reserved, Caught by default */ 3651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1C - Reserved, Caught by default */ 3661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1D - Reserved, Caught by default */ 3671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1E - Reserved, Caught by default */ 3681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1F - Reserved, Caught by default */ 3691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x20 - Reserved, Caught by default */ 3701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x21 - Undefined Instruction, handled here */ 3711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNDEF_I: 3721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLOPC; 3731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 3749f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x21(KERN_NOTICE)); 375a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x22 - Illegal Instruction Combination, handled here */ 3781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILGAL_I: 3791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLPARAOP; 3801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 3819f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x22(KERN_NOTICE)); 382a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 384f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x23 - Data CPLB protection violation, handled here */ 3851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_VL: 3861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 387f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz sig = SIGBUS; 3889f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x23(KERN_NOTICE)); 389a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x24 - Data access misaligned, handled here */ 3921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_D: 3931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 3941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 3959f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x24(KERN_NOTICE)); 396a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 3971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x25 - Unrecoverable Event, handled here */ 3991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNCOV: 4001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLEXCPT; 4011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 4029f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x25(KERN_NOTICE)); 403a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, 4061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu error case is handled here */ 4071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_M: 4081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4109f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x26(KERN_NOTICE)); 4111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ 4131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_MHIT: 4141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 4151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 416c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 417bd628bd085c459838d38f93f2f154f1a2e019e48Mike Frysinger if (saved_dcplb_fault_addr < FIXED_CODE_START) 4189f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "NULL pointer access\n"); 419c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 4201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 4219f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); 422a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x28 - Emulation Watchpoint, handled here */ 4251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_WATCH: 4261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_WATCHPT; 4271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 428569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz pr_debug(EXC_0x28(KERN_DEBUG)); 4291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 4301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a watchpoint in kernel space */ 4311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 4321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 4331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 4341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_BF535 4361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Instruction fetch access error (535 only) */ 4371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */ 4381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_OPFETCH; 4391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4409f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n"); 441a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else 4441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Reserved, Caught by default */ 4451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 4461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2A - Instruction fetch misaligned, handled here */ 4471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_I: 4481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4509f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE)); 451a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 453f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x2B - Instruction CPLB protection violation, handled here */ 4541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_VL: 4551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 456f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz sig = SIGBUS; 4579f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE)); 458a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ 4611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_M: 4621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MISS; 4631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 4649f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE)); 4651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2D - Instruction CPLB Multiple Hits, handled here */ 4671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_MHIT: 4681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 4691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 470c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 471bd628bd085c459838d38f93f2f154f1a2e019e48Mike Frysinger if (saved_icplb_fault_addr < FIXED_CODE_START) 4729f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Jump to NULL address\n"); 473c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 4741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 4759f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); 476a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2E - Illegal use of Supervisor Resource, handled here */ 4791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILL_RES: 4801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_PRVOPC; 4811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 4829f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE)); 483a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 4841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2F - Reserved, Caught by default */ 4861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x30 - Reserved, Caught by default */ 4871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x31 - Reserved, Caught by default */ 4881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x32 - Reserved, Caught by default */ 4891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x33 - Reserved, Caught by default */ 4901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x34 - Reserved, Caught by default */ 4911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x35 - Reserved, Caught by default */ 4921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x36 - Reserved, Caught by default */ 4931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x37 - Reserved, Caught by default */ 4941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x38 - Reserved, Caught by default */ 4951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x39 - Reserved, Caught by default */ 4961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3A - Reserved, Caught by default */ 4971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3B - Reserved, Caught by default */ 4981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3C - Reserved, Caught by default */ 4991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3D - Reserved, Caught by default */ 5001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3E - Reserved, Caught by default */ 5011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3F - Reserved, Caught by default */ 50213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case VEC_HWERR: 50313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 50413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 50513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz switch (fp->seqstat & SEQSTAT_HWERRCAUSE) { 50613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* System MMR Error */ 50713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): 50813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 50913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 5109f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE HWC_x2(KERN_NOTICE)); 51113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 51213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* External Memory Addressing Error */ 51313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): 51413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRERR; 51513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 5169f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE HWC_x3(KERN_NOTICE)); 51713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 51813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* Performance Monitor Overflow */ 51913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_PERF_FLOW): 5209f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE HWC_x12(KERN_NOTICE)); 52113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 52213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* RAISE 5 instruction */ 52313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_RAISE_5): 52413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_x18(KERN_NOTICE)); 52513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 52613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz default: /* Reserved */ 52713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_default(KERN_NOTICE)); 52813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 52913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz } 530a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 53113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 5325c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz /* 5335c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * We should be handling all known exception types above, 5345c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz * if we get here we hit a reserved one, so panic 5355c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz */ 5361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu default: 5375c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz oops_in_progress = 1; 5385c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz info.si_code = ILL_ILLPARAOP; 5395c64e0d5109532f8184be29c1dc163059e3ded4bRobin Getz sig = SIGILL; 5409f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", 5411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu (fp->seqstat & SEQSTAT_EXCAUSE)); 542a5ac0129249611fc4a35e6d7cd9b8462d67e5798Sonic Zhang CHK_DEBUGGER_TRAP_MAYBE(); 5431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 5441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 5451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 546226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz BUG_ON(sig == 0); 547226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 548226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (sig != SIGTRAP) { 54949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 550b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 55149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 552226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 553226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Print out the trace buffer if it makes sense */ 554226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE 555226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M) 5569f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "No trace since you do not have " 557226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n" 558226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz KERN_NOTICE "\n"); 559226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz else 560226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 561226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz dump_bfin_trace_buffer(); 562f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 563226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (oops_in_progress) { 564f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the current kernel stack */ 5659f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); 566f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(current, NULL); 567aee3a29240ad167ad7875d859506d8bb90431c70Robin Getz print_modules(); 568226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_ACCESS_CHECK 5699f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Please turn on " 57090c7f4686f82aef875aadf8e5c9c1a9465e5143bRobin Getz "CONFIG_ACCESS_CHECK\n"); 571226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 5721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu panic("Kernel exception"); 573f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 5749f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_VERBOSE_DEBUG 5759f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz unsigned long *stack; 576f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the user space stack */ 577f09630bff51daaf427968c61c0f2370c64148e06Robin Getz stack = (unsigned long *)rdusp(); 5789f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Userspace Stack\n"); 579f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(NULL, stack); 5809f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 581226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 5821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 583fb322915a05804a3a153f714f2f08e4c32ce84c7Robin Getz 584ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz info.si_signo = sig; 585ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz info.si_errno = 0; 5860ddeeca25ce33686262459e2387f57bd09574e47Mike Frysinger info.si_addr = (void __user *)fp->pc; 587ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz force_sig_info(sig, &info, current); 5881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 5891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(j); 5901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 5911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 5921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 5931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Typical exception handling routines */ 5941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 595518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) 596518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 597f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 598f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Similar to get_user, do some address checking, then dereference 599f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Return true on sucess, false on bad address 600f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 6019f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic bool get_instruction(unsigned short *val, unsigned short *address) 602f09630bff51daaf427968c61c0f2370c64148e06Robin Getz{ 603f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 604f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned long addr; 605f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 606f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned long)address; 607f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 608f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Check for odd addresses */ 609f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr & 0x1) 610f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 611f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 612f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Check that things do not wrap around */ 613f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr > (addr + 2)) 614f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 615f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 616f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 617f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Since we are in exception context, we need to do a little address checking 618f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * We need to make sure we are only accessing valid memory, and 619f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * we don't read something in the async space that can hang forever 620f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 621f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || 62207aa7be5708afb3d9afa68f6f853c98e51bc64b3Mike Frysinger#if L2_LENGTH != 0 623f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || 624f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 625f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || 626f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_DATA_A_LENGTH != 0 627f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || 628f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 629f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_DATA_B_LENGTH != 0 630f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) || 631f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 632f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) || 633f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) && 634f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) || 635f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) && 636f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) || 637f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) && 638f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) || 639f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) && 640f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) { 641f09630bff51daaf427968c61c0f2370c64148e06Robin Getz *val = *address; 642f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 643f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 644f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 645f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_CODE_LENGTH != 0 646f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { 6479df10281e1c03b1c04d17f387bc59eb932c0bb87Robin Getz isram_memcpy(val, address, 2); 648f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 649f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 650f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 651f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 652f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 653f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 654f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 655f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 656d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz/* 657d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * decode the instruction if we are printing out the trace, as it 658d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * makes things easier to follow, without running it through objdump 659d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * These are the normal instructions which cause change of flow, which 660d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * would be at the source of the trace buffer 661d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz */ 6629f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 6639f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic void decode_instruction(unsigned short *address) 664d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz{ 665d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short opcode; 666d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 667d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (get_instruction(&opcode, address)) { 668d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (opcode == 0x0010) 6699f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTS"); 670d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0011) 6719f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTI"); 672d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0012) 6739f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("RTX"); 674d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0050 && opcode <= 0x0057) 6759f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP (P%i)", opcode & 7); 676d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0060 && opcode <= 0x0067) 6779f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL (P%i)", opcode & 7); 678d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0070 && opcode <= 0x0077) 6799f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL (PC+P%i)", opcode & 7); 680d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0080 && opcode <= 0x0087) 6819f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP (PC+P%i)", opcode & 7); 682d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) 6839f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("IF !CC JUMP"); 684d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) 6859f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("IF CC JUMP"); 686d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x2000 && opcode <= 0x2fff) 6879f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP.S"); 688d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe080 && opcode <= 0xe0ff) 6899f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("LSETUP"); 690d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe200 && opcode <= 0xe2ff) 6919f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("JUMP.L"); 692d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe300 && opcode <= 0xe3ff) 6939f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("CALL pcrel"); 694d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else 6959f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("0x%04x", opcode); 696d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz } 697d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 698d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz} 6999f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 700d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 7011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_bfin_trace_buffer(void) 7021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 7039f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 704518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 705518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int tflags, i = 0; 706226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz char buf[150]; 707d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short *addr; 708518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 709518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j, index; 710518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 711518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 7121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 7131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 714226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "Hardware Trace:\n"); 715518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 716d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 717d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); 718d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#endif 719d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 7201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { 721518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { 722226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, (unsigned long)bfin_read_TBUF()); 723226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 724f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned short *)bfin_read_TBUF(); 725f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned long)addr); 726f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 727d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction(addr); 728f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 7291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 7301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 7311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 732518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 733518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (trace_buff_offset) 734d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz index = trace_buff_offset / 4; 735518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz else 736518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 737518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 738518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; 739518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz while (j) { 740226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 741226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 742518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 743518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0 ) 744518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 745226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 746d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 747d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction((unsigned short *)software_trace_buff[index]); 748d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("\n"); 749518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 750518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0) 751518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 752518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j--; 753518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz i++; 754518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz } 755518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 756518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 7571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 758518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 7599f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 7601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 7611394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_bfin_trace_buffer); 7621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 763f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 764f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Checks to see if the address pointed to is either a 765f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * 16-bit CALL instruction, or a 32-bit CALL instruction 766f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 7679f06c38fb230720371397a57faa24aa6e31b2c87Robin Getzstatic bool is_bfin_call(unsigned short *addr) 7681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 769f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short opcode = 0, *ins_addr; 770f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)addr; 7711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 772f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 773f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 7741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 775f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if ((opcode >= 0x0060 && opcode <= 0x0067) || 776f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (opcode >= 0x0070 && opcode <= 0x0077)) 777f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 778f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 779f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 780f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 781f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 7821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 783f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (opcode >= 0xE300 && opcode <= 0xE3FF) 784f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 785f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 786f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 787f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 788f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 7899f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 7901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid show_stack(struct task_struct *task, unsigned long *stack) 7911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 7929f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_PRINTK 793f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int *addr, *endstack, *fp = 0, *frame; 794f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short *ins_addr; 795f09630bff51daaf427968c61c0f2370c64148e06Robin Getz char buf[150]; 796f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int i, j, ret_addr, frame_no = 0; 7971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 798f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 799f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * If we have been passed a specific stack, use that one otherwise 800f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * if we have been passed a task structure, use that, otherwise 801f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * use the stack of where the variable "stack" exists 8021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 8031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 804f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (stack == NULL) { 805f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (task) { 806f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* We know this is a kernel stack, so this is the start/end */ 8071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)task->thread.ksp; 808f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); 809f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 810f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* print out the existing stack info */ 8111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)&stack; 812f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 813f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 814f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 815f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 816f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 8179f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(KERN_NOTICE "Stack info:\n"); 818f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)stack); 8199f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz printk(KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); 8209f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz 821f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned int *)((unsigned int)stack & ~0x3F); 822f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 823f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First thing is to look for a frame pointer */ 824f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; 825f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr < endstack; addr++, i++) { 826f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1) 827f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 828f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 829f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 830f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (is_bfin_call(ins_addr)) 831f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 832f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 833f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 834f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Let's check to see if it is a frame pointer */ 835f09630bff51daaf427968c61c0f2370c64148e06Robin Getz while (fp >= (addr - 1) && fp < endstack && fp) 836f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*fp; 837f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp == 0 || fp == endstack) { 838f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 839f09630bff51daaf427968c61c0f2370c64148e06Robin Getz break; 840f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 841f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = 0; 842f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 8431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 844f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 845f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = fp; 846f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(" FP: (0x%p)\n", fp); 847f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 848f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = 0; 8491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 850f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 851f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Now that we think we know where things are, we 852f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * walk the stack again, this time printing things out 853f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * incase there is no frame pointer, we still look for 854f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * valid return addresses 855f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 8561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 857f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First time print out data, next time, print out symbols */ 858f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (j = 0; j <= 1; j++) { 859f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 860f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE "Return addresses in stack:\n"); 861f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 862f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); 863f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 864f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = frame; 865f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no = 0; 866f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 867f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; 868f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr <= endstack; addr++, i++) { 869f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 870f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = 0; 871f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && i % 8 == 0) 872f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n" KERN_NOTICE "%p:",addr); 873f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 874f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* if it is an odd address, or zero, just skip it */ 875f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1 || !*addr) 876f09630bff51daaf427968c61c0f2370c64148e06Robin Getz goto print; 877f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 878f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 879f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 880f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Go back one instruction, and see if it is a CALL */ 881f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 882f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = is_bfin_call(ins_addr); 883f09630bff51daaf427968c61c0f2370c64148e06Robin Getz print: 884f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && stack == (unsigned long *)addr) 885f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("[%08x]", *addr); 886f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (ret_addr) 887f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) { 888f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)*addr); 889f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (frame == addr) { 890f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); 891f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 892f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 893f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " address : %s\n", buf); 894f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 895f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("<%08x>", *addr); 896f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (fp == addr) { 897f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 898f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = addr+1; 899f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 900f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("(%08x)", *addr); 901f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 902f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*addr; 903f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no++; 904f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 905f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else if (!j) 906f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(" %08x ", *addr); 907f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 908f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j) 909f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 9101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 9119f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 9121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 9131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 9141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_stack(void) 9151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 9161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long stack; 917518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 9181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int tflags; 919518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 9201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 9211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_bfin_trace_buffer(); 9221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu show_stack(current, &stack); 9231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 9241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 9251394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_stack); 9261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 92749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid dump_bfin_process(struct pt_regs *fp) 9281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 9299f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 93049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger /* We should be able to look at fp->ipend, but we don't push it on the 93149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger * stack all the time, so do this until we fix that */ 93249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger unsigned int context = bfin_read_IPEND(); 93349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 93449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger if (oops_in_progress) 9359f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_EMERG "Kernel OOPS in progress\n"); 93649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 937b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) 9389f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "HW Error context\n"); 939b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz else if (context & 0x0020) 9409f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Deferred Exception context\n"); 94149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x3FC0) 9429f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Interrupt context\n"); 94349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x4000) 9449f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Deferred Interrupt context\n"); 94549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x8000) 9469f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Kernel process context\n"); 94749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 9489a62ca40fd793742f92565104c6b44319af8c282Robin Getz /* Because we are crashing, and pointers could be bad, we check things 9499a62ca40fd793742f92565104c6b44319af8c282Robin Getz * pretty closely before we use them 9509a62ca40fd793742f92565104c6b44319af8c282Robin Getz */ 9517f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 9527f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3) && current->pid) { 9539f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "CURRENT PROCESS:\n"); 9549a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (current->comm >= (char *)FIXED_CODE_START) 9559f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "COMM=%s PID=%d\n", 9569a62ca40fd793742f92565104c6b44319af8c282Robin Getz current->comm, current->pid); 9579a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 9589f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "COMM= invalid\n"); 9599a62ca40fd793742f92565104c6b44319af8c282Robin Getz 9609a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) 9619f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" 9629a62ca40fd793742f92565104c6b44319af8c282Robin Getz KERN_NOTICE " BSS = 0x%p-0x%p USER-STACK = 0x%p\n" 9639a62ca40fd793742f92565104c6b44319af8c282Robin Getz KERN_NOTICE "\n", 9649a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_code, 9659a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_code, 9669a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_data, 9679a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 9689a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 9699a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->brk, 9709a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_stack); 9719a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 9729f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "invalid mm\n"); 97349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger } else 9749f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE 97549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger "No Valid process in current context\n"); 9769f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 97749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 978226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 979b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getzvoid dump_bfin_mem(struct pt_regs *fp) 98049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 9819f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 982b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz unsigned short *addr, *erraddr, val = 0, err = 0; 983b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz char sti = 0, buf[6]; 9841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 9855d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt erraddr = (void *)fp->pc; 986b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 9879f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); 988b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 989b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; 990b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; 991b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr++) { 992b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (!((unsigned long)addr & 0xF)) 9939f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n" KERN_NOTICE "0x%p: ", addr); 994b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 9957d98c881eed9e19767bc77ffd650d0041b4f41ecRobin Getz if (!get_instruction(&val, addr)) { 996b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val = 0; 997b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "????"); 998b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 999b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "%04x", val); 1000b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1001b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr == erraddr) { 10029f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("[%s]", buf); 1003b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz err = val; 1004b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 10059f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(" %s ", buf); 1006b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1007b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Do any previous instructions turn on interrupts? */ 1008b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr <= erraddr && /* in the past */ 1009b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */ 1010b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val == 0x017b)) /* [SP++] = RETI */ 1011b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sti = 1; 1012b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 1013b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 10149f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n"); 1015b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 1016b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Hardware error interrupts can be deferred */ 1017b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && 1018b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz oops_in_progress)){ 10199f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); 10201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifndef CONFIG_DEBUG_HWERR 10219f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "The remaining message may be meaningless\n" 1022b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a" 1023b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz " better idea where it came from\n"); 1024b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#else 1025b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* If we are handling only one peripheral interrupt 1026b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * and current mm and pid are valid, and the last error 1027b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * was in that user space process's text area 1028b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * print it out - because that is where the problem exists 1029b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz */ 1030b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) && 1031b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (current->pid && current->mm)) { 1032b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* And the last RETI points to the current userspace context */ 1033b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((fp + 1)->pc >= current->mm->start_code && 1034b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (fp + 1)->pc <= current->mm->end_code) { 10359f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "It might be better to look around here : \n"); 10369f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1037b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz show_regs(fp + 1); 10389f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "-------------------------------------------\n"); 1039b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 10401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1041b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#endif 1042b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 10439f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 104449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 104549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 104649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid show_regs(struct pt_regs *fp) 104749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 10489f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#ifdef CONFIG_DEBUG_VERBOSE 104949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger char buf [150]; 1050d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz struct irqaction *action; 1051d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz unsigned int i; 1052d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz unsigned long flags; 1053226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 10549f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); 10559f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", 1056226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz (long)fp->seqstat, fp->ipend, fp->syscfg); 10571d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz if ((fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) { 10589f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", 10591d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); 10601d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz#ifdef EBIU_ERRMST 10611d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz /* If the error was from the EBIU, print it out */ 10621d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz if (bfin_read_EBIU_ERRMST() & CORE_ERROR) { 10639f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EBIU Error Reason : 0x%04x\n", 10641d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz bfin_read_EBIU_ERRMST()); 10659f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EBIU Error Address : 0x%08x\n", 10661d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz bfin_read_EBIU_ERRADD()); 10671d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz } 10681d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz#endif 10691d5ff7e27d2ca30cd3f61afd353b03dd67330818Robin Getz } 10709f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", 107113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz fp->seqstat & SEQSTAT_EXCAUSE); 1072d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (i = 6; i <= 15 ; i++) { 1073d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & (1 << i)) { 1074d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, bfin_read32(EVT0 + 4*i)); 10759f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); 1076d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1077d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1078d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1079d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz /* if no interrupts are going off, don't print this out */ 1080d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & ~0x3F) { 1081d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (i = 0; i < (NR_IRQS - 1); i++) { 1082d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz spin_lock_irqsave(&irq_desc[i].lock, flags); 1083d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz action = irq_desc[i].action; 1084d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (!action) 1085d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz goto unlock; 1086d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1087d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 10889f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); 1089d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (action = action->next; action; action = action->next) { 1090d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 10919f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(", %s", buf); 1092d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 10939f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk("\n"); 1094d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getzunlock: 1095d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz spin_unlock_irqrestore(&irq_desc[i].lock, flags); 1096d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1097d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1098c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 1099226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rete); 11009f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETE: %s\n", buf); 1101226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retn); 11029f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETN: %s\n", buf); 1103226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retx); 11049f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETX: %s\n", buf); 1105226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rets); 11069f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " RETS: %s\n", buf); 110749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger decode_address(buf, fp->pc); 11089f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " PC : %s\n", buf); 1109c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 111013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && 111113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { 11125d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt decode_address(buf, saved_dcplb_fault_addr); 11139f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); 11145d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt decode_address(buf, saved_icplb_fault_addr); 11159f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); 1116226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 1117226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 11189f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n"); 11199f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", 1120c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r0, fp->r1, fp->r2, fp->r3); 11219f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", 1122c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r4, fp->r5, fp->r6, fp->r7); 11239f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", 1124c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->p0, fp->p1, fp->p2, fp->p3); 11259f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", 1126226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->p4, fp->p5, fp->fp, (long)fp); 11279f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", 1128c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb0, fp->lt0, fp->lc0); 11299f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", 1130c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb1, fp->lt1, fp->lc1); 11319f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", 1132c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b0, fp->l0, fp->m0, fp->i0); 11339f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", 1134c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b1, fp->l1, fp->m1, fp->i1); 11359f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", 1136c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b2, fp->l2, fp->m2, fp->i2); 11379f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", 1138c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b3, fp->l3, fp->m3, fp->i3); 11399f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", 1140226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->a0w, fp->a0x, fp->a1w, fp->a1x); 1141c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 11429f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", 1143c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz rdusp(), fp->astat); 11441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 11459f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz verbose_printk(KERN_NOTICE "\n"); 11469f06c38fb230720371397a57faa24aa6e31b2c87Robin Getz#endif 11471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 11481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 11491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 11501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); 11511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 11521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 11531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock) 11541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 11551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int ret = 0; 11561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int tmp = 0; 11571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 11581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu local_irq_disable(); 11591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu ret = get_user(tmp, spinlock); 11601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (ret == 0) { 11611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (tmp) 11621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu ret = 1; 11631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu tmp = 1; 11641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu put_user(tmp, spinlock); 11651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 11661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu local_irq_enable(); 11671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return ret; 11681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 11691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 11701ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_request_exception(unsigned int exception, void (*handler)(void)) 11711ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 11721ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 11731ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11741ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 11751ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 11761ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11771ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 11781ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11791ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != ex_replaceable) 11801ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 11811ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11821ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = handler; 11831ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11841ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 11851ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 11861ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_request_exception); 11871ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11881ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_free_exception(unsigned int exception, void (*handler)(void)) 11891ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 11901ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 11911ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11921ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 11931ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 11941ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11951ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 11961ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11971ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != handler) 11981ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 11991ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12001ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = ex_replaceable; 12011ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12021ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 12031ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 12041ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_free_exception); 12051ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 12061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid panic_cplb_error(int cplb_panic, struct pt_regs *fp) 12071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 12081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (cplb_panic) { 12091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_UNLOCKED: 12101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "All CPLBs are locked\n"); 12111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 12121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_PROT_VIOL: 12131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 12141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_ADDR_MATCH: 12151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 12161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_UNKNOWN_ERR: 12171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "Unknown CPLB Exception\n"); 12181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 12191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 12201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1221226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 1222226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 122349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 1224b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 122549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 12261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_stack(); 12271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu panic("Unrecoverable event\n"); 12281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 1229