You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

armv7a.c 6.5 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. /***************************************************************************
  2. * Copyright (C) 2009 by David Brownell *
  3. * *
  4. * This program is free software; you can redistribute it and/or modify *
  5. * it under the terms of the GNU General Public License as published by *
  6. * the Free Software Foundation; either version 2 of the License, or *
  7. * (at your option) any later version. *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  18. ***************************************************************************/
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include <helper/replacements.h>
  23. #include "armv7a.h"
  24. #include "arm_disassembler.h"
  25. #include "register.h"
  26. #include <helper/binarybuffer.h>
  27. #include <helper/command.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <unistd.h>
  31. #include "arm_opcodes.h"
  32. static void armv7a_show_fault_registers(struct target *target)
  33. {
  34. uint32_t dfsr, ifsr, dfar, ifar;
  35. struct armv7a_common *armv7a = target_to_armv7a(target);
  36. struct arm_dpm *dpm = armv7a->armv4_5_common.dpm;
  37. int retval;
  38. retval = dpm->prepare(dpm);
  39. if (retval != ERROR_OK)
  40. return;
  41. /* ARMV4_5_MRC(cpnum, op1, r0, CRn, CRm, op2) */
  42. /* c5/c0 - {data, instruction} fault status registers */
  43. retval = dpm->instr_read_data_r0(dpm,
  44. ARMV4_5_MRC(15, 0, 0, 5, 0, 0),
  45. &dfsr);
  46. if (retval != ERROR_OK)
  47. goto done;
  48. retval = dpm->instr_read_data_r0(dpm,
  49. ARMV4_5_MRC(15, 0, 0, 5, 0, 1),
  50. &ifsr);
  51. if (retval != ERROR_OK)
  52. goto done;
  53. /* c6/c0 - {data, instruction} fault address registers */
  54. retval = dpm->instr_read_data_r0(dpm,
  55. ARMV4_5_MRC(15, 0, 0, 6, 0, 0),
  56. &dfar);
  57. if (retval != ERROR_OK)
  58. goto done;
  59. retval = dpm->instr_read_data_r0(dpm,
  60. ARMV4_5_MRC(15, 0, 0, 6, 0, 2),
  61. &ifar);
  62. if (retval != ERROR_OK)
  63. goto done;
  64. LOG_USER("Data fault registers DFSR: %8.8" PRIx32
  65. ", DFAR: %8.8" PRIx32, dfsr, dfar);
  66. LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
  67. ", IFAR: %8.8" PRIx32, ifsr, ifar);
  68. done:
  69. /* (void) */ dpm->finish(dpm);
  70. }
  71. int armv7a_arch_state(struct target *target)
  72. {
  73. static const char *state[] =
  74. {
  75. "disabled", "enabled"
  76. };
  77. struct armv7a_common *armv7a = target_to_armv7a(target);
  78. struct arm *armv4_5 = &armv7a->armv4_5_common;
  79. if (armv7a->common_magic != ARMV7_COMMON_MAGIC)
  80. {
  81. LOG_ERROR("BUG: called for a non-ARMv7A target");
  82. return ERROR_INVALID_ARGUMENTS;
  83. }
  84. arm_arch_state(target);
  85. LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
  86. state[armv7a->armv4_5_mmu.mmu_enabled],
  87. state[armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
  88. state[armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
  89. if (armv4_5->core_mode == ARM_MODE_ABT)
  90. armv7a_show_fault_registers(target);
  91. if (target->debug_reason == DBG_REASON_WATCHPOINT)
  92. LOG_USER("Watchpoint triggered at PC %#08x",
  93. (unsigned) armv7a->dpm.wp_pc);
  94. return ERROR_OK;
  95. }
  96. COMMAND_HANDLER(handle_dap_baseaddr_command)
  97. {
  98. struct target *target = get_current_target(CMD_CTX);
  99. struct armv7a_common *armv7a = target_to_armv7a(target);
  100. struct swjdp_common *swjdp = &armv7a->swjdp_info;
  101. return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp);
  102. }
  103. COMMAND_HANDLER(handle_dap_memaccess_command)
  104. {
  105. struct target *target = get_current_target(CMD_CTX);
  106. struct armv7a_common *armv7a = target_to_armv7a(target);
  107. struct swjdp_common *swjdp = &armv7a->swjdp_info;
  108. return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp);
  109. }
  110. COMMAND_HANDLER(handle_dap_apsel_command)
  111. {
  112. struct target *target = get_current_target(CMD_CTX);
  113. struct armv7a_common *armv7a = target_to_armv7a(target);
  114. struct swjdp_common *swjdp = &armv7a->swjdp_info;
  115. return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp);
  116. }
  117. COMMAND_HANDLER(handle_dap_apid_command)
  118. {
  119. struct target *target = get_current_target(CMD_CTX);
  120. struct armv7a_common *armv7a = target_to_armv7a(target);
  121. struct swjdp_common *swjdp = &armv7a->swjdp_info;
  122. return CALL_COMMAND_HANDLER(dap_apid_command, swjdp);
  123. }
  124. COMMAND_HANDLER(handle_dap_info_command)
  125. {
  126. struct target *target = get_current_target(CMD_CTX);
  127. struct armv7a_common *armv7a = target_to_armv7a(target);
  128. struct swjdp_common *swjdp = &armv7a->swjdp_info;
  129. uint32_t apsel;
  130. switch (CMD_ARGC) {
  131. case 0:
  132. apsel = swjdp->apsel;
  133. break;
  134. case 1:
  135. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
  136. break;
  137. default:
  138. return ERROR_COMMAND_SYNTAX_ERROR;
  139. }
  140. return dap_info_command(CMD_CTX, swjdp, apsel);
  141. }
  142. /* FIXME this table should be part of generic DAP support, and
  143. * be shared by the ARMv7-A/R and ARMv7-M support ...
  144. */
  145. static const struct command_registration armv7a_exec_command_handlers[] = {
  146. {
  147. .name = "info",
  148. .handler = handle_dap_info_command,
  149. .mode = COMMAND_EXEC,
  150. .help = "display ROM table for MEM-AP "
  151. "(default currently selected AP)",
  152. .usage = "[ap_num]",
  153. },
  154. {
  155. .name = "apsel",
  156. .handler = handle_dap_apsel_command,
  157. .mode = COMMAND_EXEC,
  158. .help = "Set the currently selected AP (default 0) "
  159. "and display the result",
  160. .usage = "[ap_num]",
  161. },
  162. {
  163. .name = "apid",
  164. .handler = handle_dap_apid_command,
  165. .mode = COMMAND_EXEC,
  166. .help = "return ID register from AP "
  167. "(default currently selected AP)",
  168. .usage = "[ap_num]",
  169. },
  170. {
  171. .name = "baseaddr",
  172. .handler = handle_dap_baseaddr_command,
  173. .mode = COMMAND_EXEC,
  174. .help = "return debug base address from MEM-AP "
  175. "(default currently selected AP)",
  176. .usage = "[ap_num]",
  177. },
  178. {
  179. .name = "memaccess",
  180. .handler = handle_dap_memaccess_command,
  181. .mode = COMMAND_EXEC,
  182. .help = "set/get number of extra tck for MEM-AP memory "
  183. "bus access [0-255]",
  184. .usage = "[cycles]",
  185. },
  186. COMMAND_REGISTRATION_DONE
  187. };
  188. const struct command_registration armv7a_command_handlers[] = {
  189. {
  190. .name = "dap",
  191. .mode = COMMAND_ANY,
  192. .help = "Cortex DAP command group",
  193. .chain = armv7a_exec_command_handlers,
  194. },
  195. COMMAND_REGISTRATION_DONE
  196. };