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.
 
 
 
 
 
 

984 lines
30 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 "arm9tdmi.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 "log.h"
  30. #include "jtag.h"
  31. #include "arm_jtag.h"
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #if 0
  35. #define _DEBUG_INSTRUCTION_EXECUTION_
  36. #endif
  37. /* cli handling */
  38. int arm9tdmi_register_commands(struct command_context_s *cmd_ctx);
  39. /* forward declarations */
  40. int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
  41. int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
  42. int arm9tdmi_quit();
  43. target_type_t arm9tdmi_target =
  44. {
  45. .name = "arm9tdmi",
  46. .poll = arm7_9_poll,
  47. .arch_state = armv4_5_arch_state,
  48. .halt = arm7_9_halt,
  49. .resume = arm7_9_resume,
  50. .step = arm7_9_step,
  51. .assert_reset = arm7_9_assert_reset,
  52. .deassert_reset = arm7_9_deassert_reset,
  53. .soft_reset_halt = arm7_9_soft_reset_halt,
  54. .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
  55. .read_memory = arm7_9_read_memory,
  56. .write_memory = arm7_9_write_memory,
  57. .bulk_write_memory = arm7_9_bulk_write_memory,
  58. .run_algorithm = armv4_5_run_algorithm,
  59. .add_breakpoint = arm7_9_add_breakpoint,
  60. .remove_breakpoint = arm7_9_remove_breakpoint,
  61. .add_watchpoint = arm7_9_add_watchpoint,
  62. .remove_watchpoint = arm7_9_remove_watchpoint,
  63. .register_commands = arm9tdmi_register_commands,
  64. .target_command = arm9tdmi_target_command,
  65. .init_target = arm9tdmi_init_target,
  66. .quit = arm9tdmi_quit
  67. };
  68. int arm9tdmi_examine_debug_reason(target_t *target)
  69. {
  70. /* get pointers to arch-specific information */
  71. armv4_5_common_t *armv4_5 = target->arch_info;
  72. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  73. /* only check the debug reason if we don't know it already */
  74. if ((target->debug_reason != DBG_REASON_DBGRQ)
  75. && (target->debug_reason != DBG_REASON_SINGLESTEP))
  76. {
  77. scan_field_t fields[3];
  78. u8 databus[4];
  79. u8 instructionbus[4];
  80. u8 debug_reason;
  81. jtag_add_end_state(TAP_PD);
  82. fields[0].device = arm7_9->jtag_info.chain_pos;
  83. fields[0].num_bits = 32;
  84. fields[0].out_value = NULL;
  85. fields[0].out_mask = NULL;
  86. fields[0].in_value = databus;
  87. fields[0].in_check_value = NULL;
  88. fields[0].in_check_mask = NULL;
  89. fields[0].in_handler = NULL;
  90. fields[0].in_handler_priv = NULL;
  91. fields[1].device = arm7_9->jtag_info.chain_pos;
  92. fields[1].num_bits = 3;
  93. fields[1].out_value = NULL;
  94. fields[1].out_mask = NULL;
  95. fields[1].in_value = &debug_reason;
  96. fields[1].in_check_value = NULL;
  97. fields[1].in_check_mask = NULL;
  98. fields[1].in_handler = NULL;
  99. fields[1].in_handler_priv = NULL;
  100. fields[2].device = arm7_9->jtag_info.chain_pos;
  101. fields[2].num_bits = 32;
  102. fields[2].out_value = NULL;
  103. fields[2].out_mask = NULL;
  104. fields[2].in_value = instructionbus;
  105. fields[2].in_check_value = NULL;
  106. fields[2].in_check_mask = NULL;
  107. fields[2].in_handler = NULL;
  108. fields[2].in_handler_priv = NULL;
  109. arm_jtag_scann(&arm7_9->jtag_info, 0x1);
  110. arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr);
  111. jtag_add_dr_scan(3, fields, TAP_PD);
  112. jtag_execute_queue();
  113. fields[0].in_value = NULL;
  114. fields[0].out_value = databus;
  115. fields[1].in_value = NULL;
  116. fields[1].out_value = &debug_reason;
  117. fields[2].in_value = NULL;
  118. fields[2].out_value = instructionbus;
  119. jtag_add_dr_scan(3, fields, TAP_PD);
  120. if (debug_reason & 0x4)
  121. if (debug_reason & 0x2)
  122. target->debug_reason = DBG_REASON_WPTANDBKPT;
  123. else
  124. target->debug_reason = DBG_REASON_WATCHPOINT;
  125. else
  126. target->debug_reason = DBG_REASON_BREAKPOINT;
  127. }
  128. return ERROR_OK;
  129. }
  130. /* put an instruction in the ARM9TDMI pipeline or write the data bus, and optionally read data */
  131. int arm9tdmi_clock_out(arm_jtag_t *jtag_info, u32 instr, u32 out, u32 *in, int sysspeed)
  132. {
  133. scan_field_t fields[3];
  134. u8 out_buf[4];
  135. u8 instr_buf[4];
  136. u8 sysspeed_buf = 0x0;
  137. /* prepare buffer */
  138. buf_set_u32(out_buf, 0, 32, out);
  139. buf_set_u32(instr_buf, 0, 32, flip_u32(instr, 32));
  140. if (sysspeed)
  141. buf_set_u32(&sysspeed_buf, 2, 1, 1);
  142. jtag_add_end_state(TAP_PD);
  143. arm_jtag_scann(jtag_info, 0x1);
  144. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
  145. fields[0].device = jtag_info->chain_pos;
  146. fields[0].num_bits = 32;
  147. fields[0].out_value = out_buf;
  148. fields[0].out_mask = NULL;
  149. fields[0].in_value = NULL;
  150. if (in)
  151. {
  152. fields[0].in_handler = arm_jtag_buf_to_u32;
  153. fields[0].in_handler_priv = in;
  154. }
  155. else
  156. {
  157. fields[0].in_handler = NULL;
  158. fields[0].in_handler_priv = NULL;
  159. }
  160. fields[0].in_check_value = NULL;
  161. fields[0].in_check_mask = NULL;
  162. fields[1].device = jtag_info->chain_pos;
  163. fields[1].num_bits = 3;
  164. fields[1].out_value = &sysspeed_buf;
  165. fields[1].out_mask = NULL;
  166. fields[1].in_value = NULL;
  167. fields[1].in_check_value = NULL;
  168. fields[1].in_check_mask = NULL;
  169. fields[1].in_handler = NULL;
  170. fields[1].in_handler_priv = NULL;
  171. fields[2].device = jtag_info->chain_pos;
  172. fields[2].num_bits = 32;
  173. fields[2].out_value = instr_buf;
  174. fields[2].out_mask = NULL;
  175. fields[2].in_value = NULL;
  176. fields[2].in_check_value = NULL;
  177. fields[2].in_check_mask = NULL;
  178. fields[2].in_handler = NULL;
  179. fields[2].in_handler_priv = NULL;
  180. jtag_add_dr_scan(3, fields, -1);
  181. jtag_add_runtest(0, -1);
  182. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  183. {
  184. jtag_execute_queue();
  185. if (in)
  186. {
  187. DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
  188. }
  189. else
  190. DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
  191. }
  192. #endif
  193. return ERROR_OK;
  194. }
  195. /* just read data (instruction and data-out = don't care) */
  196. int arm9tdmi_clock_data_in(arm_jtag_t *jtag_info, u32 *in)
  197. {
  198. scan_field_t fields[3];
  199. jtag_add_end_state(TAP_PD);
  200. arm_jtag_scann(jtag_info, 0x1);
  201. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
  202. fields[0].device = jtag_info->chain_pos;
  203. fields[0].num_bits = 32;
  204. fields[0].out_value = NULL;
  205. fields[0].out_mask = NULL;
  206. fields[0].in_value = NULL;
  207. fields[0].in_handler = arm_jtag_buf_to_u32;
  208. fields[0].in_handler_priv = in;
  209. fields[0].in_check_value = NULL;
  210. fields[0].in_check_mask = NULL;
  211. fields[1].device = jtag_info->chain_pos;
  212. fields[1].num_bits = 3;
  213. fields[1].out_value = NULL;
  214. fields[1].out_mask = NULL;
  215. fields[1].in_value = NULL;
  216. fields[1].in_handler = NULL;
  217. fields[1].in_handler_priv = NULL;
  218. fields[1].in_check_value = NULL;
  219. fields[1].in_check_mask = NULL;
  220. fields[2].device = jtag_info->chain_pos;
  221. fields[2].num_bits = 32;
  222. fields[2].out_value = NULL;
  223. fields[2].out_mask = NULL;
  224. fields[2].in_value = NULL;
  225. fields[2].in_check_value = NULL;
  226. fields[2].in_check_mask = NULL;
  227. fields[2].in_handler = NULL;
  228. fields[2].in_handler_priv = NULL;
  229. jtag_add_dr_scan(3, fields, -1);
  230. jtag_add_runtest(0, -1);
  231. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  232. {
  233. jtag_execute_queue();
  234. if (in)
  235. {
  236. DEBUG("in: 0x%8.8x", *in);
  237. }
  238. else
  239. {
  240. ERROR("BUG: called with in == NULL");
  241. }
  242. }
  243. #endif
  244. return ERROR_OK;
  245. }
  246. /* clock the target, and read the databus
  247. * the *in pointer points to a buffer where elements of 'size' bytes
  248. * are stored in big (be==1) or little (be==0) endianness
  249. */
  250. int arm9tdmi_clock_data_in_endianness(arm_jtag_t *jtag_info, void *in, int size, int be)
  251. {
  252. scan_field_t fields[3];
  253. jtag_add_end_state(TAP_PD);
  254. arm_jtag_scann(jtag_info, 0x1);
  255. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr);
  256. fields[0].device = jtag_info->chain_pos;
  257. fields[0].num_bits = 32;
  258. fields[0].out_value = NULL;
  259. fields[0].out_mask = NULL;
  260. fields[0].in_value = NULL;
  261. switch (size)
  262. {
  263. case 4:
  264. fields[0].in_handler = (be) ? arm_jtag_buf_to_be32 : arm_jtag_buf_to_le32;
  265. break;
  266. case 2:
  267. fields[0].in_handler = (be) ? arm_jtag_buf_to_be16 : arm_jtag_buf_to_le16;
  268. break;
  269. case 1:
  270. fields[0].in_handler = arm_jtag_buf_to_8;
  271. break;
  272. }
  273. fields[0].in_handler_priv = in;
  274. fields[0].in_check_value = NULL;
  275. fields[0].in_check_mask = NULL;
  276. fields[1].device = jtag_info->chain_pos;
  277. fields[1].num_bits = 3;
  278. fields[1].out_value = NULL;
  279. fields[1].out_mask = NULL;
  280. fields[1].in_value = NULL;
  281. fields[1].in_handler = NULL;
  282. fields[1].in_handler_priv = NULL;
  283. fields[1].in_check_value = NULL;
  284. fields[1].in_check_mask = NULL;
  285. fields[2].device = jtag_info->chain_pos;
  286. fields[2].num_bits = 32;
  287. fields[2].out_value = NULL;
  288. fields[2].out_mask = NULL;
  289. fields[2].in_value = NULL;
  290. fields[2].in_check_value = NULL;
  291. fields[2].in_check_mask = NULL;
  292. fields[2].in_handler = NULL;
  293. fields[2].in_handler_priv = NULL;
  294. jtag_add_dr_scan(3, fields, -1);
  295. jtag_add_runtest(0, -1);
  296. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  297. {
  298. jtag_execute_queue();
  299. if (in)
  300. {
  301. DEBUG("in: 0x%8.8x", *in);
  302. }
  303. else
  304. {
  305. ERROR("BUG: called with in == NULL");
  306. }
  307. }
  308. #endif
  309. return ERROR_OK;
  310. }
  311. void arm9tdmi_change_to_arm(target_t *target, u32 *r0, u32 *pc)
  312. {
  313. /* get pointers to arch-specific information */
  314. armv4_5_common_t *armv4_5 = target->arch_info;
  315. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  316. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  317. /* save r0 before using it and put system in ARM state
  318. * to allow common handling of ARM and THUMB debugging */
  319. /* fetch STR r0, [r0] */
  320. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
  321. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  322. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  323. /* STR r0, [r0] in Memory */
  324. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, r0, 0);
  325. /* MOV r0, r15 fetched, STR in Decode */
  326. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_MOV(0, 15), 0, NULL, 0);
  327. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  328. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_STR(0, 0), 0, NULL, 0);
  329. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  330. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  331. /* nothing fetched, STR r0, [r0] in Memory */
  332. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, pc, 0);
  333. /* use pc-relative LDR to clear r0[1:0] (for switch to ARM mode) */
  334. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
  335. /* LDR in Decode */
  336. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  337. /* LDR in Execute */
  338. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  339. /* LDR in Memory (to account for interlock) */
  340. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  341. /* fetch BX */
  342. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_BX(0), 0, NULL, 0);
  343. /* NOP fetched, BX in Decode, MOV in Execute */
  344. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  345. /* NOP fetched, BX in Execute (1) */
  346. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  347. jtag_execute_queue();
  348. /* fix program counter:
  349. * MOV r0, r15 was the 5th instruction (+8)
  350. * reading PC in Thumb state gives address of instruction + 4
  351. */
  352. *pc -= 0xc;
  353. }
  354. void arm9tdmi_read_core_regs(target_t *target, u32 mask, u32* core_regs[16])
  355. {
  356. int i;
  357. /* get pointers to arch-specific information */
  358. armv4_5_common_t *armv4_5 = target->arch_info;
  359. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  360. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  361. /* STMIA r0-15, [r0] at debug speed
  362. * register values will start to appear on 4th DCLK
  363. */
  364. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  365. /* fetch NOP, STM in DECODE stage */
  366. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  367. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  368. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  369. for (i = 0; i <= 15; i++)
  370. {
  371. if (mask & (1 << i))
  372. /* nothing fetched, STM in MEMORY (i'th cycle) */
  373. arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
  374. }
  375. }
  376. void arm9tdmi_read_core_regs_target_buffer(target_t *target, u32 mask, void* buffer, int size)
  377. {
  378. int i;
  379. /* get pointers to arch-specific information */
  380. armv4_5_common_t *armv4_5 = target->arch_info;
  381. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  382. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  383. int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
  384. u32 *buf_u32 = buffer;
  385. u16 *buf_u16 = buffer;
  386. u8 *buf_u8 = buffer;
  387. /* STMIA r0-15, [r0] at debug speed
  388. * register values will start to appear on 4th DCLK
  389. */
  390. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  391. /* fetch NOP, STM in DECODE stage */
  392. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  393. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  394. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  395. for (i = 0; i <= 15; i++)
  396. {
  397. if (mask & (1 << i))
  398. /* nothing fetched, STM in MEMORY (i'th cycle) */
  399. switch (size)
  400. {
  401. case 4:
  402. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
  403. break;
  404. case 2:
  405. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
  406. break;
  407. case 1:
  408. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
  409. break;
  410. }
  411. }
  412. }
  413. void arm9tdmi_read_xpsr(target_t *target, u32 *xpsr, int spsr)
  414. {
  415. /* get pointers to arch-specific information */
  416. armv4_5_common_t *armv4_5 = target->arch_info;
  417. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  418. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  419. /* MRS r0, cpsr */
  420. arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
  421. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  422. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  423. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  424. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  425. /* STR r0, [r15] */
  426. arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
  427. /* fetch NOP, STR in DECODE stage */
  428. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  429. /* fetch NOP, STR in EXECUTE stage (1st cycle) */
  430. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  431. /* nothing fetched, STR in MEMORY */
  432. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
  433. }
  434. void arm9tdmi_write_xpsr(target_t *target, u32 xpsr, int spsr)
  435. {
  436. /* get pointers to arch-specific information */
  437. armv4_5_common_t *armv4_5 = target->arch_info;
  438. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  439. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  440. DEBUG("xpsr: %8.8x, spsr: %i", xpsr, spsr);
  441. /* MSR1 fetched */
  442. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
  443. /* MSR2 fetched, MSR1 in DECODE */
  444. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
  445. /* MSR3 fetched, MSR1 in EXECUTE (1), MSR2 in DECODE */
  446. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
  447. /* nothing fetched, MSR1 in EXECUTE (2) */
  448. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  449. /* nothing fetched, MSR1 in EXECUTE (3) */
  450. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  451. /* MSR4 fetched, MSR2 in EXECUTE (1), MSR3 in DECODE */
  452. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
  453. /* nothing fetched, MSR2 in EXECUTE (2) */
  454. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  455. /* nothing fetched, MSR2 in EXECUTE (3) */
  456. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  457. /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in DECODE */
  458. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  459. /* nothing fetched, MSR3 in EXECUTE (2) */
  460. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  461. /* nothing fetched, MSR3 in EXECUTE (3) */
  462. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  463. /* NOP fetched, MSR4 in EXECUTE (1) */
  464. /* last MSR writes flags, which takes only one cycle */
  465. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  466. }
  467. void arm9tdmi_write_xpsr_im8(target_t *target, u8 xpsr_im, int rot, int spsr)
  468. {
  469. /* get pointers to arch-specific information */
  470. armv4_5_common_t *armv4_5 = target->arch_info;
  471. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  472. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  473. DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
  474. /* MSR fetched */
  475. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
  476. /* NOP fetched, MSR in DECODE */
  477. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  478. /* NOP fetched, MSR in EXECUTE (1) */
  479. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  480. /* rot == 4 writes flags, which takes only one cycle */
  481. if (rot != 4)
  482. {
  483. /* nothing fetched, MSR in EXECUTE (2) */
  484. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  485. /* nothing fetched, MSR in EXECUTE (3) */
  486. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  487. }
  488. }
  489. void arm9tdmi_write_core_regs(target_t *target, u32 mask, u32 core_regs[16])
  490. {
  491. int i;
  492. /* get pointers to arch-specific information */
  493. armv4_5_common_t *armv4_5 = target->arch_info;
  494. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  495. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  496. /* LDMIA r0-15, [r0] at debug speed
  497. * register values will start to appear on 4th DCLK
  498. */
  499. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  500. /* fetch NOP, LDM in DECODE stage */
  501. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  502. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  503. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  504. for (i = 0; i <= 15; i++)
  505. {
  506. if (mask & (1 << i))
  507. /* nothing fetched, LDM still in EXECUTE (1+i cycle) */
  508. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
  509. }
  510. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  511. }
  512. void arm9tdmi_load_word_regs(target_t *target, u32 mask)
  513. {
  514. /* get pointers to arch-specific information */
  515. armv4_5_common_t *armv4_5 = target->arch_info;
  516. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  517. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  518. /* put system-speed load-multiple into the pipeline */
  519. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 1), 0, NULL, 0);
  520. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  521. }
  522. void arm9tdmi_load_hword_reg(target_t *target, int num)
  523. {
  524. /* get pointers to arch-specific information */
  525. armv4_5_common_t *armv4_5 = target->arch_info;
  526. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  527. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  528. /* put system-speed load half-word into the pipeline */
  529. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRH_IP(num, 0), 0, NULL, 0);
  530. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  531. }
  532. void arm9tdmi_load_byte_reg(target_t *target, int num)
  533. {
  534. /* get pointers to arch-specific information */
  535. armv4_5_common_t *armv4_5 = target->arch_info;
  536. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  537. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  538. /* put system-speed load byte into the pipeline */
  539. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDRB_IP(num, 0), 0, NULL, 0);
  540. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  541. }
  542. void arm9tdmi_store_word_regs(target_t *target, u32 mask)
  543. {
  544. /* get pointers to arch-specific information */
  545. armv4_5_common_t *armv4_5 = target->arch_info;
  546. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  547. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  548. /* put system-speed store-multiple into the pipeline */
  549. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask, 0, 1), 0, NULL, 0);
  550. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  551. }
  552. void arm9tdmi_store_hword_reg(target_t *target, int num)
  553. {
  554. /* get pointers to arch-specific information */
  555. armv4_5_common_t *armv4_5 = target->arch_info;
  556. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  557. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  558. /* put system-speed store half-word into the pipeline */
  559. arm9tdmi_clock_out(jtag_info, ARMV4_5_STRH_IP(num, 0), 0, NULL, 0);
  560. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  561. }
  562. void arm9tdmi_store_byte_reg(target_t *target, int num)
  563. {
  564. /* get pointers to arch-specific information */
  565. armv4_5_common_t *armv4_5 = target->arch_info;
  566. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  567. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  568. /* put system-speed store byte into the pipeline */
  569. arm9tdmi_clock_out(jtag_info, ARMV4_5_STRB_IP(num, 0), 0, NULL, 0);
  570. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  571. }
  572. void arm9tdmi_write_pc(target_t *target, u32 pc)
  573. {
  574. /* get pointers to arch-specific information */
  575. armv4_5_common_t *armv4_5 = target->arch_info;
  576. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  577. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  578. /* LDMIA r0-15, [r0] at debug speed
  579. * register values will start to appear on 4th DCLK
  580. */
  581. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
  582. /* fetch NOP, LDM in DECODE stage */
  583. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  584. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  585. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  586. /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
  587. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
  588. /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
  589. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  590. /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
  591. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  592. /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
  593. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  594. }
  595. void arm9tdmi_branch_resume(target_t *target)
  596. {
  597. /* get pointers to arch-specific information */
  598. armv4_5_common_t *armv4_5 = target->arch_info;
  599. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  600. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  601. arm9tdmi_clock_out(jtag_info, ARMV4_5_B(0xfffffc, 0), 0, NULL, 0);
  602. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  603. }
  604. void arm9tdmi_branch_resume_thumb(target_t *target)
  605. {
  606. DEBUG("");
  607. /* get pointers to arch-specific information */
  608. armv4_5_common_t *armv4_5 = target->arch_info;
  609. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  610. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  611. reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
  612. /* LDMIA r0-15, [r0] at debug speed
  613. * register values will start to appear on 4th DCLK
  614. */
  615. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x1, 0, 0), 0, NULL, 0);
  616. /* fetch NOP, LDM in DECODE stage */
  617. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  618. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  619. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  620. /* nothing fetched, LDM in EXECUTE stage (2nd cycle) */
  621. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) | 1, NULL, 0);
  622. /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
  623. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  624. /* Branch and eXchange */
  625. arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
  626. embeddedice_read_reg(dbg_stat);
  627. /* fetch NOP, BX in DECODE stage */
  628. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  629. embeddedice_read_reg(dbg_stat);
  630. /* fetch NOP, BX in EXECUTE stage (1st cycle) */
  631. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  632. /* target is now in Thumb state */
  633. embeddedice_read_reg(dbg_stat);
  634. /* load r0 value, MOV_IM in Decode*/
  635. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_LDR_PCREL(0), 0, NULL, 0);
  636. /* fetch NOP, LDR in Decode, MOV_IM in Execute */
  637. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  638. /* fetch NOP, LDR in Execute */
  639. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  640. /* nothing fetched, LDR in EXECUTE stage (2nd cycle) */
  641. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, buf_get_u32(armv4_5->core_cache->reg_list[0].value, 0, 32), NULL, 0);
  642. /* nothing fetched, LDR in EXECUTE stage (3rd cycle) */
  643. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  644. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  645. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  646. embeddedice_read_reg(dbg_stat);
  647. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_B(0x7f7), 0, NULL, 1);
  648. arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
  649. }
  650. void arm9tdmi_enable_single_step(target_t *target)
  651. {
  652. /* get pointers to arch-specific information */
  653. armv4_5_common_t *armv4_5 = target->arch_info;
  654. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  655. arm9tdmi_common_t *arm9 = arm7_9->arch_info;
  656. if (arm9->has_single_step)
  657. {
  658. buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
  659. embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
  660. }
  661. else
  662. {
  663. arm7_9_enable_eice_step(target);
  664. }
  665. }
  666. void arm9tdmi_disable_single_step(target_t *target)
  667. {
  668. /* get pointers to arch-specific information */
  669. armv4_5_common_t *armv4_5 = target->arch_info;
  670. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  671. arm9tdmi_common_t *arm9 = arm7_9->arch_info;
  672. if (arm9->has_single_step)
  673. {
  674. buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
  675. embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
  676. }
  677. else
  678. {
  679. arm7_9_disable_eice_step(target);
  680. }
  681. }
  682. void arm9tdmi_build_reg_cache(target_t *target)
  683. {
  684. reg_cache_t **cache_p = register_get_last_cache_p(&target->reg_cache);
  685. /* get pointers to arch-specific information */
  686. armv4_5_common_t *armv4_5 = target->arch_info;
  687. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  688. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  689. arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
  690. embeddedice_reg_t *vec_catch_arch_info;
  691. (*cache_p) = armv4_5_build_reg_cache(target, armv4_5);
  692. armv4_5->core_cache = (*cache_p);
  693. /* one extra register (vector catch) */
  694. (*cache_p)->next = embeddedice_build_reg_cache(target, jtag_info, 1);
  695. arm7_9->eice_cache = (*cache_p)->next;
  696. if (arm9tdmi->has_monitor_mode)
  697. (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 6;
  698. else
  699. (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 4;
  700. (*cache_p)->next->reg_list[EICE_DBG_STAT].size = 5;
  701. (*cache_p)->next->reg_list[EICE_VEC_CATCH].name = "vector catch";
  702. (*cache_p)->next->reg_list[EICE_VEC_CATCH].dirty = 0;
  703. (*cache_p)->next->reg_list[EICE_VEC_CATCH].valid = 0;
  704. (*cache_p)->next->reg_list[EICE_VEC_CATCH].bitfield_desc = NULL;
  705. (*cache_p)->next->reg_list[EICE_VEC_CATCH].num_bitfields = 0;
  706. (*cache_p)->next->reg_list[EICE_VEC_CATCH].size = 8;
  707. (*cache_p)->next->reg_list[EICE_VEC_CATCH].value = calloc(1, 4);
  708. vec_catch_arch_info = (*cache_p)->next->reg_list[EICE_VEC_CATCH].arch_info;
  709. vec_catch_arch_info->addr = 0x2;
  710. }
  711. int arm9tdmi_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
  712. {
  713. arm9tdmi_build_reg_cache(target);
  714. return ERROR_OK;
  715. }
  716. int arm9tdmi_quit()
  717. {
  718. return ERROR_OK;
  719. }
  720. int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int chain_pos, char *variant)
  721. {
  722. armv4_5_common_t *armv4_5;
  723. arm7_9_common_t *arm7_9;
  724. arm7_9 = &arm9tdmi->arm7_9_common;
  725. armv4_5 = &arm7_9->armv4_5_common;
  726. /* prepare JTAG information for the new target */
  727. arm7_9->jtag_info.chain_pos = chain_pos;
  728. arm7_9->jtag_info.scann_size = 5;
  729. /* register arch-specific functions */
  730. arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
  731. arm7_9->change_to_arm = arm9tdmi_change_to_arm;
  732. arm7_9->read_core_regs = arm9tdmi_read_core_regs;
  733. arm7_9->read_core_regs_target_buffer = arm9tdmi_read_core_regs_target_buffer;
  734. arm7_9->read_xpsr = arm9tdmi_read_xpsr;
  735. arm7_9->write_xpsr = arm9tdmi_write_xpsr;
  736. arm7_9->write_xpsr_im8 = arm9tdmi_write_xpsr_im8;
  737. arm7_9->write_core_regs = arm9tdmi_write_core_regs;
  738. arm7_9->load_word_regs = arm9tdmi_load_word_regs;
  739. arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
  740. arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
  741. arm7_9->store_word_regs = arm9tdmi_store_word_regs;
  742. arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
  743. arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
  744. arm7_9->write_pc = arm9tdmi_write_pc;
  745. arm7_9->branch_resume = arm9tdmi_branch_resume;
  746. arm7_9->branch_resume_thumb = arm9tdmi_branch_resume_thumb;
  747. arm7_9->enable_single_step = arm9tdmi_enable_single_step;
  748. arm7_9->disable_single_step = arm9tdmi_disable_single_step;
  749. arm7_9->pre_debug_entry = NULL;
  750. arm7_9->post_debug_entry = NULL;
  751. arm7_9->pre_restore_context = NULL;
  752. arm7_9->post_restore_context = NULL;
  753. /* initialize arch-specific breakpoint handling */
  754. buf_set_u32((u8*)(&arm7_9->arm_bkpt), 0, 32, 0xdeeedeee);
  755. buf_set_u32((u8*)(&arm7_9->thumb_bkpt), 0, 16, 0xdeee);
  756. arm7_9->sw_bkpts_use_wp = 1;
  757. arm7_9->sw_bkpts_enabled = 0;
  758. arm7_9->dbgreq_adjust_pc = 3;
  759. arm7_9->arch_info = arm9tdmi;
  760. arm9tdmi->common_magic = ARM9TDMI_COMMON_MAGIC;
  761. arm9tdmi->has_monitor_mode = 0;
  762. arm9tdmi->has_single_step = 0;
  763. arm9tdmi->arch_info = NULL;
  764. if (variant)
  765. {
  766. if (strcmp(variant, "arm920t") == 0)
  767. arm9tdmi->has_single_step = 1;
  768. else if (strcmp(variant, "arm922t") == 0)
  769. arm9tdmi->has_single_step = 1;
  770. else if (strcmp(variant, "arm940t") == 0)
  771. arm9tdmi->has_single_step = 1;
  772. arm9tdmi->variant = strdup(variant);
  773. }
  774. else
  775. arm9tdmi->variant = strdup("");
  776. arm7_9_init_arch_info(target, arm7_9);
  777. /* override use of DBGRQ, this is safe on ARM9TDMI */
  778. arm7_9->use_dbgrq = 1;
  779. return ERROR_OK;
  780. }
  781. /* target arm9tdmi <endianess> <startup_mode> <chain_pos> <variant>*/
  782. int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
  783. {
  784. int chain_pos;
  785. char *variant = NULL;
  786. arm9tdmi_common_t *arm9tdmi = malloc(sizeof(arm9tdmi_common_t));
  787. if (argc < 4)
  788. {
  789. ERROR("'target arm9tdmi' requires at least one additional argument");
  790. exit(-1);
  791. }
  792. chain_pos = strtoul(args[3], NULL, 0);
  793. if (argc >= 5)
  794. variant = args[4];
  795. arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
  796. return ERROR_OK;
  797. }
  798. int arm9tdmi_register_commands(struct command_context_s *cmd_ctx)
  799. {
  800. int retval;
  801. retval = arm7_9_register_commands(cmd_ctx);
  802. return ERROR_OK;
  803. }