patch-2.1.48 linux/arch/ppc/kernel/traps.c

Next file: linux/arch/ppc/kernel/usercpy.c
Previous file: linux/arch/ppc/kernel/time.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.47/linux/arch/ppc/kernel/traps.c linux/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 @@
 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
+	_exception(SIGTRAP, regs);
+}
 
-  /* 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;		
+void
+RunModeException(struct pt_regs *regs)
+{
+	_exception(SIGTRAP, regs);	
 }
 
-AlignmentException(struct pt_regs *regs)
+ProgramCheckException(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);	
+	if (current->flags & PF_PTRACED)
+		_exception(SIGTRAP, regs);
+	else
+		_exception(SIGILL, regs);
 }
 
+SingleStepException(struct pt_regs *regs)
+{
+	regs->msr &= ~MSR_SE;  /* Turn off 'trace' bit */
+	_exception(SIGTRAP, 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)
+AlignmentException(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);
-}
-
-dump_regs(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;
 	}
 }
-

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov