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"
39 char* armv7a_core_reg_list
[] =
41 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
42 "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
43 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
48 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
49 "r13_mon", "lr_mon", "spsr_mon"
52 char * armv7a_mode_strings_list
[] =
54 "Illegal mode value", "User", "FIQ", "IRQ",
55 "Supervisor", "Abort", "Undefined", "System", "Monitor"
58 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
59 char** armv7a_mode_strings
= armv7a_mode_strings_list
+1;
61 char* armv7a_state_strings
[] =
63 "ARM", "Thumb", "Jazelle", "ThumbEE"
66 struct armv7a_core_reg armv7a_core_reg_list_arch_info
[] =
68 {0, ARMV4_5_MODE_ANY
, NULL
, NULL
},
69 {1, ARMV4_5_MODE_ANY
, NULL
, NULL
},
70 {2, ARMV4_5_MODE_ANY
, NULL
, NULL
},
71 {3, ARMV4_5_MODE_ANY
, NULL
, NULL
},
72 {4, ARMV4_5_MODE_ANY
, NULL
, NULL
},
73 {5, ARMV4_5_MODE_ANY
, NULL
, NULL
},
74 {6, ARMV4_5_MODE_ANY
, NULL
, NULL
},
75 {7, ARMV4_5_MODE_ANY
, NULL
, NULL
},
76 {8, ARMV4_5_MODE_ANY
, NULL
, NULL
},
77 {9, ARMV4_5_MODE_ANY
, NULL
, NULL
},
78 {10, ARMV4_5_MODE_ANY
, NULL
, NULL
},
79 {11, ARMV4_5_MODE_ANY
, NULL
, NULL
},
80 {12, ARMV4_5_MODE_ANY
, NULL
, NULL
},
81 {13, ARMV4_5_MODE_USR
, NULL
, NULL
},
82 {14, ARMV4_5_MODE_USR
, NULL
, NULL
},
83 {15, ARMV4_5_MODE_ANY
, NULL
, NULL
},
85 {8, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
86 {9, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
87 {10, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
88 {11, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
89 {12, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
90 {13, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
91 {14, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
93 {13, ARMV4_5_MODE_IRQ
, NULL
, NULL
},
94 {14, ARMV4_5_MODE_IRQ
, NULL
, NULL
},
96 {13, ARMV4_5_MODE_SVC
, NULL
, NULL
},
97 {14, ARMV4_5_MODE_SVC
, NULL
, NULL
},
99 {13, ARMV4_5_MODE_ABT
, NULL
, NULL
},
100 {14, ARMV4_5_MODE_ABT
, NULL
, NULL
},
102 {13, ARMV4_5_MODE_UND
, NULL
, NULL
},
103 {14, ARMV4_5_MODE_UND
, NULL
, NULL
},
105 {16, ARMV4_5_MODE_ANY
, NULL
, NULL
},
106 {16, ARMV4_5_MODE_FIQ
, NULL
, NULL
},
107 {16, ARMV4_5_MODE_IRQ
, NULL
, NULL
},
108 {16, ARMV4_5_MODE_SVC
, NULL
, NULL
},
109 {16, ARMV4_5_MODE_ABT
, NULL
, NULL
},
110 {16, ARMV4_5_MODE_UND
, NULL
, NULL
},
112 {13, ARMV7A_MODE_MON
, NULL
, NULL
},
113 {14, ARMV7A_MODE_MON
, NULL
, NULL
},
114 {16, ARMV7A_MODE_MON
, NULL
, NULL
}
117 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
118 int armv7a_core_reg_map
[8][17] =
121 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
124 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
127 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
130 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
133 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
136 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
139 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
142 /* TODO Fix the register mapping for mon, we need r13_mon,
143 * r14_mon and spsr_mon
145 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
149 /* FIXME this dummy is IDENTICAL to the armv4_5, arm11, and armv7m
150 * ones... except for naming/scoping
152 uint8_t armv7a_gdb_dummy_fp_value
[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
154 struct reg armv7a_gdb_dummy_fp_reg
=
156 .name
= "GDB dummy floating-point register",
157 .value
= armv7a_gdb_dummy_fp_value
,
165 void armv7a_show_fault_registers(struct target
*target
)
167 uint32_t dfsr
, ifsr
, dfar
, ifar
;
168 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
170 armv7a
->read_cp15(target
, 0, 0, 5, 0, &dfsr
);
171 armv7a
->read_cp15(target
, 0, 1, 5, 0, &ifsr
);
172 armv7a
->read_cp15(target
, 0, 0, 6, 0, &dfar
);
173 armv7a
->read_cp15(target
, 0, 2, 6, 0, &ifar
);
175 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
176 ", DFAR: %8.8" PRIx32
, dfsr
, dfar
);
177 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
178 ", IFAR: %8.8" PRIx32
, ifsr
, ifar
);
182 int armv7a_arch_state(struct target
*target
)
184 static const char *state
[] =
186 "disabled", "enabled"
189 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
190 struct armv4_5_common_s
*armv4_5
= &armv7a
->armv4_5_common
;
192 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
194 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
198 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
199 "%s: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"\n"
200 "MMU: %s, D-Cache: %s, I-Cache: %s",
201 armv7a_state_strings
[armv7a
->core_state
],
202 Jim_Nvp_value2name_simple(nvp_target_debug_reason
,
203 target
->debug_reason
)->name
,
205 armv7a_mode_to_number(armv4_5
->core_mode
)],
206 armv7a_core_reg_list
[armv7a_core_reg_map
[
207 armv7a_mode_to_number(armv4_5
->core_mode
)][16]],
208 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
209 armv4_5
->core_mode
, 16).value
, 0, 32),
210 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
211 state
[armv7a
->armv4_5_mmu
.mmu_enabled
],
212 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
213 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
]);
215 if (armv4_5
->core_mode
== ARMV7A_MODE_ABT
)
216 armv7a_show_fault_registers(target
);
222 COMMAND_HANDLER(handle_dap_baseaddr_command
)
224 struct target
*target
= get_current_target(cmd_ctx
);
225 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
226 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
228 return CALL_COMMAND_HANDLER(dap_baseaddr_command
, swjdp
);
231 COMMAND_HANDLER(handle_dap_memaccess_command
)
233 struct target
*target
= get_current_target(cmd_ctx
);
234 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
235 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
237 return CALL_COMMAND_HANDLER(dap_memaccess_command
, swjdp
);
240 COMMAND_HANDLER(handle_dap_apsel_command
)
242 struct target
*target
= get_current_target(cmd_ctx
);
243 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
244 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
246 return CALL_COMMAND_HANDLER(dap_apsel_command
, swjdp
);
249 COMMAND_HANDLER(handle_dap_apid_command
)
251 struct target
*target
= get_current_target(cmd_ctx
);
252 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
253 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
255 return CALL_COMMAND_HANDLER(dap_apid_command
, swjdp
);
258 COMMAND_HANDLER(handle_dap_info_command
)
260 struct target
*target
= get_current_target(cmd_ctx
);
261 struct armv7a_common
*armv7a
= target_to_armv7a(target
);
262 struct swjdp_common
*swjdp
= &armv7a
->swjdp_info
;
267 apsel
= swjdp
->apsel
;
270 COMMAND_PARSE_NUMBER(u32
, args
[0], apsel
);
273 return ERROR_COMMAND_SYNTAX_ERROR
;
276 return dap_info_command(cmd_ctx
, swjdp
, apsel
);
279 COMMAND_HANDLER(handle_armv7a_disassemble_command
)
281 struct target
*target
= get_current_target(cmd_ctx
);
282 struct armv4_5_common_s
*armv4_5
= target_to_armv4_5(target
);
288 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
) {
289 command_print(cmd_ctx
, "current target isn't an ARM target");
293 /* REVISIT: eventually support ThumbEE disassembly too;
294 * some opcodes work differently.
299 if (strcmp(args
[2], "thumb") != 0)
304 COMMAND_PARSE_NUMBER(int, args
[1], count
);
307 COMMAND_PARSE_NUMBER(u32
, args
[0], address
);
308 if (address
& 0x01) {
310 command_print(cmd_ctx
, "Disassemble as Thumb");
318 command_print(cmd_ctx
,
319 "usage: armv7a disassemble <address> [<count> ['thumb']]");
323 for (i
= 0; i
< count
; i
++) {
324 struct arm_instruction cur_instruction
;
328 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
329 if (retval
!= ERROR_OK
)
332 address
+= cur_instruction
.instruction_size
;
336 retval
= target_read_u32(target
, address
, &opcode
);
337 if (retval
!= ERROR_OK
)
340 retval
= arm_evaluate_opcode(opcode
, address
,
342 if (retval
!= ERROR_OK
)
347 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
353 int armv7a_register_commands(struct command_context
*cmd_ctx
)
355 struct command
*arm_adi_v5_dap_cmd
;
356 struct command
*armv7a_cmd
;
358 arm_adi_v5_dap_cmd
= register_command(cmd_ctx
, NULL
, "dap",
360 "cortex dap specific commands");
362 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "info",
363 handle_dap_info_command
, COMMAND_EXEC
,
364 "dap info for ap [num], "
365 "default currently selected AP");
366 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apsel",
367 handle_dap_apsel_command
, COMMAND_EXEC
,
368 "select a different AP [num] (default 0)");
369 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apid",
370 handle_dap_apid_command
, COMMAND_EXEC
,
371 "return id reg from AP [num], "
372 "default currently selected AP");
373 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "baseaddr",
374 handle_dap_baseaddr_command
, COMMAND_EXEC
,
375 "return debug base address from AP [num], "
376 "default currently selected AP");
377 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "memaccess",
378 handle_dap_memaccess_command
, COMMAND_EXEC
,
379 "set/get number of extra tck for mem-ap memory "
380 "bus access [0-255]");
382 armv7a_cmd
= register_command(cmd_ctx
, NULL
, "armv7a",
384 "ARMv7-A specific commands");
386 register_command(cmd_ctx
, armv7a_cmd
, "disassemble",
387 handle_armv7a_disassemble_command
, COMMAND_EXEC
,
388 "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)