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 <jtag/jtag.h>
26 #include "breakpoints.h"
27 #include "target_type.h"
28 #include "arm_opcodes.h"
33 * Implements various ARM DPM operations using architectural debug registers.
34 * These routines layer over core-specific communication methods to cope with
35 * implementation differences between cores like ARM1136 and Cortex-A8.
37 * The "Debug Programmers' Model" (DPM) for ARMv6 and ARMv7 is defined by
38 * Part C (Debug Architecture) of the ARM Architecture Reference Manual,
39 * ARMv7-A and ARMv7-R edition (ARM DDI 0406B). In OpenOCD, DPM operations
40 * are abstracted through internal programming interfaces to share code and
41 * to minimize needless differences in debug behavior between cores.
44 /*----------------------------------------------------------------------*/
50 /* Read coprocessor */
51 static int dpm_mrc(struct target
*target
, int cpnum
,
52 uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
,
55 struct arm
*arm
= target_to_arm(target
);
56 struct arm_dpm
*dpm
= arm
->dpm
;
59 retval
= dpm
->prepare(dpm
);
60 if (retval
!= ERROR_OK
)
63 LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum
,
65 (int) CRm
, (int) op2
);
67 /* read coprocessor register into R0; return via DCC */
68 retval
= dpm
->instr_read_data_r0(dpm
,
69 ARMV4_5_MRC(cpnum
, op1
, 0, CRn
, CRm
, op2
),
72 /* (void) */ dpm
->finish(dpm
);
76 static int dpm_mcr(struct target
*target
, int cpnum
,
77 uint32_t op1
, uint32_t op2
, uint32_t CRn
, uint32_t CRm
,
80 struct arm
*arm
= target_to_arm(target
);
81 struct arm_dpm
*dpm
= arm
->dpm
;
84 retval
= dpm
->prepare(dpm
);
85 if (retval
!= ERROR_OK
)
88 LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum
,
90 (int) CRm
, (int) op2
);
92 /* read DCC into r0; then write coprocessor register from R0 */
93 retval
= dpm
->instr_write_data_r0(dpm
,
94 ARMV4_5_MCR(cpnum
, op1
, 0, CRn
, CRm
, op2
),
97 /* (void) */ dpm
->finish(dpm
);
101 /*----------------------------------------------------------------------*/
104 * Register access utilities
107 /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one.
108 * Routines *must* restore the original mode before returning!!
110 int dpm_modeswitch(struct arm_dpm
*dpm
, enum arm_mode mode
)
115 /* restore previous mode */
116 if (mode
== ARM_MODE_ANY
)
117 cpsr
= buf_get_u32(dpm
->arm
->cpsr
->value
, 0, 32);
119 /* else force to the specified mode */
123 retval
= dpm
->instr_write_data_r0(dpm
, ARMV4_5_MSR_GP(0, 0xf, 0), cpsr
);
124 if (retval
!= ERROR_OK
)
127 if (dpm
->instr_cpsr_sync
)
128 retval
= dpm
->instr_cpsr_sync(dpm
);
133 /* just read the register -- rely on the core mode being right */
134 static int dpm_read_reg(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
141 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
142 retval
= dpm
->instr_read_data_dcc(dpm
,
143 ARMV4_5_MCR(14, 0, regnum
, 0, 5, 0),
147 * "MOV r0, pc"; then return via DCC */
148 retval
= dpm
->instr_read_data_r0(dpm
, 0xe1a0000f, &value
);
150 /* NOTE: this seems like a slightly awkward place to update
151 * this value ... but if the PC gets written (the only way
152 * to change what we compute), the arch spec says subsequent
153 * reads return values which are "unpredictable". So this
154 * is always right except in those broken-by-intent cases.
156 switch (dpm
->arm
->core_state
) {
160 case ARM_STATE_THUMB
:
161 case ARM_STATE_THUMB_EE
:
164 case ARM_STATE_JAZELLE
:
165 /* core-specific ... ? */
166 LOG_WARNING("Jazelle PC adjustment unknown");
171 /* 16: "MRS r0, CPSR"; then return via DCC
172 * 17: "MRS r0, SPSR"; then return via DCC
174 retval
= dpm
->instr_read_data_r0(dpm
,
175 ARMV4_5_MRS(0, regnum
& 1),
180 if (retval
== ERROR_OK
) {
181 buf_set_u32(r
->value
, 0, 32, value
);
184 LOG_DEBUG("READ: %s, %8.8x", r
->name
, (unsigned) value
);
190 /* just write the register -- rely on the core mode being right */
191 static int dpm_write_reg(struct arm_dpm
*dpm
, struct reg
*r
, unsigned regnum
)
194 uint32_t value
= buf_get_u32(r
->value
, 0, 32);
198 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
199 retval
= dpm
->instr_write_data_dcc(dpm
,
200 ARMV4_5_MRC(14, 0, regnum
, 0, 5, 0),
204 * read r0 from DCC; then "MOV pc, r0" */
205 retval
= dpm
->instr_write_data_r0(dpm
, 0xe1a0f000, value
);
208 /* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf"
209 * 17: read r0 from DCC, then "MSR r0, SPSR_cxsf"
211 retval
= dpm
->instr_write_data_r0(dpm
,
212 ARMV4_5_MSR_GP(0, 0xf, regnum
& 1),
214 if (retval
!= ERROR_OK
)
217 if (regnum
== 16 && dpm
->instr_cpsr_sync
)
218 retval
= dpm
->instr_cpsr_sync(dpm
);
223 if (retval
== ERROR_OK
) {
225 LOG_DEBUG("WRITE: %s, %8.8x", r
->name
, (unsigned) value
);
232 * Read basic registers of the the current context: R0 to R15, and CPSR;
233 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
234 * In normal operation this is called on entry to halting debug state,
235 * possibly after some other operations supporting restore of debug state
236 * or making sure the CPU is fully idle (drain write buffer, etc).
238 int arm_dpm_read_current_registers(struct arm_dpm
*dpm
)
240 struct arm
*arm
= dpm
->arm
;
245 retval
= dpm
->prepare(dpm
);
246 if (retval
!= ERROR_OK
)
249 /* read R0 first (it's used for scratch), then CPSR */
250 r
= arm
->core_cache
->reg_list
+ 0;
252 retval
= dpm_read_reg(dpm
, r
, 0);
253 if (retval
!= ERROR_OK
)
258 retval
= dpm
->instr_read_data_r0(dpm
, ARMV4_5_MRS(0, 0), &cpsr
);
259 if (retval
!= ERROR_OK
)
262 /* update core mode and state, plus shadow mapping for R8..R14 */
263 arm_set_cpsr(arm
, cpsr
);
265 /* REVISIT we can probably avoid reading R1..R14, saving time... */
266 for (unsigned i
= 1; i
< 16; i
++) {
267 r
= arm_reg_current(arm
, i
);
271 retval
= dpm_read_reg(dpm
, r
, i
);
272 if (retval
!= ERROR_OK
)
276 /* NOTE: SPSR ignored (if it's even relevant). */
278 /* REVISIT the debugger can trigger various exceptions. See the
279 * ARMv7A architecture spec, section C5.7, for more info about
280 * what defenses are needed; v6 debug has the most issues.
284 /* (void) */ dpm
->finish(dpm
);
288 /* Avoid needless I/O ... leave breakpoints and watchpoints alone
289 * unless they're removed, or need updating because of single-stepping
290 * or running debugger code.
292 static int dpm_maybe_update_bpwp(struct arm_dpm
*dpm
, bool bpwp
,
293 struct dpm_bpwp
*xp
, int *set_p
)
295 int retval
= ERROR_OK
;
302 /* removed or startup; we must disable it */
307 /* disabled, but we must set it */
308 xp
->dirty
= disable
= false;
313 /* set, but we must temporarily disable it */
314 xp
->dirty
= disable
= true;
319 retval
= dpm
->bpwp_disable(dpm
, xp
->number
);
321 retval
= dpm
->bpwp_enable(dpm
, xp
->number
,
322 xp
->address
, xp
->control
);
324 if (retval
!= ERROR_OK
)
325 LOG_ERROR("%s: can't %s HW %spoint %d",
326 disable
? "disable" : "enable",
327 target_name(dpm
->arm
->target
),
328 (xp
->number
< 16) ? "break" : "watch",
334 static int dpm_add_breakpoint(struct target
*target
, struct breakpoint
*bp
);
337 * Writes all modified core registers for all processor modes. In normal
338 * operation this is called on exit from halting debug state.
340 * @param dpm: represents the processor
341 * @param bpwp: true ensures breakpoints and watchpoints are set,
342 * false ensures they are cleared
344 int arm_dpm_write_dirty_registers(struct arm_dpm
*dpm
, bool bpwp
)
346 struct arm
*arm
= dpm
->arm
;
347 struct reg_cache
*cache
= arm
->core_cache
;
351 retval
= dpm
->prepare(dpm
);
352 if (retval
!= ERROR_OK
)
355 /* If we're managing hardware breakpoints for this core, enable
356 * or disable them as requested.
358 * REVISIT We don't yet manage them for ANY cores. Eventually
359 * we should be able to assume we handle them; but until then,
360 * cope with the hand-crafted breakpoint code.
362 if (arm
->target
->type
->add_breakpoint
== dpm_add_breakpoint
) {
363 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
364 struct dpm_bp
*dbp
= dpm
->dbp
+ i
;
365 struct breakpoint
*bp
= dbp
->bp
;
367 retval
= dpm_maybe_update_bpwp(dpm
, bpwp
, &dbp
->bpwp
,
368 bp
? &bp
->set
: NULL
);
369 if (retval
!= ERROR_OK
)
374 /* enable/disable watchpoints */
375 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
376 struct dpm_wp
*dwp
= dpm
->dwp
+ i
;
377 struct watchpoint
*wp
= dwp
->wp
;
379 retval
= dpm_maybe_update_bpwp(dpm
, bpwp
, &dwp
->bpwp
,
380 wp
? &wp
->set
: NULL
);
381 if (retval
!= ERROR_OK
)
385 /* NOTE: writes to breakpoint and watchpoint registers might
386 * be queued, and need (efficient/batched) flushing later.
389 /* Scan the registers until we find one that's both dirty and
390 * eligible for flushing. Flush that and everything else that
391 * shares the same core mode setting. Typically this won't
392 * actually find anything to do...
395 enum arm_mode mode
= ARM_MODE_ANY
;
399 /* check everything except our scratch register R0 */
400 for (unsigned i
= 1; i
< cache
->num_regs
; i
++) {
404 /* also skip PC, CPSR, and non-dirty */
407 if (arm
->cpsr
== cache
->reg_list
+ i
)
409 if (!cache
->reg_list
[i
].dirty
)
412 r
= cache
->reg_list
[i
].arch_info
;
415 /* may need to pick and set a mode */
420 mode
= tmode
= r
->mode
;
422 /* cope with special cases */
425 /* r8..r12 "anything but FIQ" case;
426 * we "know" core mode is accurate
427 * since we haven't changed it yet
429 if (arm
->core_mode
== ARM_MODE_FIQ
432 tmode
= ARM_MODE_USR
;
440 /* REVISIT error checks */
441 if (tmode
!= ARM_MODE_ANY
) {
442 retval
= dpm_modeswitch(dpm
, tmode
);
443 if (retval
!= ERROR_OK
)
450 retval
= dpm_write_reg(dpm
,
453 if (retval
!= ERROR_OK
)
459 /* Restore original CPSR ... assuming either that we changed it,
460 * or it's dirty. Must write PC to ensure the return address is
461 * defined, and must not write it before CPSR.
463 retval
= dpm_modeswitch(dpm
, ARM_MODE_ANY
);
464 if (retval
!= ERROR_OK
)
466 arm
->cpsr
->dirty
= false;
468 retval
= dpm_write_reg(dpm
, arm
->pc
, 15);
469 if (retval
!= ERROR_OK
)
471 arm
->pc
->dirty
= false;
473 /* flush R0 -- it's *very* dirty by now */
474 retval
= dpm_write_reg(dpm
, &cache
->reg_list
[0], 0);
475 if (retval
!= ERROR_OK
)
477 cache
->reg_list
[0].dirty
= false;
479 /* (void) */ dpm
->finish(dpm
);
484 /* Returns ARM_MODE_ANY or temporary mode to use while reading the
485 * specified register ... works around flakiness from ARM core calls.
486 * Caller already filtered out SPSR access; mode is never MODE_SYS
489 static enum arm_mode
dpm_mapmode(struct arm
*arm
,
490 unsigned num
, enum arm_mode mode
)
492 enum arm_mode amode
= arm
->core_mode
;
494 /* don't switch if the mode is already correct */
495 if (amode
== ARM_MODE_SYS
)
496 amode
= ARM_MODE_USR
;
501 /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */
506 /* r8..r12 aren't shadowed for anything except FIQ */
508 if (mode
== ARM_MODE_FIQ
)
511 /* r13/sp, and r14/lr are always shadowed */
516 LOG_WARNING("invalid register #%u", num
);
524 * Standard ARM register accessors ... there are three methods
525 * in "struct arm", to support individual read/write and bulk read
529 static int arm_dpm_read_core_reg(struct target
*target
, struct reg
*r
,
530 int regnum
, enum arm_mode mode
)
532 struct arm_dpm
*dpm
= target_to_arm(target
)->dpm
;
535 if (regnum
< 0 || regnum
> 16)
536 return ERROR_COMMAND_SYNTAX_ERROR
;
539 if (mode
!= ARM_MODE_ANY
)
542 mode
= dpm_mapmode(dpm
->arm
, regnum
, mode
);
544 /* REVISIT what happens if we try to read SPSR in a core mode
545 * which has no such register?
548 retval
= dpm
->prepare(dpm
);
549 if (retval
!= ERROR_OK
)
552 if (mode
!= ARM_MODE_ANY
) {
553 retval
= dpm_modeswitch(dpm
, mode
);
554 if (retval
!= ERROR_OK
)
558 retval
= dpm_read_reg(dpm
, r
, regnum
);
559 if (retval
!= ERROR_OK
)
561 /* always clean up, regardless of error */
563 if (mode
!= ARM_MODE_ANY
)
564 /* (void) */ dpm_modeswitch(dpm
, ARM_MODE_ANY
);
567 /* (void) */ dpm
->finish(dpm
);
571 static int arm_dpm_write_core_reg(struct target
*target
, struct reg
*r
,
572 int regnum
, enum arm_mode mode
, uint8_t *value
)
574 struct arm_dpm
*dpm
= target_to_arm(target
)->dpm
;
578 if (regnum
< 0 || regnum
> 16)
579 return ERROR_COMMAND_SYNTAX_ERROR
;
582 if (mode
!= ARM_MODE_ANY
)
585 mode
= dpm_mapmode(dpm
->arm
, regnum
, mode
);
587 /* REVISIT what happens if we try to write SPSR in a core mode
588 * which has no such register?
591 retval
= dpm
->prepare(dpm
);
592 if (retval
!= ERROR_OK
)
595 if (mode
!= ARM_MODE_ANY
) {
596 retval
= dpm_modeswitch(dpm
, mode
);
597 if (retval
!= ERROR_OK
)
601 retval
= dpm_write_reg(dpm
, r
, regnum
);
602 /* always clean up, regardless of error */
604 if (mode
!= ARM_MODE_ANY
)
605 /* (void) */ dpm_modeswitch(dpm
, ARM_MODE_ANY
);
608 /* (void) */ dpm
->finish(dpm
);
612 static int arm_dpm_full_context(struct target
*target
)
614 struct arm
*arm
= target_to_arm(target
);
615 struct arm_dpm
*dpm
= arm
->dpm
;
616 struct reg_cache
*cache
= arm
->core_cache
;
620 retval
= dpm
->prepare(dpm
);
621 if (retval
!= ERROR_OK
)
625 enum arm_mode mode
= ARM_MODE_ANY
;
629 /* We "know" arm_dpm_read_current_registers() was called so
630 * the unmapped registers (R0..R7, PC, AND CPSR) and some
631 * view of R8..R14 are current. We also "know" oddities of
632 * register mapping: special cases for R8..R12 and SPSR.
634 * Pick some mode with unread registers and read them all.
637 for (unsigned i
= 0; i
< cache
->num_regs
; i
++) {
640 if (cache
->reg_list
[i
].valid
)
642 r
= cache
->reg_list
[i
].arch_info
;
644 /* may need to pick a mode and set CPSR */
649 /* For regular (ARM_MODE_ANY) R8..R12
650 * in case we've entered debug state
651 * in FIQ mode we need to patch mode.
653 if (mode
!= ARM_MODE_ANY
)
654 retval
= dpm_modeswitch(dpm
, mode
);
656 retval
= dpm_modeswitch(dpm
, ARM_MODE_USR
);
658 if (retval
!= ERROR_OK
)
664 /* CPSR was read, so "R16" must mean SPSR */
665 retval
= dpm_read_reg(dpm
,
667 (r
->num
== 16) ? 17 : r
->num
);
668 if (retval
!= ERROR_OK
)
674 retval
= dpm_modeswitch(dpm
, ARM_MODE_ANY
);
675 /* (void) */ dpm
->finish(dpm
);
681 /*----------------------------------------------------------------------*/
684 * Breakpoint and Watchpoint support.
686 * Hardware {break,watch}points are usually left active, to minimize
687 * debug entry/exit costs. When they are set or cleared, it's done in
688 * batches. Also, DPM-conformant hardware can update debug registers
689 * regardless of whether the CPU is running or halted ... though that
690 * fact isn't currently leveraged.
693 static int dpm_bpwp_setup(struct arm_dpm
*dpm
, struct dpm_bpwp
*xp
,
694 uint32_t addr
, uint32_t length
)
698 control
= (1 << 0) /* enable */
699 | (3 << 1); /* both user and privileged access */
701 /* Match 1, 2, or all 4 byte addresses in this word.
703 * FIXME: v7 hardware allows lengths up to 2 GB for BP and WP.
704 * Support larger length, when addr is suitably aligned. In
705 * particular, allow watchpoints on 8 byte "double" values.
707 * REVISIT allow watchpoints on unaligned 2-bit values; and on
708 * v7 hardware, unaligned 4-byte ones too.
712 control
|= (1 << (addr
& 3)) << 5;
715 /* require 2-byte alignment */
717 control
|= (3 << (addr
& 2)) << 5;
722 /* require 4-byte alignment */
729 LOG_ERROR("unsupported {break,watch}point length/alignment");
730 return ERROR_COMMAND_SYNTAX_ERROR
;
733 /* other shared control bits:
734 * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
735 * bit 20 == 0 ... not linked to a context ID
736 * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
739 xp
->address
= addr
& ~3;
740 xp
->control
= control
;
743 LOG_DEBUG("BPWP: addr %8.8" PRIx32
", control %" PRIx32
", number %d",
744 xp
->address
, control
, xp
->number
);
746 /* hardware is updated in write_dirty_registers() */
750 static int dpm_add_breakpoint(struct target
*target
, struct breakpoint
*bp
)
752 struct arm
*arm
= target_to_arm(target
);
753 struct arm_dpm
*dpm
= arm
->dpm
;
754 int retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
757 return ERROR_COMMAND_SYNTAX_ERROR
;
758 if (!dpm
->bpwp_enable
)
761 /* FIXME we need a generic solution for software breakpoints. */
762 if (bp
->type
== BKPT_SOFT
)
763 LOG_DEBUG("using HW bkpt, not SW...");
765 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
766 if (!dpm
->dbp
[i
].bp
) {
767 retval
= dpm_bpwp_setup(dpm
, &dpm
->dbp
[i
].bpwp
,
768 bp
->address
, bp
->length
);
769 if (retval
== ERROR_OK
)
778 static int dpm_remove_breakpoint(struct target
*target
, struct breakpoint
*bp
)
780 struct arm
*arm
= target_to_arm(target
);
781 struct arm_dpm
*dpm
= arm
->dpm
;
782 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
784 for (unsigned i
= 0; i
< dpm
->nbp
; i
++) {
785 if (dpm
->dbp
[i
].bp
== bp
) {
786 dpm
->dbp
[i
].bp
= NULL
;
787 dpm
->dbp
[i
].bpwp
.dirty
= true;
789 /* hardware is updated in write_dirty_registers() */
798 static int dpm_watchpoint_setup(struct arm_dpm
*dpm
, unsigned index_t
,
799 struct watchpoint
*wp
)
802 struct dpm_wp
*dwp
= dpm
->dwp
+ index_t
;
805 /* this hardware doesn't support data value matching or masking */
806 if (wp
->value
|| wp
->mask
!= ~(uint32_t)0) {
807 LOG_DEBUG("watchpoint values and masking not supported");
808 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
811 retval
= dpm_bpwp_setup(dpm
, &dwp
->bpwp
, wp
->address
, wp
->length
);
812 if (retval
!= ERROR_OK
)
815 control
= dwp
->bpwp
.control
;
827 dwp
->bpwp
.control
= control
;
829 dpm
->dwp
[index_t
].wp
= wp
;
834 static int dpm_add_watchpoint(struct target
*target
, struct watchpoint
*wp
)
836 struct arm
*arm
= target_to_arm(target
);
837 struct arm_dpm
*dpm
= arm
->dpm
;
838 int retval
= ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
840 if (dpm
->bpwp_enable
) {
841 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
842 if (!dpm
->dwp
[i
].wp
) {
843 retval
= dpm_watchpoint_setup(dpm
, i
, wp
);
852 static int dpm_remove_watchpoint(struct target
*target
, struct watchpoint
*wp
)
854 struct arm
*arm
= target_to_arm(target
);
855 struct arm_dpm
*dpm
= arm
->dpm
;
856 int retval
= ERROR_COMMAND_SYNTAX_ERROR
;
858 for (unsigned i
= 0; i
< dpm
->nwp
; i
++) {
859 if (dpm
->dwp
[i
].wp
== wp
) {
860 dpm
->dwp
[i
].wp
= NULL
;
861 dpm
->dwp
[i
].bpwp
.dirty
= true;
863 /* hardware is updated in write_dirty_registers() */
872 void arm_dpm_report_wfar(struct arm_dpm
*dpm
, uint32_t addr
)
874 switch (dpm
->arm
->core_state
) {
878 case ARM_STATE_THUMB
:
879 case ARM_STATE_THUMB_EE
:
882 case ARM_STATE_JAZELLE
:
889 /*----------------------------------------------------------------------*/
892 * Other debug and support utilities
895 void arm_dpm_report_dscr(struct arm_dpm
*dpm
, uint32_t dscr
)
897 struct target
*target
= dpm
->arm
->target
;
901 /* Examine debug reason */
902 switch (DSCR_ENTRY(dscr
)) {
903 case 6: /* Data abort (v6 only) */
904 case 7: /* Prefetch abort (v6 only) */
905 /* FALL THROUGH -- assume a v6 core in abort mode */
906 case 0: /* HALT request from debugger */
908 target
->debug_reason
= DBG_REASON_DBGRQ
;
910 case 1: /* HW breakpoint */
911 case 3: /* SW BKPT */
912 case 5: /* vector catch */
913 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
915 case 2: /* asynch watchpoint */
916 case 10:/* precise watchpoint */
917 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
920 target
->debug_reason
= DBG_REASON_UNDEFINED
;
925 /*----------------------------------------------------------------------*/
928 * Setup and management support.
932 * Hooks up this DPM to its associated target; call only once.
933 * Initially this only covers the register cache.
935 * Oh, and watchpoints. Yeah.
937 int arm_dpm_setup(struct arm_dpm
*dpm
)
939 struct arm
*arm
= dpm
->arm
;
940 struct target
*target
= arm
->target
;
941 struct reg_cache
*cache
;
945 /* register access setup */
946 arm
->full_context
= arm_dpm_full_context
;
947 arm
->read_core_reg
= arm_dpm_read_core_reg
;
948 arm
->write_core_reg
= arm_dpm_write_core_reg
;
950 cache
= arm_build_reg_cache(target
, arm
);
954 *register_get_last_cache_p(&target
->reg_cache
) = cache
;
956 /* coprocessor access setup */
960 /* breakpoint setup -- optional until it works everywhere */
961 if (!target
->type
->add_breakpoint
) {
962 target
->type
->add_breakpoint
= dpm_add_breakpoint
;
963 target
->type
->remove_breakpoint
= dpm_remove_breakpoint
;
966 /* watchpoint setup */
967 target
->type
->add_watchpoint
= dpm_add_watchpoint
;
968 target
->type
->remove_watchpoint
= dpm_remove_watchpoint
;
970 /* FIXME add vector catch support */
972 dpm
->nbp
= 1 + ((dpm
->didr
>> 24) & 0xf);
973 dpm
->dbp
= calloc(dpm
->nbp
, sizeof *dpm
->dbp
);
975 dpm
->nwp
= 1 + ((dpm
->didr
>> 28) & 0xf);
976 dpm
->dwp
= calloc(dpm
->nwp
, sizeof *dpm
->dwp
);
978 if (!dpm
->dbp
|| !dpm
->dwp
) {
984 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
985 target_name(target
), dpm
->nbp
, dpm
->nwp
);
987 /* REVISIT ... and some of those breakpoints could match
988 * execution context IDs...
995 * Reinitializes DPM state at the beginning of a new debug session
996 * or after a reset which may have affected the debug module.
998 int arm_dpm_initialize(struct arm_dpm
*dpm
)
1000 /* Disable all breakpoints and watchpoints at startup. */
1001 if (dpm
->bpwp_disable
) {
1004 for (i
= 0; i
< dpm
->nbp
; i
++) {
1005 dpm
->dbp
[i
].bpwp
.number
= i
;
1006 (void) dpm
->bpwp_disable(dpm
, i
);
1008 for (i
= 0; i
< dpm
->nwp
; i
++) {
1009 dpm
->dwp
[i
].bpwp
.number
= 16 + i
;
1010 (void) dpm
->bpwp_disable(dpm
, 16 + i
);
1013 LOG_WARNING("%s: can't disable breakpoints and watchpoints",
1014 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)