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

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)