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.
 
 
 
 
 
 

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