ARM: only use one set of dummy FPA registers
[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_mode_strings_list[] =
51 {
52 "Illegal mode value", "User", "FIQ", "IRQ",
53 "Supervisor", "Abort", "Undefined", "System", "Monitor"
54 };
55
56 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
57 char** armv7a_mode_strings = armv7a_mode_strings_list+1;
58
59 char* armv7a_state_strings[] =
60 {
61 "ARM", "Thumb", "Jazelle", "ThumbEE"
62 };
63
64 struct armv7a_core_reg armv7a_core_reg_list_arch_info[] =
65 {
66 {0, ARMV4_5_MODE_ANY, NULL, NULL},
67 {1, ARMV4_5_MODE_ANY, NULL, NULL},
68 {2, ARMV4_5_MODE_ANY, NULL, NULL},
69 {3, ARMV4_5_MODE_ANY, NULL, NULL},
70 {4, ARMV4_5_MODE_ANY, NULL, NULL},
71 {5, ARMV4_5_MODE_ANY, NULL, NULL},
72 {6, ARMV4_5_MODE_ANY, NULL, NULL},
73 {7, ARMV4_5_MODE_ANY, NULL, NULL},
74 {8, ARMV4_5_MODE_ANY, NULL, NULL},
75 {9, ARMV4_5_MODE_ANY, NULL, NULL},
76 {10, ARMV4_5_MODE_ANY, NULL, NULL},
77 {11, ARMV4_5_MODE_ANY, NULL, NULL},
78 {12, ARMV4_5_MODE_ANY, NULL, NULL},
79 {13, ARMV4_5_MODE_USR, NULL, NULL},
80 {14, ARMV4_5_MODE_USR, NULL, NULL},
81 {15, ARMV4_5_MODE_ANY, NULL, NULL},
82
83 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
84 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
85 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
86 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
87 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
88 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
89 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
90
91 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
92 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
93
94 {13, ARMV4_5_MODE_SVC, NULL, NULL},
95 {14, ARMV4_5_MODE_SVC, NULL, NULL},
96
97 {13, ARMV4_5_MODE_ABT, NULL, NULL},
98 {14, ARMV4_5_MODE_ABT, NULL, NULL},
99
100 {13, ARMV4_5_MODE_UND, NULL, NULL},
101 {14, ARMV4_5_MODE_UND, NULL, NULL},
102
103 {16, ARMV4_5_MODE_ANY, NULL, NULL},
104 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
105 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
106 {16, ARMV4_5_MODE_SVC, NULL, NULL},
107 {16, ARMV4_5_MODE_ABT, NULL, NULL},
108 {16, ARMV4_5_MODE_UND, NULL, NULL},
109
110 {13, ARMV7A_MODE_MON, NULL, NULL},
111 {14, ARMV7A_MODE_MON, NULL, NULL},
112 {16, ARMV7A_MODE_MON, NULL, NULL}
113 };
114
115 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
116 int armv7a_core_reg_map[8][17] =
117 {
118 { /* USR */
119 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
120 },
121 { /* FIQ */
122 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
123 },
124 { /* IRQ */
125 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
126 },
127 { /* SVC */
128 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
129 },
130 { /* ABT */
131 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
132 },
133 { /* UND */
134 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
135 },
136 { /* SYS */
137 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
138 },
139 { /* MON */
140 /* TODO Fix the register mapping for mon, we need r13_mon,
141 * r14_mon and spsr_mon
142 */
143 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
144 }
145 };
146
147 void armv7a_show_fault_registers(struct target *target)
148 {
149 uint32_t dfsr, ifsr, dfar, ifar;
150 struct armv7a_common *armv7a = target_to_armv7a(target);
151
152 armv7a->read_cp15(target, 0, 0, 5, 0, &dfsr);
153 armv7a->read_cp15(target, 0, 1, 5, 0, &ifsr);
154 armv7a->read_cp15(target, 0, 0, 6, 0, &dfar);
155 armv7a->read_cp15(target, 0, 2, 6, 0, &ifar);
156
157 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
158 ", DFAR: %8.8" PRIx32, dfsr, dfar);
159 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
160 ", IFAR: %8.8" PRIx32, ifsr, ifar);
161
162 }
163
164 int armv7a_arch_state(struct target *target)
165 {
166 static const char *state[] =
167 {
168 "disabled", "enabled"
169 };
170
171 struct armv7a_common *armv7a = target_to_armv7a(target);
172 struct armv4_5_common_s *armv4_5 = &armv7a->armv4_5_common;
173
174 if (armv7a->common_magic != ARMV7_COMMON_MAGIC)
175 {
176 LOG_ERROR("BUG: called for a non-ARMv7A target");
177 return ERROR_INVALID_ARGUMENTS;
178 }
179
180 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
181 "%s: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "\n"
182 "MMU: %s, D-Cache: %s, I-Cache: %s",
183 armv7a_state_strings[armv7a->core_state],
184 Jim_Nvp_value2name_simple(nvp_target_debug_reason,
185 target->debug_reason)->name,
186 armv7a_mode_strings[
187 armv7a_mode_to_number(armv4_5->core_mode)],
188 armv7a_core_reg_list[armv7a_core_reg_map[
189 armv7a_mode_to_number(armv4_5->core_mode)][16]],
190 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
191 armv4_5->core_mode, 16).value, 0, 32),
192 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
193 state[armv7a->armv4_5_mmu.mmu_enabled],
194 state[armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
195 state[armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
196
197 if (armv4_5->core_mode == ARMV7A_MODE_ABT)
198 armv7a_show_fault_registers(target);
199
200 return ERROR_OK;
201 }
202
203
204 COMMAND_HANDLER(handle_dap_baseaddr_command)
205 {
206 struct target *target = get_current_target(CMD_CTX);
207 struct armv7a_common *armv7a = target_to_armv7a(target);
208 struct swjdp_common *swjdp = &armv7a->swjdp_info;
209
210 return CALL_COMMAND_HANDLER(dap_baseaddr_command, swjdp);
211 }
212
213 COMMAND_HANDLER(handle_dap_memaccess_command)
214 {
215 struct target *target = get_current_target(CMD_CTX);
216 struct armv7a_common *armv7a = target_to_armv7a(target);
217 struct swjdp_common *swjdp = &armv7a->swjdp_info;
218
219 return CALL_COMMAND_HANDLER(dap_memaccess_command, swjdp);
220 }
221
222 COMMAND_HANDLER(handle_dap_apsel_command)
223 {
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;
227
228 return CALL_COMMAND_HANDLER(dap_apsel_command, swjdp);
229 }
230
231 COMMAND_HANDLER(handle_dap_apid_command)
232 {
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;
236
237 return CALL_COMMAND_HANDLER(dap_apid_command, swjdp);
238 }
239
240 COMMAND_HANDLER(handle_dap_info_command)
241 {
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;
245 uint32_t apsel;
246
247 switch (CMD_ARGC) {
248 case 0:
249 apsel = swjdp->apsel;
250 break;
251 case 1:
252 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
253 break;
254 default:
255 return ERROR_COMMAND_SYNTAX_ERROR;
256 }
257
258 return dap_info_command(CMD_CTX, swjdp, apsel);
259 }
260
261 int armv7a_register_commands(struct command_context *cmd_ctx)
262 {
263 struct command *arm_adi_v5_dap_cmd;
264
265 arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap",
266 NULL, COMMAND_ANY,
267 "cortex dap specific commands");
268
269 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info",
270 handle_dap_info_command, COMMAND_EXEC,
271 "dap info for ap [num], "
272 "default currently selected AP");
273 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel",
274 handle_dap_apsel_command, COMMAND_EXEC,
275 "select a different AP [num] (default 0)");
276 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid",
277 handle_dap_apid_command, COMMAND_EXEC,
278 "return id reg from AP [num], "
279 "default currently selected AP");
280 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "baseaddr",
281 handle_dap_baseaddr_command, COMMAND_EXEC,
282 "return debug base address from AP [num], "
283 "default currently selected AP");
284 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "memaccess",
285 handle_dap_memaccess_command, COMMAND_EXEC,
286 "set/get number of extra tck for mem-ap memory "
287 "bus access [0-255]");
288
289 return ERROR_OK;
290 }

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)