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.
 
 
 
 
 
 

1484 lines
46 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 "arm920t.h"
  24. #include "jtag.h"
  25. #include "log.h"
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #if 0
  29. #define _DEBUG_INSTRUCTION_EXECUTION_
  30. #endif
  31. /* cli handling */
  32. int arm920t_register_commands(struct command_context_s *cmd_ctx);
  33. int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  34. int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  35. int arm920t_handle_virt2phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  36. int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  37. int arm920t_handle_md_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  38. int arm920t_handle_mw_phys_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  39. int arm920t_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  40. int arm920t_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
  41. /* forward declarations */
  42. int arm920t_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
  43. int arm920t_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
  44. int arm920t_quit();
  45. int arm920t_arch_state(struct target_s *target, char *buf, int buf_size);
  46. int arm920t_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
  47. int arm920t_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
  48. int arm920t_soft_reset_halt(struct target_s *target);
  49. #define ARM920T_CP15_PHYS_ADDR(x, y, z) ((x << 5) | (y << 1) << (z))
  50. target_type_t arm920t_target =
  51. {
  52. .name = "arm920t",
  53. .poll = arm7_9_poll,
  54. .arch_state = arm920t_arch_state,
  55. .halt = arm7_9_halt,
  56. .resume = arm7_9_resume,
  57. .step = arm7_9_step,
  58. .assert_reset = arm7_9_assert_reset,
  59. .deassert_reset = arm7_9_deassert_reset,
  60. .soft_reset_halt = arm920t_soft_reset_halt,
  61. .prepare_reset_halt = arm7_9_prepare_reset_halt,
  62. .get_gdb_reg_list = armv4_5_get_gdb_reg_list,
  63. .read_memory = arm920t_read_memory,
  64. .write_memory = arm920t_write_memory,
  65. .bulk_write_memory = arm7_9_bulk_write_memory,
  66. .run_algorithm = armv4_5_run_algorithm,
  67. .add_breakpoint = arm7_9_add_breakpoint,
  68. .remove_breakpoint = arm7_9_remove_breakpoint,
  69. .add_watchpoint = arm7_9_add_watchpoint,
  70. .remove_watchpoint = arm7_9_remove_watchpoint,
  71. .register_commands = arm920t_register_commands,
  72. .target_command = arm920t_target_command,
  73. .init_target = arm920t_init_target,
  74. .quit = arm920t_quit
  75. };
  76. int arm920t_read_cp15_physical(target_t *target, int reg_addr, u32 *value)
  77. {
  78. armv4_5_common_t *armv4_5 = target->arch_info;
  79. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  80. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  81. scan_field_t fields[4];
  82. u8 access_type_buf = 1;
  83. u8 reg_addr_buf = reg_addr & 0x3f;
  84. u8 nr_w_buf = 0;
  85. jtag_add_end_state(TAP_RTI);
  86. arm_jtag_scann(jtag_info, 0xf);
  87. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  88. fields[0].device = jtag_info->chain_pos;
  89. fields[0].num_bits = 1;
  90. fields[0].out_value = &access_type_buf;
  91. fields[0].out_mask = NULL;
  92. fields[0].in_value = NULL;
  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 = 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 = NULL;
  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. fields[2].device = jtag_info->chain_pos;
  107. fields[2].num_bits = 6;
  108. fields[2].out_value = &reg_addr_buf;
  109. fields[2].out_mask = NULL;
  110. fields[2].in_value = NULL;
  111. fields[2].in_check_value = NULL;
  112. fields[2].in_check_mask = NULL;
  113. fields[2].in_handler = NULL;
  114. fields[2].in_handler_priv = NULL;
  115. fields[3].device = jtag_info->chain_pos;
  116. fields[3].num_bits = 1;
  117. fields[3].out_value = &nr_w_buf;
  118. fields[3].out_mask = NULL;
  119. fields[3].in_value = NULL;
  120. fields[3].in_check_value = NULL;
  121. fields[3].in_check_mask = NULL;
  122. fields[3].in_handler = NULL;
  123. fields[3].in_handler_priv = NULL;
  124. jtag_add_dr_scan(4, fields, -1, NULL);
  125. fields[1].in_handler_priv = value;
  126. fields[1].in_handler = arm_jtag_buf_to_u32;
  127. jtag_add_dr_scan(4, fields, -1, NULL);
  128. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  129. jtag_execute_queue();
  130. DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
  131. #endif
  132. return ERROR_OK;
  133. }
  134. int arm920t_write_cp15_physical(target_t *target, int reg_addr, u32 value)
  135. {
  136. armv4_5_common_t *armv4_5 = target->arch_info;
  137. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  138. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  139. scan_field_t fields[4];
  140. u8 access_type_buf = 1;
  141. u8 reg_addr_buf = reg_addr & 0x3f;
  142. u8 nr_w_buf = 1;
  143. u8 value_buf[4];
  144. buf_set_u32(value_buf, 0, 32, value);
  145. jtag_add_end_state(TAP_RTI);
  146. arm_jtag_scann(jtag_info, 0xf);
  147. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  148. fields[0].device = jtag_info->chain_pos;
  149. fields[0].num_bits = 1;
  150. fields[0].out_value = &access_type_buf;
  151. fields[0].out_mask = NULL;
  152. fields[0].in_value = NULL;
  153. fields[0].in_check_value = NULL;
  154. fields[0].in_check_mask = NULL;
  155. fields[0].in_handler = NULL;
  156. fields[0].in_handler_priv = NULL;
  157. fields[1].device = jtag_info->chain_pos;
  158. fields[1].num_bits = 32;
  159. fields[1].out_value = value_buf;
  160. fields[1].out_mask = NULL;
  161. fields[1].in_value = NULL;
  162. fields[1].in_check_value = NULL;
  163. fields[1].in_check_mask = NULL;
  164. fields[1].in_handler = NULL;
  165. fields[1].in_handler_priv = NULL;
  166. fields[2].device = jtag_info->chain_pos;
  167. fields[2].num_bits = 6;
  168. fields[2].out_value = &reg_addr_buf;
  169. fields[2].out_mask = NULL;
  170. fields[2].in_value = NULL;
  171. fields[2].in_check_value = NULL;
  172. fields[2].in_check_mask = NULL;
  173. fields[2].in_handler = NULL;
  174. fields[2].in_handler_priv = NULL;
  175. fields[3].device = jtag_info->chain_pos;
  176. fields[3].num_bits = 1;
  177. fields[3].out_value = &nr_w_buf;
  178. fields[3].out_mask = NULL;
  179. fields[3].in_value = NULL;
  180. fields[3].in_check_value = NULL;
  181. fields[3].in_check_mask = NULL;
  182. fields[3].in_handler = NULL;
  183. fields[3].in_handler_priv = NULL;
  184. jtag_add_dr_scan(4, fields, -1, NULL);
  185. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  186. DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
  187. #endif
  188. return ERROR_OK;
  189. }
  190. int arm920t_execute_cp15(target_t *target, u32 cp15_opcode, u32 arm_opcode)
  191. {
  192. armv4_5_common_t *armv4_5 = target->arch_info;
  193. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  194. arm_jtag_t *jtag_info = &arm7_9->jtag_info;
  195. scan_field_t fields[4];
  196. u8 access_type_buf = 0; /* interpreted access */
  197. u8 reg_addr_buf = 0x0;
  198. u8 nr_w_buf = 0;
  199. u8 cp15_opcode_buf[4];
  200. jtag_add_end_state(TAP_RTI);
  201. arm_jtag_scann(jtag_info, 0xf);
  202. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  203. buf_set_u32(cp15_opcode_buf, 0, 32, cp15_opcode);
  204. fields[0].device = jtag_info->chain_pos;
  205. fields[0].num_bits = 1;
  206. fields[0].out_value = &access_type_buf;
  207. fields[0].out_mask = NULL;
  208. fields[0].in_value = NULL;
  209. fields[0].in_check_value = NULL;
  210. fields[0].in_check_mask = NULL;
  211. fields[0].in_handler = NULL;
  212. fields[0].in_handler_priv = NULL;
  213. fields[1].device = jtag_info->chain_pos;
  214. fields[1].num_bits = 32;
  215. fields[1].out_value = cp15_opcode_buf;
  216. fields[1].out_mask = NULL;
  217. fields[1].in_value = NULL;
  218. fields[1].in_check_value = NULL;
  219. fields[1].in_check_mask = NULL;
  220. fields[1].in_handler = NULL;
  221. fields[1].in_handler_priv = NULL;
  222. fields[2].device = jtag_info->chain_pos;
  223. fields[2].num_bits = 6;
  224. fields[2].out_value = &reg_addr_buf;
  225. fields[2].out_mask = NULL;
  226. fields[2].in_value = NULL;
  227. fields[2].in_check_value = NULL;
  228. fields[2].in_check_mask = NULL;
  229. fields[2].in_handler = NULL;
  230. fields[2].in_handler_priv = NULL;
  231. fields[3].device = jtag_info->chain_pos;
  232. fields[3].num_bits = 1;
  233. fields[3].out_value = &nr_w_buf;
  234. fields[3].out_mask = NULL;
  235. fields[3].in_value = NULL;
  236. fields[3].in_check_value = NULL;
  237. fields[3].in_check_mask = NULL;
  238. fields[3].in_handler = NULL;
  239. fields[3].in_handler_priv = NULL;
  240. jtag_add_dr_scan(4, fields, -1, NULL);
  241. arm9tdmi_clock_out(jtag_info, arm_opcode, 0, NULL, 0);
  242. arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 1);
  243. arm7_9_execute_sys_speed(target);
  244. if (jtag_execute_queue() != ERROR_OK)
  245. {
  246. ERROR("failed executing JTAG queue, exiting");
  247. exit(-1);
  248. }
  249. return ERROR_OK;
  250. }
  251. int arm920t_read_cp15_interpreted(target_t *target, u32 cp15_opcode, u32 address, u32 *value)
  252. {
  253. armv4_5_common_t *armv4_5 = target->arch_info;
  254. u32* regs_p[1];
  255. u32 regs[2];
  256. u32 cp15c15 = 0x0;
  257. /* load address into R1 */
  258. regs[1] = address;
  259. arm9tdmi_write_core_regs(target, 0x2, regs);
  260. /* read-modify-write CP15 test state register
  261. * to enable interpreted access mode */
  262. arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
  263. jtag_execute_queue();
  264. cp15c15 |= 1; /* set interpret mode */
  265. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  266. /* execute CP15 instruction and ARM load (reading from coprocessor) */
  267. arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_LDR(0, 1));
  268. /* disable interpreted access mode */
  269. cp15c15 &= ~1U; /* clear interpret mode */
  270. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  271. /* retrieve value from R0 */
  272. regs_p[0] = value;
  273. arm9tdmi_read_core_regs(target, 0x1, regs_p);
  274. jtag_execute_queue();
  275. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  276. DEBUG("cp15_opcode: %8.8x, address: %8.8x, value: %8.8x", cp15_opcode, address, *value);
  277. #endif
  278. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
  279. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
  280. return ERROR_OK;
  281. }
  282. int arm920t_write_cp15_interpreted(target_t *target, u32 cp15_opcode, u32 value, u32 address)
  283. {
  284. u32 cp15c15 = 0x0;
  285. armv4_5_common_t *armv4_5 = target->arch_info;
  286. u32 regs[2];
  287. /* load value, address into R0, R1 */
  288. regs[0] = value;
  289. regs[1] = address;
  290. arm9tdmi_write_core_regs(target, 0x3, regs);
  291. /* read-modify-write CP15 test state register
  292. * to enable interpreted access mode */
  293. arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
  294. jtag_execute_queue();
  295. cp15c15 |= 1; /* set interpret mode */
  296. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  297. /* execute CP15 instruction and ARM store (writing to coprocessor) */
  298. arm920t_execute_cp15(target, cp15_opcode, ARMV4_5_STR(0, 1));
  299. /* disable interpreted access mode */
  300. cp15c15 &= ~1U; /* set interpret mode */
  301. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  302. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  303. DEBUG("cp15_opcode: %8.8x, value: %8.8x, address: %8.8x", cp15_opcode, value, address);
  304. #endif
  305. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
  306. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
  307. return ERROR_OK;
  308. }
  309. u32 arm920t_get_ttb(target_t *target)
  310. {
  311. int retval;
  312. u32 ttb = 0x0;
  313. if ((retval = arm920t_read_cp15_interpreted(target, 0xeebf0f51, 0x0, &ttb)) != ERROR_OK)
  314. return retval;
  315. return ttb;
  316. }
  317. void arm920t_disable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
  318. {
  319. u32 cp15_control;
  320. /* read cp15 control register */
  321. arm920t_read_cp15_physical(target, 0x2, &cp15_control);
  322. jtag_execute_queue();
  323. if (mmu)
  324. cp15_control &= ~0x1U;
  325. if (d_u_cache)
  326. cp15_control &= ~0x4U;
  327. if (i_cache)
  328. cp15_control &= ~0x1000U;
  329. arm920t_write_cp15_physical(target, 0x2, cp15_control);
  330. }
  331. void arm920t_enable_mmu_caches(target_t *target, int mmu, int d_u_cache, int i_cache)
  332. {
  333. u32 cp15_control;
  334. /* read cp15 control register */
  335. arm920t_read_cp15_physical(target, 0x2, &cp15_control);
  336. jtag_execute_queue();
  337. if (mmu)
  338. cp15_control |= 0x1U;
  339. if (d_u_cache)
  340. cp15_control |= 0x4U;
  341. if (i_cache)
  342. cp15_control |= 0x1000U;
  343. arm920t_write_cp15_physical(target, 0x2, cp15_control);
  344. }
  345. void arm920t_post_debug_entry(target_t *target)
  346. {
  347. u32 cp15c15;
  348. armv4_5_common_t *armv4_5 = target->arch_info;
  349. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  350. arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
  351. arm920t_common_t *arm920t = arm9tdmi->arch_info;
  352. /* examine cp15 control reg */
  353. arm920t_read_cp15_physical(target, 0x2, &arm920t->cp15_control_reg);
  354. jtag_execute_queue();
  355. DEBUG("cp15_control_reg: %8.8x", arm920t->cp15_control_reg);
  356. if (arm920t->armv4_5_mmu.armv4_5_cache.ctype == -1)
  357. {
  358. u32 cache_type_reg;
  359. /* identify caches */
  360. arm920t_read_cp15_physical(target, 0x1, &cache_type_reg);
  361. jtag_execute_queue();
  362. armv4_5_identify_cache(cache_type_reg, &arm920t->armv4_5_mmu.armv4_5_cache);
  363. }
  364. arm920t->armv4_5_mmu.mmu_enabled = (arm920t->cp15_control_reg & 0x1U) ? 1 : 0;
  365. arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = (arm920t->cp15_control_reg & 0x4U) ? 1 : 0;
  366. arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = (arm920t->cp15_control_reg & 0x1000U) ? 1 : 0;
  367. /* save i/d fault status and address register */
  368. arm920t_read_cp15_interpreted(target, 0xee150f10, 0x0, &arm920t->d_fsr);
  369. arm920t_read_cp15_interpreted(target, 0xee150f30, 0x0, &arm920t->i_fsr);
  370. arm920t_read_cp15_interpreted(target, 0xee160f10, 0x0, &arm920t->d_far);
  371. arm920t_read_cp15_interpreted(target, 0xee160f30, 0x0, &arm920t->i_far);
  372. DEBUG("D FSR: 0x%8.8x, D FAR: 0x%8.8x, I FSR: 0x%8.8x, I FAR: 0x%8.8x",
  373. arm920t->d_fsr, arm920t->d_far, arm920t->i_fsr, arm920t->i_far);
  374. if (arm920t->preserve_cache)
  375. {
  376. /* read-modify-write CP15 test state register
  377. * to disable I/D-cache linefills */
  378. arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
  379. jtag_execute_queue();
  380. cp15c15 |= 0x600;
  381. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  382. }
  383. }
  384. void arm920t_pre_restore_context(target_t *target)
  385. {
  386. u32 cp15c15;
  387. armv4_5_common_t *armv4_5 = target->arch_info;
  388. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  389. arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
  390. arm920t_common_t *arm920t = arm9tdmi->arch_info;
  391. /* restore i/d fault status and address register */
  392. arm920t_write_cp15_interpreted(target, 0xee050f10, arm920t->d_fsr, 0x0);
  393. arm920t_write_cp15_interpreted(target, 0xee050f30, arm920t->i_fsr, 0x0);
  394. arm920t_write_cp15_interpreted(target, 0xee060f10, arm920t->d_far, 0x0);
  395. arm920t_write_cp15_interpreted(target, 0xee060f30, arm920t->i_far, 0x0);
  396. /* read-modify-write CP15 test state register
  397. * to reenable I/D-cache linefills */
  398. if (arm920t->preserve_cache)
  399. {
  400. arm920t_read_cp15_physical(target, 0x1e, &cp15c15);
  401. jtag_execute_queue();
  402. cp15c15 &= ~0x600U;
  403. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  404. }
  405. }
  406. int arm920t_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm920t_common_t **arm920t_p)
  407. {
  408. armv4_5_common_t *armv4_5 = target->arch_info;
  409. arm7_9_common_t *arm7_9;
  410. arm9tdmi_common_t *arm9tdmi;
  411. arm920t_common_t *arm920t;
  412. if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
  413. {
  414. return -1;
  415. }
  416. arm7_9 = armv4_5->arch_info;
  417. if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC)
  418. {
  419. return -1;
  420. }
  421. arm9tdmi = arm7_9->arch_info;
  422. if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC)
  423. {
  424. return -1;
  425. }
  426. arm920t = arm9tdmi->arch_info;
  427. if (arm920t->common_magic != ARM920T_COMMON_MAGIC)
  428. {
  429. return -1;
  430. }
  431. *armv4_5_p = armv4_5;
  432. *arm7_9_p = arm7_9;
  433. *arm9tdmi_p = arm9tdmi;
  434. *arm920t_p = arm920t;
  435. return ERROR_OK;
  436. }
  437. int arm920t_arch_state(struct target_s *target, char *buf, int buf_size)
  438. {
  439. armv4_5_common_t *armv4_5 = target->arch_info;
  440. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  441. arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
  442. arm920t_common_t *arm920t = arm9tdmi->arch_info;
  443. char *state[] =
  444. {
  445. "disabled", "enabled"
  446. };
  447. if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
  448. {
  449. ERROR("BUG: called for a non-ARMv4/5 target");
  450. exit(-1);
  451. }
  452. snprintf(buf, buf_size,
  453. "target halted in %s state due to %s, current mode: %s\n"
  454. "cpsr: 0x%8.8x pc: 0x%8.8x\n"
  455. "MMU: %s, D-Cache: %s, I-Cache: %s",
  456. armv4_5_state_strings[armv4_5->core_state],
  457. target_debug_reason_strings[target->debug_reason],
  458. armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
  459. buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
  460. buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
  461. state[arm920t->armv4_5_mmu.mmu_enabled],
  462. state[arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
  463. state[arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
  464. return ERROR_OK;
  465. }
  466. int arm920t_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
  467. {
  468. int retval;
  469. retval = arm7_9_read_memory(target, address, size, count, buffer);
  470. return retval;
  471. }
  472. int arm920t_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
  473. {
  474. int retval;
  475. armv4_5_common_t *armv4_5 = target->arch_info;
  476. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  477. arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
  478. arm920t_common_t *arm920t = arm9tdmi->arch_info;
  479. if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK)
  480. return retval;
  481. if (((size == 4) || (size == 2)) && (count == 1))
  482. {
  483. if (arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled)
  484. {
  485. DEBUG("D-Cache enabled, writing through to main memory");
  486. u32 pa, cb, ap;
  487. int type, domain;
  488. pa = armv4_5_mmu_translate_va(target, &arm920t->armv4_5_mmu, address, &type, &cb, &domain, &ap);
  489. if (type == -1)
  490. return ERROR_OK;
  491. /* cacheable & bufferable means write-back region */
  492. if (cb == 3)
  493. armv4_5_mmu_write_physical(target, &arm920t->armv4_5_mmu, pa, size, count, buffer);
  494. }
  495. if (arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled)
  496. {
  497. DEBUG("I-Cache enabled, invalidating affected I-Cache line");
  498. arm920t_write_cp15_interpreted(target, 0xee070f35, 0x0, address);
  499. }
  500. }
  501. return retval;
  502. }
  503. int arm920t_soft_reset_halt(struct target_s *target)
  504. {
  505. armv4_5_common_t *armv4_5 = target->arch_info;
  506. arm7_9_common_t *arm7_9 = armv4_5->arch_info;
  507. arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info;
  508. arm920t_common_t *arm920t = arm9tdmi->arch_info;
  509. reg_t *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
  510. if (target->state == TARGET_RUNNING)
  511. {
  512. target->type->halt(target);
  513. }
  514. while (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
  515. {
  516. embeddedice_read_reg(dbg_stat);
  517. jtag_execute_queue();
  518. }
  519. target->state = TARGET_HALTED;
  520. /* SVC, ARM state, IRQ and FIQ disabled */
  521. buf_set_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 8, 0xd3);
  522. armv4_5->core_cache->reg_list[ARMV4_5_CPSR].dirty = 1;
  523. armv4_5->core_cache->reg_list[ARMV4_5_CPSR].valid = 1;
  524. /* start fetching from 0x0 */
  525. buf_set_u32(armv4_5->core_cache->reg_list[15].value, 0, 32, 0x0);
  526. armv4_5->core_cache->reg_list[15].dirty = 1;
  527. armv4_5->core_cache->reg_list[15].valid = 1;
  528. armv4_5->core_mode = ARMV4_5_MODE_SVC;
  529. armv4_5->core_state = ARMV4_5_STATE_ARM;
  530. arm920t_disable_mmu_caches(target, 1, 1, 1);
  531. arm920t->armv4_5_mmu.mmu_enabled = 0;
  532. arm920t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
  533. arm920t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
  534. target_call_event_callbacks(target, TARGET_EVENT_HALTED);
  535. return ERROR_OK;
  536. }
  537. int arm920t_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
  538. {
  539. arm9tdmi_init_target(cmd_ctx, target);
  540. return ERROR_OK;
  541. }
  542. int arm920t_quit()
  543. {
  544. return ERROR_OK;
  545. }
  546. int arm920t_init_arch_info(target_t *target, arm920t_common_t *arm920t, int chain_pos, char *variant)
  547. {
  548. arm9tdmi_common_t *arm9tdmi = &arm920t->arm9tdmi_common;
  549. arm7_9_common_t *arm7_9 = &arm9tdmi->arm7_9_common;
  550. /* initialize arm9tdmi specific info (including arm7_9 and armv4_5)
  551. */
  552. arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant);
  553. arm9tdmi->arch_info = arm920t;
  554. arm920t->common_magic = ARM920T_COMMON_MAGIC;
  555. arm7_9->post_debug_entry = arm920t_post_debug_entry;
  556. arm7_9->pre_restore_context = arm920t_pre_restore_context;
  557. arm920t->armv4_5_mmu.armv4_5_cache.ctype = -1;
  558. arm920t->armv4_5_mmu.get_ttb = arm920t_get_ttb;
  559. arm920t->armv4_5_mmu.read_memory = arm7_9_read_memory;
  560. arm920t->armv4_5_mmu.write_memory = arm7_9_write_memory;
  561. arm920t->armv4_5_mmu.disable_mmu_caches = arm920t_disable_mmu_caches;
  562. arm920t->armv4_5_mmu.enable_mmu_caches = arm920t_enable_mmu_caches;
  563. arm920t->armv4_5_mmu.has_tiny_pages = 1;
  564. arm920t->armv4_5_mmu.mmu_enabled = 0;
  565. /* disabling linefills leads to lockups, so keep them enabled for now
  566. * this doesn't affect correctness, but might affect timing issues, if
  567. * important data is evicted from the cache during the debug session
  568. * */
  569. arm920t->preserve_cache = 0;
  570. /* override hw single-step capability from ARM9TDMI */
  571. arm7_9->has_single_step = 1;
  572. return ERROR_OK;
  573. }
  574. int arm920t_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
  575. {
  576. int chain_pos;
  577. char *variant = NULL;
  578. arm920t_common_t *arm920t = malloc(sizeof(arm920t_common_t));
  579. if (argc < 4)
  580. {
  581. ERROR("'target arm920t' requires at least one additional argument");
  582. exit(-1);
  583. }
  584. chain_pos = strtoul(args[3], NULL, 0);
  585. if (argc >= 5)
  586. variant = args[4];
  587. DEBUG("chain_pos: %i, variant: %s", chain_pos, variant);
  588. arm920t_init_arch_info(target, arm920t, chain_pos, variant);
  589. return ERROR_OK;
  590. }
  591. int arm920t_register_commands(struct command_context_s *cmd_ctx)
  592. {
  593. int retval;
  594. command_t *arm920t_cmd;
  595. retval = arm9tdmi_register_commands(cmd_ctx);
  596. arm920t_cmd = register_command(cmd_ctx, NULL, "arm920t", NULL, COMMAND_ANY, "arm920t specific commands");
  597. register_command(cmd_ctx, arm920t_cmd, "cp15", arm920t_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <num> [value]");
  598. register_command(cmd_ctx, arm920t_cmd, "cp15i", arm920t_handle_cp15i_command, COMMAND_EXEC, "display/modify cp15 (interpreted access) <opcode> [value] [address]");
  599. register_command(cmd_ctx, arm920t_cmd, "cache_info", arm920t_handle_cache_info_command, COMMAND_EXEC, "display information about target caches");
  600. register_command(cmd_ctx, arm920t_cmd, "virt2phys", arm920t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>");
  601. register_command(cmd_ctx, arm920t_cmd, "mdw_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory words <physical addr> [count]");
  602. register_command(cmd_ctx, arm920t_cmd, "mdh_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory half-words <physical addr> [count]");
  603. register_command(cmd_ctx, arm920t_cmd, "mdb_phys", arm920t_handle_md_phys_command, COMMAND_EXEC, "display memory bytes <physical addr> [count]");
  604. register_command(cmd_ctx, arm920t_cmd, "mww_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory word <physical addr> <value>");
  605. register_command(cmd_ctx, arm920t_cmd, "mwh_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory half-word <physical addr> <value>");
  606. register_command(cmd_ctx, arm920t_cmd, "mwb_phys", arm920t_handle_mw_phys_command, COMMAND_EXEC, "write memory byte <physical addr> <value>");
  607. register_command(cmd_ctx, arm920t_cmd, "read_cache", arm920t_handle_read_cache_command, COMMAND_EXEC, "display I/D cache content");
  608. register_command(cmd_ctx, arm920t_cmd, "read_mmu", arm920t_handle_read_mmu_command, COMMAND_EXEC, "display I/D mmu content");
  609. return ERROR_OK;
  610. }
  611. int arm920t_handle_read_cache_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  612. {
  613. target_t *target = get_current_target(cmd_ctx);
  614. armv4_5_common_t *armv4_5;
  615. arm7_9_common_t *arm7_9;
  616. arm9tdmi_common_t *arm9tdmi;
  617. arm920t_common_t *arm920t;
  618. arm_jtag_t *jtag_info;
  619. u32 cp15c15;
  620. u32 cp15_ctrl, cp15_ctrl_saved;
  621. u32 regs[16];
  622. u32 *regs_p[16];
  623. u32 C15_C_D_Ind, C15_C_I_Ind;
  624. int i;
  625. FILE *output;
  626. arm920t_cache_line_t d_cache[8][64], i_cache[8][64];
  627. int segment, index;
  628. if (argc != 1)
  629. {
  630. command_print(cmd_ctx, "usage: arm920t read_cache <filename>");
  631. return ERROR_OK;
  632. }
  633. if ((output = fopen(args[0], "w")) == NULL)
  634. {
  635. DEBUG("error opening cache content file");
  636. return ERROR_OK;
  637. }
  638. for (i = 0; i < 16; i++)
  639. regs_p[i] = &regs[i];
  640. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  641. {
  642. command_print(cmd_ctx, "current target isn't an ARM920t target");
  643. return ERROR_OK;
  644. }
  645. jtag_info = &arm7_9->jtag_info;
  646. /* disable MMU and Caches */
  647. arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
  648. jtag_execute_queue();
  649. cp15_ctrl_saved = cp15_ctrl;
  650. cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
  651. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
  652. /* read CP15 test state register */
  653. arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
  654. jtag_execute_queue();
  655. /* read DCache content */
  656. fprintf(output, "DCache:\n");
  657. /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
  658. for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
  659. {
  660. fprintf(output, "\nsegment: %i\n----------", segment);
  661. /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
  662. regs[0] = 0x0 | (segment << 5);
  663. arm9tdmi_write_core_regs(target, 0x1, regs);
  664. /* set interpret mode */
  665. cp15c15 |= 0x1;
  666. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  667. /* D CAM Read, loads current victim into C15.C.D.Ind */
  668. arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(1, 0));
  669. /* read current victim */
  670. arm920t_read_cp15_physical(target, 0x3d, &C15_C_D_Ind);
  671. /* clear interpret mode */
  672. cp15c15 &= ~0x1;
  673. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  674. for (index = 0; index < 64; index++)
  675. {
  676. /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
  677. regs[0] = 0x0 | (segment << 5) | (index << 26);
  678. arm9tdmi_write_core_regs(target, 0x1, regs);
  679. /* set interpret mode */
  680. cp15c15 |= 0x1;
  681. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  682. /* Write DCache victim */
  683. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
  684. /* Read D RAM */
  685. arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,10,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
  686. /* Read D CAM */
  687. arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,6,2), ARMV4_5_LDR(9, 0));
  688. /* clear interpret mode */
  689. cp15c15 &= ~0x1;
  690. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  691. /* read D RAM and CAM content */
  692. arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
  693. jtag_execute_queue();
  694. d_cache[segment][index].cam = regs[9];
  695. /* mask LFSR[6] */
  696. regs[9] &= 0xfffffffe;
  697. fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8x, content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
  698. for (i = 1; i < 9; i++)
  699. {
  700. d_cache[segment][index].data[i] = regs[i];
  701. fprintf(output, "%i: 0x%8.8x\n", i-1, regs[i]);
  702. }
  703. }
  704. /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
  705. regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
  706. arm9tdmi_write_core_regs(target, 0x1, regs);
  707. /* set interpret mode */
  708. cp15c15 |= 0x1;
  709. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  710. /* Write DCache victim */
  711. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,0), ARMV4_5_LDR(1, 0));
  712. /* clear interpret mode */
  713. cp15c15 &= ~0x1;
  714. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  715. }
  716. /* read ICache content */
  717. fprintf(output, "ICache:\n");
  718. /* go through segments 0 to nsets (8 on ARM920T, 4 on ARM922T) */
  719. for (segment = 0; segment < arm920t->armv4_5_mmu.armv4_5_cache.d_u_size.nsets; segment++)
  720. {
  721. fprintf(output, "segment: %i\n----------", segment);
  722. /* Ra: r0 = SBZ(31:8):segment(7:5):SBZ(4:0) */
  723. regs[0] = 0x0 | (segment << 5);
  724. arm9tdmi_write_core_regs(target, 0x1, regs);
  725. /* set interpret mode */
  726. cp15c15 |= 0x1;
  727. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  728. /* I CAM Read, loads current victim into C15.C.I.Ind */
  729. arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(1, 0));
  730. /* read current victim */
  731. arm920t_read_cp15_physical(target, 0x3b, &C15_C_I_Ind);
  732. /* clear interpret mode */
  733. cp15c15 &= ~0x1;
  734. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  735. for (index = 0; index < 64; index++)
  736. {
  737. /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
  738. regs[0] = 0x0 | (segment << 5) | (index << 26);
  739. arm9tdmi_write_core_regs(target, 0x1, regs);
  740. /* set interpret mode */
  741. cp15c15 |= 0x1;
  742. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  743. /* Write ICache victim */
  744. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
  745. /* Read I RAM */
  746. arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,9,2), ARMV4_5_LDMIA(0, 0x1fe, 0, 0));
  747. /* Read I CAM */
  748. arm920t_execute_cp15(target, ARMV4_5_MCR(15,2,0,15,5,2), ARMV4_5_LDR(9, 0));
  749. /* clear interpret mode */
  750. cp15c15 &= ~0x1;
  751. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  752. /* read I RAM and CAM content */
  753. arm9tdmi_read_core_regs(target, 0x3fe, regs_p);
  754. jtag_execute_queue();
  755. i_cache[segment][index].cam = regs[9];
  756. /* mask LFSR[6] */
  757. regs[9] &= 0xfffffffe;
  758. fprintf(output, "\nsegment: %i, index: %i, CAM: 0x%8.8x, content (%s):\n", segment, index, regs[9], (regs[9] & 0x10) ? "valid" : "invalid");
  759. for (i = 1; i < 9; i++)
  760. {
  761. i_cache[segment][index].data[i] = regs[i];
  762. fprintf(output, "%i: 0x%8.8x\n", i-1, regs[i]);
  763. }
  764. }
  765. /* Ra: r0 = index(31:26):SBZ(25:8):segment(7:5):SBZ(4:0) */
  766. regs[0] = 0x0 | (segment << 5) | (C15_C_D_Ind << 26);
  767. arm9tdmi_write_core_regs(target, 0x1, regs);
  768. /* set interpret mode */
  769. cp15c15 |= 0x1;
  770. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  771. /* Write ICache victim */
  772. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,9,1,1), ARMV4_5_LDR(1, 0));
  773. /* clear interpret mode */
  774. cp15c15 &= ~0x1;
  775. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  776. }
  777. /* restore CP15 MMU and Cache settings */
  778. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
  779. command_print(cmd_ctx, "cache content successfully output to %s", args[0]);
  780. fclose(output);
  781. /* mark registers dirty */
  782. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
  783. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
  784. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = 1;
  785. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = 1;
  786. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = 1;
  787. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = 1;
  788. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = 1;
  789. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = 1;
  790. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = 1;
  791. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = 1;
  792. return ERROR_OK;
  793. }
  794. int arm920t_handle_read_mmu_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  795. {
  796. target_t *target = get_current_target(cmd_ctx);
  797. armv4_5_common_t *armv4_5;
  798. arm7_9_common_t *arm7_9;
  799. arm9tdmi_common_t *arm9tdmi;
  800. arm920t_common_t *arm920t;
  801. arm_jtag_t *jtag_info;
  802. u32 cp15c15;
  803. u32 cp15_ctrl, cp15_ctrl_saved;
  804. u32 regs[16];
  805. u32 *regs_p[16];
  806. int i;
  807. FILE *output;
  808. u32 Dlockdown, Ilockdown;
  809. arm920t_tlb_entry_t d_tlb[64], i_tlb[64];
  810. int victim;
  811. if (argc != 1)
  812. {
  813. command_print(cmd_ctx, "usage: arm920t read_mmu <filename>");
  814. return ERROR_OK;
  815. }
  816. if ((output = fopen(args[0], "w")) == NULL)
  817. {
  818. DEBUG("error opening mmu content file");
  819. return ERROR_OK;
  820. }
  821. for (i = 0; i < 16; i++)
  822. regs_p[i] = &regs[i];
  823. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  824. {
  825. command_print(cmd_ctx, "current target isn't an ARM920t target");
  826. return ERROR_OK;
  827. }
  828. jtag_info = &arm7_9->jtag_info;
  829. /* disable MMU and Caches */
  830. arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), &cp15_ctrl);
  831. jtag_execute_queue();
  832. cp15_ctrl_saved = cp15_ctrl;
  833. cp15_ctrl &= ~(ARMV4_5_MMU_ENABLED | ARMV4_5_D_U_CACHE_ENABLED | ARMV4_5_I_CACHE_ENABLED);
  834. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl);
  835. /* read CP15 test state register */
  836. arm920t_read_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), &cp15c15);
  837. jtag_execute_queue();
  838. /* prepare reading D TLB content
  839. * */
  840. /* set interpret mode */
  841. cp15c15 |= 0x1;
  842. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  843. /* Read D TLB lockdown */
  844. arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,0), ARMV4_5_LDR(1, 0));
  845. /* clear interpret mode */
  846. cp15c15 &= ~0x1;
  847. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  848. /* read D TLB lockdown stored to r1 */
  849. arm9tdmi_read_core_regs(target, 0x2, regs_p);
  850. jtag_execute_queue();
  851. Dlockdown = regs[1];
  852. for (victim = 0; victim < 64; victim += 8)
  853. {
  854. /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
  855. * base remains unchanged, victim goes through entries 0 to 63 */
  856. regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
  857. arm9tdmi_write_core_regs(target, 0x2, regs);
  858. /* set interpret mode */
  859. cp15c15 |= 0x1;
  860. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  861. /* Write D TLB lockdown */
  862. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
  863. /* Read D TLB CAM */
  864. arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,6,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
  865. /* clear interpret mode */
  866. cp15c15 &= ~0x1;
  867. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  868. /* read D TLB CAM content stored to r2-r9 */
  869. arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
  870. jtag_execute_queue();
  871. for (i = 0; i < 8; i++)
  872. d_tlb[victim + i].cam = regs[i + 2];
  873. }
  874. for (victim = 0; victim < 64; victim++)
  875. {
  876. /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
  877. * base remains unchanged, victim goes through entries 0 to 63 */
  878. regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
  879. arm9tdmi_write_core_regs(target, 0x2, regs);
  880. /* set interpret mode */
  881. cp15c15 |= 0x1;
  882. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  883. /* Write D TLB lockdown */
  884. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
  885. /* Read D TLB RAM1 */
  886. arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,10,4), ARMV4_5_LDR(2,0));
  887. /* Read D TLB RAM2 */
  888. arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,2,5), ARMV4_5_LDR(3,0));
  889. /* clear interpret mode */
  890. cp15c15 &= ~0x1;
  891. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  892. /* read D TLB RAM content stored to r2 and r3 */
  893. arm9tdmi_read_core_regs(target, 0xc, regs_p);
  894. jtag_execute_queue();
  895. d_tlb[victim].ram1 = regs[2];
  896. d_tlb[victim].ram2 = regs[3];
  897. }
  898. /* restore D TLB lockdown */
  899. regs[1] = Dlockdown;
  900. arm9tdmi_write_core_regs(target, 0x2, regs);
  901. /* Write D TLB lockdown */
  902. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,0), ARMV4_5_STR(1, 0));
  903. /* prepare reading I TLB content
  904. * */
  905. /* set interpret mode */
  906. cp15c15 |= 0x1;
  907. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  908. /* Read I TLB lockdown */
  909. arm920t_execute_cp15(target, ARMV4_5_MRC(15,0,0,10,0,1), ARMV4_5_LDR(1, 0));
  910. /* clear interpret mode */
  911. cp15c15 &= ~0x1;
  912. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  913. /* read I TLB lockdown stored to r1 */
  914. arm9tdmi_read_core_regs(target, 0x2, regs_p);
  915. jtag_execute_queue();
  916. Ilockdown = regs[1];
  917. for (victim = 0; victim < 64; victim += 8)
  918. {
  919. /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
  920. * base remains unchanged, victim goes through entries 0 to 63 */
  921. regs[1] = (Ilockdown & 0xfc000000) | (victim << 20);
  922. arm9tdmi_write_core_regs(target, 0x2, regs);
  923. /* set interpret mode */
  924. cp15c15 |= 0x1;
  925. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  926. /* Write I TLB lockdown */
  927. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
  928. /* Read I TLB CAM */
  929. arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,5,4), ARMV4_5_LDMIA(0, 0x3fc, 0, 0));
  930. /* clear interpret mode */
  931. cp15c15 &= ~0x1;
  932. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  933. /* read I TLB CAM content stored to r2-r9 */
  934. arm9tdmi_read_core_regs(target, 0x3fc, regs_p);
  935. jtag_execute_queue();
  936. for (i = 0; i < 8; i++)
  937. i_tlb[i + victim].cam = regs[i + 2];
  938. }
  939. for (victim = 0; victim < 64; victim++)
  940. {
  941. /* new lockdown value: base[31:26]:victim[25:20]:SBZ[19:1]:p[0]
  942. * base remains unchanged, victim goes through entries 0 to 63 */
  943. regs[1] = (Dlockdown & 0xfc000000) | (victim << 20);
  944. arm9tdmi_write_core_regs(target, 0x2, regs);
  945. /* set interpret mode */
  946. cp15c15 |= 0x1;
  947. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0xf, 0), cp15c15);
  948. /* Write I TLB lockdown */
  949. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
  950. /* Read I TLB RAM1 */
  951. arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,9,4), ARMV4_5_LDR(2,0));
  952. /* Read I TLB RAM2 */
  953. arm920t_execute_cp15(target, ARMV4_5_MCR(15,4,0,15,1,5), ARMV4_5_LDR(3,0));
  954. /* clear interpret mode */
  955. cp15c15 &= ~0x1;
  956. arm920t_write_cp15_physical(target, 0x1e, cp15c15);
  957. /* read I TLB RAM content stored to r2 and r3 */
  958. arm9tdmi_read_core_regs(target, 0xc, regs_p);
  959. jtag_execute_queue();
  960. i_tlb[victim].ram1 = regs[2];
  961. i_tlb[victim].ram2 = regs[3];
  962. }
  963. /* restore I TLB lockdown */
  964. regs[1] = Ilockdown;
  965. arm9tdmi_write_core_regs(target, 0x2, regs);
  966. /* Write I TLB lockdown */
  967. arm920t_execute_cp15(target, ARMV4_5_MCR(15,0,0,10,0,1), ARMV4_5_STR(1, 0));
  968. /* restore CP15 MMU and Cache settings */
  969. arm920t_write_cp15_physical(target, ARM920T_CP15_PHYS_ADDR(0, 0x1, 0), cp15_ctrl_saved);
  970. /* output data to file */
  971. fprintf(output, "D TLB content:\n");
  972. for (i = 0; i < 64; i++)
  973. {
  974. fprintf(output, "%i: 0x%8.8x 0x%8.8x 0x%8.8x %s\n", i, d_tlb[i].cam, d_tlb[i].ram1, d_tlb[i].ram2, (d_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
  975. }
  976. fprintf(output, "\n\nI TLB content:\n");
  977. for (i = 0; i < 64; i++)
  978. {
  979. fprintf(output, "%i: 0x%8.8x 0x%8.8x 0x%8.8x %s\n", i, i_tlb[i].cam, i_tlb[i].ram1, i_tlb[i].ram2, (i_tlb[i].cam & 0x20) ? "(valid)" : "(invalid)");
  980. }
  981. command_print(cmd_ctx, "mmu content successfully output to %s", args[0]);
  982. fclose(output);
  983. /* mark registers dirty */
  984. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
  985. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
  986. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = 1;
  987. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = 1;
  988. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = 1;
  989. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = 1;
  990. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = 1;
  991. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = 1;
  992. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = 1;
  993. ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = 1;
  994. return ERROR_OK;
  995. }
  996. int arm920t_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  997. {
  998. int retval;
  999. target_t *target = get_current_target(cmd_ctx);
  1000. armv4_5_common_t *armv4_5;
  1001. arm7_9_common_t *arm7_9;
  1002. arm9tdmi_common_t *arm9tdmi;
  1003. arm920t_common_t *arm920t;
  1004. arm_jtag_t *jtag_info;
  1005. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  1006. {
  1007. command_print(cmd_ctx, "current target isn't an ARM920t target");
  1008. return ERROR_OK;
  1009. }
  1010. jtag_info = &arm7_9->jtag_info;
  1011. if (target->state != TARGET_HALTED)
  1012. {
  1013. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  1014. return ERROR_OK;
  1015. }
  1016. /* one or more argument, access a single register (write if second argument is given */
  1017. if (argc >= 1)
  1018. {
  1019. int address = strtoul(args[0], NULL, 0);
  1020. if (argc == 1)
  1021. {
  1022. u32 value;
  1023. if ((retval = arm920t_read_cp15_physical(target, address, &value)) != ERROR_OK)
  1024. {
  1025. command_print(cmd_ctx, "couldn't access reg %i", address);
  1026. return ERROR_OK;
  1027. }
  1028. jtag_execute_queue();
  1029. command_print(cmd_ctx, "%i: %8.8x", address, value);
  1030. }
  1031. else if (argc == 2)
  1032. {
  1033. u32 value = strtoul(args[1], NULL, 0);
  1034. if ((retval = arm920t_write_cp15_physical(target, address, value)) != ERROR_OK)
  1035. {
  1036. command_print(cmd_ctx, "couldn't access reg %i", address);
  1037. return ERROR_OK;
  1038. }
  1039. command_print(cmd_ctx, "%i: %8.8x", address, value);
  1040. }
  1041. }
  1042. return ERROR_OK;
  1043. }
  1044. int arm920t_handle_cp15i_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  1045. {
  1046. int retval;
  1047. target_t *target = get_current_target(cmd_ctx);
  1048. armv4_5_common_t *armv4_5;
  1049. arm7_9_common_t *arm7_9;
  1050. arm9tdmi_common_t *arm9tdmi;
  1051. arm920t_common_t *arm920t;
  1052. arm_jtag_t *jtag_info;
  1053. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  1054. {
  1055. command_print(cmd_ctx, "current target isn't an ARM920t target");
  1056. return ERROR_OK;
  1057. }
  1058. jtag_info = &arm7_9->jtag_info;
  1059. if (target->state != TARGET_HALTED)
  1060. {
  1061. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  1062. return ERROR_OK;
  1063. }
  1064. /* one or more argument, access a single register (write if second argument is given */
  1065. if (argc >= 1)
  1066. {
  1067. u32 opcode = strtoul(args[0], NULL, 0);
  1068. if (argc == 1)
  1069. {
  1070. u32 value;
  1071. if ((retval = arm920t_read_cp15_interpreted(target, opcode, 0x0, &value)) != ERROR_OK)
  1072. {
  1073. command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
  1074. return ERROR_OK;
  1075. }
  1076. command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
  1077. }
  1078. else if (argc == 2)
  1079. {
  1080. u32 value = strtoul(args[1], NULL, 0);
  1081. if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, 0)) != ERROR_OK)
  1082. {
  1083. command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
  1084. return ERROR_OK;
  1085. }
  1086. command_print(cmd_ctx, "%8.8x: %8.8x", opcode, value);
  1087. }
  1088. else if (argc == 3)
  1089. {
  1090. u32 value = strtoul(args[1], NULL, 0);
  1091. u32 address = strtoul(args[2], NULL, 0);
  1092. if ((retval = arm920t_write_cp15_interpreted(target, opcode, value, address)) != ERROR_OK)
  1093. {
  1094. command_print(cmd_ctx, "couldn't execute %8.8x", opcode);
  1095. return ERROR_OK;
  1096. }
  1097. command_print(cmd_ctx, "%8.8x: %8.8x %8.8x", opcode, value, address);
  1098. }
  1099. }
  1100. else
  1101. {
  1102. command_print(cmd_ctx, "usage: arm920t cp15i <opcode> [value] [address]");
  1103. }
  1104. return ERROR_OK;
  1105. }
  1106. int arm920t_handle_cache_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
  1107. {
  1108. target_t *target = get_current_target(cmd_ctx);
  1109. armv4_5_common_t *armv4_5;
  1110. arm7_9_common_t *arm7_9;
  1111. arm9tdmi_common_t *arm9tdmi;
  1112. arm920t_common_t *arm920t;
  1113. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  1114. {
  1115. command_print(cmd_ctx, "current target isn't an ARM920t target");
  1116. return ERROR_OK;
  1117. }
  1118. return armv4_5_handle_cache_info_command(cmd_ctx, &arm920t->armv4_5_mmu.armv4_5_cache);
  1119. }
  1120. int arm920t_handle_virt2phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
  1121. {
  1122. target_t *target = get_current_target(cmd_ctx);
  1123. armv4_5_common_t *armv4_5;
  1124. arm7_9_common_t *arm7_9;
  1125. arm9tdmi_common_t *arm9tdmi;
  1126. arm920t_common_t *arm920t;
  1127. arm_jtag_t *jtag_info;
  1128. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  1129. {
  1130. command_print(cmd_ctx, "current target isn't an ARM920t target");
  1131. return ERROR_OK;
  1132. }
  1133. jtag_info = &arm7_9->jtag_info;
  1134. if (target->state != TARGET_HALTED)
  1135. {
  1136. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  1137. return ERROR_OK;
  1138. }
  1139. return armv4_5_mmu_handle_virt2phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
  1140. }
  1141. int arm920t_handle_md_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
  1142. {
  1143. target_t *target = get_current_target(cmd_ctx);
  1144. armv4_5_common_t *armv4_5;
  1145. arm7_9_common_t *arm7_9;
  1146. arm9tdmi_common_t *arm9tdmi;
  1147. arm920t_common_t *arm920t;
  1148. arm_jtag_t *jtag_info;
  1149. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  1150. {
  1151. command_print(cmd_ctx, "current target isn't an ARM920t target");
  1152. return ERROR_OK;
  1153. }
  1154. jtag_info = &arm7_9->jtag_info;
  1155. if (target->state != TARGET_HALTED)
  1156. {
  1157. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  1158. return ERROR_OK;
  1159. }
  1160. return armv4_5_mmu_handle_md_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
  1161. }
  1162. int arm920t_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
  1163. {
  1164. target_t *target = get_current_target(cmd_ctx);
  1165. armv4_5_common_t *armv4_5;
  1166. arm7_9_common_t *arm7_9;
  1167. arm9tdmi_common_t *arm9tdmi;
  1168. arm920t_common_t *arm920t;
  1169. arm_jtag_t *jtag_info;
  1170. if (arm920t_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm920t) != ERROR_OK)
  1171. {
  1172. command_print(cmd_ctx, "current target isn't an ARM920t target");
  1173. return ERROR_OK;
  1174. }
  1175. jtag_info = &arm7_9->jtag_info;
  1176. if (target->state != TARGET_HALTED)
  1177. {
  1178. command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
  1179. return ERROR_OK;
  1180. }
  1181. return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm920t->armv4_5_mmu);
  1182. }