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.
 
 
 
 
 
 

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