David Brownell Subset of Cortex-A8 support from Magnus: create an armv7a file
[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
27 #include "target.h"
28 #include "register.h"
29 #include "log.h"
30 #include "binarybuffer.h"
31 #include "command.h"
32
33 #include <stdlib.h>
34 #include <string.h>
35 #include <unistd.h>
36
37 bitfield_desc_t armv7a_psr_bitfield_desc[] =
38 {
39 {"M[4:0]", 5},
40 {"T", 1},
41 {"F", 1},
42 {"I", 1},
43 {"A", 1},
44 {"E", 1},
45 {"IT[7:2]", 6},
46 {"GE[3:0]", 4},
47 {"reserved(DNM)", 4},
48 {"J", 1},
49 {"IT[0:1]", 2},
50 {"Q", 1},
51 {"V", 1},
52 {"C", 1},
53 {"Z", 1},
54 {"N", 1},
55 };
56
57 char* armv7a_core_reg_list[] =
58 {
59 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
60 "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc",
61 "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq",
62 "r13_irq", "lr_irq",
63 "r13_svc", "lr_svc",
64 "r13_abt", "lr_abt",
65 "r13_und", "lr_und",
66 "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und",
67 "r13_mon", "lr_mon", "spsr_mon"
68 };
69
70 char * armv7a_mode_strings_list[] =
71 {
72 "Illegal mode value", "System and User", "FIQ", "IRQ",
73 "Supervisor", "Abort", "Undefined", "Monitor"
74 };
75
76 /* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
77 char** armv7a_mode_strings = armv7a_mode_strings_list+1;
78
79 char* armv7a_state_strings[] =
80 {
81 "ARM", "Thumb", "Jazelle", "ThumbEE"
82 };
83
84 armv7a_core_reg_t armv7a_core_reg_list_arch_info[] =
85 {
86 {0, ARMV4_5_MODE_ANY, NULL, NULL},
87 {1, ARMV4_5_MODE_ANY, NULL, NULL},
88 {2, ARMV4_5_MODE_ANY, NULL, NULL},
89 {3, ARMV4_5_MODE_ANY, NULL, NULL},
90 {4, ARMV4_5_MODE_ANY, NULL, NULL},
91 {5, ARMV4_5_MODE_ANY, NULL, NULL},
92 {6, ARMV4_5_MODE_ANY, NULL, NULL},
93 {7, ARMV4_5_MODE_ANY, NULL, NULL},
94 {8, ARMV4_5_MODE_ANY, NULL, NULL},
95 {9, ARMV4_5_MODE_ANY, NULL, NULL},
96 {10, ARMV4_5_MODE_ANY, NULL, NULL},
97 {11, ARMV4_5_MODE_ANY, NULL, NULL},
98 {12, ARMV4_5_MODE_ANY, NULL, NULL},
99 {13, ARMV4_5_MODE_USR, NULL, NULL},
100 {14, ARMV4_5_MODE_USR, NULL, NULL},
101 {15, ARMV4_5_MODE_ANY, NULL, NULL},
102
103 {8, ARMV4_5_MODE_FIQ, NULL, NULL},
104 {9, ARMV4_5_MODE_FIQ, NULL, NULL},
105 {10, ARMV4_5_MODE_FIQ, NULL, NULL},
106 {11, ARMV4_5_MODE_FIQ, NULL, NULL},
107 {12, ARMV4_5_MODE_FIQ, NULL, NULL},
108 {13, ARMV4_5_MODE_FIQ, NULL, NULL},
109 {14, ARMV4_5_MODE_FIQ, NULL, NULL},
110
111 {13, ARMV4_5_MODE_IRQ, NULL, NULL},
112 {14, ARMV4_5_MODE_IRQ, NULL, NULL},
113
114 {13, ARMV4_5_MODE_SVC, NULL, NULL},
115 {14, ARMV4_5_MODE_SVC, NULL, NULL},
116
117 {13, ARMV4_5_MODE_ABT, NULL, NULL},
118 {14, ARMV4_5_MODE_ABT, NULL, NULL},
119
120 {13, ARMV4_5_MODE_UND, NULL, NULL},
121 {14, ARMV4_5_MODE_UND, NULL, NULL},
122
123 {16, ARMV4_5_MODE_ANY, NULL, NULL},
124 {16, ARMV4_5_MODE_FIQ, NULL, NULL},
125 {16, ARMV4_5_MODE_IRQ, NULL, NULL},
126 {16, ARMV4_5_MODE_SVC, NULL, NULL},
127 {16, ARMV4_5_MODE_ABT, NULL, NULL},
128 {16, ARMV4_5_MODE_UND, NULL, NULL},
129
130 {13, ARMV7A_MODE_MON, NULL, NULL},
131 {14, ARMV7A_MODE_MON, NULL, NULL},
132 {16, ARMV7A_MODE_MON, NULL, NULL}
133 };
134
135 /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */
136 int armv7a_core_reg_map[8][17] =
137 {
138 { /* USR */
139 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
140 },
141 { /* FIQ */
142 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
143 },
144 { /* IRQ */
145 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
146 },
147 { /* SVC */
148 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
149 },
150 { /* ABT */
151 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
152 },
153 { /* UND */
154 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
155 },
156 { /* SYS */
157 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
158 },
159 { /* MON */
160 /* TODO Fix the register mapping for mon, we need r13_mon,
161 * r14_mon and spsr_mon
162 */
163 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
164 }
165 };
166
167 uint8_t armv7a_gdb_dummy_fp_value[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
168
169 reg_t armv7a_gdb_dummy_fp_reg =
170 {
171 "GDB dummy floating-point register", armv7a_gdb_dummy_fp_value,
172 0, 1, 96, NULL, 0, NULL, 0
173 };
174
175 int armv7a_arch_state(struct target_s *target)
176 {
177 static const char *state[] =
178 {
179 "disabled", "enabled"
180 };
181
182 armv4_5_common_t *armv4_5 = target->arch_info;
183 armv7a_common_t *armv7a = armv4_5->arch_info;
184
185 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
186 {
187 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
188 exit(-1);
189 }
190
191 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
192 "%s: 0x%8.8x pc: 0x%8.8x\n"
193 "MMU: %s, D-Cache: %s, I-Cache: %s",
194 armv7a_state_strings[armv4_5->core_state],
195 Jim_Nvp_value2name_simple(nvp_target_debug_reason,
196 target->debug_reason)->name,
197 armv7a_mode_strings[
198 armv7a_mode_to_number(armv4_5->core_mode)],
199 armv7a_core_reg_list[armv7a_core_reg_map[
200 armv7a_mode_to_number(armv4_5->core_mode)][16]],
201 buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
202 armv4_5->core_mode, 16).value, 0, 32),
203 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
204 state[armv7a->armv4_5_mmu.mmu_enabled],
205 state[armv7a->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled],
206 state[armv7a->armv4_5_mmu.armv4_5_cache.i_cache_enabled]);
207
208 return ERROR_OK;
209 }
210
211
212 static int handle_dap_baseaddr_command(struct command_context_s *cmd_ctx,
213 char *cmd, char **args, int argc)
214 {
215 target_t *target = get_current_target(cmd_ctx);
216 armv4_5_common_t *armv4_5 = target->arch_info;
217 armv7a_common_t *armv7a = armv4_5->arch_info;
218 swjdp_common_t *swjdp = &armv7a->swjdp_info;
219
220 return dap_baseaddr_command(cmd_ctx, swjdp, args, argc);
221 }
222
223 static int handle_dap_memaccess_command(struct command_context_s *cmd_ctx,
224 char *cmd, char **args, int argc)
225 {
226 target_t *target = get_current_target(cmd_ctx);
227 armv4_5_common_t *armv4_5 = target->arch_info;
228 armv7a_common_t *armv7a = armv4_5->arch_info;
229 swjdp_common_t *swjdp = &armv7a->swjdp_info;
230
231 return dap_memaccess_command(cmd_ctx, swjdp, args, argc);
232 }
233
234 static int handle_dap_apsel_command(struct command_context_s *cmd_ctx,
235 char *cmd, char **args, int argc)
236 {
237 target_t *target = get_current_target(cmd_ctx);
238 armv4_5_common_t *armv4_5 = target->arch_info;
239 armv7a_common_t *armv7a = armv4_5->arch_info;
240 swjdp_common_t *swjdp = &armv7a->swjdp_info;
241
242 return dap_apsel_command(cmd_ctx, swjdp, args, argc);
243 }
244
245 static int handle_dap_apid_command(struct command_context_s *cmd_ctx,
246 char *cmd, char **args, int argc)
247 {
248 target_t *target = get_current_target(cmd_ctx);
249 armv4_5_common_t *armv4_5 = target->arch_info;
250 armv7a_common_t *armv7a = armv4_5->arch_info;
251 swjdp_common_t *swjdp = &armv7a->swjdp_info;
252
253 return dap_apid_command(cmd_ctx, swjdp, args, argc);
254 }
255
256 static int handle_dap_info_command(struct command_context_s *cmd_ctx,
257 char *cmd, char **args, int argc)
258 {
259 target_t *target = get_current_target(cmd_ctx);
260 armv4_5_common_t *armv4_5 = target->arch_info;
261 armv7a_common_t *armv7a = armv4_5->arch_info;
262 swjdp_common_t *swjdp = &armv7a->swjdp_info;
263 uint32_t apsel;
264
265 apsel = swjdp->apsel;
266 if (argc > 0)
267 apsel = strtoul(args[0], NULL, 0);
268
269 return dap_info_command(cmd_ctx, swjdp, apsel);
270 }
271
272 int armv7a_register_commands(struct command_context_s *cmd_ctx)
273 {
274 command_t *arm_adi_v5_dap_cmd;
275
276 arm_adi_v5_dap_cmd = register_command(cmd_ctx, NULL, "dap",
277 NULL, COMMAND_ANY,
278 "cortex dap specific commands");
279
280 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "info",
281 handle_dap_info_command, COMMAND_EXEC,
282 "dap info for ap [num], "
283 "default currently selected AP");
284 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apsel",
285 handle_dap_apsel_command, COMMAND_EXEC,
286 "select a different AP [num] (default 0)");
287 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "apid",
288 handle_dap_apid_command, COMMAND_EXEC,
289 "return id reg from AP [num], "
290 "default currently selected AP");
291 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "baseaddr",
292 handle_dap_baseaddr_command, COMMAND_EXEC,
293 "return debug base address from AP [num], "
294 "default currently selected AP");
295 register_command(cmd_ctx, arm_adi_v5_dap_cmd, "memaccess",
296 handle_dap_memaccess_command, COMMAND_EXEC,
297 "set/get number of extra tck for mem-ap memory "
298 "bus access [0-255]");
299
300 return ERROR_OK;
301 }

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)