kgdb.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * kgdb support for ARC
  3. *
  4. * Copyright (C) 2012 Synopsys, Inc. (www.synopsys.com)
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/kgdb.h>
  11. #include <asm/disasm.h>
  12. #include <asm/cacheflush.h>
  13. static void to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs,
  14. struct callee_regs *cregs)
  15. {
  16. int regno;
  17. for (regno = 0; regno <= 26; regno++)
  18. gdb_regs[_R0 + regno] = get_reg(regno, kernel_regs, cregs);
  19. for (regno = 27; regno < GDB_MAX_REGS; regno++)
  20. gdb_regs[regno] = 0;
  21. gdb_regs[_FP] = kernel_regs->fp;
  22. gdb_regs[__SP] = kernel_regs->sp;
  23. gdb_regs[_BLINK] = kernel_regs->blink;
  24. gdb_regs[_RET] = kernel_regs->ret;
  25. gdb_regs[_STATUS32] = kernel_regs->status32;
  26. gdb_regs[_LP_COUNT] = kernel_regs->lp_count;
  27. gdb_regs[_LP_END] = kernel_regs->lp_end;
  28. gdb_regs[_LP_START] = kernel_regs->lp_start;
  29. gdb_regs[_BTA] = kernel_regs->bta;
  30. gdb_regs[_STOP_PC] = kernel_regs->ret;
  31. }
  32. static void from_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs,
  33. struct callee_regs *cregs)
  34. {
  35. int regno;
  36. for (regno = 0; regno <= 26; regno++)
  37. set_reg(regno, gdb_regs[regno + _R0], kernel_regs, cregs);
  38. kernel_regs->fp = gdb_regs[_FP];
  39. kernel_regs->sp = gdb_regs[__SP];
  40. kernel_regs->blink = gdb_regs[_BLINK];
  41. kernel_regs->ret = gdb_regs[_RET];
  42. kernel_regs->status32 = gdb_regs[_STATUS32];
  43. kernel_regs->lp_count = gdb_regs[_LP_COUNT];
  44. kernel_regs->lp_end = gdb_regs[_LP_END];
  45. kernel_regs->lp_start = gdb_regs[_LP_START];
  46. kernel_regs->bta = gdb_regs[_BTA];
  47. }
  48. void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
  49. {
  50. to_gdb_regs(gdb_regs, kernel_regs, (struct callee_regs *)
  51. current->thread.callee_reg);
  52. }
  53. void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs)
  54. {
  55. from_gdb_regs(gdb_regs, kernel_regs, (struct callee_regs *)
  56. current->thread.callee_reg);
  57. }
  58. void sleeping_thread_to_gdb_regs(unsigned long *gdb_regs,
  59. struct task_struct *task)
  60. {
  61. if (task)
  62. to_gdb_regs(gdb_regs, task_pt_regs(task),
  63. (struct callee_regs *) task->thread.callee_reg);
  64. }
  65. struct single_step_data_t {
  66. uint16_t opcode[2];
  67. unsigned long address[2];
  68. int is_branch;
  69. int armed;
  70. } single_step_data;
  71. static void undo_single_step(struct pt_regs *regs)
  72. {
  73. if (single_step_data.armed) {
  74. int i;
  75. for (i = 0; i < (single_step_data.is_branch ? 2 : 1); i++) {
  76. memcpy((void *) single_step_data.address[i],
  77. &single_step_data.opcode[i],
  78. BREAK_INSTR_SIZE);
  79. flush_icache_range(single_step_data.address[i],
  80. single_step_data.address[i] +
  81. BREAK_INSTR_SIZE);
  82. }
  83. single_step_data.armed = 0;
  84. }
  85. }
  86. static void place_trap(unsigned long address, void *save)
  87. {
  88. memcpy(save, (void *) address, BREAK_INSTR_SIZE);
  89. memcpy((void *) address, &arch_kgdb_ops.gdb_bpt_instr,
  90. BREAK_INSTR_SIZE);
  91. flush_icache_range(address, address + BREAK_INSTR_SIZE);
  92. }
  93. static void do_single_step(struct pt_regs *regs)
  94. {
  95. single_step_data.is_branch = disasm_next_pc((unsigned long)
  96. regs->ret, regs, (struct callee_regs *)
  97. current->thread.callee_reg,
  98. &single_step_data.address[0],
  99. &single_step_data.address[1]);
  100. place_trap(single_step_data.address[0], &single_step_data.opcode[0]);
  101. if (single_step_data.is_branch) {
  102. place_trap(single_step_data.address[1],
  103. &single_step_data.opcode[1]);
  104. }
  105. single_step_data.armed++;
  106. }
  107. int kgdb_arch_handle_exception(int e_vector, int signo, int err_code,
  108. char *remcomInBuffer, char *remcomOutBuffer,
  109. struct pt_regs *regs)
  110. {
  111. unsigned long addr;
  112. char *ptr;
  113. undo_single_step(regs);
  114. switch (remcomInBuffer[0]) {
  115. case 's':
  116. case 'c':
  117. ptr = &remcomInBuffer[1];
  118. if (kgdb_hex2long(&ptr, &addr))
  119. regs->ret = addr;
  120. case 'D':
  121. case 'k':
  122. atomic_set(&kgdb_cpu_doing_single_step, -1);
  123. if (remcomInBuffer[0] == 's') {
  124. do_single_step(regs);
  125. atomic_set(&kgdb_cpu_doing_single_step,
  126. smp_processor_id());
  127. }
  128. return 0;
  129. }
  130. return -1;
  131. }
  132. unsigned long kgdb_arch_pc(int exception, struct pt_regs *regs)
  133. {
  134. return instruction_pointer(regs);
  135. }
  136. int kgdb_arch_init(void)
  137. {
  138. single_step_data.armed = 0;
  139. return 0;
  140. }
  141. void kgdb_trap(struct pt_regs *regs, int param)
  142. {
  143. /* trap_s 3 is used for breakpoints that overwrite existing
  144. * instructions, while trap_s 4 is used for compiled breakpoints.
  145. *
  146. * with trap_s 3 breakpoints the original instruction needs to be
  147. * restored and continuation needs to start at the location of the
  148. * breakpoint.
  149. *
  150. * with trap_s 4 (compiled) breakpoints, continuation needs to
  151. * start after the breakpoint.
  152. */
  153. if (param == 3)
  154. instruction_pointer(regs) -= BREAK_INSTR_SIZE;
  155. kgdb_handle_exception(1, SIGTRAP, 0, regs);
  156. }
  157. void kgdb_arch_exit(void)
  158. {
  159. }
  160. void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
  161. {
  162. instruction_pointer(regs) = ip;
  163. }
  164. struct kgdb_arch arch_kgdb_ops = {
  165. /* breakpoint instruction: TRAP_S 0x3 */
  166. #ifdef CONFIG_CPU_BIG_ENDIAN
  167. .gdb_bpt_instr = {0x78, 0x7e},
  168. #else
  169. .gdb_bpt_instr = {0x7e, 0x78},
  170. #endif
  171. };