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 int armv7a_arch_state(struct target_s
*target
)
178 static const char *state
[] =
180 "disabled", "enabled"
183 armv4_5_common_t
*armv4_5
= target
->arch_info
;
184 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
186 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
)
188 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
192 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
193 "%s: 0x%8.8" PRIx32
" pc: 0x%8.8" PRIx32
"\n"
194 "MMU: %s, D-Cache: %s, I-Cache: %s",
195 armv7a_state_strings
[armv7a
->core_state
],
196 Jim_Nvp_value2name_simple(nvp_target_debug_reason
,
197 target
->debug_reason
)->name
,
199 armv7a_mode_to_number(armv4_5
->core_mode
)],
200 armv7a_core_reg_list
[armv7a_core_reg_map
[
201 armv7a_mode_to_number(armv4_5
->core_mode
)][16]],
202 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5
->core_cache
,
203 armv4_5
->core_mode
, 16).value
, 0, 32),
204 buf_get_u32(armv4_5
->core_cache
->reg_list
[15].value
, 0, 32),
205 state
[armv7a
->armv4_5_mmu
.mmu_enabled
],
206 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.d_u_cache_enabled
],
207 state
[armv7a
->armv4_5_mmu
.armv4_5_cache
.i_cache_enabled
]);
213 static int handle_dap_baseaddr_command(struct command_context_s
*cmd_ctx
,
214 char *cmd
, char **args
, int argc
)
216 target_t
*target
= get_current_target(cmd_ctx
);
217 armv4_5_common_t
*armv4_5
= target
->arch_info
;
218 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
219 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
221 return dap_baseaddr_command(cmd_ctx
, swjdp
, args
, argc
);
224 static int handle_dap_memaccess_command(struct command_context_s
*cmd_ctx
,
225 char *cmd
, char **args
, int argc
)
227 target_t
*target
= get_current_target(cmd_ctx
);
228 armv4_5_common_t
*armv4_5
= target
->arch_info
;
229 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
230 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
232 return dap_memaccess_command(cmd_ctx
, swjdp
, args
, argc
);
235 static int handle_dap_apsel_command(struct command_context_s
*cmd_ctx
,
236 char *cmd
, char **args
, int argc
)
238 target_t
*target
= get_current_target(cmd_ctx
);
239 armv4_5_common_t
*armv4_5
= target
->arch_info
;
240 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
241 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
243 return dap_apsel_command(cmd_ctx
, swjdp
, args
, argc
);
246 static int handle_dap_apid_command(struct command_context_s
*cmd_ctx
,
247 char *cmd
, char **args
, int argc
)
249 target_t
*target
= get_current_target(cmd_ctx
);
250 armv4_5_common_t
*armv4_5
= target
->arch_info
;
251 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
252 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
254 return dap_apid_command(cmd_ctx
, swjdp
, args
, argc
);
257 static int handle_dap_info_command(struct command_context_s
*cmd_ctx
,
258 char *cmd
, char **args
, int argc
)
260 target_t
*target
= get_current_target(cmd_ctx
);
261 armv4_5_common_t
*armv4_5
= target
->arch_info
;
262 armv7a_common_t
*armv7a
= armv4_5
->arch_info
;
263 swjdp_common_t
*swjdp
= &armv7a
->swjdp_info
;
266 apsel
= swjdp
->apsel
;
268 apsel
= strtoul(args
[0], NULL
, 0);
270 return dap_info_command(cmd_ctx
, swjdp
, apsel
);
274 handle_armv7a_disassemble_command(struct command_context_s
*cmd_ctx
,
275 char *cmd
, char **args
, int argc
)
277 target_t
*target
= get_current_target(cmd_ctx
);
278 armv4_5_common_t
*armv4_5
= target
->arch_info
;
284 if (armv4_5
->common_magic
!= ARMV4_5_COMMON_MAGIC
) {
285 command_print(cmd_ctx
, "current target isn't an ARM target");
289 /* REVISIT: eventually support ThumbEE disassembly too;
290 * some opcodes work differently.
295 if (strcmp(args
[2], "thumb") != 0)
300 count
= strtoul(args
[1], NULL
, 0);
303 address
= strtoul(args
[0], NULL
, 0);
304 if (address
& 0x01) {
306 command_print(cmd_ctx
, "Disassemble as Thumb");
314 command_print(cmd_ctx
,
315 "usage: armv4_5 disassemble <address> [<count> ['thumb']]");
319 for (i
= 0; i
< count
; i
++) {
320 arm_instruction_t cur_instruction
;
324 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
325 if (retval
!= ERROR_OK
)
328 address
+= cur_instruction
.instruction_size
;
332 retval
= target_read_u32(target
, address
, &opcode
);
333 if (retval
!= ERROR_OK
)
336 retval
= arm_evaluate_opcode(opcode
, address
,
338 if (retval
!= ERROR_OK
)
343 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
349 int armv7a_register_commands(struct command_context_s
*cmd_ctx
)
351 command_t
*arm_adi_v5_dap_cmd
;
352 command_t
*armv7a_cmd
;
354 arm_adi_v5_dap_cmd
= register_command(cmd_ctx
, NULL
, "dap",
356 "cortex dap specific commands");
358 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "info",
359 handle_dap_info_command
, COMMAND_EXEC
,
360 "dap info for ap [num], "
361 "default currently selected AP");
362 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apsel",
363 handle_dap_apsel_command
, COMMAND_EXEC
,
364 "select a different AP [num] (default 0)");
365 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "apid",
366 handle_dap_apid_command
, COMMAND_EXEC
,
367 "return id reg from AP [num], "
368 "default currently selected AP");
369 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "baseaddr",
370 handle_dap_baseaddr_command
, COMMAND_EXEC
,
371 "return debug base address from AP [num], "
372 "default currently selected AP");
373 register_command(cmd_ctx
, arm_adi_v5_dap_cmd
, "memaccess",
374 handle_dap_memaccess_command
, COMMAND_EXEC
,
375 "set/get number of extra tck for mem-ap memory "
376 "bus access [0-255]");
378 armv7a_cmd
= register_command(cmd_ctx
, NULL
, "armv7a",
380 "ARMv7-A specific commands");
382 register_command(cmd_ctx
, armv7a_cmd
, "disassemble",
383 handle_armv7a_disassemble_command
, COMMAND_EXEC
,
384 "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)