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.
 
 
 
 
 
 

411 lines
11 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_deassert_reset(target_t *target);
  41. int arm966e_assert_reset(target_t *target);
  42. int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
  43. int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
  44. int arm966e_quit(void);
  45. target_type_t arm966e_target =
  46. {
  47. .name = "arm966e",
  48. .poll = arm7_9_poll,
  49. .arch_state = armv4_5_arch_state,
  50. .halt = arm7_9_halt,
  51. .resume = arm7_9_resume,
  52. .step = arm7_9_step,
  53. .assert_reset = arm966e_assert_reset,
  54. .deassert_reset = arm966e_deassert_reset,
  55. .soft_reset_halt = arm7_9_soft_reset_halt,
  56. .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
  57. .read_memory = arm7_9_read_memory,
  58. .write_memory = arm7_9_write_memory,
  59. .bulk_write_memory = arm7_9_bulk_write_memory,
  60. .run_algorithm = armv4_5_run_algorithm,
  61. .add_breakpoint = arm7_9_add_breakpoint,
  62. .remove_breakpoint = arm7_9_remove_breakpoint,
  63. .add_watchpoint = arm7_9_add_watchpoint,
  64. .remove_watchpoint = arm7_9_remove_watchpoint,
  65. .register_commands = arm966e_register_commands,
  66. .target_command = arm966e_target_command,
  67. .init_target = arm966e_init_target,
  68. .quit = arm966e_quit,
  69. };
  70. int arm966e_assert_reset(target_t *target)
  71. {
  72. int retval;
  73. DEBUG("target->state: %s", target_state_strings[target->state]);
  74. if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
  75. {
  76. /* assert SRST and TRST */
  77. /* system would get ouf sync if we didn't reset test-logic, too */
  78. if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
  79. {
  80. if (retval == ERROR_JTAG_RESET_CANT_SRST)
  81. {
  82. WARNING("can't assert srst");
  83. return retval;
  84. }
  85. else
  86. {
  87. ERROR("unknown error");
  88. exit(-1);
  89. }
  90. }
  91. jtag_add_sleep(5000);
  92. if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
  93. {
  94. if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
  95. {
  96. WARNING("srst resets test logic, too");
  97. retval = jtag_add_reset(1, 1);
  98. }
  99. }
  100. }
  101. else
  102. {
  103. if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
  104. {
  105. if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
  106. {
  107. WARNING("srst resets test logic, too");
  108. retval = jtag_add_reset(1, 1);
  109. }
  110. if (retval == ERROR_JTAG_RESET_CANT_SRST)
  111. {
  112. WARNING("can't assert srst");
  113. return retval;
  114. }
  115. else if (retval != ERROR_OK)
  116. {
  117. ERROR("unknown error");
  118. exit(-1);
  119. }
  120. }
  121. }
  122. target->state = TARGET_RESET;
  123. jtag_add_sleep(50000);
  124. armv4_5_invalidate_core_regs(target);
  125. return ERROR_OK;
  126. }
  127. int arm966e_deassert_reset(target_t *target)
  128. {
  129. arm7_9_deassert_reset( target );
  130. return ERROR_OK;
  131. }
  132. int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
  133. {
  134. arm9tdmi_init_target(cmd_ctx, target);
  135. return ERROR_OK;
  136. }
  137. int arm966e_quit(void)
  138. {
  139. return ERROR_OK;
  140. }
  141. int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant)
  142. {
  143. arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common;
  144. arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
  145. arm9tdmi->arch_info = arm966e;
  146. arm966e->common_magic = ARM966E_COMMON_MAGIC;
  147. return ERROR_OK;
  148. }
  149. int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
  150. {
  151. int chain_pos;
  152. char *variant = NULL;
  153. arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t));
  154. if (argc < 4)
  155. {
  156. ERROR("'target arm966e' requires at least one additional argument");
  157. exit(-1);
  158. }
  159. chain_pos = strtoul(args[3], NULL, 0);
  160. if (argc >= 5)
  161. variant = args[4];
  162. DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
  163. arm966e_init_arch_info(target, arm966e, chain_pos, variant);
  164. return ERROR_OK;
  165. }
  166. 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)
  167. {
  168. armv4_5_common_t *armv4_5 = target->arch_info;
  169. arm7_9_common_t *arm7_9;
  170. arm9tdmi_common_t *arm9tdmi;
  171. arm966e_common_t *arm966e;
  172. if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
  173. {
  174. return -1;
  175. }
  176. arm7_9 = armv4_5->arch_info;
  177. if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
  178. {
  179. return -1;
  180. }
  181. arm9tdmi = arm7_9->arch_info;
  182. if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
  183. {
  184. return -1;
  185. }
  186. arm966e = arm9tdmi->arch_info;
  187. if (arm966e->common_magic != ARM966E_COMMON_MAGIC)
  188. {
  189. return -1;
  190. }
  191. *armv4_5_p = armv4_5;
  192. *arm7_9_p = arm7_9;
  193. *arm9tdmi_p = arm9tdmi;
  194. *arm966e_p = arm966e;
  195. return ERROR_OK;
  196. }
  197. int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value)
  198. {
  199. armv4_5_common_t *armv4_5 = target->arch_info;
  200. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  201. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  202. scan_field_t fields[3];
  203. u8 reg_addr_buf = reg_addr & 0x3f;
  204. u8 nr_w_buf = 0;
  205. jtag_add_end_state(TAP_RTI);
  206. arm_jtag_scann(jtag_info, 0xf);
  207. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
  208. fields[0].device = jtag_info->chain_pos;
  209. fields[0].num_bits = 32;
  210. fields[0].out_value = NULL;
  211. fields[0].out_mask = NULL;
  212. fields[0].in_value = NULL;
  213. fields[0].in_check_value = NULL;
  214. fields[0].in_check_mask = NULL;
  215. fields[0].in_handler = NULL;
  216. fields[0].in_handler_priv = NULL;
  217. fields[1].device = jtag_info->chain_pos;
  218. fields[1].num_bits = 6;
  219. fields[1].out_value = &reg_addr_buf;
  220. fields[1].out_mask = NULL;
  221. fields[1].in_value = NULL;
  222. fields[1].in_check_value = NULL;
  223. fields[1].in_check_mask = NULL;
  224. fields[1].in_handler = NULL;
  225. fields[1].in_handler_priv = NULL;
  226. fields[2].device = jtag_info->chain_pos;
  227. fields[2].num_bits = 1;
  228. fields[2].out_value = &nr_w_buf;
  229. fields[2].out_mask = NULL;
  230. fields[2].in_value = NULL;
  231. fields[2].in_check_value = NULL;
  232. fields[2].in_check_mask = NULL;
  233. fields[2].in_handler = NULL;
  234. fields[2].in_handler_priv = NULL;
  235. jtag_add_dr_scan(3, fields, -1);
  236. fields[0].in_value = (u8*)value;
  237. jtag_add_dr_scan(3, fields, -1);
  238. return ERROR_OK;
  239. }
  240. int arm966e_write_cp15(target_t *target, int reg_addr, u32 value)
  241. {
  242. armv4_5_common_t *armv4_5 = target->arch_info;
  243. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  244. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  245. scan_field_t fields[3];
  246. u8 reg_addr_buf = reg_addr & 0x3f;
  247. u8 nr_w_buf = 1;
  248. jtag_add_end_state(TAP_RTI);
  249. arm_jtag_scann(jtag_info, 0xf);
  250. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
  251. fields[0].device = jtag_info->chain_pos;
  252. fields[0].num_bits = 32;
  253. fields[0].out_value = (u8*)&value;
  254. fields[0].out_mask = NULL;
  255. fields[0].in_value = NULL;
  256. fields[0].in_check_value = NULL;
  257. fields[0].in_check_mask = NULL;
  258. fields[0].in_handler = NULL;
  259. fields[0].in_handler_priv = NULL;
  260. fields[1].device = jtag_info->chain_pos;
  261. fields[1].num_bits = 6;
  262. fields[1].out_value = &reg_addr_buf;
  263. fields[1].out_mask = NULL;
  264. fields[1].in_value = NULL;
  265. fields[1].in_check_value = NULL;
  266. fields[1].in_check_mask = NULL;
  267. fields[1].in_handler = NULL;
  268. fields[1].in_handler_priv = NULL;
  269. fields[2].device = jtag_info->chain_pos;
  270. fields[2].num_bits = 1;
  271. fields[2].out_value = &nr_w_buf;
  272. fields[2].out_mask = NULL;
  273. fields[2].in_value = NULL;
  274. fields[2].in_check_value = NULL;
  275. fields[2].in_check_mask = NULL;
  276. fields[2].in_handler = NULL;
  277. fields[2].in_handler_priv = NULL;
  278. jtag_add_dr_scan(3, fields, -1);
  279. return ERROR_OK;
  280. }
  281. int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  282. {
  283. int retval;
  284. target_t *target = get_current_target(cmd_ctx);
  285. armv4_5_common_t *armv4_5;
  286. arm7_9_common_t *arm7_9;
  287. arm9tdmi_common_t *arm9tdmi;
  288. arm966e_common_t *arm966e;
  289. arm_jtag_t *jtag_info;
  290. if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK)
  291. {
  292. command_print(cmd_ctx, "current target isn't an ARM966e target");
  293. return ERROR_OK;
  294. }
  295. jtag_info = &arm7_9->jtag_info;
  296. if (target->state != TARGET_HALTED)
  297. {
  298. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  299. return ERROR_OK;
  300. }
  301. /* one or more argument, access a single register (write if second argument is given */
  302. if (argc >= 1)
  303. {
  304. int address = strtoul(args[0], NULL, 0);
  305. if (argc == 1)
  306. {
  307. u32 value;
  308. if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
  309. {
  310. command_print(cmd_ctx, "couldn't access reg %i", address);
  311. return ERROR_OK;
  312. }
  313. jtag_execute_queue();
  314. command_print(cmd_ctx, "%i: %8.8x", address, value);
  315. }
  316. else if (argc == 2)
  317. {
  318. u32 value = strtoul(args[1], NULL, 0);
  319. if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
  320. {
  321. command_print(cmd_ctx, "couldn't access reg %i", address);
  322. return ERROR_OK;
  323. }
  324. command_print(cmd_ctx, "%i: %8.8x", address, value);
  325. }
  326. }
  327. return ERROR_OK;
  328. }
  329. int arm966e_register_commands(struct command_context_s *cmd_ctx)
  330. {
  331. int retval;
  332. command_t *arm966e_cmd;
  333. retval = arm7_9_register_commands(cmd_ctx);
  334. arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands");
  335. register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
  336. return ERROR_OK;
  337. }