2005-04-16 15:20:36 -07:00
/*
* linux / arch / h8300 / boot / traps . c - - general exception handling code
* H8 / 300 support Yoshinori Sato < ysato @ users . sourceforge . jp >
*
* Cloned from Linux / m68k .
*
* No original Copyright holder listed ,
2007-10-20 01:10:46 +02:00
* Probable original ( C ) Roman Zippel ( assigned DJD , 1999 )
2005-04-16 15:20:36 -07:00
*
* Copyright 1999 - 2000 D . Jeff Dionne , < jeff @ rt - control . com >
*
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file COPYING in the main directory of this archive
* for more details .
*/
# include <linux/types.h>
# include <linux/sched.h>
# include <linux/kernel.h>
# include <linux/errno.h>
# include <linux/init.h>
# include <linux/module.h>
2008-10-15 22:01:17 -07:00
# include <linux/bug.h>
2005-04-16 15:20:36 -07:00
# include <asm/system.h>
# include <asm/irq.h>
# include <asm/traps.h>
# include <asm/page.h>
2008-10-15 22:01:17 -07:00
static DEFINE_SPINLOCK ( die_lock ) ;
2005-04-16 15:20:36 -07:00
/*
* this must be called very early as the kernel might
* use some instruction that are emulated on the 060
*/
void __init base_trap_init ( void )
{
}
void __init trap_init ( void )
{
}
asmlinkage void set_esp0 ( unsigned long ssp )
{
current - > thread . esp0 = ssp ;
}
/*
* Generic dumping code . Used for panic and debug .
*/
static void dump ( struct pt_regs * fp )
{
unsigned long * sp ;
unsigned char * tp ;
int i ;
printk ( " \n CURRENT PROCESS: \n \n " ) ;
printk ( " COMM=%s PID=%d \n " , current - > comm , current - > pid ) ;
if ( current - > mm ) {
printk ( " TEXT=%08x-%08x DATA=%08x-%08x BSS=%08x-%08x \n " ,
( int ) current - > mm - > start_code ,
( int ) current - > mm - > end_code ,
( int ) current - > mm - > start_data ,
( int ) current - > mm - > end_data ,
( int ) current - > mm - > end_data ,
( int ) current - > mm - > brk ) ;
printk ( " USER-STACK=%08x KERNEL-STACK=%08lx \n \n " ,
( int ) current - > mm - > start_stack ,
( int ) PAGE_SIZE + ( unsigned long ) current ) ;
}
show_regs ( fp ) ;
printk ( " \n CODE: " ) ;
tp = ( ( unsigned char * ) fp - > pc ) - 0x20 ;
for ( sp = ( unsigned long * ) tp , i = 0 ; ( i < 0x40 ) ; i + = 4 ) {
if ( ( i % 0x10 ) = = 0 )
printk ( " \n %08x: " , ( int ) ( tp + i ) ) ;
printk ( " %08x " , ( int ) * sp + + ) ;
}
printk ( " \n " ) ;
printk ( " \n KERNEL STACK: " ) ;
tp = ( ( unsigned char * ) fp ) - 0x40 ;
for ( sp = ( unsigned long * ) tp , i = 0 ; ( i < 0xc0 ) ; i + = 4 ) {
if ( ( i % 0x10 ) = = 0 )
printk ( " \n %08x: " , ( int ) ( tp + i ) ) ;
printk ( " %08x " , ( int ) * sp + + ) ;
}
printk ( " \n " ) ;
if ( STACK_MAGIC ! = * ( unsigned long * ) ( ( unsigned long ) current + PAGE_SIZE ) )
printk ( " (Possibly corrupted stack page??) \n " ) ;
printk ( " \n \n " ) ;
}
2010-08-31 16:52:16 +01:00
void die ( const char * str , struct pt_regs * fp , unsigned long err )
2005-04-16 15:20:36 -07:00
{
2008-10-15 22:01:17 -07:00
static int diecount ;
2005-04-16 15:20:36 -07:00
2008-10-15 22:01:17 -07:00
oops_enter ( ) ;
2005-04-16 15:20:36 -07:00
2008-10-15 22:01:17 -07:00
console_verbose ( ) ;
spin_lock_irq ( & die_lock ) ;
report_bug ( fp - > pc , fp ) ;
printk ( KERN_EMERG " %s: %04lx [#%d] " , str , err & 0xffff , + + diecount ) ;
2005-04-16 15:20:36 -07:00
dump ( fp ) ;
2008-10-15 22:01:17 -07:00
spin_unlock_irq ( & die_lock ) ;
2005-04-16 15:20:36 -07:00
do_exit ( SIGSEGV ) ;
}
extern char _start , _etext ;
# define check_kernel_text(addr) \
( ( addr > = ( unsigned long ) ( & _start ) ) & & \
( addr < ( unsigned long ) ( & _etext ) ) )
static int kstack_depth_to_print = 24 ;
void show_stack ( struct task_struct * task , unsigned long * esp )
{
unsigned long * stack , addr ;
int i ;
if ( esp = = NULL )
esp = ( unsigned long * ) & esp ;
stack = esp ;
printk ( " Stack from %08lx: " , ( unsigned long ) stack ) ;
for ( i = 0 ; i < kstack_depth_to_print ; i + + ) {
if ( ( ( unsigned long ) stack & ( THREAD_SIZE - 1 ) ) = = 0 )
break ;
if ( i % 8 = = 0 )
printk ( " \n " ) ;
printk ( " %08lx " , * stack + + ) ;
}
printk ( " \n Call Trace: " ) ;
i = 0 ;
stack = esp ;
2007-06-01 00:47:01 -07:00
while ( ( ( unsigned long ) stack & ( THREAD_SIZE - 1 ) ) ! = 0 ) {
2005-04-16 15:20:36 -07:00
addr = * stack + + ;
/*
* If the address is either in the text segment of the
* kernel , or in the region which contains vmalloc ' ed
* memory , it * may * be the address of a calling
* routine ; if so , print it so that someone tracing
* down the cause of the crash will be able to figure
* out the call path that was taken .
*/
if ( check_kernel_text ( addr ) ) {
if ( i % 4 = = 0 )
printk ( " \n " ) ;
printk ( " [<%08lx>] " , addr ) ;
i + + ;
}
}
printk ( " \n " ) ;
}
void show_trace_task ( struct task_struct * tsk )
{
show_stack ( tsk , ( unsigned long * ) tsk - > thread . esp0 ) ;
}
void dump_stack ( void )
{
show_stack ( NULL , NULL ) ;
}
EXPORT_SYMBOL ( dump_stack ) ;