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.
 
 
 
 
 
 

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