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.
 
 
 
 
 
 

843 lines
26 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) 2007,2008 Øyvind Harboe *
  9. * oyvind.harboe@zylin.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 "arm7tdmi.h"
  30. #include "target_type.h"
  31. #if 0
  32. #define _DEBUG_INSTRUCTION_EXECUTION_
  33. #endif
  34. /* forward declarations */
  35. int arm7tdmi_target_create(struct target_s *target,Jim_Interp *interp);
  36. int arm7tdmi_quit(void);
  37. /* target function declarations */
  38. int arm7tdmi_poll(struct target_s *target);
  39. int arm7tdmi_halt(target_t *target);
  40. target_type_t arm7tdmi_target =
  41. {
  42. .name = "arm7tdmi",
  43. .poll = arm7_9_poll,
  44. .arch_state = armv4_5_arch_state,
  45. .target_request_data = arm7_9_target_request_data,
  46. .halt = arm7_9_halt,
  47. .resume = arm7_9_resume,
  48. .step = arm7_9_step,
  49. .assert_reset = arm7_9_assert_reset,
  50. .deassert_reset = arm7_9_deassert_reset,
  51. .soft_reset_halt = arm7_9_soft_reset_halt,
  52. .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
  53. .read_memory = arm7_9_read_memory,
  54. .write_memory = arm7_9_write_memory,
  55. .bulk_write_memory = arm7_9_bulk_write_memory,
  56. .checksum_memory = arm7_9_checksum_memory,
  57. .blank_check_memory = arm7_9_blank_check_memory,
  58. .run_algorithm = armv4_5_run_algorithm,
  59. .add_breakpoint = arm7_9_add_breakpoint,
  60. .remove_breakpoint = arm7_9_remove_breakpoint,
  61. .add_watchpoint = arm7_9_add_watchpoint,
  62. .remove_watchpoint = arm7_9_remove_watchpoint,
  63. .register_commands = arm7tdmi_register_commands,
  64. .target_create = arm7tdmi_target_create,
  65. .init_target = arm7tdmi_init_target,
  66. .examine = arm7tdmi_examine,
  67. .quit = arm7tdmi_quit
  68. };
  69. int arm7tdmi_examine_debug_reason(target_t *target)
  70. {
  71. int retval = ERROR_OK;
  72. /* get pointers to arch-specific information */
  73. armv4_5_common_t *armv4_5 = target->arch_info;
  74. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  75. /* only check the debug reason if we don't know it already */
  76. if ((target->debug_reason != DBG_REASON_DBGRQ)
  77. && (target->debug_reason != DBG_REASON_SINGLESTEP))
  78. {
  79. scan_field_t fields[2];
  80. uint8_t databus[4];
  81. uint8_t breakpoint;
  82. jtag_set_end_state(TAP_DRPAUSE);
  83. fields[0].tap = arm7_9->jtag_info.tap;
  84. fields[0].num_bits = 1;
  85. fields[0].out_value = NULL;
  86. fields[0].in_value = &breakpoint;
  87. fields[1].tap = arm7_9->jtag_info.tap;
  88. fields[1].num_bits = 32;
  89. fields[1].out_value = NULL;
  90. fields[1].in_value = databus;
  91. if ((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1)) != ERROR_OK)
  92. {
  93. return retval;
  94. }
  95. arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL);
  96. jtag_add_dr_scan(2, fields, jtag_set_end_state(TAP_DRPAUSE));
  97. if ((retval = jtag_execute_queue()) != ERROR_OK)
  98. {
  99. return retval;
  100. }
  101. fields[0].in_value = NULL;
  102. fields[0].out_value = &breakpoint;
  103. fields[1].in_value = NULL;
  104. fields[1].out_value = databus;
  105. jtag_add_dr_scan(2, fields, jtag_set_end_state(TAP_DRPAUSE));
  106. if (breakpoint & 1)
  107. target->debug_reason = DBG_REASON_WATCHPOINT;
  108. else
  109. target->debug_reason = DBG_REASON_BREAKPOINT;
  110. }
  111. return ERROR_OK;
  112. }
  113. static int arm7tdmi_num_bits[]={1, 32};
  114. static __inline int arm7tdmi_clock_out_inner(arm_jtag_t *jtag_info, uint32_t out, int breakpoint)
  115. {
  116. uint32_t values[2]={breakpoint, flip_u32(out, 32)};
  117. jtag_add_dr_out(jtag_info->tap,
  118. 2,
  119. arm7tdmi_num_bits,
  120. values,
  121. jtag_get_end_state());
  122. jtag_add_runtest(0, jtag_get_end_state());
  123. return ERROR_OK;
  124. }
  125. /* put an instruction in the ARM7TDMI pipeline or write the data bus, and optionally read data */
  126. static __inline int arm7tdmi_clock_out(arm_jtag_t *jtag_info, uint32_t out, uint32_t *deprecated, int breakpoint)
  127. {
  128. jtag_set_end_state(TAP_DRPAUSE);
  129. arm_jtag_scann(jtag_info, 0x1);
  130. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  131. return arm7tdmi_clock_out_inner(jtag_info, out, breakpoint);
  132. }
  133. /* clock the target, reading the databus */
  134. int arm7tdmi_clock_data_in(arm_jtag_t *jtag_info, uint32_t *in)
  135. {
  136. int retval = ERROR_OK;
  137. scan_field_t fields[2];
  138. jtag_set_end_state(TAP_DRPAUSE);
  139. if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
  140. {
  141. return retval;
  142. }
  143. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  144. fields[0].tap = jtag_info->tap;
  145. fields[0].num_bits = 1;
  146. fields[0].out_value = NULL;
  147. fields[0].in_value = NULL;
  148. fields[1].tap = jtag_info->tap;
  149. fields[1].num_bits = 32;
  150. fields[1].out_value = NULL;
  151. fields[1].in_value = (uint8_t *)in;
  152. jtag_add_dr_scan(2, fields, jtag_get_end_state());
  153. jtag_add_callback(arm7flip32, (jtag_callback_data_t)in);
  154. jtag_add_runtest(0, jtag_get_end_state());
  155. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  156. {
  157. if ((retval = jtag_execute_queue()) != ERROR_OK)
  158. {
  159. return retval;
  160. }
  161. if (in)
  162. {
  163. LOG_DEBUG("in: 0x%8.8x", *in);
  164. }
  165. else
  166. {
  167. LOG_ERROR("BUG: called with in == NULL");
  168. }
  169. }
  170. #endif
  171. return ERROR_OK;
  172. }
  173. void arm_endianness(uint8_t *tmp, void *in, int size, int be, int flip)
  174. {
  175. uint32_t readback = le_to_h_u32(tmp);
  176. if (flip)
  177. readback = flip_u32(readback, 32);
  178. switch (size)
  179. {
  180. case 4:
  181. if (be)
  182. {
  183. h_u32_to_be(((uint8_t*)in), readback);
  184. } else
  185. {
  186. h_u32_to_le(((uint8_t*)in), readback);
  187. }
  188. break;
  189. case 2:
  190. if (be)
  191. {
  192. h_u16_to_be(((uint8_t*)in), readback & 0xffff);
  193. } else
  194. {
  195. h_u16_to_le(((uint8_t*)in), readback & 0xffff);
  196. }
  197. break;
  198. case 1:
  199. *((uint8_t *)in)= readback & 0xff;
  200. break;
  201. }
  202. }
  203. static int arm7endianness(jtag_callback_data_t arg, jtag_callback_data_t size, jtag_callback_data_t be, jtag_callback_data_t captured)
  204. {
  205. uint8_t *in = (uint8_t *)arg;
  206. arm_endianness((uint8_t *)captured, in, (int)size, (int)be, 1);
  207. return ERROR_OK;
  208. }
  209. /* clock the target, and read the databus
  210. * the *in pointer points to a buffer where elements of 'size' bytes
  211. * are stored in big (be == 1) or little (be == 0) endianness
  212. */
  213. int arm7tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
  214. {
  215. int retval = ERROR_OK;
  216. scan_field_t fields[2];
  217. jtag_set_end_state(TAP_DRPAUSE);
  218. if ((retval = arm_jtag_scann(jtag_info, 0x1)) != ERROR_OK)
  219. {
  220. return retval;
  221. }
  222. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  223. fields[0].tap = jtag_info->tap;
  224. fields[0].num_bits = 1;
  225. fields[0].out_value = NULL;
  226. fields[0].in_value = NULL;
  227. fields[1].tap = jtag_info->tap;
  228. fields[1].num_bits = 32;
  229. fields[1].out_value = NULL;
  230. jtag_alloc_in_value32(&fields[1]);
  231. jtag_add_dr_scan(2, fields, jtag_get_end_state());
  232. jtag_add_callback4(arm7endianness, (jtag_callback_data_t)in, (jtag_callback_data_t)size, (jtag_callback_data_t)be, (jtag_callback_data_t)fields[1].in_value);
  233. jtag_add_runtest(0, jtag_get_end_state());
  234. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  235. {
  236. if ((retval = jtag_execute_queue()) != ERROR_OK)
  237. {
  238. return retval;
  239. }
  240. if (in)
  241. {
  242. LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in);
  243. }
  244. else
  245. {
  246. LOG_ERROR("BUG: called with in == NULL");
  247. }
  248. }
  249. #endif
  250. return ERROR_OK;
  251. }
  252. void arm7tdmi_change_to_arm(target_t *target, uint32_t *r0, uint32_t *pc)
  253. {
  254. /* get pointers to arch-specific information */
  255. armv4_5_common_t *armv4_5 = target->arch_info;
  256. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  257. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  258. /* save r0 before using it and put system in ARM state
  259. * to allow common handling of ARM and THUMB debugging */
  260. /* fetch STR r0, [r0] */
  261. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
  262. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  263. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  264. /* nothing fetched, STR r0, [r0] in Execute (2) */
  265. arm7tdmi_clock_data_in(jtag_info, r0);
  266. /* MOV r0, r15 fetched, STR in Decode */
  267. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), NULL, 0);
  268. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), NULL, 0);
  269. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  270. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  271. /* nothing fetched, STR r0, [r0] in Execute (2) */
  272. arm7tdmi_clock_data_in(jtag_info, pc);
  273. /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
  274. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
  275. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  276. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  277. /* nothing fetched, data for LDR r0, [PC, #0] */
  278. arm7tdmi_clock_out(jtag_info, 0x0, NULL, 0);
  279. /* nothing fetched, data from previous cycle is written to register */
  280. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  281. /* fetch BX */
  282. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), NULL, 0);
  283. /* NOP fetched, BX in Decode, MOV in Execute */
  284. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  285. /* NOP fetched, BX in Execute (1) */
  286. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  287. jtag_execute_queue();
  288. /* fix program counter:
  289. * MOV r0, r15 was the 4th instruction (+6)
  290. * reading PC in Thumb state gives address of instruction + 4
  291. */
  292. *pc -= 0xa;
  293. }
  294. /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
  295. * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
  296. *
  297. * The solution is to arrange for a large out/in scan in this loop and
  298. * and convert data afterwards.
  299. */
  300. void arm7tdmi_read_core_regs(target_t *target, uint32_t mask, uint32_t* core_regs[16])
  301. {
  302. int i;
  303. /* get pointers to arch-specific information */
  304. armv4_5_common_t *armv4_5 = target->arch_info;
  305. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  306. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  307. /* STMIA r0-15, [r0] at debug speed
  308. * register values will start to appear on 4th DCLK
  309. */
  310. arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
  311. /* fetch NOP, STM in DECODE stage */
  312. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  313. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  314. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  315. for (i = 0; i <= 15; i++)
  316. {
  317. if (mask & (1 << i))
  318. /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
  319. arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
  320. }
  321. }
  322. void arm7tdmi_read_core_regs_target_buffer(target_t *target, uint32_t mask, void* buffer, int size)
  323. {
  324. int i;
  325. /* get pointers to arch-specific information */
  326. armv4_5_common_t *armv4_5 = target->arch_info;
  327. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  328. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  329. int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
  330. uint32_t *buf_u32 = buffer;
  331. uint16_t *buf_u16 = buffer;
  332. uint8_t *buf_u8 = buffer;
  333. /* STMIA r0-15, [r0] at debug speed
  334. * register values will start to appear on 4th DCLK
  335. */
  336. arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), NULL, 0);
  337. /* fetch NOP, STM in DECODE stage */
  338. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  339. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  340. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  341. for (i = 0; i <= 15; i++)
  342. {
  343. /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
  344. if (mask & (1 << i))
  345. {
  346. switch (size)
  347. {
  348. case 4:
  349. arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
  350. break;
  351. case 2:
  352. arm7tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
  353. break;
  354. case 1:
  355. arm7tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
  356. break;
  357. }
  358. }
  359. }
  360. }
  361. void arm7tdmi_read_xpsr(target_t *target, uint32_t *xpsr, int spsr)
  362. {
  363. /* get pointers to arch-specific information */
  364. armv4_5_common_t *armv4_5 = target->arch_info;
  365. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  366. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  367. /* MRS r0, cpsr */
  368. arm7tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), NULL, 0);
  369. /* STR r0, [r15] */
  370. arm7tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), NULL, 0);
  371. /* fetch NOP, STR in DECODE stage */
  372. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  373. /* fetch NOP, STR in EXECUTE stage (1st cycle) */
  374. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  375. /* nothing fetched, STR still in EXECUTE (2nd cycle) */
  376. arm7tdmi_clock_data_in(jtag_info, xpsr);
  377. }
  378. void arm7tdmi_write_xpsr(target_t *target, uint32_t xpsr, int spsr)
  379. {
  380. /* get pointers to arch-specific information */
  381. armv4_5_common_t *armv4_5 = target->arch_info;
  382. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  383. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  384. LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr);
  385. /* MSR1 fetched */
  386. arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), NULL, 0);
  387. /* MSR2 fetched, MSR1 in DECODE */
  388. arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), NULL, 0);
  389. /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
  390. arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), NULL, 0);
  391. /* nothing fetched, MSR1 in EXECUTE (2) */
  392. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  393. /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
  394. arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), NULL, 0);
  395. /* nothing fetched, MSR2 in EXECUTE (2) */
  396. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  397. /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
  398. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  399. /* nothing fetched, MSR3 in EXECUTE (2) */
  400. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  401. /* NOP fetched, MSR4 in EXECUTE (1) */
  402. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  403. /* nothing fetched, MSR4 in EXECUTE (2) */
  404. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  405. }
  406. void arm7tdmi_write_xpsr_im8(target_t *target, uint8_t xpsr_im, int rot, int spsr)
  407. {
  408. /* get pointers to arch-specific information */
  409. armv4_5_common_t *armv4_5 = target->arch_info;
  410. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  411. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  412. LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
  413. /* MSR fetched */
  414. arm7tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), NULL, 0);
  415. /* NOP fetched, MSR in DECODE */
  416. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  417. /* NOP fetched, MSR in EXECUTE (1) */
  418. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  419. /* nothing fetched, MSR in EXECUTE (2) */
  420. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  421. }
  422. void arm7tdmi_write_core_regs(target_t *target, uint32_t mask, uint32_t core_regs[16])
  423. {
  424. int i;
  425. /* get pointers to arch-specific information */
  426. armv4_5_common_t *armv4_5 = target->arch_info;
  427. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  428. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  429. /* LDMIA r0-15, [r0] at debug speed
  430. * register values will start to appear on 4th DCLK
  431. */
  432. arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), NULL, 0);
  433. /* fetch NOP, LDM in DECODE stage */
  434. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  435. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  436. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  437. for (i = 0; i <= 15; i++)
  438. {
  439. if (mask & (1 << i))
  440. /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
  441. arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);
  442. }
  443. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  444. }
  445. void arm7tdmi_load_word_regs(target_t *target, uint32_t mask)
  446. {
  447. /* get pointers to arch-specific information */
  448. armv4_5_common_t *armv4_5 = target->arch_info;
  449. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  450. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  451. /* put system-speed load-multiple into the pipeline */
  452. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  453. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
  454. arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), NULL, 0);
  455. }
  456. void arm7tdmi_load_hword_reg(target_t *target, int num)
  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. /* put system-speed load half-word into the pipeline */
  463. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  464. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
  465. arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), NULL, 0);
  466. }
  467. void arm7tdmi_load_byte_reg(target_t *target, int num)
  468. {
  469. /* get pointers to arch-specific information */
  470. armv4_5_common_t *armv4_5 = target->arch_info;
  471. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  472. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  473. /* put system-speed load byte into the pipeline */
  474. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  475. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
  476. arm7tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), NULL, 0);
  477. }
  478. void arm7tdmi_store_word_regs(target_t *target, uint32_t mask)
  479. {
  480. /* get pointers to arch-specific information */
  481. armv4_5_common_t *armv4_5 = target->arch_info;
  482. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  483. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  484. /* put system-speed store-multiple into the pipeline */
  485. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  486. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
  487. arm7tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), NULL, 0);
  488. }
  489. void arm7tdmi_store_hword_reg(target_t *target, int num)
  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. /* put system-speed store half-word into the pipeline */
  496. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  497. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
  498. arm7tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), NULL, 0);
  499. }
  500. void arm7tdmi_store_byte_reg(target_t *target, int num)
  501. {
  502. /* get pointers to arch-specific information */
  503. armv4_5_common_t *armv4_5 = target->arch_info;
  504. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  505. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  506. /* put system-speed store byte into the pipeline */
  507. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  508. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
  509. arm7tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), NULL, 0);
  510. }
  511. void arm7tdmi_write_pc(target_t *target, uint32_t pc)
  512. {
  513. /* get pointers to arch-specific information */
  514. armv4_5_common_t *armv4_5 = target->arch_info;
  515. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  516. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  517. /* LDMIA r0-15, [r0] at debug speed
  518. * register values will start to appear on 4th DCLK
  519. */
  520. arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), NULL, 0);
  521. /* fetch NOP, LDM in DECODE stage */
  522. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  523. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  524. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  525. /* nothing fetched, LDM in EXECUTE stage (1st cycle) load register */
  526. arm7tdmi_clock_out_inner(jtag_info, pc, 0);
  527. /* nothing fetched, LDM in EXECUTE stage (2nd cycle) load register */
  528. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  529. /* nothing fetched, LDM in EXECUTE stage (3rd cycle) load register */
  530. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  531. /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
  532. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  533. /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
  534. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
  535. }
  536. void arm7tdmi_branch_resume(target_t *target)
  537. {
  538. /* get pointers to arch-specific information */
  539. armv4_5_common_t *armv4_5 = target->arch_info;
  540. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  541. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  542. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 1);
  543. arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_B(0xfffffa, 0), 0);
  544. }
  545. void arm7tdmi_branch_resume_thumb(target_t *target)
  546. {
  547. LOG_DEBUG("-");
  548. /* get pointers to arch-specific information */
  549. armv4_5_common_t *armv4_5 = target->arch_info;
  550. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  551. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  552. reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
  553. /* LDMIA r0, [r0] at debug speed
  554. * register values will start to appear on 4th DCLK
  555. */
  556. arm7tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), NULL, 0);
  557. /* fetch NOP, LDM in DECODE stage */
  558. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  559. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  560. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  561. /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
  562. arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
  563. /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
  564. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  565. /* Branch and eXchange */
  566. arm7tdmi_clock_out(jtag_info, ARMV4_5_BX(0), NULL, 0);
  567. embeddedice_read_reg(dbg_stat);
  568. /* fetch NOP, BX in DECODE stage */
  569. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  570. /* target is now in Thumb state */
  571. embeddedice_read_reg(dbg_stat);
  572. /* fetch NOP, BX in EXECUTE stage (1st cycle) */
  573. arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
  574. /* target is now in Thumb state */
  575. embeddedice_read_reg(dbg_stat);
  576. /* load r0 value */
  577. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), NULL, 0);
  578. /* fetch NOP, LDR in Decode */
  579. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  580. /* fetch NOP, LDR in Execute */
  581. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  582. /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
  583. arm7tdmi_clock_out(jtag_info, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
  584. /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
  585. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  586. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  587. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 0);
  588. embeddedice_read_reg(dbg_stat);
  589. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, NULL, 1);
  590. arm7tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f8), NULL, 0);
  591. }
  592. void arm7tdmi_build_reg_cache(target_t *target)
  593. {
  594. reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
  595. /* get pointers to arch-specific information */
  596. armv4_5_common_t *armv4_5 = target->arch_info;
  597. (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
  598. armv4_5->core_cache = (*cache_p);
  599. }
  600. int arm7tdmi_examine(struct target_s *target)
  601. {
  602. int retval;
  603. armv4_5_common_t *armv4_5 = target->arch_info;
  604. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  605. if (!target_was_examined(target))
  606. {
  607. /* get pointers to arch-specific information */
  608. reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
  609. reg_cache_t *t = embeddedice_build_reg_cache(target, arm7_9);
  610. if (t == NULL)
  611. return ERROR_FAIL;
  612. (*cache_p) = t;
  613. arm7_9->eice_cache = (*cache_p);
  614. if (arm7_9->etm_ctx)
  615. {
  616. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  617. (*cache_p)->next = etm_build_reg_cache(target, jtag_info, arm7_9->etm_ctx);
  618. arm7_9->etm_ctx->reg_cache = (*cache_p)->next;
  619. }
  620. target_set_examined(target);
  621. }
  622. if ((retval = embeddedice_setup(target)) != ERROR_OK)
  623. return retval;
  624. if ((retval = arm7_9_setup(target)) != ERROR_OK)
  625. return retval;
  626. if (arm7_9->etm_ctx)
  627. {
  628. if ((retval = etm_setup(target)) != ERROR_OK)
  629. return retval;
  630. }
  631. return ERROR_OK;
  632. }
  633. int arm7tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
  634. {
  635. arm7tdmi_build_reg_cache(target);
  636. return ERROR_OK;
  637. }
  638. int arm7tdmi_quit(void)
  639. {
  640. return ERROR_OK;
  641. }
  642. int arm7tdmi_init_arch_info(target_t *target, arm7tdmi_common_t *arm7tdmi, jtag_tap_t *tap)
  643. {
  644. armv4_5_common_t *armv4_5;
  645. arm7_9_common_t *arm7_9;
  646. arm7_9 = &arm7tdmi->arm7_9_common;
  647. armv4_5 = &arm7_9->armv4_5_common;
  648. /* prepare JTAG information for the new target */
  649. arm7_9->jtag_info.tap = tap;
  650. arm7_9->jtag_info.scann_size = 4;
  651. /* register arch-specific functions */
  652. arm7_9->examine_debug_reason = arm7tdmi_examine_debug_reason;
  653. arm7_9->change_to_arm = arm7tdmi_change_to_arm;
  654. arm7_9->read_core_regs = arm7tdmi_read_core_regs;
  655. arm7_9->read_core_regs_target_buffer = arm7tdmi_read_core_regs_target_buffer;
  656. arm7_9->read_xpsr = arm7tdmi_read_xpsr;
  657. arm7_9->write_xpsr = arm7tdmi_write_xpsr;
  658. arm7_9->write_xpsr_im8 = arm7tdmi_write_xpsr_im8;
  659. arm7_9->write_core_regs = arm7tdmi_write_core_regs;
  660. arm7_9->load_word_regs = arm7tdmi_load_word_regs;
  661. arm7_9->load_hword_reg = arm7tdmi_load_hword_reg;
  662. arm7_9->load_byte_reg = arm7tdmi_load_byte_reg;
  663. arm7_9->store_word_regs = arm7tdmi_store_word_regs;
  664. arm7_9->store_hword_reg = arm7tdmi_store_hword_reg;
  665. arm7_9->store_byte_reg = arm7tdmi_store_byte_reg;
  666. arm7_9->write_pc = arm7tdmi_write_pc;
  667. arm7_9->branch_resume = arm7tdmi_branch_resume;
  668. arm7_9->branch_resume_thumb = arm7tdmi_branch_resume_thumb;
  669. arm7_9->enable_single_step = arm7_9_enable_eice_step;
  670. arm7_9->disable_single_step = arm7_9_disable_eice_step;
  671. arm7_9->pre_debug_entry = NULL;
  672. arm7_9->post_debug_entry = NULL;
  673. arm7_9->pre_restore_context = NULL;
  674. arm7_9->post_restore_context = NULL;
  675. /* initialize arch-specific breakpoint handling */
  676. arm7_9->arm_bkpt = 0xdeeedeee;
  677. arm7_9->thumb_bkpt = 0xdeee;
  678. arm7_9->dbgreq_adjust_pc = 2;
  679. arm7_9->arch_info = arm7tdmi;
  680. arm7tdmi->arch_info = NULL;
  681. arm7tdmi->common_magic = ARM7TDMI_COMMON_MAGIC;
  682. arm7_9_init_arch_info(target, arm7_9);
  683. return ERROR_OK;
  684. }
  685. int arm7tdmi_target_create( struct target_s *target, Jim_Interp *interp )
  686. {
  687. arm7tdmi_common_t *arm7tdmi;
  688. arm7tdmi = calloc(1,sizeof(arm7tdmi_common_t));
  689. arm7tdmi_init_arch_info(target, arm7tdmi, target->tap);
  690. return ERROR_OK;
  691. }
  692. int arm7tdmi_register_commands(struct command_context_s *cmd_ctx)
  693. {
  694. int retval;
  695. retval = arm7_9_register_commands(cmd_ctx);
  696. return retval;
  697. }