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

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)