target: cygwin build fixes
[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, write to the
16 * Free Software Foundation, Inc.,
17 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "armv4_5.h" /* REVISIT to become arm.h */
25 #include "arm_dpm.h"
26 #include <jtag/jtag.h>
27 #include "register.h"
28 #include "breakpoints.h"
29 #include "target_type.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
39 /*----------------------------------------------------------------------*/
40
41 /*
42 * Coprocessor support
43 */
44
45 /* Read coprocessor */
46 static int dpm_mrc(struct target *target, int cpnum,
47 uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm,
48 uint32_t *value)
49 {
50 struct arm *arm = target_to_arm(target);
51 struct arm_dpm *dpm = arm->dpm;
52 int retval;
53
54 retval = dpm->prepare(dpm);
55 if (retval != ERROR_OK)
56 return retval;
57
58 LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum,
59 (int) op1, (int) CRn,
60 (int) CRm, (int) op2);
61
62 /* read coprocessor register into R0; return via DCC */
63 retval = dpm->instr_read_data_r0(dpm,
64 ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2),
65 value);
66
67 /* (void) */ dpm->finish(dpm);
68 return retval;
69 }
70
71 static int dpm_mcr(struct target *target, int cpnum,
72 uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm,
73 uint32_t value)
74 {
75 struct arm *arm = target_to_arm(target);
76 struct arm_dpm *dpm = arm->dpm;
77 int retval;
78
79 retval = dpm->prepare(dpm);
80 if (retval != ERROR_OK)
81 return retval;
82
83 LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum,
84 (int) op1, (int) CRn,
85 (int) CRm, (int) op2);
86
87 /* read DCC into r0; then write coprocessor register from R0 */
88 retval = dpm->instr_write_data_r0(dpm,
89 ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2),
90 value);
91
92 /* (void) */ dpm->finish(dpm);
93 return retval;
94 }
95
96 /*----------------------------------------------------------------------*/
97
98 /*
99 * Register access utilities
100 */
101
102 /* Toggles between recorded core mode (USR, SVC, etc) and a temporary one.
103 * Routines *must* restore the original mode before returning!!
104 */
105 static int dpm_modeswitch(struct arm_dpm *dpm, enum armv4_5_mode mode)
106 {
107 int retval;
108 uint32_t cpsr;
109
110 /* restore previous mode */
111 if (mode == ARMV4_5_MODE_ANY)
112 cpsr = buf_get_u32(dpm->arm->cpsr->value, 0, 32);
113
114 /* else force to the specified mode */
115 else
116 cpsr = mode;
117
118 retval = dpm->instr_write_data_r0(dpm, ARMV4_5_MSR_GP(0, 0xf, 0), cpsr);
119
120 if (dpm->instr_cpsr_sync)
121 retval = dpm->instr_cpsr_sync(dpm);
122
123 return retval;
124 }
125
126 /* just read the register -- rely on the core mode being right */
127 static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
128 {
129 uint32_t value;
130 int retval;
131
132 switch (regnum) {
133 case 0 ... 14:
134 /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
135 retval = dpm->instr_read_data_dcc(dpm,
136 ARMV4_5_MCR(14, 0, regnum, 0, 5, 0),
137 &value);
138 break;
139 case 15: /* PC */
140 /* "MOV r0, pc"; then return via DCC */
141 retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value);
142
143 /* NOTE: this seems like a slightly awkward place to update
144 * this value ... but if the PC gets written (the only way
145 * to change what we compute), the arch spec says subsequent
146 * reads return values which are "unpredictable". So this
147 * is always right except in those broken-by-intent cases.
148 */
149 switch (dpm->arm->core_state) {
150 case ARMV4_5_STATE_ARM:
151 value -= 8;
152 break;
153 case ARMV4_5_STATE_THUMB:
154 case ARM_STATE_THUMB_EE:
155 value -= 4;
156 break;
157 case ARMV4_5_STATE_JAZELLE:
158 /* core-specific ... ? */
159 LOG_WARNING("Jazelle PC adjustment unknown");
160 break;
161 }
162 break;
163 default:
164 /* 16: "MRS r0, CPSR"; then return via DCC
165 * 17: "MRS r0, SPSR"; then return via DCC
166 */
167 retval = dpm->instr_read_data_r0(dpm,
168 ARMV4_5_MRS(0, regnum & 1),
169 &value);
170 break;
171 }
172
173 if (retval == ERROR_OK) {
174 buf_set_u32(r->value, 0, 32, value);
175 r->valid = true;
176 r->dirty = false;
177 LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned) value);
178 }
179
180 return retval;
181 }
182
183 /* just write the register -- rely on the core mode being right */
184 static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
185 {
186 int retval;
187 uint32_t value = buf_get_u32(r->value, 0, 32);
188
189 switch (regnum) {
190 case 0 ... 14:
191 /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
192 retval = dpm->instr_write_data_dcc(dpm,
193 ARMV4_5_MRC(14, 0, regnum, 0, 5, 0),
194 value);
195 break;
196 case 15: /* PC */
197 /* read r0 from DCC; then "MOV pc, r0" */
198 retval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value);
199 break;
200 default:
201 /* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf"
202 * 17: read r0 from DCC, then "MSR r0, SPSR_cxsf"
203 */
204 retval = dpm->instr_write_data_r0(dpm,
205 ARMV4_5_MSR_GP(0, 0xf, regnum & 1),
206 value);
207
208 if (regnum == 16 && dpm->instr_cpsr_sync)
209 retval = dpm->instr_cpsr_sync(dpm);
210
211 break;
212 }
213
214 if (retval == ERROR_OK) {
215 r->dirty = false;
216 LOG_DEBUG("WRITE: %s, %8.8x", r->name, (unsigned) value);
217 }
218
219 return retval;
220 }
221
222 /**
223 * Read basic registers of the the current context: R0 to R15, and CPSR;
224 * sets the core mode (such as USR or IRQ) and state (such as ARM or Thumb).
225 * In normal operation this is called on entry to halting debug state,
226 * possibly after some other operations supporting restore of debug state
227 * or making sure the CPU is fully idle (drain write buffer, etc).
228 */
229 int arm_dpm_read_current_registers(struct arm_dpm *dpm)
230 {
231 struct arm *arm = dpm->arm;
232 uint32_t cpsr;
233 int retval;
234 struct reg *r;
235
236 retval = dpm->prepare(dpm);
237 if (retval != ERROR_OK)
238 return retval;
239
240 /* read R0 first (it's used for scratch), then CPSR */
241 r = arm->core_cache->reg_list + 0;
242 if (!r->valid) {
243 retval = dpm_read_reg(dpm, r, 0);
244 if (retval != ERROR_OK)
245 goto fail;
246 }
247 r->dirty = true;
248
249 retval = dpm->instr_read_data_r0(dpm, ARMV4_5_MRS(0, 0), &cpsr);
250 if (retval != ERROR_OK)
251 goto fail;
252
253 /* update core mode and state, plus shadow mapping for R8..R14 */
254 arm_set_cpsr(arm, cpsr);
255
256 /* REVISIT we can probably avoid reading R1..R14, saving time... */
257 for (unsigned i = 1; i < 16; i++) {
258 r = arm_reg_current(arm, i);
259 if (r->valid)
260 continue;
261
262 retval = dpm_read_reg(dpm, r, i);
263 if (retval != ERROR_OK)
264 goto fail;
265 }
266
267 /* NOTE: SPSR ignored (if it's even relevant). */
268
269 /* REVISIT the debugger can trigger various exceptions. See the
270 * ARMv7A architecture spec, section C5.7, for more info about
271 * what defenses are needed; v6 debug has the most issues.
272 */
273
274 fail:
275 /* (void) */ dpm->finish(dpm);
276 return retval;
277 }
278
279 /**
280 * Writes all modified core registers for all processor modes. In normal
281 * operation this is called on exit from halting debug state.
282 *
283 * @param dpm: represents the processor
284 * @param bpwp: true ensures breakpoints and watchpoints are set,
285 * false ensures they are cleared
286 */
287 int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
288 {
289 struct arm *arm = dpm->arm;
290 struct reg_cache *cache = arm->core_cache;
291 int retval;
292 bool did_write;
293
294 retval = dpm->prepare(dpm);
295 if (retval != ERROR_OK)
296 goto done;
297
298 /* enable/disable watchpoints */
299 for (unsigned i = 0; i < dpm->nwp; i++) {
300 struct dpm_wp *dwp = dpm->dwp + i;
301 struct watchpoint *wp = dwp->wp;
302 bool disable;
303
304 /* Avoid needless I/O ... leave watchpoints alone
305 * unless they're removed, or need updating because
306 * of single-stepping or running debugger code.
307 */
308 if (!wp) {
309 if (!dwp->dirty)
310 continue;
311 dwp->dirty = false;
312 /* removed or startup; we must disable it */
313 disable = true;
314 } else if (bpwp) {
315 if (!dwp->dirty)
316 continue;
317 /* disabled, but we must set it */
318 dwp->dirty = disable = false;
319 wp->set = true;
320 } else {
321 if (!wp->set)
322 continue;
323 /* set, but we must temporarily disable it */
324 dwp->dirty = disable = true;
325 wp->set = false;
326 }
327
328 if (disable)
329 retval = dpm->bpwp_disable(dpm, 16 + i);
330 else
331 retval = dpm->bpwp_enable(dpm, 16 + i,
332 wp->address, dwp->control);
333
334 if (retval != ERROR_OK)
335 LOG_ERROR("%s: can't %s HW watchpoint %d",
336 target_name(arm->target),
337 disable ? "disable" : "enable",
338 i);
339 }
340
341 /* NOTE: writes to breakpoint and watchpoint registers might
342 * be queued, and need (efficient/batched) flushing later.
343 */
344
345 /* Scan the registers until we find one that's both dirty and
346 * eligible for flushing. Flush that and everything else that
347 * shares the same core mode setting. Typically this won't
348 * actually find anything to do...
349 */
350 do {
351 enum armv4_5_mode mode = ARMV4_5_MODE_ANY;
352
353 did_write = false;
354
355 /* check everything except our scratch register R0 */
356 for (unsigned i = 1; i < cache->num_regs; i++) {
357 struct arm_reg *r;
358 unsigned regnum;
359
360 /* also skip PC, CPSR, and non-dirty */
361 if (i == 15)
362 continue;
363 if (arm->cpsr == cache->reg_list + i)
364 continue;
365 if (!cache->reg_list[i].dirty)
366 continue;
367
368 r = cache->reg_list[i].arch_info;
369 regnum = r->num;
370
371 /* may need to pick and set a mode */
372 if (!did_write) {
373 enum armv4_5_mode tmode;
374
375 did_write = true;
376 mode = tmode = r->mode;
377
378 /* cope with special cases */
379 switch (regnum) {
380 case 8 ... 12:
381 /* r8..r12 "anything but FIQ" case;
382 * we "know" core mode is accurate
383 * since we haven't changed it yet
384 */
385 if (arm->core_mode == ARMV4_5_MODE_FIQ
386 && ARMV4_5_MODE_ANY
387 != mode)
388 tmode = ARMV4_5_MODE_USR;
389 break;
390 case 16:
391 /* SPSR */
392 regnum++;
393 break;
394 }
395
396 /* REVISIT error checks */
397 if (tmode != ARMV4_5_MODE_ANY)
398 retval = dpm_modeswitch(dpm, tmode);
399 }
400 if (r->mode != mode)
401 continue;
402
403 retval = dpm_write_reg(dpm,
404 &cache->reg_list[i],
405 regnum);
406
407 }
408
409 } while (did_write);
410
411 /* Restore original CPSR ... assuming either that we changed it,
412 * or it's dirty. Must write PC to ensure the return address is
413 * defined, and must not write it before CPSR.
414 */
415 retval = dpm_modeswitch(dpm, ARMV4_5_MODE_ANY);
416 arm->cpsr->dirty = false;
417
418 retval = dpm_write_reg(dpm, &cache->reg_list[15], 15);
419 cache->reg_list[15].dirty = false;
420
421 /* flush R0 -- it's *very* dirty by now */
422 retval = dpm_write_reg(dpm, &cache->reg_list[0], 0);
423 cache->reg_list[0].dirty = false;
424
425 /* (void) */ dpm->finish(dpm);
426 done:
427 return retval;
428 }
429
430 /* Returns ARMV4_5_MODE_ANY or temporary mode to use while reading the
431 * specified register ... works around flakiness from ARM core calls.
432 * Caller already filtered out SPSR access; mode is never MODE_SYS
433 * or MODE_ANY.
434 */
435 static enum armv4_5_mode dpm_mapmode(struct arm *arm,
436 unsigned num, enum armv4_5_mode mode)
437 {
438 enum armv4_5_mode amode = arm->core_mode;
439
440 /* don't switch if the mode is already correct */
441 if (amode == ARMV4_5_MODE_SYS)
442 amode = ARMV4_5_MODE_USR;
443 if (mode == amode)
444 return ARMV4_5_MODE_ANY;
445
446 switch (num) {
447 /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */
448 case 0 ... 7:
449 case 15:
450 case 16:
451 break;
452 /* r8..r12 aren't shadowed for anything except FIQ */
453 case 8 ... 12:
454 if (mode == ARMV4_5_MODE_FIQ)
455 return mode;
456 break;
457 /* r13/sp, and r14/lr are always shadowed */
458 case 13:
459 case 14:
460 return mode;
461 default:
462 LOG_WARNING("invalid register #%u", num);
463 break;
464 }
465 return ARMV4_5_MODE_ANY;
466 }
467
468
469 /*
470 * Standard ARM register accessors ... there are three methods
471 * in "struct arm", to support individual read/write and bulk read
472 * of registers.
473 */
474
475 static int arm_dpm_read_core_reg(struct target *target, struct reg *r,
476 int regnum, enum armv4_5_mode mode)
477 {
478 struct arm_dpm *dpm = target_to_arm(target)->dpm;
479 int retval;
480
481 if (regnum < 0 || regnum > 16)
482 return ERROR_INVALID_ARGUMENTS;
483
484 if (regnum == 16) {
485 if (mode != ARMV4_5_MODE_ANY)
486 regnum = 17;
487 } else
488 mode = dpm_mapmode(dpm->arm, regnum, mode);
489
490 /* REVISIT what happens if we try to read SPSR in a core mode
491 * which has no such register?
492 */
493
494 retval = dpm->prepare(dpm);
495 if (retval != ERROR_OK)
496 return retval;
497
498 if (mode != ARMV4_5_MODE_ANY) {
499 retval = dpm_modeswitch(dpm, mode);
500 if (retval != ERROR_OK)
501 goto fail;
502 }
503
504 retval = dpm_read_reg(dpm, r, regnum);
505 /* always clean up, regardless of error */
506
507 if (mode != ARMV4_5_MODE_ANY)
508 /* (void) */ dpm_modeswitch(dpm, ARMV4_5_MODE_ANY);
509
510 fail:
511 /* (void) */ dpm->finish(dpm);
512 return retval;
513 }
514
515 static int arm_dpm_write_core_reg(struct target *target, struct reg *r,
516 int regnum, enum armv4_5_mode mode, uint32_t value)
517 {
518 struct arm_dpm *dpm = target_to_arm(target)->dpm;
519 int retval;
520
521
522 if (regnum < 0 || regnum > 16)
523 return ERROR_INVALID_ARGUMENTS;
524
525 if (regnum == 16) {
526 if (mode != ARMV4_5_MODE_ANY)
527 regnum = 17;
528 } else
529 mode = dpm_mapmode(dpm->arm, regnum, mode);
530
531 /* REVISIT what happens if we try to write SPSR in a core mode
532 * which has no such register?
533 */
534
535 retval = dpm->prepare(dpm);
536 if (retval != ERROR_OK)
537 return retval;
538
539 if (mode != ARMV4_5_MODE_ANY) {
540 retval = dpm_modeswitch(dpm, mode);
541 if (retval != ERROR_OK)
542 goto fail;
543 }
544
545 retval = dpm_write_reg(dpm, r, regnum);
546 /* always clean up, regardless of error */
547
548 if (mode != ARMV4_5_MODE_ANY)
549 /* (void) */ dpm_modeswitch(dpm, ARMV4_5_MODE_ANY);
550
551 fail:
552 /* (void) */ dpm->finish(dpm);
553 return retval;
554 }
555
556 static int arm_dpm_full_context(struct target *target)
557 {
558 struct arm *arm = target_to_arm(target);
559 struct arm_dpm *dpm = arm->dpm;
560 struct reg_cache *cache = arm->core_cache;
561 int retval;
562 bool did_read;
563
564 retval = dpm->prepare(dpm);
565 if (retval != ERROR_OK)
566 goto done;
567
568 do {
569 enum armv4_5_mode mode = ARMV4_5_MODE_ANY;
570
571 did_read = false;
572
573 /* We "know" arm_dpm_read_current_registers() was called so
574 * the unmapped registers (R0..R7, PC, AND CPSR) and some
575 * view of R8..R14 are current. We also "know" oddities of
576 * register mapping: special cases for R8..R12 and SPSR.
577 *
578 * Pick some mode with unread registers and read them all.
579 * Repeat until done.
580 */
581 for (unsigned i = 0; i < cache->num_regs; i++) {
582 struct arm_reg *r;
583
584 if (cache->reg_list[i].valid)
585 continue;
586 r = cache->reg_list[i].arch_info;
587
588 /* may need to pick a mode and set CPSR */
589 if (!did_read) {
590 did_read = true;
591 mode = r->mode;
592
593 /* For R8..R12 when we've entered debug
594 * state in FIQ mode... patch mode.
595 */
596 if (mode == ARMV4_5_MODE_ANY)
597 mode = ARMV4_5_MODE_USR;
598
599 /* REVISIT error checks */
600 retval = dpm_modeswitch(dpm, mode);
601 }
602 if (r->mode != mode)
603 continue;
604
605 /* CPSR was read, so "R16" must mean SPSR */
606 retval = dpm_read_reg(dpm,
607 &cache->reg_list[i],
608 (r->num == 16) ? 17 : r->num);
609
610 }
611
612 } while (did_read);
613
614 retval = dpm_modeswitch(dpm, ARMV4_5_MODE_ANY);
615 /* (void) */ dpm->finish(dpm);
616 done:
617 return retval;
618 }
619
620
621 /*----------------------------------------------------------------------*/
622
623 /*
624 * Breakpoint and Watchpoint support.
625 *
626 * Hardware {break,watch}points are usually left active, to minimize
627 * debug entry/exit costs. When they are set or cleared, it's done in
628 * batches. Also, DPM-conformant hardware can update debug registers
629 * regardless of whether the CPU is running or halted ... though that
630 * fact isn't currently leveraged.
631 */
632
633 static int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index,
634 struct watchpoint *wp)
635 {
636 uint32_t addr = wp->address;
637 uint32_t control;
638
639 /* this hardware doesn't support data value matching or masking */
640 if (wp->value || wp->mask != ~(uint32_t)0) {
641 LOG_DEBUG("watchpoint values and masking not supported");
642 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
643 }
644
645 control = (1 << 0) /* enable */
646 | (3 << 1); /* both user and privileged access */
647
648 switch (wp->rw) {
649 case WPT_READ:
650 control |= 1 << 3;
651 break;
652 case WPT_WRITE:
653 control |= 2 << 3;
654 break;
655 case WPT_ACCESS:
656 control |= 3 << 3;
657 break;
658 }
659
660 /* Match 1, 2, or all 4 byte addresses in this word.
661 *
662 * FIXME: v7 hardware allows lengths up to 2 GB, and has eight
663 * byte address select bits. Support larger wp->length, if addr
664 * is suitably aligned.
665 */
666 switch (wp->length) {
667 case 1:
668 control |= (1 << (addr & 3)) << 5;
669 addr &= ~3;
670 break;
671 case 2:
672 /* require 2-byte alignment */
673 if (!(addr & 1)) {
674 control |= (3 << (addr & 2)) << 5;
675 break;
676 }
677 /* FALL THROUGH */
678 case 4:
679 /* require 4-byte alignment */
680 if (!(addr & 3)) {
681 control |= 0xf << 5;
682 break;
683 }
684 /* FALL THROUGH */
685 default:
686 LOG_DEBUG("bad watchpoint length or alignment");
687 return ERROR_INVALID_ARGUMENTS;
688 }
689
690 /* other control bits:
691 * bits 9:12 == 0 ... only checking up to four byte addresses (v7 only)
692 * bits 15:14 == 0 ... both secure and nonsecure states (v6.1+ only)
693 * bit 20 == 0 ... not linked to a context ID
694 * bit 28:24 == 0 ... not ignoring N LSBs (v7 only)
695 */
696
697 dpm->dwp[index].wp = wp;
698 dpm->dwp[index].control = control;
699 dpm->dwp[index].dirty = true;
700
701 /* hardware is updated in write_dirty_registers() */
702 return ERROR_OK;
703 }
704
705
706 static int dpm_add_watchpoint(struct target *target, struct watchpoint *wp)
707 {
708 struct arm *arm = target_to_arm(target);
709 struct arm_dpm *dpm = arm->dpm;
710 int retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
711
712 if (dpm->bpwp_enable) {
713 for (unsigned i = 0; i < dpm->nwp; i++) {
714 if (!dpm->dwp[i].wp) {
715 retval = dpm_watchpoint_setup(dpm, i, wp);
716 break;
717 }
718 }
719 }
720
721 return retval;
722 }
723
724 static int dpm_remove_watchpoint(struct target *target, struct watchpoint *wp)
725 {
726 struct arm *arm = target_to_arm(target);
727 struct arm_dpm *dpm = arm->dpm;
728 int retval = ERROR_INVALID_ARGUMENTS;
729
730 for (unsigned i = 0; i < dpm->nwp; i++) {
731 if (dpm->dwp[i].wp == wp) {
732 dpm->dwp[i].wp = NULL;
733 dpm->dwp[i].dirty = true;
734
735 /* hardware is updated in write_dirty_registers() */
736 retval = ERROR_OK;
737 break;
738 }
739 }
740
741 return retval;
742 }
743
744 void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr)
745 {
746 switch (dpm->arm->core_state) {
747 case ARMV4_5_STATE_ARM:
748 addr -= 8;
749 break;
750 case ARMV4_5_STATE_THUMB:
751 case ARM_STATE_THUMB_EE:
752 addr -= 4;
753 break;
754 case ARMV4_5_STATE_JAZELLE:
755 /* ?? */
756 break;
757 }
758 dpm->wp_pc = addr;
759 }
760
761 /*----------------------------------------------------------------------*/
762
763 /*
764 * Other debug and support utilities
765 */
766
767 void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
768 {
769 struct target *target = dpm->arm->target;
770
771 dpm->dscr = dscr;
772
773 /* Examine debug reason */
774 switch (DSCR_ENTRY(dscr)) {
775 case 6: /* Data abort (v6 only) */
776 case 7: /* Prefetch abort (v6 only) */
777 /* FALL THROUGH -- assume a v6 core in abort mode */
778 case 0: /* HALT request from debugger */
779 case 4: /* EDBGRQ */
780 target->debug_reason = DBG_REASON_DBGRQ;
781 break;
782 case 1: /* HW breakpoint */
783 case 3: /* SW BKPT */
784 case 5: /* vector catch */
785 target->debug_reason = DBG_REASON_BREAKPOINT;
786 break;
787 case 2: /* asynch watchpoint */
788 case 10: /* precise watchpoint */
789 target->debug_reason = DBG_REASON_WATCHPOINT;
790 break;
791 default:
792 target->debug_reason = DBG_REASON_UNDEFINED;
793 break;
794 }
795 }
796
797 /*----------------------------------------------------------------------*/
798
799 /*
800 * Setup and management support.
801 */
802
803 /**
804 * Hooks up this DPM to its associated target; call only once.
805 * Initially this only covers the register cache.
806 *
807 * Oh, and watchpoints. Yeah.
808 */
809 int arm_dpm_setup(struct arm_dpm *dpm)
810 {
811 struct arm *arm = dpm->arm;
812 struct target *target = arm->target;
813 struct reg_cache *cache;
814
815 arm->dpm = dpm;
816
817 /* register access setup */
818 arm->full_context = arm_dpm_full_context;
819 arm->read_core_reg = arm_dpm_read_core_reg;
820 arm->write_core_reg = arm_dpm_write_core_reg;
821
822 cache = armv4_5_build_reg_cache(target, arm);
823 if (!cache)
824 return ERROR_FAIL;
825
826 *register_get_last_cache_p(&target->reg_cache) = cache;
827
828 /* coprocessor access setup */
829 arm->mrc = dpm_mrc;
830 arm->mcr = dpm_mcr;
831
832 /* breakpoint and watchpoint setup */
833 target->type->add_watchpoint = dpm_add_watchpoint;
834 target->type->remove_watchpoint = dpm_remove_watchpoint;
835
836 /* FIXME add breakpoint support */
837 /* FIXME add vector catch support */
838
839 dpm->nbp = 1 + ((dpm->didr >> 24) & 0xf);
840 dpm->dbp = calloc(dpm->nbp, sizeof *dpm->dbp);
841
842 dpm->nwp = 1 + ((dpm->didr >> 28) & 0xf);
843 dpm->dwp = calloc(dpm->nwp, sizeof *dpm->dwp);
844
845 if (!dpm->dbp || !dpm->dwp) {
846 free(dpm->dbp);
847 free(dpm->dwp);
848 return ERROR_FAIL;
849 }
850
851 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
852 target_name(target), dpm->nbp, dpm->nwp);
853
854 /* REVISIT ... and some of those breakpoints could match
855 * execution context IDs...
856 */
857
858 return ERROR_OK;
859 }
860
861 /**
862 * Reinitializes DPM state at the beginning of a new debug session
863 * or after a reset which may have affected the debug module.
864 */
865 int arm_dpm_initialize(struct arm_dpm *dpm)
866 {
867 /* Disable all breakpoints and watchpoints at startup. */
868 if (dpm->bpwp_disable) {
869 unsigned i;
870
871 for (i = 0; i < dpm->nbp; i++)
872 (void) dpm->bpwp_disable(dpm, i);
873 for (i = 0; i < dpm->nwp; i++)
874 (void) dpm->bpwp_disable(dpm, 16 + i);
875 } else
876 LOG_WARNING("%s: can't disable breakpoints and watchpoints",
877 target_name(dpm->arm->target));
878
879 return ERROR_OK;
880 }

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)