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

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)