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

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)