traps.c revision f4585a08479a730fb809606b8ee327a5398c117c
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> 43b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#include <asm/dma.h> 441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu# include <linux/debugger.h> 471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu# include <linux/kgdb.h> 48226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 49226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() \ 50226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 51226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz CHK_DEBUGGER(trapnr, sig, info.si_code, fp, ); \ 52226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 53226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() \ 54226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz do { \ 55226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (kgdb_connected) \ 56226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz CHK_DEBUGGER_TRAP(); \ 57226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } while (0) 58226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#else 59226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP() do { } while (0) 60226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz# define CHK_DEBUGGER_TRAP_MAYBE() do { } while (0) 611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Initiate the event table handler */ 641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid __init trap_init(void) 651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu bfin_write_EVT3(trap); 681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CSYNC(); 691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 71bd628bd085c459838d38f93f2f154f1a2e019e48Mike Frysingerunsigned long saved_icplb_fault_addr, saved_dcplb_fault_addr; 725d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt 73226eb1ef523a33c66193bc319a92c647e47311d4Robin Getzstatic void decode_address(char *buf, unsigned long address) 741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct vm_list_struct *vml; 761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct task_struct *p; 771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct mm_struct *mm; 78885be03b069131d242506f0f717d38659b2bdb6cRobin Getz unsigned long flags, offset; 79904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz unsigned char in_atomic = (bfin_read_IPEND() & 0x10) || in_atomic(); 801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KALLSYMS 828a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger unsigned long symsize; 831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu const char *symname; 841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *modname; 851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *delim = ":"; 861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char namebuf[128]; 871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* look up the address and see if we are in kernel space */ 891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu symname = kallsyms_lookup(address, &symsize, &offset, &modname, namebuf); 901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (symname) { 921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* yeah! kernel space! */ 931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!modname) 941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu modname = delim = ""; 95226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> { %s%s%s%s + 0x%lx }", 961f83b8f148a1eb967d2a628cbb741cd56fb54572Mike Frysinger (void *)address, delim, modname, delim, symname, 971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu (unsigned long)offset); 98885be03b069131d242506f0f717d38659b2bdb6cRobin Getz return; 991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 1021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 103226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Problem in fixed code section? */ 104226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (address >= FIXED_CODE_START && address < FIXED_CODE_END) { 105226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> /* Maybe fixed code section */", (void *)address); 106226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 107226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 108226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 109226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Problem somewhere before the kernel start address */ 110226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (address < CONFIG_BOOT_LOAD) { 111226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz sprintf(buf, "<0x%p> /* Maybe null pointer? */", (void *)address); 112226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz return; 113226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 114226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* looks like we're off in user-land, so let's walk all the 1161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * mappings of all our processes and see if we can't be a whee 1171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * bit more specific 1181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 119885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_lock_irqsave(&tasklist_lock, flags); 1201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu for_each_process(p) { 121904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz mm = (in_atomic ? p->mm : get_task_mm(p)); 1221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (!mm) 1231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu continue; 1241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu vml = mm->context.vmlist; 1261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu while (vml) { 1271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct vm_area_struct *vma = vml->vma; 1281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (address >= vma->vm_start && address < vma->vm_end) { 130cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck char _tmpbuf[256]; 1311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu char *name = p->comm; 1321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu struct file *file = vma->vm_file; 133cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck 134cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck if (file) 135cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck name = d_path(&file->f_path, _tmpbuf, 136cf28b4863f9ee8f122e8ff3ac0d403e07ba9c6d9Jan Blunck sizeof(_tmpbuf)); 1371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1388a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger /* FLAT does not have its text aligned to the start of 1398a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger * the map while FDPIC ELF does ... 1408a0e6656030ffe9bcb81b725e956917bafc7522dMike Frysinger */ 1417f1c906808a36630990d83d872935c079b76595bRobin Getz 1427f1c906808a36630990d83d872935c079b76595bRobin Getz /* before we can check flat/fdpic, we need to 1437f1c906808a36630990d83d872935c079b76595bRobin Getz * make sure current is valid 1447f1c906808a36630990d83d872935c079b76595bRobin Getz */ 1457f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 1467f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3)) { 1477f1c906808a36630990d83d872935c079b76595bRobin Getz if (current->mm && 1487f1c906808a36630990d83d872935c079b76595bRobin Getz (address > current->mm->start_code) && 1497f1c906808a36630990d83d872935c079b76595bRobin Getz (address < current->mm->end_code)) 1507f1c906808a36630990d83d872935c079b76595bRobin Getz offset = address - current->mm->start_code; 1517f1c906808a36630990d83d872935c079b76595bRobin Getz else 1527f1c906808a36630990d83d872935c079b76595bRobin Getz offset = (address - vma->vm_start) + 1537f1c906808a36630990d83d872935c079b76595bRobin Getz (vma->vm_pgoff << PAGE_SHIFT); 1547f1c906808a36630990d83d872935c079b76595bRobin Getz 1557f1c906808a36630990d83d872935c079b76595bRobin Getz sprintf(buf, "<0x%p> [ %s + 0x%lx ]", 1567f1c906808a36630990d83d872935c079b76595bRobin Getz (void *)address, name, offset); 1577f1c906808a36630990d83d872935c079b76595bRobin Getz } else 1587f1c906808a36630990d83d872935c079b76595bRobin Getz sprintf(buf, "<0x%p> [ %s vma:0x%lx-0x%lx]", 1597f1c906808a36630990d83d872935c079b76595bRobin Getz (void *)address, name, 1607f1c906808a36630990d83d872935c079b76595bRobin Getz vma->vm_start, vma->vm_end); 1617f1c906808a36630990d83d872935c079b76595bRobin Getz 162904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 163885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 1647f1c906808a36630990d83d872935c079b76595bRobin Getz 165f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!strlen(buf)) 166f09630bff51daaf427968c61c0f2370c64148e06Robin Getz sprintf(buf, "<0x%p> [ %s ] dynamic memory", (void *)address, name); 167f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 168885be03b069131d242506f0f717d38659b2bdb6cRobin Getz goto done; 1691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu vml = vml->next; 1721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 173904656cda10ce985e6bc8b16488b58236eaec8e2Robin Getz if (!in_atomic) 174885be03b069131d242506f0f717d38659b2bdb6cRobin Getz mmput(mm); 1751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 1761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* we were unable to find this address anywhere */ 178f09630bff51daaf427968c61c0f2370c64148e06Robin Getz sprintf(buf, "<0x%p> /* kernel dynamic memory */", (void *)address); 179885be03b069131d242506f0f717d38659b2bdb6cRobin Getz 180885be03b069131d242506f0f717d38659b2bdb6cRobin Getzdone: 181885be03b069131d242506f0f717d38659b2bdb6cRobin Getz write_unlock_irqrestore(&tasklist_lock, flags); 1821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 1831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1842ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getzasmlinkage void double_fault_c(struct pt_regs *fp) 1852ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz{ 186226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 187226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 1882ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz printk(KERN_EMERG "\n" KERN_EMERG "Double Fault\n"); 18949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 190b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 19149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 1922ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz panic("Double Fault - unrecoverable event\n"); 1932ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 1942ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz} 1952ebcade590dcf822dcdadcc4f8f68efd3ff2e217Robin Getz 1961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage void trap_c(struct pt_regs *fp) 1971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 198518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 199518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j; 200518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 201518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int sig = 0; 2021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu siginfo_t info; 2031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long trapnr = fp->seqstat & SEQSTAT_EXCAUSE; 2041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 205226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz trace_buffer_save(j); 206226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 207226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Important - be very careful dereferncing pointers - will lead to 208226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * double faults if the stack has become corrupt 209226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz */ 210226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 211226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* If the fault was caused by a kernel thread, or interrupt handler 212226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * we will kernel panic, so the system reboots. 213226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz * If KGDB is enabled, don't set this for kernel breakpoints 214226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz */ 215b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 216b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* TODO: check to see if we are in some sort of deferred HWERR 217b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * that we should be able to recover from, not kernel panic 218b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz */ 2196b5eace2f15b53d5a6849078d22e78db77625929Robin Getz if ((bfin_read_IPEND() & 0xFFC0) && (trapnr != VEC_STEP) 2201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 2216b5eace2f15b53d5a6849078d22e78db77625929Robin Getz && (trapnr != VEC_EXCPT02) 2221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 223226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz ){ 224226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 225226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 226226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } else if (current) { 227226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (current->mm == NULL) { 228226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz console_verbose(); 229226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 230226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 231226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 2321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* trap_c() will be called for exceptions. During exceptions 2341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * processing, the pc value should be set with retx value. 2351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * With this change we can cleanup some code in signal.c- TODO 2361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 2371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu fp->orig_pc = fp->retx; 2381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* printk("exception: 0x%x, ipend=%x, reti=%x, retx=%x\n", 2391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trapnr, fp->ipend, fp->pc, fp->retx); */ 2401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* send the appropriate signal to the user program */ 2421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (trapnr) { 2431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* This table works in conjuction with the one in ./mach-common/entry.S 2451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some exceptions are handled there (in assembly, in exception space) 2461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some are handled here, (in C, in interrupt space) 2471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * Some, like CPLB, are handled in both, where the normal path is 2481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * handled in assembly/exception space, and the error path is handled 2491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu * here 2501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 2511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 2521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x00 - Linux Syscall, getting here is an error */ 2531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x01 - userspace gdb breakpoint, handled here */ 2541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT01: 2551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_ILLTRAP; 2561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 2571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 2581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a breakpoint in kernel space */ 2591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 2601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 2611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 2621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 2631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_KGDB 2641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT02 : /* gdb connection */ 2651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_ILLTRAP; 2661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 2671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 2681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 2691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else 2701394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x02 - User Defined, Caught by default */ 2711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 2729401e618c8f70920f34893946239e24d40a3519aMike Frysinger /* 0x03 - User Defined, userspace stack overflow */ 2731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_EXCPT03: 2741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = SEGV_STACKFLOW; 2751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 276569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x03(KERN_NOTICE)); 2771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 2781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 2799401e618c8f70920f34893946239e24d40a3519aMike Frysinger /* 0x04 - User Defined, Caught by default */ 2801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x05 - User Defined, Caught by default */ 2811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x06 - User Defined, Caught by default */ 2821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x07 - User Defined, Caught by default */ 2831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x08 - User Defined, Caught by default */ 2841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x09 - User Defined, Caught by default */ 2851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x0A - User Defined, Caught by default */ 2861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x0B - User Defined, Caught by default */ 2871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x0C - User Defined, Caught by default */ 2881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x0D - User Defined, Caught by default */ 2891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x0E - User Defined, Caught by default */ 2901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x0F - User Defined, Caught by default */ 2911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x10 HW Single step, handled here */ 2921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_STEP: 2931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_STEP; 2941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 2951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 2961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a single step in kernel space */ 2971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 2981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 2991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x11 - Trace Buffer Full, handled here */ 3021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_OVFLOW: 3031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_TRACEFLOW; 3041394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 305569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x11(KERN_NOTICE)); 3061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x12 - Reserved, Caught by default */ 3091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x13 - Reserved, Caught by default */ 3101394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x14 - Reserved, Caught by default */ 3111394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x15 - Reserved, Caught by default */ 3121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x16 - Reserved, Caught by default */ 3131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x17 - Reserved, Caught by default */ 3141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x18 - Reserved, Caught by default */ 3151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x19 - Reserved, Caught by default */ 3161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1A - Reserved, Caught by default */ 3171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1B - Reserved, Caught by default */ 3181394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1C - Reserved, Caught by default */ 3191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1D - Reserved, Caught by default */ 3201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1E - Reserved, Caught by default */ 3211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x1F - Reserved, Caught by default */ 3221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x20 - Reserved, Caught by default */ 3231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x21 - Undefined Instruction, handled here */ 3241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNDEF_I: 3251394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLOPC; 3261394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 327569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x21(KERN_NOTICE)); 3281394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x22 - Illegal Instruction Combination, handled here */ 3311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILGAL_I: 3321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLPARAOP; 3331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 334569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x22(KERN_NOTICE)); 3351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 337f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x23 - Data CPLB protection violation, handled here */ 3381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_VL: 3391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 340f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz sig = SIGBUS; 341569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x23(KERN_NOTICE)); 3421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x24 - Data access misaligned, handled here */ 3451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_D: 3461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 3471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 348569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x24(KERN_NOTICE)); 3491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x25 - Unrecoverable Event, handled here */ 3521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_UNCOV: 3531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_ILLEXCPT; 3541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 355569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x25(KERN_NOTICE)); 3561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x26 - Data CPLB Miss, normal case is handled in _cplb_hdr, 3591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu error case is handled here */ 3601394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_M: 3611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 3621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 363569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x26(KERN_NOTICE)); 3641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x27 - Data CPLB Multiple Hits - Linux Trap Zero, handled here */ 3671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_MHIT: 3681394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 3691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 370c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 371bd628bd085c459838d38f93f2f154f1a2e019e48Mike Frysinger if (saved_dcplb_fault_addr < FIXED_CODE_START) 372c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger printk(KERN_NOTICE "NULL pointer access\n"); 373c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 3741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 375c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger printk(KERN_NOTICE EXC_0x27(KERN_NOTICE)); 3761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x28 - Emulation Watchpoint, handled here */ 3791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_WATCH: 3801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_WATCHPT; 3811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 382569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz pr_debug(EXC_0x28(KERN_DEBUG)); 3831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP_MAYBE(); 3841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* Check if this is a watchpoint in kernel space */ 3851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (fp->ipend & 0xffc0) 3861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 3871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu else 3881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_BF535 3901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Instruction fetch access error (535 only) */ 3911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ISTRU_VL: /* ADSP-BF535 only (MH) */ 3921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_OPFETCH; 3931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 394226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "BF535: VEC_ISTRU_VL\n"); 3951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 3961394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 3971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#else 3981394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x29 - Reserved, Caught by default */ 3991394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 4001394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2A - Instruction fetch misaligned, handled here */ 4011394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_MISALI_I: 4021394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = BUS_ADRALN; 4031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 404569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x2A(KERN_NOTICE)); 4051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 4061394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 407f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz /* 0x2B - Instruction CPLB protection violation, handled here */ 4081394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_VL: 4091394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_VI; 410f26fbc48f130962fce15f37d079968f0f272e0c2Robin Getz sig = SIGBUS; 411569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x2B(KERN_NOTICE)); 4121394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 4131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4141394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2C - Instruction CPLB miss, handled in _cplb_hdr */ 4151394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_M: 4161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MISS; 4171394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGBUS; 418569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x2C(KERN_NOTICE)); 4191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 4201394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4211394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2D - Instruction CPLB Multiple Hits, handled here */ 4221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_CPLB_I_MHIT: 4231394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_CPLB_MULHIT; 4241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGSEGV; 425c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger#ifdef CONFIG_DEBUG_HUNT_FOR_ZERO 426bd628bd085c459838d38f93f2f154f1a2e019e48Mike Frysinger if (saved_icplb_fault_addr < FIXED_CODE_START) 427c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger printk(KERN_NOTICE "Jump to NULL address\n"); 428c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger else 4291394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 430c6c6f75d54ca734c409e336245662934c21fcee0Mike Frysinger printk(KERN_NOTICE EXC_0x2D(KERN_NOTICE)); 4311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 4321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2E - Illegal use of Supervisor Resource, handled here */ 4341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case VEC_ILL_RES: 4351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = ILL_PRVOPC; 4361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGILL; 437569a50ca3f56cd69199733580e7ca0e81029473aRobin Getz printk(KERN_NOTICE EXC_0x2E(KERN_NOTICE)); 4381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 4391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x2F - Reserved, Caught by default */ 4411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x30 - Reserved, Caught by default */ 4421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x31 - Reserved, Caught by default */ 4431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x32 - Reserved, Caught by default */ 4441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x33 - Reserved, Caught by default */ 4451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x34 - Reserved, Caught by default */ 4461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x35 - Reserved, Caught by default */ 4471394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x36 - Reserved, Caught by default */ 4481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x37 - Reserved, Caught by default */ 4491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x38 - Reserved, Caught by default */ 4501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x39 - Reserved, Caught by default */ 4511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3A - Reserved, Caught by default */ 4521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3B - Reserved, Caught by default */ 4531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3C - Reserved, Caught by default */ 4541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3D - Reserved, Caught by default */ 4551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3E - Reserved, Caught by default */ 4561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu /* 0x3F - Reserved, Caught by default */ 45713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case VEC_HWERR: 45813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 45913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 46013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz switch (fp->seqstat & SEQSTAT_HWERRCAUSE) { 46113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* System MMR Error */ 46213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_SYSTEM_MMR): 46313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRALN; 46413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 46513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_x2(KERN_NOTICE)); 46613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 46713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* External Memory Addressing Error */ 46813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_EXTERN_ADDR): 46913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz info.si_code = BUS_ADRERR; 47013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz sig = SIGBUS; 47113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_x3(KERN_NOTICE)); 47213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 47313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* Performance Monitor Overflow */ 47413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_PERF_FLOW): 47513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_x12(KERN_NOTICE)); 47613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 47713fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz /* RAISE 5 instruction */ 47813fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz case (SEQSTAT_HWERRCAUSE_RAISE_5): 47913fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_x18(KERN_NOTICE)); 48013fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 48113fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz default: /* Reserved */ 48213fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE HWC_default(KERN_NOTICE)); 48313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 48413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz } 48513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz CHK_DEBUGGER_TRAP(); 48613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz break; 4871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu default: 4881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu info.si_code = TRAP_ILLTRAP; 4891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu sig = SIGTRAP; 4901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "Caught Unhandled Exception, code = %08lx\n", 4911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu (fp->seqstat & SEQSTAT_EXCAUSE)); 4921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu CHK_DEBUGGER_TRAP(); 4931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 4941394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 4951394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 496226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz BUG_ON(sig == 0); 497226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 498226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (sig != SIGTRAP) { 499f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned long *stack; 50049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 501b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 50249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 503226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 504226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz /* Print out the trace buffer if it makes sense */ 505226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE 506226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (trapnr == VEC_CPLB_I_M || trapnr == VEC_CPLB_M) 507226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "No trace since you do not have " 508226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz "CONFIG_DEBUG_BFIN_NO_KERN_HWTRACE enabled\n" 509226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz KERN_NOTICE "\n"); 510226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz else 511226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 512226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz dump_bfin_trace_buffer(); 513f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 514226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz if (oops_in_progress) { 515f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the current kernel stack */ 516f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE "\n" KERN_NOTICE "Kernel Stack\n"); 517f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(current, NULL); 518f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 519aee3a29240ad167ad7875d859506d8bb90431c70Robin Getz print_modules(); 520226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#ifndef CONFIG_ACCESS_CHECK 52190c7f4686f82aef875aadf8e5c9c1a9465e5143bRobin Getz printk(KERN_EMERG "Please turn on " 52290c7f4686f82aef875aadf8e5c9c1a9465e5143bRobin Getz "CONFIG_ACCESS_CHECK\n"); 523226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz#endif 5241394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu panic("Kernel exception"); 525f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 526f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Dump the user space stack */ 527f09630bff51daaf427968c61c0f2370c64148e06Robin Getz stack = (unsigned long *)rdusp(); 528f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE "Userspace Stack\n"); 529f09630bff51daaf427968c61c0f2370c64148e06Robin Getz show_stack(NULL, stack); 530226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 5311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 532fb322915a05804a3a153f714f2f08e4c32ce84c7Robin Getz 533ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz info.si_signo = sig; 534ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz info.si_errno = 0; 5350ddeeca25ce33686262459e2387f57bd09574e47Mike Frysinger info.si_addr = (void __user *)fp->pc; 536ce3afa1c043ab3d4125671441a57353d80f5f6f7Robin Getz force_sig_info(sig, &info, current); 5371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 5381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(j); 5391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 5401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 5411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 5421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu/* Typical exception handling routines */ 5431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 544518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#define EXPAND_LEN ((1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 256 - 1) 545518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 546f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 547f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Similar to get_user, do some address checking, then dereference 548f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Return true on sucess, false on bad address 549f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 550f09630bff51daaf427968c61c0f2370c64148e06Robin Getzbool get_instruction(unsigned short *val, unsigned short *address) 551f09630bff51daaf427968c61c0f2370c64148e06Robin Getz{ 552f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 553f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned long addr; 554f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 555f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned long)address; 556f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 557f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Check for odd addresses */ 558f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr & 0x1) 559f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 560f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 561f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Check that things do not wrap around */ 562f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr > (addr + 2)) 563f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 564f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 565f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 566f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Since we are in exception context, we need to do a little address checking 567f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * We need to make sure we are only accessing valid memory, and 568f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * we don't read something in the async space that can hang forever 569f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 570f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if ((addr >= FIXED_CODE_START && (addr + 2) <= physical_mem_end) || 57107aa7be5708afb3d9afa68f6f853c98e51bc64b3Mike Frysinger#if L2_LENGTH != 0 572f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L2_START && (addr + 2) <= (L2_START + L2_LENGTH)) || 573f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 574f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= BOOT_ROM_START && (addr + 2) <= (BOOT_ROM_START + BOOT_ROM_LENGTH)) || 575f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_DATA_A_LENGTH != 0 576f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_DATA_A_START && (addr + 2) <= (L1_DATA_A_START + L1_DATA_A_LENGTH)) || 577f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 578f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_DATA_B_LENGTH != 0 579f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_DATA_B_START && (addr + 2) <= (L1_DATA_B_START + L1_DATA_B_LENGTH)) || 580f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 581f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (addr >= L1_SCRATCH_START && (addr + 2) <= (L1_SCRATCH_START + L1_SCRATCH_LENGTH)) || 582f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL0() & B0RDYEN) && 583f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK0_BASE && (addr + 2) <= (ASYNC_BANK0_BASE + ASYNC_BANK0_SIZE)) || 584f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL0() & B1RDYEN) && 585f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK1_BASE && (addr + 2) <= (ASYNC_BANK1_BASE + ASYNC_BANK1_SIZE)) || 586f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL1() & B2RDYEN) && 587f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK2_BASE && (addr + 2) <= (ASYNC_BANK2_BASE + ASYNC_BANK1_SIZE)) || 588f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (!(bfin_read_EBIU_AMBCTL1() & B3RDYEN) && 589f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr >= ASYNC_BANK3_BASE && (addr + 2) <= (ASYNC_BANK3_BASE + ASYNC_BANK1_SIZE))) { 590f09630bff51daaf427968c61c0f2370c64148e06Robin Getz *val = *address; 591f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 592f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 593f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 594f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#if L1_CODE_LENGTH != 0 595f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (addr >= L1_CODE_START && (addr + 2) <= (L1_CODE_START + L1_CODE_LENGTH)) { 596f09630bff51daaf427968c61c0f2370c64148e06Robin Getz dma_memcpy(val, address, 2); 597f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 598f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 599f09630bff51daaf427968c61c0f2370c64148e06Robin Getz#endif 600f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 601f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 602f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 603f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 604f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 605d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz/* 606d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * decode the instruction if we are printing out the trace, as it 607d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * makes things easier to follow, without running it through objdump 608d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * These are the normal instructions which cause change of flow, which 609d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz * would be at the source of the trace buffer 610d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz */ 611d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getzvoid decode_instruction(unsigned short *address) 612d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz{ 613d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short opcode; 614d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 615d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (get_instruction(&opcode, address)) { 616d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz if (opcode == 0x0010) 617d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("RTS"); 618d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0011) 619d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("RTI"); 620d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode == 0x0012) 621d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("RTX"); 622d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0050 && opcode <= 0x0057) 623d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("JUMP (P%i)", opcode & 7); 624d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0060 && opcode <= 0x0067) 625d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("CALL (P%i)", opcode & 7); 626d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0070 && opcode <= 0x0077) 627d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("CALL (PC+P%i)", opcode & 7); 628d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x0080 && opcode <= 0x0087) 629d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("JUMP (PC+P%i)", opcode & 7); 630d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1000 && opcode <= 0x13FF) || (opcode >= 0x1800 && opcode <= 0x1BFF)) 631d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("IF !CC JUMP"); 632d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if ((opcode >= 0x1400 && opcode <= 0x17ff) || (opcode >= 0x1c00 && opcode <= 0x1fff)) 633d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("IF CC JUMP"); 634d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0x2000 && opcode <= 0x2fff) 635d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("JUMP.S"); 636d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe080 && opcode <= 0xe0ff) 637d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("LSETUP"); 638d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe200 && opcode <= 0xe2ff) 639d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("JUMP.L"); 640d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else if (opcode >= 0xe300 && opcode <= 0xe3ff) 641d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("CALL pcrel"); 642d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz else 643d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("0x%04x", opcode); 644d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz } 645d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 646d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz} 647d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 6481394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_bfin_trace_buffer(void) 6491394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 650518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 651518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int tflags, i = 0; 652226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz char buf[150]; 653d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz unsigned short *addr; 654518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 655518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz int j, index; 656518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 657518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 6581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 6591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 660226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "Hardware Trace:\n"); 661518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 662d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 663d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE "WARNING: Expanded trace turned on - can not trace exceptions\n"); 664d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz#endif 665d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz 6661394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (likely(bfin_read_TBUFSTAT() & TBUFCNT)) { 667518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz for (; bfin_read_TBUFSTAT() & TBUFCNT; i++) { 668226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, (unsigned long)bfin_read_TBUF()); 669226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 670f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned short *)bfin_read_TBUF(); 671f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned long)addr); 672f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 673d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction(addr); 674f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 6751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 6761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 6771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 678518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_EXPAND 679518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (trace_buff_offset) 680d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz index = trace_buff_offset / 4; 681518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz else 682518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 683518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 684518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j = (1 << CONFIG_DEBUG_BFIN_HWTRACE_EXPAND_LEN) * 128; 685518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz while (j) { 686226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 687226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "%4i Target : %s\n", i, buf); 688518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 689518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0 ) 690518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 691226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, software_trace_buff[index]); 692d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk(KERN_NOTICE " Source : %s ", buf); 693d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz decode_instruction((unsigned short *)software_trace_buff[index]); 694d3d0ac23a308f92fc5e5e2846ca40e7bffa5cec3Robin Getz printk("\n"); 695518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index -= 1; 696518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz if (index < 0) 697518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz index = EXPAND_LEN; 698518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz j--; 699518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz i++; 700518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz } 701518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 702518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz 7031394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 704518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 7051394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 7061394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_bfin_trace_buffer); 7071394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 708f09630bff51daaf427968c61c0f2370c64148e06Robin Getz/* 709f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Checks to see if the address pointed to is either a 710f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * 16-bit CALL instruction, or a 32-bit CALL instruction 711f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 712f09630bff51daaf427968c61c0f2370c64148e06Robin Getzbool is_bfin_call(unsigned short *addr) 7131394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 714f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short opcode = 0, *ins_addr; 715f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)addr; 7161394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 717f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 718f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 7191394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 720f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if ((opcode >= 0x0060 && opcode <= 0x0067) || 721f09630bff51daaf427968c61c0f2370c64148e06Robin Getz (opcode >= 0x0070 && opcode <= 0x0077)) 722f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 723f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 724f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 725f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!get_instruction(&opcode, ins_addr)) 726f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 7271394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 728f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (opcode >= 0xE300 && opcode <= 0xE3FF) 729f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return true; 730f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 731f09630bff51daaf427968c61c0f2370c64148e06Robin Getz return false; 732f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 733f09630bff51daaf427968c61c0f2370c64148e06Robin Getz} 7341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid show_stack(struct task_struct *task, unsigned long *stack) 7351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 736f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int *addr, *endstack, *fp = 0, *frame; 737f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned short *ins_addr; 738f09630bff51daaf427968c61c0f2370c64148e06Robin Getz char buf[150]; 739f09630bff51daaf427968c61c0f2370c64148e06Robin Getz unsigned int i, j, ret_addr, frame_no = 0; 7401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 741f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 742f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * If we have been passed a specific stack, use that one otherwise 743f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * if we have been passed a task structure, use that, otherwise 744f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * use the stack of where the variable "stack" exists 7451394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu */ 7461394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 747f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (stack == NULL) { 748f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (task) { 749f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* We know this is a kernel stack, so this is the start/end */ 7501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)task->thread.ksp; 751f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)(((unsigned int)(stack) & ~(THREAD_SIZE - 1)) + THREAD_SIZE); 752f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else { 753f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* print out the existing stack info */ 7541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu stack = (unsigned long *)&stack; 755f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 756f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 757f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 758f09630bff51daaf427968c61c0f2370c64148e06Robin Getz endstack = (unsigned int *)PAGE_ALIGN((unsigned int)stack); 759f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 760f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)stack); 761f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE "Stack info:\n" KERN_NOTICE " SP: [0x%p] %s\n", stack, buf); 762f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr = (unsigned int *)((unsigned int)stack & ~0x3F); 763f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 764f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First thing is to look for a frame pointer */ 765f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; 766f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr < endstack; addr++, i++) { 767f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1) 768f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 769f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 770f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 771f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (is_bfin_call(ins_addr)) 772f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 773f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 774f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 775f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Let's check to see if it is a frame pointer */ 776f09630bff51daaf427968c61c0f2370c64148e06Robin Getz while (fp >= (addr - 1) && fp < endstack && fp) 777f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*fp; 778f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp == 0 || fp == endstack) { 779f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = addr - 1; 780f09630bff51daaf427968c61c0f2370c64148e06Robin Getz break; 781f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 782f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = 0; 783f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 7841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 785f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (fp) { 786f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = fp; 787f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(" FP: (0x%p)\n", fp); 788f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 789f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = 0; 7901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 791f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* 792f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * Now that we think we know where things are, we 793f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * walk the stack again, this time printing things out 794f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * incase there is no frame pointer, we still look for 795f09630bff51daaf427968c61c0f2370c64148e06Robin Getz * valid return addresses 796f09630bff51daaf427968c61c0f2370c64148e06Robin Getz */ 7971394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 798f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* First time print out data, next time, print out symbols */ 799f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (j = 0; j <= 1; j++) { 800f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 801f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE "Return addresses in stack:\n"); 802f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 803f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " Memory from 0x%08lx to %p", ((long unsigned int)stack & ~0xF), endstack); 804f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 805f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = frame; 806f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no = 0; 807f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 808f09630bff51daaf427968c61c0f2370c64148e06Robin Getz for (addr = (unsigned int *)((unsigned int)stack & ~0xF), i = 0; 809f09630bff51daaf427968c61c0f2370c64148e06Robin Getz addr <= endstack; addr++, i++) { 810f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 811f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = 0; 812f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && i % 8 == 0) 813f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n" KERN_NOTICE "%p:",addr); 814f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 815f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* if it is an odd address, or zero, just skip it */ 816f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (*addr & 0x1 || !*addr) 817f09630bff51daaf427968c61c0f2370c64148e06Robin Getz goto print; 818f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 819f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr = (unsigned short *)*addr; 820f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 821f09630bff51daaf427968c61c0f2370c64148e06Robin Getz /* Go back one instruction, and see if it is a CALL */ 822f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ins_addr--; 823f09630bff51daaf427968c61c0f2370c64148e06Robin Getz ret_addr = is_bfin_call(ins_addr); 824f09630bff51daaf427968c61c0f2370c64148e06Robin Getz print: 825f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j && stack == (unsigned long *)addr) 826f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("[%08x]", *addr); 827f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (ret_addr) 828f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) { 829f09630bff51daaf427968c61c0f2370c64148e06Robin Getz decode_address(buf, (unsigned int)*addr); 830f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (frame == addr) { 831f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " frame %2i : %s\n", frame_no, buf); 832f09630bff51daaf427968c61c0f2370c64148e06Robin Getz continue; 833f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 834f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(KERN_NOTICE " address : %s\n", buf); 835f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else 836f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("<%08x>", *addr); 837f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else if (fp == addr) { 838f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (j) 839f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame = addr+1; 840f09630bff51daaf427968c61c0f2370c64148e06Robin Getz else 841f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("(%08x)", *addr); 842f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 843f09630bff51daaf427968c61c0f2370c64148e06Robin Getz fp = (unsigned int *)*addr; 844f09630bff51daaf427968c61c0f2370c64148e06Robin Getz frame_no++; 845f09630bff51daaf427968c61c0f2370c64148e06Robin Getz 846f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } else if (!j) 847f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk(" %08x ", *addr); 848f09630bff51daaf427968c61c0f2370c64148e06Robin Getz } 849f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (!j) 850f09630bff51daaf427968c61c0f2370c64148e06Robin Getz printk("\n"); 8511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 8521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 8531394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 8541394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 8551394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid dump_stack(void) 8561394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 8571394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu unsigned long stack; 858518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#ifdef CONFIG_DEBUG_BFIN_HWTRACE_ON 8591394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int tflags; 860518039bc24cbb9ce34665814fe120eac50bedd9aRobin Getz#endif 8611394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_save(tflags); 8621394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_bfin_trace_buffer(); 8631394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu show_stack(current, &stack); 8641394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu trace_buffer_restore(tflags); 8651394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 8661394f03221790a988afc3e4b3cb79f2e477246a9Bryan WuEXPORT_SYMBOL(dump_stack); 8671394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 86849dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid dump_bfin_process(struct pt_regs *fp) 8691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 87049dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger /* We should be able to look at fp->ipend, but we don't push it on the 87149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger * stack all the time, so do this until we fix that */ 87249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger unsigned int context = bfin_read_IPEND(); 87349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 87449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger if (oops_in_progress) 87549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger printk(KERN_EMERG "Kernel OOPS in progress\n"); 87649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 877b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (context & 0x0020 && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR) 878b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(KERN_NOTICE "HW Error context\n"); 879b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz else if (context & 0x0020) 880a3acf52885a2312efb30a043062ef88dc3813082Mike Frysinger printk(KERN_NOTICE "Deferred Exception context\n"); 88149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x3FC0) 88249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger printk(KERN_NOTICE "Interrupt context\n"); 88349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x4000) 88449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger printk(KERN_NOTICE "Deferred Interrupt context\n"); 88549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger else if (context & 0x8000) 88649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger printk(KERN_NOTICE "Kernel process context\n"); 88749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 8889a62ca40fd793742f92565104c6b44319af8c282Robin Getz /* Because we are crashing, and pointers could be bad, we check things 8899a62ca40fd793742f92565104c6b44319af8c282Robin Getz * pretty closely before we use them 8909a62ca40fd793742f92565104c6b44319af8c282Robin Getz */ 8917f1c906808a36630990d83d872935c079b76595bRobin Getz if ((unsigned long)current >= FIXED_CODE_START && 8927f1c906808a36630990d83d872935c079b76595bRobin Getz !((unsigned long)current & 0x3) && current->pid) { 89349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger printk(KERN_NOTICE "CURRENT PROCESS:\n"); 8949a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (current->comm >= (char *)FIXED_CODE_START) 8959a62ca40fd793742f92565104c6b44319af8c282Robin Getz printk(KERN_NOTICE "COMM=%s PID=%d\n", 8969a62ca40fd793742f92565104c6b44319af8c282Robin Getz current->comm, current->pid); 8979a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 8989a62ca40fd793742f92565104c6b44319af8c282Robin Getz printk(KERN_NOTICE "COMM= invalid\n"); 8999a62ca40fd793742f92565104c6b44319af8c282Robin Getz 9009a62ca40fd793742f92565104c6b44319af8c282Robin Getz if (!((unsigned long)current->mm & 0x3) && (unsigned long)current->mm >= FIXED_CODE_START) 9019a62ca40fd793742f92565104c6b44319af8c282Robin Getz printk(KERN_NOTICE "TEXT = 0x%p-0x%p DATA = 0x%p-0x%p\n" 9029a62ca40fd793742f92565104c6b44319af8c282Robin Getz KERN_NOTICE " BSS = 0x%p-0x%p USER-STACK = 0x%p\n" 9039a62ca40fd793742f92565104c6b44319af8c282Robin Getz KERN_NOTICE "\n", 9049a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_code, 9059a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_code, 9069a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_data, 9079a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 9089a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->end_data, 9099a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->brk, 9109a62ca40fd793742f92565104c6b44319af8c282Robin Getz (void *)current->mm->start_stack); 9119a62ca40fd793742f92565104c6b44319af8c282Robin Getz else 9129a62ca40fd793742f92565104c6b44319af8c282Robin Getz printk(KERN_NOTICE "invalid mm\n"); 91349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger } else 91449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger printk(KERN_NOTICE "\n" KERN_NOTICE 91549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger "No Valid process in current context\n"); 91649dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 917226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 918b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getzvoid dump_bfin_mem(struct pt_regs *fp) 91949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 920b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz unsigned short *addr, *erraddr, val = 0, err = 0; 921b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz char sti = 0, buf[6]; 9221394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 9235d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt erraddr = (void *)fp->pc; 924b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 925b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(KERN_NOTICE "return address: [0x%p]; contents of:", erraddr); 926b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 927b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz for (addr = (unsigned short *)((unsigned long)erraddr & ~0xF) - 0x10; 928b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr < (unsigned short *)((unsigned long)erraddr & ~0xF) + 0x10; 929b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz addr++) { 930b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (!((unsigned long)addr & 0xF)) 931b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk("\n" KERN_NOTICE "0x%p: ", addr); 932b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 933f09630bff51daaf427968c61c0f2370c64148e06Robin Getz if (get_instruction(&val, addr)) { 934b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val = 0; 935b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "????"); 936b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 937b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sprintf(buf, "%04x", val); 938b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 939b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr == erraddr) { 940b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk("[%s]", buf); 941b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz err = val; 942b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } else 943b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(" %s ", buf); 944b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 945b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Do any previous instructions turn on interrupts? */ 946b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (addr <= erraddr && /* in the past */ 947b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz ((val >= 0x0040 && val <= 0x0047) || /* STI instruction */ 948b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz val == 0x017b)) /* [SP++] = RETI */ 949b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz sti = 1; 950b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 951b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 952b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk("\n"); 953b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz 954b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* Hardware error interrupts can be deferred */ 955b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if (unlikely(sti && (fp->seqstat & SEQSTAT_EXCAUSE) == VEC_HWERR && 956b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz oops_in_progress)){ 957b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(KERN_NOTICE "Looks like this was a deferred error - sorry\n"); 9581394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifndef CONFIG_DEBUG_HWERR 959b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(KERN_NOTICE "The remaining message may be meaningless\n" 960b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz KERN_NOTICE "You should enable CONFIG_DEBUG_HWERR to get a" 961b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz " better idea where it came from\n"); 962b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#else 963b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* If we are handling only one peripheral interrupt 964b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * and current mm and pid are valid, and the last error 965b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * was in that user space process's text area 966b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz * print it out - because that is where the problem exists 967b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz */ 968b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((!(((fp)->ipend & ~0x30) & (((fp)->ipend & ~0x30) - 1))) && 969b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (current->pid && current->mm)) { 970b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz /* And the last RETI points to the current userspace context */ 971b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz if ((fp + 1)->pc >= current->mm->start_code && 972b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz (fp + 1)->pc <= current->mm->end_code) { 973b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(KERN_NOTICE "It might be better to look around here : \n"); 974b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(KERN_NOTICE "-------------------------------------------\n"); 975b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz show_regs(fp + 1); 976b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz printk(KERN_NOTICE "-------------------------------------------\n"); 977b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 9781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 979b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz#endif 980b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz } 98149dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger} 98249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger 98349dce9124b41984bf1e918847bc17929c2e8f80fMike Frysingervoid show_regs(struct pt_regs *fp) 98449dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger{ 98549dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger char buf [150]; 986d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz struct irqaction *action; 987d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz unsigned int i; 988d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz unsigned long flags; 989226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 990aee3a29240ad167ad7875d859506d8bb90431c70Robin Getz printk(KERN_NOTICE "\n" KERN_NOTICE "SEQUENCER STATUS:\t\t%s\n", print_tainted()); 991226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " SEQSTAT: %08lx IPEND: %04lx SYSCFG: %04lx\n", 992226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz (long)fp->seqstat, fp->ipend, fp->syscfg); 99313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE " HWERRCAUSE: 0x%lx\n", 99413fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz (fp->seqstat & SEQSTAT_HWERRCAUSE) >> 14); 99513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE " EXCAUSE : 0x%lx\n", 99613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz fp->seqstat & SEQSTAT_EXCAUSE); 997d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (i = 6; i <= 15 ; i++) { 998d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & (1 << i)) { 999d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, bfin_read32(EVT0 + 4*i)); 1000d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz printk(KERN_NOTICE " physical IVG%i asserted : %s\n", i, buf); 1001d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1002d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1003d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1004d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz /* if no interrupts are going off, don't print this out */ 1005d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (fp->ipend & ~0x3F) { 1006d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (i = 0; i < (NR_IRQS - 1); i++) { 1007d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz spin_lock_irqsave(&irq_desc[i].lock, flags); 1008d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz action = irq_desc[i].action; 1009d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz if (!action) 1010d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz goto unlock; 1011d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz 1012d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 1013d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz printk(KERN_NOTICE " logical irq %3d mapped : %s", i, buf); 1014d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz for (action = action->next; action; action = action->next) { 1015d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz decode_address(buf, (unsigned int)action->handler); 1016d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz printk(", %s", buf); 1017d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1018d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz printk("\n"); 1019d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getzunlock: 1020d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz spin_unlock_irqrestore(&irq_desc[i].lock, flags); 1021d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1022d8f66c8c1ea8e948483ee4739ad91120f5f7de51Robin Getz } 1023c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 1024226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rete); 1025226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " RETE: %s\n", buf); 1026226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retn); 1027226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " RETN: %s\n", buf); 1028226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->retx); 1029226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " RETX: %s\n", buf); 1030226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz decode_address(buf, fp->rets); 1031226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " RETS: %s\n", buf); 103249dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger decode_address(buf, fp->pc); 103313fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz printk(KERN_NOTICE " PC : %s\n", buf); 1034c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 103513fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz if (((long)fp->seqstat & SEQSTAT_EXCAUSE) && 103613fe24f37df20e580a5a364e67ec8cf3219d8f8cRobin Getz (((long)fp->seqstat & SEQSTAT_EXCAUSE) != VEC_HWERR)) { 10375d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt decode_address(buf, saved_dcplb_fault_addr); 1038226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "DCPLB_FAULT_ADDR: %s\n", buf); 10395d750b9e4f6ca7d366b4954517ff8be9ee07e1bfBernd Schmidt decode_address(buf, saved_icplb_fault_addr); 1040226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "ICPLB_FAULT_ADDR: %s\n", buf); 1041226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz } 1042226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 1043226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "\n" KERN_NOTICE "PROCESSOR STATE:\n"); 1044226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " R0 : %08lx R1 : %08lx R2 : %08lx R3 : %08lx\n", 1045c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r0, fp->r1, fp->r2, fp->r3); 1046226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " R4 : %08lx R5 : %08lx R6 : %08lx R7 : %08lx\n", 1047c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->r4, fp->r5, fp->r6, fp->r7); 1048226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " P0 : %08lx P1 : %08lx P2 : %08lx P3 : %08lx\n", 1049c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->p0, fp->p1, fp->p2, fp->p3); 1050226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " P4 : %08lx P5 : %08lx FP : %08lx SP : %08lx\n", 1051226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->p4, fp->p5, fp->fp, (long)fp); 1052226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " LB0: %08lx LT0: %08lx LC0: %08lx\n", 1053c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb0, fp->lt0, fp->lc0); 1054226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " LB1: %08lx LT1: %08lx LC1: %08lx\n", 1055c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->lb1, fp->lt1, fp->lc1); 1056226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " B0 : %08lx L0 : %08lx M0 : %08lx I0 : %08lx\n", 1057c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b0, fp->l0, fp->m0, fp->i0); 1058226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " B1 : %08lx L1 : %08lx M1 : %08lx I1 : %08lx\n", 1059c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b1, fp->l1, fp->m1, fp->i1); 1060226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " B2 : %08lx L2 : %08lx M2 : %08lx I2 : %08lx\n", 1061c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b2, fp->l2, fp->m2, fp->i2); 1062226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE " B3 : %08lx L3 : %08lx M3 : %08lx I3 : %08lx\n", 1063c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz fp->b3, fp->l3, fp->m3, fp->i3); 1064226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "A0.w: %08lx A0.x: %08lx A1.w: %08lx A1.x: %08lx\n", 1065226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz fp->a0w, fp->a0x, fp->a1w, fp->a1x); 1066c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz 1067226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "USP : %08lx ASTAT: %08lx\n", 1068c5d88d9e2566e7ddccb0e001446b9a39882560a3Robin Getz rdusp(), fp->astat); 10691394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1070226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz printk(KERN_NOTICE "\n"); 10711394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 10721394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 10731394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#ifdef CONFIG_SYS_BFIN_SPINLOCK_L1 10741394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock)__attribute__((l1_text)); 10751394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu#endif 10761394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 10771394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuasmlinkage int sys_bfin_spinlock(int *spinlock) 10781394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 10791394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int ret = 0; 10801394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu int tmp = 0; 10811394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 10821394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu local_irq_disable(); 10831394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu ret = get_user(tmp, spinlock); 10841394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (ret == 0) { 10851394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu if (tmp) 10861394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu ret = 1; 10871394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu tmp = 1; 10881394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu put_user(tmp, spinlock); 10891394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 10901394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu local_irq_enable(); 10911394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return ret; 10921394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 10931394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 10941ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_request_exception(unsigned int exception, void (*handler)(void)) 10951ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 10961ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 10971ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 10981ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 10991ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 11001ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11011ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 11021ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11031ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != ex_replaceable) 11041ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 11051ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11061ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = handler; 11071ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11081ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 11091ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 11101ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_request_exception); 11111ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11121ffe6646babf8471714e649849ec2c9662bf410cMike Frysingerint bfin_free_exception(unsigned int exception, void (*handler)(void)) 11131ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger{ 11141ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger void (*curr_handler)(void); 11151ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11161ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (exception > 0x3F) 11171ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EINVAL; 11181ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11191ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger curr_handler = ex_table[exception]; 11201ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11211ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger if (curr_handler != handler) 11221ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return -EBUSY; 11231ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11241ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger ex_table[exception] = ex_replaceable; 11251ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11261ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger return 0; 11271ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger} 11281ffe6646babf8471714e649849ec2c9662bf410cMike FrysingerEXPORT_SYMBOL(bfin_free_exception); 11291ffe6646babf8471714e649849ec2c9662bf410cMike Frysinger 11301394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wuvoid panic_cplb_error(int cplb_panic, struct pt_regs *fp) 11311394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu{ 11321394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu switch (cplb_panic) { 11331394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_UNLOCKED: 11341394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "All CPLBs are locked\n"); 11351394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 11361394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_PROT_VIOL: 11371394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 11381394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_NO_ADDR_MATCH: 11391394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu return; 11401394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu case CPLB_UNKNOWN_ERR: 11411394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu printk(KERN_EMERG "Unknown CPLB Exception\n"); 11421394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu break; 11431394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu } 11441394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu 1145226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz oops_in_progress = 1; 1146226eb1ef523a33c66193bc319a92c647e47311d4Robin Getz 114749dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger dump_bfin_process(fp); 1148b03b08ba9c7235861adf4dde712dade0bb756fe0Robin Getz dump_bfin_mem(fp); 114949dce9124b41984bf1e918847bc17929c2e8f80fMike Frysinger show_regs(fp); 11501394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu dump_stack(); 11511394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu panic("Unrecoverable event\n"); 11521394f03221790a988afc3e4b3cb79f2e477246a9Bryan Wu} 1153