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.
 
 
 
 
 
 

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