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"
26 #include "arm_disassembler.h"
31 #include "binarybuffer.h"
38 bitfield_desc_t armv7a_psr_bitfield_desc
[] =
58 char* armv7a_core_reg_list
[] =
60 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
61 "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
62 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
67 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
68 "r13_mon", "lr_mon", "spsr_mon"
71 char * armv7a_mode_strings_list
[] =
73 "Illegal mode value", "User", "FIQ", "IRQ",
74 "Supervisor", "Abort", "Undefined", "System", "Monitor"
77 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
78 char** armv7a_mode_strings
= armv7a_mode_strings_list
+1;
80 char* armv7a_state_strings
[] =
82 "ARM", "Thumb", "Jazelle", "ThumbEE"
85 armv7a_core_reg_t armv7a_core_reg_list_arch_info
[] =
87 {0, ARMV4_5_MODE_ANY
, NULL
, NULL
},
88 {1, ARMV4_5_MODE_ANY
, NULL
, NULL
},
89 {2, ARMV4_5_MODE_ANY
, NULL
, NULL
},
90 {3, ARMV4_5_MODE_ANY
, NULL
, NULL
},
91 {4, ARMV4_5_MODE_ANY
, NULL
, NULL
},
92 {5, ARMV4_5_MODE_ANY
, NULL
, NULL
},
93 {6, ARMV4_5_MODE_ANY
, NULL
, NULL
},
94 {7, ARMV4_5_MODE_ANY
, NULL
, NULL
},
95 {8, ARMV4_5_MODE_ANY
, NULL
, NULL
},
96 {9, ARMV4_5_MODE_ANY
, NULL
, NULL
},
97 {10, ARMV4_5_MODE_ANY
, NULL
, NULL
},
98 {11, ARMV4_5_MODE_ANY
, NULL
, NULL
},
99 {12, ARMV4_5_MODE_ANY
, NULL
, NULL
},
100 {13, ARMV4_5_MODE_USR
, NULL
, NULL
},
101 {14, ARMV4_5_MODE_USR
, NULL
, NULL
},
102 {15, ARMV4_5_MODE_ANY
, NULL
, NULL
},
104 {8, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
105 {9, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
106 {10, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
107 {11, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
108 {12, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
109 {13, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
110 {14, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
112 {13, ARMV4_5_MODE_IRQ
, NULL
, NULL
},
113 {14, ARMV4_5_MODE_IRQ
, NULL
, NULL
},
115 {13, ARMV4_5_MODE_SVC
, NULL
, NULL
},
116 {14, ARMV4_5_MODE_SVC
, NULL
, NULL
},
118 {13, ARMV4_5_MODE_ABT
, NULL
, NULL
},
119 {14, ARMV4_5_MODE_ABT
, NULL
, NULL
},
121 {13, ARMV4_5_MODE_UND
, NULL
, NULL
},
122 {14, ARMV4_5_MODE_UND
, NULL
, NULL
},
124 {16, ARMV4_5_MODE_ANY
, NULL
, NULL
},
125 {16, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
126 {16, ARMV4_5_MODE_IRQ
, NULL
, NULL
},
127 {16, ARMV4_5_MODE_SVC
, NULL
, NULL
},
128 {16, ARMV4_5_MODE_ABT
, NULL
, NULL
},
129 {16, ARMV4_5_MODE_UND
, NULL
, NULL
},
131 {13, ARMV7A_MODE_MON
, NULL
, NULL
},
132 {14, ARMV7A_MODE_MON
, NULL
, NULL
},
133 {16, ARMV7A_MODE_MON
, NULL
, NULL
}
136 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
137 int armv7a_core_reg_map
[8][17] =
140 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
143 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
146 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
149 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
152 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
155 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
158 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
161 /* TODO Fix the register mapping for mon, we need r13_mon,
162 * r14_mon and spsr_mon
164 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
168 uint8_t armv7a_gdb_dummy_fp_value
[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
170 reg_t armv7a_gdb_dummy_fp_reg
=
172 "GDB dummy floating-point register", armv7a_gdb_dummy_fp_value
,
173 0, 1, 96, NULL
, 0, NULL
, 0
176 void armv7a_show_fault_registers(target_t
*target
)
178 uint32_t dfsr
, ifsr
, dfar
, ifar
;
180 /* get pointers to arch-specific information */
181 armv4_5_common_t
*armv4_5
= target
->arch_info
;
182 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
184 armv7a
->read_cp15(target
, 0, 0, 5, 0, &dfsr
);
185 armv7a
->read_cp15(target
, 0, 1, 5, 0, &ifsr
);
186 armv7a
->read_cp15(target
, 0, 0, 6, 0, &dfar
);
187 armv7a
->read_cp15(target
, 0, 2, 6, 0, &ifar
);
189 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
190 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
191 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
192 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
196 int armv7a_arch_state(struct target_s
*target
)
198 static const char *state
[] =
200 "disabled", "enabled"
203 armv4_5_common_t
*armv4_5
= target
->arch_info
;
204 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
206 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
208 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
212 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
213 "%s: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"\n"
214 "MMU: %s, D-Cache: %s, I-Cache: %s",
215 armv7a_state_strings
[armv7a
->core_state
],
216 Jim_Nvp_value2name_simple(nvp_target_debug_reason
,
217 target
->debug_reason
)->name
,
219 armv7a_mode_to_number(armv4_5
->core_mode
)],
220 armv7a_core_reg_list
[armv7a_core_reg_map
[
221 armv7a_mode_to_number(armv4_5
->core_mode
)][16]],
222 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
223 armv4_5
->core_mode
, 16).value
, 0, 32),
224 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
225 state
[armv7a
->armv4_5_mmu
.mmu_enabled
],
226 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
227 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
]);
229 if (armv4_5
->core_mode
== ARMV7A_MODE_ABT
)
230 armv7a_show_fault_registers(target
);
236 static int handle_dap_baseaddr_command(struct command_context_s
*cmd_ctx
,
237 char *cmd
, char **args
, int argc
)
239 target_t
*target
= get_current_target(cmd_ctx
);
240 armv4_5_common_t
*armv4_5
= target
->arch_info
;
241 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
242 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
244 return dap_baseaddr_command(cmd_ctx
, swjdp
, args
, argc
);
247 static int handle_dap_memaccess_command(struct command_context_s
*cmd_ctx
,
248 char *cmd
, char **args
, int argc
)
250 target_t
*target
= get_current_target(cmd_ctx
);
251 armv4_5_common_t
*armv4_5
= target
->arch_info
;
252 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
253 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
255 return dap_memaccess_command(cmd_ctx
, swjdp
, args
, argc
);
258 static int handle_dap_apsel_command(struct command_context_s
*cmd_ctx
,
259 char *cmd
, char **args
, int argc
)
261 target_t
*target
= get_current_target(cmd_ctx
);
262 armv4_5_common_t
*armv4_5
= target
->arch_info
;
263 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
264 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
266 return dap_apsel_command(cmd_ctx
, swjdp
, args
, argc
);
269 static int handle_dap_apid_command(struct command_context_s
*cmd_ctx
,
270 char *cmd
, char **args
, int argc
)
272 target_t
*target
= get_current_target(cmd_ctx
);
273 armv4_5_common_t
*armv4_5
= target
->arch_info
;
274 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
275 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
277 return dap_apid_command(cmd_ctx
, swjdp
, args
, argc
);
280 static int handle_dap_info_command(struct command_context_s
*cmd_ctx
,
281 char *cmd
, char **args
, int argc
)
283 target_t
*target
= get_current_target(cmd_ctx
);
284 armv4_5_common_t
*armv4_5
= target
->arch_info
;
285 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
286 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
291 apsel
= swjdp
->apsel
;
294 COMMAND_PARSE_NUMBER(u32
, args
[0], apsel
);
297 return ERROR_COMMAND_SYNTAX_ERROR
;
300 return dap_info_command(cmd_ctx
, swjdp
, apsel
);
304 handle_armv7a_disassemble_command(struct command_context_s
*cmd_ctx
,
305 char *cmd
, char **args
, int argc
)
307 target_t
*target
= get_current_target(cmd_ctx
);
308 armv4_5_common_t
*armv4_5
= target
->arch_info
;
314 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
) {
315 command_print(cmd_ctx
, "current target isn't an ARM target");
319 /* REVISIT: eventually support ThumbEE disassembly too;
320 * some opcodes work differently.
325 if (strcmp(args
[2], "thumb") != 0)
330 COMMAND_PARSE_NUMBER(int, args
[1], count
);
333 COMMAND_PARSE_NUMBER(u32
, args
[0], address
);
334 if (address
& 0x01) {
336 command_print(cmd_ctx
, "Disassemble as Thumb");
344 command_print(cmd_ctx
,
345 "usage: armv4_5 disassemble <address> [<count> ['thumb']]");
349 for (i
= 0; i
< count
; i
++) {
350 arm_instruction_t cur_instruction
;
354 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
355 if (retval
!= ERROR_OK
)
358 address
+= cur_instruction
.instruction_size
;
362 retval
= target_read_u32(target
, address
, &opcode
);
363 if (retval
!= ERROR_OK
)
366 retval
= arm_evaluate_opcode(opcode
, address
,
368 if (retval
!= ERROR_OK
)
373 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
379 int armv7a_register_commands(struct command_context_s
*cmd_ctx
)
381 command_t
*arm_adi_v5_dap_cmd
;
382 command_t
*armv7a_cmd
;
384 arm_adi_v5_dap_cmd
= register_command(cmd_ctx
, NULL
, "dap",
386 "cortex dap specific commands");
388 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "info",
389 handle_dap_info_command
, COMMAND_EXEC
,
390 "dap info for ap [num], "
391 "default currently selected AP");
392 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apsel",
393 handle_dap_apsel_command
, COMMAND_EXEC
,
394 "select a different AP [num] (default 0)");
395 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apid",
396 handle_dap_apid_command
, COMMAND_EXEC
,
397 "return id reg from AP [num], "
398 "default currently selected AP");
399 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "baseaddr",
400 handle_dap_baseaddr_command
, COMMAND_EXEC
,
401 "return debug base address from AP [num], "
402 "default currently selected AP");
403 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "memaccess",
404 handle_dap_memaccess_command
, COMMAND_EXEC
,
405 "set/get number of extra tck for mem-ap memory "
406 "bus access [0-255]");
408 armv7a_cmd
= register_command(cmd_ctx
, NULL
, "armv7a",
410 "ARMv7-A specific commands");
412 register_command(cmd_ctx
, armv7a_cmd
, "disassemble",
413 handle_armv7a_disassemble_command
, COMMAND_EXEC
,
414 "disassemble instructions <address> [<count> ['thumb']]");
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)