target, flash: prepare infrastructure for multi-block blank check
[openocd.git] / src / target / armv4_5.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2008 by Oyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
23 ***************************************************************************/
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "arm.h"
30 #include "armv4_5.h"
31 #include "arm_jtag.h"
32 #include "breakpoints.h"
33 #include "arm_disassembler.h"
34 #include <helper/binarybuffer.h>
35 #include "algorithm.h"
36 #include "register.h"
37
38 /* offsets into armv4_5 core register cache */
39 enum {
40 /* ARMV4_5_CPSR = 31, */
41 ARMV4_5_SPSR_FIQ = 32,
42 ARMV4_5_SPSR_IRQ = 33,
43 ARMV4_5_SPSR_SVC = 34,
44 ARMV4_5_SPSR_ABT = 35,
45 ARMV4_5_SPSR_UND = 36,
46 ARM_SPSR_MON = 41,
47 };
48
49 static const uint8_t arm_usr_indices[17] = {
50 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR,
51 };
52
53 static const uint8_t arm_fiq_indices[8] = {
54 16, 17, 18, 19, 20, 21, 22, ARMV4_5_SPSR_FIQ,
55 };
56
57 static const uint8_t arm_irq_indices[3] = {
58 23, 24, ARMV4_5_SPSR_IRQ,
59 };
60
61 static const uint8_t arm_svc_indices[3] = {
62 25, 26, ARMV4_5_SPSR_SVC,
63 };
64
65 static const uint8_t arm_abt_indices[3] = {
66 27, 28, ARMV4_5_SPSR_ABT,
67 };
68
69 static const uint8_t arm_und_indices[3] = {
70 29, 30, ARMV4_5_SPSR_UND,
71 };
72
73 static const uint8_t arm_mon_indices[3] = {
74 39, 40, ARM_SPSR_MON,
75 };
76
77 static const struct {
78 const char *name;
79 unsigned short psr;
80 /* For user and system modes, these list indices for all registers.
81 * otherwise they're just indices for the shadow registers and SPSR.
82 */
83 unsigned short n_indices;
84 const uint8_t *indices;
85 } arm_mode_data[] = {
86 /* Seven modes are standard from ARM7 on. "System" and "User" share
87 * the same registers; other modes shadow from 3 to 8 registers.
88 */
89 {
90 .name = "User",
91 .psr = ARM_MODE_USR,
92 .n_indices = ARRAY_SIZE(arm_usr_indices),
93 .indices = arm_usr_indices,
94 },
95 {
96 .name = "FIQ",
97 .psr = ARM_MODE_FIQ,
98 .n_indices = ARRAY_SIZE(arm_fiq_indices),
99 .indices = arm_fiq_indices,
100 },
101 {
102 .name = "Supervisor",
103 .psr = ARM_MODE_SVC,
104 .n_indices = ARRAY_SIZE(arm_svc_indices),
105 .indices = arm_svc_indices,
106 },
107 {
108 .name = "Abort",
109 .psr = ARM_MODE_ABT,
110 .n_indices = ARRAY_SIZE(arm_abt_indices),
111 .indices = arm_abt_indices,
112 },
113 {
114 .name = "IRQ",
115 .psr = ARM_MODE_IRQ,
116 .n_indices = ARRAY_SIZE(arm_irq_indices),
117 .indices = arm_irq_indices,
118 },
119 {
120 .name = "Undefined instruction",
121 .psr = ARM_MODE_UND,
122 .n_indices = ARRAY_SIZE(arm_und_indices),
123 .indices = arm_und_indices,
124 },
125 {
126 .name = "System",
127 .psr = ARM_MODE_SYS,
128 .n_indices = ARRAY_SIZE(arm_usr_indices),
129 .indices = arm_usr_indices,
130 },
131 /* TrustZone "Security Extensions" add a secure monitor mode.
132 * This is distinct from a "debug monitor" which can support
133 * non-halting debug, in conjunction with some debuggers.
134 */
135 {
136 .name = "Secure Monitor",
137 .psr = ARM_MODE_MON,
138 .n_indices = ARRAY_SIZE(arm_mon_indices),
139 .indices = arm_mon_indices,
140 },
141 {
142 .name = "Secure Monitor ARM1176JZF-S",
143 .psr = ARM_MODE_1176_MON,
144 .n_indices = ARRAY_SIZE(arm_mon_indices),
145 .indices = arm_mon_indices,
146 },
147
148 /* These special modes are currently only supported
149 * by ARMv6M and ARMv7M profiles */
150 {
151 .name = "Thread",
152 .psr = ARM_MODE_THREAD,
153 },
154 {
155 .name = "Thread (User)",
156 .psr = ARM_MODE_USER_THREAD,
157 },
158 {
159 .name = "Handler",
160 .psr = ARM_MODE_HANDLER,
161 },
162 };
163
164 /** Map PSR mode bits to the name of an ARM processor operating mode. */
165 const char *arm_mode_name(unsigned psr_mode)
166 {
167 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
168 if (arm_mode_data[i].psr == psr_mode)
169 return arm_mode_data[i].name;
170 }
171 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
172 return "UNRECOGNIZED";
173 }
174
175 /** Return true iff the parameter denotes a valid ARM processor mode. */
176 bool is_arm_mode(unsigned psr_mode)
177 {
178 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
179 if (arm_mode_data[i].psr == psr_mode)
180 return true;
181 }
182 return false;
183 }
184
185 /** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */
186 int arm_mode_to_number(enum arm_mode mode)
187 {
188 switch (mode) {
189 case ARM_MODE_ANY:
190 /* map MODE_ANY to user mode */
191 case ARM_MODE_USR:
192 return 0;
193 case ARM_MODE_FIQ:
194 return 1;
195 case ARM_MODE_IRQ:
196 return 2;
197 case ARM_MODE_SVC:
198 return 3;
199 case ARM_MODE_ABT:
200 return 4;
201 case ARM_MODE_UND:
202 return 5;
203 case ARM_MODE_SYS:
204 return 6;
205 case ARM_MODE_MON:
206 case ARM_MODE_1176_MON:
207 return 7;
208 default:
209 LOG_ERROR("invalid mode value encountered %d", mode);
210 return -1;
211 }
212 }
213
214 /** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */
215 enum arm_mode armv4_5_number_to_mode(int number)
216 {
217 switch (number) {
218 case 0:
219 return ARM_MODE_USR;
220 case 1:
221 return ARM_MODE_FIQ;
222 case 2:
223 return ARM_MODE_IRQ;
224 case 3:
225 return ARM_MODE_SVC;
226 case 4:
227 return ARM_MODE_ABT;
228 case 5:
229 return ARM_MODE_UND;
230 case 6:
231 return ARM_MODE_SYS;
232 case 7:
233 return ARM_MODE_MON;
234 default:
235 LOG_ERROR("mode index out of bounds %d", number);
236 return ARM_MODE_ANY;
237 }
238 }
239
240 static const char *arm_state_strings[] = {
241 "ARM", "Thumb", "Jazelle", "ThumbEE",
242 };
243
244 /* Templates for ARM core registers.
245 *
246 * NOTE: offsets in this table are coupled to the arm_mode_data
247 * table above, the armv4_5_core_reg_map array below, and also to
248 * the ARMV4_5_CPSR symbol (which should vanish after ARM11 updates).
249 */
250 static const struct {
251 /* The name is used for e.g. the "regs" command. */
252 const char *name;
253
254 /* The {cookie, mode} tuple uniquely identifies one register.
255 * In a given mode, cookies 0..15 map to registers R0..R15,
256 * with R13..R15 usually called SP, LR, PC.
257 *
258 * MODE_ANY is used as *input* to the mapping, and indicates
259 * various special cases (sigh) and errors.
260 *
261 * Cookie 16 is (currently) confusing, since it indicates
262 * CPSR -or- SPSR depending on whether 'mode' is MODE_ANY.
263 * (Exception modes have both CPSR and SPSR registers ...)
264 */
265 unsigned cookie;
266 unsigned gdb_index;
267 enum arm_mode mode;
268 } arm_core_regs[] = {
269 /* IMPORTANT: we guarantee that the first eight cached registers
270 * correspond to r0..r7, and the fifteenth to PC, so that callers
271 * don't need to map them.
272 */
273 { .name = "r0", .cookie = 0, .mode = ARM_MODE_ANY, .gdb_index = 0, },
274 { .name = "r1", .cookie = 1, .mode = ARM_MODE_ANY, .gdb_index = 1, },
275 { .name = "r2", .cookie = 2, .mode = ARM_MODE_ANY, .gdb_index = 2, },
276 { .name = "r3", .cookie = 3, .mode = ARM_MODE_ANY, .gdb_index = 3, },
277 { .name = "r4", .cookie = 4, .mode = ARM_MODE_ANY, .gdb_index = 4, },
278 { .name = "r5", .cookie = 5, .mode = ARM_MODE_ANY, .gdb_index = 5, },
279 { .name = "r6", .cookie = 6, .mode = ARM_MODE_ANY, .gdb_index = 6, },
280 { .name = "r7", .cookie = 7, .mode = ARM_MODE_ANY, .gdb_index = 7, },
281
282 /* NOTE: regs 8..12 might be shadowed by FIQ ... flagging
283 * them as MODE_ANY creates special cases. (ANY means
284 * "not mapped" elsewhere; here it's "everything but FIQ".)
285 */
286 { .name = "r8", .cookie = 8, .mode = ARM_MODE_ANY, .gdb_index = 8, },
287 { .name = "r9", .cookie = 9, .mode = ARM_MODE_ANY, .gdb_index = 9, },
288 { .name = "r10", .cookie = 10, .mode = ARM_MODE_ANY, .gdb_index = 10, },
289 { .name = "r11", .cookie = 11, .mode = ARM_MODE_ANY, .gdb_index = 11, },
290 { .name = "r12", .cookie = 12, .mode = ARM_MODE_ANY, .gdb_index = 12, },
291
292 /* Historical GDB mapping of indices:
293 * - 13-14 are sp and lr, but banked counterparts are used
294 * - 16-24 are left for deprecated 8 FPA + 1 FPS
295 * - 25 is the cpsr
296 */
297
298 /* NOTE all MODE_USR registers are equivalent to MODE_SYS ones */
299 { .name = "sp_usr", .cookie = 13, .mode = ARM_MODE_USR, .gdb_index = 26, },
300 { .name = "lr_usr", .cookie = 14, .mode = ARM_MODE_USR, .gdb_index = 27, },
301
302 /* guaranteed to be at index 15 */
303 { .name = "pc", .cookie = 15, .mode = ARM_MODE_ANY, .gdb_index = 15, },
304 { .name = "r8_fiq", .cookie = 8, .mode = ARM_MODE_FIQ, .gdb_index = 28, },
305 { .name = "r9_fiq", .cookie = 9, .mode = ARM_MODE_FIQ, .gdb_index = 29, },
306 { .name = "r10_fiq", .cookie = 10, .mode = ARM_MODE_FIQ, .gdb_index = 30, },
307 { .name = "r11_fiq", .cookie = 11, .mode = ARM_MODE_FIQ, .gdb_index = 31, },
308 { .name = "r12_fiq", .cookie = 12, .mode = ARM_MODE_FIQ, .gdb_index = 32, },
309
310 { .name = "sp_fiq", .cookie = 13, .mode = ARM_MODE_FIQ, .gdb_index = 33, },
311 { .name = "lr_fiq", .cookie = 14, .mode = ARM_MODE_FIQ, .gdb_index = 34, },
312
313 { .name = "sp_irq", .cookie = 13, .mode = ARM_MODE_IRQ, .gdb_index = 35, },
314 { .name = "lr_irq", .cookie = 14, .mode = ARM_MODE_IRQ, .gdb_index = 36, },
315
316 { .name = "sp_svc", .cookie = 13, .mode = ARM_MODE_SVC, .gdb_index = 37, },
317 { .name = "lr_svc", .cookie = 14, .mode = ARM_MODE_SVC, .gdb_index = 38, },
318
319 { .name = "sp_abt", .cookie = 13, .mode = ARM_MODE_ABT, .gdb_index = 39, },
320 { .name = "lr_abt", .cookie = 14, .mode = ARM_MODE_ABT, .gdb_index = 40, },
321
322 { .name = "sp_und", .cookie = 13, .mode = ARM_MODE_UND, .gdb_index = 41, },
323 { .name = "lr_und", .cookie = 14, .mode = ARM_MODE_UND, .gdb_index = 42, },
324
325 { .name = "cpsr", .cookie = 16, .mode = ARM_MODE_ANY, .gdb_index = 25, },
326 { .name = "spsr_fiq", .cookie = 16, .mode = ARM_MODE_FIQ, .gdb_index = 43, },
327 { .name = "spsr_irq", .cookie = 16, .mode = ARM_MODE_IRQ, .gdb_index = 44, },
328 { .name = "spsr_svc", .cookie = 16, .mode = ARM_MODE_SVC, .gdb_index = 45, },
329 { .name = "spsr_abt", .cookie = 16, .mode = ARM_MODE_ABT, .gdb_index = 46, },
330 { .name = "spsr_und", .cookie = 16, .mode = ARM_MODE_UND, .gdb_index = 47, },
331
332 /* These are only used for GDB target description, banked registers are accessed instead */
333 { .name = "sp", .cookie = 13, .mode = ARM_MODE_ANY, .gdb_index = 13, },
334 { .name = "lr", .cookie = 14, .mode = ARM_MODE_ANY, .gdb_index = 14, },
335
336 /* These exist only when the Security Extension (TrustZone) is present */
337 { .name = "sp_mon", .cookie = 13, .mode = ARM_MODE_MON, .gdb_index = 48, },
338 { .name = "lr_mon", .cookie = 14, .mode = ARM_MODE_MON, .gdb_index = 49, },
339 { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, .gdb_index = 50, },
340
341 };
342
343 static const struct {
344 unsigned int id;
345 const char *name;
346 uint32_t bits;
347 enum arm_mode mode;
348 enum reg_type type;
349 const char *group;
350 const char *feature;
351 } arm_vfp_v3_regs[] = {
352 { ARM_VFP_V3_D0, "d0", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
353 { ARM_VFP_V3_D1, "d1", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
354 { ARM_VFP_V3_D2, "d2", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
355 { ARM_VFP_V3_D3, "d3", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
356 { ARM_VFP_V3_D4, "d4", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
357 { ARM_VFP_V3_D5, "d5", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
358 { ARM_VFP_V3_D6, "d6", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
359 { ARM_VFP_V3_D7, "d7", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
360 { ARM_VFP_V3_D8, "d8", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
361 { ARM_VFP_V3_D9, "d9", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
362 { ARM_VFP_V3_D10, "d10", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
363 { ARM_VFP_V3_D11, "d11", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
364 { ARM_VFP_V3_D12, "d12", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
365 { ARM_VFP_V3_D13, "d13", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
366 { ARM_VFP_V3_D14, "d14", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
367 { ARM_VFP_V3_D15, "d15", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
368 { ARM_VFP_V3_D16, "d16", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
369 { ARM_VFP_V3_D17, "d17", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
370 { ARM_VFP_V3_D18, "d18", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
371 { ARM_VFP_V3_D19, "d19", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
372 { ARM_VFP_V3_D20, "d20", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
373 { ARM_VFP_V3_D21, "d21", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
374 { ARM_VFP_V3_D22, "d22", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
375 { ARM_VFP_V3_D23, "d23", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
376 { ARM_VFP_V3_D24, "d24", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
377 { ARM_VFP_V3_D25, "d25", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
378 { ARM_VFP_V3_D26, "d26", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
379 { ARM_VFP_V3_D27, "d27", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
380 { ARM_VFP_V3_D28, "d28", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
381 { ARM_VFP_V3_D29, "d29", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
382 { ARM_VFP_V3_D30, "d30", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
383 { ARM_VFP_V3_D31, "d31", 64, ARM_MODE_ANY, REG_TYPE_IEEE_DOUBLE, NULL, "org.gnu.gdb.arm.vfp"},
384 { ARM_VFP_V3_FPSCR, "fpscr", 32, ARM_MODE_ANY, REG_TYPE_INT, "float", "org.gnu.gdb.arm.vfp"},
385 };
386
387 /* map core mode (USR, FIQ, ...) and register number to
388 * indices into the register cache
389 */
390 const int armv4_5_core_reg_map[8][17] = {
391 { /* USR */
392 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
393 },
394 { /* FIQ (8 shadows of USR, vs normal 3) */
395 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
396 },
397 { /* IRQ */
398 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
399 },
400 { /* SVC */
401 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
402 },
403 { /* ABT */
404 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
405 },
406 { /* UND */
407 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
408 },
409 { /* SYS (same registers as USR) */
410 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
411 },
412 { /* MON */
413 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39,
414 }
415 };
416
417 /**
418 * Configures host-side ARM records to reflect the specified CPSR.
419 * Later, code can use arm_reg_current() to map register numbers
420 * according to how they are exposed by this mode.
421 */
422 void arm_set_cpsr(struct arm *arm, uint32_t cpsr)
423 {
424 enum arm_mode mode = cpsr & 0x1f;
425 int num;
426
427 /* NOTE: this may be called very early, before the register
428 * cache is set up. We can't defend against many errors, in
429 * particular against CPSRs that aren't valid *here* ...
430 */
431 if (arm->cpsr) {
432 buf_set_u32(arm->cpsr->value, 0, 32, cpsr);
433 arm->cpsr->valid = 1;
434 arm->cpsr->dirty = 0;
435 }
436
437 arm->core_mode = mode;
438
439 /* mode_to_number() warned; set up a somewhat-sane mapping */
440 num = arm_mode_to_number(mode);
441 if (num < 0) {
442 mode = ARM_MODE_USR;
443 num = 0;
444 }
445
446 arm->map = &armv4_5_core_reg_map[num][0];
447 arm->spsr = (mode == ARM_MODE_USR || mode == ARM_MODE_SYS)
448 ? NULL
449 : arm->core_cache->reg_list + arm->map[16];
450
451 /* Older ARMs won't have the J bit */
452 enum arm_state state;
453
454 if (cpsr & (1 << 5)) { /* T */
455 if (cpsr & (1 << 24)) { /* J */
456 LOG_WARNING("ThumbEE -- incomplete support");
457 state = ARM_STATE_THUMB_EE;
458 } else
459 state = ARM_STATE_THUMB;
460 } else {
461 if (cpsr & (1 << 24)) { /* J */
462 LOG_ERROR("Jazelle state handling is BROKEN!");
463 state = ARM_STATE_JAZELLE;
464 } else
465 state = ARM_STATE_ARM;
466 }
467 arm->core_state = state;
468
469 LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
470 arm_mode_name(mode),
471 arm_state_strings[arm->core_state]);
472 }
473
474 /**
475 * Returns handle to the register currently mapped to a given number.
476 * Someone must have called arm_set_cpsr() before.
477 *
478 * \param arm This core's state and registers are used.
479 * \param regnum From 0..15 corresponding to R0..R14 and PC.
480 * Note that R0..R7 don't require mapping; you may access those
481 * as the first eight entries in the register cache. Likewise
482 * R15 (PC) doesn't need mapping; you may also access it directly.
483 * However, R8..R14, and SPSR (arm->spsr) *must* be mapped.
484 * CPSR (arm->cpsr) is also not mapped.
485 */
486 struct reg *arm_reg_current(struct arm *arm, unsigned regnum)
487 {
488 struct reg *r;
489
490 if (regnum > 16)
491 return NULL;
492
493 if (!arm->map) {
494 LOG_ERROR("Register map is not available yet, the target is not fully initialised");
495 r = arm->core_cache->reg_list + regnum;
496 } else
497 r = arm->core_cache->reg_list + arm->map[regnum];
498
499 /* e.g. invalid CPSR said "secure monitor" mode on a core
500 * that doesn't support it...
501 */
502 if (!r) {
503 LOG_ERROR("Invalid CPSR mode");
504 r = arm->core_cache->reg_list + regnum;
505 }
506
507 return r;
508 }
509
510 static const uint8_t arm_gdb_dummy_fp_value[12];
511
512 static struct reg_feature arm_gdb_dummy_fp_features = {
513 .name = "net.sourceforge.openocd.fake_fpa"
514 };
515
516 /**
517 * Dummy FPA registers are required to support GDB on ARM.
518 * Register packets require eight obsolete FPA register values.
519 * Modern ARM cores use Vector Floating Point (VFP), if they
520 * have any floating point support. VFP is not FPA-compatible.
521 */
522 struct reg arm_gdb_dummy_fp_reg = {
523 .name = "GDB dummy FPA register",
524 .value = (uint8_t *) arm_gdb_dummy_fp_value,
525 .valid = 1,
526 .size = 96,
527 .exist = false,
528 .number = 16,
529 .feature = &arm_gdb_dummy_fp_features,
530 .group = "fake_fpa",
531 };
532
533 static const uint8_t arm_gdb_dummy_fps_value[4];
534
535 /**
536 * Dummy FPA status registers are required to support GDB on ARM.
537 * Register packets require an obsolete FPA status register.
538 */
539 struct reg arm_gdb_dummy_fps_reg = {
540 .name = "GDB dummy FPA status register",
541 .value = (uint8_t *) arm_gdb_dummy_fps_value,
542 .valid = 1,
543 .size = 32,
544 .exist = false,
545 .number = 24,
546 .feature = &arm_gdb_dummy_fp_features,
547 .group = "fake_fpa",
548 };
549
550 static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
551
552 static void arm_gdb_dummy_init(void)
553 {
554 register_init_dummy(&arm_gdb_dummy_fp_reg);
555 register_init_dummy(&arm_gdb_dummy_fps_reg);
556 }
557
558 static int armv4_5_get_core_reg(struct reg *reg)
559 {
560 int retval;
561 struct arm_reg *reg_arch_info = reg->arch_info;
562 struct target *target = reg_arch_info->target;
563
564 if (target->state != TARGET_HALTED) {
565 LOG_ERROR("Target not halted");
566 return ERROR_TARGET_NOT_HALTED;
567 }
568
569 retval = reg_arch_info->arm->read_core_reg(target, reg,
570 reg_arch_info->num, reg_arch_info->mode);
571 if (retval == ERROR_OK) {
572 reg->valid = 1;
573 reg->dirty = 0;
574 }
575
576 return retval;
577 }
578
579 static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
580 {
581 struct arm_reg *reg_arch_info = reg->arch_info;
582 struct target *target = reg_arch_info->target;
583 struct arm *armv4_5_target = target_to_arm(target);
584 uint32_t value = buf_get_u32(buf, 0, 32);
585
586 if (target->state != TARGET_HALTED) {
587 LOG_ERROR("Target not halted");
588 return ERROR_TARGET_NOT_HALTED;
589 }
590
591 /* Except for CPSR, the "reg" command exposes a writeback model
592 * for the register cache.
593 */
594 if (reg == armv4_5_target->cpsr) {
595 arm_set_cpsr(armv4_5_target, value);
596
597 /* Older cores need help to be in ARM mode during halt
598 * mode debug, so we clear the J and T bits if we flush.
599 * For newer cores (v6/v7a/v7r) we don't need that, but
600 * it won't hurt since CPSR is always flushed anyway.
601 */
602 if (armv4_5_target->core_mode !=
603 (enum arm_mode)(value & 0x1f)) {
604 LOG_DEBUG("changing ARM core mode to '%s'",
605 arm_mode_name(value & 0x1f));
606 value &= ~((1 << 24) | (1 << 5));
607 uint8_t t[4];
608 buf_set_u32(t, 0, 32, value);
609 armv4_5_target->write_core_reg(target, reg,
610 16, ARM_MODE_ANY, t);
611 }
612 } else {
613 buf_set_u32(reg->value, 0, 32, value);
614 if (reg->size == 64) {
615 value = buf_get_u32(buf + 4, 0, 32);
616 buf_set_u32(reg->value + 4, 0, 32, value);
617 }
618 reg->valid = 1;
619 }
620 reg->dirty = 1;
621
622 return ERROR_OK;
623 }
624
625 static const struct reg_arch_type arm_reg_type = {
626 .get = armv4_5_get_core_reg,
627 .set = armv4_5_set_core_reg,
628 };
629
630 struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
631 {
632 int num_regs = ARRAY_SIZE(arm_core_regs);
633 int num_core_regs = num_regs;
634 if (arm->arm_vfp_version == ARM_VFP_V3)
635 num_regs += ARRAY_SIZE(arm_vfp_v3_regs);
636
637 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
638 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
639 struct arm_reg *reg_arch_info = calloc(num_regs, sizeof(struct arm_reg));
640 int i;
641
642 if (!cache || !reg_list || !reg_arch_info) {
643 free(cache);
644 free(reg_list);
645 free(reg_arch_info);
646 return NULL;
647 }
648
649 cache->name = "ARM registers";
650 cache->next = NULL;
651 cache->reg_list = reg_list;
652 cache->num_regs = 0;
653
654 for (i = 0; i < num_core_regs; i++) {
655 /* Skip registers this core doesn't expose */
656 if (arm_core_regs[i].mode == ARM_MODE_MON
657 && arm->core_type != ARM_MODE_MON)
658 continue;
659
660 /* REVISIT handle Cortex-M, which only shadows R13/SP */
661
662 reg_arch_info[i].num = arm_core_regs[i].cookie;
663 reg_arch_info[i].mode = arm_core_regs[i].mode;
664 reg_arch_info[i].target = target;
665 reg_arch_info[i].arm = arm;
666
667 reg_list[i].name = arm_core_regs[i].name;
668 reg_list[i].number = arm_core_regs[i].gdb_index;
669 reg_list[i].size = 32;
670 reg_list[i].value = reg_arch_info[i].value;
671 reg_list[i].type = &arm_reg_type;
672 reg_list[i].arch_info = &reg_arch_info[i];
673 reg_list[i].exist = true;
674
675 /* This really depends on the calling convention in use */
676 reg_list[i].caller_save = false;
677
678 /* Registers data type, as used by GDB target description */
679 reg_list[i].reg_data_type = malloc(sizeof(struct reg_data_type));
680 switch (arm_core_regs[i].cookie) {
681 case 13:
682 reg_list[i].reg_data_type->type = REG_TYPE_DATA_PTR;
683 break;
684 case 14:
685 case 15:
686 reg_list[i].reg_data_type->type = REG_TYPE_CODE_PTR;
687 break;
688 default:
689 reg_list[i].reg_data_type->type = REG_TYPE_UINT32;
690 break;
691 }
692
693 /* let GDB shows banked registers only in "info all-reg" */
694 reg_list[i].feature = malloc(sizeof(struct reg_feature));
695 if (reg_list[i].number <= 15 || reg_list[i].number == 25) {
696 reg_list[i].feature->name = "org.gnu.gdb.arm.core";
697 reg_list[i].group = "general";
698 } else {
699 reg_list[i].feature->name = "net.sourceforge.openocd.banked";
700 reg_list[i].group = "banked";
701 }
702
703 cache->num_regs++;
704 }
705
706 int j;
707 for (i = num_core_regs, j = 0; i < num_regs; i++, j++) {
708 reg_arch_info[i].num = arm_vfp_v3_regs[j].id;
709 reg_arch_info[i].mode = arm_vfp_v3_regs[j].mode;
710 reg_arch_info[i].target = target;
711 reg_arch_info[i].arm = arm;
712
713 reg_list[i].name = arm_vfp_v3_regs[j].name;
714 reg_list[i].number = arm_vfp_v3_regs[j].id;
715 reg_list[i].size = arm_vfp_v3_regs[j].bits;
716 reg_list[i].value = reg_arch_info[i].value;
717 reg_list[i].type = &arm_reg_type;
718 reg_list[i].arch_info = &reg_arch_info[i];
719 reg_list[i].exist = true;
720
721 reg_list[i].caller_save = false;
722
723 reg_list[i].reg_data_type = malloc(sizeof(struct reg_data_type));
724 reg_list[i].reg_data_type->type = arm_vfp_v3_regs[j].type;
725
726 reg_list[i].feature = malloc(sizeof(struct reg_feature));
727 reg_list[i].feature->name = arm_vfp_v3_regs[j].feature;
728
729 reg_list[i].group = arm_vfp_v3_regs[j].group;
730
731 cache->num_regs++;
732 }
733
734 arm->pc = reg_list + 15;
735 arm->cpsr = reg_list + ARMV4_5_CPSR;
736 arm->core_cache = cache;
737
738 return cache;
739 }
740
741 int arm_arch_state(struct target *target)
742 {
743 struct arm *arm = target_to_arm(target);
744
745 if (arm->common_magic != ARM_COMMON_MAGIC) {
746 LOG_ERROR("BUG: called for a non-ARM target");
747 return ERROR_FAIL;
748 }
749
750 /* avoid filling log waiting for fileio reply */
751 if (arm->semihosting_hit_fileio)
752 return ERROR_OK;
753
754 LOG_USER("target halted in %s state due to %s, current mode: %s\n"
755 "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s%s",
756 arm_state_strings[arm->core_state],
757 debug_reason_name(target),
758 arm_mode_name(arm->core_mode),
759 buf_get_u32(arm->cpsr->value, 0, 32),
760 buf_get_u32(arm->pc->value, 0, 32),
761 arm->is_semihosting ? ", semihosting" : "",
762 arm->is_semihosting_fileio ? " fileio" : "");
763
764 return ERROR_OK;
765 }
766
767 #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
768 (cache->reg_list[armv4_5_core_reg_map[mode][num]])
769
770 COMMAND_HANDLER(handle_armv4_5_reg_command)
771 {
772 struct target *target = get_current_target(CMD_CTX);
773 struct arm *arm = target_to_arm(target);
774 struct reg *regs;
775
776 if (!is_arm(arm)) {
777 command_print(CMD_CTX, "current target isn't an ARM");
778 return ERROR_FAIL;
779 }
780
781 if (target->state != TARGET_HALTED) {
782 command_print(CMD_CTX, "error: target must be halted for register accesses");
783 return ERROR_FAIL;
784 }
785
786 if (arm->core_type != ARM_MODE_ANY) {
787 command_print(CMD_CTX,
788 "Microcontroller Profile not supported - use standard reg cmd");
789 return ERROR_OK;
790 }
791
792 if (!is_arm_mode(arm->core_mode)) {
793 LOG_ERROR("not a valid arm core mode - communication failure?");
794 return ERROR_FAIL;
795 }
796
797 if (!arm->full_context) {
798 command_print(CMD_CTX, "error: target doesn't support %s",
799 CMD_NAME);
800 return ERROR_FAIL;
801 }
802
803 regs = arm->core_cache->reg_list;
804
805 for (unsigned mode = 0; mode < ARRAY_SIZE(arm_mode_data); mode++) {
806 const char *name;
807 char *sep = "\n";
808 char *shadow = "";
809
810 /* label this bank of registers (or shadows) */
811 switch (arm_mode_data[mode].psr) {
812 case ARM_MODE_SYS:
813 continue;
814 case ARM_MODE_USR:
815 name = "System and User";
816 sep = "";
817 break;
818 case ARM_MODE_MON:
819 if (arm->core_type != ARM_MODE_MON)
820 continue;
821 /* FALLTHROUGH */
822 default:
823 name = arm_mode_data[mode].name;
824 shadow = "shadow ";
825 break;
826 }
827 command_print(CMD_CTX, "%s%s mode %sregisters",
828 sep, name, shadow);
829
830 /* display N rows of up to 4 registers each */
831 for (unsigned i = 0; i < arm_mode_data[mode].n_indices; ) {
832 char output[80];
833 int output_len = 0;
834
835 for (unsigned j = 0; j < 4; j++, i++) {
836 uint32_t value;
837 struct reg *reg = regs;
838
839 if (i >= arm_mode_data[mode].n_indices)
840 break;
841
842 reg += arm_mode_data[mode].indices[i];
843
844 /* REVISIT be smarter about faults... */
845 if (!reg->valid)
846 arm->full_context(target);
847
848 value = buf_get_u32(reg->value, 0, 32);
849 output_len += snprintf(output + output_len,
850 sizeof(output) - output_len,
851 "%8s: %8.8" PRIx32 " ",
852 reg->name, value);
853 }
854 command_print(CMD_CTX, "%s", output);
855 }
856 }
857
858 return ERROR_OK;
859 }
860
861 COMMAND_HANDLER(handle_armv4_5_core_state_command)
862 {
863 struct target *target = get_current_target(CMD_CTX);
864 struct arm *arm = target_to_arm(target);
865
866 if (!is_arm(arm)) {
867 command_print(CMD_CTX, "current target isn't an ARM");
868 return ERROR_FAIL;
869 }
870
871 if (arm->core_type == ARM_MODE_THREAD) {
872 /* armv7m not supported */
873 command_print(CMD_CTX, "Unsupported Command");
874 return ERROR_OK;
875 }
876
877 if (CMD_ARGC > 0) {
878 if (strcmp(CMD_ARGV[0], "arm") == 0)
879 arm->core_state = ARM_STATE_ARM;
880 if (strcmp(CMD_ARGV[0], "thumb") == 0)
881 arm->core_state = ARM_STATE_THUMB;
882 }
883
884 command_print(CMD_CTX, "core state: %s", arm_state_strings[arm->core_state]);
885
886 return ERROR_OK;
887 }
888
889 COMMAND_HANDLER(handle_arm_disassemble_command)
890 {
891 int retval = ERROR_OK;
892 struct target *target = get_current_target(CMD_CTX);
893
894 if (target == NULL) {
895 LOG_ERROR("No target selected");
896 return ERROR_FAIL;
897 }
898
899 struct arm *arm = target_to_arm(target);
900 target_addr_t address;
901 int count = 1;
902 int thumb = 0;
903
904 if (!is_arm(arm)) {
905 command_print(CMD_CTX, "current target isn't an ARM");
906 return ERROR_FAIL;
907 }
908
909 if (arm->core_type == ARM_MODE_THREAD) {
910 /* armv7m is always thumb mode */
911 thumb = 1;
912 }
913
914 switch (CMD_ARGC) {
915 case 3:
916 if (strcmp(CMD_ARGV[2], "thumb") != 0)
917 goto usage;
918 thumb = 1;
919 /* FALL THROUGH */
920 case 2:
921 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
922 /* FALL THROUGH */
923 case 1:
924 COMMAND_PARSE_ADDRESS(CMD_ARGV[0], address);
925 if (address & 0x01) {
926 if (!thumb) {
927 command_print(CMD_CTX, "Disassemble as Thumb");
928 thumb = 1;
929 }
930 address &= ~1;
931 }
932 break;
933 default:
934 usage:
935 count = 0;
936 retval = ERROR_COMMAND_SYNTAX_ERROR;
937 }
938
939 while (count-- > 0) {
940 struct arm_instruction cur_instruction;
941
942 if (thumb) {
943 /* Always use Thumb2 disassembly for best handling
944 * of 32-bit BL/BLX, and to work with newer cores
945 * (some ARMv6, all ARMv7) that use Thumb2.
946 */
947 retval = thumb2_opcode(target, address,
948 &cur_instruction);
949 if (retval != ERROR_OK)
950 break;
951 } else {
952 uint32_t opcode;
953
954 retval = target_read_u32(target, address, &opcode);
955 if (retval != ERROR_OK)
956 break;
957 retval = arm_evaluate_opcode(opcode, address,
958 &cur_instruction) != ERROR_OK;
959 if (retval != ERROR_OK)
960 break;
961 }
962 command_print(CMD_CTX, "%s", cur_instruction.text);
963 address += cur_instruction.instruction_size;
964 }
965
966 return retval;
967 }
968
969 static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
970 {
971 struct command_context *context;
972 struct target *target;
973 struct arm *arm;
974 int retval;
975
976 context = current_command_context(interp);
977 assert(context != NULL);
978
979 target = get_current_target(context);
980 if (target == NULL) {
981 LOG_ERROR("%s: no current target", __func__);
982 return JIM_ERR;
983 }
984 if (!target_was_examined(target)) {
985 LOG_ERROR("%s: not yet examined", target_name(target));
986 return JIM_ERR;
987 }
988 arm = target_to_arm(target);
989 if (!is_arm(arm)) {
990 LOG_ERROR("%s: not an ARM", target_name(target));
991 return JIM_ERR;
992 }
993
994 if ((argc < 6) || (argc > 7)) {
995 /* FIXME use the command name to verify # params... */
996 LOG_ERROR("%s: wrong number of arguments", __func__);
997 return JIM_ERR;
998 }
999
1000 int cpnum;
1001 uint32_t op1;
1002 uint32_t op2;
1003 uint32_t CRn;
1004 uint32_t CRm;
1005 uint32_t value;
1006 long l;
1007
1008 /* NOTE: parameter sequence matches ARM instruction set usage:
1009 * MCR pNUM, op1, rX, CRn, CRm, op2 ; write CP from rX
1010 * MRC pNUM, op1, rX, CRn, CRm, op2 ; read CP into rX
1011 * The "rX" is necessarily omitted; it uses Tcl mechanisms.
1012 */
1013 retval = Jim_GetLong(interp, argv[1], &l);
1014 if (retval != JIM_OK)
1015 return retval;
1016 if (l & ~0xf) {
1017 LOG_ERROR("%s: %s %d out of range", __func__,
1018 "coprocessor", (int) l);
1019 return JIM_ERR;
1020 }
1021 cpnum = l;
1022
1023 retval = Jim_GetLong(interp, argv[2], &l);
1024 if (retval != JIM_OK)
1025 return retval;
1026 if (l & ~0x7) {
1027 LOG_ERROR("%s: %s %d out of range", __func__,
1028 "op1", (int) l);
1029 return JIM_ERR;
1030 }
1031 op1 = l;
1032
1033 retval = Jim_GetLong(interp, argv[3], &l);
1034 if (retval != JIM_OK)
1035 return retval;
1036 if (l & ~0xf) {
1037 LOG_ERROR("%s: %s %d out of range", __func__,
1038 "CRn", (int) l);
1039 return JIM_ERR;
1040 }
1041 CRn = l;
1042
1043 retval = Jim_GetLong(interp, argv[4], &l);
1044 if (retval != JIM_OK)
1045 return retval;
1046 if (l & ~0xf) {
1047 LOG_ERROR("%s: %s %d out of range", __func__,
1048 "CRm", (int) l);
1049 return JIM_ERR;
1050 }
1051 CRm = l;
1052
1053 retval = Jim_GetLong(interp, argv[5], &l);
1054 if (retval != JIM_OK)
1055 return retval;
1056 if (l & ~0x7) {
1057 LOG_ERROR("%s: %s %d out of range", __func__,
1058 "op2", (int) l);
1059 return JIM_ERR;
1060 }
1061 op2 = l;
1062
1063 value = 0;
1064
1065 /* FIXME don't assume "mrc" vs "mcr" from the number of params;
1066 * that could easily be a typo! Check both...
1067 *
1068 * FIXME change the call syntax here ... simplest to just pass
1069 * the MRC() or MCR() instruction to be executed. That will also
1070 * let us support the "mrc2" and "mcr2" opcodes (toggling one bit)
1071 * if that's ever needed.
1072 */
1073 if (argc == 7) {
1074 retval = Jim_GetLong(interp, argv[6], &l);
1075 if (retval != JIM_OK)
1076 return retval;
1077 value = l;
1078
1079 /* NOTE: parameters reordered! */
1080 /* ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2) */
1081 retval = arm->mcr(target, cpnum, op1, op2, CRn, CRm, value);
1082 if (retval != ERROR_OK)
1083 return JIM_ERR;
1084 } else {
1085 /* NOTE: parameters reordered! */
1086 /* ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2) */
1087 retval = arm->mrc(target, cpnum, op1, op2, CRn, CRm, &value);
1088 if (retval != ERROR_OK)
1089 return JIM_ERR;
1090
1091 Jim_SetResult(interp, Jim_NewIntObj(interp, value));
1092 }
1093
1094 return JIM_OK;
1095 }
1096
1097 COMMAND_HANDLER(handle_arm_semihosting_command)
1098 {
1099 struct target *target = get_current_target(CMD_CTX);
1100
1101 if (target == NULL) {
1102 LOG_ERROR("No target selected");
1103 return ERROR_FAIL;
1104 }
1105
1106 struct arm *arm = target_to_arm(target);
1107
1108 if (!is_arm(arm)) {
1109 command_print(CMD_CTX, "current target isn't an ARM");
1110 return ERROR_FAIL;
1111 }
1112
1113 if (!arm->setup_semihosting) {
1114 command_print(CMD_CTX, "semihosting not supported for current target");
1115 return ERROR_FAIL;
1116 }
1117
1118 if (CMD_ARGC > 0) {
1119 int semihosting;
1120
1121 COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting);
1122
1123 if (!target_was_examined(target)) {
1124 LOG_ERROR("Target not examined yet");
1125 return ERROR_FAIL;
1126 }
1127
1128 if (arm->setup_semihosting(target, semihosting) != ERROR_OK) {
1129 LOG_ERROR("Failed to Configure semihosting");
1130 return ERROR_FAIL;
1131 }
1132
1133 /* FIXME never let that "catch" be dropped! */
1134 arm->is_semihosting = semihosting;
1135 }
1136
1137 command_print(CMD_CTX, "semihosting is %s",
1138 arm->is_semihosting
1139 ? "enabled" : "disabled");
1140
1141 return ERROR_OK;
1142 }
1143
1144 COMMAND_HANDLER(handle_arm_semihosting_fileio_command)
1145 {
1146 struct target *target = get_current_target(CMD_CTX);
1147
1148 if (target == NULL) {
1149 LOG_ERROR("No target selected");
1150 return ERROR_FAIL;
1151 }
1152
1153 struct arm *arm = target_to_arm(target);
1154
1155 if (!is_arm(arm)) {
1156 command_print(CMD_CTX, "current target isn't an ARM");
1157 return ERROR_FAIL;
1158 }
1159
1160 if (!arm->is_semihosting) {
1161 command_print(CMD_CTX, "semihosting is not enabled");
1162 return ERROR_FAIL;
1163 }
1164
1165 if (CMD_ARGC > 0)
1166 COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm->is_semihosting_fileio);
1167
1168 command_print(CMD_CTX, "semihosting fileio is %s",
1169 arm->is_semihosting_fileio
1170 ? "enabled" : "disabled");
1171
1172 return ERROR_OK;
1173 }
1174
1175 COMMAND_HANDLER(handle_arm_semihosting_cmdline)
1176 {
1177 struct target *target = get_current_target(CMD_CTX);
1178 unsigned int i;
1179
1180 if (target == NULL) {
1181 LOG_ERROR("No target selected");
1182 return ERROR_FAIL;
1183 }
1184
1185 struct arm *arm = target_to_arm(target);
1186
1187 if (!is_arm(arm)) {
1188 command_print(CMD_CTX, "current target isn't an ARM");
1189 return ERROR_FAIL;
1190 }
1191
1192 if (!arm->setup_semihosting) {
1193 command_print(CMD_CTX, "semihosting not supported for current target");
1194 return ERROR_FAIL;
1195 }
1196
1197 free(arm->semihosting_cmdline);
1198 arm->semihosting_cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
1199
1200 for (i = 1; i < CMD_ARGC; i++) {
1201 char *cmdline = alloc_printf("%s %s", arm->semihosting_cmdline, CMD_ARGV[i]);
1202 if (cmdline == NULL)
1203 break;
1204 free(arm->semihosting_cmdline);
1205 arm->semihosting_cmdline = cmdline;
1206 }
1207
1208 return ERROR_OK;
1209 }
1210
1211 static const struct command_registration arm_exec_command_handlers[] = {
1212 {
1213 .name = "reg",
1214 .handler = handle_armv4_5_reg_command,
1215 .mode = COMMAND_EXEC,
1216 .help = "display ARM core registers",
1217 .usage = "",
1218 },
1219 {
1220 .name = "core_state",
1221 .handler = handle_armv4_5_core_state_command,
1222 .mode = COMMAND_EXEC,
1223 .usage = "['arm'|'thumb']",
1224 .help = "display/change ARM core state",
1225 },
1226 {
1227 .name = "disassemble",
1228 .handler = handle_arm_disassemble_command,
1229 .mode = COMMAND_EXEC,
1230 .usage = "address [count ['thumb']]",
1231 .help = "disassemble instructions ",
1232 },
1233 {
1234 .name = "mcr",
1235 .mode = COMMAND_EXEC,
1236 .jim_handler = &jim_mcrmrc,
1237 .help = "write coprocessor register",
1238 .usage = "cpnum op1 CRn CRm op2 value",
1239 },
1240 {
1241 .name = "mrc",
1242 .jim_handler = &jim_mcrmrc,
1243 .help = "read coprocessor register",
1244 .usage = "cpnum op1 CRn CRm op2",
1245 },
1246 {
1247 "semihosting",
1248 .handler = handle_arm_semihosting_command,
1249 .mode = COMMAND_EXEC,
1250 .usage = "['enable'|'disable']",
1251 .help = "activate support for semihosting operations",
1252 },
1253 {
1254 "semihosting_cmdline",
1255 .handler = handle_arm_semihosting_cmdline,
1256 .mode = COMMAND_EXEC,
1257 .usage = "arguments",
1258 .help = "command line arguments to be passed to program",
1259 },
1260 {
1261 "semihosting_fileio",
1262 .handler = handle_arm_semihosting_fileio_command,
1263 .mode = COMMAND_EXEC,
1264 .usage = "['enable'|'disable']",
1265 .help = "activate support for semihosting fileio operations",
1266 },
1267
1268 COMMAND_REGISTRATION_DONE
1269 };
1270 const struct command_registration arm_command_handlers[] = {
1271 {
1272 .name = "arm",
1273 .mode = COMMAND_ANY,
1274 .help = "ARM command group",
1275 .usage = "",
1276 .chain = arm_exec_command_handlers,
1277 },
1278 COMMAND_REGISTRATION_DONE
1279 };
1280
1281 int arm_get_gdb_reg_list(struct target *target,
1282 struct reg **reg_list[], int *reg_list_size,
1283 enum target_register_class reg_class)
1284 {
1285 struct arm *arm = target_to_arm(target);
1286 unsigned int i;
1287
1288 if (!is_arm_mode(arm->core_mode)) {
1289 LOG_ERROR("not a valid arm core mode - communication failure?");
1290 return ERROR_FAIL;
1291 }
1292
1293 switch (reg_class) {
1294 case REG_CLASS_GENERAL:
1295 *reg_list_size = 26;
1296 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1297
1298 for (i = 0; i < 16; i++)
1299 (*reg_list)[i] = arm_reg_current(arm, i);
1300
1301 /* For GDB compatibility, take FPA registers size into account and zero-fill it*/
1302 for (i = 16; i < 24; i++)
1303 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
1304 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
1305
1306 (*reg_list)[25] = arm->cpsr;
1307
1308 return ERROR_OK;
1309 break;
1310
1311 case REG_CLASS_ALL:
1312 *reg_list_size = (arm->core_type != ARM_MODE_MON ? 48 : 51);
1313 unsigned int list_size_core = *reg_list_size;
1314 if (arm->arm_vfp_version == ARM_VFP_V3)
1315 *reg_list_size += 33;
1316
1317 *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
1318
1319 for (i = 0; i < 16; i++)
1320 (*reg_list)[i] = arm_reg_current(arm, i);
1321
1322 for (i = 13; i < ARRAY_SIZE(arm_core_regs); i++) {
1323 int reg_index = arm->core_cache->reg_list[i].number;
1324 if (!(arm_core_regs[i].mode == ARM_MODE_MON
1325 && arm->core_type != ARM_MODE_MON))
1326 (*reg_list)[reg_index] = &(arm->core_cache->reg_list[i]);
1327 }
1328
1329 /* When we supply the target description, there is no need for fake FPA */
1330 for (i = 16; i < 24; i++) {
1331 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
1332 (*reg_list)[i]->size = 0;
1333 }
1334 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
1335 (*reg_list)[24]->size = 0;
1336
1337 if (arm->arm_vfp_version == ARM_VFP_V3) {
1338 unsigned int num_core_regs = ARRAY_SIZE(arm_core_regs);
1339 for (i = 0; i < 33; i++)
1340 (*reg_list)[list_size_core + i] = &(arm->core_cache->reg_list[num_core_regs + i]);
1341 }
1342
1343 return ERROR_OK;
1344 break;
1345
1346 default:
1347 LOG_ERROR("not a valid register class type in query.");
1348 return ERROR_FAIL;
1349 break;
1350 }
1351 }
1352
1353 /* wait for execution to complete and check exit point */
1354 static int armv4_5_run_algorithm_completion(struct target *target,
1355 uint32_t exit_point,
1356 int timeout_ms,
1357 void *arch_info)
1358 {
1359 int retval;
1360 struct arm *arm = target_to_arm(target);
1361
1362 retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
1363 if (retval != ERROR_OK)
1364 return retval;
1365 if (target->state != TARGET_HALTED) {
1366 retval = target_halt(target);
1367 if (retval != ERROR_OK)
1368 return retval;
1369 retval = target_wait_state(target, TARGET_HALTED, 500);
1370 if (retval != ERROR_OK)
1371 return retval;
1372 return ERROR_TARGET_TIMEOUT;
1373 }
1374
1375 /* fast exit: ARMv5+ code can use BKPT */
1376 if (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) {
1377 LOG_WARNING(
1378 "target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
1379 buf_get_u32(arm->pc->value, 0, 32));
1380 return ERROR_TARGET_TIMEOUT;
1381 }
1382
1383 return ERROR_OK;
1384 }
1385
1386 int armv4_5_run_algorithm_inner(struct target *target,
1387 int num_mem_params, struct mem_param *mem_params,
1388 int num_reg_params, struct reg_param *reg_params,
1389 uint32_t entry_point, uint32_t exit_point,
1390 int timeout_ms, void *arch_info,
1391 int (*run_it)(struct target *target, uint32_t exit_point,
1392 int timeout_ms, void *arch_info))
1393 {
1394 struct arm *arm = target_to_arm(target);
1395 struct arm_algorithm *arm_algorithm_info = arch_info;
1396 enum arm_state core_state = arm->core_state;
1397 uint32_t context[17];
1398 uint32_t cpsr;
1399 int exit_breakpoint_size = 0;
1400 int i;
1401 int retval = ERROR_OK;
1402
1403 LOG_DEBUG("Running algorithm");
1404
1405 if (arm_algorithm_info->common_magic != ARM_COMMON_MAGIC) {
1406 LOG_ERROR("current target isn't an ARMV4/5 target");
1407 return ERROR_TARGET_INVALID;
1408 }
1409
1410 if (target->state != TARGET_HALTED) {
1411 LOG_WARNING("target not halted");
1412 return ERROR_TARGET_NOT_HALTED;
1413 }
1414
1415 if (!is_arm_mode(arm->core_mode)) {
1416 LOG_ERROR("not a valid arm core mode - communication failure?");
1417 return ERROR_FAIL;
1418 }
1419
1420 /* armv5 and later can terminate with BKPT instruction; less overhead */
1421 if (!exit_point && arm->is_armv4) {
1422 LOG_ERROR("ARMv4 target needs HW breakpoint location");
1423 return ERROR_FAIL;
1424 }
1425
1426 /* save r0..pc, cpsr-or-spsr, and then cpsr-for-sure;
1427 * they'll be restored later.
1428 */
1429 for (i = 0; i <= 16; i++) {
1430 struct reg *r;
1431
1432 r = &ARMV4_5_CORE_REG_MODE(arm->core_cache,
1433 arm_algorithm_info->core_mode, i);
1434 if (!r->valid)
1435 arm->read_core_reg(target, r, i,
1436 arm_algorithm_info->core_mode);
1437 context[i] = buf_get_u32(r->value, 0, 32);
1438 }
1439 cpsr = buf_get_u32(arm->cpsr->value, 0, 32);
1440
1441 for (i = 0; i < num_mem_params; i++) {
1442 retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size,
1443 mem_params[i].value);
1444 if (retval != ERROR_OK)
1445 return retval;
1446 }
1447
1448 for (i = 0; i < num_reg_params; i++) {
1449 struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, 0);
1450 if (!reg) {
1451 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1452 return ERROR_COMMAND_SYNTAX_ERROR;
1453 }
1454
1455 if (reg->size != reg_params[i].size) {
1456 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
1457 reg_params[i].reg_name);
1458 return ERROR_COMMAND_SYNTAX_ERROR;
1459 }
1460
1461 retval = armv4_5_set_core_reg(reg, reg_params[i].value);
1462 if (retval != ERROR_OK)
1463 return retval;
1464 }
1465
1466 arm->core_state = arm_algorithm_info->core_state;
1467 if (arm->core_state == ARM_STATE_ARM)
1468 exit_breakpoint_size = 4;
1469 else if (arm->core_state == ARM_STATE_THUMB)
1470 exit_breakpoint_size = 2;
1471 else {
1472 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
1473 return ERROR_COMMAND_SYNTAX_ERROR;
1474 }
1475
1476 if (arm_algorithm_info->core_mode != ARM_MODE_ANY) {
1477 LOG_DEBUG("setting core_mode: 0x%2.2x",
1478 arm_algorithm_info->core_mode);
1479 buf_set_u32(arm->cpsr->value, 0, 5,
1480 arm_algorithm_info->core_mode);
1481 arm->cpsr->dirty = 1;
1482 arm->cpsr->valid = 1;
1483 }
1484
1485 /* terminate using a hardware or (ARMv5+) software breakpoint */
1486 if (exit_point) {
1487 retval = breakpoint_add(target, exit_point,
1488 exit_breakpoint_size, BKPT_HARD);
1489 if (retval != ERROR_OK) {
1490 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
1491 return ERROR_TARGET_FAILURE;
1492 }
1493 }
1494
1495 retval = target_resume(target, 0, entry_point, 1, 1);
1496 if (retval != ERROR_OK)
1497 return retval;
1498 retval = run_it(target, exit_point, timeout_ms, arch_info);
1499
1500 if (exit_point)
1501 breakpoint_remove(target, exit_point);
1502
1503 if (retval != ERROR_OK)
1504 return retval;
1505
1506 for (i = 0; i < num_mem_params; i++) {
1507 if (mem_params[i].direction != PARAM_OUT) {
1508 int retvaltemp = target_read_buffer(target, mem_params[i].address,
1509 mem_params[i].size,
1510 mem_params[i].value);
1511 if (retvaltemp != ERROR_OK)
1512 retval = retvaltemp;
1513 }
1514 }
1515
1516 for (i = 0; i < num_reg_params; i++) {
1517 if (reg_params[i].direction != PARAM_OUT) {
1518
1519 struct reg *reg = register_get_by_name(arm->core_cache,
1520 reg_params[i].reg_name,
1521 0);
1522 if (!reg) {
1523 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
1524 retval = ERROR_COMMAND_SYNTAX_ERROR;
1525 continue;
1526 }
1527
1528 if (reg->size != reg_params[i].size) {
1529 LOG_ERROR(
1530 "BUG: register '%s' size doesn't match reg_params[i].size",
1531 reg_params[i].reg_name);
1532 retval = ERROR_COMMAND_SYNTAX_ERROR;
1533 continue;
1534 }
1535
1536 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
1537 }
1538 }
1539
1540 /* restore everything we saved before (17 or 18 registers) */
1541 for (i = 0; i <= 16; i++) {
1542 uint32_t regvalue;
1543 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
1544 arm_algorithm_info->core_mode, i).value, 0, 32);
1545 if (regvalue != context[i]) {
1546 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "",
1547 ARMV4_5_CORE_REG_MODE(arm->core_cache,
1548 arm_algorithm_info->core_mode, i).name, context[i]);
1549 buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
1550 arm_algorithm_info->core_mode, i).value, 0, 32, context[i]);
1551 ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode,
1552 i).valid = 1;
1553 ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode,
1554 i).dirty = 1;
1555 }
1556 }
1557
1558 arm_set_cpsr(arm, cpsr);
1559 arm->cpsr->dirty = 1;
1560
1561 arm->core_state = core_state;
1562
1563 return retval;
1564 }
1565
1566 int armv4_5_run_algorithm(struct target *target,
1567 int num_mem_params,
1568 struct mem_param *mem_params,
1569 int num_reg_params,
1570 struct reg_param *reg_params,
1571 target_addr_t entry_point,
1572 target_addr_t exit_point,
1573 int timeout_ms,
1574 void *arch_info)
1575 {
1576 return armv4_5_run_algorithm_inner(target,
1577 num_mem_params,
1578 mem_params,
1579 num_reg_params,
1580 reg_params,
1581 (uint32_t)entry_point,
1582 (uint32_t)exit_point,
1583 timeout_ms,
1584 arch_info,
1585 armv4_5_run_algorithm_completion);
1586 }
1587
1588 /**
1589 * Runs ARM code in the target to calculate a CRC32 checksum.
1590 *
1591 */
1592 int arm_checksum_memory(struct target *target,
1593 target_addr_t address, uint32_t count, uint32_t *checksum)
1594 {
1595 struct working_area *crc_algorithm;
1596 struct arm_algorithm arm_algo;
1597 struct arm *arm = target_to_arm(target);
1598 struct reg_param reg_params[2];
1599 int retval;
1600 uint32_t i;
1601 uint32_t exit_var = 0;
1602
1603 static const uint8_t arm_crc_code_le[] = {
1604 #include "../../contrib/loaders/checksum/armv4_5_crc.inc"
1605 };
1606
1607 assert(sizeof(arm_crc_code_le) % 4 == 0);
1608
1609 retval = target_alloc_working_area(target,
1610 sizeof(arm_crc_code_le), &crc_algorithm);
1611 if (retval != ERROR_OK)
1612 return retval;
1613
1614 /* convert code into a buffer in target endianness */
1615 for (i = 0; i < ARRAY_SIZE(arm_crc_code_le) / 4; i++) {
1616 retval = target_write_u32(target,
1617 crc_algorithm->address + i * sizeof(uint32_t),
1618 le_to_h_u32(&arm_crc_code_le[i * 4]));
1619 if (retval != ERROR_OK)
1620 goto cleanup;
1621 }
1622
1623 arm_algo.common_magic = ARM_COMMON_MAGIC;
1624 arm_algo.core_mode = ARM_MODE_SVC;
1625 arm_algo.core_state = ARM_STATE_ARM;
1626
1627 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
1628 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1629
1630 buf_set_u32(reg_params[0].value, 0, 32, address);
1631 buf_set_u32(reg_params[1].value, 0, 32, count);
1632
1633 /* 20 second timeout/megabyte */
1634 int timeout = 20000 * (1 + (count / (1024 * 1024)));
1635
1636 /* armv4 must exit using a hardware breakpoint */
1637 if (arm->is_armv4)
1638 exit_var = crc_algorithm->address + sizeof(arm_crc_code_le) - 8;
1639
1640 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
1641 crc_algorithm->address,
1642 exit_var,
1643 timeout, &arm_algo);
1644
1645 if (retval == ERROR_OK)
1646 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
1647 else
1648 LOG_ERROR("error executing ARM crc algorithm");
1649
1650 destroy_reg_param(&reg_params[0]);
1651 destroy_reg_param(&reg_params[1]);
1652
1653 cleanup:
1654 target_free_working_area(target, crc_algorithm);
1655
1656 return retval;
1657 }
1658
1659 /**
1660 * Runs ARM code in the target to check whether a memory block holds
1661 * all ones. NOR flash which has been erased, and thus may be written,
1662 * holds all ones.
1663 *
1664 */
1665 int arm_blank_check_memory(struct target *target,
1666 struct target_memory_check_block *blocks, int num_blocks, uint8_t erased_value)
1667 {
1668 struct working_area *check_algorithm;
1669 struct reg_param reg_params[3];
1670 struct arm_algorithm arm_algo;
1671 struct arm *arm = target_to_arm(target);
1672 int retval;
1673 uint32_t i;
1674 uint32_t exit_var = 0;
1675
1676 static const uint8_t check_code_le[] = {
1677 #include "../../contrib/loaders/erase_check/armv4_5_erase_check.inc"
1678 };
1679
1680 assert(sizeof(check_code_le) % 4 == 0);
1681
1682 if (erased_value != 0xff) {
1683 LOG_ERROR("Erase value 0x%02" PRIx8 " not yet supported for ARMv4/v5 targets",
1684 erased_value);
1685 return ERROR_FAIL;
1686 }
1687
1688 /* make sure we have a working area */
1689 retval = target_alloc_working_area(target,
1690 sizeof(check_code_le), &check_algorithm);
1691 if (retval != ERROR_OK)
1692 return retval;
1693
1694 /* convert code into a buffer in target endianness */
1695 for (i = 0; i < ARRAY_SIZE(check_code_le) / 4; i++) {
1696 retval = target_write_u32(target,
1697 check_algorithm->address
1698 + i * sizeof(uint32_t),
1699 le_to_h_u32(&check_code_le[i * 4]));
1700 if (retval != ERROR_OK)
1701 goto cleanup;
1702 }
1703
1704 arm_algo.common_magic = ARM_COMMON_MAGIC;
1705 arm_algo.core_mode = ARM_MODE_SVC;
1706 arm_algo.core_state = ARM_STATE_ARM;
1707
1708 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1709 buf_set_u32(reg_params[0].value, 0, 32, blocks[0].address);
1710
1711 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1712 buf_set_u32(reg_params[1].value, 0, 32, blocks[0].size);
1713
1714 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1715 buf_set_u32(reg_params[2].value, 0, 32, erased_value);
1716
1717 /* armv4 must exit using a hardware breakpoint */
1718 if (arm->is_armv4)
1719 exit_var = check_algorithm->address + sizeof(check_code_le) - 4;
1720
1721 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
1722 check_algorithm->address,
1723 exit_var,
1724 10000, &arm_algo);
1725
1726 if (retval == ERROR_OK)
1727 blocks[0].result = buf_get_u32(reg_params[2].value, 0, 32);
1728
1729 destroy_reg_param(&reg_params[0]);
1730 destroy_reg_param(&reg_params[1]);
1731 destroy_reg_param(&reg_params[2]);
1732
1733 cleanup:
1734 target_free_working_area(target, check_algorithm);
1735
1736 if (retval != ERROR_OK)
1737 return retval;
1738
1739 return 1; /* only one block has been checked */
1740 }
1741
1742 static int arm_full_context(struct target *target)
1743 {
1744 struct arm *arm = target_to_arm(target);
1745 unsigned num_regs = arm->core_cache->num_regs;
1746 struct reg *reg = arm->core_cache->reg_list;
1747 int retval = ERROR_OK;
1748
1749 for (; num_regs && retval == ERROR_OK; num_regs--, reg++) {
1750 if (reg->valid)
1751 continue;
1752 retval = armv4_5_get_core_reg(reg);
1753 }
1754 return retval;
1755 }
1756
1757 static int arm_default_mrc(struct target *target, int cpnum,
1758 uint32_t op1, uint32_t op2,
1759 uint32_t CRn, uint32_t CRm,
1760 uint32_t *value)
1761 {
1762 LOG_ERROR("%s doesn't implement MRC", target_type_name(target));
1763 return ERROR_FAIL;
1764 }
1765
1766 static int arm_default_mcr(struct target *target, int cpnum,
1767 uint32_t op1, uint32_t op2,
1768 uint32_t CRn, uint32_t CRm,
1769 uint32_t value)
1770 {
1771 LOG_ERROR("%s doesn't implement MCR", target_type_name(target));
1772 return ERROR_FAIL;
1773 }
1774
1775 int arm_init_arch_info(struct target *target, struct arm *arm)
1776 {
1777 target->arch_info = arm;
1778 arm->target = target;
1779
1780 arm->common_magic = ARM_COMMON_MAGIC;
1781
1782 /* core_type may be overridden by subtype logic */
1783 if (arm->core_type != ARM_MODE_THREAD) {
1784 arm->core_type = ARM_MODE_ANY;
1785 arm_set_cpsr(arm, ARM_MODE_USR);
1786 }
1787
1788 /* default full_context() has no core-specific optimizations */
1789 if (!arm->full_context && arm->read_core_reg)
1790 arm->full_context = arm_full_context;
1791
1792 if (!arm->mrc)
1793 arm->mrc = arm_default_mrc;
1794 if (!arm->mcr)
1795 arm->mcr = arm_default_mcr;
1796
1797 return ERROR_OK;
1798 }

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)