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

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)