traps.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2000
  4. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  5. *
  6. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  7. */
  8. /*
  9. * This file handles the architecture-dependent parts of hardware
  10. * exceptions
  11. */
  12. #include <common.h>
  13. #include <command.h>
  14. #include <kgdb.h>
  15. #include <asm/processor.h>
  16. #include <asm/mpc8349_pci.h>
  17. DECLARE_GLOBAL_DATA_PTR;
  18. /* Returns 0 if exception not found and fixup otherwise. */
  19. extern unsigned long search_exception_table(unsigned long);
  20. #define END_OF_MEM (gd->bd->bi_memstart + gd->bd->bi_memsize)
  21. /*
  22. * Trap & Exception support
  23. */
  24. static void print_backtrace(unsigned long *sp)
  25. {
  26. int cnt = 0;
  27. unsigned long i;
  28. puts ("Call backtrace: ");
  29. while (sp) {
  30. if ((uint)sp > END_OF_MEM)
  31. break;
  32. i = sp[1];
  33. if (cnt++ % 7 == 0)
  34. putc ('\n');
  35. printf("%08lX ", i);
  36. if (cnt > 32) break;
  37. sp = (unsigned long *)*sp;
  38. }
  39. putc ('\n');
  40. }
  41. void show_regs(struct pt_regs *regs)
  42. {
  43. int i;
  44. printf("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx DAR: %08lX\n",
  45. regs->nip, regs->xer, regs->link, regs, regs->trap, regs->dar);
  46. printf("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
  47. regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
  48. regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
  49. regs->msr&MSR_IR ? 1 : 0,
  50. regs->msr&MSR_DR ? 1 : 0);
  51. putc ('\n');
  52. for (i = 0; i < 32; i++) {
  53. if ((i % 8) == 0) {
  54. printf("GPR%02d: ", i);
  55. }
  56. printf("%08lX ", regs->gpr[i]);
  57. if ((i % 8) == 7) {
  58. putc ('\n');
  59. }
  60. }
  61. }
  62. static void _exception(int signr, struct pt_regs *regs)
  63. {
  64. show_regs(regs);
  65. print_backtrace((unsigned long *)regs->gpr[1]);
  66. panic("Exception in kernel pc %lx signal %d",regs->nip,signr);
  67. }
  68. #ifdef CONFIG_PCI
  69. void dump_pci (void)
  70. {
  71. /*
  72. volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
  73. printf ("PCI: err status %x err mask %x err ctrl %x\n",
  74. le32_to_cpu (immap->im_pci.pci_esr),
  75. le32_to_cpu (immap->im_pci.pci_emr),
  76. le32_to_cpu (immap->im_pci.pci_ecr));
  77. printf (" error address %x error data %x ctrl %x\n",
  78. le32_to_cpu (immap->im_pci.pci_eacr),
  79. le32_to_cpu (immap->im_pci.pci_edcr),
  80. le32_to_cpu (immap->im_pci.pci_eccr));
  81. */
  82. }
  83. #endif
  84. void MachineCheckException(struct pt_regs *regs)
  85. {
  86. unsigned long fixup;
  87. /* Probing PCI using config cycles cause this exception
  88. * when a device is not present. Catch it and return to
  89. * the PCI exception handler.
  90. */
  91. #ifdef CONFIG_PCI
  92. #if 0
  93. volatile immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
  94. #ifdef DEBUG
  95. dump_pci();
  96. #endif
  97. /* clear the error in the error status register */
  98. if(immap->im_pci.pci_esr & cpu_to_le32(PCI_ERROR_PCI_NO_RSP)) {
  99. immap->im_pci.pci_esr = cpu_to_le32(PCI_ERROR_PCI_NO_RSP);
  100. return;
  101. }
  102. #endif
  103. #endif /* CONFIG_PCI */
  104. if ((fixup = search_exception_table(regs->nip)) != 0) {
  105. regs->nip = fixup;
  106. return;
  107. }
  108. #if defined(CONFIG_CMD_KGDB)
  109. if (debugger_exception_handler && (*debugger_exception_handler)(regs))
  110. return;
  111. #endif
  112. puts ("Machine check in kernel mode.\n"
  113. "Caused by (from msr): ");
  114. printf("regs %p ",regs);
  115. switch( regs->msr & 0x000F0000) {
  116. case (0x80000000>>12):
  117. puts ("Machine check signal - probably due to mm fault\n"
  118. "with mmu off\n");
  119. break;
  120. case (0x80000000>>13):
  121. puts ("Transfer error ack signal\n");
  122. break;
  123. case (0x80000000>>14):
  124. puts ("Data parity signal\n");
  125. break;
  126. case (0x80000000>>15):
  127. puts ("Address parity signal\n");
  128. break;
  129. default:
  130. puts ("Unknown values in msr\n");
  131. }
  132. show_regs(regs);
  133. print_backtrace((unsigned long *)regs->gpr[1]);
  134. #ifdef CONFIG_PCI
  135. dump_pci();
  136. #endif
  137. panic("machine check");
  138. }
  139. void AlignmentException(struct pt_regs *regs)
  140. {
  141. #if defined(CONFIG_CMD_KGDB)
  142. if (debugger_exception_handler && (*debugger_exception_handler)(regs))
  143. return;
  144. #endif
  145. show_regs(regs);
  146. print_backtrace((unsigned long *)regs->gpr[1]);
  147. panic("Alignment Exception");
  148. }
  149. void ProgramCheckException(struct pt_regs *regs)
  150. {
  151. #if defined(CONFIG_CMD_KGDB)
  152. if (debugger_exception_handler && (*debugger_exception_handler)(regs))
  153. return;
  154. #endif
  155. show_regs(regs);
  156. print_backtrace((unsigned long *)regs->gpr[1]);
  157. panic("Program Check Exception");
  158. }
  159. void SoftEmuException(struct pt_regs *regs)
  160. {
  161. #if defined(CONFIG_CMD_KGDB)
  162. if (debugger_exception_handler && (*debugger_exception_handler)(regs))
  163. return;
  164. #endif
  165. show_regs(regs);
  166. print_backtrace((unsigned long *)regs->gpr[1]);
  167. panic("Software Emulation Exception");
  168. }
  169. void UnknownException(struct pt_regs *regs)
  170. {
  171. #if defined(CONFIG_CMD_KGDB)
  172. if (debugger_exception_handler && (*debugger_exception_handler)(regs))
  173. return;
  174. #endif
  175. printf("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
  176. regs->nip, regs->msr, regs->trap);
  177. _exception(0, regs);
  178. }
  179. #if defined(CONFIG_CMD_BEDBUG)
  180. extern void do_bedbug_breakpoint(struct pt_regs *);
  181. #endif
  182. void DebugException(struct pt_regs *regs)
  183. {
  184. printf("Debugger trap at @ %lx\n", regs->nip );
  185. show_regs(regs);
  186. #if defined(CONFIG_CMD_BEDBUG)
  187. do_bedbug_breakpoint( regs );
  188. #endif
  189. }