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.
 
 
 
 
 
 

901 lines
27 KiB

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