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.
 
 
 
 
 
 

298 lines
8.4 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2005 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2008 by Spencer Oliver *
  6. * spen@spen-soft.co.uk *
  7. * *
  8. * This program is free software; you can redistribute it and/or modify *
  9. * it under the terms of the GNU General Public License as published by *
  10. * the Free Software Foundation; either version 2 of the License, or *
  11. * (at your option) any later version. *
  12. * *
  13. * This program is distributed in the hope that it will be useful, *
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  16. * GNU General Public License for more details. *
  17. * *
  18. * You should have received a copy of the GNU General Public License *
  19. * along with this program; if not, write to the *
  20. * Free Software Foundation, Inc., *
  21. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  22. ***************************************************************************/
  23. #ifdef HAVE_CONFIG_H
  24. #include "config.h"
  25. #endif
  26. #include "arm966e.h"
  27. #include "target_type.h"
  28. #include "arm_opcodes.h"
  29. #if 0
  30. #define _DEBUG_INSTRUCTION_EXECUTION_
  31. #endif
  32. int arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e, struct jtag_tap *tap)
  33. {
  34. struct arm7_9_common *arm7_9 = &arm966e->arm7_9_common;
  35. /* initialize arm7/arm9 specific info (including armv4_5) */
  36. arm9tdmi_init_arch_info(target, arm7_9, tap);
  37. arm966e->common_magic = ARM966E_COMMON_MAGIC;
  38. /* The ARM966E-S implements the ARMv5TE architecture which
  39. * has the BKPT instruction, so we don't have to use a watchpoint comparator
  40. */
  41. arm7_9->arm_bkpt = ARMV5_BKPT(0x0);
  42. arm7_9->thumb_bkpt = ARMV5_T_BKPT(0x0) & 0xffff;
  43. return ERROR_OK;
  44. }
  45. static int arm966e_target_create(struct target *target, Jim_Interp *interp)
  46. {
  47. struct arm966e_common *arm966e = calloc(1,sizeof(struct arm966e_common));
  48. return arm966e_init_arch_info(target, arm966e, target->tap);
  49. }
  50. static int arm966e_verify_pointer(struct command_context *cmd_ctx,
  51. struct arm966e_common *arm966e)
  52. {
  53. if (arm966e->common_magic != ARM966E_COMMON_MAGIC) {
  54. command_print(cmd_ctx, "target is not an ARM966");
  55. return ERROR_TARGET_INVALID;
  56. }
  57. return ERROR_OK;
  58. }
  59. /*
  60. * REVISIT: The "read_cp15" and "write_cp15" commands could hook up
  61. * to eventual mrc() and mcr() routines ... the reg_addr values being
  62. * constructed (for CP15 only) from Opcode_1, Opcode_2, and CRn values.
  63. * See section 7.3 of the ARM966E-S TRM.
  64. */
  65. static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *value)
  66. {
  67. int retval = ERROR_OK;
  68. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  69. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  70. struct scan_field fields[3];
  71. uint8_t reg_addr_buf = reg_addr & 0x3f;
  72. uint8_t nr_w_buf = 0;
  73. jtag_set_end_state(TAP_IDLE);
  74. if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
  75. {
  76. return retval;
  77. }
  78. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  79. fields[0].tap = jtag_info->tap;
  80. fields[0].num_bits = 32;
  81. /* REVISIT: table 7-2 shows that bits 31-31 need to be
  82. * specified for accessing BIST registers ...
  83. */
  84. fields[0].out_value = NULL;
  85. fields[0].in_value = NULL;
  86. fields[1].tap = jtag_info->tap;
  87. fields[1].num_bits = 6;
  88. fields[1].out_value = &reg_addr_buf;
  89. fields[1].in_value = NULL;
  90. fields[2].tap = jtag_info->tap;
  91. fields[2].num_bits = 1;
  92. fields[2].out_value = &nr_w_buf;
  93. fields[2].in_value = NULL;
  94. jtag_add_dr_scan(3, fields, jtag_get_end_state());
  95. fields[1].in_value = (uint8_t *)value;
  96. jtag_add_dr_scan(3, fields, jtag_get_end_state());
  97. jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
  98. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  99. if ((retval = jtag_execute_queue()) != ERROR_OK)
  100. {
  101. return retval;
  102. }
  103. LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
  104. #endif
  105. return ERROR_OK;
  106. }
  107. // EXPORTED to str9x (flash)
  108. int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)
  109. {
  110. int retval = ERROR_OK;
  111. struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
  112. struct arm_jtag *jtag_info = &arm7_9->jtag_info;
  113. struct scan_field fields[3];
  114. uint8_t reg_addr_buf = reg_addr & 0x3f;
  115. uint8_t nr_w_buf = 1;
  116. uint8_t value_buf[4];
  117. buf_set_u32(value_buf, 0, 32, value);
  118. jtag_set_end_state(TAP_IDLE);
  119. if ((retval = arm_jtag_scann(jtag_info, 0xf)) != ERROR_OK)
  120. {
  121. return retval;
  122. }
  123. arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL);
  124. fields[0].tap = jtag_info->tap;
  125. fields[0].num_bits = 32;
  126. fields[0].out_value = value_buf;
  127. fields[0].in_value = NULL;
  128. fields[1].tap = jtag_info->tap;
  129. fields[1].num_bits = 6;
  130. fields[1].out_value = &reg_addr_buf;
  131. fields[1].in_value = NULL;
  132. fields[2].tap = jtag_info->tap;
  133. fields[2].num_bits = 1;
  134. fields[2].out_value = &nr_w_buf;
  135. fields[2].in_value = NULL;
  136. jtag_add_dr_scan(3, fields, jtag_get_end_state());
  137. #ifdef _DEBUG_INSTRUCTION_EXECUTION_
  138. LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
  139. #endif
  140. return ERROR_OK;
  141. }
  142. COMMAND_HANDLER(arm966e_handle_cp15_command)
  143. {
  144. int retval;
  145. struct target *target = get_current_target(CMD_CTX);
  146. struct arm966e_common *arm966e = target_to_arm966(target);
  147. retval = arm966e_verify_pointer(CMD_CTX, arm966e);
  148. if (retval != ERROR_OK)
  149. return retval;
  150. if (target->state != TARGET_HALTED)
  151. {
  152. command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
  153. return ERROR_OK;
  154. }
  155. /* one or more argument, access a single register (write if second argument is given */
  156. if (CMD_ARGC >= 1)
  157. {
  158. uint32_t address;
  159. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
  160. if (CMD_ARGC == 1)
  161. {
  162. uint32_t value;
  163. if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK)
  164. {
  165. command_print(CMD_CTX,
  166. "couldn't access reg %" PRIi32,
  167. address);
  168. return ERROR_OK;
  169. }
  170. if ((retval = jtag_execute_queue()) != ERROR_OK)
  171. {
  172. return retval;
  173. }
  174. command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32,
  175. address, value);
  176. }
  177. else if (CMD_ARGC == 2)
  178. {
  179. uint32_t value;
  180. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
  181. if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK)
  182. {
  183. command_print(CMD_CTX,
  184. "couldn't access reg %" PRIi32,
  185. address);
  186. return ERROR_OK;
  187. }
  188. command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32,
  189. address, value);
  190. }
  191. }
  192. return ERROR_OK;
  193. }
  194. static const struct command_registration arm966e_exec_command_handlers[] = {
  195. {
  196. .name = "cp15",
  197. .handler = arm966e_handle_cp15_command,
  198. .mode = COMMAND_EXEC,
  199. .usage = "regnum [value]",
  200. .help = "display/modify cp15 register",
  201. },
  202. COMMAND_REGISTRATION_DONE
  203. };
  204. const struct command_registration arm966e_command_handlers[] = {
  205. {
  206. .chain = arm9tdmi_command_handlers,
  207. },
  208. {
  209. .name = "arm966e",
  210. .mode = COMMAND_ANY,
  211. .help = "arm966e command group",
  212. .chain = arm966e_exec_command_handlers,
  213. },
  214. COMMAND_REGISTRATION_DONE
  215. };
  216. /** Holds methods for ARM966 targets. */
  217. struct target_type arm966e_target =
  218. {
  219. .name = "arm966e",
  220. .poll = arm7_9_poll,
  221. .arch_state = arm_arch_state,
  222. .target_request_data = arm7_9_target_request_data,
  223. .halt = arm7_9_halt,
  224. .resume = arm7_9_resume,
  225. .step = arm7_9_step,
  226. .assert_reset = arm7_9_assert_reset,
  227. .deassert_reset = arm7_9_deassert_reset,
  228. .soft_reset_halt = arm7_9_soft_reset_halt,
  229. .get_gdb_reg_list = arm_get_gdb_reg_list,
  230. .read_memory = arm7_9_read_memory,
  231. .write_memory = arm7_9_write_memory,
  232. .bulk_write_memory = arm7_9_bulk_write_memory,
  233. .checksum_memory = arm_checksum_memory,
  234. .blank_check_memory = arm_blank_check_memory,
  235. .run_algorithm = armv4_5_run_algorithm,
  236. .add_breakpoint = arm7_9_add_breakpoint,
  237. .remove_breakpoint = arm7_9_remove_breakpoint,
  238. .add_watchpoint = arm7_9_add_watchpoint,
  239. .remove_watchpoint = arm7_9_remove_watchpoint,
  240. .commands = arm966e_command_handlers,
  241. .target_create = arm966e_target_create,
  242. .init_target = arm9tdmi_init_target,
  243. .examine = arm7_9_examine,
  244. };