traps.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /* $Id: traps.c,v 1.4 2005/04/24 18:47:55 starvik Exp $
  2. *
  3. * linux/arch/cris/arch-v10/traps.c
  4. *
  5. * Heler functions for trap handlers
  6. *
  7. * Copyright (C) 2000-2002 Axis Communications AB
  8. *
  9. * Authors: Bjorn Wesen
  10. * Hans-Peter Nilsson
  11. *
  12. */
  13. #include <linux/ptrace.h>
  14. #include <asm/uaccess.h>
  15. #include <asm/arch/sv_addr_ag.h>
  16. extern int raw_printk(const char *fmt, ...);
  17. void
  18. show_registers(struct pt_regs * regs)
  19. {
  20. /* We either use rdusp() - the USP register, which might not
  21. correspond to the current process for all cases we're called,
  22. or we use the current->thread.usp, which is not up to date for
  23. the current process. Experience shows we want the USP
  24. register. */
  25. unsigned long usp = rdusp();
  26. raw_printk("IRP: %08lx SRP: %08lx DCCR: %08lx USP: %08lx MOF: %08lx\n",
  27. regs->irp, regs->srp, regs->dccr, usp, regs->mof );
  28. raw_printk(" r0: %08lx r1: %08lx r2: %08lx r3: %08lx\n",
  29. regs->r0, regs->r1, regs->r2, regs->r3);
  30. raw_printk(" r4: %08lx r5: %08lx r6: %08lx r7: %08lx\n",
  31. regs->r4, regs->r5, regs->r6, regs->r7);
  32. raw_printk(" r8: %08lx r9: %08lx r10: %08lx r11: %08lx\n",
  33. regs->r8, regs->r9, regs->r10, regs->r11);
  34. raw_printk("r12: %08lx r13: %08lx oR10: %08lx sp: %08lx\n",
  35. regs->r12, regs->r13, regs->orig_r10, regs);
  36. raw_printk("R_MMU_CAUSE: %08lx\n", (unsigned long)*R_MMU_CAUSE);
  37. raw_printk("Process %s (pid: %d, stackpage=%08lx)\n",
  38. current->comm, current->pid, (unsigned long)current);
  39. /*
  40. * When in-kernel, we also print out the stack and code at the
  41. * time of the fault..
  42. */
  43. if (! user_mode(regs)) {
  44. int i;
  45. show_stack(NULL, (unsigned long*)usp);
  46. /* Dump kernel stack if the previous dump wasn't one. */
  47. if (usp != 0)
  48. show_stack (NULL, NULL);
  49. raw_printk("\nCode: ");
  50. if(regs->irp < PAGE_OFFSET)
  51. goto bad;
  52. /* Often enough the value at regs->irp does not point to
  53. the interesting instruction, which is most often the
  54. _previous_ instruction. So we dump at an offset large
  55. enough that instruction decoding should be in sync at
  56. the interesting point, but small enough to fit on a row
  57. (sort of). We point out the regs->irp location in a
  58. ksymoops-friendly way by wrapping the byte for that
  59. address in parentheses. */
  60. for(i = -12; i < 12; i++)
  61. {
  62. unsigned char c;
  63. if(__get_user(c, &((unsigned char*)regs->irp)[i])) {
  64. bad:
  65. raw_printk(" Bad IP value.");
  66. break;
  67. }
  68. if (i == 0)
  69. raw_printk("(%02x) ", c);
  70. else
  71. raw_printk("%02x ", c);
  72. }
  73. raw_printk("\n");
  74. }
  75. }
  76. /* Called from entry.S when the watchdog has bitten
  77. * We print out something resembling an oops dump, and if
  78. * we have the nice doggy development flag set, we halt here
  79. * instead of rebooting.
  80. */
  81. extern void reset_watchdog(void);
  82. extern void stop_watchdog(void);
  83. void
  84. watchdog_bite_hook(struct pt_regs *regs)
  85. {
  86. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  87. local_irq_disable();
  88. stop_watchdog();
  89. show_registers(regs);
  90. while(1) /* nothing */;
  91. #else
  92. show_registers(regs);
  93. #endif
  94. }
  95. /* This is normally the 'Oops' routine */
  96. void
  97. die_if_kernel(const char * str, struct pt_regs * regs, long err)
  98. {
  99. if(user_mode(regs))
  100. return;
  101. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  102. /* This printout might take too long and trigger the
  103. * watchdog normally. If we're in the nice doggy
  104. * development mode, stop the watchdog during printout.
  105. */
  106. stop_watchdog();
  107. #endif
  108. raw_printk("%s: %04lx\n", str, err & 0xffff);
  109. show_registers(regs);
  110. #ifdef CONFIG_ETRAX_WATCHDOG_NICE_DOGGY
  111. reset_watchdog();
  112. #endif
  113. do_exit(SIGSEGV);
  114. }
  115. void arch_enable_nmi(void)
  116. {
  117. asm volatile("setf m");
  118. }