2 * Copyright (C) 2009 by David Brownell
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.
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.
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/>.
24 #include "armv8_dpm.h"
25 #include <jtag/jtag.h>
27 #include "breakpoints.h"
28 #include "target_type.h"
29 #include "arm_opcodes.h"
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.
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.
45 /*----------------------------------------------------------------------*/
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
,
56 struct arm
*arm
= target_to_arm(target
);
57 struct arm_dpm
*dpm
= arm
->dpm
;
60 retval
= dpm
->prepare(dpm
);
61 if (retval
!= ERROR_OK
)
64 LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum
,
66 (int) CRm
, (int) op2
);
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
),
73 /* (void) */ dpm
->finish(dpm
);
77 static int dpm_mcr(struct target
*target
, int cpnum
,
78 uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
,
81 struct arm
*arm
= target_to_arm(target
);
82 struct arm_dpm
*dpm
= arm
->dpm
;
85 retval
= dpm
->prepare(dpm
);
86 if (retval
!= ERROR_OK
)
89 LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum
,
91 (int) CRm
, (int) op2
);
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
),
98 /* (void) */ dpm
->finish(dpm
);
102 /*----------------------------------------------------------------------*/
105 * Register access utilities
108 /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one.
109 * Routines *must* restore the original mode before returning!!
111 int dpm_modeswitch(struct arm_dpm
*dpm
, enum arm_mode mode
)
116 /* restore previous mode */
117 if (mode
== ARM_MODE_ANY
)
118 cpsr
= buf_get_u32(dpm
->arm
->cpsr
->value
, 0, 32);
120 /* else force to the specified mode */
124 retval
= dpm
->instr_write_data_r0(dpm
, ARMV4_5_MSR_GP(0, 0xf, 0), cpsr
);
125 if (retval
!= ERROR_OK
)
128 if (dpm
->instr_cpsr_sync
)
129 retval
= dpm
->instr_cpsr_sync(dpm
);
134 /* just read the register -- rely on the core mode being right */
135 static int dpm_read_reg(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
142 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
143 retval
= dpm
->instr_read_data_dcc(dpm
,
144 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
148 * "MOV r0, pc"; then return via DCC */
149 retval
= dpm
->instr_read_data_r0(dpm
, 0xe1a0000f, &value
);
151 /* NOTE: this seems like a slightly awkward place to update
152 * this value ... but if the PC gets written (the only way
153 * to change what we compute), the arch spec says subsequent
154 * reads return values which are "unpredictable". So this
155 * is always right except in those broken-by-intent cases.
157 switch (dpm
->arm
->core_state
) {
161 case ARM_STATE_THUMB
:
162 case ARM_STATE_THUMB_EE
:
165 case ARM_STATE_JAZELLE
:
166 /* core-specific ... ? */
167 LOG_WARNING("Jazelle PC adjustment unknown");
170 LOG_WARNING("unknow core state");
175 /* 16: "MRS r0, CPSR"; then return via DCC
176 * 17: "MRS r0, SPSR"; then return via DCC
178 retval
= dpm
->instr_read_data_r0(dpm
,
179 ARMV4_5_MRS(0, regnum
& 1),
184 if (retval
== ERROR_OK
) {
185 buf_set_u32(r
->value
, 0, 32, value
);
188 LOG_DEBUG("READ: %s, %8.8x", r
->name
, (unsigned) value
);
194 /* just write the register -- rely on the core mode being right */
195 static int dpm_write_reg(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
198 uint32_t value
= buf_get_u32(r
->value
, 0, 32);
202 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
203 retval
= dpm
->instr_write_data_dcc(dpm
,
204 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0),
208 * read r0 from DCC; then "MOV pc, r0" */
209 retval
= dpm
->instr_write_data_r0(dpm
, 0xe1a0f000, value
);
212 /* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf"
213 * 17: read r0 from DCC, then "MSR r0, SPSR_cxsf"
215 retval
= dpm
->instr_write_data_r0(dpm
,
216 ARMV4_5_MSR_GP(0, 0xf, regnum
& 1),
218 if (retval
!= ERROR_OK
)
221 if (regnum
== 16 && dpm
->instr_cpsr_sync
)
222 retval
= dpm
->instr_cpsr_sync(dpm
);
227 if (retval
== ERROR_OK
) {
229 LOG_DEBUG("WRITE: %s, %8.8x", r
->name
, (unsigned) value
);
236 * Write to program counter and switch the core state (arm/thumb) according to
239 static int dpm_write_pc_core_state(struct arm_dpm
*dpm
, struct reg
*r
)
241 uint32_t value
= buf_get_u32(r
->value
, 0, 32);
243 /* read r0 from DCC; then "BX r0" */
244 return dpm
->instr_write_data_r0(dpm
, ARMV4_5_BX(0), value
);
248 * Read basic registers of the the current context: R0 to R15, and CPSR;
249 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
250 * In normal operation this is called on entry to halting debug state,
251 * possibly after some other operations supporting restore of debug state
252 * or making sure the CPU is fully idle (drain write buffer, etc).
254 int arm_dpm_read_current_registers(struct arm_dpm
*dpm
)
256 struct arm
*arm
= dpm
->arm
;
261 retval
= dpm
->prepare(dpm
);
262 if (retval
!= ERROR_OK
)
265 /* read R0 first (it's used for scratch), then CPSR */
266 r
= arm
->core_cache
->reg_list
+ 0;
268 retval
= dpm_read_reg(dpm
, r
, 0);
269 if (retval
!= ERROR_OK
)
274 retval
= dpm
->instr_read_data_r0(dpm
, ARMV4_5_MRS(0, 0), &cpsr
);
275 if (retval
!= ERROR_OK
)
278 /* update core mode and state, plus shadow mapping for R8..R14 */
279 arm_set_cpsr(arm
, cpsr
);
281 /* REVISIT we can probably avoid reading R1..R14, saving time... */
282 for (unsigned i
= 1; i
< 16; i
++) {
283 r
= arm_reg_current(arm
, i
);
287 retval
= dpm_read_reg(dpm
, r
, i
);
288 if (retval
!= ERROR_OK
)
292 /* NOTE: SPSR ignored (if it's even relevant). */
294 /* REVISIT the debugger can trigger various exceptions. See the
295 * ARMv7A architecture spec, section C5.7, for more info about
296 * what defenses are needed; v6 debug has the most issues.
300 /* (void) */ dpm
->finish(dpm
);
304 /* Avoid needless I/O ... leave breakpoints and watchpoints alone
305 * unless they're removed, or need updating because of single-stepping
306 * or running debugger code.
308 static int dpm_maybe_update_bpwp(struct arm_dpm
*dpm
, bool bpwp
,
309 struct dpm_bpwp
*xp
, int *set_p
)
311 int retval
= ERROR_OK
;
318 /* removed or startup; we must disable it */
323 /* disabled, but we must set it */
324 xp
->dirty
= disable
= false;
329 /* set, but we must temporarily disable it */
330 xp
->dirty
= disable
= true;
335 retval
= dpm
->bpwp_disable(dpm
, xp
->number
);
337 retval
= dpm
->bpwp_enable(dpm
, xp
->number
,
338 xp
->address
, xp
->control
);
340 if (retval
!= ERROR_OK
)
341 LOG_ERROR("%s: can't %s HW %spoint %d",
342 disable
? "disable" : "enable",
343 target_name(dpm
->arm
->target
),
344 (xp
->number
< 16) ? "break" : "watch",
350 static int dpm_add_breakpoint(struct target
*target
, struct breakpoint
*bp
);
353 * Writes all modified core registers for all processor modes. In normal
354 * operation this is called on exit from halting debug state.
356 * @param dpm: represents the processor
357 * @param bpwp: true ensures breakpoints and watchpoints are set,
358 * false ensures they are cleared
360 int arm_dpm_write_dirty_registers(struct arm_dpm
*dpm
, bool bpwp
)
362 struct arm
*arm
= dpm
->arm
;
363 struct reg_cache
*cache
= arm
->core_cache
;
367 retval
= dpm
->prepare(dpm
);
368 if (retval
!= ERROR_OK
)
371 /* If we're managing hardware breakpoints for this core, enable
372 * or disable them as requested.
374 * REVISIT We don't yet manage them for ANY cores. Eventually
375 * we should be able to assume we handle them; but until then,
376 * cope with the hand-crafted breakpoint code.
378 if (arm
->target
->type
->add_breakpoint
== dpm_add_breakpoint
) {
379 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
380 struct dpm_bp
*dbp
= dpm
->dbp
+ i
;
381 struct breakpoint
*bp
= dbp
->bp
;
383 retval
= dpm_maybe_update_bpwp(dpm
, bpwp
, &dbp
->bpwp
,
384 bp
? &bp
->set
: NULL
);
385 if (retval
!= ERROR_OK
)
390 /* enable/disable watchpoints */
391 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
392 struct dpm_wp
*dwp
= dpm
->dwp
+ i
;
393 struct watchpoint
*wp
= dwp
->wp
;
395 retval
= dpm_maybe_update_bpwp(dpm
, bpwp
, &dwp
->bpwp
,
396 wp
? &wp
->set
: NULL
);
397 if (retval
!= ERROR_OK
)
401 /* NOTE: writes to breakpoint and watchpoint registers might
402 * be queued, and need (efficient/batched) flushing later.
405 /* Scan the registers until we find one that's both dirty and
406 * eligible for flushing. Flush that and everything else that
407 * shares the same core mode setting. Typically this won't
408 * actually find anything to do...
411 enum arm_mode mode
= ARM_MODE_ANY
;
415 /* check everything except our scratch register R0 */
416 for (unsigned i
= 1; i
< cache
->num_regs
; i
++) {
420 /* also skip PC, CPSR, and non-dirty */
423 if (arm
->cpsr
== cache
->reg_list
+ i
)
425 if (!cache
->reg_list
[i
].dirty
)
428 r
= cache
->reg_list
[i
].arch_info
;
431 /* may need to pick and set a mode */
436 mode
= tmode
= r
->mode
;
438 /* cope with special cases */
441 /* r8..r12 "anything but FIQ" case;
442 * we "know" core mode is accurate
443 * since we haven't changed it yet
445 if (arm
->core_mode
== ARM_MODE_FIQ
448 tmode
= ARM_MODE_USR
;
456 /* REVISIT error checks */
457 if (tmode
!= ARM_MODE_ANY
) {
458 retval
= dpm_modeswitch(dpm
, tmode
);
459 if (retval
!= ERROR_OK
)
466 retval
= dpm_write_reg(dpm
,
469 if (retval
!= ERROR_OK
)
475 /* Restore original CPSR ... assuming either that we changed it,
476 * or it's dirty. Must write PC to ensure the return address is
477 * defined, and must not write it before CPSR.
479 retval
= dpm_modeswitch(dpm
, ARM_MODE_ANY
);
480 if (retval
!= ERROR_OK
)
482 arm
->cpsr
->dirty
= false;
484 /* restore the PC, make sure to also switch the core state
485 * to whatever it was set to with "arm core_state" command.
486 * target code will have set PC to an appropriate resume address.
488 retval
= dpm_write_pc_core_state(dpm
, arm
->pc
);
489 if (retval
!= ERROR_OK
)
491 /* on Cortex-A5 (as found on NXP VF610 SoC), BX instruction
492 * executed in debug state doesn't appear to set the PC,
493 * explicitly set it with a "MOV pc, r0". This doesn't influence
494 * CPSR on Cortex-A9 so it should be OK. Maybe due to different
497 retval
= dpm_write_reg(dpm
, arm
->pc
, 15);
498 if (retval
!= ERROR_OK
)
500 arm
->pc
->dirty
= false;
502 /* flush R0 -- it's *very* dirty by now */
503 retval
= dpm_write_reg(dpm
, &cache
->reg_list
[0], 0);
504 if (retval
!= ERROR_OK
)
506 cache
->reg_list
[0].dirty
= false;
508 /* (void) */ dpm
->finish(dpm
);
513 /* Returns ARM_MODE_ANY or temporary mode to use while reading the
514 * specified register ... works around flakiness from ARM core calls.
515 * Caller already filtered out SPSR access; mode is never MODE_SYS
518 static enum arm_mode
dpm_mapmode(struct arm
*arm
,
519 unsigned num
, enum arm_mode mode
)
521 enum arm_mode amode
= arm
->core_mode
;
523 /* don't switch if the mode is already correct */
524 if (amode
== ARM_MODE_SYS
)
525 amode
= ARM_MODE_USR
;
530 /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */
535 /* r8..r12 aren't shadowed for anything except FIQ */
537 if (mode
== ARM_MODE_FIQ
)
540 /* r13/sp, and r14/lr are always shadowed */
545 LOG_WARNING("invalid register #%u", num
);
553 * Standard ARM register accessors ... there are three methods
554 * in "struct arm", to support individual read/write and bulk read
558 static int arm_dpm_read_core_reg(struct target
*target
, struct reg
*r
,
559 int regnum
, enum arm_mode mode
)
561 struct arm_dpm
*dpm
= target_to_arm(target
)->dpm
;
564 if (regnum
< 0 || regnum
> 16)
565 return ERROR_COMMAND_SYNTAX_ERROR
;
568 if (mode
!= ARM_MODE_ANY
)
571 mode
= dpm_mapmode(dpm
->arm
, regnum
, mode
);
573 /* REVISIT what happens if we try to read SPSR in a core mode
574 * which has no such register?
577 retval
= dpm
->prepare(dpm
);
578 if (retval
!= ERROR_OK
)
581 if (mode
!= ARM_MODE_ANY
) {
582 retval
= dpm_modeswitch(dpm
, mode
);
583 if (retval
!= ERROR_OK
)
587 retval
= dpm_read_reg(dpm
, r
, regnum
);
588 if (retval
!= ERROR_OK
)
590 /* always clean up, regardless of error */
592 if (mode
!= ARM_MODE_ANY
)
593 /* (void) */ dpm_modeswitch(dpm
, ARM_MODE_ANY
);
596 /* (void) */ dpm
->finish(dpm
);
600 static int arm_dpm_write_core_reg(struct target
*target
, struct reg
*r
,
601 int regnum
, enum arm_mode mode
, uint8_t *value
)
603 struct arm_dpm
*dpm
= target_to_arm(target
)->dpm
;
607 if (regnum
< 0 || regnum
> 16)
608 return ERROR_COMMAND_SYNTAX_ERROR
;
611 if (mode
!= ARM_MODE_ANY
)
614 mode
= dpm_mapmode(dpm
->arm
, regnum
, mode
);
616 /* REVISIT what happens if we try to write SPSR in a core mode
617 * which has no such register?
620 retval
= dpm
->prepare(dpm
);
621 if (retval
!= ERROR_OK
)
624 if (mode
!= ARM_MODE_ANY
) {
625 retval
= dpm_modeswitch(dpm
, mode
);
626 if (retval
!= ERROR_OK
)
630 retval
= dpm_write_reg(dpm
, r
, regnum
);
631 /* always clean up, regardless of error */
633 if (mode
!= ARM_MODE_ANY
)
634 /* (void) */ dpm_modeswitch(dpm
, ARM_MODE_ANY
);
637 /* (void) */ dpm
->finish(dpm
);
641 static int arm_dpm_full_context(struct target
*target
)
643 struct arm
*arm
= target_to_arm(target
);
644 struct arm_dpm
*dpm
= arm
->dpm
;
645 struct reg_cache
*cache
= arm
->core_cache
;
649 retval
= dpm
->prepare(dpm
);
650 if (retval
!= ERROR_OK
)
654 enum arm_mode mode
= ARM_MODE_ANY
;
658 /* We "know" arm_dpm_read_current_registers() was called so
659 * the unmapped registers (R0..R7, PC, AND CPSR) and some
660 * view of R8..R14 are current. We also "know" oddities of
661 * register mapping: special cases for R8..R12 and SPSR.
663 * Pick some mode with unread registers and read them all.
666 for (unsigned i
= 0; i
< cache
->num_regs
; i
++) {
669 if (cache
->reg_list
[i
].valid
)
671 r
= cache
->reg_list
[i
].arch_info
;
673 /* may need to pick a mode and set CPSR */
678 /* For regular (ARM_MODE_ANY) R8..R12
679 * in case we've entered debug state
680 * in FIQ mode we need to patch mode.
682 if (mode
!= ARM_MODE_ANY
)
683 retval
= dpm_modeswitch(dpm
, mode
);
685 retval
= dpm_modeswitch(dpm
, ARM_MODE_USR
);
687 if (retval
!= ERROR_OK
)
693 /* CPSR was read, so "R16" must mean SPSR */
694 retval
= dpm_read_reg(dpm
,
696 (r
->num
== 16) ? 17 : r
->num
);
697 if (retval
!= ERROR_OK
)
703 retval
= dpm_modeswitch(dpm
, ARM_MODE_ANY
);
704 /* (void) */ dpm
->finish(dpm
);
710 /*----------------------------------------------------------------------*/
713 * Breakpoint and Watchpoint support.
715 * Hardware {break,watch}points are usually left active, to minimize
716 * debug entry/exit costs. When they are set or cleared, it's done in
717 * batches. Also, DPM-conformant hardware can update debug registers
718 * regardless of whether the CPU is running or halted ... though that
719 * fact isn't currently leveraged.
722 static int dpm_bpwp_setup(struct arm_dpm
*dpm
, struct dpm_bpwp
*xp
,
723 uint32_t addr
, uint32_t length
)
727 control
= (1 << 0) /* enable */
728 | (3 << 1); /* both user and privileged access */
730 /* Match 1, 2, or all 4 byte addresses in this word.
732 * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP.
733 * Support larger length, when addr is suitably aligned. In
734 * particular, allow watchpoints on 8 byte "double" values.
736 * REVISIT allow watchpoints on unaligned 2-bit values; and on
737 * v7 hardware, unaligned 4-byte ones too.
741 control
|= (1 << (addr
& 3)) << 5;
744 /* require 2-byte alignment */
746 control
|= (3 << (addr
& 2)) << 5;
751 /* require 4-byte alignment */
758 LOG_ERROR("unsupported {break,watch}point length/alignment");
759 return ERROR_COMMAND_SYNTAX_ERROR
;
762 /* other shared control bits:
763 * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
764 * bit 20 == 0 ... not linked to a context ID
765 * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
768 xp
->address
= addr
& ~3;
769 xp
->control
= control
;
772 LOG_DEBUG("BPWP: addr %8.8" PRIx32
", control %" PRIx32
", number %d",
773 xp
->address
, control
, xp
->number
);
775 /* hardware is updated in write_dirty_registers() */
779 static int dpm_add_breakpoint(struct target
*target
, struct breakpoint
*bp
)
781 struct arm
*arm
= target_to_arm(target
);
782 struct arm_dpm
*dpm
= arm
->dpm
;
783 int retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
786 return ERROR_COMMAND_SYNTAX_ERROR
;
787 if (!dpm
->bpwp_enable
)
790 /* FIXME we need a generic solution for software breakpoints. */
791 if (bp
->type
== BKPT_SOFT
)
792 LOG_DEBUG("using HW bkpt, not SW...");
794 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
795 if (!dpm
->dbp
[i
].bp
) {
796 retval
= dpm_bpwp_setup(dpm
, &dpm
->dbp
[i
].bpwp
,
797 bp
->address
, bp
->length
);
798 if (retval
== ERROR_OK
)
807 static int dpm_remove_breakpoint(struct target
*target
, struct breakpoint
*bp
)
809 struct arm
*arm
= target_to_arm(target
);
810 struct arm_dpm
*dpm
= arm
->dpm
;
811 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
813 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
814 if (dpm
->dbp
[i
].bp
== bp
) {
815 dpm
->dbp
[i
].bp
= NULL
;
816 dpm
->dbp
[i
].bpwp
.dirty
= true;
818 /* hardware is updated in write_dirty_registers() */
827 static int dpm_watchpoint_setup(struct arm_dpm
*dpm
, unsigned index_t
,
828 struct watchpoint
*wp
)
831 struct dpm_wp
*dwp
= dpm
->dwp
+ index_t
;
834 /* this hardware doesn't support data value matching or masking */
835 if (wp
->value
|| wp
->mask
!= ~(uint32_t)0) {
836 LOG_DEBUG("watchpoint values and masking not supported");
837 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
840 retval
= dpm_bpwp_setup(dpm
, &dwp
->bpwp
, wp
->address
, wp
->length
);
841 if (retval
!= ERROR_OK
)
844 control
= dwp
->bpwp
.control
;
856 dwp
->bpwp
.control
= control
;
858 dpm
->dwp
[index_t
].wp
= wp
;
863 static int dpm_add_watchpoint(struct target
*target
, struct watchpoint
*wp
)
865 struct arm
*arm
= target_to_arm(target
);
866 struct arm_dpm
*dpm
= arm
->dpm
;
867 int retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
869 if (dpm
->bpwp_enable
) {
870 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
871 if (!dpm
->dwp
[i
].wp
) {
872 retval
= dpm_watchpoint_setup(dpm
, i
, wp
);
881 static int dpm_remove_watchpoint(struct target
*target
, struct watchpoint
*wp
)
883 struct arm
*arm
= target_to_arm(target
);
884 struct arm_dpm
*dpm
= arm
->dpm
;
885 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
887 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
888 if (dpm
->dwp
[i
].wp
== wp
) {
889 dpm
->dwp
[i
].wp
= NULL
;
890 dpm
->dwp
[i
].bpwp
.dirty
= true;
892 /* hardware is updated in write_dirty_registers() */
901 void arm_dpm_report_wfar(struct arm_dpm
*dpm
, uint32_t addr
)
903 switch (dpm
->arm
->core_state
) {
907 case ARM_STATE_THUMB
:
908 case ARM_STATE_THUMB_EE
:
911 case ARM_STATE_JAZELLE
:
912 case ARM_STATE_AARCH64
:
919 /*----------------------------------------------------------------------*/
922 * Other debug and support utilities
925 void arm_dpm_report_dscr(struct arm_dpm
*dpm
, uint32_t dscr
)
927 struct target
*target
= dpm
->arm
->target
;
931 /* Examine debug reason */
932 switch (DSCR_ENTRY(dscr
)) {
933 case DSCR_ENTRY_HALT_REQ
: /* HALT request from debugger */
934 case DSCR_ENTRY_EXT_DBG_REQ
: /* EDBGRQ */
935 target
->debug_reason
= DBG_REASON_DBGRQ
;
937 case DSCR_ENTRY_BREAKPOINT
: /* HW breakpoint */
938 case DSCR_ENTRY_BKPT_INSTR
: /* vector catch */
939 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
941 case DSCR_ENTRY_IMPRECISE_WATCHPT
: /* asynch watchpoint */
942 case DSCR_ENTRY_PRECISE_WATCHPT
:/* precise watchpoint */
943 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
946 target
->debug_reason
= DBG_REASON_UNDEFINED
;
951 /*----------------------------------------------------------------------*/
954 * Setup and management support.
958 * Hooks up this DPM to its associated target; call only once.
959 * Initially this only covers the register cache.
961 * Oh, and watchpoints. Yeah.
963 int arm_dpm_setup(struct arm_dpm
*dpm
)
965 struct arm
*arm
= dpm
->arm
;
966 struct target
*target
= arm
->target
;
967 struct reg_cache
*cache
= 0;
971 /* register access setup */
972 arm
->full_context
= arm_dpm_full_context
;
973 arm
->read_core_reg
= arm_dpm_read_core_reg
;
974 arm
->write_core_reg
= arm_dpm_write_core_reg
;
976 if (arm
->core_cache
== NULL
) {
977 cache
= arm_build_reg_cache(target
, arm
);
981 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
984 /* coprocessor access setup */
988 /* breakpoint setup -- optional until it works everywhere */
989 if (!target
->type
->add_breakpoint
) {
990 target
->type
->add_breakpoint
= dpm_add_breakpoint
;
991 target
->type
->remove_breakpoint
= dpm_remove_breakpoint
;
994 /* watchpoint setup */
995 target
->type
->add_watchpoint
= dpm_add_watchpoint
;
996 target
->type
->remove_watchpoint
= dpm_remove_watchpoint
;
998 /* FIXME add vector catch support */
1000 dpm
->nbp
= 1 + ((dpm
->didr
>> 24) & 0xf);
1001 dpm
->nwp
= 1 + ((dpm
->didr
>> 28) & 0xf);
1002 dpm
->dbp
= calloc(dpm
->nbp
, sizeof *dpm
->dbp
);
1003 dpm
->dwp
= calloc(dpm
->nwp
, sizeof *dpm
->dwp
);
1005 if (!dpm
->dbp
|| !dpm
->dwp
) {
1011 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
1012 target_name(target
), dpm
->nbp
, dpm
->nwp
);
1014 /* REVISIT ... and some of those breakpoints could match
1015 * execution context IDs...
1022 * Reinitializes DPM state at the beginning of a new debug session
1023 * or after a reset which may have affected the debug module.
1025 int arm_dpm_initialize(struct arm_dpm
*dpm
)
1027 /* Disable all breakpoints and watchpoints at startup. */
1028 if (dpm
->bpwp_disable
) {
1031 for (i
= 0; i
< dpm
->nbp
; i
++) {
1032 dpm
->dbp
[i
].bpwp
.number
= i
;
1033 (void) dpm
->bpwp_disable(dpm
, i
);
1035 for (i
= 0; i
< dpm
->nwp
; i
++) {
1036 dpm
->dwp
[i
].bpwp
.number
= 16 + i
;
1037 (void) dpm
->bpwp_disable(dpm
, 16 + i
);
1040 LOG_WARNING("%s: can't disable breakpoints and watchpoints",
1041 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)