summaryrefslogtreecommitdiffstats
path: root/arch/ppc/kernel/traps.c
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
committerMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
commite2819e52a162873ff5061de81bb749831bdb5de9 (patch)
tree6067ea700202750ba335a423696f2972700e5f76 /arch/ppc/kernel/traps.c
parent17a005074429bbf143e40401f405ae4363e56828 (diff)
Merge to 2.1.38.
IMPORTANT NOTE: I could not figure out what information is the one that should be used for the following files (ie, those that were in our tree, or those that came from Linus' patch), please, check these: include/asm-mips/jazz.h include/asm-mips/jazzdma.h include/asm-mips/ioctls.h
Diffstat (limited to 'arch/ppc/kernel/traps.c')
-rw-r--r--arch/ppc/kernel/traps.c154
1 files changed, 65 insertions, 89 deletions
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index a637e0acb..84ce1c5ca 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -20,14 +20,14 @@
#include <linux/malloc.h>
#include <linux/user.h>
#include <linux/a.out.h>
+#include <linux/interrupt.h>
+#include <linux/config.h>
#include <asm/pgtable.h>
#include <asm/segment.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/ppc_machine.h>
-
/*
* Trap & Exception support
*/
@@ -40,122 +40,98 @@ trap_init(void)
void
_exception(int signr, struct pt_regs *regs)
{
- /* dump_regs(regs);*/
- force_sig(signr, current);
- if (!user_mode(regs))
- {
- printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
- while (1) ;
- }
+ if (!user_mode(regs))
+ {
+ show_regs(regs);
+ print_backtrace(regs->gpr[1]);
+ panic("Exception in kernel pc %x signal %d",regs->nip,signr);
+ }
+ force_sig(signr, current);
}
MachineCheckException(struct pt_regs *regs)
{
- printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
- _exception(SIGSEGV, regs);
-}
-
-ProgramCheckException(struct pt_regs *regs)
-{
-#if 0
- printk("Program check at PC: %x[%x], SR: %x\n",
- regs->nip, va_to_phys(regs->nip), regs->msr);
- #endif
- if (current->flags & PF_PTRACED)
- {
- _exception(SIGTRAP, regs);
- } else
- {
- _exception(SIGILL, regs);
- }
+ if ( !user_mode(regs) )
+ {
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from msr): ");
+ printk("regs %08x ",regs);
+ switch( regs->msr & 0x0000F000)
+ {
+ case (1<<12) :
+ printk("Machine check signal - probably due to mm fault\n"
+ "with mmu off\n");
+ break;
+ case (1<<13) :
+ printk("Transfer error ack signal\n");
+ break;
+ case (1<<14) :
+ printk("Data parity signal\n");
+ break;
+ case (1<<15) :
+ printk("Address parity signal\n");
+ break;
+ default:
+ printk("Unknown values in msr\n");
+ }
+ show_regs(regs);
+ print_backtrace(regs->gpr[1]);
+ panic("");
+ }
+ _exception(SIGSEGV, regs);
}
-SingleStepException(struct pt_regs *regs)
+void
+UnknownException(struct pt_regs *regs)
{
- regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
+ printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
+ regs->nip, regs->msr, regs->trap);
_exception(SIGTRAP, regs);
}
-FloatingPointCheckException(struct pt_regs *regs)
+void
+InstructionBreakpoint(struct pt_regs *regs)
{
- /* if fpu already on -- then exception was generated by an error */
- if ( (unsigned long)(regs->msr) & (unsigned long)MSR_FP )
- {
- _exception(SIGFPE, regs);
- return 0;
- }
-
-#if 0
- printk("fpu off -- turning on: %s pc %x fpscr %x msr %x ksp %x r1 %x\n",
- current->comm,regs->nip,regs->fpcsr,regs->msr,regs,regs->gpr[1]);
+#ifdef CONFIG_XMON
+ if (xmon_iabr_match(regs))
+ return;
#endif
-
- /* if the fpu is off then turn it on and return */
- regs->msr |= MSR_FP;
- current->tss.fp_used++;
- /* tells return_from_int to restore fp regs since fp was turned on
- see head.S -- Cort */
- return MSR_FP;
+ _exception(SIGTRAP, regs);
}
-AlignmentException(struct pt_regs *regs)
+void
+RunModeException(struct pt_regs *regs)
{
-/* printk("Alignment error at PC: %x, SR: %x\n", regs->nip, regs->msr);
- dump_regs(regs);
- printk("Alignment error at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/
- _exception(SIGBUS, regs);
+ _exception(SIGTRAP, regs);
}
+ProgramCheckException(struct pt_regs *regs)
+{
+ if (current->flags & PF_PTRACED)
+ _exception(SIGTRAP, regs);
+ else
+ _exception(SIGILL, regs);
+}
-/* see CHECK_STACK macro in head.S for argument definitions */
-bad_stack(unsigned int r3, unsigned int r4, unsigned int r5, unsigned int r6)
+SingleStepException(struct pt_regs *regs)
{
- /* r6 (was r1) kernel stack pointer */
- /* r5 (was r2) kernel stack page */
- /* r4 kernel stack magic */
- /* r3 stack magic or ksp masked to page boundary */
- printk("bad_stack(): Kernel stack bad.\n");
- printk("ksp %x kpage %x stack magic %x r3 %x\n",
- r6,r5,r4,r3);
- printk("current: %s/%d\n",
- current->comm,current->pid);
- while(1);
+ regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */
+ _exception(SIGTRAP, regs);
}
-dump_regs(struct pt_regs *regs)
+AlignmentException(struct pt_regs *regs)
{
- int i;
- printk("NIP: %08X, MSR: %08X, XER: %08X, LR: %08X, FRAME: %08X\n", regs->nip, regs->msr, regs->xer, regs->link, regs);
-#if 0
- printk("HASH = %08X/%08X, MISS = %08X/%08X, CMP = %08X/%08X\n", regs->hash1, regs->hash2, regs->imiss, regs->dmiss, regs->icmp, regs->dcmp);
-#endif
- printk("TASK = %x[%d] '%s'\n", current, current->pid, current->comm);
- for (i = 0; i < 32; i++)
- {
- if ((i % 8) == 0)
- {
- printk("GPR%02d: ", i);
- }
- printk("%08X ", regs->gpr[i]);
- if ((i % 8) == 7)
- {
- printk("\n");
- }
- }
-#if 0
- if (regs->nip >= 0x1000)
- dump_buf(regs->nip-32, 64);
- dump_buf((regs->nip&0x0FFFFFFF)|KERNELBASE, 32);
-#endif
+ _exception(SIGBUS, regs);
}
trace_syscall(struct pt_regs *regs)
{
static int count;
- printk("Task: %08X(%d), PC: %08X/%08X, Syscall: %3d, Result: %s%d\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->ccr&0x10000000?"Error=":"", regs->gpr[3]);
+ printk("Task: %08X(%d), PC: %08X/%08X, Syscall: %3d, Result: %s%d\n",
+ current, current->pid, regs->nip, regs->link, regs->gpr[0],
+ regs->ccr&0x10000000?"Error=":"", regs->gpr[3]);
if (++count == 20)
{
count = 0;
}
}
-