1/* 2 * linux/arch/h8300/boot/traps.c -- general exception handling code 3 * H8/300 support Yoshinori Sato <ysato@users.sourceforge.jp> 4 * 5 * Cloned from Linux/m68k. 6 * 7 * No original Copyright holder listed, 8 * Probable original (C) Roman Zippel (assigned DJD, 1999) 9 * 10 * Copyright 1999-2000 D. Jeff Dionne, <jeff@rt-control.com> 11 * 12 * This file is subject to the terms and conditions of the GNU General Public 13 * License. See the file COPYING in the main directory of this archive 14 * for more details. 15 */ 16 17#include <linux/types.h> 18#include <linux/sched.h> 19#include <linux/kernel.h> 20#include <linux/errno.h> 21#include <linux/init.h> 22#include <linux/module.h> 23#include <linux/bug.h> 24 25#include <asm/system.h> 26#include <asm/irq.h> 27#include <asm/traps.h> 28#include <asm/page.h> 29 30static DEFINE_SPINLOCK(die_lock); 31 32/* 33 * this must be called very early as the kernel might 34 * use some instruction that are emulated on the 060 35 */ 36 37void __init base_trap_init(void) 38{ 39} 40 41void __init trap_init (void) 42{ 43} 44 45asmlinkage void set_esp0 (unsigned long ssp) 46{ 47 current->thread.esp0 = ssp; 48} 49 50/* 51 * Generic dumping code. Used for panic and debug. 52 */ 53 54static void dump(struct pt_regs *fp) 55{ 56 unsigned long *sp; 57 unsigned char *tp; 58 int i; 59 60 printk("\nCURRENT PROCESS:\n\n"); 61 printk("COMM=%s PID=%d\n", current->comm, current->pid); 62 if (current->mm) { 63 printk("TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x\n", 64 (int) current->mm->start_code, 65 (int) current->mm->end_code, 66 (int) current->mm->start_data, 67 (int) current->mm->end_data, 68 (int) current->mm->end_data, 69 (int) current->mm->brk); 70 printk("USER-STACK=%08x KERNEL-STACK=%08lx\n\n", 71 (int) current->mm->start_stack, 72 (int) PAGE_SIZE+(unsigned long)current); 73 } 74 75 show_regs(fp); 76 printk("\nCODE:"); 77 tp = ((unsigned char *) fp->pc) - 0x20; 78 for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { 79 if ((i % 0x10) == 0) 80 printk("\n%08x: ", (int) (tp + i)); 81 printk("%08x ", (int) *sp++); 82 } 83 printk("\n"); 84 85 printk("\nKERNEL STACK:"); 86 tp = ((unsigned char *) fp) - 0x40; 87 for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { 88 if ((i % 0x10) == 0) 89 printk("\n%08x: ", (int) (tp + i)); 90 printk("%08x ", (int) *sp++); 91 } 92 printk("\n"); 93 if (STACK_MAGIC != *(unsigned long *)((unsigned long)current+PAGE_SIZE)) 94 printk("(Possibly corrupted stack page??)\n"); 95 96 printk("\n\n"); 97} 98 99void die(const char *str, struct pt_regs *fp, unsigned long err) 100{ 101 static int diecount; 102 103 oops_enter(); 104 105 console_verbose(); 106 spin_lock_irq(&die_lock); 107 report_bug(fp->pc, fp); 108 printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++diecount); 109 dump(fp); 110 111 spin_unlock_irq(&die_lock); 112 do_exit(SIGSEGV); 113} 114 115extern char _start, _etext; 116#define check_kernel_text(addr) \ 117 ((addr >= (unsigned long)(&_start)) && \ 118 (addr < (unsigned long)(&_etext))) 119 120static int kstack_depth_to_print = 24; 121 122void show_stack(struct task_struct *task, unsigned long *esp) 123{ 124 unsigned long *stack, addr; 125 int i; 126 127 if (esp == NULL) 128 esp = (unsigned long *) &esp; 129 130 stack = esp; 131 132 printk("Stack from %08lx:", (unsigned long)stack); 133 for (i = 0; i < kstack_depth_to_print; i++) { 134 if (((unsigned long)stack & (THREAD_SIZE - 1)) == 0) 135 break; 136 if (i % 8 == 0) 137 printk("\n "); 138 printk(" %08lx", *stack++); 139 } 140 141 printk("\nCall Trace:"); 142 i = 0; 143 stack = esp; 144 while (((unsigned long)stack & (THREAD_SIZE - 1)) != 0) { 145 addr = *stack++; 146 /* 147 * If the address is either in the text segment of the 148 * kernel, or in the region which contains vmalloc'ed 149 * memory, it *may* be the address of a calling 150 * routine; if so, print it so that someone tracing 151 * down the cause of the crash will be able to figure 152 * out the call path that was taken. 153 */ 154 if (check_kernel_text(addr)) { 155 if (i % 4 == 0) 156 printk("\n "); 157 printk(" [<%08lx>]", addr); 158 i++; 159 } 160 } 161 printk("\n"); 162} 163 164void show_trace_task(struct task_struct *tsk) 165{ 166 show_stack(tsk,(unsigned long *)tsk->thread.esp0); 167} 168 169void dump_stack(void) 170{ 171 show_stack(NULL,NULL); 172} 173 174EXPORT_SYMBOL(dump_stack); 175