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.
 
 
 
 
 
 

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