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.
 
 
 
 
 
 

349 lines
9.7 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program; if not, write to the *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include "arm966e.h"
  24. #include "arm7_9_common.h"
  25. #include "register.h"
  26. #include "target.h"
  27. #include "armv4_5.h"
  28. #include "embeddedice.h"
  29. #include "log.h"
  30. #include "jtag.h"
  31. #include "arm_jtag.h"
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #if 0
  35. #define _DEBUG_INSTRUCTION_EXECUTION_
  36. #endif
  37. /* cli handling */
  38. int arm966e_register_commands(struct command_context_s *cmd_ctx);
  39. /* forward declarations */
  40. int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
  41. int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
  42. int arm966e_quit(void);
  43. target_type_t arm966e_target =
  44. {
  45. .name = "arm966e",
  46. .poll = arm7_9_poll,
  47. .arch_state = armv4_5_arch_state,
  48. .halt = arm7_9_halt,
  49. .resume = arm7_9_resume,
  50. .step = arm7_9_step,
  51. .assert_reset = arm7_9_assert_reset,
  52. .deassert_reset = arm7_9_deassert_reset,
  53. .soft_reset_halt = arm7_9_soft_reset_halt,
  54. .prepare_reset_halt = arm7_9_prepare_reset_halt,
  55. .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
  56. .read_memory = arm7_9_read_memory,
  57. .write_memory = arm7_9_write_memory,
  58. .bulk_write_memory = arm7_9_bulk_write_memory,
  59. .run_algorithm = armv4_5_run_algorithm,
  60. .add_breakpoint = arm7_9_add_breakpoint,
  61. .remove_breakpoint = arm7_9_remove_breakpoint,
  62. .add_watchpoint = arm7_9_add_watchpoint,
  63. .remove_watchpoint = arm7_9_remove_watchpoint,
  64. .register_commands = arm966e_register_commands,
  65. .target_command = arm966e_target_command,
  66. .init_target = arm966e_init_target,
  67. .quit = arm966e_quit,
  68. };
  69. int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
  70. {
  71. arm9tdmi_init_target(cmd_ctx, target);
  72. return ERROR_OK;
  73. }
  74. int arm966e_quit(void)
  75. {
  76. return ERROR_OK;
  77. }
  78. int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
  79. {
  80. arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
  81. arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
  82. arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
  83. arm9tdmi->arch_info = arm966e;
  84. arm966e->common_magic = ARM966E_COMMON_MAGIC;
  85. /* The ARM966E-S implements the ARMv5TE architecture which
  86. * has the BKPT instruction, so we don't have to use a watchpoint comparator
  87. */
  88. arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
  89. arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
  90. arm7_9->sw_bkpts_use_wp = 0;
  91. arm7_9->sw_bkpts_enabled = 1;
  92. return ERROR_OK;
  93. }
  94. int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
  95. {
  96. int chain_pos;
  97. char *variant = NULL;
  98. arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
  99. if (argc < 4)
  100. {
  101. ERROR("'target arm966e' requires at least one additional argument");
  102. exit(-1);
  103. }
  104. chain_pos = strtoul(args[3], NULL, 0);
  105. if (argc >= 5)
  106. variant = args[4];
  107. DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
  108. arm966e_init_arch_info(target, arm966e, chain_pos, variant);
  109. return ERROR_OK;
  110. }
  111. 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)
  112. {
  113. armv4_5_common_t *armv4_5 = target->arch_info;
  114. arm7_9_common_t *arm7_9;
  115. arm9tdmi_common_t *arm9tdmi;
  116. arm966e_common_t *arm966e;
  117. if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
  118. {
  119. return -1;
  120. }
  121. arm7_9 = armv4_5->arch_info;
  122. if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
  123. {
  124. return -1;
  125. }
  126. arm9tdmi = arm7_9->arch_info;
  127. if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
  128. {
  129. return -1;
  130. }
  131. arm966e = arm9tdmi->arch_info;
  132. if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
  133. {
  134. return -1;
  135. }
  136. *armv4_5_p = armv4_5;
  137. *arm7_9_p = arm7_9;
  138. *arm9tdmi_p = arm9tdmi;
  139. *arm966e_p = arm966e;
  140. return ERROR_OK;
  141. }
  142. int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
  143. {
  144. armv4_5_common_t *armv4_5 = target->arch_info;
  145. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  146. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  147. scan_field_t fields[3];
  148. u8 reg_addr_buf = reg_addr & 0x3f;
  149. u8 nr_w_buf = 0;
  150. jtag_add_end_state(TAP_RTI);
  151. arm_jtag_scann(jtag_info, 0xf);
  152. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  153. fields[0].device = jtag_info->chain_pos;
  154. fields[0].num_bits = 32;
  155. fields[0].out_value = NULL;
  156. fields[0].out_mask = NULL;
  157. fields[0].in_value = NULL;
  158. fields[0].in_check_value = NULL;
  159. fields[0].in_check_mask = NULL;
  160. fields[0].in_handler = NULL;
  161. fields[0].in_handler_priv = NULL;
  162. fields[1].device = jtag_info->chain_pos;
  163. fields[1].num_bits = 6;
  164. fields[1].out_value = &reg_addr_buf;
  165. fields[1].out_mask = NULL;
  166. fields[1].in_value = NULL;
  167. fields[1].in_check_value = NULL;
  168. fields[1].in_check_mask = NULL;
  169. fields[1].in_handler = NULL;
  170. fields[1].in_handler_priv = NULL;
  171. fields[2].device = jtag_info->chain_pos;
  172. fields[2].num_bits = 1;
  173. fields[2].out_value = &nr_w_buf;
  174. fields[2].out_mask = NULL;
  175. fields[2].in_value = NULL;
  176. fields[2].in_check_value = NULL;
  177. fields[2].in_check_mask = NULL;
  178. fields[2].in_handler = NULL;
  179. fields[2].in_handler_priv = NULL;
  180. jtag_add_dr_scan(3, fields, -1, NULL);
  181. fields[0].in_value = (u8*)value;
  182. jtag_add_dr_scan(3, fields, -1, NULL);
  183. return ERROR_OK;
  184. }
  185. int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
  186. {
  187. armv4_5_common_t *armv4_5 = target->arch_info;
  188. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  189. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  190. scan_field_t fields[3];
  191. u8 reg_addr_buf = reg_addr & 0x3f;
  192. u8 nr_w_buf = 1;
  193. jtag_add_end_state(TAP_RTI);
  194. arm_jtag_scann(jtag_info, 0xf);
  195. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  196. fields[0].device = jtag_info->chain_pos;
  197. fields[0].num_bits = 32;
  198. fields[0].out_value = (u8*)&value;
  199. fields[0].out_mask = NULL;
  200. fields[0].in_value = NULL;
  201. fields[0].in_check_value = NULL;
  202. fields[0].in_check_mask = NULL;
  203. fields[0].in_handler = NULL;
  204. fields[0].in_handler_priv = NULL;
  205. fields[1].device = jtag_info->chain_pos;
  206. fields[1].num_bits = 6;
  207. fields[1].out_value = &reg_addr_buf;
  208. fields[1].out_mask = NULL;
  209. fields[1].in_value = NULL;
  210. fields[1].in_check_value = NULL;
  211. fields[1].in_check_mask = NULL;
  212. fields[1].in_handler = NULL;
  213. fields[1].in_handler_priv = NULL;
  214. fields[2].device = jtag_info->chain_pos;
  215. fields[2].num_bits = 1;
  216. fields[2].out_value = &nr_w_buf;
  217. fields[2].out_mask = NULL;
  218. fields[2].in_value = NULL;
  219. fields[2].in_check_value = NULL;
  220. fields[2].in_check_mask = NULL;
  221. fields[2].in_handler = NULL;
  222. fields[2].in_handler_priv = NULL;
  223. jtag_add_dr_scan(3, fields, -1, NULL);
  224. return ERROR_OK;
  225. }
  226. int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  227. {
  228. int retval;
  229. target_t *target = get_current_target(cmd_ctx);
  230. armv4_5_common_t *armv4_5;
  231. arm7_9_common_t *arm7_9;
  232. arm9tdmi_common_t *arm9tdmi;
  233. arm966e_common_t *arm966e;
  234. arm_jtag_t *jtag_info;
  235. if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
  236. {
  237. command_print(cmd_ctx, "current target isn't an ARM966e target");
  238. return ERROR_OK;
  239. }
  240. jtag_info = &arm7_9->jtag_info;
  241. if (target->state != TARGET_HALTED)
  242. {
  243. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  244. return ERROR_OK;
  245. }
  246. /* one or more argument, access a single register (write if second argument is given */
  247. if (argc >= 1)
  248. {
  249. int address = strtoul(args[0], NULL, 0);
  250. if (argc == 1)
  251. {
  252. u32 value;
  253. if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
  254. {
  255. command_print(cmd_ctx, "couldn't access reg %i", address);
  256. return ERROR_OK;
  257. }
  258. jtag_execute_queue();
  259. command_print(cmd_ctx, "%i: %8.8x", address, value);
  260. }
  261. else if (argc == 2)
  262. {
  263. u32 value = strtoul(args[1], NULL, 0);
  264. if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
  265. {
  266. command_print(cmd_ctx, "couldn't access reg %i", address);
  267. return ERROR_OK;
  268. }
  269. command_print(cmd_ctx, "%i: %8.8x", address, value);
  270. }
  271. }
  272. return ERROR_OK;
  273. }
  274. int arm966e_register_commands(struct command_context_s *cmd_ctx)
  275. {
  276. int retval;
  277. command_t *arm966e_cmd;
  278. retval = arm9tdmi_register_commands(cmd_ctx);
  279. arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
  280. register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
  281. return ERROR_OK;
  282. }