traps.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  4. *
  5. * Modified by Cort Dougan (cort@cs.nmt.edu)
  6. * and Paul Mackerras (paulus@cs.anu.edu.au)
  7. *
  8. * (C) Copyright 2000
  9. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  10. */
  11. /*
  12. * This file handles the architecture-dependent parts of hardware exceptions
  13. */
  14. #include <common.h>
  15. #include <asm/ptrace.h>
  16. #include <command.h>
  17. #include <init.h>
  18. #include <kgdb.h>
  19. #include <asm/processor.h>
  20. DECLARE_GLOBAL_DATA_PTR;
  21. /* Returns 0 if exception not found and fixup otherwise. */
  22. extern unsigned long search_exception_table(unsigned long);
  23. /*
  24. * End of addressable memory. This may be less than the actual
  25. * amount of memory on the system if we're unable to keep all
  26. * the memory mapped in.
  27. */
  28. #define END_OF_MEM (gd->ram_base + get_effective_memsize())
  29. /*
  30. * Trap & Exception support
  31. */
  32. static void print_backtrace(unsigned long *sp)
  33. {
  34. int cnt = 0;
  35. unsigned long i;
  36. printf("Call backtrace: ");
  37. while (sp) {
  38. if ((uint) sp > END_OF_MEM)
  39. break;
  40. i = sp[1];
  41. if (cnt++ % 7 == 0)
  42. printf("\n");
  43. printf("%08lX ", i);
  44. if (cnt > 32)
  45. break;
  46. sp = (unsigned long *)*sp;
  47. }
  48. printf("\n");
  49. }
  50. void show_regs(struct pt_regs *regs)
  51. {
  52. int i;
  53. printf("NIP: %08lX XER: %08lX LR: %08lX REGS:"
  54. " %p TRAP: %04lx DAR: %08lX\n",
  55. regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
  56. printf("MSR: %08lx EE: %01x PR: %01x FP:"
  57. " %01x ME: %01x IR/DR: %01x%01x\n",
  58. regs->msr, regs->msr & MSR_EE ? 1 : 0,
  59. regs->msr & MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,
  60. regs->msr & MSR_ME ? 1 : 0, regs->msr & MSR_IR ? 1 : 0,
  61. regs->msr & MSR_DR ? 1 : 0);
  62. printf("\n");
  63. for (i = 0; i < 32; i++) {
  64. if ((i % 8) == 0) {
  65. printf("GPR%02d: ", i);
  66. }
  67. printf("%08lX ", regs->gpr[i]);
  68. if ((i % 8) == 7) {
  69. printf("\n");
  70. }
  71. }
  72. }
  73. static void _exception(int signr, struct pt_regs *regs)
  74. {
  75. show_regs(regs);
  76. print_backtrace((unsigned long *)regs->gpr[1]);
  77. panic("Exception in kernel pc %lx signal %d", regs->nip, signr);
  78. }
  79. void MachineCheckException(struct pt_regs *regs)
  80. {
  81. unsigned long fixup;
  82. /* Probing PCI using config cycles cause this exception
  83. * when a device is not present. Catch it and return to
  84. * the PCI exception handler.
  85. */
  86. if ((fixup = search_exception_table(regs->nip)) != 0) {
  87. regs->nip = fixup;
  88. return;
  89. }
  90. #if defined(CONFIG_CMD_KGDB)
  91. if (debugger_exception_handler && (*debugger_exception_handler) (regs))
  92. return;
  93. #endif
  94. printf("Machine check in kernel mode.\n");
  95. printf("Caused by (from msr): ");
  96. printf("regs %p ", regs);
  97. switch ( regs->msr & 0x001F0000) {
  98. case (0x80000000>>11):
  99. printf("MSS error. MSSSR0: %08x\n", mfspr(SPRN_MSSSR0));
  100. break;
  101. case (0x80000000>>12):
  102. printf("Machine check signal - probably due to mm fault\n"
  103. "with mmu off\n");
  104. break;
  105. case (0x80000000 >> 13):
  106. printf("Transfer error ack signal\n");
  107. break;
  108. case (0x80000000 >> 14):
  109. printf("Data parity signal\n");
  110. break;
  111. case (0x80000000 >> 15):
  112. printf("Address parity signal\n");
  113. break;
  114. default:
  115. printf("Unknown values in msr\n");
  116. }
  117. show_regs(regs);
  118. print_backtrace((unsigned long *)regs->gpr[1]);
  119. panic("machine check");
  120. }
  121. void AlignmentException(struct pt_regs *regs)
  122. {
  123. #if defined(CONFIG_CMD_KGDB)
  124. if (debugger_exception_handler && (*debugger_exception_handler) (regs))
  125. return;
  126. #endif
  127. show_regs(regs);
  128. print_backtrace((unsigned long *)regs->gpr[1]);
  129. panic("Alignment Exception");
  130. }
  131. void ProgramCheckException(struct pt_regs *regs)
  132. {
  133. unsigned char *p = regs ? (unsigned char *)(regs->nip) : NULL;
  134. int i, j;
  135. #if defined(CONFIG_CMD_KGDB)
  136. if (debugger_exception_handler && (*debugger_exception_handler) (regs))
  137. return;
  138. #endif
  139. show_regs(regs);
  140. p = (unsigned char *)((unsigned long)p & 0xFFFFFFE0);
  141. p -= 32;
  142. for (i = 0; i < 256; i += 16) {
  143. printf("%08x: ", (unsigned int)p + i);
  144. for (j = 0; j < 16; j++) {
  145. printf("%02x ", p[i + j]);
  146. }
  147. printf("\n");
  148. }
  149. print_backtrace((unsigned long *)regs->gpr[1]);
  150. panic("Program Check Exception");
  151. }
  152. void SoftEmuException(struct pt_regs *regs)
  153. {
  154. #if defined(CONFIG_CMD_KGDB)
  155. if (debugger_exception_handler && (*debugger_exception_handler) (regs))
  156. return;
  157. #endif
  158. show_regs(regs);
  159. print_backtrace((unsigned long *)regs->gpr[1]);
  160. panic("Software Emulation Exception");
  161. }
  162. void UnknownException(struct pt_regs *regs)
  163. {
  164. #if defined(CONFIG_CMD_KGDB)
  165. if (debugger_exception_handler && (*debugger_exception_handler) (regs))
  166. return;
  167. #endif
  168. printf("UnknownException regs@%lx\n", (ulong)regs);
  169. printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
  170. regs->nip, regs->msr, regs->trap);
  171. _exception(0, regs);
  172. }