1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2009 by David Brownell
13 #include "armv8_dpm.h"
14 #include <jtag/jtag.h>
16 #include "breakpoints.h"
17 #include "target_type.h"
18 #include "arm_opcodes.h"
23 * Implements various ARM DPM operations using architectural debug registers.
24 * These routines layer over core-specific communication methods to cope with
25 * implementation differences between cores like ARM1136 and Cortex-A8.
27 * The "Debug Programmers' Model" (DPM) for ARMv6 and ARMv7 is defined by
28 * Part C (Debug Architecture) of the ARM Architecture Reference Manual,
29 * ARMv7-A and ARMv7-R edition (ARM DDI 0406B). In OpenOCD, DPM operations
30 * are abstracted through internal programming interfaces to share code and
31 * to minimize needless differences in debug behavior between cores.
34 /*----------------------------------------------------------------------*/
40 /* Read coprocessor */
41 static int dpm_mrc(struct target
*target
, int cpnum
,
42 uint32_t op1
, uint32_t op2
, uint32_t crn
, uint32_t crm
,
45 struct arm
*arm
= target_to_arm(target
);
46 struct arm_dpm
*dpm
= arm
->dpm
;
49 retval
= dpm
->prepare(dpm
);
50 if (retval
!= ERROR_OK
)
53 LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum
,
55 (int) crm
, (int) op2
);
57 /* read coprocessor register into R0; return via DCC */
58 retval
= dpm
->instr_read_data_r0(dpm
,
59 ARMV4_5_MRC(cpnum
, op1
, 0, crn
, crm
, op2
),
62 /* (void) */ dpm
->finish(dpm
);
66 static int dpm_mrrc(struct target
*target
, int cpnum
,
67 uint32_t op
, uint32_t crm
, uint64_t *value
)
69 struct arm
*arm
= target_to_arm(target
);
70 struct arm_dpm
*dpm
= arm
->dpm
;
73 retval
= dpm
->prepare(dpm
);
74 if (retval
!= ERROR_OK
)
77 LOG_DEBUG("MRRC p%d, %d, r0, r1, c%d", cpnum
,
80 /* read coprocessor register into R0, R1; return via DCC */
81 retval
= dpm
->instr_read_data_r0_r1(dpm
,
82 ARMV5_T_MRRC(cpnum
, op
, 0, 1, crm
),
85 /* (void) */ dpm
->finish(dpm
);
89 static int dpm_mcr(struct target
*target
, int cpnum
,
90 uint32_t op1
, uint32_t op2
, uint32_t crn
, uint32_t crm
,
93 struct arm
*arm
= target_to_arm(target
);
94 struct arm_dpm
*dpm
= arm
->dpm
;
97 retval
= dpm
->prepare(dpm
);
98 if (retval
!= ERROR_OK
)
101 LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum
,
102 (int) op1
, (int) crn
,
103 (int) crm
, (int) op2
);
105 /* read DCC into r0; then write coprocessor register from R0 */
106 retval
= dpm
->instr_write_data_r0(dpm
,
107 ARMV4_5_MCR(cpnum
, op1
, 0, crn
, crm
, op2
),
110 /* (void) */ dpm
->finish(dpm
);
114 static int dpm_mcrr(struct target
*target
, int cpnum
,
115 uint32_t op
, uint32_t crm
, uint64_t value
)
117 struct arm
*arm
= target_to_arm(target
);
118 struct arm_dpm
*dpm
= arm
->dpm
;
121 retval
= dpm
->prepare(dpm
);
122 if (retval
!= ERROR_OK
)
125 LOG_DEBUG("MCRR p%d, %d, r0, r1, c%d", cpnum
,
128 /* read DCC into r0, r1; then write coprocessor register from R0, R1 */
129 retval
= dpm
->instr_write_data_r0_r1(dpm
,
130 ARMV5_T_MCRR(cpnum
, op
, 0, 1, crm
), value
);
132 /* (void) */ dpm
->finish(dpm
);
137 /*----------------------------------------------------------------------*/
140 * Register access utilities
143 /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one.
144 * Routines *must* restore the original mode before returning!!
146 int arm_dpm_modeswitch(struct arm_dpm
*dpm
, enum arm_mode mode
)
151 /* restore previous mode */
152 if (mode
== ARM_MODE_ANY
)
153 cpsr
= buf_get_u32(dpm
->arm
->cpsr
->value
, 0, 32);
155 /* else force to the specified mode */
159 retval
= dpm
->instr_write_data_r0(dpm
, ARMV4_5_MSR_GP(0, 0xf, 0), cpsr
);
160 if (retval
!= ERROR_OK
)
163 if (dpm
->instr_cpsr_sync
)
164 retval
= dpm
->instr_cpsr_sync(dpm
);
169 /* Read 64bit VFP registers */
170 static int dpm_read_reg_u64(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
172 int retval
= ERROR_FAIL
;
173 uint32_t value_r0
, value_r1
;
176 case ARM_VFP_V3_D0
... ARM_VFP_V3_D31
:
177 /* move from double word register to r0:r1: "vmov r0, r1, vm"
178 * then read r0 via dcc
180 retval
= dpm
->instr_read_data_r0(dpm
,
181 ARMV4_5_VMOV(1, 1, 0, ((regnum
- ARM_VFP_V3_D0
) >> 4),
182 ((regnum
- ARM_VFP_V3_D0
) & 0xf)), &value_r0
);
183 if (retval
!= ERROR_OK
)
186 /* read r1 via dcc */
187 retval
= dpm
->instr_read_data_dcc(dpm
,
188 ARMV4_5_MCR(14, 0, 1, 0, 5, 0),
196 if (retval
== ERROR_OK
) {
197 buf_set_u32(r
->value
, 0, 32, value_r0
);
198 buf_set_u32(r
->value
+ 4, 0, 32, value_r1
);
201 LOG_DEBUG("READ: %s, %8.8x, %8.8x", r
->name
,
202 (unsigned) value_r0
, (unsigned) value_r1
);
208 /* just read the register -- rely on the core mode being right */
209 int arm_dpm_read_reg(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
216 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
217 retval
= dpm
->instr_read_data_dcc(dpm
,
218 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
222 * "MOV r0, pc"; then return via DCC */
223 retval
= dpm
->instr_read_data_r0(dpm
, 0xe1a0000f, &value
);
225 /* NOTE: this seems like a slightly awkward place to update
226 * this value ... but if the PC gets written (the only way
227 * to change what we compute), the arch spec says subsequent
228 * reads return values which are "unpredictable". So this
229 * is always right except in those broken-by-intent cases.
231 switch (dpm
->arm
->core_state
) {
235 case ARM_STATE_THUMB
:
236 case ARM_STATE_THUMB_EE
:
239 case ARM_STATE_JAZELLE
:
240 /* core-specific ... ? */
241 LOG_WARNING("Jazelle PC adjustment unknown");
244 LOG_WARNING("unknown core state");
248 case ARM_VFP_V3_D0
... ARM_VFP_V3_D31
:
249 return dpm_read_reg_u64(dpm
, r
, regnum
);
250 case ARM_VFP_V3_FPSCR
:
251 /* "VMRS r0, FPSCR"; then return via DCC */
252 retval
= dpm
->instr_read_data_r0(dpm
,
253 ARMV4_5_VMRS(0), &value
);
256 /* 16: "MRS r0, CPSR"; then return via DCC
257 * 17: "MRS r0, SPSR"; then return via DCC
259 retval
= dpm
->instr_read_data_r0(dpm
,
260 ARMV4_5_MRS(0, regnum
& 1),
265 if (retval
== ERROR_OK
) {
266 buf_set_u32(r
->value
, 0, 32, value
);
269 LOG_DEBUG("READ: %s, %8.8x", r
->name
, (unsigned) value
);
275 /* Write 64bit VFP registers */
276 static int dpm_write_reg_u64(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
278 int retval
= ERROR_FAIL
;
279 uint32_t value_r0
= buf_get_u32(r
->value
, 0, 32);
280 uint32_t value_r1
= buf_get_u32(r
->value
+ 4, 0, 32);
283 case ARM_VFP_V3_D0
... ARM_VFP_V3_D31
:
284 /* write value_r1 to r1 via dcc */
285 retval
= dpm
->instr_write_data_dcc(dpm
,
286 ARMV4_5_MRC(14, 0, 1, 0, 5, 0),
288 if (retval
!= ERROR_OK
)
291 /* write value_r0 to r0 via dcc then,
292 * move to double word register from r0:r1: "vmov vm, r0, r1"
294 retval
= dpm
->instr_write_data_r0(dpm
,
295 ARMV4_5_VMOV(0, 1, 0, ((regnum
- ARM_VFP_V3_D0
) >> 4),
296 ((regnum
- ARM_VFP_V3_D0
) & 0xf)), value_r0
);
303 if (retval
== ERROR_OK
) {
305 LOG_DEBUG("WRITE: %s, %8.8x, %8.8x", r
->name
,
306 (unsigned) value_r0
, (unsigned) value_r1
);
312 /* just write the register -- rely on the core mode being right */
313 static int dpm_write_reg(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
316 uint32_t value
= buf_get_u32(r
->value
, 0, 32);
320 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
321 retval
= dpm
->instr_write_data_dcc(dpm
,
322 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0),
326 * read r0 from DCC; then "MOV pc, r0" */
327 retval
= dpm
->instr_write_data_r0(dpm
, 0xe1a0f000, value
);
329 case ARM_VFP_V3_D0
... ARM_VFP_V3_D31
:
330 return dpm_write_reg_u64(dpm
, r
, regnum
);
331 case ARM_VFP_V3_FPSCR
:
332 /* move to r0 from DCC, then "VMSR FPSCR, r0" */
333 retval
= dpm
->instr_write_data_r0(dpm
,
334 ARMV4_5_VMSR(0), value
);
337 /* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf"
338 * 17: read r0 from DCC, then "MSR r0, SPSR_cxsf"
340 retval
= dpm
->instr_write_data_r0(dpm
,
341 ARMV4_5_MSR_GP(0, 0xf, regnum
& 1),
343 if (retval
!= ERROR_OK
)
346 if (regnum
== 16 && dpm
->instr_cpsr_sync
)
347 retval
= dpm
->instr_cpsr_sync(dpm
);
352 if (retval
== ERROR_OK
) {
354 LOG_DEBUG("WRITE: %s, %8.8x", r
->name
, (unsigned) value
);
361 * Write to program counter and switch the core state (arm/thumb) according to
364 static int dpm_write_pc_core_state(struct arm_dpm
*dpm
, struct reg
*r
)
366 uint32_t value
= buf_get_u32(r
->value
, 0, 32);
368 /* read r0 from DCC; then "BX r0" */
369 return dpm
->instr_write_data_r0(dpm
, ARMV4_5_BX(0), value
);
373 * Read basic registers of the current context: R0 to R15, and CPSR;
374 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
375 * In normal operation this is called on entry to halting debug state,
376 * possibly after some other operations supporting restore of debug state
377 * or making sure the CPU is fully idle (drain write buffer, etc).
379 int arm_dpm_read_current_registers(struct arm_dpm
*dpm
)
381 struct arm
*arm
= dpm
->arm
;
386 retval
= dpm
->prepare(dpm
);
387 if (retval
!= ERROR_OK
)
390 /* read R0 and R1 first (it's used for scratch), then CPSR */
391 for (unsigned i
= 0; i
< 2; i
++) {
392 r
= arm
->core_cache
->reg_list
+ i
;
394 retval
= arm_dpm_read_reg(dpm
, r
, i
);
395 if (retval
!= ERROR_OK
)
401 retval
= dpm
->instr_read_data_r0(dpm
, ARMV4_5_MRS(0, 0), &cpsr
);
402 if (retval
!= ERROR_OK
)
405 /* update core mode and state, plus shadow mapping for R8..R14 */
406 arm_set_cpsr(arm
, cpsr
);
408 /* REVISIT we can probably avoid reading R1..R14, saving time... */
409 for (unsigned i
= 2; i
< 16; i
++) {
410 r
= arm_reg_current(arm
, i
);
414 retval
= arm_dpm_read_reg(dpm
, r
, i
);
415 if (retval
!= ERROR_OK
)
419 /* NOTE: SPSR ignored (if it's even relevant). */
421 /* REVISIT the debugger can trigger various exceptions. See the
422 * ARMv7A architecture spec, section C5.7, for more info about
423 * what defenses are needed; v6 debug has the most issues.
427 /* (void) */ dpm
->finish(dpm
);
431 /* Avoid needless I/O ... leave breakpoints and watchpoints alone
432 * unless they're removed, or need updating because of single-stepping
433 * or running debugger code.
435 static int dpm_maybe_update_bpwp(struct arm_dpm
*dpm
, bool bpwp
,
436 struct dpm_bpwp
*xp
, bool *set_p
)
438 int retval
= ERROR_OK
;
445 /* removed or startup; we must disable it */
450 /* disabled, but we must set it */
451 xp
->dirty
= disable
= false;
456 /* set, but we must temporarily disable it */
457 xp
->dirty
= disable
= true;
462 retval
= dpm
->bpwp_disable(dpm
, xp
->number
);
464 retval
= dpm
->bpwp_enable(dpm
, xp
->number
,
465 xp
->address
, xp
->control
);
467 if (retval
!= ERROR_OK
)
468 LOG_ERROR("%s: can't %s HW %spoint %d",
469 disable
? "disable" : "enable",
470 target_name(dpm
->arm
->target
),
471 (xp
->number
< 16) ? "break" : "watch",
477 static int dpm_add_breakpoint(struct target
*target
, struct breakpoint
*bp
);
480 * Writes all modified core registers for all processor modes. In normal
481 * operation this is called on exit from halting debug state.
483 * @param dpm: represents the processor
484 * @param bpwp: true ensures breakpoints and watchpoints are set,
485 * false ensures they are cleared
487 int arm_dpm_write_dirty_registers(struct arm_dpm
*dpm
, bool bpwp
)
489 struct arm
*arm
= dpm
->arm
;
490 struct reg_cache
*cache
= arm
->core_cache
;
494 retval
= dpm
->prepare(dpm
);
495 if (retval
!= ERROR_OK
)
498 /* If we're managing hardware breakpoints for this core, enable
499 * or disable them as requested.
501 * REVISIT We don't yet manage them for ANY cores. Eventually
502 * we should be able to assume we handle them; but until then,
503 * cope with the hand-crafted breakpoint code.
505 if (arm
->target
->type
->add_breakpoint
== dpm_add_breakpoint
) {
506 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
507 struct dpm_bp
*dbp
= dpm
->dbp
+ i
;
508 struct breakpoint
*bp
= dbp
->bp
;
510 retval
= dpm_maybe_update_bpwp(dpm
, bpwp
, &dbp
->bpwp
,
511 bp
? &bp
->is_set
: NULL
);
512 if (retval
!= ERROR_OK
)
517 /* enable/disable watchpoints */
518 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
519 struct dpm_wp
*dwp
= dpm
->dwp
+ i
;
520 struct watchpoint
*wp
= dwp
->wp
;
522 retval
= dpm_maybe_update_bpwp(dpm
, bpwp
, &dwp
->bpwp
,
523 wp
? &wp
->is_set
: NULL
);
524 if (retval
!= ERROR_OK
)
528 /* NOTE: writes to breakpoint and watchpoint registers might
529 * be queued, and need (efficient/batched) flushing later.
532 /* Scan the registers until we find one that's both dirty and
533 * eligible for flushing. Flush that and everything else that
534 * shares the same core mode setting. Typically this won't
535 * actually find anything to do...
538 enum arm_mode mode
= ARM_MODE_ANY
;
542 /* check everything except our scratch registers R0 and R1 */
543 for (unsigned i
= 2; i
< cache
->num_regs
; i
++) {
547 /* also skip PC, CPSR, and non-dirty */
550 if (arm
->cpsr
== cache
->reg_list
+ i
)
552 if (!cache
->reg_list
[i
].exist
|| !cache
->reg_list
[i
].dirty
)
555 r
= cache
->reg_list
[i
].arch_info
;
558 /* may need to pick and set a mode */
563 mode
= tmode
= r
->mode
;
565 /* cope with special cases */
568 /* r8..r12 "anything but FIQ" case;
569 * we "know" core mode is accurate
570 * since we haven't changed it yet
572 if (arm
->core_mode
== ARM_MODE_FIQ
575 tmode
= ARM_MODE_USR
;
583 /* REVISIT error checks */
584 if (tmode
!= ARM_MODE_ANY
) {
585 retval
= arm_dpm_modeswitch(dpm
, tmode
);
586 if (retval
!= ERROR_OK
)
593 retval
= dpm_write_reg(dpm
,
596 if (retval
!= ERROR_OK
)
602 /* Restore original CPSR ... assuming either that we changed it,
603 * or it's dirty. Must write PC to ensure the return address is
604 * defined, and must not write it before CPSR.
606 retval
= arm_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
607 if (retval
!= ERROR_OK
)
609 arm
->cpsr
->dirty
= false;
611 /* restore the PC, make sure to also switch the core state
612 * to whatever it was set to with "arm core_state" command.
613 * target code will have set PC to an appropriate resume address.
615 retval
= dpm_write_pc_core_state(dpm
, arm
->pc
);
616 if (retval
!= ERROR_OK
)
618 /* on Cortex-A5 (as found on NXP VF610 SoC), BX instruction
619 * executed in debug state doesn't appear to set the PC,
620 * explicitly set it with a "MOV pc, r0". This doesn't influence
621 * CPSR on Cortex-A9 so it should be OK. Maybe due to different
624 retval
= dpm_write_reg(dpm
, arm
->pc
, 15);
625 if (retval
!= ERROR_OK
)
627 arm
->pc
->dirty
= false;
629 /* flush R0 and R1 (our scratch registers) */
630 for (unsigned i
= 0; i
< 2; i
++) {
631 retval
= dpm_write_reg(dpm
, &cache
->reg_list
[i
], i
);
632 if (retval
!= ERROR_OK
)
634 cache
->reg_list
[i
].dirty
= false;
637 /* (void) */ dpm
->finish(dpm
);
642 /* Returns ARM_MODE_ANY or temporary mode to use while reading the
643 * specified register ... works around flakiness from ARM core calls.
644 * Caller already filtered out SPSR access; mode is never MODE_SYS
647 static enum arm_mode
dpm_mapmode(struct arm
*arm
,
648 unsigned num
, enum arm_mode mode
)
650 enum arm_mode amode
= arm
->core_mode
;
652 /* don't switch if the mode is already correct */
653 if (amode
== ARM_MODE_SYS
)
654 amode
= ARM_MODE_USR
;
659 /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */
664 /* r8..r12 aren't shadowed for anything except FIQ */
666 if (mode
== ARM_MODE_FIQ
)
669 /* r13/sp, and r14/lr are always shadowed */
672 case ARM_VFP_V3_D0
... ARM_VFP_V3_FPSCR
:
675 LOG_WARNING("invalid register #%u", num
);
683 * Standard ARM register accessors ... there are three methods
684 * in "struct arm", to support individual read/write and bulk read
688 static int arm_dpm_read_core_reg(struct target
*target
, struct reg
*r
,
689 int regnum
, enum arm_mode mode
)
691 struct arm_dpm
*dpm
= target_to_arm(target
)->dpm
;
694 if (regnum
< 0 || (regnum
> 16 && regnum
< ARM_VFP_V3_D0
) ||
695 (regnum
> ARM_VFP_V3_FPSCR
))
696 return ERROR_COMMAND_SYNTAX_ERROR
;
699 if (mode
!= ARM_MODE_ANY
)
702 mode
= dpm_mapmode(dpm
->arm
, regnum
, mode
);
704 /* REVISIT what happens if we try to read SPSR in a core mode
705 * which has no such register?
708 retval
= dpm
->prepare(dpm
);
709 if (retval
!= ERROR_OK
)
712 if (mode
!= ARM_MODE_ANY
) {
713 retval
= arm_dpm_modeswitch(dpm
, mode
);
714 if (retval
!= ERROR_OK
)
718 retval
= arm_dpm_read_reg(dpm
, r
, regnum
);
719 if (retval
!= ERROR_OK
)
721 /* always clean up, regardless of error */
723 if (mode
!= ARM_MODE_ANY
)
724 /* (void) */ arm_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
727 /* (void) */ dpm
->finish(dpm
);
731 static int arm_dpm_write_core_reg(struct target
*target
, struct reg
*r
,
732 int regnum
, enum arm_mode mode
, uint8_t *value
)
734 struct arm_dpm
*dpm
= target_to_arm(target
)->dpm
;
738 if (regnum
< 0 || (regnum
> 16 && regnum
< ARM_VFP_V3_D0
) ||
739 (regnum
> ARM_VFP_V3_FPSCR
))
740 return ERROR_COMMAND_SYNTAX_ERROR
;
743 if (mode
!= ARM_MODE_ANY
)
746 mode
= dpm_mapmode(dpm
->arm
, regnum
, mode
);
748 /* REVISIT what happens if we try to write SPSR in a core mode
749 * which has no such register?
752 retval
= dpm
->prepare(dpm
);
753 if (retval
!= ERROR_OK
)
756 if (mode
!= ARM_MODE_ANY
) {
757 retval
= arm_dpm_modeswitch(dpm
, mode
);
758 if (retval
!= ERROR_OK
)
762 retval
= dpm_write_reg(dpm
, r
, regnum
);
763 /* always clean up, regardless of error */
765 if (mode
!= ARM_MODE_ANY
)
766 /* (void) */ arm_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
769 /* (void) */ dpm
->finish(dpm
);
773 static int arm_dpm_full_context(struct target
*target
)
775 struct arm
*arm
= target_to_arm(target
);
776 struct arm_dpm
*dpm
= arm
->dpm
;
777 struct reg_cache
*cache
= arm
->core_cache
;
781 retval
= dpm
->prepare(dpm
);
782 if (retval
!= ERROR_OK
)
786 enum arm_mode mode
= ARM_MODE_ANY
;
790 /* We "know" arm_dpm_read_current_registers() was called so
791 * the unmapped registers (R0..R7, PC, AND CPSR) and some
792 * view of R8..R14 are current. We also "know" oddities of
793 * register mapping: special cases for R8..R12 and SPSR.
795 * Pick some mode with unread registers and read them all.
798 for (unsigned i
= 0; i
< cache
->num_regs
; i
++) {
801 if (!cache
->reg_list
[i
].exist
|| cache
->reg_list
[i
].valid
)
803 r
= cache
->reg_list
[i
].arch_info
;
805 /* may need to pick a mode and set CPSR */
810 /* For regular (ARM_MODE_ANY) R8..R12
811 * in case we've entered debug state
812 * in FIQ mode we need to patch mode.
814 if (mode
!= ARM_MODE_ANY
)
815 retval
= arm_dpm_modeswitch(dpm
, mode
);
817 retval
= arm_dpm_modeswitch(dpm
, ARM_MODE_USR
);
819 if (retval
!= ERROR_OK
)
825 /* CPSR was read, so "R16" must mean SPSR */
826 retval
= arm_dpm_read_reg(dpm
,
828 (r
->num
== 16) ? 17 : r
->num
);
829 if (retval
!= ERROR_OK
)
835 retval
= arm_dpm_modeswitch(dpm
, ARM_MODE_ANY
);
836 /* (void) */ dpm
->finish(dpm
);
842 /*----------------------------------------------------------------------*/
845 * Breakpoint and Watchpoint support.
847 * Hardware {break,watch}points are usually left active, to minimize
848 * debug entry/exit costs. When they are set or cleared, it's done in
849 * batches. Also, DPM-conformant hardware can update debug registers
850 * regardless of whether the CPU is running or halted ... though that
851 * fact isn't currently leveraged.
854 static int dpm_bpwp_setup(struct arm_dpm
*dpm
, struct dpm_bpwp
*xp
,
855 uint32_t addr
, uint32_t length
)
859 control
= (1 << 0) /* enable */
860 | (3 << 1); /* both user and privileged access */
862 /* Match 1, 2, or all 4 byte addresses in this word.
864 * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP.
865 * Support larger length, when addr is suitably aligned. In
866 * particular, allow watchpoints on 8 byte "double" values.
868 * REVISIT allow watchpoints on unaligned 2-bit values; and on
869 * v7 hardware, unaligned 4-byte ones too.
873 control
|= (1 << (addr
& 3)) << 5;
876 /* require 2-byte alignment */
878 control
|= (3 << (addr
& 2)) << 5;
883 /* require 4-byte alignment */
890 LOG_ERROR("unsupported {break,watch}point length/alignment");
891 return ERROR_COMMAND_SYNTAX_ERROR
;
894 /* other shared control bits:
895 * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
896 * bit 20 == 0 ... not linked to a context ID
897 * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
900 xp
->address
= addr
& ~3;
901 xp
->control
= control
;
904 LOG_DEBUG("BPWP: addr %8.8" PRIx32
", control %" PRIx32
", number %d",
905 xp
->address
, control
, xp
->number
);
907 /* hardware is updated in write_dirty_registers() */
911 static int dpm_add_breakpoint(struct target
*target
, struct breakpoint
*bp
)
913 struct arm
*arm
= target_to_arm(target
);
914 struct arm_dpm
*dpm
= arm
->dpm
;
915 int retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
918 return ERROR_COMMAND_SYNTAX_ERROR
;
919 if (!dpm
->bpwp_enable
)
922 /* FIXME we need a generic solution for software breakpoints. */
923 if (bp
->type
== BKPT_SOFT
)
924 LOG_DEBUG("using HW bkpt, not SW...");
926 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
927 if (!dpm
->dbp
[i
].bp
) {
928 retval
= dpm_bpwp_setup(dpm
, &dpm
->dbp
[i
].bpwp
,
929 bp
->address
, bp
->length
);
930 if (retval
== ERROR_OK
)
939 static int dpm_remove_breakpoint(struct target
*target
, struct breakpoint
*bp
)
941 struct arm
*arm
= target_to_arm(target
);
942 struct arm_dpm
*dpm
= arm
->dpm
;
943 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
945 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
946 if (dpm
->dbp
[i
].bp
== bp
) {
947 dpm
->dbp
[i
].bp
= NULL
;
948 dpm
->dbp
[i
].bpwp
.dirty
= true;
950 /* hardware is updated in write_dirty_registers() */
959 static int dpm_watchpoint_setup(struct arm_dpm
*dpm
, unsigned index_t
,
960 struct watchpoint
*wp
)
963 struct dpm_wp
*dwp
= dpm
->dwp
+ index_t
;
966 /* this hardware doesn't support data value matching or masking */
967 if (wp
->mask
!= WATCHPOINT_IGNORE_DATA_VALUE_MASK
) {
968 LOG_DEBUG("watchpoint values and masking not supported");
969 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
972 retval
= dpm_bpwp_setup(dpm
, &dwp
->bpwp
, wp
->address
, wp
->length
);
973 if (retval
!= ERROR_OK
)
976 control
= dwp
->bpwp
.control
;
988 dwp
->bpwp
.control
= control
;
990 dpm
->dwp
[index_t
].wp
= wp
;
995 static int dpm_add_watchpoint(struct target
*target
, struct watchpoint
*wp
)
997 struct arm
*arm
= target_to_arm(target
);
998 struct arm_dpm
*dpm
= arm
->dpm
;
999 int retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1001 if (dpm
->bpwp_enable
) {
1002 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
1003 if (!dpm
->dwp
[i
].wp
) {
1004 retval
= dpm_watchpoint_setup(dpm
, i
, wp
);
1013 static int dpm_remove_watchpoint(struct target
*target
, struct watchpoint
*wp
)
1015 struct arm
*arm
= target_to_arm(target
);
1016 struct arm_dpm
*dpm
= arm
->dpm
;
1017 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
1019 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
1020 if (dpm
->dwp
[i
].wp
== wp
) {
1021 dpm
->dwp
[i
].wp
= NULL
;
1022 dpm
->dwp
[i
].bpwp
.dirty
= true;
1024 /* hardware is updated in write_dirty_registers() */
1033 void arm_dpm_report_wfar(struct arm_dpm
*dpm
, uint32_t addr
)
1035 switch (dpm
->arm
->core_state
) {
1039 case ARM_STATE_THUMB
:
1040 case ARM_STATE_THUMB_EE
:
1043 case ARM_STATE_JAZELLE
:
1044 case ARM_STATE_AARCH64
:
1048 dpm
->wp_addr
= addr
;
1051 /*----------------------------------------------------------------------*/
1054 * Other debug and support utilities
1057 void arm_dpm_report_dscr(struct arm_dpm
*dpm
, uint32_t dscr
)
1059 struct target
*target
= dpm
->arm
->target
;
1063 /* Examine debug reason */
1064 switch (DSCR_ENTRY(dscr
)) {
1065 case DSCR_ENTRY_HALT_REQ
: /* HALT request from debugger */
1066 case DSCR_ENTRY_EXT_DBG_REQ
: /* EDBGRQ */
1067 target
->debug_reason
= DBG_REASON_DBGRQ
;
1069 case DSCR_ENTRY_BREAKPOINT
: /* HW breakpoint */
1070 case DSCR_ENTRY_BKPT_INSTR
: /* vector catch */
1071 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
1073 case DSCR_ENTRY_IMPRECISE_WATCHPT
: /* asynch watchpoint */
1074 case DSCR_ENTRY_PRECISE_WATCHPT
:/* precise watchpoint */
1075 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
1078 target
->debug_reason
= DBG_REASON_UNDEFINED
;
1083 /*----------------------------------------------------------------------*/
1086 * Setup and management support.
1090 * Hooks up this DPM to its associated target; call only once.
1091 * Initially this only covers the register cache.
1093 * Oh, and watchpoints. Yeah.
1095 int arm_dpm_setup(struct arm_dpm
*dpm
)
1097 struct arm
*arm
= dpm
->arm
;
1098 struct target
*target
= arm
->target
;
1099 struct reg_cache
*cache
= NULL
;
1103 /* register access setup */
1104 arm
->full_context
= arm_dpm_full_context
;
1105 arm
->read_core_reg
= arm_dpm_read_core_reg
;
1106 arm
->write_core_reg
= arm_dpm_write_core_reg
;
1108 if (!arm
->core_cache
) {
1109 cache
= arm_build_reg_cache(target
, arm
);
1113 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
1116 /* coprocessor access setup */
1119 arm
->mrrc
= dpm_mrrc
;
1120 arm
->mcrr
= dpm_mcrr
;
1122 /* breakpoint setup -- optional until it works everywhere */
1123 if (!target
->type
->add_breakpoint
) {
1124 target
->type
->add_breakpoint
= dpm_add_breakpoint
;
1125 target
->type
->remove_breakpoint
= dpm_remove_breakpoint
;
1128 /* watchpoint setup -- optional until it works everywhere */
1129 if (!target
->type
->add_watchpoint
) {
1130 target
->type
->add_watchpoint
= dpm_add_watchpoint
;
1131 target
->type
->remove_watchpoint
= dpm_remove_watchpoint
;
1134 /* FIXME add vector catch support */
1136 dpm
->nbp
= 1 + ((dpm
->didr
>> 24) & 0xf);
1137 dpm
->nwp
= 1 + ((dpm
->didr
>> 28) & 0xf);
1138 dpm
->dbp
= calloc(dpm
->nbp
, sizeof(*dpm
->dbp
));
1139 dpm
->dwp
= calloc(dpm
->nwp
, sizeof(*dpm
->dwp
));
1141 if (!dpm
->dbp
|| !dpm
->dwp
) {
1142 arm_free_reg_cache(arm
);
1148 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1149 target_name(target
), dpm
->nbp
, dpm
->nwp
);
1151 /* REVISIT ... and some of those breakpoints could match
1152 * execution context IDs...
1159 * Reinitializes DPM state at the beginning of a new debug session
1160 * or after a reset which may have affected the debug module.
1162 int arm_dpm_initialize(struct arm_dpm
*dpm
)
1164 /* Disable all breakpoints and watchpoints at startup. */
1165 if (dpm
->bpwp_disable
) {
1168 for (i
= 0; i
< dpm
->nbp
; i
++) {
1169 dpm
->dbp
[i
].bpwp
.number
= i
;
1170 (void) dpm
->bpwp_disable(dpm
, i
);
1172 for (i
= 0; i
< dpm
->nwp
; i
++) {
1173 dpm
->dwp
[i
].bpwp
.number
= 16 + i
;
1174 (void) dpm
->bpwp_disable(dpm
, 16 + i
);
1177 LOG_WARNING("%s: can't disable breakpoints and watchpoints",
1178 target_name(dpm
->arm
->target
));
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)