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.
 
 
 
 
 
 

376 lines
12 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. * Copyright (C) 2009 by Øyvind Harboe *
  9. * oyvind.harboe@zylin.com *
  10. * *
  11. * This program is free software; you can redistribute it and/or modify *
  12. * it under the terms of the GNU General Public License as published by *
  13. * the Free Software Foundation; either version 2 of the License, or *
  14. * (at your option) any later version. *
  15. * *
  16. * This program is distributed in the hope that it will be useful, *
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  19. * GNU General Public License for more details. *
  20. * *
  21. * You should have received a copy of the GNU General Public License *
  22. * along with this program; if not, write to the *
  23. * Free Software Foundation, Inc., *
  24. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  25. ***************************************************************************/
  26. #ifndef ARMV4_5_H
  27. #define ARMV4_5_H
  28. #include "register.h"
  29. #include "target.h"
  30. #include "log.h"
  31. #include "etm.h"
  32. typedef enum armv4_5_mode
  33. {
  34. ARMV4_5_MODE_USR = 16,
  35. ARMV4_5_MODE_FIQ = 17,
  36. ARMV4_5_MODE_IRQ = 18,
  37. ARMV4_5_MODE_SVC = 19,
  38. ARMV4_5_MODE_ABT = 23,
  39. ARMV4_5_MODE_UND = 27,
  40. ARMV4_5_MODE_SYS = 31,
  41. ARMV4_5_MODE_ANY = -1
  42. } armv4_5_mode_t;
  43. extern char** armv4_5_mode_strings;
  44. typedef enum armv4_5_state
  45. {
  46. ARMV4_5_STATE_ARM,
  47. ARMV4_5_STATE_THUMB,
  48. ARMV4_5_STATE_JAZELLE,
  49. } armv4_5_state_t;
  50. extern char* armv4_5_state_strings[];
  51. extern int armv4_5_core_reg_map[7][17];
  52. #define ARMV4_5_CORE_REG_MODE(cache, mode, num) \
  53. cache->reg_list[armv4_5_core_reg_map[armv4_5_mode_to_number(mode)][num]]
  54. #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
  55. cache->reg_list[armv4_5_core_reg_map[mode][num]]
  56. /* offsets into armv4_5 core register cache */
  57. enum
  58. {
  59. ARMV4_5_CPSR = 31,
  60. ARMV4_5_SPSR_FIQ = 32,
  61. ARMV4_5_SPSR_IRQ = 33,
  62. ARMV4_5_SPSR_SVC = 34,
  63. ARMV4_5_SPSR_ABT = 35,
  64. ARMV4_5_SPSR_UND = 36
  65. };
  66. #define ARMV4_5_COMMON_MAGIC 0x0A450A45
  67. /* NOTE: this is being morphed into a generic toplevel holder for ARMs. */
  68. #define armv4_5_common_s arm
  69. /**
  70. * Represents a generic ARM core, with standard application registers.
  71. *
  72. * There are sixteen application registers (including PC, SP, LR) and a PSR.
  73. * Cortex-M series cores do not support as many core states or shadowed
  74. * registers as traditional ARM cores, and only support Thumb2 instructions.
  75. */
  76. typedef struct arm
  77. {
  78. int common_magic;
  79. reg_cache_t *core_cache;
  80. int /* armv4_5_mode */ core_mode;
  81. enum armv4_5_state core_state;
  82. /** Flag reporting unavailability of the BKPT instruction. */
  83. bool is_armv4;
  84. /** Handle for the Embedded Trace Module, if one is present. */
  85. struct etm *etm;
  86. int (*full_context)(struct target_s *target);
  87. int (*read_core_reg)(struct target_s *target,
  88. int num, enum armv4_5_mode mode);
  89. int (*write_core_reg)(struct target_s *target,
  90. int num, enum armv4_5_mode mode, uint32_t value);
  91. void *arch_info;
  92. } armv4_5_common_t;
  93. #define target_to_armv4_5 target_to_arm
  94. /** Convert target handle to generic ARM target state handle. */
  95. static inline struct arm *target_to_arm(struct target_s *target)
  96. {
  97. return target->arch_info;
  98. }
  99. static inline bool is_arm(struct arm *arm)
  100. {
  101. return arm && arm->common_magic == ARMV4_5_COMMON_MAGIC;
  102. }
  103. typedef struct armv4_5_algorithm_s
  104. {
  105. int common_magic;
  106. enum armv4_5_mode core_mode;
  107. enum armv4_5_state core_state;
  108. } armv4_5_algorithm_t;
  109. typedef struct armv4_5_core_reg_s
  110. {
  111. int num;
  112. enum armv4_5_mode mode;
  113. target_t *target;
  114. armv4_5_common_t *armv4_5_common;
  115. } armv4_5_core_reg_t;
  116. reg_cache_t* armv4_5_build_reg_cache(target_t *target,
  117. armv4_5_common_t *armv4_5_common);
  118. /* map psr mode bits to linear number */
  119. static __inline int armv4_5_mode_to_number(enum armv4_5_mode mode)
  120. {
  121. switch (mode)
  122. {
  123. case ARMV4_5_MODE_USR: return 0; break;
  124. case ARMV4_5_MODE_FIQ: return 1; break;
  125. case ARMV4_5_MODE_IRQ: return 2; break;
  126. case ARMV4_5_MODE_SVC: return 3; break;
  127. case ARMV4_5_MODE_ABT: return 4; break;
  128. case ARMV4_5_MODE_UND: return 5; break;
  129. case ARMV4_5_MODE_SYS: return 6; break;
  130. case ARMV4_5_MODE_ANY: return 0; break; /* map MODE_ANY to user mode */
  131. default:
  132. LOG_ERROR("invalid mode value encountered %d", mode);
  133. return -1;
  134. }
  135. }
  136. /* map linear number to mode bits */
  137. static __inline enum armv4_5_mode armv4_5_number_to_mode(int number)
  138. {
  139. switch (number)
  140. {
  141. case 0: return ARMV4_5_MODE_USR; break;
  142. case 1: return ARMV4_5_MODE_FIQ; break;
  143. case 2: return ARMV4_5_MODE_IRQ; break;
  144. case 3: return ARMV4_5_MODE_SVC; break;
  145. case 4: return ARMV4_5_MODE_ABT; break;
  146. case 5: return ARMV4_5_MODE_UND; break;
  147. case 6: return ARMV4_5_MODE_SYS; break;
  148. default:
  149. LOG_ERROR("mode index out of bounds %d", number);
  150. return ARMV4_5_MODE_ANY;
  151. }
  152. };
  153. int armv4_5_arch_state(struct target_s *target);
  154. int armv4_5_get_gdb_reg_list(target_t *target,
  155. reg_t **reg_list[], int *reg_list_size);
  156. int armv4_5_register_commands(struct command_context_s *cmd_ctx);
  157. int armv4_5_init_arch_info(target_t *target, armv4_5_common_t *armv4_5);
  158. int armv4_5_run_algorithm(struct target_s *target,
  159. int num_mem_params, mem_param_t *mem_params,
  160. int num_reg_params, reg_param_t *reg_params,
  161. uint32_t entry_point, uint32_t exit_point,
  162. int timeout_ms, void *arch_info);
  163. int armv4_5_invalidate_core_regs(target_t *target);
  164. /* ARM mode instructions
  165. */
  166. /* Store multiple increment after
  167. * Rn: base register
  168. * List: for each bit in list: store register
  169. * S: in priviledged mode: store user-mode registers
  170. * W = 1: update the base register. W = 0: leave the base register untouched
  171. */
  172. #define ARMV4_5_STMIA(Rn, List, S, W) (0xe8800000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List))
  173. /* Load multiple increment after
  174. * Rn: base register
  175. * List: for each bit in list: store register
  176. * S: in priviledged mode: store user-mode registers
  177. * W = 1: update the base register. W = 0: leave the base register untouched
  178. */
  179. #define ARMV4_5_LDMIA(Rn, List, S, W) (0xe8900000 | ((S) << 22) | ((W) << 21) | ((Rn) << 16) | (List))
  180. /* MOV r8, r8 */
  181. #define ARMV4_5_NOP (0xe1a08008)
  182. /* Move PSR to general purpose register
  183. * R = 1: SPSR R = 0: CPSR
  184. * Rn: target register
  185. */
  186. #define ARMV4_5_MRS(Rn, R) (0xe10f0000 | ((R) << 22) | ((Rn) << 12))
  187. /* Store register
  188. * Rd: register to store
  189. * Rn: base register
  190. */
  191. #define ARMV4_5_STR(Rd, Rn) (0xe5800000 | ((Rd) << 12) | ((Rn) << 16))
  192. /* Load register
  193. * Rd: register to load
  194. * Rn: base register
  195. */
  196. #define ARMV4_5_LDR(Rd, Rn) (0xe5900000 | ((Rd) << 12) | ((Rn) << 16))
  197. /* Move general purpose register to PSR
  198. * R = 1: SPSR R = 0: CPSR
  199. * Field: Field mask
  200. * 1: control field 2: extension field 4: status field 8: flags field
  201. * Rm: source register
  202. */
  203. #define ARMV4_5_MSR_GP(Rm, Field, R) (0xe120f000 | (Rm) | ((Field) << 16) | ((R) << 22))
  204. #define ARMV4_5_MSR_IM(Im, Rotate, Field, R) (0xe320f000 | (Im) | ((Rotate) << 8) | ((Field) << 16) | ((R) << 22))
  205. /* Load Register Halfword Immediate Post-Index
  206. * Rd: register to load
  207. * Rn: base register
  208. */
  209. #define ARMV4_5_LDRH_IP(Rd, Rn) (0xe0d000b2 | ((Rd) << 12) | ((Rn) << 16))
  210. /* Load Register Byte Immediate Post-Index
  211. * Rd: register to load
  212. * Rn: base register
  213. */
  214. #define ARMV4_5_LDRB_IP(Rd, Rn) (0xe4d00001 | ((Rd) << 12) | ((Rn) << 16))
  215. /* Store register Halfword Immediate Post-Index
  216. * Rd: register to store
  217. * Rn: base register
  218. */
  219. #define ARMV4_5_STRH_IP(Rd, Rn) (0xe0c000b2 | ((Rd) << 12) | ((Rn) << 16))
  220. /* Store register Byte Immediate Post-Index
  221. * Rd: register to store
  222. * Rn: base register
  223. */
  224. #define ARMV4_5_STRB_IP(Rd, Rn) (0xe4c00001 | ((Rd) << 12) | ((Rn) << 16))
  225. /* Branch (and Link)
  226. * Im: Branch target (left-shifted by 2 bits, added to PC)
  227. * L: 1: branch and link 0: branch only
  228. */
  229. #define ARMV4_5_B(Im, L) (0xea000000 | (Im) | ((L) << 24))
  230. /* Branch and exchange (ARM state)
  231. * Rm: register holding branch target address
  232. */
  233. #define ARMV4_5_BX(Rm) (0xe12fff10 | (Rm))
  234. /* Move to ARM register from coprocessor
  235. * CP: Coprocessor number
  236. * op1: Coprocessor opcode
  237. * Rd: destination register
  238. * CRn: first coprocessor operand
  239. * CRm: second coprocessor operand
  240. * op2: Second coprocessor opcode
  241. */
  242. #define ARMV4_5_MRC(CP, op1, Rd, CRn, CRm, op2) (0xee100010 | (CRm) | ((op2) << 5) | ((CP) << 8) | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
  243. /* Move to coprocessor from ARM register
  244. * CP: Coprocessor number
  245. * op1: Coprocessor opcode
  246. * Rd: destination register
  247. * CRn: first coprocessor operand
  248. * CRm: second coprocessor operand
  249. * op2: Second coprocessor opcode
  250. */
  251. #define ARMV4_5_MCR(CP, op1, Rd, CRn, CRm, op2) (0xee000010 | (CRm) | ((op2) << 5) | ((CP) << 8) | ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
  252. /* Breakpoint instruction (ARMv5)
  253. * Im: 16-bit immediate
  254. */
  255. #define ARMV5_BKPT(Im) (0xe1200070 | ((Im & 0xfff0) << 8) | (Im & 0xf))
  256. /* Thumb mode instructions
  257. */
  258. /* Store register (Thumb mode)
  259. * Rd: source register
  260. * Rn: base register
  261. */
  262. #define ARMV4_5_T_STR(Rd, Rn) ((0x6000 | (Rd) | ((Rn) << 3)) | ((0x6000 | (Rd) | ((Rn) << 3)) << 16))
  263. /* Load register (Thumb state)
  264. * Rd: destination register
  265. * Rn: base register
  266. */
  267. #define ARMV4_5_T_LDR(Rd, Rn) ((0x6800 | ((Rn) << 3) | (Rd)) | ((0x6800 | ((Rn) << 3) | (Rd)) << 16))
  268. /* Load multiple (Thumb state)
  269. * Rn: base register
  270. * List: for each bit in list: store register
  271. */
  272. #define ARMV4_5_T_LDMIA(Rn, List) ((0xc800 | ((Rn) << 8) | (List)) | ((0xc800 | ((Rn) << 8) | List) << 16))
  273. /* Load register with PC relative addressing
  274. * Rd: register to load
  275. */
  276. #define ARMV4_5_T_LDR_PCREL(Rd) ((0x4800 | ((Rd) << 8)) | ((0x4800 | ((Rd) << 8)) << 16))
  277. /* Move hi register (Thumb mode)
  278. * Rd: destination register
  279. * Rm: source register
  280. */
  281. #define ARMV4_5_T_MOV(Rd, Rm) ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) | ((0x4600 | ((Rd) & 0x7) | (((Rd) & 0x8) << 4) | (((Rm) & 0x7) << 3) | (((Rm) & 0x8) << 3)) << 16))
  282. /* No operation (Thumb mode)
  283. */
  284. #define ARMV4_5_T_NOP (0x46c0 | (0x46c0 << 16))
  285. /* Move immediate to register (Thumb state)
  286. * Rd: destination register
  287. * Im: 8-bit immediate value
  288. */
  289. #define ARMV4_5_T_MOV_IM(Rd, Im) ((0x2000 | ((Rd) << 8) | (Im)) | ((0x2000 | ((Rd) << 8) | (Im)) << 16))
  290. /* Branch and Exchange
  291. * Rm: register containing branch target
  292. */
  293. #define ARMV4_5_T_BX(Rm) ((0x4700 | ((Rm) << 3)) | ((0x4700 | ((Rm) << 3)) << 16))
  294. /* Branch (Thumb state)
  295. * Imm: Branch target
  296. */
  297. #define ARMV4_5_T_B(Imm) ((0xe000 | (Imm)) | ((0xe000 | (Imm)) << 16))
  298. /* Breakpoint instruction (ARMv5) (Thumb state)
  299. * Im: 8-bit immediate
  300. */
  301. #define ARMV5_T_BKPT(Im) ((0xbe00 | Im) | ((0xbe00 | Im) << 16))
  302. /* build basic mrc/mcr opcode */
  303. static inline uint32_t mrc_opcode(int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm)
  304. {
  305. uint32_t t = 0;
  306. t|=op1<<21;
  307. t|=op2<<5;
  308. t|=CRn<<16;
  309. t|=CRm<<0;
  310. return t;
  311. }
  312. #endif /* ARMV4_5_H */