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.
 
 
 
 
 
 

326 lines
9.0 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, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  22. ***************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include "arm966e.h"
  27. #include "target_type.h"
  28. #if 0
  29. #define _DEBUG_INSTRUCTION_EXECUTION_
  30. #endif
  31. /* cli handling */
  32. int arm966e_register_commands(struct command_context_s *cmd_ctx);
  33. /* forward declarations */
  34. int arm966e_target_create(struct target_s *target, Jim_Interp *interp);
  35. int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
  36. int arm966e_quit(void);
  37. target_type_t arm966e_target =
  38. {
  39. .name = "arm966e",
  40. .poll = arm7_9_poll,
  41. .arch_state = armv4_5_arch_state,
  42. .target_request_data = arm7_9_target_request_data,
  43. .halt = arm7_9_halt,
  44. .resume = arm7_9_resume,
  45. .step = arm7_9_step,
  46. .assert_reset = arm7_9_assert_reset,
  47. .deassert_reset = arm7_9_deassert_reset,
  48. .soft_reset_halt = arm7_9_soft_reset_halt,
  49. .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
  50. .read_memory = arm7_9_read_memory,
  51. .write_memory = arm7_9_write_memory,
  52. .bulk_write_memory = arm7_9_bulk_write_memory,
  53. .checksum_memory = arm7_9_checksum_memory,
  54. .blank_check_memory = arm7_9_blank_check_memory,
  55. .run_algorithm = armv4_5_run_algorithm,
  56. .add_breakpoint = arm7_9_add_breakpoint,
  57. .remove_breakpoint = arm7_9_remove_breakpoint,
  58. .add_watchpoint = arm7_9_add_watchpoint,
  59. .remove_watchpoint = arm7_9_remove_watchpoint,
  60. .register_commands = arm966e_register_commands,
  61. .target_create = arm966e_target_create,
  62. .init_target = arm966e_init_target,
  63. .examine = arm9tdmi_examine,
  64. .quit = arm966e_quit,
  65. };
  66. int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
  67. {
  68. arm9tdmi_init_target(cmd_ctx, target);
  69. return ERROR_OK;
  70. }
  71. int arm966e_quit(void)
  72. {
  73. return ERROR_OK;
  74. }
  75. int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, jtag_tap_t *tap)
  76. {
  77. arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
  78. arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
  79. arm9tdmi_init_arch_info(target, arm9tdmi, tap);
  80. arm9tdmi->arch_info = arm966e;
  81. arm966e->common_magic = ARM966E_COMMON_MAGIC;
  82. /* The ARM966E-S implements the ARMv5TE architecture which
  83. * has the BKPT instruction, so we don't have to use a watchpoint comparator
  84. */
  85. arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
  86. arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
  87. return ERROR_OK;
  88. }
  89. int arm966e_target_create( struct target_s *target, Jim_Interp *interp )
  90. {
  91. arm966e_common_t *arm966e = calloc(1,sizeof(arm966e_common_t));
  92. arm966e_init_arch_info(target, arm966e, target->tap);
  93. return ERROR_OK;
  94. }
  95. int arm966e_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm966e_common_t **arm966e_p)
  96. {
  97. armv4_5_common_t *armv4_5 = target->arch_info;
  98. arm7_9_common_t *arm7_9;
  99. arm9tdmi_common_t *arm9tdmi;
  100. arm966e_common_t *arm966e;
  101. if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
  102. {
  103. return -1;
  104. }
  105. arm7_9 = armv4_5->arch_info;
  106. if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
  107. {
  108. return -1;
  109. }
  110. arm9tdmi = arm7_9->arch_info;
  111. if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
  112. {
  113. return -1;
  114. }
  115. arm966e = arm9tdmi->arch_info;
  116. if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
  117. {
  118. return -1;
  119. }
  120. *armv4_5_p = armv4_5;
  121. *arm7_9_p = arm7_9;
  122. *arm9tdmi_p = arm9tdmi;
  123. *arm966e_p = arm966e;
  124. return ERROR_OK;
  125. }
  126. int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
  127. {
  128. int retval = ERROR_OK;
  129. armv4_5_common_t *armv4_5 = target->arch_info;
  130. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  131. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  132. scan_field_t fields[3];
  133. u8 reg_addr_buf = reg_addr & 0x3f;
  134. u8 nr_w_buf = 0;
  135. jtag_add_end_state(TAP_IDLE);
  136. if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
  137. {
  138. return retval;
  139. }
  140. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  141. fields[0].tap = jtag_info->tap;
  142. fields[0].num_bits = 32;
  143. fields[0].out_value = NULL;
  144. fields[0].in_value = NULL;
  145. fields[1].tap = jtag_info->tap;
  146. fields[1].num_bits = 6;
  147. fields[1].out_value = &reg_addr_buf;
  148. fields[1].in_value = NULL;
  149. fields[2].tap = jtag_info->tap;
  150. fields[2].num_bits = 1;
  151. fields[2].out_value = &nr_w_buf;
  152. fields[2].in_value = NULL;
  153. jtag_add_dr_scan(3, fields, jtag_get_end_state());
  154. fields[1].in_value = (u8 *)value;
  155. jtag_add_dr_scan(3, fields, jtag_get_end_state());
  156. jtag_add_callback(arm_le_to_h_u32, (u8 *)value);
  157. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  158. if ((retval = jtag_execute_queue()) != ERROR_OK)
  159. {
  160. return retval;
  161. }
  162. LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
  163. #endif
  164. return ERROR_OK;
  165. }
  166. int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
  167. {
  168. int retval = ERROR_OK;
  169. armv4_5_common_t *armv4_5 = target->arch_info;
  170. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  171. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  172. scan_field_t fields[3];
  173. u8 reg_addr_buf = reg_addr & 0x3f;
  174. u8 nr_w_buf = 1;
  175. u8 value_buf[4];
  176. buf_set_u32(value_buf, 0, 32, value);
  177. jtag_add_end_state(TAP_IDLE);
  178. if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
  179. {
  180. return retval;
  181. }
  182. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  183. fields[0].tap = jtag_info->tap;
  184. fields[0].num_bits = 32;
  185. fields[0].out_value = value_buf;
  186. fields[0].in_value = NULL;
  187. fields[1].tap = jtag_info->tap;
  188. fields[1].num_bits = 6;
  189. fields[1].out_value = &reg_addr_buf;
  190. fields[1].in_value = NULL;
  191. fields[2].tap = jtag_info->tap;
  192. fields[2].num_bits = 1;
  193. fields[2].out_value = &nr_w_buf;
  194. fields[2].in_value = NULL;
  195. jtag_add_dr_scan(3, fields, jtag_get_end_state());
  196. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  197. LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
  198. #endif
  199. return ERROR_OK;
  200. }
  201. int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  202. {
  203. int retval;
  204. target_t *target = get_current_target(cmd_ctx);
  205. armv4_5_common_t *armv4_5;
  206. arm7_9_common_t *arm7_9;
  207. arm9tdmi_common_t *arm9tdmi;
  208. arm966e_common_t *arm966e;
  209. arm_jtag_t *jtag_info;
  210. if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
  211. {
  212. command_print(cmd_ctx, "current target isn't an ARM966e target");
  213. return ERROR_OK;
  214. }
  215. jtag_info = &arm7_9->jtag_info;
  216. if (target->state != TARGET_HALTED)
  217. {
  218. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  219. return ERROR_OK;
  220. }
  221. /* one or more argument, access a single register (write if second argument is given */
  222. if (argc >= 1)
  223. {
  224. int address = strtoul(args[0], NULL, 0);
  225. if (argc == 1)
  226. {
  227. u32 value;
  228. if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
  229. {
  230. command_print(cmd_ctx, "couldn't access reg %i", address);
  231. return ERROR_OK;
  232. }
  233. if ((retval = jtag_execute_queue()) != ERROR_OK)
  234. {
  235. return retval;
  236. }
  237. command_print(cmd_ctx, "%i: %8.8x", address, value);
  238. }
  239. else if (argc == 2)
  240. {
  241. u32 value = strtoul(args[1], NULL, 0);
  242. if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
  243. {
  244. command_print(cmd_ctx, "couldn't access reg %i", address);
  245. return ERROR_OK;
  246. }
  247. command_print(cmd_ctx, "%i: %8.8x", address, value);
  248. }
  249. }
  250. return ERROR_OK;
  251. }
  252. int arm966e_register_commands(struct command_context_s *cmd_ctx)
  253. {
  254. int retval;
  255. command_t *arm966e_cmd;
  256. retval = arm9tdmi_register_commands(cmd_ctx);
  257. arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
  258. register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
  259. return retval;
  260. }