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

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)