ARM: add arm_mode_name()
[openocd.git] / src / target / armv7a.c
1 /***************************************************************************
2 * Copyright (C) 2009 by David Brownell *
3 * *
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. *
8 * *
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. *
13 * *
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 ***************************************************************************/
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "replacements.h"
24
25 #include "armv7a.h"
26 #include "arm_disassembler.h"
27
28 #include "register.h"
29 #include "binarybuffer.h"
30 #include "command.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <unistd.h>
35
36
37 char* armv7a_core_reg_list[] =
38 {
39 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
40 "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
41 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
42 "r13_irq", "lr_irq",
43 "r13_svc", "lr_svc",
44 "r13_abt", "lr_abt",
45 "r13_und", "lr_und",
46 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
47 "r13_mon", "lr_mon", "spsr_mon"
48 };
49
50 char* armv7a_state_strings[] =
51 {
52 "ARM", "Thumb", "Jazelle", "ThumbEE"
53 };
54
55 struct armv7a_core_reg armv7a_core_reg_list_arch_info[] =
56 {
57 {0, ARMV4_5_MODE_ANY, NULL, NULL},
58 {1, ARMV4_5_MODE_ANY, NULL, NULL},
59 {2, ARMV4_5_MODE_ANY, NULL, NULL},
60 {3, ARMV4_5_MODE_ANY, NULL, NULL},
61 {4, ARMV4_5_MODE_ANY, NULL, NULL},
62 {5, ARMV4_5_MODE_ANY, NULL, NULL},
63 {6, ARMV4_5_MODE_ANY, NULL, NULL},
64 {7, ARMV4_5_MODE_ANY, NULL, NULL},
65 {8, ARMV4_5_MODE_ANY, NULL, NULL},
66 {9, ARMV4_5_MODE_ANY, NULL, NULL},
67 {10, ARMV4_5_MODE_ANY, NULL, NULL},
68 {11, ARMV4_5_MODE_ANY, NULL, NULL},
69 {12, ARMV4_5_MODE_ANY, NULL, NULL},
70 {13, ARMV4_5_MODE_USR, NULL, NULL},
71 {14, ARMV4_5_MODE_USR, NULL, NULL},
72 {15, ARMV4_5_MODE_ANY, NULL, NULL},
73
74 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
75 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
76 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
77 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
78 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
79 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
80 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
81
82 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
83 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
84
85 {13, ARMV4_5_MODE_SVC, NULL, NULL},
86 {14, ARMV4_5_MODE_SVC, NULL, NULL},
87
88 {13, ARMV4_5_MODE_ABT, NULL, NULL},
89 {14, ARMV4_5_MODE_ABT, NULL, NULL},
90
91 {13, ARMV4_5_MODE_UND, NULL, NULL},
92 {14, ARMV4_5_MODE_UND, NULL, NULL},
93
94 {16, ARMV4_5_MODE_ANY, NULL, NULL},
95 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
96 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
97 {16, ARMV4_5_MODE_SVC, NULL, NULL},
98 {16, ARMV4_5_MODE_ABT, NULL, NULL},
99 {16, ARMV4_5_MODE_UND, NULL, NULL},
100
101 {13, ARMV7A_MODE_MON, NULL, NULL},
102 {14, ARMV7A_MODE_MON, NULL, NULL},
103 {16, ARMV7A_MODE_MON, NULL, NULL}
104 };
105
106 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
107 int armv7a_core_reg_map[8][17] =
108 {
109 { /* USR */
110 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
111 },
112 { /* FIQ */
113 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
114 },
115 { /* IRQ */
116 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
117 },
118 { /* SVC */
119 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
120 },
121 { /* ABT */
122 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
123 },
124 { /* UND */
125 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
126 },
127 { /* SYS */
128 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
129 },
130 { /* MON */
131 /* TODO Fix the register mapping for mon, we need r13_mon,
132 * r14_mon and spsr_mon
133 */
134 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
135 }
136 };
137
138 void armv7a_show_fault_registers(struct target *target)
139 {
140 uint32_t dfsr, ifsr, dfar, ifar;
141 struct armv7a_common *armv7a = target_to_armv7a(target);
142
143 armv7a->read_cp15(target, 0, 0, 5, 0, &dfsr);
144 armv7a->read_cp15(target, 0, 1, 5, 0, &ifsr);
145 armv7a->read_cp15(target, 0, 0, 6, 0, &dfar);
146 armv7a->read_cp15(target, 0, 2, 6, 0, &ifar);
147
148 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
149 ", DFAR: %8.8" PRIx32, dfsr, dfar);
150 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
151 ", IFAR: %8.8" PRIx32, ifsr, ifar);
152
153 }
154
155 int armv7a_arch_state(struct target *target)
156 {
157 static const char *state[] =
158 {
159 "disabled", "enabled"
160 };
161
162 struct armv7a_common *armv7a = target_to_armv7a(target);
163 struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
164
165 if (armv7a->common_magic != ARMV7_COMMON_MAGIC)
166 {
167 LOG_ERROR("BUG: called for a non-ARMv7A target");
168 return ERROR_INVALID_ARGUMENTS;
169 }
170
171 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
172 "%s: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
173 "MMU: %s, D-Cache: %s, I-Cache: %s",
174 armv7a_state_strings[armv7a->core_state],
175 Jim_Nvp_value2name_simple(nvp_target_debug_reason,
176 target->debug_reason)->name,
177 arm_mode_name(armv4_5->core_mode),
178 armv7a_core_reg_list[armv7a_core_reg_map[
179 armv7a_mode_to_number(armv4_5->core_mode)][16]],
180 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
181 armv4_5->core_mode, 16).value, 0, 32),
182 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
183 state[armv7a->armv4_5_mmu.mmu_enabled],
184 state[armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
185 state[armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
186
187 if (armv4_5->core_mode == ARMV7A_MODE_ABT)
188 armv7a_show_fault_registers(target);
189
190 return ERROR_OK;
191 }
192
193
194 COMMAND_HANDLER(handle_dap_baseaddr_command)
195 {
196 struct target *target = get_current_target(CMD_CTX);
197 struct armv7a_common *armv7a = target_to_armv7a(target);
198 struct swjdp_common *swjdp = &armv7a->swjdp_info;
199
200 return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp);
201 }
202
203 COMMAND_HANDLER(handle_dap_memaccess_command)
204 {
205 struct target *target = get_current_target(CMD_CTX);
206 struct armv7a_common *armv7a = target_to_armv7a(target);
207 struct swjdp_common *swjdp = &armv7a->swjdp_info;
208
209 return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp);
210 }
211
212 COMMAND_HANDLER(handle_dap_apsel_command)
213 {
214 struct target *target = get_current_target(CMD_CTX);
215 struct armv7a_common *armv7a = target_to_armv7a(target);
216 struct swjdp_common *swjdp = &armv7a->swjdp_info;
217
218 return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp);
219 }
220
221 COMMAND_HANDLER(handle_dap_apid_command)
222 {
223 struct target *target = get_current_target(CMD_CTX);
224 struct armv7a_common *armv7a = target_to_armv7a(target);
225 struct swjdp_common *swjdp = &armv7a->swjdp_info;
226
227 return CALL_COMMAND_HANDLER(dap_apid_command, swjdp);
228 }
229
230 COMMAND_HANDLER(handle_dap_info_command)
231 {
232 struct target *target = get_current_target(CMD_CTX);
233 struct armv7a_common *armv7a = target_to_armv7a(target);
234 struct swjdp_common *swjdp = &armv7a->swjdp_info;
235 uint32_t apsel;
236
237 switch (CMD_ARGC) {
238 case 0:
239 apsel = swjdp->apsel;
240 break;
241 case 1:
242 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
243 break;
244 default:
245 return ERROR_COMMAND_SYNTAX_ERROR;
246 }
247
248 return dap_info_command(CMD_CTX, swjdp, apsel);
249 }
250
251 int armv7a_register_commands(struct command_context *cmd_ctx)
252 {
253 struct command *arm_adi_v5_dap_cmd;
254
255 arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap",
256 NULL, COMMAND_ANY,
257 "cortex dap specific commands");
258
259 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info",
260 handle_dap_info_command, COMMAND_EXEC,
261 "dap info for ap [num], "
262 "default currently selected AP");
263 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel",
264 handle_dap_apsel_command, COMMAND_EXEC,
265 "select a different AP [num] (default 0)");
266 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid",
267 handle_dap_apid_command, COMMAND_EXEC,
268 "return id reg from AP [num], "
269 "default currently selected AP");
270 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "baseaddr",
271 handle_dap_baseaddr_command, COMMAND_EXEC,
272 "return debug base address from AP [num], "
273 "default currently selected AP");
274 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "memaccess",
275 handle_dap_memaccess_command, COMMAND_EXEC,
276 "set/get number of extra tck for mem-ap memory "
277 "bus access [0-255]");
278
279 return ERROR_OK;
280 }

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)