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.
 
 
 
 
 
 

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