ARM: simplify CPSR handling
[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, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "armv4_5.h"
31 #include "arm_jtag.h"
32 #include "breakpoints.h"
33 #include "arm_disassembler.h"
34 #include "binarybuffer.h"
35 #include "algorithm.h"
36 #include "register.h"
37
38
39 /* offsets into armv4_5 core register cache */
40 enum {
41 // ARMV4_5_CPSR = 31,
42 ARMV4_5_SPSR_FIQ = 32,
43 ARMV4_5_SPSR_IRQ = 33,
44 ARMV4_5_SPSR_SVC = 34,
45 ARMV4_5_SPSR_ABT = 35,
46 ARMV4_5_SPSR_UND = 36,
47 ARM_SPSR_MON = 39,
48 };
49
50 static const uint8_t arm_usr_indices[17] = {
51 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ARMV4_5_CPSR,
52 };
53
54 static const uint8_t arm_fiq_indices[8] = {
55 16, 17, 18, 19, 20, 21, 22, ARMV4_5_SPSR_FIQ,
56 };
57
58 static const uint8_t arm_irq_indices[3] = {
59 23, 24, ARMV4_5_SPSR_IRQ,
60 };
61
62 static const uint8_t arm_svc_indices[3] = {
63 25, 26, ARMV4_5_SPSR_SVC,
64 };
65
66 static const uint8_t arm_abt_indices[3] = {
67 27, 28, ARMV4_5_SPSR_ABT,
68 };
69
70 static const uint8_t arm_und_indices[3] = {
71 29, 30, ARMV4_5_SPSR_UND,
72 };
73
74 static const uint8_t arm_mon_indices[3] = {
75 37, 38, ARM_SPSR_MON,
76 };
77
78 static const struct {
79 const char *name;
80 unsigned short psr;
81 /* For user and system modes, these list indices for all registers.
82 * otherwise they're just indices for the shadow registers and SPSR.
83 */
84 unsigned short n_indices;
85 const uint8_t *indices;
86 } arm_mode_data[] = {
87 /* Seven modes are standard from ARM7 on. "System" and "User" share
88 * the same registers; other modes shadow from 3 to 8 registers.
89 */
90 {
91 .name = "User",
92 .psr = ARMV4_5_MODE_USR,
93 .n_indices = ARRAY_SIZE(arm_usr_indices),
94 .indices = arm_usr_indices,
95 },
96 {
97 .name = "FIQ",
98 .psr = ARMV4_5_MODE_FIQ,
99 .n_indices = ARRAY_SIZE(arm_fiq_indices),
100 .indices = arm_fiq_indices,
101 },
102 {
103 .name = "Supervisor",
104 .psr = ARMV4_5_MODE_SVC,
105 .n_indices = ARRAY_SIZE(arm_svc_indices),
106 .indices = arm_svc_indices,
107 },
108 {
109 .name = "Abort",
110 .psr = ARMV4_5_MODE_ABT,
111 .n_indices = ARRAY_SIZE(arm_abt_indices),
112 .indices = arm_abt_indices,
113 },
114 {
115 .name = "IRQ",
116 .psr = ARMV4_5_MODE_IRQ,
117 .n_indices = ARRAY_SIZE(arm_irq_indices),
118 .indices = arm_irq_indices,
119 },
120 {
121 .name = "Undefined instruction",
122 .psr = ARMV4_5_MODE_UND,
123 .n_indices = ARRAY_SIZE(arm_und_indices),
124 .indices = arm_und_indices,
125 },
126 {
127 .name = "System",
128 .psr = ARMV4_5_MODE_SYS,
129 .n_indices = ARRAY_SIZE(arm_usr_indices),
130 .indices = arm_usr_indices,
131 },
132 /* TrustZone "Security Extensions" add a secure monitor mode.
133 * This is distinct from a "debug monitor" which can support
134 * non-halting debug, in conjunction with some debuggers.
135 */
136 {
137 .name = "Secure Monitor",
138 .psr = ARM_MODE_MON,
139 .n_indices = ARRAY_SIZE(arm_mon_indices),
140 .indices = arm_mon_indices,
141 },
142 };
143
144 /** Map PSR mode bits to the name of an ARM processor operating mode. */
145 const char *arm_mode_name(unsigned psr_mode)
146 {
147 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
148 if (arm_mode_data[i].psr == psr_mode)
149 return arm_mode_data[i].name;
150 }
151 LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
152 return "UNRECOGNIZED";
153 }
154
155 /** Return true iff the parameter denotes a valid ARM processor mode. */
156 bool is_arm_mode(unsigned psr_mode)
157 {
158 for (unsigned i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
159 if (arm_mode_data[i].psr == psr_mode)
160 return true;
161 }
162 return false;
163 }
164
165 /** Map PSR mode bits to linear number indexing armv4_5_core_reg_map */
166 int armv4_5_mode_to_number(enum armv4_5_mode mode)
167 {
168 switch (mode) {
169 case ARMV4_5_MODE_ANY:
170 /* map MODE_ANY to user mode */
171 case ARMV4_5_MODE_USR:
172 return 0;
173 case ARMV4_5_MODE_FIQ:
174 return 1;
175 case ARMV4_5_MODE_IRQ:
176 return 2;
177 case ARMV4_5_MODE_SVC:
178 return 3;
179 case ARMV4_5_MODE_ABT:
180 return 4;
181 case ARMV4_5_MODE_UND:
182 return 5;
183 case ARMV4_5_MODE_SYS:
184 return 6;
185 case ARM_MODE_MON:
186 return 7;
187 default:
188 LOG_ERROR("invalid mode value encountered %d", mode);
189 return -1;
190 }
191 }
192
193 /** Map linear number indexing armv4_5_core_reg_map to PSR mode bits. */
194 enum armv4_5_mode armv4_5_number_to_mode(int number)
195 {
196 switch (number) {
197 case 0:
198 return ARMV4_5_MODE_USR;
199 case 1:
200 return ARMV4_5_MODE_FIQ;
201 case 2:
202 return ARMV4_5_MODE_IRQ;
203 case 3:
204 return ARMV4_5_MODE_SVC;
205 case 4:
206 return ARMV4_5_MODE_ABT;
207 case 5:
208 return ARMV4_5_MODE_UND;
209 case 6:
210 return ARMV4_5_MODE_SYS;
211 case 7:
212 return ARM_MODE_MON;
213 default:
214 LOG_ERROR("mode index out of bounds %d", number);
215 return ARMV4_5_MODE_ANY;
216 }
217 }
218
219 char* armv4_5_state_strings[] =
220 {
221 "ARM", "Thumb", "Jazelle", "ThumbEE",
222 };
223
224 /* Templates for ARM core registers.
225 *
226 * NOTE: offsets in this table are coupled to the arm_mode_data
227 * table above, the armv4_5_core_reg_map array below, and also to
228 * the ARMV4_5_CPSR symbol (which should vanish after ARM11 updates).
229 */
230 static const struct {
231 /* The name is used for e.g. the "regs" command. */
232 const char *name;
233
234 /* The {cookie, mode} tuple uniquely identifies one register.
235 * In a given mode, cookies 0..15 map to registers R0..R15,
236 * with R13..R15 usually called SP, LR, PC.
237 *
238 * MODE_ANY is used as *input* to the mapping, and indicates
239 * various special cases (sigh) and errors.
240 *
241 * Cookie 16 is (currently) confusing, since it indicates
242 * CPSR -or- SPSR depending on whether 'mode' is MODE_ANY.
243 * (Exception modes have both CPSR and SPSR registers ...)
244 */
245 unsigned cookie;
246 enum armv4_5_mode mode;
247 } arm_core_regs[] = {
248 { .name = "r0", .cookie = 0, .mode = ARMV4_5_MODE_ANY, },
249 { .name = "r1", .cookie = 1, .mode = ARMV4_5_MODE_ANY, },
250 { .name = "r2", .cookie = 2, .mode = ARMV4_5_MODE_ANY, },
251 { .name = "r3", .cookie = 3, .mode = ARMV4_5_MODE_ANY, },
252 { .name = "r4", .cookie = 4, .mode = ARMV4_5_MODE_ANY, },
253 { .name = "r5", .cookie = 5, .mode = ARMV4_5_MODE_ANY, },
254 { .name = "r6", .cookie = 6, .mode = ARMV4_5_MODE_ANY, },
255 { .name = "r7", .cookie = 7, .mode = ARMV4_5_MODE_ANY, },
256
257 /* NOTE: regs 8..12 might be shadowed by FIQ ... flagging
258 * them as MODE_ANY creates special cases.
259 */
260 { .name = "r8", .cookie = 8, .mode = ARMV4_5_MODE_ANY, },
261 { .name = "r9", .cookie = 9, .mode = ARMV4_5_MODE_ANY, },
262 { .name = "r10", .cookie = 10, .mode = ARMV4_5_MODE_ANY, },
263 { .name = "r11", .cookie = 11, .mode = ARMV4_5_MODE_ANY, },
264 { .name = "r12", .cookie = 12, .mode = ARMV4_5_MODE_ANY, },
265
266 /* NOTE all MODE_USR registers are equivalent to MODE_SYS ones */
267 { .name = "sp_usr", .cookie = 13, .mode = ARMV4_5_MODE_USR, },
268 { .name = "lr_usr", .cookie = 14, .mode = ARMV4_5_MODE_USR, },
269
270 { .name = "pc", .cookie = 15, .mode = ARMV4_5_MODE_ANY, },
271
272 { .name = "r8_fiq", .cookie = 8, .mode = ARMV4_5_MODE_FIQ, },
273 { .name = "r9_fiq", .cookie = 9, .mode = ARMV4_5_MODE_FIQ, },
274 { .name = "r10_fiq", .cookie = 10, .mode = ARMV4_5_MODE_FIQ, },
275 { .name = "r11_fiq", .cookie = 11, .mode = ARMV4_5_MODE_FIQ, },
276 { .name = "r12_fiq", .cookie = 12, .mode = ARMV4_5_MODE_FIQ, },
277
278 { .name = "lr_fiq", .cookie = 13, .mode = ARMV4_5_MODE_FIQ, },
279 { .name = "sp_fiq", .cookie = 14, .mode = ARMV4_5_MODE_FIQ, },
280
281 { .name = "lr_irq", .cookie = 13, .mode = ARMV4_5_MODE_IRQ, },
282 { .name = "sp_irq", .cookie = 14, .mode = ARMV4_5_MODE_IRQ, },
283
284 { .name = "lr_svc", .cookie = 13, .mode = ARMV4_5_MODE_SVC, },
285 { .name = "sp_svc", .cookie = 14, .mode = ARMV4_5_MODE_SVC, },
286
287 { .name = "lr_abt", .cookie = 13, .mode = ARMV4_5_MODE_ABT, },
288 { .name = "sp_abt", .cookie = 14, .mode = ARMV4_5_MODE_ABT, },
289
290 { .name = "lr_und", .cookie = 13, .mode = ARMV4_5_MODE_UND, },
291 { .name = "sp_und", .cookie = 14, .mode = ARMV4_5_MODE_UND, },
292
293 { .name = "cpsr", .cookie = 16, .mode = ARMV4_5_MODE_ANY, },
294 { .name = "spsr_fiq", .cookie = 16, .mode = ARMV4_5_MODE_FIQ, },
295 { .name = "spsr_irq", .cookie = 16, .mode = ARMV4_5_MODE_IRQ, },
296 { .name = "spsr_svc", .cookie = 16, .mode = ARMV4_5_MODE_SVC, },
297 { .name = "spsr_abt", .cookie = 16, .mode = ARMV4_5_MODE_ABT, },
298 { .name = "spsr_und", .cookie = 16, .mode = ARMV4_5_MODE_UND, },
299
300 { .name = "lr_mon", .cookie = 13, .mode = ARM_MODE_MON, },
301 { .name = "sp_mon", .cookie = 14, .mode = ARM_MODE_MON, },
302 { .name = "spsr_mon", .cookie = 16, .mode = ARM_MODE_MON, },
303 };
304
305 /* map core mode (USR, FIQ, ...) and register number to
306 * indices into the register cache
307 */
308 const int armv4_5_core_reg_map[8][17] =
309 {
310 { /* USR */
311 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
312 },
313 { /* FIQ (8 shadows of USR, vs normal 3) */
314 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32
315 },
316 { /* IRQ */
317 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 23, 24, 15, 33
318 },
319 { /* SVC */
320 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 25, 26, 15, 34
321 },
322 { /* ABT */
323 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 27, 28, 15, 35
324 },
325 { /* UND */
326 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36
327 },
328 { /* SYS (same registers as USR) */
329 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
330 },
331 { /* MON */
332 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39,
333 }
334 };
335
336 static const uint8_t arm_gdb_dummy_fp_value[12];
337
338 /**
339 * Dummy FPA registers are required to support GDB on ARM.
340 * Register packets require eight obsolete FPA register values.
341 * Modern ARM cores use Vector Floating Point (VFP), if they
342 * have any floating point support. VFP is not FPA-compatible.
343 */
344 struct reg arm_gdb_dummy_fp_reg =
345 {
346 .name = "GDB dummy FPA register",
347 .value = (uint8_t *) arm_gdb_dummy_fp_value,
348 .valid = 1,
349 .size = 96,
350 };
351
352 static const uint8_t arm_gdb_dummy_fps_value[4];
353
354 /**
355 * Dummy FPA status registers are required to support GDB on ARM.
356 * Register packets require an obsolete FPA status register.
357 */
358 struct reg arm_gdb_dummy_fps_reg =
359 {
360 .name = "GDB dummy FPA status register",
361 .value = (uint8_t *) arm_gdb_dummy_fps_value,
362 .valid = 1,
363 .size = 32,
364 };
365
366 static void arm_gdb_dummy_init(void) __attribute__ ((constructor));
367
368 static void arm_gdb_dummy_init(void)
369 {
370 register_init_dummy(&arm_gdb_dummy_fp_reg);
371 register_init_dummy(&arm_gdb_dummy_fps_reg);
372 }
373
374 static int armv4_5_get_core_reg(struct reg *reg)
375 {
376 int retval;
377 struct arm_reg *armv4_5 = reg->arch_info;
378 struct target *target = armv4_5->target;
379
380 if (target->state != TARGET_HALTED)
381 {
382 LOG_ERROR("Target not halted");
383 return ERROR_TARGET_NOT_HALTED;
384 }
385
386 retval = armv4_5->armv4_5_common->read_core_reg(target, reg, armv4_5->num, armv4_5->mode);
387 if (retval == ERROR_OK) {
388 reg->valid = 1;
389 reg->dirty = 0;
390 }
391
392 return retval;
393 }
394
395 static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
396 {
397 struct arm_reg *armv4_5 = reg->arch_info;
398 struct target *target = armv4_5->target;
399 struct armv4_5_common_s *armv4_5_target = target_to_armv4_5(target);
400 uint32_t value = buf_get_u32(buf, 0, 32);
401
402 if (target->state != TARGET_HALTED)
403 {
404 LOG_ERROR("Target not halted");
405 return ERROR_TARGET_NOT_HALTED;
406 }
407
408 /* Except for CPSR, the "reg" command exposes a writeback model
409 * for the register cache.
410 */
411 buf_set_u32(reg->value, 0, 32, value);
412 reg->dirty = 1;
413 reg->valid = 1;
414
415 if (reg == armv4_5_target->cpsr)
416 {
417 /* FIXME handle J bit too; mostly for ThumbEE, also Jazelle */
418 if (value & 0x20)
419 {
420 /* T bit should be set */
421 if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
422 {
423 /* change state to Thumb */
424 LOG_DEBUG("changing to Thumb state");
425 armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
426 }
427 }
428 else
429 {
430 /* T bit should be cleared */
431 if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
432 {
433 /* change state to ARM */
434 LOG_DEBUG("changing to ARM state");
435 armv4_5_target->core_state = ARMV4_5_STATE_ARM;
436 }
437 }
438
439 /* REVISIT Why only update core for mode change, not also
440 * for state changes? Possibly older cores need to stay
441 * in ARM mode during halt mode debug, not execute Thumb;
442 * v6/v7a/v7r seem to do that automatically...
443 */
444
445 if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
446 {
447 LOG_DEBUG("changing ARM core mode to '%s'",
448 arm_mode_name(value & 0x1f));
449 armv4_5_target->core_mode = value & 0x1f;
450 armv4_5_target->write_core_reg(target, reg,
451 16, ARMV4_5_MODE_ANY, value);
452 reg->dirty = 0;
453 }
454 }
455
456 return ERROR_OK;
457 }
458
459 static const struct reg_arch_type arm_reg_type = {
460 .get = armv4_5_get_core_reg,
461 .set = armv4_5_set_core_reg,
462 };
463
464 struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common)
465 {
466 int num_regs = ARRAY_SIZE(arm_core_regs);
467 struct reg_cache *cache = malloc(sizeof(struct reg_cache));
468 struct reg *reg_list = calloc(num_regs, sizeof(struct reg));
469 struct arm_reg *arch_info = calloc(num_regs, sizeof(struct arm_reg));
470 int i;
471
472 if (!cache || !reg_list || !arch_info) {
473 free(cache);
474 free(reg_list);
475 free(arch_info);
476 return NULL;
477 }
478
479 cache->name = "ARM registers";
480 cache->next = NULL;
481 cache->reg_list = reg_list;
482 cache->num_regs = 0;
483
484 for (i = 0; i < num_regs; i++)
485 {
486 /* Skip registers this core doesn't expose */
487 if (arm_core_regs[i].mode == ARM_MODE_MON
488 && armv4_5_common->core_type != ARM_MODE_MON)
489 continue;
490
491 /* REVISIT handle Cortex-M, which only shadows R13/SP */
492
493 arch_info[i].num = arm_core_regs[i].cookie;
494 arch_info[i].mode = arm_core_regs[i].mode;
495 arch_info[i].target = target;
496 arch_info[i].armv4_5_common = armv4_5_common;
497
498 reg_list[i].name = (char *) arm_core_regs[i].name;
499 reg_list[i].size = 32;
500 reg_list[i].value = &arch_info[i].value;
501 reg_list[i].type = &arm_reg_type;
502 reg_list[i].arch_info = &arch_info[i];
503
504 cache->num_regs++;
505 }
506
507 armv4_5_common->cpsr = reg_list + ARMV4_5_CPSR;
508 armv4_5_common->core_cache = cache;
509 return cache;
510 }
511
512 int armv4_5_arch_state(struct target *target)
513 {
514 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
515
516 if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
517 {
518 LOG_ERROR("BUG: called for a non-ARMv4/5 target");
519 return ERROR_FAIL;
520 }
521
522 LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
523 armv4_5_state_strings[armv4_5->core_state],
524 Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
525 arm_mode_name(armv4_5->core_mode),
526 buf_get_u32(armv4_5->cpsr->value, 0, 32),
527 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
528
529 return ERROR_OK;
530 }
531
532 #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
533 cache->reg_list[armv4_5_core_reg_map[mode][num]]
534
535 COMMAND_HANDLER(handle_armv4_5_reg_command)
536 {
537 struct target *target = get_current_target(CMD_CTX);
538 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
539 unsigned num_regs;
540 struct reg *regs;
541
542 if (!is_arm(armv4_5))
543 {
544 command_print(CMD_CTX, "current target isn't an ARM");
545 return ERROR_FAIL;
546 }
547
548 if (target->state != TARGET_HALTED)
549 {
550 command_print(CMD_CTX, "error: target must be halted for register accesses");
551 return ERROR_FAIL;
552 }
553
554 if (!is_arm_mode(armv4_5->core_mode))
555 return ERROR_FAIL;
556
557 if (!armv4_5->full_context) {
558 command_print(CMD_CTX, "error: target doesn't support %s",
559 CMD_NAME);
560 return ERROR_FAIL;
561 }
562
563 num_regs = armv4_5->core_cache->num_regs;
564 regs = armv4_5->core_cache->reg_list;
565
566 for (unsigned mode = 0; mode < ARRAY_SIZE(arm_mode_data); mode++) {
567 const char *name;
568 char *sep = "\n";
569 char *shadow = "";
570
571 /* label this bank of registers (or shadows) */
572 switch (arm_mode_data[mode].psr) {
573 case ARMV4_5_MODE_SYS:
574 continue;
575 case ARMV4_5_MODE_USR:
576 name = "System and User";
577 sep = "";
578 break;
579 case ARM_MODE_MON:
580 if (armv4_5->core_type != ARM_MODE_MON)
581 continue;
582 /* FALLTHROUGH */
583 default:
584 name = arm_mode_data[mode].name;
585 shadow = "shadow ";
586 break;
587 }
588 command_print(CMD_CTX, "%s%s mode %sregisters",
589 sep, name, shadow);
590
591 /* display N rows of up to 4 registers each */
592 for (unsigned i = 0; i < arm_mode_data[mode].n_indices;) {
593 char output[80];
594 int output_len = 0;
595
596 for (unsigned j = 0; j < 4; j++, i++) {
597 uint32_t value;
598 struct reg *reg = regs;
599
600 if (i >= arm_mode_data[mode].n_indices)
601 break;
602
603 reg += arm_mode_data[mode].indices[i];
604
605 /* REVISIT be smarter about faults... */
606 if (!reg->valid)
607 armv4_5->full_context(target);
608
609 value = buf_get_u32(reg->value, 0, 32);
610 output_len += snprintf(output + output_len,
611 sizeof(output) - output_len,
612 "%8s: %8.8" PRIx32 " ",
613 reg->name, value);
614 }
615 command_print(CMD_CTX, "%s", output);
616 }
617 }
618
619 return ERROR_OK;
620 }
621
622 COMMAND_HANDLER(handle_armv4_5_core_state_command)
623 {
624 struct target *target = get_current_target(CMD_CTX);
625 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
626
627 if (!is_arm(armv4_5))
628 {
629 command_print(CMD_CTX, "current target isn't an ARM");
630 return ERROR_FAIL;
631 }
632
633 if (CMD_ARGC > 0)
634 {
635 if (strcmp(CMD_ARGV[0], "arm") == 0)
636 {
637 armv4_5->core_state = ARMV4_5_STATE_ARM;
638 }
639 if (strcmp(CMD_ARGV[0], "thumb") == 0)
640 {
641 armv4_5->core_state = ARMV4_5_STATE_THUMB;
642 }
643 }
644
645 command_print(CMD_CTX, "core state: %s", armv4_5_state_strings[armv4_5->core_state]);
646
647 return ERROR_OK;
648 }
649
650 COMMAND_HANDLER(handle_armv4_5_disassemble_command)
651 {
652 int retval = ERROR_OK;
653 struct target *target = get_current_target(CMD_CTX);
654 struct arm *arm = target ? target_to_arm(target) : NULL;
655 uint32_t address;
656 int count = 1;
657 int thumb = 0;
658
659 if (!is_arm(arm)) {
660 command_print(CMD_CTX, "current target isn't an ARM");
661 return ERROR_FAIL;
662 }
663
664 switch (CMD_ARGC) {
665 case 3:
666 if (strcmp(CMD_ARGV[2], "thumb") != 0)
667 goto usage;
668 thumb = 1;
669 /* FALL THROUGH */
670 case 2:
671 COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
672 /* FALL THROUGH */
673 case 1:
674 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
675 if (address & 0x01) {
676 if (!thumb) {
677 command_print(CMD_CTX, "Disassemble as Thumb");
678 thumb = 1;
679 }
680 address &= ~1;
681 }
682 break;
683 default:
684 usage:
685 command_print(CMD_CTX,
686 "usage: arm disassemble <address> [<count> ['thumb']]");
687 count = 0;
688 retval = ERROR_FAIL;
689 }
690
691 while (count-- > 0) {
692 struct arm_instruction cur_instruction;
693
694 if (thumb) {
695 /* Always use Thumb2 disassembly for best handling
696 * of 32-bit BL/BLX, and to work with newer cores
697 * (some ARMv6, all ARMv7) that use Thumb2.
698 */
699 retval = thumb2_opcode(target, address,
700 &cur_instruction);
701 if (retval != ERROR_OK)
702 break;
703 } else {
704 uint32_t opcode;
705
706 retval = target_read_u32(target, address, &opcode);
707 if (retval != ERROR_OK)
708 break;
709 retval = arm_evaluate_opcode(opcode, address,
710 &cur_instruction) != ERROR_OK;
711 if (retval != ERROR_OK)
712 break;
713 }
714 command_print(CMD_CTX, "%s", cur_instruction.text);
715 address += cur_instruction.instruction_size;
716 }
717
718 return retval;
719 }
720
721 int armv4_5_register_commands(struct command_context *cmd_ctx)
722 {
723 struct command *armv4_5_cmd;
724
725 armv4_5_cmd = register_command(cmd_ctx, NULL, "arm",
726 NULL, COMMAND_ANY,
727 "generic ARM commands");
728
729 register_command(cmd_ctx, armv4_5_cmd, "reg",
730 handle_armv4_5_reg_command, COMMAND_EXEC,
731 "display ARM core registers");
732 register_command(cmd_ctx, armv4_5_cmd, "core_state",
733 handle_armv4_5_core_state_command, COMMAND_EXEC,
734 "display/change ARM core state <arm | thumb>");
735 register_command(cmd_ctx, armv4_5_cmd, "disassemble",
736 handle_armv4_5_disassemble_command, COMMAND_EXEC,
737 "disassemble instructions "
738 "<address> [<count> ['thumb']]");
739
740 return ERROR_OK;
741 }
742
743 int armv4_5_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
744 {
745 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
746 int i;
747
748 if (!is_arm_mode(armv4_5->core_mode))
749 return ERROR_FAIL;
750
751 *reg_list_size = 26;
752 *reg_list = malloc(sizeof(struct reg*) * (*reg_list_size));
753
754 for (i = 0; i < 16; i++)
755 {
756 (*reg_list)[i] = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i);
757 }
758
759 for (i = 16; i < 24; i++)
760 {
761 (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
762 }
763
764 (*reg_list)[24] = &arm_gdb_dummy_fps_reg;
765 (*reg_list)[25] = armv4_5->cpsr;
766
767 return ERROR_OK;
768 }
769
770 /* wait for execution to complete and check exit point */
771 static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info)
772 {
773 int retval;
774 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
775
776 if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
777 {
778 return retval;
779 }
780 if (target->state != TARGET_HALTED)
781 {
782 if ((retval = target_halt(target)) != ERROR_OK)
783 return retval;
784 if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK)
785 {
786 return retval;
787 }
788 return ERROR_TARGET_TIMEOUT;
789 }
790
791 /* fast exit: ARMv5+ code can use BKPT */
792 if (exit_point && buf_get_u32(armv4_5->core_cache->reg_list[15].value,
793 0, 32) != exit_point)
794 {
795 LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
796 buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
797 return ERROR_TARGET_TIMEOUT;
798 }
799
800 return ERROR_OK;
801 }
802
803 int armv4_5_run_algorithm_inner(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info, int (*run_it)(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info))
804 {
805 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
806 struct armv4_5_algorithm *armv4_5_algorithm_info = arch_info;
807 enum armv4_5_state core_state = armv4_5->core_state;
808 enum armv4_5_mode core_mode = armv4_5->core_mode;
809 uint32_t context[17];
810 uint32_t cpsr;
811 int exit_breakpoint_size = 0;
812 int i;
813 int retval = ERROR_OK;
814 LOG_DEBUG("Running algorithm");
815
816 if (armv4_5_algorithm_info->common_magic != ARMV4_5_COMMON_MAGIC)
817 {
818 LOG_ERROR("current target isn't an ARMV4/5 target");
819 return ERROR_TARGET_INVALID;
820 }
821
822 if (target->state != TARGET_HALTED)
823 {
824 LOG_WARNING("target not halted");
825 return ERROR_TARGET_NOT_HALTED;
826 }
827
828 if (!is_arm_mode(armv4_5->core_mode))
829 return ERROR_FAIL;
830
831 /* armv5 and later can terminate with BKPT instruction; less overhead */
832 if (!exit_point && armv4_5->is_armv4)
833 {
834 LOG_ERROR("ARMv4 target needs HW breakpoint location");
835 return ERROR_FAIL;
836 }
837
838 for (i = 0; i <= 16; i++)
839 {
840 struct reg *r;
841
842 r = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
843 armv4_5_algorithm_info->core_mode, i);
844 if (!r->valid)
845 armv4_5->read_core_reg(target, r, i,
846 armv4_5_algorithm_info->core_mode);
847 context[i] = buf_get_u32(r->value, 0, 32);
848 }
849 cpsr = buf_get_u32(armv4_5->cpsr->value, 0, 32);
850
851 for (i = 0; i < num_mem_params; i++)
852 {
853 if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
854 {
855 return retval;
856 }
857 }
858
859 for (i = 0; i < num_reg_params; i++)
860 {
861 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
862 if (!reg)
863 {
864 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
865 return ERROR_INVALID_ARGUMENTS;
866 }
867
868 if (reg->size != reg_params[i].size)
869 {
870 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
871 return ERROR_INVALID_ARGUMENTS;
872 }
873
874 if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
875 {
876 return retval;
877 }
878 }
879
880 armv4_5->core_state = armv4_5_algorithm_info->core_state;
881 if (armv4_5->core_state == ARMV4_5_STATE_ARM)
882 exit_breakpoint_size = 4;
883 else if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
884 exit_breakpoint_size = 2;
885 else
886 {
887 LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
888 return ERROR_INVALID_ARGUMENTS;
889 }
890
891 if (armv4_5_algorithm_info->core_mode != ARMV4_5_MODE_ANY)
892 {
893 LOG_DEBUG("setting core_mode: 0x%2.2x",
894 armv4_5_algorithm_info->core_mode);
895 buf_set_u32(armv4_5->cpsr->value, 0, 5,
896 armv4_5_algorithm_info->core_mode);
897 armv4_5->cpsr->dirty = 1;
898 armv4_5->cpsr->valid = 1;
899 }
900
901 /* terminate using a hardware or (ARMv5+) software breakpoint */
902 if (exit_point && (retval = breakpoint_add(target, exit_point,
903 exit_breakpoint_size, BKPT_HARD)) != ERROR_OK)
904 {
905 LOG_ERROR("can't add HW breakpoint to terminate algorithm");
906 return ERROR_TARGET_FAILURE;
907 }
908
909 if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
910 {
911 return retval;
912 }
913 int retvaltemp;
914 retval = run_it(target, exit_point, timeout_ms, arch_info);
915
916 if (exit_point)
917 breakpoint_remove(target, exit_point);
918
919 if (retval != ERROR_OK)
920 return retval;
921
922 for (i = 0; i < num_mem_params; i++)
923 {
924 if (mem_params[i].direction != PARAM_OUT)
925 if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
926 {
927 retval = retvaltemp;
928 }
929 }
930
931 for (i = 0; i < num_reg_params; i++)
932 {
933 if (reg_params[i].direction != PARAM_OUT)
934 {
935
936 struct reg *reg = register_get_by_name(armv4_5->core_cache, reg_params[i].reg_name, 0);
937 if (!reg)
938 {
939 LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
940 retval = ERROR_INVALID_ARGUMENTS;
941 continue;
942 }
943
944 if (reg->size != reg_params[i].size)
945 {
946 LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
947 retval = ERROR_INVALID_ARGUMENTS;
948 continue;
949 }
950
951 buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
952 }
953 }
954
955 for (i = 0; i <= 16; i++)
956 {
957 uint32_t regvalue;
958 regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32);
959 if (regvalue != context[i])
960 {
961 LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, context[i]);
962 buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
963 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
964 ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;
965 }
966 }
967 buf_set_u32(armv4_5->cpsr->value, 0, 32, cpsr);
968 armv4_5->cpsr->valid = 1;
969 armv4_5->cpsr->dirty = 1;
970
971 armv4_5->core_state = core_state;
972 armv4_5->core_mode = core_mode;
973
974 return retval;
975 }
976
977 int armv4_5_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info)
978 {
979 return armv4_5_run_algorithm_inner(target, num_mem_params, mem_params, num_reg_params, reg_params, entry_point, exit_point, timeout_ms, arch_info, armv4_5_run_algorithm_completion);
980 }
981
982 /**
983 * Runs ARM code in the target to calculate a CRC32 checksum.
984 *
985 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
986 */
987 int arm_checksum_memory(struct target *target,
988 uint32_t address, uint32_t count, uint32_t *checksum)
989 {
990 struct working_area *crc_algorithm;
991 struct armv4_5_algorithm armv4_5_info;
992 struct reg_param reg_params[2];
993 int retval;
994 uint32_t i;
995
996 static const uint32_t arm_crc_code[] = {
997 0xE1A02000, /* mov r2, r0 */
998 0xE3E00000, /* mov r0, #0xffffffff */
999 0xE1A03001, /* mov r3, r1 */
1000 0xE3A04000, /* mov r4, #0 */
1001 0xEA00000B, /* b ncomp */
1002 /* nbyte: */
1003 0xE7D21004, /* ldrb r1, [r2, r4] */
1004 0xE59F7030, /* ldr r7, CRC32XOR */
1005 0xE0200C01, /* eor r0, r0, r1, asl 24 */
1006 0xE3A05000, /* mov r5, #0 */
1007 /* loop: */
1008 0xE3500000, /* cmp r0, #0 */
1009 0xE1A06080, /* mov r6, r0, asl #1 */
1010 0xE2855001, /* add r5, r5, #1 */
1011 0xE1A00006, /* mov r0, r6 */
1012 0xB0260007, /* eorlt r0, r6, r7 */
1013 0xE3550008, /* cmp r5, #8 */
1014 0x1AFFFFF8, /* bne loop */
1015 0xE2844001, /* add r4, r4, #1 */
1016 /* ncomp: */
1017 0xE1540003, /* cmp r4, r3 */
1018 0x1AFFFFF1, /* bne nbyte */
1019 /* end: */
1020 0xEAFFFFFE, /* b end */
1021 /* CRC32XOR: */
1022 0x04C11DB7 /* .word 0x04C11DB7 */
1023 };
1024
1025 retval = target_alloc_working_area(target,
1026 sizeof(arm_crc_code), &crc_algorithm);
1027 if (retval != ERROR_OK)
1028 return retval;
1029
1030 /* convert code into a buffer in target endianness */
1031 for (i = 0; i < ARRAY_SIZE(arm_crc_code); i++) {
1032 retval = target_write_u32(target,
1033 crc_algorithm->address + i * sizeof(uint32_t),
1034 arm_crc_code[i]);
1035 if (retval != ERROR_OK)
1036 return retval;
1037 }
1038
1039 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1040 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1041 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1042
1043 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT);
1044 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1045
1046 buf_set_u32(reg_params[0].value, 0, 32, address);
1047 buf_set_u32(reg_params[1].value, 0, 32, count);
1048
1049 /* 20 second timeout/megabyte */
1050 int timeout = 20000 * (1 + (count / (1024 * 1024)));
1051
1052 retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
1053 crc_algorithm->address,
1054 crc_algorithm->address + sizeof(arm_crc_code) - 8,
1055 timeout, &armv4_5_info);
1056 if (retval != ERROR_OK) {
1057 LOG_ERROR("error executing ARM crc algorithm");
1058 destroy_reg_param(&reg_params[0]);
1059 destroy_reg_param(&reg_params[1]);
1060 target_free_working_area(target, crc_algorithm);
1061 return retval;
1062 }
1063
1064 *checksum = buf_get_u32(reg_params[0].value, 0, 32);
1065
1066 destroy_reg_param(&reg_params[0]);
1067 destroy_reg_param(&reg_params[1]);
1068
1069 target_free_working_area(target, crc_algorithm);
1070
1071 return ERROR_OK;
1072 }
1073
1074 /**
1075 * Runs ARM code in the target to check whether a memory block holds
1076 * all ones. NOR flash which has been erased, and thus may be written,
1077 * holds all ones.
1078 *
1079 * \todo On ARMv5+, rely on BKPT termination for reduced overhead.
1080 */
1081 int arm_blank_check_memory(struct target *target,
1082 uint32_t address, uint32_t count, uint32_t *blank)
1083 {
1084 struct working_area *check_algorithm;
1085 struct reg_param reg_params[3];
1086 struct armv4_5_algorithm armv4_5_info;
1087 int retval;
1088 uint32_t i;
1089
1090 static const uint32_t check_code[] = {
1091 /* loop: */
1092 0xe4d03001, /* ldrb r3, [r0], #1 */
1093 0xe0022003, /* and r2, r2, r3 */
1094 0xe2511001, /* subs r1, r1, #1 */
1095 0x1afffffb, /* bne loop */
1096 /* end: */
1097 0xeafffffe /* b end */
1098 };
1099
1100 /* make sure we have a working area */
1101 retval = target_alloc_working_area(target,
1102 sizeof(check_code), &check_algorithm);
1103 if (retval != ERROR_OK)
1104 return retval;
1105
1106 /* convert code into a buffer in target endianness */
1107 for (i = 0; i < ARRAY_SIZE(check_code); i++) {
1108 retval = target_write_u32(target,
1109 check_algorithm->address
1110 + i * sizeof(uint32_t),
1111 check_code[i]);
1112 if (retval != ERROR_OK)
1113 return retval;
1114 }
1115
1116 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
1117 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
1118 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
1119
1120 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
1121 buf_set_u32(reg_params[0].value, 0, 32, address);
1122
1123 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
1124 buf_set_u32(reg_params[1].value, 0, 32, count);
1125
1126 init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
1127 buf_set_u32(reg_params[2].value, 0, 32, 0xff);
1128
1129 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
1130 check_algorithm->address,
1131 check_algorithm->address + sizeof(check_code) - 4,
1132 10000, &armv4_5_info);
1133 if (retval != ERROR_OK) {
1134 destroy_reg_param(&reg_params[0]);
1135 destroy_reg_param(&reg_params[1]);
1136 destroy_reg_param(&reg_params[2]);
1137 target_free_working_area(target, check_algorithm);
1138 return retval;
1139 }
1140
1141 *blank = buf_get_u32(reg_params[2].value, 0, 32);
1142
1143 destroy_reg_param(&reg_params[0]);
1144 destroy_reg_param(&reg_params[1]);
1145 destroy_reg_param(&reg_params[2]);
1146
1147 target_free_working_area(target, check_algorithm);
1148
1149 return ERROR_OK;
1150 }
1151
1152 static int arm_full_context(struct target *target)
1153 {
1154 struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target);
1155 unsigned num_regs = armv4_5->core_cache->num_regs;
1156 struct reg *reg = armv4_5->core_cache->reg_list;
1157 int retval = ERROR_OK;
1158
1159 for (; num_regs && retval == ERROR_OK; num_regs--, reg++) {
1160 if (reg->valid)
1161 continue;
1162 retval = armv4_5_get_core_reg(reg);
1163 }
1164 return retval;
1165 }
1166
1167 int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5)
1168 {
1169 target->arch_info = armv4_5;
1170
1171 armv4_5->common_magic = ARMV4_5_COMMON_MAGIC;
1172 armv4_5->core_state = ARMV4_5_STATE_ARM;
1173 armv4_5->core_mode = ARMV4_5_MODE_USR;
1174
1175 /* core_type may be overridden by subtype logic */
1176 armv4_5->core_type = ARMV4_5_MODE_ANY;
1177
1178 /* default full_context() has no core-specific optimizations */
1179 if (!armv4_5->full_context && armv4_5->read_core_reg)
1180 armv4_5->full_context = arm_full_context;
1181
1182 return ERROR_OK;
1183 }

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)