-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 84934 b: refs/heads/master c: 1e4cc2c h: refs/heads/master v: v3
- Loading branch information
Jesper Nilsson
committed
Feb 8, 2008
1 parent
a16a1ed
commit 41e67e1
Showing
2 changed files
with
96 additions
and
104 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: 32872b203b542f0696b6af4db992a3c320de57e1 | ||
refs/heads/master: 1e4cc2c8c7cb54ce0e5a7002c68aca9e89607117 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,138 +1,130 @@ | ||
/* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $ | ||
/* | ||
* Helper functions for trap handlers | ||
* | ||
* linux/arch/cris/arch-v10/traps.c | ||
* Copyright (C) 2000-2007, Axis Communications AB. | ||
* | ||
* Heler functions for trap handlers | ||
* | ||
* Copyright (C) 2000-2002 Axis Communications AB | ||
* | ||
* Authors: Bjorn Wesen | ||
* Hans-Peter Nilsson | ||
* Authors: Bjorn Wesen | ||
* Hans-Peter Nilsson | ||
* | ||
*/ | ||
|
||
#include <linux/ptrace.h> | ||
#include <asm/uaccess.h> | ||
#include <asm/arch/sv_addr_ag.h> | ||
|
||
extern int raw_printk(const char *fmt, ...); | ||
|
||
void | ||
show_registers(struct pt_regs * regs) | ||
void | ||
show_registers(struct pt_regs *regs) | ||
{ | ||
/* We either use rdusp() - the USP register, which might not | ||
correspond to the current process for all cases we're called, | ||
or we use the current->thread.usp, which is not up to date for | ||
the current process. Experience shows we want the USP | ||
register. */ | ||
/* | ||
* It's possible to use either the USP register or current->thread.usp. | ||
* USP might not correspond to the current process for all cases this | ||
* function is called, and current->thread.usp isn't up to date for the | ||
* current process. Experience shows that using USP is the way to go. | ||
*/ | ||
unsigned long usp = rdusp(); | ||
|
||
raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", | ||
regs->irp, regs->srp, regs->dccr, usp, regs->mof ); | ||
raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", | ||
printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n", | ||
regs->irp, regs->srp, regs->dccr, usp, regs->mof); | ||
|
||
printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n", | ||
regs->r0, regs->r1, regs->r2, regs->r3); | ||
raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", | ||
|
||
printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n", | ||
regs->r4, regs->r5, regs->r6, regs->r7); | ||
raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", | ||
|
||
printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n", | ||
regs->r8, regs->r9, regs->r10, regs->r11); | ||
raw_printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n", | ||
regs->r12, regs->r13, regs->orig_r10, regs); | ||
raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); | ||
raw_printk("Process %s (pid: %d, stackpage=%08lx)\n", | ||
|
||
printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n", | ||
regs->r12, regs->r13, regs->orig_r10, (long unsigned)regs); | ||
|
||
printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE); | ||
|
||
printk("Process %s (pid: %d, stackpage=%08lx)\n", | ||
current->comm, current->pid, (unsigned long)current); | ||
|
||
/* | ||
* When in-kernel, we also print out the stack and code at the | ||
* time of the fault.. | ||
*/ | ||
if (! user_mode(regs)) { | ||
int i; | ||
* When in-kernel, we also print out the stack and code at the | ||
* time of the fault.. | ||
*/ | ||
if (!user_mode(regs)) { | ||
int i; | ||
|
||
show_stack(NULL, (unsigned long*)usp); | ||
show_stack(NULL, (unsigned long *)usp); | ||
|
||
/* Dump kernel stack if the previous dump wasn't one. */ | ||
/* | ||
* If the previous stack-dump wasn't a kernel one, dump the | ||
* kernel stack now. | ||
*/ | ||
if (usp != 0) | ||
show_stack (NULL, NULL); | ||
|
||
raw_printk("\nCode: "); | ||
if(regs->irp < PAGE_OFFSET) | ||
goto bad; | ||
|
||
/* Often enough the value at regs->irp does not point to | ||
the interesting instruction, which is most often the | ||
_previous_ instruction. So we dump at an offset large | ||
enough that instruction decoding should be in sync at | ||
the interesting point, but small enough to fit on a row | ||
(sort of). We point out the regs->irp location in a | ||
ksymoops-friendly way by wrapping the byte for that | ||
address in parentheses. */ | ||
for(i = -12; i < 12; i++) | ||
{ | ||
unsigned char c; | ||
if(__get_user(c, &((unsigned char*)regs->irp)[i])) { | ||
bad: | ||
raw_printk(" Bad IP value."); | ||
break; | ||
} | ||
show_stack(NULL, NULL); | ||
|
||
printk("\nCode: "); | ||
|
||
if (regs->irp < PAGE_OFFSET) | ||
goto bad_value; | ||
|
||
/* | ||
* Quite often the value at regs->irp doesn't point to the | ||
* interesting instruction, which often is the previous | ||
* instruction. So dump at an offset large enough that the | ||
* instruction decoding should be in sync at the interesting | ||
* point, but small enough to fit on a row. The regs->irp | ||
* location is pointed out in a ksymoops-friendly way by | ||
* wrapping the byte for that address in parenthesises. | ||
*/ | ||
for (i = -12; i < 12; i++) { | ||
unsigned char c; | ||
|
||
if (__get_user(c, &((unsigned char *)regs->irp)[i])) { | ||
bad_value: | ||
printk(" Bad IP value."); | ||
break; | ||
} | ||
|
||
if (i == 0) | ||
raw_printk("(%02x) ", c); | ||
printk("(%02x) ", c); | ||
else | ||
raw_printk("%02x ", c); | ||
} | ||
raw_printk("\n"); | ||
} | ||
printk("%02x ", c); | ||
} | ||
printk("\n"); | ||
} | ||
} | ||
|
||
/* Called from entry.S when the watchdog has bitten | ||
* We print out something resembling an oops dump, and if | ||
* we have the nice doggy development flag set, we halt here | ||
* instead of rebooting. | ||
*/ | ||
|
||
extern void reset_watchdog(void); | ||
extern void stop_watchdog(void); | ||
|
||
|
||
void | ||
watchdog_bite_hook(struct pt_regs *regs) | ||
arch_enable_nmi(void) | ||
{ | ||
#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | ||
local_irq_disable(); | ||
stop_watchdog(); | ||
show_registers(regs); | ||
while(1) /* nothing */; | ||
#else | ||
show_registers(regs); | ||
#endif | ||
asm volatile ("setf m"); | ||
} | ||
|
||
/* This is normally the 'Oops' routine */ | ||
void | ||
die_if_kernel(const char * str, struct pt_regs * regs, long err) | ||
extern void (*nmi_handler)(struct pt_regs *); | ||
void handle_nmi(struct pt_regs *regs) | ||
{ | ||
if(user_mode(regs)) | ||
return; | ||
|
||
#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | ||
/* This printout might take too long and trigger the | ||
* watchdog normally. If we're in the nice doggy | ||
* development mode, stop the watchdog during printout. | ||
*/ | ||
stop_watchdog(); | ||
#endif | ||
|
||
raw_printk("%s: %04lx\n", str, err & 0xffff); | ||
|
||
show_registers(regs); | ||
|
||
#ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY | ||
reset_watchdog(); | ||
#endif | ||
do_exit(SIGSEGV); | ||
if (nmi_handler) | ||
nmi_handler(regs); | ||
|
||
/* Wait until nmi is no longer active. (We enable NMI immediately after | ||
returning from this function, and we don't want it happening while | ||
exiting from the NMI interrupt handler.) */ | ||
while (*R_IRQ_MASK0_RD & IO_STATE(R_IRQ_MASK0_RD, nmi_pin, active)) | ||
; | ||
} | ||
|
||
void arch_enable_nmi(void) | ||
#ifdef CONFIG_DEBUG_BUGVERBOSE | ||
void | ||
handle_BUG(struct pt_regs *regs) | ||
{ | ||
asm volatile("setf m"); | ||
struct bug_frame f; | ||
unsigned char c; | ||
unsigned long irp = regs->irp; | ||
|
||
if (__copy_from_user(&f, (const void __user *)(irp - 8), sizeof f)) | ||
return; | ||
if (f.prefix != BUG_PREFIX || f.magic != BUG_MAGIC) | ||
return; | ||
if (__get_user(c, f.filename)) | ||
f.filename = "<bad filename>"; | ||
|
||
printk("kernel BUG at %s:%d!\n", f.filename, f.line); | ||
} | ||
#endif |