armv7m.h: relax dependency from 'arm_adi_v5.h'
[openocd.git] / src / target / cortex_m.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2006 by Magnus Lundin *
6 * lundin@mlu.mine.nu *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
23 * *
24 * *
25 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
26 * *
27 ***************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include "jtag/interface.h"
33 #include "breakpoints.h"
34 #include "cortex_m.h"
35 #include "target_request.h"
36 #include "target_type.h"
37 #include "arm_adi_v5.h"
38 #include "arm_disassembler.h"
39 #include "register.h"
40 #include "arm_opcodes.h"
41 #include "arm_semihosting.h"
42 #include <helper/time_support.h>
43 #include <rtt/rtt.h>
44
45 /* NOTE: most of this should work fine for the Cortex-M1 and
46 * Cortex-M0 cores too, although they're ARMv6-M not ARMv7-M.
47 * Some differences: M0/M1 doesn't have FPB remapping or the
48 * DWT tracing/profiling support. (So the cycle counter will
49 * not be usable; the other stuff isn't currently used here.)
50 *
51 * Although there are some workarounds for errata seen only in r0p0
52 * silicon, such old parts are hard to find and thus not much tested
53 * any longer.
54 */
55
56 /* Supported Cortex-M Cores */
57 static const struct cortex_m_part_info cortex_m_parts[] = {
58 {
59 .partno = CORTEX_M0_PARTNO,
60 .name = "Cortex-M0",
61 .arch = ARM_ARCH_V6M,
62 },
63 {
64 .partno = CORTEX_M0P_PARTNO,
65 .name = "Cortex-M0+",
66 .arch = ARM_ARCH_V6M,
67 },
68 {
69 .partno = CORTEX_M1_PARTNO,
70 .name = "Cortex-M1",
71 .arch = ARM_ARCH_V6M,
72 },
73 {
74 .partno = CORTEX_M3_PARTNO,
75 .name = "Cortex-M3",
76 .arch = ARM_ARCH_V7M,
77 .flags = CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K,
78 },
79 {
80 .partno = CORTEX_M4_PARTNO,
81 .name = "Cortex-M4",
82 .arch = ARM_ARCH_V7M,
83 .flags = CORTEX_M_F_HAS_FPV4 | CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K,
84 },
85 {
86 .partno = CORTEX_M7_PARTNO,
87 .name = "Cortex-M7",
88 .arch = ARM_ARCH_V7M,
89 .flags = CORTEX_M_F_HAS_FPV5,
90 },
91 {
92 .partno = CORTEX_M23_PARTNO,
93 .name = "Cortex-M23",
94 .arch = ARM_ARCH_V8M,
95 },
96 {
97 .partno = CORTEX_M33_PARTNO,
98 .name = "Cortex-M33",
99 .arch = ARM_ARCH_V8M,
100 .flags = CORTEX_M_F_HAS_FPV5,
101 },
102 {
103 .partno = CORTEX_M35P_PARTNO,
104 .name = "Cortex-M35P",
105 .arch = ARM_ARCH_V8M,
106 .flags = CORTEX_M_F_HAS_FPV5,
107 },
108 {
109 .partno = CORTEX_M55_PARTNO,
110 .name = "Cortex-M55",
111 .arch = ARM_ARCH_V8M,
112 .flags = CORTEX_M_F_HAS_FPV5,
113 },
114 };
115
116 /* forward declarations */
117 static int cortex_m_store_core_reg_u32(struct target *target,
118 uint32_t num, uint32_t value);
119 static void cortex_m_dwt_free(struct target *target);
120
121 static int cortex_m_load_core_reg_u32(struct target *target,
122 uint32_t regsel, uint32_t *value)
123 {
124 struct armv7m_common *armv7m = target_to_armv7m(target);
125 int retval;
126 uint32_t dcrdr;
127
128 /* because the DCB_DCRDR is used for the emulated dcc channel
129 * we have to save/restore the DCB_DCRDR when used */
130 if (target->dbg_msg_enabled) {
131 retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);
132 if (retval != ERROR_OK)
133 return retval;
134 }
135
136 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regsel);
137 if (retval != ERROR_OK)
138 return retval;
139
140 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DCRDR, value);
141 if (retval != ERROR_OK)
142 return retval;
143
144 if (target->dbg_msg_enabled) {
145 /* restore DCB_DCRDR - this needs to be in a separate
146 * transaction otherwise the emulated DCC channel breaks */
147 if (retval == ERROR_OK)
148 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);
149 }
150
151 return retval;
152 }
153
154 static int cortex_m_store_core_reg_u32(struct target *target,
155 uint32_t regsel, uint32_t value)
156 {
157 struct armv7m_common *armv7m = target_to_armv7m(target);
158 int retval;
159 uint32_t dcrdr;
160
161 /* because the DCB_DCRDR is used for the emulated dcc channel
162 * we have to save/restore the DCB_DCRDR when used */
163 if (target->dbg_msg_enabled) {
164 retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);
165 if (retval != ERROR_OK)
166 return retval;
167 }
168
169 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, value);
170 if (retval != ERROR_OK)
171 return retval;
172
173 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regsel | DCRSR_WNR);
174 if (retval != ERROR_OK)
175 return retval;
176
177 if (target->dbg_msg_enabled) {
178 /* restore DCB_DCRDR - this needs to be in a separate
179 * transaction otherwise the emulated DCC channel breaks */
180 if (retval == ERROR_OK)
181 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);
182 }
183
184 return retval;
185 }
186
187 static int cortex_m_write_debug_halt_mask(struct target *target,
188 uint32_t mask_on, uint32_t mask_off)
189 {
190 struct cortex_m_common *cortex_m = target_to_cm(target);
191 struct armv7m_common *armv7m = &cortex_m->armv7m;
192
193 /* mask off status bits */
194 cortex_m->dcb_dhcsr &= ~((0xFFFFul << 16) | mask_off);
195 /* create new register mask */
196 cortex_m->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on;
197
198 return mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, cortex_m->dcb_dhcsr);
199 }
200
201 static int cortex_m_set_maskints(struct target *target, bool mask)
202 {
203 struct cortex_m_common *cortex_m = target_to_cm(target);
204 if (!!(cortex_m->dcb_dhcsr & C_MASKINTS) != mask)
205 return cortex_m_write_debug_halt_mask(target, mask ? C_MASKINTS : 0, mask ? 0 : C_MASKINTS);
206 else
207 return ERROR_OK;
208 }
209
210 static int cortex_m_set_maskints_for_halt(struct target *target)
211 {
212 struct cortex_m_common *cortex_m = target_to_cm(target);
213 switch (cortex_m->isrmasking_mode) {
214 case CORTEX_M_ISRMASK_AUTO:
215 /* interrupts taken at resume, whether for step or run -> no mask */
216 return cortex_m_set_maskints(target, false);
217
218 case CORTEX_M_ISRMASK_OFF:
219 /* interrupts never masked */
220 return cortex_m_set_maskints(target, false);
221
222 case CORTEX_M_ISRMASK_ON:
223 /* interrupts always masked */
224 return cortex_m_set_maskints(target, true);
225
226 case CORTEX_M_ISRMASK_STEPONLY:
227 /* interrupts masked for single step only -> mask now if MASKINTS
228 * erratum, otherwise only mask before stepping */
229 return cortex_m_set_maskints(target, cortex_m->maskints_erratum);
230 }
231 return ERROR_OK;
232 }
233
234 static int cortex_m_set_maskints_for_run(struct target *target)
235 {
236 switch (target_to_cm(target)->isrmasking_mode) {
237 case CORTEX_M_ISRMASK_AUTO:
238 /* interrupts taken at resume, whether for step or run -> no mask */
239 return cortex_m_set_maskints(target, false);
240
241 case CORTEX_M_ISRMASK_OFF:
242 /* interrupts never masked */
243 return cortex_m_set_maskints(target, false);
244
245 case CORTEX_M_ISRMASK_ON:
246 /* interrupts always masked */
247 return cortex_m_set_maskints(target, true);
248
249 case CORTEX_M_ISRMASK_STEPONLY:
250 /* interrupts masked for single step only -> no mask */
251 return cortex_m_set_maskints(target, false);
252 }
253 return ERROR_OK;
254 }
255
256 static int cortex_m_set_maskints_for_step(struct target *target)
257 {
258 switch (target_to_cm(target)->isrmasking_mode) {
259 case CORTEX_M_ISRMASK_AUTO:
260 /* the auto-interrupt should already be done -> mask */
261 return cortex_m_set_maskints(target, true);
262
263 case CORTEX_M_ISRMASK_OFF:
264 /* interrupts never masked */
265 return cortex_m_set_maskints(target, false);
266
267 case CORTEX_M_ISRMASK_ON:
268 /* interrupts always masked */
269 return cortex_m_set_maskints(target, true);
270
271 case CORTEX_M_ISRMASK_STEPONLY:
272 /* interrupts masked for single step only -> mask */
273 return cortex_m_set_maskints(target, true);
274 }
275 return ERROR_OK;
276 }
277
278 static int cortex_m_clear_halt(struct target *target)
279 {
280 struct cortex_m_common *cortex_m = target_to_cm(target);
281 struct armv7m_common *armv7m = &cortex_m->armv7m;
282 int retval;
283
284 /* clear step if any */
285 cortex_m_write_debug_halt_mask(target, C_HALT, C_STEP);
286
287 /* Read Debug Fault Status Register */
288 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR, &cortex_m->nvic_dfsr);
289 if (retval != ERROR_OK)
290 return retval;
291
292 /* Clear Debug Fault Status */
293 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_DFSR, cortex_m->nvic_dfsr);
294 if (retval != ERROR_OK)
295 return retval;
296 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32 "", cortex_m->nvic_dfsr);
297
298 return ERROR_OK;
299 }
300
301 static int cortex_m_single_step_core(struct target *target)
302 {
303 struct cortex_m_common *cortex_m = target_to_cm(target);
304 struct armv7m_common *armv7m = &cortex_m->armv7m;
305 int retval;
306
307 /* Mask interrupts before clearing halt, if not done already. This avoids
308 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
309 * HALT can put the core into an unknown state.
310 */
311 if (!(cortex_m->dcb_dhcsr & C_MASKINTS)) {
312 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
313 DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN);
314 if (retval != ERROR_OK)
315 return retval;
316 }
317 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
318 DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN);
319 if (retval != ERROR_OK)
320 return retval;
321 LOG_DEBUG(" ");
322
323 /* restore dhcsr reg */
324 cortex_m_clear_halt(target);
325
326 return ERROR_OK;
327 }
328
329 static int cortex_m_enable_fpb(struct target *target)
330 {
331 int retval = target_write_u32(target, FP_CTRL, 3);
332 if (retval != ERROR_OK)
333 return retval;
334
335 /* check the fpb is actually enabled */
336 uint32_t fpctrl;
337 retval = target_read_u32(target, FP_CTRL, &fpctrl);
338 if (retval != ERROR_OK)
339 return retval;
340
341 if (fpctrl & 1)
342 return ERROR_OK;
343
344 return ERROR_FAIL;
345 }
346
347 static int cortex_m_endreset_event(struct target *target)
348 {
349 int retval;
350 uint32_t dcb_demcr;
351 struct cortex_m_common *cortex_m = target_to_cm(target);
352 struct armv7m_common *armv7m = &cortex_m->armv7m;
353 struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
354 struct cortex_m_fp_comparator *fp_list = cortex_m->fp_comparator_list;
355 struct cortex_m_dwt_comparator *dwt_list = cortex_m->dwt_comparator_list;
356
357 /* REVISIT The four debug monitor bits are currently ignored... */
358 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &dcb_demcr);
359 if (retval != ERROR_OK)
360 return retval;
361 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "", dcb_demcr);
362
363 /* this register is used for emulated dcc channel */
364 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
365 if (retval != ERROR_OK)
366 return retval;
367
368 /* Enable debug requests */
369 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
370 if (retval != ERROR_OK)
371 return retval;
372 if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
373 retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);
374 if (retval != ERROR_OK)
375 return retval;
376 }
377
378 /* Restore proper interrupt masking setting for running CPU. */
379 cortex_m_set_maskints_for_run(target);
380
381 /* Enable features controlled by ITM and DWT blocks, and catch only
382 * the vectors we were told to pay attention to.
383 *
384 * Target firmware is responsible for all fault handling policy
385 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
386 * or manual updates to the NVIC SHCSR and CCR registers.
387 */
388 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, TRCENA | armv7m->demcr);
389 if (retval != ERROR_OK)
390 return retval;
391
392 /* Paranoia: evidently some (early?) chips don't preserve all the
393 * debug state (including FPB, DWT, etc) across reset...
394 */
395
396 /* Enable FPB */
397 retval = cortex_m_enable_fpb(target);
398 if (retval != ERROR_OK) {
399 LOG_ERROR("Failed to enable the FPB");
400 return retval;
401 }
402
403 cortex_m->fpb_enabled = true;
404
405 /* Restore FPB registers */
406 for (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
407 retval = target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
408 if (retval != ERROR_OK)
409 return retval;
410 }
411
412 /* Restore DWT registers */
413 for (unsigned int i = 0; i < cortex_m->dwt_num_comp; i++) {
414 retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 0,
415 dwt_list[i].comp);
416 if (retval != ERROR_OK)
417 return retval;
418 retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 4,
419 dwt_list[i].mask);
420 if (retval != ERROR_OK)
421 return retval;
422 retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 8,
423 dwt_list[i].function);
424 if (retval != ERROR_OK)
425 return retval;
426 }
427 retval = dap_run(swjdp);
428 if (retval != ERROR_OK)
429 return retval;
430
431 register_cache_invalidate(armv7m->arm.core_cache);
432
433 /* make sure we have latest dhcsr flags */
434 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
435
436 return retval;
437 }
438
439 static int cortex_m_examine_debug_reason(struct target *target)
440 {
441 struct cortex_m_common *cortex_m = target_to_cm(target);
442
443 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason
444 * only check the debug reason if we don't know it already */
445
446 if ((target->debug_reason != DBG_REASON_DBGRQ)
447 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
448 if (cortex_m->nvic_dfsr & DFSR_BKPT) {
449 target->debug_reason = DBG_REASON_BREAKPOINT;
450 if (cortex_m->nvic_dfsr & DFSR_DWTTRAP)
451 target->debug_reason = DBG_REASON_WPTANDBKPT;
452 } else if (cortex_m->nvic_dfsr & DFSR_DWTTRAP)
453 target->debug_reason = DBG_REASON_WATCHPOINT;
454 else if (cortex_m->nvic_dfsr & DFSR_VCATCH)
455 target->debug_reason = DBG_REASON_BREAKPOINT;
456 else if (cortex_m->nvic_dfsr & DFSR_EXTERNAL)
457 target->debug_reason = DBG_REASON_DBGRQ;
458 else /* HALTED */
459 target->debug_reason = DBG_REASON_UNDEFINED;
460 }
461
462 return ERROR_OK;
463 }
464
465 static int cortex_m_examine_exception_reason(struct target *target)
466 {
467 uint32_t shcsr = 0, except_sr = 0, cfsr = -1, except_ar = -1;
468 struct armv7m_common *armv7m = target_to_armv7m(target);
469 struct adiv5_dap *swjdp = armv7m->arm.dap;
470 int retval;
471
472 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SHCSR, &shcsr);
473 if (retval != ERROR_OK)
474 return retval;
475 switch (armv7m->exception_number) {
476 case 2: /* NMI */
477 break;
478 case 3: /* Hard Fault */
479 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_HFSR, &except_sr);
480 if (retval != ERROR_OK)
481 return retval;
482 if (except_sr & 0x40000000) {
483 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &cfsr);
484 if (retval != ERROR_OK)
485 return retval;
486 }
487 break;
488 case 4: /* Memory Management */
489 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);
490 if (retval != ERROR_OK)
491 return retval;
492 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_MMFAR, &except_ar);
493 if (retval != ERROR_OK)
494 return retval;
495 break;
496 case 5: /* Bus Fault */
497 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);
498 if (retval != ERROR_OK)
499 return retval;
500 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_BFAR, &except_ar);
501 if (retval != ERROR_OK)
502 return retval;
503 break;
504 case 6: /* Usage Fault */
505 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);
506 if (retval != ERROR_OK)
507 return retval;
508 break;
509 case 7: /* Secure Fault */
510 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SFSR, &except_sr);
511 if (retval != ERROR_OK)
512 return retval;
513 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SFAR, &except_ar);
514 if (retval != ERROR_OK)
515 return retval;
516 break;
517 case 11: /* SVCall */
518 break;
519 case 12: /* Debug Monitor */
520 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_DFSR, &except_sr);
521 if (retval != ERROR_OK)
522 return retval;
523 break;
524 case 14: /* PendSV */
525 break;
526 case 15: /* SysTick */
527 break;
528 default:
529 except_sr = 0;
530 break;
531 }
532 retval = dap_run(swjdp);
533 if (retval == ERROR_OK)
534 LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32
535 ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32,
536 armv7m_exception_string(armv7m->exception_number),
537 shcsr, except_sr, cfsr, except_ar);
538 return retval;
539 }
540
541 static int cortex_m_debug_entry(struct target *target)
542 {
543 int i;
544 uint32_t xPSR;
545 int retval;
546 struct cortex_m_common *cortex_m = target_to_cm(target);
547 struct armv7m_common *armv7m = &cortex_m->armv7m;
548 struct arm *arm = &armv7m->arm;
549 struct reg *r;
550
551 LOG_DEBUG(" ");
552
553 /* Do this really early to minimize the window where the MASKINTS erratum
554 * can pile up pending interrupts. */
555 cortex_m_set_maskints_for_halt(target);
556
557 cortex_m_clear_halt(target);
558 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
559 if (retval != ERROR_OK)
560 return retval;
561
562 retval = armv7m->examine_debug_reason(target);
563 if (retval != ERROR_OK)
564 return retval;
565
566 /* examine PE security state */
567 bool secure_state = false;
568 if (armv7m->arm.arch == ARM_ARCH_V8M) {
569 uint32_t dscsr;
570
571 retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DSCSR, &dscsr);
572 if (retval != ERROR_OK)
573 return retval;
574
575 secure_state = (dscsr & DSCSR_CDS) == DSCSR_CDS;
576 }
577
578 /* Examine target state and mode
579 * First load register accessible through core debug port */
580 int num_regs = arm->core_cache->num_regs;
581
582 for (i = 0; i < num_regs; i++) {
583 r = &armv7m->arm.core_cache->reg_list[i];
584 if (r->exist && !r->valid)
585 arm->read_core_reg(target, r, i, ARM_MODE_ANY);
586 }
587
588 r = arm->cpsr;
589 xPSR = buf_get_u32(r->value, 0, 32);
590
591 /* Are we in an exception handler */
592 if (xPSR & 0x1FF) {
593 armv7m->exception_number = (xPSR & 0x1FF);
594
595 arm->core_mode = ARM_MODE_HANDLER;
596 arm->map = armv7m_msp_reg_map;
597 } else {
598 unsigned control = buf_get_u32(arm->core_cache
599 ->reg_list[ARMV7M_CONTROL].value, 0, 3);
600
601 /* is this thread privileged? */
602 arm->core_mode = control & 1
603 ? ARM_MODE_USER_THREAD
604 : ARM_MODE_THREAD;
605
606 /* which stack is it using? */
607 if (control & 2)
608 arm->map = armv7m_psp_reg_map;
609 else
610 arm->map = armv7m_msp_reg_map;
611
612 armv7m->exception_number = 0;
613 }
614
615 if (armv7m->exception_number)
616 cortex_m_examine_exception_reason(target);
617
618 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", cpu in %s state, target->state: %s",
619 arm_mode_name(arm->core_mode),
620 buf_get_u32(arm->pc->value, 0, 32),
621 secure_state ? "Secure" : "Non-Secure",
622 target_state_name(target));
623
624 if (armv7m->post_debug_entry) {
625 retval = armv7m->post_debug_entry(target);
626 if (retval != ERROR_OK)
627 return retval;
628 }
629
630 return ERROR_OK;
631 }
632
633 static int cortex_m_poll(struct target *target)
634 {
635 int detected_failure = ERROR_OK;
636 int retval = ERROR_OK;
637 enum target_state prev_target_state = target->state;
638 struct cortex_m_common *cortex_m = target_to_cm(target);
639 struct armv7m_common *armv7m = &cortex_m->armv7m;
640
641 /* Read from Debug Halting Control and Status Register */
642 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
643 if (retval != ERROR_OK) {
644 target->state = TARGET_UNKNOWN;
645 return retval;
646 }
647
648 /* Recover from lockup. See ARMv7-M architecture spec,
649 * section B1.5.15 "Unrecoverable exception cases".
650 */
651 if (cortex_m->dcb_dhcsr & S_LOCKUP) {
652 LOG_ERROR("%s -- clearing lockup after double fault",
653 target_name(target));
654 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
655 target->debug_reason = DBG_REASON_DBGRQ;
656
657 /* We have to execute the rest (the "finally" equivalent, but
658 * still throw this exception again).
659 */
660 detected_failure = ERROR_FAIL;
661
662 /* refresh status bits */
663 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
664 if (retval != ERROR_OK)
665 return retval;
666 }
667
668 if (cortex_m->dcb_dhcsr & S_RESET_ST) {
669 if (target->state != TARGET_RESET) {
670 target->state = TARGET_RESET;
671 LOG_INFO("%s: external reset detected", target_name(target));
672 }
673 return ERROR_OK;
674 }
675
676 if (target->state == TARGET_RESET) {
677 /* Cannot switch context while running so endreset is
678 * called with target->state == TARGET_RESET
679 */
680 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32,
681 cortex_m->dcb_dhcsr);
682 retval = cortex_m_endreset_event(target);
683 if (retval != ERROR_OK) {
684 target->state = TARGET_UNKNOWN;
685 return retval;
686 }
687 target->state = TARGET_RUNNING;
688 prev_target_state = TARGET_RUNNING;
689 }
690
691 if (cortex_m->dcb_dhcsr & S_HALT) {
692 target->state = TARGET_HALTED;
693
694 if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) {
695 retval = cortex_m_debug_entry(target);
696 if (retval != ERROR_OK)
697 return retval;
698
699 if (arm_semihosting(target, &retval) != 0)
700 return retval;
701
702 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
703 }
704 if (prev_target_state == TARGET_DEBUG_RUNNING) {
705 LOG_DEBUG(" ");
706 retval = cortex_m_debug_entry(target);
707 if (retval != ERROR_OK)
708 return retval;
709
710 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
711 }
712 }
713
714 if (target->state == TARGET_UNKNOWN) {
715 /* check if processor is retiring instructions or sleeping */
716 if (cortex_m->dcb_dhcsr & S_RETIRE_ST || cortex_m->dcb_dhcsr & S_SLEEP) {
717 target->state = TARGET_RUNNING;
718 retval = ERROR_OK;
719 }
720 }
721
722 /* Check that target is truly halted, since the target could be resumed externally */
723 if ((prev_target_state == TARGET_HALTED) && !(cortex_m->dcb_dhcsr & S_HALT)) {
724 /* registers are now invalid */
725 register_cache_invalidate(armv7m->arm.core_cache);
726
727 target->state = TARGET_RUNNING;
728 LOG_WARNING("%s: external resume detected", target_name(target));
729 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
730 retval = ERROR_OK;
731 }
732
733 /* Did we detect a failure condition that we cleared? */
734 if (detected_failure != ERROR_OK)
735 retval = detected_failure;
736 return retval;
737 }
738
739 static int cortex_m_halt(struct target *target)
740 {
741 LOG_DEBUG("target->state: %s",
742 target_state_name(target));
743
744 if (target->state == TARGET_HALTED) {
745 LOG_DEBUG("target was already halted");
746 return ERROR_OK;
747 }
748
749 if (target->state == TARGET_UNKNOWN)
750 LOG_WARNING("target was in unknown state when halt was requested");
751
752 if (target->state == TARGET_RESET) {
753 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {
754 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
755 return ERROR_TARGET_FAILURE;
756 } else {
757 /* we came here in a reset_halt or reset_init sequence
758 * debug entry was already prepared in cortex_m3_assert_reset()
759 */
760 target->debug_reason = DBG_REASON_DBGRQ;
761
762 return ERROR_OK;
763 }
764 }
765
766 /* Write to Debug Halting Control and Status Register */
767 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
768
769 /* Do this really early to minimize the window where the MASKINTS erratum
770 * can pile up pending interrupts. */
771 cortex_m_set_maskints_for_halt(target);
772
773 target->debug_reason = DBG_REASON_DBGRQ;
774
775 return ERROR_OK;
776 }
777
778 static int cortex_m_soft_reset_halt(struct target *target)
779 {
780 struct cortex_m_common *cortex_m = target_to_cm(target);
781 struct armv7m_common *armv7m = &cortex_m->armv7m;
782 uint32_t dcb_dhcsr = 0;
783 int retval, timeout = 0;
784
785 /* on single cortex_m MCU soft_reset_halt should be avoided as same functionality
786 * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'.
787 * As this reset only uses VC_CORERESET it would only ever reset the cortex_m
788 * core, not the peripherals */
789 LOG_DEBUG("soft_reset_halt is discouraged, please use 'reset halt' instead.");
790
791 if (!cortex_m->vectreset_supported) {
792 LOG_ERROR("VECTRESET is not supported on this Cortex-M core");
793 return ERROR_FAIL;
794 }
795
796 /* Set C_DEBUGEN */
797 retval = cortex_m_write_debug_halt_mask(target, 0, C_STEP | C_MASKINTS);
798 if (retval != ERROR_OK)
799 return retval;
800
801 /* Enter debug state on reset; restore DEMCR in endreset_event() */
802 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR,
803 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
804 if (retval != ERROR_OK)
805 return retval;
806
807 /* Request a core-only reset */
808 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
809 AIRCR_VECTKEY | AIRCR_VECTRESET);
810 if (retval != ERROR_OK)
811 return retval;
812 target->state = TARGET_RESET;
813
814 /* registers are now invalid */
815 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
816
817 while (timeout < 100) {
818 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &dcb_dhcsr);
819 if (retval == ERROR_OK) {
820 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR,
821 &cortex_m->nvic_dfsr);
822 if (retval != ERROR_OK)
823 return retval;
824 if ((dcb_dhcsr & S_HALT)
825 && (cortex_m->nvic_dfsr & DFSR_VCATCH)) {
826 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
827 "DFSR 0x%08x",
828 (unsigned) dcb_dhcsr,
829 (unsigned) cortex_m->nvic_dfsr);
830 cortex_m_poll(target);
831 /* FIXME restore user's vector catch config */
832 return ERROR_OK;
833 } else
834 LOG_DEBUG("waiting for system reset-halt, "
835 "DHCSR 0x%08x, %d ms",
836 (unsigned) dcb_dhcsr, timeout);
837 }
838 timeout++;
839 alive_sleep(1);
840 }
841
842 return ERROR_OK;
843 }
844
845 void cortex_m_enable_breakpoints(struct target *target)
846 {
847 struct breakpoint *breakpoint = target->breakpoints;
848
849 /* set any pending breakpoints */
850 while (breakpoint) {
851 if (!breakpoint->set)
852 cortex_m_set_breakpoint(target, breakpoint);
853 breakpoint = breakpoint->next;
854 }
855 }
856
857 static int cortex_m_resume(struct target *target, int current,
858 target_addr_t address, int handle_breakpoints, int debug_execution)
859 {
860 struct armv7m_common *armv7m = target_to_armv7m(target);
861 struct breakpoint *breakpoint = NULL;
862 uint32_t resume_pc;
863 struct reg *r;
864
865 if (target->state != TARGET_HALTED) {
866 LOG_WARNING("target not halted");
867 return ERROR_TARGET_NOT_HALTED;
868 }
869
870 if (!debug_execution) {
871 target_free_all_working_areas(target);
872 cortex_m_enable_breakpoints(target);
873 cortex_m_enable_watchpoints(target);
874 }
875
876 if (debug_execution) {
877 r = armv7m->arm.core_cache->reg_list + ARMV7M_PRIMASK;
878
879 /* Disable interrupts */
880 /* We disable interrupts in the PRIMASK register instead of
881 * masking with C_MASKINTS. This is probably the same issue
882 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
883 * in parallel with disabled interrupts can cause local faults
884 * to not be taken.
885 *
886 * This breaks non-debug (application) execution if not
887 * called from armv7m_start_algorithm() which saves registers.
888 */
889 buf_set_u32(r->value, 0, 1, 1);
890 r->dirty = true;
891 r->valid = true;
892
893 /* Make sure we are in Thumb mode, set xPSR.T bit */
894 /* armv7m_start_algorithm() initializes entire xPSR register.
895 * This duplicity handles the case when cortex_m_resume()
896 * is used with the debug_execution flag directly,
897 * not called through armv7m_start_algorithm().
898 */
899 r = armv7m->arm.cpsr;
900 buf_set_u32(r->value, 24, 1, 1);
901 r->dirty = true;
902 r->valid = true;
903 }
904
905 /* current = 1: continue on current pc, otherwise continue at <address> */
906 r = armv7m->arm.pc;
907 if (!current) {
908 buf_set_u32(r->value, 0, 32, address);
909 r->dirty = true;
910 r->valid = true;
911 }
912
913 /* if we halted last time due to a bkpt instruction
914 * then we have to manually step over it, otherwise
915 * the core will break again */
916
917 if (!breakpoint_find(target, buf_get_u32(r->value, 0, 32))
918 && !debug_execution)
919 armv7m_maybe_skip_bkpt_inst(target, NULL);
920
921 resume_pc = buf_get_u32(r->value, 0, 32);
922
923 armv7m_restore_context(target);
924
925 /* the front-end may request us not to handle breakpoints */
926 if (handle_breakpoints) {
927 /* Single step past breakpoint at current address */
928 breakpoint = breakpoint_find(target, resume_pc);
929 if (breakpoint) {
930 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
931 breakpoint->address,
932 breakpoint->unique_id);
933 cortex_m_unset_breakpoint(target, breakpoint);
934 cortex_m_single_step_core(target);
935 cortex_m_set_breakpoint(target, breakpoint);
936 }
937 }
938
939 /* Restart core */
940 cortex_m_set_maskints_for_run(target);
941 cortex_m_write_debug_halt_mask(target, 0, C_HALT);
942
943 target->debug_reason = DBG_REASON_NOTHALTED;
944
945 /* registers are now invalid */
946 register_cache_invalidate(armv7m->arm.core_cache);
947
948 if (!debug_execution) {
949 target->state = TARGET_RUNNING;
950 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
951 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
952 } else {
953 target->state = TARGET_DEBUG_RUNNING;
954 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
955 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
956 }
957
958 return ERROR_OK;
959 }
960
961 /* int irqstepcount = 0; */
962 static int cortex_m_step(struct target *target, int current,
963 target_addr_t address, int handle_breakpoints)
964 {
965 struct cortex_m_common *cortex_m = target_to_cm(target);
966 struct armv7m_common *armv7m = &cortex_m->armv7m;
967 struct breakpoint *breakpoint = NULL;
968 struct reg *pc = armv7m->arm.pc;
969 bool bkpt_inst_found = false;
970 int retval;
971 bool isr_timed_out = false;
972
973 if (target->state != TARGET_HALTED) {
974 LOG_WARNING("target not halted");
975 return ERROR_TARGET_NOT_HALTED;
976 }
977
978 /* current = 1: continue on current pc, otherwise continue at <address> */
979 if (!current) {
980 buf_set_u32(pc->value, 0, 32, address);
981 pc->dirty = true;
982 pc->valid = true;
983 }
984
985 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
986
987 /* the front-end may request us not to handle breakpoints */
988 if (handle_breakpoints) {
989 breakpoint = breakpoint_find(target, pc_value);
990 if (breakpoint)
991 cortex_m_unset_breakpoint(target, breakpoint);
992 }
993
994 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
995
996 target->debug_reason = DBG_REASON_SINGLESTEP;
997
998 armv7m_restore_context(target);
999
1000 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
1001
1002 /* if no bkpt instruction is found at pc then we can perform
1003 * a normal step, otherwise we have to manually step over the bkpt
1004 * instruction - as such simulate a step */
1005 if (bkpt_inst_found == false) {
1006 if (cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO) {
1007 /* Automatic ISR masking mode off: Just step over the next
1008 * instruction, with interrupts on or off as appropriate. */
1009 cortex_m_set_maskints_for_step(target);
1010 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1011 } else {
1012 /* Process interrupts during stepping in a way they don't interfere
1013 * debugging.
1014 *
1015 * Principle:
1016 *
1017 * Set a temporary break point at the current pc and let the core run
1018 * with interrupts enabled. Pending interrupts get served and we run
1019 * into the breakpoint again afterwards. Then we step over the next
1020 * instruction with interrupts disabled.
1021 *
1022 * If the pending interrupts don't complete within time, we leave the
1023 * core running. This may happen if the interrupts trigger faster
1024 * than the core can process them or the handler doesn't return.
1025 *
1026 * If no more breakpoints are available we simply do a step with
1027 * interrupts enabled.
1028 *
1029 */
1030
1031 /* 2012-09-29 ph
1032 *
1033 * If a break point is already set on the lower half word then a break point on
1034 * the upper half word will not break again when the core is restarted. So we
1035 * just step over the instruction with interrupts disabled.
1036 *
1037 * The documentation has no information about this, it was found by observation
1038 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to
1039 * suffer from this problem.
1040 *
1041 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
1042 * address has it always cleared. The former is done to indicate thumb mode
1043 * to gdb.
1044 *
1045 */
1046 if ((pc_value & 0x02) && breakpoint_find(target, pc_value & ~0x03)) {
1047 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
1048 cortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
1049 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1050 /* Re-enable interrupts if appropriate */
1051 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1052 cortex_m_set_maskints_for_halt(target);
1053 } else {
1054
1055 /* Set a temporary break point */
1056 if (breakpoint) {
1057 retval = cortex_m_set_breakpoint(target, breakpoint);
1058 } else {
1059 enum breakpoint_type type = BKPT_HARD;
1060 if (cortex_m->fp_rev == 0 && pc_value > 0x1FFFFFFF) {
1061 /* FPB rev.1 cannot handle such addr, try BKPT instr */
1062 type = BKPT_SOFT;
1063 }
1064 retval = breakpoint_add(target, pc_value, 2, type);
1065 }
1066
1067 bool tmp_bp_set = (retval == ERROR_OK);
1068
1069 /* No more breakpoints left, just do a step */
1070 if (!tmp_bp_set) {
1071 cortex_m_set_maskints_for_step(target);
1072 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1073 /* Re-enable interrupts if appropriate */
1074 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1075 cortex_m_set_maskints_for_halt(target);
1076 } else {
1077 /* Start the core */
1078 LOG_DEBUG("Starting core to serve pending interrupts");
1079 int64_t t_start = timeval_ms();
1080 cortex_m_set_maskints_for_run(target);
1081 cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP);
1082
1083 /* Wait for pending handlers to complete or timeout */
1084 do {
1085 retval = mem_ap_read_atomic_u32(armv7m->debug_ap,
1086 DCB_DHCSR,
1087 &cortex_m->dcb_dhcsr);
1088 if (retval != ERROR_OK) {
1089 target->state = TARGET_UNKNOWN;
1090 return retval;
1091 }
1092 isr_timed_out = ((timeval_ms() - t_start) > 500);
1093 } while (!((cortex_m->dcb_dhcsr & S_HALT) || isr_timed_out));
1094
1095 /* only remove breakpoint if we created it */
1096 if (breakpoint)
1097 cortex_m_unset_breakpoint(target, breakpoint);
1098 else {
1099 /* Remove the temporary breakpoint */
1100 breakpoint_remove(target, pc_value);
1101 }
1102
1103 if (isr_timed_out) {
1104 LOG_DEBUG("Interrupt handlers didn't complete within time, "
1105 "leaving target running");
1106 } else {
1107 /* Step over next instruction with interrupts disabled */
1108 cortex_m_set_maskints_for_step(target);
1109 cortex_m_write_debug_halt_mask(target,
1110 C_HALT | C_MASKINTS,
1111 0);
1112 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1113 /* Re-enable interrupts if appropriate */
1114 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1115 cortex_m_set_maskints_for_halt(target);
1116 }
1117 }
1118 }
1119 }
1120 }
1121
1122 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
1123 if (retval != ERROR_OK)
1124 return retval;
1125
1126 /* registers are now invalid */
1127 register_cache_invalidate(armv7m->arm.core_cache);
1128
1129 if (breakpoint)
1130 cortex_m_set_breakpoint(target, breakpoint);
1131
1132 if (isr_timed_out) {
1133 /* Leave the core running. The user has to stop execution manually. */
1134 target->debug_reason = DBG_REASON_NOTHALTED;
1135 target->state = TARGET_RUNNING;
1136 return ERROR_OK;
1137 }
1138
1139 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1140 " nvic_icsr = 0x%" PRIx32,
1141 cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
1142
1143 retval = cortex_m_debug_entry(target);
1144 if (retval != ERROR_OK)
1145 return retval;
1146 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1147
1148 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1149 " nvic_icsr = 0x%" PRIx32,
1150 cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
1151
1152 return ERROR_OK;
1153 }
1154
1155 static int cortex_m_assert_reset(struct target *target)
1156 {
1157 struct cortex_m_common *cortex_m = target_to_cm(target);
1158 struct armv7m_common *armv7m = &cortex_m->armv7m;
1159 enum cortex_m_soft_reset_config reset_config = cortex_m->soft_reset_config;
1160
1161 LOG_DEBUG("target->state: %s",
1162 target_state_name(target));
1163
1164 enum reset_types jtag_reset_config = jtag_get_reset_config();
1165
1166 if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {
1167 /* allow scripts to override the reset event */
1168
1169 target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
1170 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
1171 target->state = TARGET_RESET;
1172
1173 return ERROR_OK;
1174 }
1175
1176 /* some cores support connecting while srst is asserted
1177 * use that mode is it has been configured */
1178
1179 bool srst_asserted = false;
1180
1181 if (!target_was_examined(target)) {
1182 if (jtag_reset_config & RESET_HAS_SRST) {
1183 adapter_assert_reset();
1184 if (target->reset_halt)
1185 LOG_ERROR("Target not examined, will not halt after reset!");
1186 return ERROR_OK;
1187 } else {
1188 LOG_ERROR("Target not examined, reset NOT asserted!");
1189 return ERROR_FAIL;
1190 }
1191 }
1192
1193 if ((jtag_reset_config & RESET_HAS_SRST) &&
1194 (jtag_reset_config & RESET_SRST_NO_GATING)) {
1195 adapter_assert_reset();
1196 srst_asserted = true;
1197 }
1198
1199 /* Enable debug requests */
1200 int retval;
1201 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
1202 /* Store important errors instead of failing and proceed to reset assert */
1203
1204 if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN))
1205 retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);
1206
1207 /* If the processor is sleeping in a WFI or WFE instruction, the
1208 * C_HALT bit must be asserted to regain control */
1209 if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP))
1210 retval = cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1211
1212 mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
1213 /* Ignore less important errors */
1214
1215 if (!target->reset_halt) {
1216 /* Set/Clear C_MASKINTS in a separate operation */
1217 cortex_m_set_maskints_for_run(target);
1218
1219 /* clear any debug flags before resuming */
1220 cortex_m_clear_halt(target);
1221
1222 /* clear C_HALT in dhcsr reg */
1223 cortex_m_write_debug_halt_mask(target, 0, C_HALT);
1224 } else {
1225 /* Halt in debug on reset; endreset_event() restores DEMCR.
1226 *
1227 * REVISIT catching BUSERR presumably helps to defend against
1228 * bad vector table entries. Should this include MMERR or
1229 * other flags too?
1230 */
1231 int retval2;
1232 retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
1233 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
1234 if (retval != ERROR_OK || retval2 != ERROR_OK)
1235 LOG_INFO("AP write error, reset will not halt");
1236 }
1237
1238 if (jtag_reset_config & RESET_HAS_SRST) {
1239 /* default to asserting srst */
1240 if (!srst_asserted)
1241 adapter_assert_reset();
1242
1243 /* srst is asserted, ignore AP access errors */
1244 retval = ERROR_OK;
1245 } else {
1246 /* Use a standard Cortex-M3 software reset mechanism.
1247 * We default to using VECTRESET as it is supported on all current cores
1248 * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!)
1249 * This has the disadvantage of not resetting the peripherals, so a
1250 * reset-init event handler is needed to perform any peripheral resets.
1251 */
1252 if (!cortex_m->vectreset_supported
1253 && reset_config == CORTEX_M_RESET_VECTRESET) {
1254 reset_config = CORTEX_M_RESET_SYSRESETREQ;
1255 LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
1256 LOG_WARNING("Set 'cortex_m reset_config sysresetreq'.");
1257 }
1258
1259 LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ)
1260 ? "SYSRESETREQ" : "VECTRESET");
1261
1262 if (reset_config == CORTEX_M_RESET_VECTRESET) {
1263 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1264 "handler to reset any peripherals or configure hardware srst support.");
1265 }
1266
1267 int retval3;
1268 retval3 = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
1269 AIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ)
1270 ? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
1271 if (retval3 != ERROR_OK)
1272 LOG_DEBUG("Ignoring AP write error right after reset");
1273
1274 retval3 = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
1275 if (retval3 != ERROR_OK) {
1276 LOG_ERROR("DP initialisation failed");
1277 /* The error return value must not be propagated in this case.
1278 * SYSRESETREQ or VECTRESET have been possibly triggered
1279 * so reset processing should continue */
1280 } else {
1281 /* I do not know why this is necessary, but it
1282 * fixes strange effects (step/resume cause NMI
1283 * after reset) on LM3S6918 -- Michael Schwingen
1284 */
1285 uint32_t tmp;
1286 mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);
1287 }
1288 }
1289
1290 target->state = TARGET_RESET;
1291 jtag_sleep(50000);
1292
1293 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
1294
1295 /* now return stored error code if any */
1296 if (retval != ERROR_OK)
1297 return retval;
1298
1299 if (target->reset_halt) {
1300 retval = target_halt(target);
1301 if (retval != ERROR_OK)
1302 return retval;
1303 }
1304
1305 return ERROR_OK;
1306 }
1307
1308 static int cortex_m_deassert_reset(struct target *target)
1309 {
1310 struct armv7m_common *armv7m = &target_to_cm(target)->armv7m;
1311
1312 LOG_DEBUG("target->state: %s",
1313 target_state_name(target));
1314
1315 /* deassert reset lines */
1316 adapter_deassert_reset();
1317
1318 enum reset_types jtag_reset_config = jtag_get_reset_config();
1319
1320 if ((jtag_reset_config & RESET_HAS_SRST) &&
1321 !(jtag_reset_config & RESET_SRST_NO_GATING) &&
1322 target_was_examined(target)) {
1323
1324 int retval = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
1325 if (retval != ERROR_OK) {
1326 LOG_ERROR("DP initialisation failed");
1327 return retval;
1328 }
1329 }
1330
1331 return ERROR_OK;
1332 }
1333
1334 int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
1335 {
1336 int retval;
1337 unsigned int fp_num = 0;
1338 struct cortex_m_common *cortex_m = target_to_cm(target);
1339 struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
1340
1341 if (breakpoint->set) {
1342 LOG_WARNING("breakpoint (BPID: %" PRIu32 ") already set", breakpoint->unique_id);
1343 return ERROR_OK;
1344 }
1345
1346 if (breakpoint->type == BKPT_HARD) {
1347 uint32_t fpcr_value;
1348 while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code))
1349 fp_num++;
1350 if (fp_num >= cortex_m->fp_num_code) {
1351 LOG_ERROR("Can not find free FPB Comparator!");
1352 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1353 }
1354 breakpoint->set = fp_num + 1;
1355 fpcr_value = breakpoint->address | 1;
1356 if (cortex_m->fp_rev == 0) {
1357 if (breakpoint->address > 0x1FFFFFFF) {
1358 LOG_ERROR("Cortex-M Flash Patch Breakpoint rev.1 cannot handle HW breakpoint above address 0x1FFFFFFE");
1359 return ERROR_FAIL;
1360 }
1361 uint32_t hilo;
1362 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
1363 fpcr_value = (fpcr_value & 0x1FFFFFFC) | hilo | 1;
1364 } else if (cortex_m->fp_rev > 1) {
1365 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1366 return ERROR_FAIL;
1367 }
1368 comparator_list[fp_num].used = true;
1369 comparator_list[fp_num].fpcr_value = fpcr_value;
1370 target_write_u32(target, comparator_list[fp_num].fpcr_address,
1371 comparator_list[fp_num].fpcr_value);
1372 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "",
1373 fp_num,
1374 comparator_list[fp_num].fpcr_value);
1375 if (!cortex_m->fpb_enabled) {
1376 LOG_DEBUG("FPB wasn't enabled, do it now");
1377 retval = cortex_m_enable_fpb(target);
1378 if (retval != ERROR_OK) {
1379 LOG_ERROR("Failed to enable the FPB");
1380 return retval;
1381 }
1382
1383 cortex_m->fpb_enabled = true;
1384 }
1385 } else if (breakpoint->type == BKPT_SOFT) {
1386 uint8_t code[4];
1387
1388 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1389 * semihosting; don't use that. Otherwise the BKPT
1390 * parameter is arbitrary.
1391 */
1392 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1393 retval = target_read_memory(target,
1394 breakpoint->address & 0xFFFFFFFE,
1395 breakpoint->length, 1,
1396 breakpoint->orig_instr);
1397 if (retval != ERROR_OK)
1398 return retval;
1399 retval = target_write_memory(target,
1400 breakpoint->address & 0xFFFFFFFE,
1401 breakpoint->length, 1,
1402 code);
1403 if (retval != ERROR_OK)
1404 return retval;
1405 breakpoint->set = true;
1406 }
1407
1408 LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
1409 breakpoint->unique_id,
1410 (int)(breakpoint->type),
1411 breakpoint->address,
1412 breakpoint->length,
1413 breakpoint->set);
1414
1415 return ERROR_OK;
1416 }
1417
1418 int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1419 {
1420 int retval;
1421 struct cortex_m_common *cortex_m = target_to_cm(target);
1422 struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
1423
1424 if (breakpoint->set <= 0) {
1425 LOG_WARNING("breakpoint not set");
1426 return ERROR_OK;
1427 }
1428
1429 LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
1430 breakpoint->unique_id,
1431 (int)(breakpoint->type),
1432 breakpoint->address,
1433 breakpoint->length,
1434 breakpoint->set);
1435
1436 if (breakpoint->type == BKPT_HARD) {
1437 unsigned int fp_num = breakpoint->set - 1;
1438 if (fp_num >= cortex_m->fp_num_code) {
1439 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1440 return ERROR_OK;
1441 }
1442 comparator_list[fp_num].used = false;
1443 comparator_list[fp_num].fpcr_value = 0;
1444 target_write_u32(target, comparator_list[fp_num].fpcr_address,
1445 comparator_list[fp_num].fpcr_value);
1446 } else {
1447 /* restore original instruction (kept in target endianness) */
1448 retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE,
1449 breakpoint->length, 1,
1450 breakpoint->orig_instr);
1451 if (retval != ERROR_OK)
1452 return retval;
1453 }
1454 breakpoint->set = false;
1455
1456 return ERROR_OK;
1457 }
1458
1459 int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
1460 {
1461 if (breakpoint->length == 3) {
1462 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1463 breakpoint->length = 2;
1464 }
1465
1466 if ((breakpoint->length != 2)) {
1467 LOG_INFO("only breakpoints of two bytes length supported");
1468 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1469 }
1470
1471 return cortex_m_set_breakpoint(target, breakpoint);
1472 }
1473
1474 int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1475 {
1476 if (!breakpoint->set)
1477 return ERROR_OK;
1478
1479 return cortex_m_unset_breakpoint(target, breakpoint);
1480 }
1481
1482 static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
1483 {
1484 unsigned int dwt_num = 0;
1485 struct cortex_m_common *cortex_m = target_to_cm(target);
1486
1487 /* REVISIT Don't fully trust these "not used" records ... users
1488 * may set up breakpoints by hand, e.g. dual-address data value
1489 * watchpoint using comparator #1; comparator #0 matching cycle
1490 * count; send data trace info through ITM and TPIU; etc
1491 */
1492 struct cortex_m_dwt_comparator *comparator;
1493
1494 for (comparator = cortex_m->dwt_comparator_list;
1495 comparator->used && dwt_num < cortex_m->dwt_num_comp;
1496 comparator++, dwt_num++)
1497 continue;
1498 if (dwt_num >= cortex_m->dwt_num_comp) {
1499 LOG_ERROR("Can not find free DWT Comparator");
1500 return ERROR_FAIL;
1501 }
1502 comparator->used = true;
1503 watchpoint->set = dwt_num + 1;
1504
1505 comparator->comp = watchpoint->address;
1506 target_write_u32(target, comparator->dwt_comparator_address + 0,
1507 comparator->comp);
1508
1509 if ((cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M) {
1510 uint32_t mask = 0, temp;
1511
1512 /* watchpoint params were validated earlier */
1513 temp = watchpoint->length;
1514 while (temp) {
1515 temp >>= 1;
1516 mask++;
1517 }
1518 mask--;
1519
1520 comparator->mask = mask;
1521 target_write_u32(target, comparator->dwt_comparator_address + 4,
1522 comparator->mask);
1523
1524 switch (watchpoint->rw) {
1525 case WPT_READ:
1526 comparator->function = 5;
1527 break;
1528 case WPT_WRITE:
1529 comparator->function = 6;
1530 break;
1531 case WPT_ACCESS:
1532 comparator->function = 7;
1533 break;
1534 }
1535 } else {
1536 uint32_t data_size = watchpoint->length >> 1;
1537 comparator->mask = (watchpoint->length >> 1) | 1;
1538
1539 switch (watchpoint->rw) {
1540 case WPT_ACCESS:
1541 comparator->function = 4;
1542 break;
1543 case WPT_WRITE:
1544 comparator->function = 5;
1545 break;
1546 case WPT_READ:
1547 comparator->function = 6;
1548 break;
1549 }
1550 comparator->function = comparator->function | (1 << 4) |
1551 (data_size << 10);
1552 }
1553
1554 target_write_u32(target, comparator->dwt_comparator_address + 8,
1555 comparator->function);
1556
1557 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1558 watchpoint->unique_id, dwt_num,
1559 (unsigned) comparator->comp,
1560 (unsigned) comparator->mask,
1561 (unsigned) comparator->function);
1562 return ERROR_OK;
1563 }
1564
1565 static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
1566 {
1567 struct cortex_m_common *cortex_m = target_to_cm(target);
1568 struct cortex_m_dwt_comparator *comparator;
1569
1570 if (watchpoint->set <= 0) {
1571 LOG_WARNING("watchpoint (wpid: %d) not set",
1572 watchpoint->unique_id);
1573 return ERROR_OK;
1574 }
1575
1576 unsigned int dwt_num = watchpoint->set - 1;
1577
1578 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1579 watchpoint->unique_id, dwt_num,
1580 (unsigned) watchpoint->address);
1581
1582 if (dwt_num >= cortex_m->dwt_num_comp) {
1583 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1584 return ERROR_OK;
1585 }
1586
1587 comparator = cortex_m->dwt_comparator_list + dwt_num;
1588 comparator->used = false;
1589 comparator->function = 0;
1590 target_write_u32(target, comparator->dwt_comparator_address + 8,
1591 comparator->function);
1592
1593 watchpoint->set = false;
1594
1595 return ERROR_OK;
1596 }
1597
1598 int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
1599 {
1600 struct cortex_m_common *cortex_m = target_to_cm(target);
1601
1602 if (cortex_m->dwt_comp_available < 1) {
1603 LOG_DEBUG("no comparators?");
1604 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1605 }
1606
1607 /* hardware doesn't support data value masking */
1608 if (watchpoint->mask != ~(uint32_t)0) {
1609 LOG_DEBUG("watchpoint value masks not supported");
1610 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1611 }
1612
1613 /* hardware allows address masks of up to 32K */
1614 unsigned mask;
1615
1616 for (mask = 0; mask < 16; mask++) {
1617 if ((1u << mask) == watchpoint->length)
1618 break;
1619 }
1620 if (mask == 16) {
1621 LOG_DEBUG("unsupported watchpoint length");
1622 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1623 }
1624 if (watchpoint->address & ((1 << mask) - 1)) {
1625 LOG_DEBUG("watchpoint address is unaligned");
1626 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1627 }
1628
1629 /* Caller doesn't seem to be able to describe watching for data
1630 * values of zero; that flags "no value".
1631 *
1632 * REVISIT This DWT may well be able to watch for specific data
1633 * values. Requires comparator #1 to set DATAVMATCH and match
1634 * the data, and another comparator (DATAVADDR0) matching addr.
1635 */
1636 if (watchpoint->value) {
1637 LOG_DEBUG("data value watchpoint not YET supported");
1638 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1639 }
1640
1641 cortex_m->dwt_comp_available--;
1642 LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available);
1643
1644 return ERROR_OK;
1645 }
1646
1647 int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
1648 {
1649 struct cortex_m_common *cortex_m = target_to_cm(target);
1650
1651 /* REVISIT why check? DWT can be updated with core running ... */
1652 if (target->state != TARGET_HALTED) {
1653 LOG_WARNING("target not halted");
1654 return ERROR_TARGET_NOT_HALTED;
1655 }
1656
1657 if (watchpoint->set)
1658 cortex_m_unset_watchpoint(target, watchpoint);
1659
1660 cortex_m->dwt_comp_available++;
1661 LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available);
1662
1663 return ERROR_OK;
1664 }
1665
1666 int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
1667 {
1668 if (target->debug_reason != DBG_REASON_WATCHPOINT)
1669 return ERROR_FAIL;
1670
1671 struct cortex_m_common *cortex_m = target_to_cm(target);
1672
1673 for (struct watchpoint *wp = target->watchpoints; wp; wp = wp->next) {
1674 if (!wp->set)
1675 continue;
1676
1677 unsigned int dwt_num = wp->set - 1;
1678 struct cortex_m_dwt_comparator *comparator = cortex_m->dwt_comparator_list + dwt_num;
1679
1680 uint32_t dwt_function;
1681 int retval = target_read_u32(target, comparator->dwt_comparator_address + 8, &dwt_function);
1682 if (retval != ERROR_OK)
1683 return ERROR_FAIL;
1684
1685 /* check the MATCHED bit */
1686 if (dwt_function & BIT(24)) {
1687 *hit_watchpoint = wp;
1688 return ERROR_OK;
1689 }
1690 }
1691
1692 return ERROR_FAIL;
1693 }
1694
1695 void cortex_m_enable_watchpoints(struct target *target)
1696 {
1697 struct watchpoint *watchpoint = target->watchpoints;
1698
1699 /* set any pending watchpoints */
1700 while (watchpoint) {
1701 if (!watchpoint->set)
1702 cortex_m_set_watchpoint(target, watchpoint);
1703 watchpoint = watchpoint->next;
1704 }
1705 }
1706
1707 static int cortex_m_read_memory(struct target *target, target_addr_t address,
1708 uint32_t size, uint32_t count, uint8_t *buffer)
1709 {
1710 struct armv7m_common *armv7m = target_to_armv7m(target);
1711
1712 if (armv7m->arm.arch == ARM_ARCH_V6M) {
1713 /* armv6m does not handle unaligned memory access */
1714 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1715 return ERROR_TARGET_UNALIGNED_ACCESS;
1716 }
1717
1718 return mem_ap_read_buf(armv7m->debug_ap, buffer, size, count, address);
1719 }
1720
1721 static int cortex_m_write_memory(struct target *target, target_addr_t address,
1722 uint32_t size, uint32_t count, const uint8_t *buffer)
1723 {
1724 struct armv7m_common *armv7m = target_to_armv7m(target);
1725
1726 if (armv7m->arm.arch == ARM_ARCH_V6M) {
1727 /* armv6m does not handle unaligned memory access */
1728 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1729 return ERROR_TARGET_UNALIGNED_ACCESS;
1730 }
1731
1732 return mem_ap_write_buf(armv7m->debug_ap, buffer, size, count, address);
1733 }
1734
1735 static int cortex_m_init_target(struct command_context *cmd_ctx,
1736 struct target *target)
1737 {
1738 armv7m_build_reg_cache(target);
1739 arm_semihosting_init(target);
1740 return ERROR_OK;
1741 }
1742
1743 void cortex_m_deinit_target(struct target *target)
1744 {
1745 struct cortex_m_common *cortex_m = target_to_cm(target);
1746
1747 free(cortex_m->fp_comparator_list);
1748
1749 cortex_m_dwt_free(target);
1750 armv7m_free_reg_cache(target);
1751
1752 free(target->private_config);
1753 free(cortex_m);
1754 }
1755
1756 int cortex_m_profiling(struct target *target, uint32_t *samples,
1757 uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
1758 {
1759 struct timeval timeout, now;
1760 struct armv7m_common *armv7m = target_to_armv7m(target);
1761 uint32_t reg_value;
1762 int retval;
1763
1764 retval = target_read_u32(target, DWT_PCSR, &reg_value);
1765 if (retval != ERROR_OK) {
1766 LOG_ERROR("Error while reading PCSR");
1767 return retval;
1768 }
1769 if (reg_value == 0) {
1770 LOG_INFO("PCSR sampling not supported on this processor.");
1771 return target_profiling_default(target, samples, max_num_samples, num_samples, seconds);
1772 }
1773
1774 gettimeofday(&timeout, NULL);
1775 timeval_add_time(&timeout, seconds, 0);
1776
1777 LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
1778
1779 /* Make sure the target is running */
1780 target_poll(target);
1781 if (target->state == TARGET_HALTED)
1782 retval = target_resume(target, 1, 0, 0, 0);
1783
1784 if (retval != ERROR_OK) {
1785 LOG_ERROR("Error while resuming target");
1786 return retval;
1787 }
1788
1789 uint32_t sample_count = 0;
1790
1791 for (;;) {
1792 if (armv7m && armv7m->debug_ap) {
1793 uint32_t read_count = max_num_samples - sample_count;
1794 if (read_count > 1024)
1795 read_count = 1024;
1796
1797 retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
1798 (void *)&samples[sample_count],
1799 4, read_count, DWT_PCSR);
1800 sample_count += read_count;
1801 } else {
1802 target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
1803 }
1804
1805 if (retval != ERROR_OK) {
1806 LOG_ERROR("Error while reading PCSR");
1807 return retval;
1808 }
1809
1810
1811 gettimeofday(&now, NULL);
1812 if (sample_count >= max_num_samples || timeval_compare(&now, &timeout) > 0) {
1813 LOG_INFO("Profiling completed. %" PRIu32 " samples.", sample_count);
1814 break;
1815 }
1816 }
1817
1818 *num_samples = sample_count;
1819 return retval;
1820 }
1821
1822
1823 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1824 * on r/w if the core is not running, and clear on resume or reset ... or
1825 * at least, in a post_restore_context() method.
1826 */
1827
1828 struct dwt_reg_state {
1829 struct target *target;
1830 uint32_t addr;
1831 uint8_t value[4]; /* scratch/cache */
1832 };
1833
1834 static int cortex_m_dwt_get_reg(struct reg *reg)
1835 {
1836 struct dwt_reg_state *state = reg->arch_info;
1837
1838 uint32_t tmp;
1839 int retval = target_read_u32(state->target, state->addr, &tmp);
1840 if (retval != ERROR_OK)
1841 return retval;
1842
1843 buf_set_u32(state->value, 0, 32, tmp);
1844 return ERROR_OK;
1845 }
1846
1847 static int cortex_m_dwt_set_reg(struct reg *reg, uint8_t *buf)
1848 {
1849 struct dwt_reg_state *state = reg->arch_info;
1850
1851 return target_write_u32(state->target, state->addr,
1852 buf_get_u32(buf, 0, reg->size));
1853 }
1854
1855 struct dwt_reg {
1856 uint32_t addr;
1857 const char *name;
1858 unsigned size;
1859 };
1860
1861 static const struct dwt_reg dwt_base_regs[] = {
1862 { DWT_CTRL, "dwt_ctrl", 32, },
1863 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1864 * increments while the core is asleep.
1865 */
1866 { DWT_CYCCNT, "dwt_cyccnt", 32, },
1867 /* plus some 8 bit counters, useful for profiling with TPIU */
1868 };
1869
1870 static const struct dwt_reg dwt_comp[] = {
1871 #define DWT_COMPARATOR(i) \
1872 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1873 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1874 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1875 DWT_COMPARATOR(0),
1876 DWT_COMPARATOR(1),
1877 DWT_COMPARATOR(2),
1878 DWT_COMPARATOR(3),
1879 DWT_COMPARATOR(4),
1880 DWT_COMPARATOR(5),
1881 DWT_COMPARATOR(6),
1882 DWT_COMPARATOR(7),
1883 DWT_COMPARATOR(8),
1884 DWT_COMPARATOR(9),
1885 DWT_COMPARATOR(10),
1886 DWT_COMPARATOR(11),
1887 DWT_COMPARATOR(12),
1888 DWT_COMPARATOR(13),
1889 DWT_COMPARATOR(14),
1890 DWT_COMPARATOR(15),
1891 #undef DWT_COMPARATOR
1892 };
1893
1894 static const struct reg_arch_type dwt_reg_type = {
1895 .get = cortex_m_dwt_get_reg,
1896 .set = cortex_m_dwt_set_reg,
1897 };
1898
1899 static void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dwt_reg *d)
1900 {
1901 struct dwt_reg_state *state;
1902
1903 state = calloc(1, sizeof(*state));
1904 if (!state)
1905 return;
1906 state->addr = d->addr;
1907 state->target = t;
1908
1909 r->name = d->name;
1910 r->size = d->size;
1911 r->value = state->value;
1912 r->arch_info = state;
1913 r->type = &dwt_reg_type;
1914 }
1915
1916 static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)
1917 {
1918 uint32_t dwtcr;
1919 struct reg_cache *cache;
1920 struct cortex_m_dwt_comparator *comparator;
1921 int reg;
1922
1923 target_read_u32(target, DWT_CTRL, &dwtcr);
1924 LOG_DEBUG("DWT_CTRL: 0x%" PRIx32, dwtcr);
1925 if (!dwtcr) {
1926 LOG_DEBUG("no DWT");
1927 return;
1928 }
1929
1930 target_read_u32(target, DWT_DEVARCH, &cm->dwt_devarch);
1931 LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32, cm->dwt_devarch);
1932
1933 cm->dwt_num_comp = (dwtcr >> 28) & 0xF;
1934 cm->dwt_comp_available = cm->dwt_num_comp;
1935 cm->dwt_comparator_list = calloc(cm->dwt_num_comp,
1936 sizeof(struct cortex_m_dwt_comparator));
1937 if (!cm->dwt_comparator_list) {
1938 fail0:
1939 cm->dwt_num_comp = 0;
1940 LOG_ERROR("out of mem");
1941 return;
1942 }
1943
1944 cache = calloc(1, sizeof(*cache));
1945 if (!cache) {
1946 fail1:
1947 free(cm->dwt_comparator_list);
1948 goto fail0;
1949 }
1950 cache->name = "Cortex-M DWT registers";
1951 cache->num_regs = 2 + cm->dwt_num_comp * 3;
1952 cache->reg_list = calloc(cache->num_regs, sizeof(*cache->reg_list));
1953 if (!cache->reg_list) {
1954 free(cache);
1955 goto fail1;
1956 }
1957
1958 for (reg = 0; reg < 2; reg++)
1959 cortex_m_dwt_addreg(target, cache->reg_list + reg,
1960 dwt_base_regs + reg);
1961
1962 comparator = cm->dwt_comparator_list;
1963 for (unsigned int i = 0; i < cm->dwt_num_comp; i++, comparator++) {
1964 int j;
1965
1966 comparator->dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1967 for (j = 0; j < 3; j++, reg++)
1968 cortex_m_dwt_addreg(target, cache->reg_list + reg,
1969 dwt_comp + 3 * i + j);
1970
1971 /* make sure we clear any watchpoints enabled on the target */
1972 target_write_u32(target, comparator->dwt_comparator_address + 8, 0);
1973 }
1974
1975 *register_get_last_cache_p(&target->reg_cache) = cache;
1976 cm->dwt_cache = cache;
1977
1978 LOG_DEBUG("DWT dwtcr 0x%" PRIx32 ", comp %d, watch%s",
1979 dwtcr, cm->dwt_num_comp,
1980 (dwtcr & (0xf << 24)) ? " only" : "/trigger");
1981
1982 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1983 * implement single-address data value watchpoints ... so we
1984 * won't need to check it later, when asked to set one up.
1985 */
1986 }
1987
1988 static void cortex_m_dwt_free(struct target *target)
1989 {
1990 struct cortex_m_common *cm = target_to_cm(target);
1991 struct reg_cache *cache = cm->dwt_cache;
1992
1993 free(cm->dwt_comparator_list);
1994 cm->dwt_comparator_list = NULL;
1995 cm->dwt_num_comp = 0;
1996
1997 if (cache) {
1998 register_unlink_cache(&target->reg_cache, cache);
1999
2000 if (cache->reg_list) {
2001 for (size_t i = 0; i < cache->num_regs; i++)
2002 free(cache->reg_list[i].arch_info);
2003 free(cache->reg_list);
2004 }
2005 free(cache);
2006 }
2007 cm->dwt_cache = NULL;
2008 }
2009
2010 #define MVFR0 0xe000ef40
2011 #define MVFR1 0xe000ef44
2012
2013 #define MVFR0_DEFAULT_M4 0x10110021
2014 #define MVFR1_DEFAULT_M4 0x11000011
2015
2016 #define MVFR0_DEFAULT_M7_SP 0x10110021
2017 #define MVFR0_DEFAULT_M7_DP 0x10110221
2018 #define MVFR1_DEFAULT_M7_SP 0x11000011
2019 #define MVFR1_DEFAULT_M7_DP 0x12000011
2020
2021 static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
2022 struct adiv5_ap **debug_ap)
2023 {
2024 if (dap_find_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
2025 return ERROR_OK;
2026
2027 return dap_find_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
2028 }
2029
2030 int cortex_m_examine(struct target *target)
2031 {
2032 int retval;
2033 uint32_t cpuid, fpcr, mvfr0, mvfr1;
2034 struct cortex_m_common *cortex_m = target_to_cm(target);
2035 struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
2036 struct armv7m_common *armv7m = target_to_armv7m(target);
2037
2038 /* hla_target shares the examine handler but does not support
2039 * all its calls */
2040 if (!armv7m->is_hla_target) {
2041 if (cortex_m->apsel == DP_APSEL_INVALID) {
2042 /* Search for the MEM-AP */
2043 retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
2044 if (retval != ERROR_OK) {
2045 LOG_ERROR("Could not find MEM-AP to control the core");
2046 return retval;
2047 }
2048 } else {
2049 armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel);
2050 }
2051
2052 /* Leave (only) generic DAP stuff for debugport_init(); */
2053 armv7m->debug_ap->memaccess_tck = 8;
2054
2055 retval = mem_ap_init(armv7m->debug_ap);
2056 if (retval != ERROR_OK)
2057 return retval;
2058 }
2059
2060 if (!target_was_examined(target)) {
2061 target_set_examined(target);
2062
2063 /* Read from Device Identification Registers */
2064 retval = target_read_u32(target, CPUID, &cpuid);
2065 if (retval != ERROR_OK)
2066 return retval;
2067
2068 /* Get ARCH and CPU types */
2069 const enum cortex_m_partno core_partno = (cpuid & ARM_CPUID_PARTNO_MASK) >> ARM_CPUID_PARTNO_POS;
2070
2071 for (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) {
2072 if (core_partno == cortex_m_parts[n].partno) {
2073 cortex_m->core_info = &cortex_m_parts[n];
2074 break;
2075 }
2076 }
2077
2078 if (!cortex_m->core_info) {
2079 LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno);
2080 return ERROR_FAIL;
2081 }
2082
2083 armv7m->arm.arch = cortex_m->core_info->arch;
2084
2085 LOG_DEBUG("%s r%" PRId8 "p%" PRId8 " processor detected",
2086 cortex_m->core_info->name, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
2087 cortex_m->maskints_erratum = false;
2088 if (core_partno == CORTEX_M7_PARTNO) {
2089 uint8_t rev, patch;
2090 rev = (cpuid >> 20) & 0xf;
2091 patch = (cpuid >> 0) & 0xf;
2092 if ((rev == 0) && (patch < 2)) {
2093 LOG_WARNING("Silicon bug: single stepping may enter pending exception handler!");
2094 cortex_m->maskints_erratum = true;
2095 }
2096 }
2097 LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
2098
2099 if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) {
2100 target_read_u32(target, MVFR0, &mvfr0);
2101 target_read_u32(target, MVFR1, &mvfr1);
2102
2103 /* test for floating point feature on Cortex-M4 */
2104 if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
2105 LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m->core_info->name);
2106 armv7m->fp_feature = FPV4_SP;
2107 }
2108 } else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) {
2109 target_read_u32(target, MVFR0, &mvfr0);
2110 target_read_u32(target, MVFR1, &mvfr1);
2111
2112 /* test for floating point features on Cortex-M7 */
2113 if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
2114 LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m->core_info->name);
2115 armv7m->fp_feature = FPV5_SP;
2116 } else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
2117 LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m->core_info->name);
2118 armv7m->fp_feature = FPV5_DP;
2119 }
2120 }
2121
2122 /* VECTRESET is supported only on ARMv7-M cores */
2123 cortex_m->vectreset_supported = armv7m->arm.arch == ARM_ARCH_V7M;
2124
2125 /* Check for FPU, otherwise mark FPU register as non-existent */
2126 if (armv7m->fp_feature == FP_NONE)
2127 for (size_t idx = ARMV7M_FPU_FIRST_REG; idx <= ARMV7M_FPU_LAST_REG; idx++)
2128 armv7m->arm.core_cache->reg_list[idx].exist = false;
2129
2130 if (armv7m->arm.arch != ARM_ARCH_V8M)
2131 for (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++)
2132 armv7m->arm.core_cache->reg_list[idx].exist = false;
2133
2134 if (!armv7m->is_hla_target) {
2135 if (cortex_m->core_info->flags & CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K)
2136 /* Cortex-M3/M4 have 4096 bytes autoincrement range,
2137 * s. ARM IHI 0031C: MEM-AP 7.2.2 */
2138 armv7m->debug_ap->tar_autoincr_block = (1 << 12);
2139 }
2140
2141 /* Enable debug requests */
2142 retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr);
2143 if (retval != ERROR_OK)
2144 return retval;
2145 if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
2146 uint32_t dhcsr = (cortex_m->dcb_dhcsr | C_DEBUGEN) & ~(C_HALT | C_STEP | C_MASKINTS);
2147
2148 retval = target_write_u32(target, DCB_DHCSR, DBGKEY | (dhcsr & 0x0000FFFFUL));
2149 if (retval != ERROR_OK)
2150 return retval;
2151 cortex_m->dcb_dhcsr = dhcsr;
2152 }
2153
2154 /* Configure trace modules */
2155 retval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
2156 if (retval != ERROR_OK)
2157 return retval;
2158
2159 if (armv7m->trace_config.itm_deferred_config)
2160 armv7m_trace_itm_config(target);
2161
2162 /* NOTE: FPB and DWT are both optional. */
2163
2164 /* Setup FPB */
2165 target_read_u32(target, FP_CTRL, &fpcr);
2166 /* bits [14:12] and [7:4] */
2167 cortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF);
2168 cortex_m->fp_num_lit = (fpcr >> 8) & 0xF;
2169 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
2170 Revision is zero base, fp_rev == 1 means Rev.2 ! */
2171 cortex_m->fp_rev = (fpcr >> 28) & 0xf;
2172 free(cortex_m->fp_comparator_list);
2173 cortex_m->fp_comparator_list = calloc(
2174 cortex_m->fp_num_code + cortex_m->fp_num_lit,
2175 sizeof(struct cortex_m_fp_comparator));
2176 cortex_m->fpb_enabled = fpcr & 1;
2177 for (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
2178 cortex_m->fp_comparator_list[i].type =
2179 (i < cortex_m->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
2180 cortex_m->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
2181
2182 /* make sure we clear any breakpoints enabled on the target */
2183 target_write_u32(target, cortex_m->fp_comparator_list[i].fpcr_address, 0);
2184 }
2185 LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i",
2186 fpcr,
2187 cortex_m->fp_num_code,
2188 cortex_m->fp_num_lit);
2189
2190 /* Setup DWT */
2191 cortex_m_dwt_free(target);
2192 cortex_m_dwt_setup(cortex_m, target);
2193
2194 /* These hardware breakpoints only work for code in flash! */
2195 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
2196 target_name(target),
2197 cortex_m->fp_num_code,
2198 cortex_m->dwt_num_comp);
2199 }
2200
2201 return ERROR_OK;
2202 }
2203
2204 static int cortex_m_dcc_read(struct target *target, uint8_t *value, uint8_t *ctrl)
2205 {
2206 struct armv7m_common *armv7m = target_to_armv7m(target);
2207 uint16_t dcrdr;
2208 uint8_t buf[2];
2209 int retval;
2210
2211 retval = mem_ap_read_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);
2212 if (retval != ERROR_OK)
2213 return retval;
2214
2215 dcrdr = target_buffer_get_u16(target, buf);
2216 *ctrl = (uint8_t)dcrdr;
2217 *value = (uint8_t)(dcrdr >> 8);
2218
2219 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
2220
2221 /* write ack back to software dcc register
2222 * signify we have read data */
2223 if (dcrdr & (1 << 0)) {
2224 target_buffer_set_u16(target, buf, 0);
2225 retval = mem_ap_write_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);
2226 if (retval != ERROR_OK)
2227 return retval;
2228 }
2229
2230 return ERROR_OK;
2231 }
2232
2233 static int cortex_m_target_request_data(struct target *target,
2234 uint32_t size, uint8_t *buffer)
2235 {
2236 uint8_t data;
2237 uint8_t ctrl;
2238 uint32_t i;
2239
2240 for (i = 0; i < (size * 4); i++) {
2241 int retval = cortex_m_dcc_read(target, &data, &ctrl);
2242 if (retval != ERROR_OK)
2243 return retval;
2244 buffer[i] = data;
2245 }
2246
2247 return ERROR_OK;
2248 }
2249
2250 static int cortex_m_handle_target_request(void *priv)
2251 {
2252 struct target *target = priv;
2253 if (!target_was_examined(target))
2254 return ERROR_OK;
2255
2256 if (!target->dbg_msg_enabled)
2257 return ERROR_OK;
2258
2259 if (target->state == TARGET_RUNNING) {
2260 uint8_t data;
2261 uint8_t ctrl;
2262 int retval;
2263
2264 retval = cortex_m_dcc_read(target, &data, &ctrl);
2265 if (retval != ERROR_OK)
2266 return retval;
2267
2268 /* check if we have data */
2269 if (ctrl & (1 << 0)) {
2270 uint32_t request;
2271
2272 /* we assume target is quick enough */
2273 request = data;
2274 for (int i = 1; i <= 3; i++) {
2275 retval = cortex_m_dcc_read(target, &data, &ctrl);
2276 if (retval != ERROR_OK)
2277 return retval;
2278 request |= ((uint32_t)data << (i * 8));
2279 }
2280 target_request(target, request);
2281 }
2282 }
2283
2284 return ERROR_OK;
2285 }
2286
2287 static int cortex_m_init_arch_info(struct target *target,
2288 struct cortex_m_common *cortex_m, struct adiv5_dap *dap)
2289 {
2290 struct armv7m_common *armv7m = &cortex_m->armv7m;
2291
2292 armv7m_init_arch_info(target, armv7m);
2293
2294 /* default reset mode is to use srst if fitted
2295 * if not it will use CORTEX_M3_RESET_VECTRESET */
2296 cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;
2297
2298 armv7m->arm.dap = dap;
2299
2300 /* register arch-specific functions */
2301 armv7m->examine_debug_reason = cortex_m_examine_debug_reason;
2302
2303 armv7m->post_debug_entry = NULL;
2304
2305 armv7m->pre_restore_context = NULL;
2306
2307 armv7m->load_core_reg_u32 = cortex_m_load_core_reg_u32;
2308 armv7m->store_core_reg_u32 = cortex_m_store_core_reg_u32;
2309
2310 target_register_timer_callback(cortex_m_handle_target_request, 1,
2311 TARGET_TIMER_TYPE_PERIODIC, target);
2312
2313 return ERROR_OK;
2314 }
2315
2316 static int cortex_m_target_create(struct target *target, Jim_Interp *interp)
2317 {
2318 struct adiv5_private_config *pc;
2319
2320 pc = (struct adiv5_private_config *)target->private_config;
2321 if (adiv5_verify_config(pc) != ERROR_OK)
2322 return ERROR_FAIL;
2323
2324 struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
2325 if (!cortex_m) {
2326 LOG_ERROR("No memory creating target");
2327 return ERROR_FAIL;
2328 }
2329
2330 cortex_m->common_magic = CORTEX_M_COMMON_MAGIC;
2331 cortex_m->apsel = pc->ap_num;
2332
2333 cortex_m_init_arch_info(target, cortex_m, pc->dap);
2334
2335 return ERROR_OK;
2336 }
2337
2338 /*--------------------------------------------------------------------------*/
2339
2340 static int cortex_m_verify_pointer(struct command_invocation *cmd,
2341 struct cortex_m_common *cm)
2342 {
2343 if (cm->common_magic != CORTEX_M_COMMON_MAGIC) {
2344 command_print(cmd, "target is not a Cortex-M");
2345 return ERROR_TARGET_INVALID;
2346 }
2347 return ERROR_OK;
2348 }
2349
2350 /*
2351 * Only stuff below this line should need to verify that its target
2352 * is a Cortex-M3. Everything else should have indirected through the
2353 * cortexm3_target structure, which is only used with CM3 targets.
2354 */
2355
2356 COMMAND_HANDLER(handle_cortex_m_vector_catch_command)
2357 {
2358 struct target *target = get_current_target(CMD_CTX);
2359 struct cortex_m_common *cortex_m = target_to_cm(target);
2360 struct armv7m_common *armv7m = &cortex_m->armv7m;
2361 uint32_t demcr = 0;
2362 int retval;
2363
2364 static const struct {
2365 char name[10];
2366 unsigned mask;
2367 } vec_ids[] = {
2368 { "hard_err", VC_HARDERR, },
2369 { "int_err", VC_INTERR, },
2370 { "bus_err", VC_BUSERR, },
2371 { "state_err", VC_STATERR, },
2372 { "chk_err", VC_CHKERR, },
2373 { "nocp_err", VC_NOCPERR, },
2374 { "mm_err", VC_MMERR, },
2375 { "reset", VC_CORERESET, },
2376 };
2377
2378 retval = cortex_m_verify_pointer(CMD, cortex_m);
2379 if (retval != ERROR_OK)
2380 return retval;
2381
2382 if (!target_was_examined(target)) {
2383 LOG_ERROR("Target not examined yet");
2384 return ERROR_FAIL;
2385 }
2386
2387 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);
2388 if (retval != ERROR_OK)
2389 return retval;
2390
2391 if (CMD_ARGC > 0) {
2392 unsigned catch = 0;
2393
2394 if (CMD_ARGC == 1) {
2395 if (strcmp(CMD_ARGV[0], "all") == 0) {
2396 catch = VC_HARDERR | VC_INTERR | VC_BUSERR
2397 | VC_STATERR | VC_CHKERR | VC_NOCPERR
2398 | VC_MMERR | VC_CORERESET;
2399 goto write;
2400 } else if (strcmp(CMD_ARGV[0], "none") == 0)
2401 goto write;
2402 }
2403 while (CMD_ARGC-- > 0) {
2404 unsigned i;
2405 for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
2406 if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name) != 0)
2407 continue;
2408 catch |= vec_ids[i].mask;
2409 break;
2410 }
2411 if (i == ARRAY_SIZE(vec_ids)) {
2412 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV[CMD_ARGC]);
2413 return ERROR_COMMAND_SYNTAX_ERROR;
2414 }
2415 }
2416 write:
2417 /* For now, armv7m->demcr only stores vector catch flags. */
2418 armv7m->demcr = catch;
2419
2420 demcr &= ~0xffff;
2421 demcr |= catch;
2422
2423 /* write, but don't assume it stuck (why not??) */
2424 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, demcr);
2425 if (retval != ERROR_OK)
2426 return retval;
2427 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);
2428 if (retval != ERROR_OK)
2429 return retval;
2430
2431 /* FIXME be sure to clear DEMCR on clean server shutdown.
2432 * Otherwise the vector catch hardware could fire when there's
2433 * no debugger hooked up, causing much confusion...
2434 */
2435 }
2436
2437 for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) {
2438 command_print(CMD, "%9s: %s", vec_ids[i].name,
2439 (demcr & vec_ids[i].mask) ? "catch" : "ignore");
2440 }
2441
2442 return ERROR_OK;
2443 }
2444
2445 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command)
2446 {
2447 struct target *target = get_current_target(CMD_CTX);
2448 struct cortex_m_common *cortex_m = target_to_cm(target);
2449 int retval;
2450
2451 static const struct jim_nvp nvp_maskisr_modes[] = {
2452 { .name = "auto", .value = CORTEX_M_ISRMASK_AUTO },
2453 { .name = "off", .value = CORTEX_M_ISRMASK_OFF },
2454 { .name = "on", .value = CORTEX_M_ISRMASK_ON },
2455 { .name = "steponly", .value = CORTEX_M_ISRMASK_STEPONLY },
2456 { .name = NULL, .value = -1 },
2457 };
2458 const struct jim_nvp *n;
2459
2460
2461 retval = cortex_m_verify_pointer(CMD, cortex_m);
2462 if (retval != ERROR_OK)
2463 return retval;
2464
2465 if (target->state != TARGET_HALTED) {
2466 command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
2467 return ERROR_OK;
2468 }
2469
2470 if (CMD_ARGC > 0) {
2471 n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
2472 if (!n->name)
2473 return ERROR_COMMAND_SYNTAX_ERROR;
2474 cortex_m->isrmasking_mode = n->value;
2475 cortex_m_set_maskints_for_halt(target);
2476 }
2477
2478 n = jim_nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode);
2479 command_print(CMD, "cortex_m interrupt mask %s", n->name);
2480
2481 return ERROR_OK;
2482 }
2483
2484 COMMAND_HANDLER(handle_cortex_m_reset_config_command)
2485 {
2486 struct target *target = get_current_target(CMD_CTX);
2487 struct cortex_m_common *cortex_m = target_to_cm(target);
2488 int retval;
2489 char *reset_config;
2490
2491 retval = cortex_m_verify_pointer(CMD, cortex_m);
2492 if (retval != ERROR_OK)
2493 return retval;
2494
2495 if (CMD_ARGC > 0) {
2496 if (strcmp(*CMD_ARGV, "sysresetreq") == 0)
2497 cortex_m->soft_reset_config = CORTEX_M_RESET_SYSRESETREQ;
2498
2499 else if (strcmp(*CMD_ARGV, "vectreset") == 0) {
2500 if (target_was_examined(target)
2501 && !cortex_m->vectreset_supported)
2502 LOG_WARNING("VECTRESET is not supported on your Cortex-M core!");
2503 else
2504 cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;
2505
2506 } else
2507 return ERROR_COMMAND_SYNTAX_ERROR;
2508 }
2509
2510 switch (cortex_m->soft_reset_config) {
2511 case CORTEX_M_RESET_SYSRESETREQ:
2512 reset_config = "sysresetreq";
2513 break;
2514
2515 case CORTEX_M_RESET_VECTRESET:
2516 reset_config = "vectreset";
2517 break;
2518
2519 default:
2520 reset_config = "unknown";
2521 break;
2522 }
2523
2524 command_print(CMD, "cortex_m reset_config %s", reset_config);
2525
2526 return ERROR_OK;
2527 }
2528
2529 static const struct command_registration cortex_m_exec_command_handlers[] = {
2530 {
2531 .name = "maskisr",
2532 .handler = handle_cortex_m_mask_interrupts_command,
2533 .mode = COMMAND_EXEC,
2534 .help = "mask cortex_m interrupts",
2535 .usage = "['auto'|'on'|'off'|'steponly']",
2536 },
2537 {
2538 .name = "vector_catch",
2539 .handler = handle_cortex_m_vector_catch_command,
2540 .mode = COMMAND_EXEC,
2541 .help = "configure hardware vectors to trigger debug entry",
2542 .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2543 },
2544 {
2545 .name = "reset_config",
2546 .handler = handle_cortex_m_reset_config_command,
2547 .mode = COMMAND_ANY,
2548 .help = "configure software reset handling",
2549 .usage = "['sysresetreq'|'vectreset']",
2550 },
2551 COMMAND_REGISTRATION_DONE
2552 };
2553 static const struct command_registration cortex_m_command_handlers[] = {
2554 {
2555 .chain = armv7m_command_handlers,
2556 },
2557 {
2558 .chain = armv7m_trace_command_handlers,
2559 },
2560 /* START_DEPRECATED_TPIU */
2561 {
2562 .chain = arm_tpiu_deprecated_command_handlers,
2563 },
2564 /* END_DEPRECATED_TPIU */
2565 {
2566 .name = "cortex_m",
2567 .mode = COMMAND_EXEC,
2568 .help = "Cortex-M command group",
2569 .usage = "",
2570 .chain = cortex_m_exec_command_handlers,
2571 },
2572 {
2573 .chain = rtt_target_command_handlers,
2574 },
2575 COMMAND_REGISTRATION_DONE
2576 };
2577
2578 struct target_type cortexm_target = {
2579 .name = "cortex_m",
2580
2581 .poll = cortex_m_poll,
2582 .arch_state = armv7m_arch_state,
2583
2584 .target_request_data = cortex_m_target_request_data,
2585
2586 .halt = cortex_m_halt,
2587 .resume = cortex_m_resume,
2588 .step = cortex_m_step,
2589
2590 .assert_reset = cortex_m_assert_reset,
2591 .deassert_reset = cortex_m_deassert_reset,
2592 .soft_reset_halt = cortex_m_soft_reset_halt,
2593
2594 .get_gdb_arch = arm_get_gdb_arch,
2595 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
2596
2597 .read_memory = cortex_m_read_memory,
2598 .write_memory = cortex_m_write_memory,
2599 .checksum_memory = armv7m_checksum_memory,
2600 .blank_check_memory = armv7m_blank_check_memory,
2601
2602 .run_algorithm = armv7m_run_algorithm,
2603 .start_algorithm = armv7m_start_algorithm,
2604 .wait_algorithm = armv7m_wait_algorithm,
2605
2606 .add_breakpoint = cortex_m_add_breakpoint,
2607 .remove_breakpoint = cortex_m_remove_breakpoint,
2608 .add_watchpoint = cortex_m_add_watchpoint,
2609 .remove_watchpoint = cortex_m_remove_watchpoint,
2610 .hit_watchpoint = cortex_m_hit_watchpoint,
2611
2612 .commands = cortex_m_command_handlers,
2613 .target_create = cortex_m_target_create,
2614 .target_jim_configure = adiv5_jim_configure,
2615 .init_target = cortex_m_init_target,
2616 .examine = cortex_m_examine,
2617 .deinit_target = cortex_m_deinit_target,
2618
2619 .profiling = cortex_m_profiling,
2620 };

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)