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.
 
 
 
 
 
 

295 lines
8.5 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2008 by Spencer Oliver *
  6. * spen@spen-soft.co.uk *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  20. ***************************************************************************/
  21. #ifdef HAVE_CONFIG_H
  22. #include "config.h"
  23. #endif
  24. #include "arm966e.h"
  25. #include "target_type.h"
  26. #include "arm_opcodes.h"
  27. #if 0
  28. #define _DEBUG_INSTRUCTION_EXECUTION_
  29. #endif
  30. int arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e, struct jtag_tap *tap)
  31. {
  32. struct arm7_9_common *arm7_9 = &arm966e->arm7_9_common;
  33. /* initialize arm7/arm9 specific info (including armv4_5) */
  34. arm9tdmi_init_arch_info(target, arm7_9, tap);
  35. arm966e->common_magic = ARM966E_COMMON_MAGIC;
  36. /* The ARM966E-S implements the ARMv5TE architecture which
  37. * has the BKPT instruction, so we don't have to use a watchpoint comparator
  38. */
  39. arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
  40. arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
  41. return ERROR_OK;
  42. }
  43. static int arm966e_target_create(struct target *target, Jim_Interp *interp)
  44. {
  45. struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common));
  46. return arm966e_init_arch_info(target, arm966e, target->tap);
  47. }
  48. static void arm966e_deinit_target(struct target *target)
  49. {
  50. struct arm *arm = target_to_arm(target);
  51. struct arm966e_common *arm966e = target_to_arm966(target);
  52. arm7_9_deinit(target);
  53. arm_free_reg_cache(arm);
  54. free(arm966e);
  55. }
  56. static int arm966e_verify_pointer(struct command_invocation *cmd,
  57. struct arm966e_common *arm966e)
  58. {
  59. if (arm966e->common_magic != ARM966E_COMMON_MAGIC) {
  60. command_print(cmd, "target is not an ARM966");
  61. return ERROR_TARGET_INVALID;
  62. }
  63. return ERROR_OK;
  64. }
  65. /*
  66. * REVISIT: The "read_cp15" and "write_cp15" commands could hook up
  67. * to eventual mrc() and mcr() routines ... the reg_addr values being
  68. * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.
  69. * See section 7.3 of the ARM966E-S TRM.
  70. */
  71. static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *value)
  72. {
  73. int retval = ERROR_OK;
  74. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  75. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  76. struct scan_field fields[3];
  77. uint8_t reg_addr_buf = reg_addr & 0x3f;
  78. uint8_t nr_w_buf = 0;
  79. retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
  80. if (retval != ERROR_OK)
  81. return retval;
  82. retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
  83. if (retval != ERROR_OK)
  84. return retval;
  85. fields[0].num_bits = 32;
  86. /* REVISIT: table 7-2 shows that bits 31-31 need to be
  87. * specified for accessing BIST registers ...
  88. */
  89. fields[0].out_value = NULL;
  90. fields[0].in_value = NULL;
  91. fields[1].num_bits = 6;
  92. fields[1].out_value = &reg_addr_buf;
  93. fields[1].in_value = NULL;
  94. fields[2].num_bits = 1;
  95. fields[2].out_value = &nr_w_buf;
  96. fields[2].in_value = NULL;
  97. jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
  98. fields[1].in_value = (uint8_t *)value;
  99. jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
  100. jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
  101. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  102. retval = jtag_execute_queue();
  103. if (retval != ERROR_OK)
  104. return retval;
  105. LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
  106. #endif
  107. return ERROR_OK;
  108. }
  109. /* EXPORTED to str9x (flash) */
  110. int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)
  111. {
  112. int retval = ERROR_OK;
  113. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  114. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  115. struct scan_field fields[3];
  116. uint8_t reg_addr_buf = reg_addr & 0x3f;
  117. uint8_t nr_w_buf = 1;
  118. uint8_t value_buf[4];
  119. buf_set_u32(value_buf, 0, 32, value);
  120. retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
  121. if (retval != ERROR_OK)
  122. return retval;
  123. retval = arm_jtag_set_instr(jtag_info->tap, jtag_info->intest_instr, NULL, TAP_IDLE);
  124. if (retval != ERROR_OK)
  125. return retval;
  126. fields[0].num_bits = 32;
  127. fields[0].out_value = value_buf;
  128. fields[0].in_value = NULL;
  129. fields[1].num_bits = 6;
  130. fields[1].out_value = &reg_addr_buf;
  131. fields[1].in_value = NULL;
  132. fields[2].num_bits = 1;
  133. fields[2].out_value = &nr_w_buf;
  134. fields[2].in_value = NULL;
  135. jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
  136. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  137. LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
  138. #endif
  139. return ERROR_OK;
  140. }
  141. COMMAND_HANDLER(arm966e_handle_cp15_command)
  142. {
  143. int retval;
  144. struct target *target = get_current_target(CMD_CTX);
  145. struct arm966e_common *arm966e = target_to_arm966(target);
  146. retval = arm966e_verify_pointer(CMD, arm966e);
  147. if (retval != ERROR_OK)
  148. return retval;
  149. if (target->state != TARGET_HALTED) {
  150. command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
  151. return ERROR_OK;
  152. }
  153. /* one or more argument, access a single register (write if second argument is given */
  154. if (CMD_ARGC >= 1) {
  155. uint32_t address;
  156. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
  157. if (CMD_ARGC == 1) {
  158. uint32_t value;
  159. retval = arm966e_read_cp15(target, address, &value);
  160. if (retval != ERROR_OK) {
  161. command_print(CMD,
  162. "couldn't access reg %" PRIu32,
  163. address);
  164. return ERROR_OK;
  165. }
  166. retval = jtag_execute_queue();
  167. if (retval != ERROR_OK)
  168. return retval;
  169. command_print(CMD, "%" PRIu32 ": %8.8" PRIx32,
  170. address, value);
  171. } else if (CMD_ARGC == 2) {
  172. uint32_t value;
  173. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
  174. retval = arm966e_write_cp15(target, address, value);
  175. if (retval != ERROR_OK) {
  176. command_print(CMD,
  177. "couldn't access reg %" PRIu32,
  178. address);
  179. return ERROR_OK;
  180. }
  181. command_print(CMD, "%" PRIu32 ": %8.8" PRIx32,
  182. address, value);
  183. }
  184. }
  185. return ERROR_OK;
  186. }
  187. static const struct command_registration arm966e_exec_command_handlers[] = {
  188. {
  189. .name = "cp15",
  190. .handler = arm966e_handle_cp15_command,
  191. .mode = COMMAND_EXEC,
  192. .usage = "regnum [value]",
  193. .help = "display/modify cp15 register",
  194. },
  195. COMMAND_REGISTRATION_DONE
  196. };
  197. const struct command_registration arm966e_command_handlers[] = {
  198. {
  199. .chain = arm9tdmi_command_handlers,
  200. },
  201. {
  202. .name = "arm966e",
  203. .mode = COMMAND_ANY,
  204. .help = "arm966e command group",
  205. .usage = "",
  206. .chain = arm966e_exec_command_handlers,
  207. },
  208. COMMAND_REGISTRATION_DONE
  209. };
  210. /** Holds methods for ARM966 targets. */
  211. struct target_type arm966e_target = {
  212. .name = "arm966e",
  213. .poll = arm7_9_poll,
  214. .arch_state = arm_arch_state,
  215. .target_request_data = arm7_9_target_request_data,
  216. .halt = arm7_9_halt,
  217. .resume = arm7_9_resume,
  218. .step = arm7_9_step,
  219. .assert_reset = arm7_9_assert_reset,
  220. .deassert_reset = arm7_9_deassert_reset,
  221. .soft_reset_halt = arm7_9_soft_reset_halt,
  222. .get_gdb_arch = arm_get_gdb_arch,
  223. .get_gdb_reg_list = arm_get_gdb_reg_list,
  224. .read_memory = arm7_9_read_memory,
  225. .write_memory = arm7_9_write_memory_opt,
  226. .checksum_memory = arm_checksum_memory,
  227. .blank_check_memory = arm_blank_check_memory,
  228. .run_algorithm = armv4_5_run_algorithm,
  229. .add_breakpoint = arm7_9_add_breakpoint,
  230. .remove_breakpoint = arm7_9_remove_breakpoint,
  231. .add_watchpoint = arm7_9_add_watchpoint,
  232. .remove_watchpoint = arm7_9_remove_watchpoint,
  233. .commands = arm966e_command_handlers,
  234. .target_create = arm966e_target_create,
  235. .init_target = arm9tdmi_init_target,
  236. .deinit_target = arm966e_deinit_target,
  237. .examine = arm7_9_examine,
  238. .check_reset = arm7_9_check_reset,
  239. };