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.
 
 
 
 
 
 

394 lines
14 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2009 by Paulius Zaleckas *
  3. * paulius.zaleckas@gmail.com *
  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. /*
  21. * FA526 is very similar to ARM920T with following differences:
  22. *
  23. * - execution pipeline is 6 steps
  24. * - Unified TLB
  25. * - has Branch Target Buffer
  26. * - does not support reading of I/D cache contents
  27. */
  28. #ifdef HAVE_CONFIG_H
  29. #include "config.h"
  30. #endif
  31. #include "arm920t.h"
  32. #include "target_type.h"
  33. #include "arm_opcodes.h"
  34. static void fa526_change_to_arm(struct target *target, uint32_t *r0, uint32_t *pc)
  35. {
  36. LOG_ERROR("%s: there is no Thumb state on FA526", __func__);
  37. }
  38. static void fa526_read_core_regs(struct target *target,
  39. uint32_t mask, uint32_t* core_regs[16])
  40. {
  41. int i;
  42. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  43. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  44. /* STMIA r0-15, [r0] at debug speed
  45. * register values will start to appear on 4th DCLK
  46. */
  47. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  48. /* fetch NOP, STM in DECODE stage */
  49. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  50. /* fetch NOP, STM in SHIFT stage */
  51. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  52. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  53. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  54. for (i = 0; i <= 15; i++)
  55. {
  56. if (mask & (1 << i))
  57. /* nothing fetched, STM in MEMORY (i'th cycle) */
  58. arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
  59. }
  60. }
  61. static void fa526_read_core_regs_target_buffer(struct target *target,
  62. uint32_t mask, void* buffer, int size)
  63. {
  64. int i;
  65. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  66. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  67. int be = (target->endianness == TARGET_BIG_ENDIAN) ? 1 : 0;
  68. uint32_t *buf_u32 = buffer;
  69. uint16_t *buf_u16 = buffer;
  70. uint8_t *buf_u8 = buffer;
  71. /* STMIA r0-15, [r0] at debug speed
  72. * register values will start to appear on 4th DCLK
  73. */
  74. arm9tdmi_clock_out(jtag_info, ARMV4_5_STMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  75. /* fetch NOP, STM in DECODE stage */
  76. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  77. /* fetch NOP, STM in SHIFT stage */
  78. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  79. /* fetch NOP, STM in EXECUTE stage (1st cycle) */
  80. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  81. for (i = 0; i <= 15; i++)
  82. {
  83. if (mask & (1 << i))
  84. /* nothing fetched, STM in MEMORY (i'th cycle) */
  85. switch (size)
  86. {
  87. case 4:
  88. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
  89. break;
  90. case 2:
  91. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u16++, 2, be);
  92. break;
  93. case 1:
  94. arm9tdmi_clock_data_in_endianness(jtag_info, buf_u8++, 1, be);
  95. break;
  96. }
  97. }
  98. }
  99. static void fa526_read_xpsr(struct target *target, uint32_t *xpsr, int spsr)
  100. {
  101. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  102. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  103. /* MRS r0, cpsr */
  104. arm9tdmi_clock_out(jtag_info, ARMV4_5_MRS(0, spsr & 1), 0, NULL, 0);
  105. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  106. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  107. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  108. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  109. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  110. /* STR r0, [r15] */
  111. arm9tdmi_clock_out(jtag_info, ARMV4_5_STR(0, 15), 0, NULL, 0);
  112. /* fetch NOP, STR in DECODE stage */
  113. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  114. /* fetch NOP, STR in SHIFT stage */
  115. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  116. /* fetch NOP, STR in EXECUTE stage (1st cycle) */
  117. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  118. /* nothing fetched, STR in MEMORY */
  119. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, xpsr, 0);
  120. }
  121. static void fa526_write_xpsr(struct target *target, uint32_t xpsr, int spsr)
  122. {
  123. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  124. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  125. LOG_DEBUG("xpsr: %8.8" PRIx32 ", spsr: %i", xpsr, spsr);
  126. /* MSR1 fetched */
  127. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr & 0xff, 0, 1, spsr), 0, NULL, 0);
  128. /* MSR2 fetched, MSR1 in DECODE */
  129. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff00) >> 8, 0xc, 2, spsr), 0, NULL, 0);
  130. /* MSR3 fetched, MSR1 in SHIFT, MSR2 in DECODE */
  131. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff0000) >> 16, 0x8, 4, spsr), 0, NULL, 0);
  132. /* MSR4 fetched, MSR1 in EXECUTE (1), MSR2 in SHIFT, MSR3 in DECODE */
  133. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM((xpsr & 0xff000000) >> 24, 0x4, 8, spsr), 0, NULL, 0);
  134. /* nothing fetched, MSR1 in EXECUTE (2) */
  135. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  136. /* nothing fetched, MSR1 in EXECUTE (3) */
  137. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  138. /* nothing fetched, MSR2 in EXECUTE (1), MSR3 in SHIFT, MSR4 in DECODE */
  139. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  140. /* nothing fetched, MSR2 in EXECUTE (2) */
  141. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  142. /* nothing fetched, MSR2 in EXECUTE (3) */
  143. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  144. /* NOP fetched, MSR3 in EXECUTE (1), MSR4 in SHIFT */
  145. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  146. /* nothing fetched, MSR3 in EXECUTE (2) */
  147. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  148. /* nothing fetched, MSR3 in EXECUTE (3) */
  149. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  150. /* NOP fetched, MSR4 in EXECUTE (1) */
  151. /* last MSR writes flags, which takes only one cycle */
  152. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  153. }
  154. static void fa526_write_xpsr_im8(struct target *target,
  155. uint8_t xpsr_im, int rot, int spsr)
  156. {
  157. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  158. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  159. LOG_DEBUG("xpsr_im: %2.2x, rot: %i, spsr: %i", xpsr_im, rot, spsr);
  160. /* MSR fetched */
  161. arm9tdmi_clock_out(jtag_info, ARMV4_5_MSR_IM(xpsr_im, rot, 1, spsr), 0, NULL, 0);
  162. /* NOP fetched, MSR in DECODE */
  163. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  164. /* NOP fetched, MSR in SHIFT */
  165. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  166. /* NOP fetched, MSR in EXECUTE (1) */
  167. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  168. /* rot == 4 writes flags, which takes only one cycle */
  169. if (rot != 4)
  170. {
  171. /* nothing fetched, MSR in EXECUTE (2) */
  172. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  173. /* nothing fetched, MSR in EXECUTE (3) */
  174. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  175. }
  176. }
  177. static void fa526_write_core_regs(struct target *target,
  178. uint32_t mask, uint32_t core_regs[16])
  179. {
  180. int i;
  181. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  182. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  183. /* LDMIA r0-15, [r0] at debug speed
  184. * register values will start to appear on 4th DCLK
  185. */
  186. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, mask & 0xffff, 0, 0), 0, NULL, 0);
  187. /* fetch NOP, LDM in DECODE stage */
  188. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  189. /* fetch NOP, LDM in SHIFT stage */
  190. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  191. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  192. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  193. for (i = 0; i <= 15; i++)
  194. {
  195. if (mask & (1 << i))
  196. /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
  197. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
  198. }
  199. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  200. }
  201. static void fa526_write_pc(struct target *target, uint32_t pc)
  202. {
  203. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  204. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  205. /* LDMIA r0-15, [r0] at debug speed
  206. * register values will start to appear on 4th DCLK
  207. */
  208. arm9tdmi_clock_out(jtag_info, ARMV4_5_LDMIA(0, 0x8000, 0, 0), 0, NULL, 0);
  209. /* fetch NOP, LDM in DECODE stage */
  210. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  211. /* fetch NOP, LDM in SHIFT stage */
  212. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  213. /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
  214. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  215. /* nothing fetched, LDM in EXECUTE stage (2nd cycle) (output data) */
  216. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, pc, NULL, 0);
  217. /* nothing fetched, LDM in EXECUTE stage (3rd cycle) */
  218. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  219. /* fetch NOP, LDM in EXECUTE stage (4th cycle) */
  220. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  221. /* fetch NOP, LDM in EXECUTE stage (5th cycle) */
  222. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
  223. }
  224. static void fa526_branch_resume_thumb(struct target *target)
  225. {
  226. LOG_ERROR("%s: there is no Thumb state on FA526", __func__);
  227. }
  228. static int fa526_init_arch_info_2(struct target *target,
  229. struct arm7_9_common *arm7_9, struct jtag_tap *tap)
  230. {
  231. /* prepare JTAG information for the new target */
  232. arm7_9->jtag_info.tap = tap;
  233. arm7_9->jtag_info.scann_size = 5;
  234. /* register arch-specific functions */
  235. arm7_9->examine_debug_reason = arm9tdmi_examine_debug_reason;
  236. arm7_9->change_to_arm = fa526_change_to_arm;
  237. arm7_9->read_core_regs = fa526_read_core_regs;
  238. arm7_9->read_core_regs_target_buffer = fa526_read_core_regs_target_buffer;
  239. arm7_9->read_xpsr = fa526_read_xpsr;
  240. arm7_9->write_xpsr = fa526_write_xpsr;
  241. arm7_9->write_xpsr_im8 = fa526_write_xpsr_im8;
  242. arm7_9->write_core_regs = fa526_write_core_regs;
  243. arm7_9->load_word_regs = arm9tdmi_load_word_regs;
  244. arm7_9->load_hword_reg = arm9tdmi_load_hword_reg;
  245. arm7_9->load_byte_reg = arm9tdmi_load_byte_reg;
  246. arm7_9->store_word_regs = arm9tdmi_store_word_regs;
  247. arm7_9->store_hword_reg = arm9tdmi_store_hword_reg;
  248. arm7_9->store_byte_reg = arm9tdmi_store_byte_reg;
  249. arm7_9->write_pc = fa526_write_pc;
  250. arm7_9->branch_resume = arm9tdmi_branch_resume;
  251. arm7_9->branch_resume_thumb = fa526_branch_resume_thumb;
  252. arm7_9->enable_single_step = arm9tdmi_enable_single_step;
  253. arm7_9->disable_single_step = arm9tdmi_disable_single_step;
  254. arm7_9->post_debug_entry = NULL;
  255. arm7_9->pre_restore_context = NULL;
  256. arm7_9->post_restore_context = NULL;
  257. /* initialize arch-specific breakpoint handling */
  258. arm7_9->arm_bkpt = 0xdeeedeee;
  259. arm7_9->thumb_bkpt = 0xdeee;
  260. arm7_9->dbgreq_adjust_pc = 3;
  261. arm7_9_init_arch_info(target, arm7_9);
  262. /* override use of DBGRQ, this is safe on ARM9TDMI */
  263. arm7_9->use_dbgrq = 1;
  264. /* all ARM9s have the vector catch register */
  265. arm7_9->has_vector_catch = 1;
  266. return ERROR_OK;
  267. }
  268. static int fa526_init_arch_info(struct target *target,
  269. struct arm920t_common *arm920t, struct jtag_tap *tap)
  270. {
  271. struct arm7_9_common *arm7_9 = &arm920t->arm7_9_common;
  272. /* initialize arm7/arm9 specific info (including armv4_5) */
  273. fa526_init_arch_info_2(target, arm7_9, tap);
  274. arm920t->common_magic = ARM920T_COMMON_MAGIC;
  275. arm7_9->post_debug_entry = arm920t_post_debug_entry;
  276. arm7_9->pre_restore_context = arm920t_pre_restore_context;
  277. arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
  278. arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
  279. arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
  280. arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
  281. arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
  282. arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
  283. arm920t->armv4_5_mmu.has_tiny_pages = 1;
  284. arm920t->armv4_5_mmu.mmu_enabled = 0;
  285. /* disabling linefills leads to lockups, so keep them enabled for now
  286. * this doesn't affect correctness, but might affect timing issues, if
  287. * important data is evicted from the cache during the debug session
  288. * */
  289. arm920t->preserve_cache = 0;
  290. /* override hw single-step capability from ARM9TDMI */
  291. arm7_9->has_single_step = 1;
  292. return ERROR_OK;
  293. }
  294. static int fa526_target_create(struct target *target, Jim_Interp *interp)
  295. {
  296. struct arm920t_common *arm920t = calloc(1,sizeof(struct arm920t_common));
  297. return fa526_init_arch_info(target, arm920t, target->tap);
  298. }
  299. /** Holds methods for FA526 targets. */
  300. struct target_type fa526_target =
  301. {
  302. .name = "fa526",
  303. .poll = arm7_9_poll,
  304. .arch_state = arm920t_arch_state,
  305. .target_request_data = arm7_9_target_request_data,
  306. .halt = arm7_9_halt,
  307. .resume = arm7_9_resume,
  308. .step = arm7_9_step,
  309. .assert_reset = arm7_9_assert_reset,
  310. .deassert_reset = arm7_9_deassert_reset,
  311. .soft_reset_halt = arm920t_soft_reset_halt,
  312. .get_gdb_reg_list = arm_get_gdb_reg_list,
  313. .read_memory = arm920t_read_memory,
  314. .write_memory = arm920t_write_memory,
  315. .bulk_write_memory = arm7_9_bulk_write_memory,
  316. .checksum_memory = arm_checksum_memory,
  317. .blank_check_memory = arm_blank_check_memory,
  318. .run_algorithm = armv4_5_run_algorithm,
  319. .add_breakpoint = arm7_9_add_breakpoint,
  320. .remove_breakpoint = arm7_9_remove_breakpoint,
  321. .add_watchpoint = arm7_9_add_watchpoint,
  322. .remove_watchpoint = arm7_9_remove_watchpoint,
  323. .commands = arm920t_command_handlers,
  324. .target_create = fa526_target_create,
  325. .init_target = arm9tdmi_init_target,
  326. .examine = arm7_9_examine,
  327. };