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.
 
 
 
 
 
 

1112 lines
33 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 "arm9tdmi.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 "etm.h"
  30. #include "etb.h"
  31. #include "log.h"
  32. #include "jtag.h"
  33. #include "arm_jtag.h"
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #if 0
  37. #define _DEBUG_INSTRUCTION_EXECUTION_
  38. #endif
  39. /* cli handling */
  40. int arm9tdmi_register_commands(struct command_context_s *cmd_ctx);
  41. int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  42. /* forward declarations */
  43. int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
  44. int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
  45. int arm9tdmi_quit();
  46. target_type_t arm9tdmi_target =
  47. {
  48. .name = "arm9tdmi",
  49. .poll = arm7_9_poll,
  50. .arch_state = armv4_5_arch_state,
  51. .halt = arm7_9_halt,
  52. .resume = arm7_9_resume,
  53. .step = arm7_9_step,
  54. .assert_reset = arm7_9_assert_reset,
  55. .deassert_reset = arm7_9_deassert_reset,
  56. .soft_reset_halt = arm7_9_soft_reset_halt,
  57. .prepare_reset_halt = arm7_9_prepare_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. .run_algorithm = armv4_5_run_algorithm,
  63. .add_breakpoint = arm7_9_add_breakpoint,
  64. .remove_breakpoint = arm7_9_remove_breakpoint,
  65. .add_watchpoint = arm7_9_add_watchpoint,
  66. .remove_watchpoint = arm7_9_remove_watchpoint,
  67. .register_commands = arm9tdmi_register_commands,
  68. .target_command = arm9tdmi_target_command,
  69. .init_target = arm9tdmi_init_target,
  70. .quit = arm9tdmi_quit
  71. };
  72. arm9tdmi_vector_t arm9tdmi_vectors[] =
  73. {
  74. {"reset", ARM9TDMI_RESET_VECTOR},
  75. {"undef", ARM9TDMI_UNDEF_VECTOR},
  76. {"swi", ARM9TDMI_SWI_VECTOR},
  77. {"pabt", ARM9TDMI_PABT_VECTOR},
  78. {"dabt", ARM9TDMI_DABT_VECTOR},
  79. {"reserved", ARM9TDMI_RESERVED_VECTOR},
  80. {"irq", ARM9TDMI_IRQ_VECTOR},
  81. {"fiq", ARM9TDMI_FIQ_VECTOR},
  82. {0, 0},
  83. };
  84. int arm9tdmi_jtag_error_handler(u8 *in_value, void *priv)
  85. {
  86. char *caller = priv;
  87. DEBUG("caller: %s", caller);
  88. return ERROR_JTAG_QUEUE_FAILED;
  89. }
  90. int arm9tdmi_examine_debug_reason(target_t *target)
  91. {
  92. /* get pointers to arch-specific information */
  93. armv4_5_common_t *armv4_5 = target->arch_info;
  94. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  95. /* only check the debug reason if we don't know it already */
  96. if ((target->debug_reason != DBG_REASON_DBGRQ)
  97. && (target->debug_reason != DBG_REASON_SINGLESTEP))
  98. {
  99. scan_field_t fields[3];
  100. u8 databus[4];
  101. u8 instructionbus[4];
  102. u8 debug_reason;
  103. jtag_add_end_state(TAP_PD);
  104. fields[0].device = arm7_9->jtag_info.chain_pos;
  105. fields[0].num_bits = 32;
  106. fields[0].out_value = NULL;
  107. fields[0].out_mask = NULL;
  108. fields[0].in_value = databus;
  109. fields[0].in_check_value = NULL;
  110. fields[0].in_check_mask = NULL;
  111. fields[0].in_handler = NULL;
  112. fields[0].in_handler_priv = NULL;
  113. fields[1].device = arm7_9->jtag_info.chain_pos;
  114. fields[1].num_bits = 3;
  115. fields[1].out_value = NULL;
  116. fields[1].out_mask = NULL;
  117. fields[1].in_value = &debug_reason;
  118. fields[1].in_check_value = NULL;
  119. fields[1].in_check_mask = NULL;
  120. fields[1].in_handler = NULL;
  121. fields[1].in_handler_priv = NULL;
  122. fields[2].device = arm7_9->jtag_info.chain_pos;
  123. fields[2].num_bits = 32;
  124. fields[2].out_value = NULL;
  125. fields[2].out_mask = NULL;
  126. fields[2].in_value = instructionbus;
  127. fields[2].in_check_value = NULL;
  128. fields[2].in_check_mask = NULL;
  129. fields[2].in_handler = NULL;
  130. fields[2].in_handler_priv = NULL;
  131. arm_jtag_scann(&arm7_9->jtag_info, 0x1);
  132. arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
  133. jtag_add_dr_scan(3, fields, TAP_PD, NULL);
  134. jtag_execute_queue();
  135. fields[0].in_value = NULL;
  136. fields[0].out_value = databus;
  137. fields[1].in_value = NULL;
  138. fields[1].out_value = &debug_reason;
  139. fields[2].in_value = NULL;
  140. fields[2].out_value = instructionbus;
  141. jtag_add_dr_scan(3, fields, TAP_PD, NULL);
  142. if (debug_reason & 0x4)
  143. if (debug_reason & 0x2)
  144. target->debug_reason = DBG_REASON_WPTANDBKPT;
  145. else
  146. target->debug_reason = DBG_REASON_WATCHPOINT;
  147. else
  148. target->debug_reason = DBG_REASON_BREAKPOINT;
  149. }
  150. return ERROR_OK;
  151. }
  152. /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
  153. int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
  154. {
  155. scan_field_t fields[3];
  156. u8 out_buf[4];
  157. u8 instr_buf[4];
  158. u8 sysspeed_buf = 0x0;
  159. /* prepare buffer */
  160. buf_set_u32(out_buf, 0, 32, out);
  161. buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
  162. if (sysspeed)
  163. buf_set_u32(&sysspeed_buf, 2, 1, 1);
  164. jtag_add_end_state(TAP_PD);
  165. arm_jtag_scann(jtag_info, 0x1);
  166. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  167. fields[0].device = jtag_info->chain_pos;
  168. fields[0].num_bits = 32;
  169. fields[0].out_value = out_buf;
  170. fields[0].out_mask = NULL;
  171. fields[0].in_value = NULL;
  172. if (in)
  173. {
  174. fields[0].in_handler = arm_jtag_buf_to_u32;
  175. fields[0].in_handler_priv = in;
  176. }
  177. else
  178. {
  179. fields[0].in_handler = NULL;
  180. fields[0].in_handler_priv = NULL;
  181. }
  182. fields[0].in_check_value = NULL;
  183. fields[0].in_check_mask = NULL;
  184. fields[1].device = jtag_info->chain_pos;
  185. fields[1].num_bits = 3;
  186. fields[1].out_value = &sysspeed_buf;
  187. fields[1].out_mask = NULL;
  188. fields[1].in_value = NULL;
  189. fields[1].in_check_value = NULL;
  190. fields[1].in_check_mask = NULL;
  191. fields[1].in_handler = NULL;
  192. fields[1].in_handler_priv = NULL;
  193. fields[2].device = jtag_info->chain_pos;
  194. fields[2].num_bits = 32;
  195. fields[2].out_value = instr_buf;
  196. fields[2].out_mask = NULL;
  197. fields[2].in_value = NULL;
  198. fields[2].in_check_value = NULL;
  199. fields[2].in_check_mask = NULL;
  200. fields[2].in_handler = NULL;
  201. fields[2].in_handler_priv = NULL;
  202. jtag_add_dr_scan(3, fields, -1, NULL);
  203. jtag_add_runtest(0, -1);
  204. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  205. {
  206. jtag_execute_queue();
  207. if (in)
  208. {
  209. DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
  210. }
  211. else
  212. DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
  213. }
  214. #endif
  215. return ERROR_OK;
  216. }
  217. /* just read data (instruction and data-out = don't care) */
  218. int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
  219. {
  220. scan_field_t fields[3];
  221. jtag_add_end_state(TAP_PD);
  222. arm_jtag_scann(jtag_info, 0x1);
  223. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  224. fields[0].device = jtag_info->chain_pos;
  225. fields[0].num_bits = 32;
  226. fields[0].out_value = NULL;
  227. fields[0].out_mask = NULL;
  228. fields[0].in_value = NULL;
  229. fields[0].in_handler = arm_jtag_buf_to_u32;
  230. fields[0].in_handler_priv = in;
  231. fields[0].in_check_value = NULL;
  232. fields[0].in_check_mask = NULL;
  233. fields[1].device = jtag_info->chain_pos;
  234. fields[1].num_bits = 3;
  235. fields[1].out_value = NULL;
  236. fields[1].out_mask = NULL;
  237. fields[1].in_value = NULL;
  238. fields[1].in_handler = NULL;
  239. fields[1].in_handler_priv = NULL;
  240. fields[1].in_check_value = NULL;
  241. fields[1].in_check_mask = NULL;
  242. fields[2].device = jtag_info->chain_pos;
  243. fields[2].num_bits = 32;
  244. fields[2].out_value = NULL;
  245. fields[2].out_mask = NULL;
  246. fields[2].in_value = NULL;
  247. fields[2].in_check_value = NULL;
  248. fields[2].in_check_mask = NULL;
  249. fields[2].in_handler = NULL;
  250. fields[2].in_handler_priv = NULL;
  251. jtag_add_dr_scan(3, fields, -1, NULL);
  252. jtag_add_runtest(0, -1);
  253. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  254. {
  255. jtag_execute_queue();
  256. if (in)
  257. {
  258. DEBUG("in: 0x%8.8x", *in);
  259. }
  260. else
  261. {
  262. ERROR("BUG: called with in == NULL");
  263. }
  264. }
  265. #endif
  266. return ERROR_OK;
  267. }
  268. /* clock the target, and read the databus
  269. * the *in pointer points to a buffer where elements of 'size' bytes
  270. * are stored in big (be==1) or little (be==0) endianness
  271. */
  272. int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
  273. {
  274. scan_field_t fields[3];
  275. jtag_add_end_state(TAP_PD);
  276. arm_jtag_scann(jtag_info, 0x1);
  277. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  278. fields[0].device = jtag_info->chain_pos;
  279. fields[0].num_bits = 32;
  280. fields[0].out_value = NULL;
  281. fields[0].out_mask = NULL;
  282. fields[0].in_value = NULL;
  283. switch (size)
  284. {
  285. case 4:
  286. fields[0].in_handler = (be) ? arm_jtag_buf_to_be32 : arm_jtag_buf_to_le32;
  287. break;
  288. case 2:
  289. fields[0].in_handler = (be) ? arm_jtag_buf_to_be16 : arm_jtag_buf_to_le16;
  290. break;
  291. case 1:
  292. fields[0].in_handler = arm_jtag_buf_to_8;
  293. break;
  294. }
  295. fields[0].in_handler_priv = in;
  296. fields[0].in_check_value = NULL;
  297. fields[0].in_check_mask = NULL;
  298. fields[1].device = jtag_info->chain_pos;
  299. fields[1].num_bits = 3;
  300. fields[1].out_value = NULL;
  301. fields[1].out_mask = NULL;
  302. fields[1].in_value = NULL;
  303. fields[1].in_handler = NULL;
  304. fields[1].in_handler_priv = NULL;
  305. fields[1].in_check_value = NULL;
  306. fields[1].in_check_mask = NULL;
  307. fields[2].device = jtag_info->chain_pos;
  308. fields[2].num_bits = 32;
  309. fields[2].out_value = NULL;
  310. fields[2].out_mask = NULL;
  311. fields[2].in_value = NULL;
  312. fields[2].in_check_value = NULL;
  313. fields[2].in_check_mask = NULL;
  314. fields[2].in_handler = NULL;
  315. fields[2].in_handler_priv = NULL;
  316. jtag_add_dr_scan(3, fields, -1, NULL);
  317. jtag_add_runtest(0, -1);
  318. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  319. {
  320. jtag_execute_queue();
  321. if (in)
  322. {
  323. DEBUG("in: 0x%8.8x", *in);
  324. }
  325. else
  326. {
  327. ERROR("BUG: called with in == NULL");
  328. }
  329. }
  330. #endif
  331. return ERROR_OK;
  332. }
  333. void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
  334. {
  335. /* get pointers to arch-specific information */
  336. armv4_5_common_t *armv4_5 = target->arch_info;
  337. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  338. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  339. /* save r0 before using it and put system in ARM state
  340. * to allow common handling of ARM and THUMB debugging */
  341. /* fetch STR r0, [r0] */
  342. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
  343. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  344. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  345. /* STR r0, [r0] in Memory */
  346. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
  347. /* MOV r0, r15 fetched, STR in Decode */
  348. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
  349. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  350. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
  351. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  352. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  353. /* nothing fetched, STR r0, [r0] in Memory */
  354. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
  355. /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
  356. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
  357. /* LDR in Decode */
  358. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  359. /* LDR in Execute */
  360. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  361. /* LDR in Memory (to account for interlock) */
  362. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  363. /* fetch BX */
  364. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
  365. /* NOP fetched, BX in Decode, MOV in Execute */
  366. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  367. /* NOP fetched, BX in Execute (1) */
  368. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  369. jtag_execute_queue();
  370. /* fix program counter:
  371. * MOV r0, r15 was the 5th instruction (+8)
  372. * reading PC in Thumb state gives address of instruction + 4
  373. */
  374. *pc -= 0xc;
  375. }
  376. void arm9tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
  377. {
  378. int i;
  379. /* get pointers to arch-specific information */
  380. armv4_5_common_t *armv4_5 = target->arch_info;
  381. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  382. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  383. /* STMIA r0-15, [r0] at debug speed
  384. * register values will start to appear on 4th DCLK
  385. */
  386. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  387. /* fetch NOP, STM in DECODE stage */
  388. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  389. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  390. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  391. for (i = 0; i <= 15; i++)
  392. {
  393. if (mask & (1 << i))
  394. /* nothing fetched, STM in MEMORY (i'th cycle) */
  395. arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
  396. }
  397. }
  398. void arm9tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
  399. {
  400. int i;
  401. /* get pointers to arch-specific information */
  402. armv4_5_common_t *armv4_5 = target->arch_info;
  403. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  404. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  405. int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
  406. u32 *buf_u32 = buffer;
  407. u16 *buf_u16 = buffer;
  408. u8 *buf_u8 = buffer;
  409. /* STMIA r0-15, [r0] at debug speed
  410. * register values will start to appear on 4th DCLK
  411. */
  412. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  413. /* fetch NOP, STM in DECODE stage */
  414. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  415. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  416. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  417. for (i = 0; i <= 15; i++)
  418. {
  419. if (mask & (1 << i))
  420. /* nothing fetched, STM in MEMORY (i'th cycle) */
  421. switch (size)
  422. {
  423. case 4:
  424. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
  425. break;
  426. case 2:
  427. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
  428. break;
  429. case 1:
  430. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
  431. break;
  432. }
  433. }
  434. }
  435. void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
  436. {
  437. /* get pointers to arch-specific information */
  438. armv4_5_common_t *armv4_5 = target->arch_info;
  439. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  440. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  441. /* MRS r0, cpsr */
  442. arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
  443. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  444. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  445. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  446. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  447. /* STR r0, [r15] */
  448. arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
  449. /* fetch NOP, STR in DECODE stage */
  450. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  451. /* fetch NOP, STR in EXECUTE stage (1st cycle) */
  452. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  453. /* nothing fetched, STR in MEMORY */
  454. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
  455. }
  456. void arm9tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
  457. {
  458. /* get pointers to arch-specific information */
  459. armv4_5_common_t *armv4_5 = target->arch_info;
  460. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  461. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  462. DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
  463. /* MSR1 fetched */
  464. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
  465. /* MSR2 fetched, MSR1 in DECODE */
  466. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
  467. /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
  468. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
  469. /* nothing fetched, MSR1 in EXECUTE (2) */
  470. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  471. /* nothing fetched, MSR1 in EXECUTE (3) */
  472. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  473. /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
  474. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
  475. /* nothing fetched, MSR2 in EXECUTE (2) */
  476. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  477. /* nothing fetched, MSR2 in EXECUTE (3) */
  478. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  479. /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
  480. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  481. /* nothing fetched, MSR3 in EXECUTE (2) */
  482. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  483. /* nothing fetched, MSR3 in EXECUTE (3) */
  484. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  485. /* NOP fetched, MSR4 in EXECUTE (1) */
  486. /* last MSR writes flags, which takes only one cycle */
  487. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  488. }
  489. void arm9tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
  490. {
  491. /* get pointers to arch-specific information */
  492. armv4_5_common_t *armv4_5 = target->arch_info;
  493. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  494. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  495. DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
  496. /* MSR fetched */
  497. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
  498. /* NOP fetched, MSR in DECODE */
  499. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  500. /* NOP fetched, MSR in EXECUTE (1) */
  501. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  502. /* rot == 4 writes flags, which takes only one cycle */
  503. if (rot != 4)
  504. {
  505. /* nothing fetched, MSR in EXECUTE (2) */
  506. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  507. /* nothing fetched, MSR in EXECUTE (3) */
  508. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  509. }
  510. }
  511. void arm9tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
  512. {
  513. int i;
  514. /* get pointers to arch-specific information */
  515. armv4_5_common_t *armv4_5 = target->arch_info;
  516. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  517. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  518. /* LDMIA r0-15, [r0] at debug speed
  519. * register values will start to appear on 4th DCLK
  520. */
  521. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  522. /* fetch NOP, LDM in DECODE stage */
  523. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  524. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  525. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  526. for (i = 0; i <= 15; i++)
  527. {
  528. if (mask & (1 << i))
  529. /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
  530. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
  531. }
  532. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  533. }
  534. void arm9tdmi_load_word_regs(target_t *target, u32 mask)
  535. {
  536. /* get pointers to arch-specific information */
  537. armv4_5_common_t *armv4_5 = target->arch_info;
  538. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  539. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  540. /* put system-speed load-multiple into the pipeline */
  541. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
  542. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  543. }
  544. void arm9tdmi_load_hword_reg(target_t *target, int num)
  545. {
  546. /* get pointers to arch-specific information */
  547. armv4_5_common_t *armv4_5 = target->arch_info;
  548. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  549. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  550. /* put system-speed load half-word into the pipeline */
  551. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
  552. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  553. }
  554. void arm9tdmi_load_byte_reg(target_t *target, int num)
  555. {
  556. /* get pointers to arch-specific information */
  557. armv4_5_common_t *armv4_5 = target->arch_info;
  558. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  559. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  560. /* put system-speed load byte into the pipeline */
  561. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
  562. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  563. }
  564. void arm9tdmi_store_word_regs(target_t *target, u32 mask)
  565. {
  566. /* get pointers to arch-specific information */
  567. armv4_5_common_t *armv4_5 = target->arch_info;
  568. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  569. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  570. /* put system-speed store-multiple into the pipeline */
  571. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
  572. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  573. }
  574. void arm9tdmi_store_hword_reg(target_t *target, int num)
  575. {
  576. /* get pointers to arch-specific information */
  577. armv4_5_common_t *armv4_5 = target->arch_info;
  578. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  579. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  580. /* put system-speed store half-word into the pipeline */
  581. arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
  582. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  583. }
  584. void arm9tdmi_store_byte_reg(target_t *target, int num)
  585. {
  586. /* get pointers to arch-specific information */
  587. armv4_5_common_t *armv4_5 = target->arch_info;
  588. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  589. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  590. /* put system-speed store byte into the pipeline */
  591. arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
  592. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  593. }
  594. void arm9tdmi_write_pc(target_t *target, u32 pc)
  595. {
  596. /* get pointers to arch-specific information */
  597. armv4_5_common_t *armv4_5 = target->arch_info;
  598. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  599. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  600. /* LDMIA r0-15, [r0] at debug speed
  601. * register values will start to appear on 4th DCLK
  602. */
  603. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
  604. /* fetch NOP, LDM in DECODE stage */
  605. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  606. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  607. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  608. /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
  609. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
  610. /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
  611. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  612. /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
  613. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  614. /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
  615. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  616. }
  617. void arm9tdmi_branch_resume(target_t *target)
  618. {
  619. /* get pointers to arch-specific information */
  620. armv4_5_common_t *armv4_5 = target->arch_info;
  621. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  622. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  623. arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
  624. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  625. }
  626. void arm9tdmi_branch_resume_thumb(target_t *target)
  627. {
  628. DEBUG("-");
  629. /* get pointers to arch-specific information */
  630. armv4_5_common_t *armv4_5 = target->arch_info;
  631. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  632. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  633. reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
  634. /* LDMIA r0-15, [r0] at debug speed
  635. * register values will start to appear on 4th DCLK
  636. */
  637. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
  638. /* fetch NOP, LDM in DECODE stage */
  639. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  640. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  641. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  642. /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
  643. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
  644. /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
  645. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  646. /* Branch and eXchange */
  647. arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
  648. embeddedice_read_reg(dbg_stat);
  649. /* fetch NOP, BX in DECODE stage */
  650. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  651. embeddedice_read_reg(dbg_stat);
  652. /* fetch NOP, BX in EXECUTE stage (1st cycle) */
  653. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  654. /* target is now in Thumb state */
  655. embeddedice_read_reg(dbg_stat);
  656. /* load r0 value, MOV_IM in Decode*/
  657. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
  658. /* fetch NOP, LDR in Decode, MOV_IM in Execute */
  659. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  660. /* fetch NOP, LDR in Execute */
  661. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  662. /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
  663. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
  664. /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
  665. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  666. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  667. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  668. embeddedice_read_reg(dbg_stat);
  669. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);
  670. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  671. }
  672. void arm9tdmi_enable_single_step(target_t *target)
  673. {
  674. /* get pointers to arch-specific information */
  675. armv4_5_common_t *armv4_5 = target->arch_info;
  676. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  677. if (arm7_9->has_single_step)
  678. {
  679. buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
  680. embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
  681. }
  682. else
  683. {
  684. arm7_9_enable_eice_step(target);
  685. }
  686. }
  687. void arm9tdmi_disable_single_step(target_t *target)
  688. {
  689. /* get pointers to arch-specific information */
  690. armv4_5_common_t *armv4_5 = target->arch_info;
  691. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  692. if (arm7_9->has_single_step)
  693. {
  694. buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
  695. embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
  696. }
  697. else
  698. {
  699. arm7_9_disable_eice_step(target);
  700. }
  701. }
  702. void arm9tdmi_build_reg_cache(target_t *target)
  703. {
  704. reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
  705. /* get pointers to arch-specific information */
  706. armv4_5_common_t *armv4_5 = target->arch_info;
  707. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  708. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  709. (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
  710. armv4_5->core_cache = (*cache_p);
  711. /* one extra register (vector catch) */
  712. (*cache_p)->next = embeddedice_build_reg_cache(target, arm7_9);
  713. arm7_9->eice_cache = (*cache_p)->next;
  714. if (arm7_9->etm_ctx)
  715. {
  716. (*cache_p)->next->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
  717. arm7_9->etm_ctx->reg_cache = (*cache_p)->next->next;
  718. }
  719. }
  720. int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
  721. {
  722. arm9tdmi_build_reg_cache(target);
  723. return ERROR_OK;
  724. }
  725. int arm9tdmi_quit()
  726. {
  727. return ERROR_OK;
  728. }
  729. int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int chain_pos, char *variant)
  730. {
  731. armv4_5_common_t *armv4_5;
  732. arm7_9_common_t *arm7_9;
  733. arm7_9 = &arm9tdmi->arm7_9_common;
  734. armv4_5 = &arm7_9->armv4_5_common;
  735. /* prepare JTAG information for the new target */
  736. arm7_9->jtag_info.chain_pos = chain_pos;
  737. arm7_9->jtag_info.scann_size = 5;
  738. /* register arch-specific functions */
  739. arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
  740. arm7_9->change_to_arm = arm9tdmi_change_to_arm;
  741. arm7_9->read_core_regs = arm9tdmi_read_core_regs;
  742. arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
  743. arm7_9->read_xpsr = arm9tdmi_read_xpsr;
  744. arm7_9->write_xpsr = arm9tdmi_write_xpsr;
  745. arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
  746. arm7_9->write_core_regs = arm9tdmi_write_core_regs;
  747. arm7_9->load_word_regs = arm9tdmi_load_word_regs;
  748. arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
  749. arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
  750. arm7_9->store_word_regs = arm9tdmi_store_word_regs;
  751. arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
  752. arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
  753. arm7_9->write_pc = arm9tdmi_write_pc;
  754. arm7_9->branch_resume = arm9tdmi_branch_resume;
  755. arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
  756. arm7_9->enable_single_step = arm9tdmi_enable_single_step;
  757. arm7_9->disable_single_step = arm9tdmi_disable_single_step;
  758. arm7_9->pre_debug_entry = NULL;
  759. arm7_9->post_debug_entry = NULL;
  760. arm7_9->pre_restore_context = NULL;
  761. arm7_9->post_restore_context = NULL;
  762. /* initialize arch-specific breakpoint handling */
  763. arm7_9->arm_bkpt = 0xdeeedeee;
  764. arm7_9->thumb_bkpt = 0xdeee;
  765. arm7_9->sw_bkpts_use_wp = 1;
  766. arm7_9->sw_bkpts_enabled = 0;
  767. arm7_9->dbgreq_adjust_pc = 3;
  768. arm7_9->arch_info = arm9tdmi;
  769. arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
  770. arm9tdmi->arch_info = NULL;
  771. if (variant)
  772. {
  773. arm9tdmi->variant = strdup(variant);
  774. }
  775. else
  776. {
  777. arm9tdmi->variant = strdup("");
  778. }
  779. arm7_9_init_arch_info(target, arm7_9);
  780. /* override use of DBGRQ, this is safe on ARM9TDMI */
  781. arm7_9->use_dbgrq = 1;
  782. /* all ARM9s have the vector catch register */
  783. arm7_9->has_vector_catch = 1;
  784. return ERROR_OK;
  785. }
  786. int arm9tdmi_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)
  787. {
  788. armv4_5_common_t *armv4_5 = target->arch_info;
  789. arm7_9_common_t *arm7_9;
  790. arm9tdmi_common_t *arm9tdmi;
  791. if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
  792. {
  793. return -1;
  794. }
  795. arm7_9 = armv4_5->arch_info;
  796. if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
  797. {
  798. return -1;
  799. }
  800. arm9tdmi = arm7_9->arch_info;
  801. if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
  802. {
  803. return -1;
  804. }
  805. *armv4_5_p = armv4_5;
  806. *arm7_9_p = arm7_9;
  807. *arm9tdmi_p = arm9tdmi;
  808. return ERROR_OK;
  809. }
  810. /* target arm9tdmi <endianess> <startup_mode> <chain_pos> <variant>*/
  811. int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
  812. {
  813. int chain_pos;
  814. char *variant = NULL;
  815. arm9tdmi_common_t *arm9tdmi = malloc(sizeof(arm9tdmi_common_t));
  816. if (argc < 4)
  817. {
  818. ERROR("'target arm9tdmi' requires at least one additional argument");
  819. exit(-1);
  820. }
  821. chain_pos = strtoul(args[3], NULL, 0);
  822. if (argc >= 5)
  823. variant = args[4];
  824. arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
  825. return ERROR_OK;
  826. }
  827. int arm9tdmi_register_commands(struct command_context_s *cmd_ctx)
  828. {
  829. int retval;
  830. command_t *arm9tdmi_cmd;
  831. retval = arm7_9_register_commands(cmd_ctx);
  832. arm9tdmi_cmd = register_command(cmd_ctx, NULL, "arm9tdmi", NULL, COMMAND_ANY, "arm9tdmi specific commands");
  833. register_command(cmd_ctx, arm9tdmi_cmd, "vector_catch", handle_arm9tdmi_catch_vectors_command, COMMAND_EXEC, "catch arm920t vectors ['all'|'none'|'<vec1 vec2 ...>']");
  834. return ERROR_OK;
  835. }
  836. int handle_arm9tdmi_catch_vectors_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  837. {
  838. target_t *target = get_current_target(cmd_ctx);
  839. armv4_5_common_t *armv4_5;
  840. arm7_9_common_t *arm7_9;
  841. arm9tdmi_common_t *arm9tdmi;
  842. reg_t *vector_catch;
  843. u32 vector_catch_value;
  844. int i, j;
  845. if (arm9tdmi_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi) != ERROR_OK)
  846. {
  847. command_print(cmd_ctx, "current target isn't an ARM9TDMI based target");
  848. return ERROR_OK;
  849. }
  850. vector_catch = &arm7_9->eice_cache->reg_list[EICE_VEC_CATCH];
  851. /* read the vector catch register if necessary */
  852. if (!vector_catch->valid)
  853. embeddedice_read_reg(vector_catch);
  854. /* get the current setting */
  855. vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
  856. if (argc > 0)
  857. {
  858. vector_catch_value = 0x0;
  859. if (strcmp(args[0], "all") == 0)
  860. {
  861. vector_catch_value = 0xdf;
  862. }
  863. else if (strcmp(args[0], "none") == 0)
  864. {
  865. /* do nothing */
  866. }
  867. else
  868. {
  869. for (i = 0; i < argc; i++)
  870. {
  871. /* go through list of vectors */
  872. for(j = 0; arm9tdmi_vectors[j].name; j++)
  873. {
  874. if (strcmp(args[i], arm9tdmi_vectors[j].name) == 0)
  875. {
  876. vector_catch_value |= arm9tdmi_vectors[j].value;
  877. break;
  878. }
  879. }
  880. /* complain if vector wasn't found */
  881. if (!arm9tdmi_vectors[j].name)
  882. {
  883. command_print(cmd_ctx, "vector '%s' not found, leaving current setting unchanged", args[i]);
  884. /* reread current setting */
  885. vector_catch_value = buf_get_u32(vector_catch->value, 0, 32);
  886. break;
  887. }
  888. }
  889. }
  890. /* store new settings */
  891. buf_set_u32(vector_catch->value, 0, 32, vector_catch_value);
  892. embeddedice_store_reg(vector_catch);
  893. }
  894. /* output current settings (skip RESERVED vector) */
  895. for (i = 0; i < 8; i++)
  896. {
  897. if (i != 5)
  898. {
  899. command_print(cmd_ctx, "%s: %s", arm9tdmi_vectors[i].name,
  900. (vector_catch_value & (1 << i)) ? "catch" : "don't catch");
  901. }
  902. }
  903. return ERROR_OK;
  904. }