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

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)