jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / target / arm_dpm.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /*
4 * Copyright (C) 2009 by David Brownell
5 */
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include "arm.h"
12 #include "arm_dpm.h"
13 #include "armv8_dpm.h"
14 #include <jtag/jtag.h>
15 #include "register.h"
16 #include "breakpoints.h"
17 #include "target_type.h"
18 #include "arm_opcodes.h"
19
20
21 /**
22 * @file
23 * Implements various ARM DPM operations using architectural debug registers.
24 * These routines layer over core-specific communication methods to cope with
25 * implementation differences between cores like ARM1136 and Cortex-A8.
26 *
27 * The "Debug Programmers' Model" (DPM) for ARMv6 and ARMv7 is defined by
28 * Part C (Debug Architecture) of the ARM Architecture Reference Manual,
29 * ARMv7-A and ARMv7-R edition (ARM DDI 0406B). In OpenOCD, DPM operations
30 * are abstracted through internal programming interfaces to share code and
31 * to minimize needless differences in debug behavior between cores.
32 */
33
34 /*----------------------------------------------------------------------*/
35
36 /*
37 * Coprocessor support
38 */
39
40 /* Read coprocessor */
41 static int dpm_mrc(struct target *target, int cpnum,
42 uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
43 uint32_t *value)
44 {
45 struct arm *arm = target_to_arm(target);
46 struct arm_dpm *dpm = arm->dpm;
47 int retval;
48
49 retval = dpm->prepare(dpm);
50 if (retval != ERROR_OK)
51 return retval;
52
53 LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum,
54 (int) op1, (int) crn,
55 (int) crm, (int) op2);
56
57 /* read coprocessor register into R0; return via DCC */
58 retval = dpm->instr_read_data_r0(dpm,
59 ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2),
60 value);
61
62 /* (void) */ dpm->finish(dpm);
63 return retval;
64 }
65
66 static int dpm_mrrc(struct target *target, int cpnum,
67 uint32_t op, uint32_t crm, uint64_t *value)
68 {
69 struct arm *arm = target_to_arm(target);
70 struct arm_dpm *dpm = arm->dpm;
71 int retval;
72
73 retval = dpm->prepare(dpm);
74 if (retval != ERROR_OK)
75 return retval;
76
77 LOG_DEBUG("MRRC p%d, %d, r0, r1, c%d", cpnum,
78 (int)op, (int)crm);
79
80 /* read coprocessor register into R0, R1; return via DCC */
81 retval = dpm->instr_read_data_r0_r1(dpm,
82 ARMV5_T_MRRC(cpnum, op, 0, 1, crm),
83 value);
84
85 /* (void) */ dpm->finish(dpm);
86 return retval;
87 }
88
89 static int dpm_mcr(struct target *target, int cpnum,
90 uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm,
91 uint32_t value)
92 {
93 struct arm *arm = target_to_arm(target);
94 struct arm_dpm *dpm = arm->dpm;
95 int retval;
96
97 retval = dpm->prepare(dpm);
98 if (retval != ERROR_OK)
99 return retval;
100
101 LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum,
102 (int) op1, (int) crn,
103 (int) crm, (int) op2);
104
105 /* read DCC into r0; then write coprocessor register from R0 */
106 retval = dpm->instr_write_data_r0(dpm,
107 ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2),
108 value);
109
110 /* (void) */ dpm->finish(dpm);
111 return retval;
112 }
113
114 static int dpm_mcrr(struct target *target, int cpnum,
115 uint32_t op, uint32_t crm, uint64_t value)
116 {
117 struct arm *arm = target_to_arm(target);
118 struct arm_dpm *dpm = arm->dpm;
119 int retval;
120
121 retval = dpm->prepare(dpm);
122 if (retval != ERROR_OK)
123 return retval;
124
125 LOG_DEBUG("MCRR p%d, %d, r0, r1, c%d", cpnum,
126 (int)op, (int)crm);
127
128 /* read DCC into r0, r1; then write coprocessor register from R0, R1 */
129 retval = dpm->instr_write_data_r0_r1(dpm,
130 ARMV5_T_MCRR(cpnum, op, 0, 1, crm), value);
131
132 /* (void) */ dpm->finish(dpm);
133
134 return retval;
135 }
136
137 /*----------------------------------------------------------------------*/
138
139 /*
140 * Register access utilities
141 */
142
143 /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one.
144 * Routines *must* restore the original mode before returning!!
145 */
146 int arm_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
147 {
148 int retval;
149 uint32_t cpsr;
150
151 /* restore previous mode */
152 if (mode == ARM_MODE_ANY)
153 cpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32);
154
155 /* else force to the specified mode */
156 else
157 cpsr = mode;
158
159 retval = dpm->instr_write_data_r0(dpm, ARMV4_5_MSR_GP(0, 0xf, 0), cpsr);
160 if (retval != ERROR_OK)
161 return retval;
162
163 if (dpm->instr_cpsr_sync)
164 retval = dpm->instr_cpsr_sync(dpm);
165
166 return retval;
167 }
168
169 /* Read 64bit VFP registers */
170 static int dpm_read_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
171 {
172 int retval = ERROR_FAIL;
173 uint32_t value_r0, value_r1;
174
175 switch (regnum) {
176 case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:
177 /* move from double word register to r0:r1: "vmov r0, r1, vm"
178 * then read r0 via dcc
179 */
180 retval = dpm->instr_read_data_r0(dpm,
181 ARMV4_5_VMOV(1, 1, 0, ((regnum - ARM_VFP_V3_D0) >> 4),
182 ((regnum - ARM_VFP_V3_D0) & 0xf)), &value_r0);
183 if (retval != ERROR_OK)
184 break;
185
186 /* read r1 via dcc */
187 retval = dpm->instr_read_data_dcc(dpm,
188 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
189 &value_r1);
190 break;
191 default:
192
193 break;
194 }
195
196 if (retval == ERROR_OK) {
197 buf_set_u32(r->value, 0, 32, value_r0);
198 buf_set_u32(r->value + 4, 0, 32, value_r1);
199 r->valid = true;
200 r->dirty = false;
201 LOG_DEBUG("READ: %s, %8.8x, %8.8x", r->name,
202 (unsigned) value_r0, (unsigned) value_r1);
203 }
204
205 return retval;
206 }
207
208 /* just read the register -- rely on the core mode being right */
209 int arm_dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
210 {
211 uint32_t value;
212 int retval;
213
214 switch (regnum) {
215 case 0 ... 14:
216 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
217 retval = dpm->instr_read_data_dcc(dpm,
218 ARMV4_5_MCR(14, 0, regnum, 0, 5, 0),
219 &value);
220 break;
221 case 15:/* PC
222 * "MOV r0, pc"; then return via DCC */
223 retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value);
224
225 /* NOTE: this seems like a slightly awkward place to update
226 * this value ... but if the PC gets written (the only way
227 * to change what we compute), the arch spec says subsequent
228 * reads return values which are "unpredictable". So this
229 * is always right except in those broken-by-intent cases.
230 */
231 switch (dpm->arm->core_state) {
232 case ARM_STATE_ARM:
233 value -= 8;
234 break;
235 case ARM_STATE_THUMB:
236 case ARM_STATE_THUMB_EE:
237 value -= 4;
238 break;
239 case ARM_STATE_JAZELLE:
240 /* core-specific ... ? */
241 LOG_WARNING("Jazelle PC adjustment unknown");
242 break;
243 default:
244 LOG_WARNING("unknown core state");
245 break;
246 }
247 break;
248 case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:
249 return dpm_read_reg_u64(dpm, r, regnum);
250 case ARM_VFP_V3_FPSCR:
251 /* "VMRS r0, FPSCR"; then return via DCC */
252 retval = dpm->instr_read_data_r0(dpm,
253 ARMV4_5_VMRS(0), &value);
254 break;
255 default:
256 /* 16: "MRS r0, CPSR"; then return via DCC
257 * 17: "MRS r0, SPSR"; then return via DCC
258 */
259 retval = dpm->instr_read_data_r0(dpm,
260 ARMV4_5_MRS(0, regnum & 1),
261 &value);
262 break;
263 }
264
265 if (retval == ERROR_OK) {
266 buf_set_u32(r->value, 0, 32, value);
267 r->valid = true;
268 r->dirty = false;
269 LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned) value);
270 }
271
272 return retval;
273 }
274
275 /* Write 64bit VFP registers */
276 static int dpm_write_reg_u64(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
277 {
278 int retval = ERROR_FAIL;
279 uint32_t value_r0 = buf_get_u32(r->value, 0, 32);
280 uint32_t value_r1 = buf_get_u32(r->value + 4, 0, 32);
281
282 switch (regnum) {
283 case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:
284 /* write value_r1 to r1 via dcc */
285 retval = dpm->instr_write_data_dcc(dpm,
286 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
287 value_r1);
288 if (retval != ERROR_OK)
289 break;
290
291 /* write value_r0 to r0 via dcc then,
292 * move to double word register from r0:r1: "vmov vm, r0, r1"
293 */
294 retval = dpm->instr_write_data_r0(dpm,
295 ARMV4_5_VMOV(0, 1, 0, ((regnum - ARM_VFP_V3_D0) >> 4),
296 ((regnum - ARM_VFP_V3_D0) & 0xf)), value_r0);
297 break;
298 default:
299
300 break;
301 }
302
303 if (retval == ERROR_OK) {
304 r->dirty = false;
305 LOG_DEBUG("WRITE: %s, %8.8x, %8.8x", r->name,
306 (unsigned) value_r0, (unsigned) value_r1);
307 }
308
309 return retval;
310 }
311
312 /* just write the register -- rely on the core mode being right */
313 static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
314 {
315 int retval;
316 uint32_t value = buf_get_u32(r->value, 0, 32);
317
318 switch (regnum) {
319 case 0 ... 14:
320 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
321 retval = dpm->instr_write_data_dcc(dpm,
322 ARMV4_5_MRC(14, 0, regnum, 0, 5, 0),
323 value);
324 break;
325 case 15:/* PC
326 * read r0 from DCC; then "MOV pc, r0" */
327 retval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value);
328 break;
329 case ARM_VFP_V3_D0 ... ARM_VFP_V3_D31:
330 return dpm_write_reg_u64(dpm, r, regnum);
331 case ARM_VFP_V3_FPSCR:
332 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
333 retval = dpm->instr_write_data_r0(dpm,
334 ARMV4_5_VMSR(0), value);
335 break;
336 default:
337 /* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf"
338 * 17: read r0 from DCC, then "MSR r0, SPSR_cxsf"
339 */
340 retval = dpm->instr_write_data_r0(dpm,
341 ARMV4_5_MSR_GP(0, 0xf, regnum & 1),
342 value);
343 if (retval != ERROR_OK)
344 return retval;
345
346 if (regnum == 16 && dpm->instr_cpsr_sync)
347 retval = dpm->instr_cpsr_sync(dpm);
348
349 break;
350 }
351
352 if (retval == ERROR_OK) {
353 r->dirty = false;
354 LOG_DEBUG("WRITE: %s, %8.8x", r->name, (unsigned) value);
355 }
356
357 return retval;
358 }
359
360 /**
361 * Write to program counter and switch the core state (arm/thumb) according to
362 * the address.
363 */
364 static int dpm_write_pc_core_state(struct arm_dpm *dpm, struct reg *r)
365 {
366 uint32_t value = buf_get_u32(r->value, 0, 32);
367
368 /* read r0 from DCC; then "BX r0" */
369 return dpm->instr_write_data_r0(dpm, ARMV4_5_BX(0), value);
370 }
371
372 /**
373 * Read basic registers of the current context: R0 to R15, and CPSR;
374 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
375 * In normal operation this is called on entry to halting debug state,
376 * possibly after some other operations supporting restore of debug state
377 * or making sure the CPU is fully idle (drain write buffer, etc).
378 */
379 int arm_dpm_read_current_registers(struct arm_dpm *dpm)
380 {
381 struct arm *arm = dpm->arm;
382 uint32_t cpsr;
383 int retval;
384 struct reg *r;
385
386 retval = dpm->prepare(dpm);
387 if (retval != ERROR_OK)
388 return retval;
389
390 /* read R0 and R1 first (it's used for scratch), then CPSR */
391 for (unsigned i = 0; i < 2; i++) {
392 r = arm->core_cache->reg_list + i;
393 if (!r->valid) {
394 retval = arm_dpm_read_reg(dpm, r, i);
395 if (retval != ERROR_OK)
396 goto fail;
397 }
398 r->dirty = true;
399 }
400
401 retval = dpm->instr_read_data_r0(dpm, ARMV4_5_MRS(0, 0), &cpsr);
402 if (retval != ERROR_OK)
403 goto fail;
404
405 /* update core mode and state, plus shadow mapping for R8..R14 */
406 arm_set_cpsr(arm, cpsr);
407
408 /* REVISIT we can probably avoid reading R1..R14, saving time... */
409 for (unsigned i = 2; i < 16; i++) {
410 r = arm_reg_current(arm, i);
411 if (r->valid)
412 continue;
413
414 retval = arm_dpm_read_reg(dpm, r, i);
415 if (retval != ERROR_OK)
416 goto fail;
417 }
418
419 /* NOTE: SPSR ignored (if it's even relevant). */
420
421 /* REVISIT the debugger can trigger various exceptions. See the
422 * ARMv7A architecture spec, section C5.7, for more info about
423 * what defenses are needed; v6 debug has the most issues.
424 */
425
426 fail:
427 /* (void) */ dpm->finish(dpm);
428 return retval;
429 }
430
431 /* Avoid needless I/O ... leave breakpoints and watchpoints alone
432 * unless they're removed, or need updating because of single-stepping
433 * or running debugger code.
434 */
435 static int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,
436 struct dpm_bpwp *xp, bool *set_p)
437 {
438 int retval = ERROR_OK;
439 bool disable;
440
441 if (!set_p) {
442 if (!xp->dirty)
443 goto done;
444 xp->dirty = false;
445 /* removed or startup; we must disable it */
446 disable = true;
447 } else if (bpwp) {
448 if (!xp->dirty)
449 goto done;
450 /* disabled, but we must set it */
451 xp->dirty = disable = false;
452 *set_p = true;
453 } else {
454 if (!*set_p)
455 goto done;
456 /* set, but we must temporarily disable it */
457 xp->dirty = disable = true;
458 *set_p = false;
459 }
460
461 if (disable)
462 retval = dpm->bpwp_disable(dpm, xp->number);
463 else
464 retval = dpm->bpwp_enable(dpm, xp->number,
465 xp->address, xp->control);
466
467 if (retval != ERROR_OK)
468 LOG_ERROR("%s: can't %s HW %spoint %d",
469 disable ? "disable" : "enable",
470 target_name(dpm->arm->target),
471 (xp->number < 16) ? "break" : "watch",
472 xp->number & 0xf);
473 done:
474 return retval;
475 }
476
477 static int dpm_add_breakpoint(struct target *target, struct breakpoint *bp);
478
479 /**
480 * Writes all modified core registers for all processor modes. In normal
481 * operation this is called on exit from halting debug state.
482 *
483 * @param dpm: represents the processor
484 * @param bpwp: true ensures breakpoints and watchpoints are set,
485 * false ensures they are cleared
486 */
487 int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
488 {
489 struct arm *arm = dpm->arm;
490 struct reg_cache *cache = arm->core_cache;
491 int retval;
492 bool did_write;
493
494 retval = dpm->prepare(dpm);
495 if (retval != ERROR_OK)
496 goto done;
497
498 /* If we're managing hardware breakpoints for this core, enable
499 * or disable them as requested.
500 *
501 * REVISIT We don't yet manage them for ANY cores. Eventually
502 * we should be able to assume we handle them; but until then,
503 * cope with the hand-crafted breakpoint code.
504 */
505 if (arm->target->type->add_breakpoint == dpm_add_breakpoint) {
506 for (unsigned i = 0; i < dpm->nbp; i++) {
507 struct dpm_bp *dbp = dpm->dbp + i;
508 struct breakpoint *bp = dbp->bp;
509
510 retval = dpm_maybe_update_bpwp(dpm, bpwp, &dbp->bpwp,
511 bp ? &bp->is_set : NULL);
512 if (retval != ERROR_OK)
513 goto done;
514 }
515 }
516
517 /* enable/disable watchpoints */
518 for (unsigned i = 0; i < dpm->nwp; i++) {
519 struct dpm_wp *dwp = dpm->dwp + i;
520 struct watchpoint *wp = dwp->wp;
521
522 retval = dpm_maybe_update_bpwp(dpm, bpwp, &dwp->bpwp,
523 wp ? &wp->is_set : NULL);
524 if (retval != ERROR_OK)
525 goto done;
526 }
527
528 /* NOTE: writes to breakpoint and watchpoint registers might
529 * be queued, and need (efficient/batched) flushing later.
530 */
531
532 /* Scan the registers until we find one that's both dirty and
533 * eligible for flushing. Flush that and everything else that
534 * shares the same core mode setting. Typically this won't
535 * actually find anything to do...
536 */
537 do {
538 enum arm_mode mode = ARM_MODE_ANY;
539
540 did_write = false;
541
542 /* check everything except our scratch registers R0 and R1 */
543 for (unsigned i = 2; i < cache->num_regs; i++) {
544 struct arm_reg *r;
545 unsigned regnum;
546
547 /* also skip PC, CPSR, and non-dirty */
548 if (i == 15)
549 continue;
550 if (arm->cpsr == cache->reg_list + i)
551 continue;
552 if (!cache->reg_list[i].exist || !cache->reg_list[i].dirty)
553 continue;
554
555 r = cache->reg_list[i].arch_info;
556 regnum = r->num;
557
558 /* may need to pick and set a mode */
559 if (!did_write) {
560 enum arm_mode tmode;
561
562 did_write = true;
563 mode = tmode = r->mode;
564
565 /* cope with special cases */
566 switch (regnum) {
567 case 8 ... 12:
568 /* r8..r12 "anything but FIQ" case;
569 * we "know" core mode is accurate
570 * since we haven't changed it yet
571 */
572 if (arm->core_mode == ARM_MODE_FIQ
573 && ARM_MODE_ANY
574 != mode)
575 tmode = ARM_MODE_USR;
576 break;
577 case 16:
578 /* SPSR */
579 regnum++;
580 break;
581 }
582
583 /* REVISIT error checks */
584 if (tmode != ARM_MODE_ANY) {
585 retval = arm_dpm_modeswitch(dpm, tmode);
586 if (retval != ERROR_OK)
587 goto done;
588 }
589 }
590 if (r->mode != mode)
591 continue;
592
593 retval = dpm_write_reg(dpm,
594 &cache->reg_list[i],
595 regnum);
596 if (retval != ERROR_OK)
597 goto done;
598 }
599
600 } while (did_write);
601
602 /* Restore original CPSR ... assuming either that we changed it,
603 * or it's dirty. Must write PC to ensure the return address is
604 * defined, and must not write it before CPSR.
605 */
606 retval = arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
607 if (retval != ERROR_OK)
608 goto done;
609 arm->cpsr->dirty = false;
610
611 /* restore the PC, make sure to also switch the core state
612 * to whatever it was set to with "arm core_state" command.
613 * target code will have set PC to an appropriate resume address.
614 */
615 retval = dpm_write_pc_core_state(dpm, arm->pc);
616 if (retval != ERROR_OK)
617 goto done;
618 /* on Cortex-A5 (as found on NXP VF610 SoC), BX instruction
619 * executed in debug state doesn't appear to set the PC,
620 * explicitly set it with a "MOV pc, r0". This doesn't influence
621 * CPSR on Cortex-A9 so it should be OK. Maybe due to different
622 * debug version?
623 */
624 retval = dpm_write_reg(dpm, arm->pc, 15);
625 if (retval != ERROR_OK)
626 goto done;
627 arm->pc->dirty = false;
628
629 /* flush R0 and R1 (our scratch registers) */
630 for (unsigned i = 0; i < 2; i++) {
631 retval = dpm_write_reg(dpm, &cache->reg_list[i], i);
632 if (retval != ERROR_OK)
633 goto done;
634 cache->reg_list[i].dirty = false;
635 }
636
637 /* (void) */ dpm->finish(dpm);
638 done:
639 return retval;
640 }
641
642 /* Returns ARM_MODE_ANY or temporary mode to use while reading the
643 * specified register ... works around flakiness from ARM core calls.
644 * Caller already filtered out SPSR access; mode is never MODE_SYS
645 * or MODE_ANY.
646 */
647 static enum arm_mode dpm_mapmode(struct arm *arm,
648 unsigned num, enum arm_mode mode)
649 {
650 enum arm_mode amode = arm->core_mode;
651
652 /* don't switch if the mode is already correct */
653 if (amode == ARM_MODE_SYS)
654 amode = ARM_MODE_USR;
655 if (mode == amode)
656 return ARM_MODE_ANY;
657
658 switch (num) {
659 /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */
660 case 0 ... 7:
661 case 15:
662 case 16:
663 break;
664 /* r8..r12 aren't shadowed for anything except FIQ */
665 case 8 ... 12:
666 if (mode == ARM_MODE_FIQ)
667 return mode;
668 break;
669 /* r13/sp, and r14/lr are always shadowed */
670 case 13:
671 case 14:
672 case ARM_VFP_V3_D0 ... ARM_VFP_V3_FPSCR:
673 return mode;
674 default:
675 LOG_WARNING("invalid register #%u", num);
676 break;
677 }
678 return ARM_MODE_ANY;
679 }
680
681
682 /*
683 * Standard ARM register accessors ... there are three methods
684 * in "struct arm", to support individual read/write and bulk read
685 * of registers.
686 */
687
688 static int arm_dpm_read_core_reg(struct target *target, struct reg *r,
689 int regnum, enum arm_mode mode)
690 {
691 struct arm_dpm *dpm = target_to_arm(target)->dpm;
692 int retval;
693
694 if (regnum < 0 || (regnum > 16 && regnum < ARM_VFP_V3_D0) ||
695 (regnum > ARM_VFP_V3_FPSCR))
696 return ERROR_COMMAND_SYNTAX_ERROR;
697
698 if (regnum == 16) {
699 if (mode != ARM_MODE_ANY)
700 regnum = 17;
701 } else
702 mode = dpm_mapmode(dpm->arm, regnum, mode);
703
704 /* REVISIT what happens if we try to read SPSR in a core mode
705 * which has no such register?
706 */
707
708 retval = dpm->prepare(dpm);
709 if (retval != ERROR_OK)
710 return retval;
711
712 if (mode != ARM_MODE_ANY) {
713 retval = arm_dpm_modeswitch(dpm, mode);
714 if (retval != ERROR_OK)
715 goto fail;
716 }
717
718 retval = arm_dpm_read_reg(dpm, r, regnum);
719 if (retval != ERROR_OK)
720 goto fail;
721 /* always clean up, regardless of error */
722
723 if (mode != ARM_MODE_ANY)
724 /* (void) */ arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
725
726 fail:
727 /* (void) */ dpm->finish(dpm);
728 return retval;
729 }
730
731 static int arm_dpm_write_core_reg(struct target *target, struct reg *r,
732 int regnum, enum arm_mode mode, uint8_t *value)
733 {
734 struct arm_dpm *dpm = target_to_arm(target)->dpm;
735 int retval;
736
737
738 if (regnum < 0 || (regnum > 16 && regnum < ARM_VFP_V3_D0) ||
739 (regnum > ARM_VFP_V3_FPSCR))
740 return ERROR_COMMAND_SYNTAX_ERROR;
741
742 if (regnum == 16) {
743 if (mode != ARM_MODE_ANY)
744 regnum = 17;
745 } else
746 mode = dpm_mapmode(dpm->arm, regnum, mode);
747
748 /* REVISIT what happens if we try to write SPSR in a core mode
749 * which has no such register?
750 */
751
752 retval = dpm->prepare(dpm);
753 if (retval != ERROR_OK)
754 return retval;
755
756 if (mode != ARM_MODE_ANY) {
757 retval = arm_dpm_modeswitch(dpm, mode);
758 if (retval != ERROR_OK)
759 goto fail;
760 }
761
762 retval = dpm_write_reg(dpm, r, regnum);
763 /* always clean up, regardless of error */
764
765 if (mode != ARM_MODE_ANY)
766 /* (void) */ arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
767
768 fail:
769 /* (void) */ dpm->finish(dpm);
770 return retval;
771 }
772
773 static int arm_dpm_full_context(struct target *target)
774 {
775 struct arm *arm = target_to_arm(target);
776 struct arm_dpm *dpm = arm->dpm;
777 struct reg_cache *cache = arm->core_cache;
778 int retval;
779 bool did_read;
780
781 retval = dpm->prepare(dpm);
782 if (retval != ERROR_OK)
783 goto done;
784
785 do {
786 enum arm_mode mode = ARM_MODE_ANY;
787
788 did_read = false;
789
790 /* We "know" arm_dpm_read_current_registers() was called so
791 * the unmapped registers (R0..R7, PC, AND CPSR) and some
792 * view of R8..R14 are current. We also "know" oddities of
793 * register mapping: special cases for R8..R12 and SPSR.
794 *
795 * Pick some mode with unread registers and read them all.
796 * Repeat until done.
797 */
798 for (unsigned i = 0; i < cache->num_regs; i++) {
799 struct arm_reg *r;
800
801 if (!cache->reg_list[i].exist || cache->reg_list[i].valid)
802 continue;
803 r = cache->reg_list[i].arch_info;
804
805 /* may need to pick a mode and set CPSR */
806 if (!did_read) {
807 did_read = true;
808 mode = r->mode;
809
810 /* For regular (ARM_MODE_ANY) R8..R12
811 * in case we've entered debug state
812 * in FIQ mode we need to patch mode.
813 */
814 if (mode != ARM_MODE_ANY)
815 retval = arm_dpm_modeswitch(dpm, mode);
816 else
817 retval = arm_dpm_modeswitch(dpm, ARM_MODE_USR);
818
819 if (retval != ERROR_OK)
820 goto done;
821 }
822 if (r->mode != mode)
823 continue;
824
825 /* CPSR was read, so "R16" must mean SPSR */
826 retval = arm_dpm_read_reg(dpm,
827 &cache->reg_list[i],
828 (r->num == 16) ? 17 : r->num);
829 if (retval != ERROR_OK)
830 goto done;
831 }
832
833 } while (did_read);
834
835 retval = arm_dpm_modeswitch(dpm, ARM_MODE_ANY);
836 /* (void) */ dpm->finish(dpm);
837 done:
838 return retval;
839 }
840
841
842 /*----------------------------------------------------------------------*/
843
844 /*
845 * Breakpoint and Watchpoint support.
846 *
847 * Hardware {break,watch}points are usually left active, to minimize
848 * debug entry/exit costs. When they are set or cleared, it's done in
849 * batches. Also, DPM-conformant hardware can update debug registers
850 * regardless of whether the CPU is running or halted ... though that
851 * fact isn't currently leveraged.
852 */
853
854 static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,
855 uint32_t addr, uint32_t length)
856 {
857 uint32_t control;
858
859 control = (1 << 0) /* enable */
860 | (3 << 1); /* both user and privileged access */
861
862 /* Match 1, 2, or all 4 byte addresses in this word.
863 *
864 * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP.
865 * Support larger length, when addr is suitably aligned. In
866 * particular, allow watchpoints on 8 byte "double" values.
867 *
868 * REVISIT allow watchpoints on unaligned 2-bit values; and on
869 * v7 hardware, unaligned 4-byte ones too.
870 */
871 switch (length) {
872 case 1:
873 control |= (1 << (addr & 3)) << 5;
874 break;
875 case 2:
876 /* require 2-byte alignment */
877 if (!(addr & 1)) {
878 control |= (3 << (addr & 2)) << 5;
879 break;
880 }
881 /* FALL THROUGH */
882 case 4:
883 /* require 4-byte alignment */
884 if (!(addr & 3)) {
885 control |= 0xf << 5;
886 break;
887 }
888 /* FALL THROUGH */
889 default:
890 LOG_ERROR("unsupported {break,watch}point length/alignment");
891 return ERROR_COMMAND_SYNTAX_ERROR;
892 }
893
894 /* other shared control bits:
895 * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
896 * bit 20 == 0 ... not linked to a context ID
897 * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
898 */
899
900 xp->address = addr & ~3;
901 xp->control = control;
902 xp->dirty = true;
903
904 LOG_DEBUG("BPWP: addr %8.8" PRIx32 ", control %" PRIx32 ", number %d",
905 xp->address, control, xp->number);
906
907 /* hardware is updated in write_dirty_registers() */
908 return ERROR_OK;
909 }
910
911 static int dpm_add_breakpoint(struct target *target, struct breakpoint *bp)
912 {
913 struct arm *arm = target_to_arm(target);
914 struct arm_dpm *dpm = arm->dpm;
915 int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
916
917 if (bp->length < 2)
918 return ERROR_COMMAND_SYNTAX_ERROR;
919 if (!dpm->bpwp_enable)
920 return retval;
921
922 /* FIXME we need a generic solution for software breakpoints. */
923 if (bp->type == BKPT_SOFT)
924 LOG_DEBUG("using HW bkpt, not SW...");
925
926 for (unsigned i = 0; i < dpm->nbp; i++) {
927 if (!dpm->dbp[i].bp) {
928 retval = dpm_bpwp_setup(dpm, &dpm->dbp[i].bpwp,
929 bp->address, bp->length);
930 if (retval == ERROR_OK)
931 dpm->dbp[i].bp = bp;
932 break;
933 }
934 }
935
936 return retval;
937 }
938
939 static int dpm_remove_breakpoint(struct target *target, struct breakpoint *bp)
940 {
941 struct arm *arm = target_to_arm(target);
942 struct arm_dpm *dpm = arm->dpm;
943 int retval = ERROR_COMMAND_SYNTAX_ERROR;
944
945 for (unsigned i = 0; i < dpm->nbp; i++) {
946 if (dpm->dbp[i].bp == bp) {
947 dpm->dbp[i].bp = NULL;
948 dpm->dbp[i].bpwp.dirty = true;
949
950 /* hardware is updated in write_dirty_registers() */
951 retval = ERROR_OK;
952 break;
953 }
954 }
955
956 return retval;
957 }
958
959 static int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t,
960 struct watchpoint *wp)
961 {
962 int retval;
963 struct dpm_wp *dwp = dpm->dwp + index_t;
964 uint32_t control;
965
966 /* this hardware doesn't support data value matching or masking */
967 if (wp->mask != WATCHPOINT_IGNORE_DATA_VALUE_MASK) {
968 LOG_DEBUG("watchpoint values and masking not supported");
969 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
970 }
971
972 retval = dpm_bpwp_setup(dpm, &dwp->bpwp, wp->address, wp->length);
973 if (retval != ERROR_OK)
974 return retval;
975
976 control = dwp->bpwp.control;
977 switch (wp->rw) {
978 case WPT_READ:
979 control |= 1 << 3;
980 break;
981 case WPT_WRITE:
982 control |= 2 << 3;
983 break;
984 case WPT_ACCESS:
985 control |= 3 << 3;
986 break;
987 }
988 dwp->bpwp.control = control;
989
990 dpm->dwp[index_t].wp = wp;
991
992 return retval;
993 }
994
995 static int dpm_add_watchpoint(struct target *target, struct watchpoint *wp)
996 {
997 struct arm *arm = target_to_arm(target);
998 struct arm_dpm *dpm = arm->dpm;
999 int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1000
1001 if (dpm->bpwp_enable) {
1002 for (unsigned i = 0; i < dpm->nwp; i++) {
1003 if (!dpm->dwp[i].wp) {
1004 retval = dpm_watchpoint_setup(dpm, i, wp);
1005 break;
1006 }
1007 }
1008 }
1009
1010 return retval;
1011 }
1012
1013 static int dpm_remove_watchpoint(struct target *target, struct watchpoint *wp)
1014 {
1015 struct arm *arm = target_to_arm(target);
1016 struct arm_dpm *dpm = arm->dpm;
1017 int retval = ERROR_COMMAND_SYNTAX_ERROR;
1018
1019 for (unsigned i = 0; i < dpm->nwp; i++) {
1020 if (dpm->dwp[i].wp == wp) {
1021 dpm->dwp[i].wp = NULL;
1022 dpm->dwp[i].bpwp.dirty = true;
1023
1024 /* hardware is updated in write_dirty_registers() */
1025 retval = ERROR_OK;
1026 break;
1027 }
1028 }
1029
1030 return retval;
1031 }
1032
1033 void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr)
1034 {
1035 switch (dpm->arm->core_state) {
1036 case ARM_STATE_ARM:
1037 addr -= 8;
1038 break;
1039 case ARM_STATE_THUMB:
1040 case ARM_STATE_THUMB_EE:
1041 addr -= 4;
1042 break;
1043 case ARM_STATE_JAZELLE:
1044 case ARM_STATE_AARCH64:
1045 /* ?? */
1046 break;
1047 }
1048 dpm->wp_addr = addr;
1049 }
1050
1051 /*----------------------------------------------------------------------*/
1052
1053 /*
1054 * Other debug and support utilities
1055 */
1056
1057 void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
1058 {
1059 struct target *target = dpm->arm->target;
1060
1061 dpm->dscr = dscr;
1062
1063 /* Examine debug reason */
1064 switch (DSCR_ENTRY(dscr)) {
1065 case DSCR_ENTRY_HALT_REQ: /* HALT request from debugger */
1066 case DSCR_ENTRY_EXT_DBG_REQ: /* EDBGRQ */
1067 target->debug_reason = DBG_REASON_DBGRQ;
1068 break;
1069 case DSCR_ENTRY_BREAKPOINT: /* HW breakpoint */
1070 case DSCR_ENTRY_BKPT_INSTR: /* vector catch */
1071 target->debug_reason = DBG_REASON_BREAKPOINT;
1072 break;
1073 case DSCR_ENTRY_IMPRECISE_WATCHPT: /* asynch watchpoint */
1074 case DSCR_ENTRY_PRECISE_WATCHPT:/* precise watchpoint */
1075 target->debug_reason = DBG_REASON_WATCHPOINT;
1076 break;
1077 default:
1078 target->debug_reason = DBG_REASON_UNDEFINED;
1079 break;
1080 }
1081 }
1082
1083 /*----------------------------------------------------------------------*/
1084
1085 /*
1086 * Setup and management support.
1087 */
1088
1089 /**
1090 * Hooks up this DPM to its associated target; call only once.
1091 * Initially this only covers the register cache.
1092 *
1093 * Oh, and watchpoints. Yeah.
1094 */
1095 int arm_dpm_setup(struct arm_dpm *dpm)
1096 {
1097 struct arm *arm = dpm->arm;
1098 struct target *target = arm->target;
1099 struct reg_cache *cache = NULL;
1100
1101 arm->dpm = dpm;
1102
1103 /* register access setup */
1104 arm->full_context = arm_dpm_full_context;
1105 arm->read_core_reg = arm_dpm_read_core_reg;
1106 arm->write_core_reg = arm_dpm_write_core_reg;
1107
1108 if (!arm->core_cache) {
1109 cache = arm_build_reg_cache(target, arm);
1110 if (!cache)
1111 return ERROR_FAIL;
1112
1113 *register_get_last_cache_p(&target->reg_cache) = cache;
1114 }
1115
1116 /* coprocessor access setup */
1117 arm->mrc = dpm_mrc;
1118 arm->mcr = dpm_mcr;
1119 arm->mrrc = dpm_mrrc;
1120 arm->mcrr = dpm_mcrr;
1121
1122 /* breakpoint setup -- optional until it works everywhere */
1123 if (!target->type->add_breakpoint) {
1124 target->type->add_breakpoint = dpm_add_breakpoint;
1125 target->type->remove_breakpoint = dpm_remove_breakpoint;
1126 }
1127
1128 /* watchpoint setup -- optional until it works everywhere */
1129 if (!target->type->add_watchpoint) {
1130 target->type->add_watchpoint = dpm_add_watchpoint;
1131 target->type->remove_watchpoint = dpm_remove_watchpoint;
1132 }
1133
1134 /* FIXME add vector catch support */
1135
1136 dpm->nbp = 1 + ((dpm->didr >> 24) & 0xf);
1137 dpm->nwp = 1 + ((dpm->didr >> 28) & 0xf);
1138 dpm->dbp = calloc(dpm->nbp, sizeof(*dpm->dbp));
1139 dpm->dwp = calloc(dpm->nwp, sizeof(*dpm->dwp));
1140
1141 if (!dpm->dbp || !dpm->dwp) {
1142 arm_free_reg_cache(arm);
1143 free(dpm->dbp);
1144 free(dpm->dwp);
1145 return ERROR_FAIL;
1146 }
1147
1148 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1149 target_name(target), dpm->nbp, dpm->nwp);
1150
1151 /* REVISIT ... and some of those breakpoints could match
1152 * execution context IDs...
1153 */
1154
1155 return ERROR_OK;
1156 }
1157
1158 /**
1159 * Reinitializes DPM state at the beginning of a new debug session
1160 * or after a reset which may have affected the debug module.
1161 */
1162 int arm_dpm_initialize(struct arm_dpm *dpm)
1163 {
1164 /* Disable all breakpoints and watchpoints at startup. */
1165 if (dpm->bpwp_disable) {
1166 unsigned i;
1167
1168 for (i = 0; i < dpm->nbp; i++) {
1169 dpm->dbp[i].bpwp.number = i;
1170 (void) dpm->bpwp_disable(dpm, i);
1171 }
1172 for (i = 0; i < dpm->nwp; i++) {
1173 dpm->dwp[i].bpwp.number = 16 + i;
1174 (void) dpm->bpwp_disable(dpm, 16 + i);
1175 }
1176 } else
1177 LOG_WARNING("%s: can't disable breakpoints and watchpoints",
1178 target_name(dpm->arm->target));
1179
1180 return ERROR_OK;
1181 }

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)