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

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)