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.
 
 
 
 
 
 

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