kgdb.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #include <common.h>
  2. #include <command.h>
  3. #include <kgdb.h>
  4. #include <asm/signal.h>
  5. #include <asm/processor.h>
  6. #define PC_REGNUM 64
  7. #define SP_REGNUM 1
  8. void breakinst(void);
  9. int
  10. kgdb_setjmp(long *buf)
  11. {
  12. unsigned long temp;
  13. asm volatile("mflr %0; stw %0,0(%1);"
  14. "stw %%r1,4(%1); stw %%r2,8(%1);"
  15. "mfcr %0; stw %0,12(%1);"
  16. "stmw %%r13,16(%1)"
  17. : "=&r"(temp) : "r" (buf));
  18. /* XXX should save fp regs as well */
  19. return 0;
  20. }
  21. void
  22. kgdb_longjmp(long *buf, int val)
  23. {
  24. unsigned long temp;
  25. if (val == 0)
  26. val = 1;
  27. asm volatile("lmw %%r13,16(%1);"
  28. "lwz %0,12(%1); mtcrf 0x38,%0;"
  29. "lwz %0,0(%1); lwz %%r1,4(%1); lwz %%r2,8(%1);"
  30. "mtlr %0; mr %%r3,%2"
  31. : "=&r"(temp) : "r" (buf), "r" (val));
  32. }
  33. /* Convert the SPARC hardware trap type code to a unix signal number. */
  34. /*
  35. * This table contains the mapping between PowerPC hardware trap types, and
  36. * signals, which are primarily what GDB understands.
  37. */
  38. static struct hard_trap_info
  39. {
  40. unsigned int tt; /* Trap type code for powerpc */
  41. unsigned char signo; /* Signal that we map this trap into */
  42. } hard_trap_info[] = {
  43. { 0x200, SIGSEGV }, /* machine check */
  44. { 0x300, SIGSEGV }, /* address error (store) */
  45. { 0x400, SIGBUS }, /* instruction bus error */
  46. { 0x500, SIGINT }, /* interrupt */
  47. { 0x600, SIGBUS }, /* alignment */
  48. { 0x700, SIGTRAP }, /* breakpoint trap */
  49. { 0x800, SIGFPE }, /* fpu unavail */
  50. { 0x900, SIGALRM }, /* decrementer */
  51. { 0xa00, SIGILL }, /* reserved */
  52. { 0xb00, SIGILL }, /* reserved */
  53. { 0xc00, SIGCHLD }, /* syscall */
  54. { 0xd00, SIGTRAP }, /* single-step/watch */
  55. { 0xe00, SIGFPE }, /* fp assist */
  56. { 0, 0} /* Must be last */
  57. };
  58. static int
  59. computeSignal(unsigned int tt)
  60. {
  61. struct hard_trap_info *ht;
  62. for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
  63. if (ht->tt == tt)
  64. return ht->signo;
  65. return SIGHUP; /* default for things we don't know about */
  66. }
  67. void
  68. kgdb_enter(struct pt_regs *regs, kgdb_data *kdp)
  69. {
  70. unsigned long msr;
  71. kdp->private[0] = msr = get_msr();
  72. set_msr(msr & ~MSR_EE); /* disable interrupts */
  73. if (regs->nip == (unsigned long)breakinst) {
  74. /* Skip over breakpoint trap insn */
  75. regs->nip += 4;
  76. }
  77. regs->msr &= ~MSR_SE;
  78. /* reply to host that an exception has occurred */
  79. kdp->sigval = computeSignal(regs->trap);
  80. kdp->nregs = 2;
  81. kdp->regs[0].num = PC_REGNUM;
  82. kdp->regs[0].val = regs->nip;
  83. kdp->regs[1].num = SP_REGNUM;
  84. kdp->regs[1].val = regs->gpr[SP_REGNUM];
  85. }
  86. void
  87. kgdb_exit(struct pt_regs *regs, kgdb_data *kdp)
  88. {
  89. unsigned long msr = kdp->private[0];
  90. if (kdp->extype & KGDBEXIT_WITHADDR)
  91. regs->nip = kdp->exaddr;
  92. switch (kdp->extype & KGDBEXIT_TYPEMASK) {
  93. case KGDBEXIT_KILL:
  94. case KGDBEXIT_CONTINUE:
  95. set_msr(msr);
  96. break;
  97. case KGDBEXIT_SINGLE:
  98. regs->msr |= MSR_SE;
  99. #if 0
  100. set_msr(msr | MSR_SE);
  101. #endif
  102. break;
  103. }
  104. }
  105. int
  106. kgdb_trap(struct pt_regs *regs)
  107. {
  108. return (regs->trap);
  109. }
  110. /* return the value of the CPU registers.
  111. * some of them are non-PowerPC names :(
  112. * they are stored in gdb like:
  113. * struct {
  114. * u32 gpr[32];
  115. * f64 fpr[32];
  116. * u32 pc, ps, cnd, lr; (ps=msr)
  117. * u32 cnt, xer, mq;
  118. * }
  119. */
  120. #define SPACE_REQUIRED ((32*4)+(32*8)+(6*4))
  121. int
  122. kgdb_getregs(struct pt_regs *regs, char *buf, int max)
  123. {
  124. int i;
  125. unsigned long *ptr = (unsigned long *)buf;
  126. if (max < SPACE_REQUIRED)
  127. kgdb_error(KGDBERR_NOSPACE);
  128. if ((unsigned long)ptr & 3)
  129. kgdb_error(KGDBERR_ALIGNFAULT);
  130. /* General Purpose Regs */
  131. for (i = 0; i < 32; i++)
  132. *ptr++ = regs->gpr[i];
  133. /* Floating Point Regs */
  134. for (i = 0; i < 32; i++) {
  135. *ptr++ = 0;
  136. *ptr++ = 0;
  137. }
  138. /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
  139. *ptr++ = regs->nip;
  140. *ptr++ = regs->msr;
  141. *ptr++ = regs->ccr;
  142. *ptr++ = regs->link;
  143. *ptr++ = regs->ctr;
  144. *ptr++ = regs->xer;
  145. return (SPACE_REQUIRED);
  146. }
  147. /* set the value of the CPU registers */
  148. void
  149. kgdb_putreg(struct pt_regs *regs, int regno, char *buf, int length)
  150. {
  151. unsigned long *ptr = (unsigned long *)buf;
  152. if (regno < 0 || regno >= 70)
  153. kgdb_error(KGDBERR_BADPARAMS);
  154. else if (regno >= 32 && regno < 64) {
  155. if (length < 8)
  156. kgdb_error(KGDBERR_NOSPACE);
  157. }
  158. else {
  159. if (length < 4)
  160. kgdb_error(KGDBERR_NOSPACE);
  161. }
  162. if ((unsigned long)ptr & 3)
  163. kgdb_error(KGDBERR_ALIGNFAULT);
  164. if (regno >= 0 && regno < 32)
  165. regs->gpr[regno] = *ptr;
  166. else switch (regno) {
  167. case 64: regs->nip = *ptr; break;
  168. case 65: regs->msr = *ptr; break;
  169. case 66: regs->ccr = *ptr; break;
  170. case 67: regs->link = *ptr; break;
  171. case 68: regs->ctr = *ptr; break;
  172. case 69: regs->ctr = *ptr; break;
  173. default:
  174. kgdb_error(KGDBERR_BADPARAMS);
  175. }
  176. }
  177. void
  178. kgdb_putregs(struct pt_regs *regs, char *buf, int length)
  179. {
  180. int i;
  181. unsigned long *ptr = (unsigned long *)buf;
  182. if (length < SPACE_REQUIRED)
  183. kgdb_error(KGDBERR_NOSPACE);
  184. if ((unsigned long)ptr & 3)
  185. kgdb_error(KGDBERR_ALIGNFAULT);
  186. /*
  187. * If the stack pointer has moved, you should pray.
  188. * (cause only god can help you).
  189. */
  190. /* General Purpose Regs */
  191. for (i = 0; i < 32; i++)
  192. regs->gpr[i] = *ptr++;
  193. /* Floating Point Regs */
  194. ptr += 32*2;
  195. /* pc, msr, cr, lr, ctr, xer, (mq is unused) */
  196. regs->nip = *ptr++;
  197. regs->msr = *ptr++;
  198. regs->ccr = *ptr++;
  199. regs->link = *ptr++;
  200. regs->ctr = *ptr++;
  201. regs->xer = *ptr++;
  202. }
  203. /* This function will generate a breakpoint exception. It is used at the
  204. beginning of a program to sync up with a debugger and can be used
  205. otherwise as a quick means to stop program execution and "break" into
  206. the debugger. */
  207. void
  208. kgdb_breakpoint(int argc, char *const argv[])
  209. {
  210. asm(" .globl breakinst\n\
  211. breakinst: .long 0x7d821008\n\
  212. ");
  213. }