1 /***************************************************************************
2 * Copyright (C) 2009 by David Brownell *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
18 ***************************************************************************/
23 #include "replacements.h"
30 #include "binarybuffer.h"
37 bitfield_desc_t armv7a_psr_bitfield_desc[] =
57 char* armv7a_core_reg_list[] =
59 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
60 "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
61 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
66 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
67 "r13_mon", "lr_mon", "spsr_mon"
70 char * armv7a_mode_strings_list[] =
72 "Illegal mode value", "System and User", "FIQ", "IRQ",
73 "Supervisor", "Abort", "Undefined", "Monitor"
76 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
77 char** armv7a_mode_strings = armv7a_mode_strings_list+1;
79 char* armv7a_state_strings[] =
81 "ARM", "Thumb", "Jazelle", "ThumbEE"
84 armv7a_core_reg_t armv7a_core_reg_list_arch_info[] =
86 {0, ARMV4_5_MODE_ANY, NULL, NULL},
87 {1, ARMV4_5_MODE_ANY, NULL, NULL},
88 {2, ARMV4_5_MODE_ANY, NULL, NULL},
89 {3, ARMV4_5_MODE_ANY, NULL, NULL},
90 {4, ARMV4_5_MODE_ANY, NULL, NULL},
91 {5, ARMV4_5_MODE_ANY, NULL, NULL},
92 {6, ARMV4_5_MODE_ANY, NULL, NULL},
93 {7, ARMV4_5_MODE_ANY, NULL, NULL},
94 {8, ARMV4_5_MODE_ANY, NULL, NULL},
95 {9, ARMV4_5_MODE_ANY, NULL, NULL},
96 {10, ARMV4_5_MODE_ANY, NULL, NULL},
97 {11, ARMV4_5_MODE_ANY, NULL, NULL},
98 {12, ARMV4_5_MODE_ANY, NULL, NULL},
99 {13, ARMV4_5_MODE_USR, NULL, NULL},
100 {14, ARMV4_5_MODE_USR, NULL, NULL},
101 {15, ARMV4_5_MODE_ANY, NULL, NULL},
103 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
104 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
105 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
106 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
107 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
108 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
109 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
111 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
112 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
114 {13, ARMV4_5_MODE_SVC, NULL, NULL},
115 {14, ARMV4_5_MODE_SVC, NULL, NULL},
117 {13, ARMV4_5_MODE_ABT, NULL, NULL},
118 {14, ARMV4_5_MODE_ABT, NULL, NULL},
120 {13, ARMV4_5_MODE_UND, NULL, NULL},
121 {14, ARMV4_5_MODE_UND, NULL, NULL},
123 {16, ARMV4_5_MODE_ANY, NULL, NULL},
124 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
125 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
126 {16, ARMV4_5_MODE_SVC, NULL, NULL},
127 {16, ARMV4_5_MODE_ABT, NULL, NULL},
128 {16, ARMV4_5_MODE_UND, NULL, NULL},
130 {13, ARMV7A_MODE_MON, NULL, NULL},
131 {14, ARMV7A_MODE_MON, NULL, NULL},
132 {16, ARMV7A_MODE_MON, NULL, NULL}
135 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
136 int armv7a_core_reg_map[8][17] =
139 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
142 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
145 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
148 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
151 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
154 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
157 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
160 /* TODO Fix the register mapping for mon, we need r13_mon,
161 * r14_mon and spsr_mon
163 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
167 uint8_t armv7a_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
169 reg_t armv7a_gdb_dummy_fp_reg =
171 "GDB dummy floating-point register", armv7a_gdb_dummy_fp_value,
172 0, 1, 96, NULL, 0, NULL, 0
175 int armv7a_arch_state(struct target_s *target)
177 static const char *state[] =
179 "disabled", "enabled"
182 armv4_5_common_t *armv4_5 = target->arch_info;
183 armv7a_common_t *armv7a = armv4_5->arch_info;
185 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
187 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
191 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
192 "%s: 0x%8.8x pc: 0x%8.8x\n"
193 "MMU: %s, D-Cache: %s, I-Cache: %s",
194 armv7a_state_strings[armv4_5->core_state],
195 Jim_Nvp_value2name_simple(nvp_target_debug_reason,
196 target->debug_reason)->name,
198 armv7a_mode_to_number(armv4_5->core_mode)],
199 armv7a_core_reg_list[armv7a_core_reg_map[
200 armv7a_mode_to_number(armv4_5->core_mode)][16]],
201 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
202 armv4_5->core_mode, 16).value, 0, 32),
203 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
204 state[armv7a->armv4_5_mmu.mmu_enabled],
205 state[armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
206 state[armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
212 static int handle_dap_baseaddr_command(struct command_context_s *cmd_ctx,
213 char *cmd, char **args, int argc)
215 target_t *target = get_current_target(cmd_ctx);
216 armv4_5_common_t *armv4_5 = target->arch_info;
217 armv7a_common_t *armv7a = armv4_5->arch_info;
218 swjdp_common_t *swjdp = &armv7a->swjdp_info;
220 return dap_baseaddr_command(cmd_ctx, swjdp, args, argc);
223 static int handle_dap_memaccess_command(struct command_context_s *cmd_ctx,
224 char *cmd, char **args, int argc)
226 target_t *target = get_current_target(cmd_ctx);
227 armv4_5_common_t *armv4_5 = target->arch_info;
228 armv7a_common_t *armv7a = armv4_5->arch_info;
229 swjdp_common_t *swjdp = &armv7a->swjdp_info;
231 return dap_memaccess_command(cmd_ctx, swjdp, args, argc);
234 static int handle_dap_apsel_command(struct command_context_s *cmd_ctx,
235 char *cmd, char **args, int argc)
237 target_t *target = get_current_target(cmd_ctx);
238 armv4_5_common_t *armv4_5 = target->arch_info;
239 armv7a_common_t *armv7a = armv4_5->arch_info;
240 swjdp_common_t *swjdp = &armv7a->swjdp_info;
242 return dap_apsel_command(cmd_ctx, swjdp, args, argc);
245 static int handle_dap_apid_command(struct command_context_s *cmd_ctx,
246 char *cmd, char **args, int argc)
248 target_t *target = get_current_target(cmd_ctx);
249 armv4_5_common_t *armv4_5 = target->arch_info;
250 armv7a_common_t *armv7a = armv4_5->arch_info;
251 swjdp_common_t *swjdp = &armv7a->swjdp_info;
253 return dap_apid_command(cmd_ctx, swjdp, args, argc);
256 static int handle_dap_info_command(struct command_context_s *cmd_ctx,
257 char *cmd, char **args, int argc)
259 target_t *target = get_current_target(cmd_ctx);
260 armv4_5_common_t *armv4_5 = target->arch_info;
261 armv7a_common_t *armv7a = armv4_5->arch_info;
262 swjdp_common_t *swjdp = &armv7a->swjdp_info;
265 apsel = swjdp->apsel;
267 apsel = strtoul(args[0], NULL, 0);
269 return dap_info_command(cmd_ctx, swjdp, apsel);
272 int armv7a_register_commands(struct command_context_s *cmd_ctx)
274 command_t *arm_adi_v5_dap_cmd;
276 arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap",
278 "cortex dap specific commands");
280 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info",
281 handle_dap_info_command, COMMAND_EXEC,
282 "dap info for ap [num], "
283 "default currently selected AP");
284 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel",
285 handle_dap_apsel_command, COMMAND_EXEC,
286 "select a different AP [num] (default 0)");
287 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid",
288 handle_dap_apid_command, COMMAND_EXEC,
289 "return id reg from AP [num], "
290 "default currently selected AP");
291 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "baseaddr",
292 handle_dap_baseaddr_command, COMMAND_EXEC,
293 "return debug base address from AP [num], "
294 "default currently selected AP");
295 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "memaccess",
296 handle_dap_memaccess_command, COMMAND_EXEC,
297 "set/get number of extra tck for mem-ap memory "
298 "bus access [0-255]");