armv7m: replace flag 'stlink' with 'is_hla_target'
[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
981 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
982
983 /* the front-end may request us not to handle breakpoints */
984 if (handle_breakpoints) {
985 breakpoint = breakpoint_find(target, pc_value);
986 if (breakpoint)
987 cortex_m_unset_breakpoint(target, breakpoint);
988 }
989
990 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
991
992 target->debug_reason = DBG_REASON_SINGLESTEP;
993
994 armv7m_restore_context(target);
995
996 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
997
998 /* if no bkpt instruction is found at pc then we can perform
999 * a normal step, otherwise we have to manually step over the bkpt
1000 * instruction - as such simulate a step */
1001 if (bkpt_inst_found == false) {
1002 if (cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO) {
1003 /* Automatic ISR masking mode off: Just step over the next
1004 * instruction, with interrupts on or off as appropriate. */
1005 cortex_m_set_maskints_for_step(target);
1006 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1007 } else {
1008 /* Process interrupts during stepping in a way they don't interfere
1009 * debugging.
1010 *
1011 * Principle:
1012 *
1013 * Set a temporary break point at the current pc and let the core run
1014 * with interrupts enabled. Pending interrupts get served and we run
1015 * into the breakpoint again afterwards. Then we step over the next
1016 * instruction with interrupts disabled.
1017 *
1018 * If the pending interrupts don't complete within time, we leave the
1019 * core running. This may happen if the interrupts trigger faster
1020 * than the core can process them or the handler doesn't return.
1021 *
1022 * If no more breakpoints are available we simply do a step with
1023 * interrupts enabled.
1024 *
1025 */
1026
1027 /* 2012-09-29 ph
1028 *
1029 * If a break point is already set on the lower half word then a break point on
1030 * the upper half word will not break again when the core is restarted. So we
1031 * just step over the instruction with interrupts disabled.
1032 *
1033 * The documentation has no information about this, it was found by observation
1034 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 doesn't seem to
1035 * suffer from this problem.
1036 *
1037 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
1038 * address has it always cleared. The former is done to indicate thumb mode
1039 * to gdb.
1040 *
1041 */
1042 if ((pc_value & 0x02) && breakpoint_find(target, pc_value & ~0x03)) {
1043 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
1044 cortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
1045 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1046 /* Re-enable interrupts if appropriate */
1047 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1048 cortex_m_set_maskints_for_halt(target);
1049 } else {
1050
1051 /* Set a temporary break point */
1052 if (breakpoint) {
1053 retval = cortex_m_set_breakpoint(target, breakpoint);
1054 } else {
1055 enum breakpoint_type type = BKPT_HARD;
1056 if (cortex_m->fp_rev == 0 && pc_value > 0x1FFFFFFF) {
1057 /* FPB rev.1 cannot handle such addr, try BKPT instr */
1058 type = BKPT_SOFT;
1059 }
1060 retval = breakpoint_add(target, pc_value, 2, type);
1061 }
1062
1063 bool tmp_bp_set = (retval == ERROR_OK);
1064
1065 /* No more breakpoints left, just do a step */
1066 if (!tmp_bp_set) {
1067 cortex_m_set_maskints_for_step(target);
1068 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1069 /* Re-enable interrupts if appropriate */
1070 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1071 cortex_m_set_maskints_for_halt(target);
1072 } else {
1073 /* Start the core */
1074 LOG_DEBUG("Starting core to serve pending interrupts");
1075 int64_t t_start = timeval_ms();
1076 cortex_m_set_maskints_for_run(target);
1077 cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP);
1078
1079 /* Wait for pending handlers to complete or timeout */
1080 do {
1081 retval = mem_ap_read_atomic_u32(armv7m->debug_ap,
1082 DCB_DHCSR,
1083 &cortex_m->dcb_dhcsr);
1084 if (retval != ERROR_OK) {
1085 target->state = TARGET_UNKNOWN;
1086 return retval;
1087 }
1088 isr_timed_out = ((timeval_ms() - t_start) > 500);
1089 } while (!((cortex_m->dcb_dhcsr & S_HALT) || isr_timed_out));
1090
1091 /* only remove breakpoint if we created it */
1092 if (breakpoint)
1093 cortex_m_unset_breakpoint(target, breakpoint);
1094 else {
1095 /* Remove the temporary breakpoint */
1096 breakpoint_remove(target, pc_value);
1097 }
1098
1099 if (isr_timed_out) {
1100 LOG_DEBUG("Interrupt handlers didn't complete within time, "
1101 "leaving target running");
1102 } else {
1103 /* Step over next instruction with interrupts disabled */
1104 cortex_m_set_maskints_for_step(target);
1105 cortex_m_write_debug_halt_mask(target,
1106 C_HALT | C_MASKINTS,
1107 0);
1108 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
1109 /* Re-enable interrupts if appropriate */
1110 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1111 cortex_m_set_maskints_for_halt(target);
1112 }
1113 }
1114 }
1115 }
1116 }
1117
1118 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
1119 if (retval != ERROR_OK)
1120 return retval;
1121
1122 /* registers are now invalid */
1123 register_cache_invalidate(armv7m->arm.core_cache);
1124
1125 if (breakpoint)
1126 cortex_m_set_breakpoint(target, breakpoint);
1127
1128 if (isr_timed_out) {
1129 /* Leave the core running. The user has to stop execution manually. */
1130 target->debug_reason = DBG_REASON_NOTHALTED;
1131 target->state = TARGET_RUNNING;
1132 return ERROR_OK;
1133 }
1134
1135 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1136 " nvic_icsr = 0x%" PRIx32,
1137 cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
1138
1139 retval = cortex_m_debug_entry(target);
1140 if (retval != ERROR_OK)
1141 return retval;
1142 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
1143
1144 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
1145 " nvic_icsr = 0x%" PRIx32,
1146 cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
1147
1148 return ERROR_OK;
1149 }
1150
1151 static int cortex_m_assert_reset(struct target *target)
1152 {
1153 struct cortex_m_common *cortex_m = target_to_cm(target);
1154 struct armv7m_common *armv7m = &cortex_m->armv7m;
1155 enum cortex_m_soft_reset_config reset_config = cortex_m->soft_reset_config;
1156
1157 LOG_DEBUG("target->state: %s",
1158 target_state_name(target));
1159
1160 enum reset_types jtag_reset_config = jtag_get_reset_config();
1161
1162 if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {
1163 /* allow scripts to override the reset event */
1164
1165 target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
1166 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
1167 target->state = TARGET_RESET;
1168
1169 return ERROR_OK;
1170 }
1171
1172 /* some cores support connecting while srst is asserted
1173 * use that mode is it has been configured */
1174
1175 bool srst_asserted = false;
1176
1177 if (!target_was_examined(target)) {
1178 if (jtag_reset_config & RESET_HAS_SRST) {
1179 adapter_assert_reset();
1180 if (target->reset_halt)
1181 LOG_ERROR("Target not examined, will not halt after reset!");
1182 return ERROR_OK;
1183 } else {
1184 LOG_ERROR("Target not examined, reset NOT asserted!");
1185 return ERROR_FAIL;
1186 }
1187 }
1188
1189 if ((jtag_reset_config & RESET_HAS_SRST) &&
1190 (jtag_reset_config & RESET_SRST_NO_GATING)) {
1191 adapter_assert_reset();
1192 srst_asserted = true;
1193 }
1194
1195 /* Enable debug requests */
1196 int retval;
1197 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
1198 /* Store important errors instead of failing and proceed to reset assert */
1199
1200 if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN))
1201 retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);
1202
1203 /* If the processor is sleeping in a WFI or WFE instruction, the
1204 * C_HALT bit must be asserted to regain control */
1205 if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP))
1206 retval = cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1207
1208 mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
1209 /* Ignore less important errors */
1210
1211 if (!target->reset_halt) {
1212 /* Set/Clear C_MASKINTS in a separate operation */
1213 cortex_m_set_maskints_for_run(target);
1214
1215 /* clear any debug flags before resuming */
1216 cortex_m_clear_halt(target);
1217
1218 /* clear C_HALT in dhcsr reg */
1219 cortex_m_write_debug_halt_mask(target, 0, C_HALT);
1220 } else {
1221 /* Halt in debug on reset; endreset_event() restores DEMCR.
1222 *
1223 * REVISIT catching BUSERR presumably helps to defend against
1224 * bad vector table entries. Should this include MMERR or
1225 * other flags too?
1226 */
1227 int retval2;
1228 retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
1229 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
1230 if (retval != ERROR_OK || retval2 != ERROR_OK)
1231 LOG_INFO("AP write error, reset will not halt");
1232 }
1233
1234 if (jtag_reset_config & RESET_HAS_SRST) {
1235 /* default to asserting srst */
1236 if (!srst_asserted)
1237 adapter_assert_reset();
1238
1239 /* srst is asserted, ignore AP access errors */
1240 retval = ERROR_OK;
1241 } else {
1242 /* Use a standard Cortex-M3 software reset mechanism.
1243 * We default to using VECRESET as it is supported on all current cores
1244 * (except Cortex-M0, M0+ and M1 which support SYSRESETREQ only!)
1245 * This has the disadvantage of not resetting the peripherals, so a
1246 * reset-init event handler is needed to perform any peripheral resets.
1247 */
1248 if (!cortex_m->vectreset_supported
1249 && reset_config == CORTEX_M_RESET_VECTRESET) {
1250 reset_config = CORTEX_M_RESET_SYSRESETREQ;
1251 LOG_WARNING("VECTRESET is not supported on this Cortex-M core, using SYSRESETREQ instead.");
1252 LOG_WARNING("Set 'cortex_m reset_config sysresetreq'.");
1253 }
1254
1255 LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ)
1256 ? "SYSRESETREQ" : "VECTRESET");
1257
1258 if (reset_config == CORTEX_M_RESET_VECTRESET) {
1259 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1260 "handler to reset any peripherals or configure hardware srst support.");
1261 }
1262
1263 int retval3;
1264 retval3 = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
1265 AIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ)
1266 ? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
1267 if (retval3 != ERROR_OK)
1268 LOG_DEBUG("Ignoring AP write error right after reset");
1269
1270 retval3 = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
1271 if (retval3 != ERROR_OK) {
1272 LOG_ERROR("DP initialisation failed");
1273 /* The error return value must not be propagated in this case.
1274 * SYSRESETREQ or VECTRESET have been possibly triggered
1275 * so reset processing should continue */
1276 } else {
1277 /* I do not know why this is necessary, but it
1278 * fixes strange effects (step/resume cause NMI
1279 * after reset) on LM3S6918 -- Michael Schwingen
1280 */
1281 uint32_t tmp;
1282 mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);
1283 }
1284 }
1285
1286 target->state = TARGET_RESET;
1287 jtag_sleep(50000);
1288
1289 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
1290
1291 /* now return stored error code if any */
1292 if (retval != ERROR_OK)
1293 return retval;
1294
1295 if (target->reset_halt) {
1296 retval = target_halt(target);
1297 if (retval != ERROR_OK)
1298 return retval;
1299 }
1300
1301 return ERROR_OK;
1302 }
1303
1304 static int cortex_m_deassert_reset(struct target *target)
1305 {
1306 struct armv7m_common *armv7m = &target_to_cm(target)->armv7m;
1307
1308 LOG_DEBUG("target->state: %s",
1309 target_state_name(target));
1310
1311 /* deassert reset lines */
1312 adapter_deassert_reset();
1313
1314 enum reset_types jtag_reset_config = jtag_get_reset_config();
1315
1316 if ((jtag_reset_config & RESET_HAS_SRST) &&
1317 !(jtag_reset_config & RESET_SRST_NO_GATING) &&
1318 target_was_examined(target)) {
1319
1320 int retval = dap_dp_init_or_reconnect(armv7m->debug_ap->dap);
1321 if (retval != ERROR_OK) {
1322 LOG_ERROR("DP initialisation failed");
1323 return retval;
1324 }
1325 }
1326
1327 return ERROR_OK;
1328 }
1329
1330 int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
1331 {
1332 int retval;
1333 unsigned int fp_num = 0;
1334 struct cortex_m_common *cortex_m = target_to_cm(target);
1335 struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
1336
1337 if (breakpoint->set) {
1338 LOG_WARNING("breakpoint (BPID: %" PRIu32 ") already set", breakpoint->unique_id);
1339 return ERROR_OK;
1340 }
1341
1342 if (breakpoint->type == BKPT_HARD) {
1343 uint32_t fpcr_value;
1344 while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code))
1345 fp_num++;
1346 if (fp_num >= cortex_m->fp_num_code) {
1347 LOG_ERROR("Can not find free FPB Comparator!");
1348 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1349 }
1350 breakpoint->set = fp_num + 1;
1351 fpcr_value = breakpoint->address | 1;
1352 if (cortex_m->fp_rev == 0) {
1353 if (breakpoint->address > 0x1FFFFFFF) {
1354 LOG_ERROR("Cortex-M Flash Patch Breakpoint rev.1 cannot handle HW breakpoint above address 0x1FFFFFFE");
1355 return ERROR_FAIL;
1356 }
1357 uint32_t hilo;
1358 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
1359 fpcr_value = (fpcr_value & 0x1FFFFFFC) | hilo | 1;
1360 } else if (cortex_m->fp_rev > 1) {
1361 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1362 return ERROR_FAIL;
1363 }
1364 comparator_list[fp_num].used = true;
1365 comparator_list[fp_num].fpcr_value = fpcr_value;
1366 target_write_u32(target, comparator_list[fp_num].fpcr_address,
1367 comparator_list[fp_num].fpcr_value);
1368 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "",
1369 fp_num,
1370 comparator_list[fp_num].fpcr_value);
1371 if (!cortex_m->fpb_enabled) {
1372 LOG_DEBUG("FPB wasn't enabled, do it now");
1373 retval = cortex_m_enable_fpb(target);
1374 if (retval != ERROR_OK) {
1375 LOG_ERROR("Failed to enable the FPB");
1376 return retval;
1377 }
1378
1379 cortex_m->fpb_enabled = true;
1380 }
1381 } else if (breakpoint->type == BKPT_SOFT) {
1382 uint8_t code[4];
1383
1384 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1385 * semihosting; don't use that. Otherwise the BKPT
1386 * parameter is arbitrary.
1387 */
1388 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1389 retval = target_read_memory(target,
1390 breakpoint->address & 0xFFFFFFFE,
1391 breakpoint->length, 1,
1392 breakpoint->orig_instr);
1393 if (retval != ERROR_OK)
1394 return retval;
1395 retval = target_write_memory(target,
1396 breakpoint->address & 0xFFFFFFFE,
1397 breakpoint->length, 1,
1398 code);
1399 if (retval != ERROR_OK)
1400 return retval;
1401 breakpoint->set = true;
1402 }
1403
1404 LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
1405 breakpoint->unique_id,
1406 (int)(breakpoint->type),
1407 breakpoint->address,
1408 breakpoint->length,
1409 breakpoint->set);
1410
1411 return ERROR_OK;
1412 }
1413
1414 int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1415 {
1416 int retval;
1417 struct cortex_m_common *cortex_m = target_to_cm(target);
1418 struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
1419
1420 if (breakpoint->set <= 0) {
1421 LOG_WARNING("breakpoint not set");
1422 return ERROR_OK;
1423 }
1424
1425 LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
1426 breakpoint->unique_id,
1427 (int)(breakpoint->type),
1428 breakpoint->address,
1429 breakpoint->length,
1430 breakpoint->set);
1431
1432 if (breakpoint->type == BKPT_HARD) {
1433 unsigned int fp_num = breakpoint->set - 1;
1434 if (fp_num >= cortex_m->fp_num_code) {
1435 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1436 return ERROR_OK;
1437 }
1438 comparator_list[fp_num].used = false;
1439 comparator_list[fp_num].fpcr_value = 0;
1440 target_write_u32(target, comparator_list[fp_num].fpcr_address,
1441 comparator_list[fp_num].fpcr_value);
1442 } else {
1443 /* restore original instruction (kept in target endianness) */
1444 retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE,
1445 breakpoint->length, 1,
1446 breakpoint->orig_instr);
1447 if (retval != ERROR_OK)
1448 return retval;
1449 }
1450 breakpoint->set = false;
1451
1452 return ERROR_OK;
1453 }
1454
1455 int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
1456 {
1457 if (breakpoint->length == 3) {
1458 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1459 breakpoint->length = 2;
1460 }
1461
1462 if ((breakpoint->length != 2)) {
1463 LOG_INFO("only breakpoints of two bytes length supported");
1464 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1465 }
1466
1467 return cortex_m_set_breakpoint(target, breakpoint);
1468 }
1469
1470 int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1471 {
1472 if (!breakpoint->set)
1473 return ERROR_OK;
1474
1475 return cortex_m_unset_breakpoint(target, breakpoint);
1476 }
1477
1478 static int cortex_m_set_watchpoint(struct target *target, struct watchpoint *watchpoint)
1479 {
1480 unsigned int dwt_num = 0;
1481 struct cortex_m_common *cortex_m = target_to_cm(target);
1482
1483 /* REVISIT Don't fully trust these "not used" records ... users
1484 * may set up breakpoints by hand, e.g. dual-address data value
1485 * watchpoint using comparator #1; comparator #0 matching cycle
1486 * count; send data trace info through ITM and TPIU; etc
1487 */
1488 struct cortex_m_dwt_comparator *comparator;
1489
1490 for (comparator = cortex_m->dwt_comparator_list;
1491 comparator->used && dwt_num < cortex_m->dwt_num_comp;
1492 comparator++, dwt_num++)
1493 continue;
1494 if (dwt_num >= cortex_m->dwt_num_comp) {
1495 LOG_ERROR("Can not find free DWT Comparator");
1496 return ERROR_FAIL;
1497 }
1498 comparator->used = true;
1499 watchpoint->set = dwt_num + 1;
1500
1501 comparator->comp = watchpoint->address;
1502 target_write_u32(target, comparator->dwt_comparator_address + 0,
1503 comparator->comp);
1504
1505 if ((cortex_m->dwt_devarch & 0x1FFFFF) != DWT_DEVARCH_ARMV8M) {
1506 uint32_t mask = 0, temp;
1507
1508 /* watchpoint params were validated earlier */
1509 temp = watchpoint->length;
1510 while (temp) {
1511 temp >>= 1;
1512 mask++;
1513 }
1514 mask--;
1515
1516 comparator->mask = mask;
1517 target_write_u32(target, comparator->dwt_comparator_address + 4,
1518 comparator->mask);
1519
1520 switch (watchpoint->rw) {
1521 case WPT_READ:
1522 comparator->function = 5;
1523 break;
1524 case WPT_WRITE:
1525 comparator->function = 6;
1526 break;
1527 case WPT_ACCESS:
1528 comparator->function = 7;
1529 break;
1530 }
1531 } else {
1532 uint32_t data_size = watchpoint->length >> 1;
1533 comparator->mask = (watchpoint->length >> 1) | 1;
1534
1535 switch (watchpoint->rw) {
1536 case WPT_ACCESS:
1537 comparator->function = 4;
1538 break;
1539 case WPT_WRITE:
1540 comparator->function = 5;
1541 break;
1542 case WPT_READ:
1543 comparator->function = 6;
1544 break;
1545 }
1546 comparator->function = comparator->function | (1 << 4) |
1547 (data_size << 10);
1548 }
1549
1550 target_write_u32(target, comparator->dwt_comparator_address + 8,
1551 comparator->function);
1552
1553 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1554 watchpoint->unique_id, dwt_num,
1555 (unsigned) comparator->comp,
1556 (unsigned) comparator->mask,
1557 (unsigned) comparator->function);
1558 return ERROR_OK;
1559 }
1560
1561 static int cortex_m_unset_watchpoint(struct target *target, struct watchpoint *watchpoint)
1562 {
1563 struct cortex_m_common *cortex_m = target_to_cm(target);
1564 struct cortex_m_dwt_comparator *comparator;
1565
1566 if (watchpoint->set <= 0) {
1567 LOG_WARNING("watchpoint (wpid: %d) not set",
1568 watchpoint->unique_id);
1569 return ERROR_OK;
1570 }
1571
1572 unsigned int dwt_num = watchpoint->set - 1;
1573
1574 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1575 watchpoint->unique_id, dwt_num,
1576 (unsigned) watchpoint->address);
1577
1578 if (dwt_num >= cortex_m->dwt_num_comp) {
1579 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1580 return ERROR_OK;
1581 }
1582
1583 comparator = cortex_m->dwt_comparator_list + dwt_num;
1584 comparator->used = false;
1585 comparator->function = 0;
1586 target_write_u32(target, comparator->dwt_comparator_address + 8,
1587 comparator->function);
1588
1589 watchpoint->set = false;
1590
1591 return ERROR_OK;
1592 }
1593
1594 int cortex_m_add_watchpoint(struct target *target, struct watchpoint *watchpoint)
1595 {
1596 struct cortex_m_common *cortex_m = target_to_cm(target);
1597
1598 if (cortex_m->dwt_comp_available < 1) {
1599 LOG_DEBUG("no comparators?");
1600 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1601 }
1602
1603 /* hardware doesn't support data value masking */
1604 if (watchpoint->mask != ~(uint32_t)0) {
1605 LOG_DEBUG("watchpoint value masks not supported");
1606 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1607 }
1608
1609 /* hardware allows address masks of up to 32K */
1610 unsigned mask;
1611
1612 for (mask = 0; mask < 16; mask++) {
1613 if ((1u << mask) == watchpoint->length)
1614 break;
1615 }
1616 if (mask == 16) {
1617 LOG_DEBUG("unsupported watchpoint length");
1618 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1619 }
1620 if (watchpoint->address & ((1 << mask) - 1)) {
1621 LOG_DEBUG("watchpoint address is unaligned");
1622 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1623 }
1624
1625 /* Caller doesn't seem to be able to describe watching for data
1626 * values of zero; that flags "no value".
1627 *
1628 * REVISIT This DWT may well be able to watch for specific data
1629 * values. Requires comparator #1 to set DATAVMATCH and match
1630 * the data, and another comparator (DATAVADDR0) matching addr.
1631 */
1632 if (watchpoint->value) {
1633 LOG_DEBUG("data value watchpoint not YET supported");
1634 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1635 }
1636
1637 cortex_m->dwt_comp_available--;
1638 LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available);
1639
1640 return ERROR_OK;
1641 }
1642
1643 int cortex_m_remove_watchpoint(struct target *target, struct watchpoint *watchpoint)
1644 {
1645 struct cortex_m_common *cortex_m = target_to_cm(target);
1646
1647 /* REVISIT why check? DWT can be updated with core running ... */
1648 if (target->state != TARGET_HALTED) {
1649 LOG_WARNING("target not halted");
1650 return ERROR_TARGET_NOT_HALTED;
1651 }
1652
1653 if (watchpoint->set)
1654 cortex_m_unset_watchpoint(target, watchpoint);
1655
1656 cortex_m->dwt_comp_available++;
1657 LOG_DEBUG("dwt_comp_available: %d", cortex_m->dwt_comp_available);
1658
1659 return ERROR_OK;
1660 }
1661
1662 int cortex_m_hit_watchpoint(struct target *target, struct watchpoint **hit_watchpoint)
1663 {
1664 if (target->debug_reason != DBG_REASON_WATCHPOINT)
1665 return ERROR_FAIL;
1666
1667 struct cortex_m_common *cortex_m = target_to_cm(target);
1668
1669 for (struct watchpoint *wp = target->watchpoints; wp; wp = wp->next) {
1670 if (!wp->set)
1671 continue;
1672
1673 unsigned int dwt_num = wp->set - 1;
1674 struct cortex_m_dwt_comparator *comparator = cortex_m->dwt_comparator_list + dwt_num;
1675
1676 uint32_t dwt_function;
1677 int retval = target_read_u32(target, comparator->dwt_comparator_address + 8, &dwt_function);
1678 if (retval != ERROR_OK)
1679 return ERROR_FAIL;
1680
1681 /* check the MATCHED bit */
1682 if (dwt_function & BIT(24)) {
1683 *hit_watchpoint = wp;
1684 return ERROR_OK;
1685 }
1686 }
1687
1688 return ERROR_FAIL;
1689 }
1690
1691 void cortex_m_enable_watchpoints(struct target *target)
1692 {
1693 struct watchpoint *watchpoint = target->watchpoints;
1694
1695 /* set any pending watchpoints */
1696 while (watchpoint) {
1697 if (!watchpoint->set)
1698 cortex_m_set_watchpoint(target, watchpoint);
1699 watchpoint = watchpoint->next;
1700 }
1701 }
1702
1703 static int cortex_m_read_memory(struct target *target, target_addr_t address,
1704 uint32_t size, uint32_t count, uint8_t *buffer)
1705 {
1706 struct armv7m_common *armv7m = target_to_armv7m(target);
1707
1708 if (armv7m->arm.arch == ARM_ARCH_V6M) {
1709 /* armv6m does not handle unaligned memory access */
1710 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1711 return ERROR_TARGET_UNALIGNED_ACCESS;
1712 }
1713
1714 return mem_ap_read_buf(armv7m->debug_ap, buffer, size, count, address);
1715 }
1716
1717 static int cortex_m_write_memory(struct target *target, target_addr_t address,
1718 uint32_t size, uint32_t count, const uint8_t *buffer)
1719 {
1720 struct armv7m_common *armv7m = target_to_armv7m(target);
1721
1722 if (armv7m->arm.arch == ARM_ARCH_V6M) {
1723 /* armv6m does not handle unaligned memory access */
1724 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1725 return ERROR_TARGET_UNALIGNED_ACCESS;
1726 }
1727
1728 return mem_ap_write_buf(armv7m->debug_ap, buffer, size, count, address);
1729 }
1730
1731 static int cortex_m_init_target(struct command_context *cmd_ctx,
1732 struct target *target)
1733 {
1734 armv7m_build_reg_cache(target);
1735 arm_semihosting_init(target);
1736 return ERROR_OK;
1737 }
1738
1739 void cortex_m_deinit_target(struct target *target)
1740 {
1741 struct cortex_m_common *cortex_m = target_to_cm(target);
1742
1743 free(cortex_m->fp_comparator_list);
1744
1745 cortex_m_dwt_free(target);
1746 armv7m_free_reg_cache(target);
1747
1748 free(target->private_config);
1749 free(cortex_m);
1750 }
1751
1752 int cortex_m_profiling(struct target *target, uint32_t *samples,
1753 uint32_t max_num_samples, uint32_t *num_samples, uint32_t seconds)
1754 {
1755 struct timeval timeout, now;
1756 struct armv7m_common *armv7m = target_to_armv7m(target);
1757 uint32_t reg_value;
1758 int retval;
1759
1760 retval = target_read_u32(target, DWT_PCSR, &reg_value);
1761 if (retval != ERROR_OK) {
1762 LOG_ERROR("Error while reading PCSR");
1763 return retval;
1764 }
1765 if (reg_value == 0) {
1766 LOG_INFO("PCSR sampling not supported on this processor.");
1767 return target_profiling_default(target, samples, max_num_samples, num_samples, seconds);
1768 }
1769
1770 gettimeofday(&timeout, NULL);
1771 timeval_add_time(&timeout, seconds, 0);
1772
1773 LOG_INFO("Starting Cortex-M profiling. Sampling DWT_PCSR as fast as we can...");
1774
1775 /* Make sure the target is running */
1776 target_poll(target);
1777 if (target->state == TARGET_HALTED)
1778 retval = target_resume(target, 1, 0, 0, 0);
1779
1780 if (retval != ERROR_OK) {
1781 LOG_ERROR("Error while resuming target");
1782 return retval;
1783 }
1784
1785 uint32_t sample_count = 0;
1786
1787 for (;;) {
1788 if (armv7m && armv7m->debug_ap) {
1789 uint32_t read_count = max_num_samples - sample_count;
1790 if (read_count > 1024)
1791 read_count = 1024;
1792
1793 retval = mem_ap_read_buf_noincr(armv7m->debug_ap,
1794 (void *)&samples[sample_count],
1795 4, read_count, DWT_PCSR);
1796 sample_count += read_count;
1797 } else {
1798 target_read_u32(target, DWT_PCSR, &samples[sample_count++]);
1799 }
1800
1801 if (retval != ERROR_OK) {
1802 LOG_ERROR("Error while reading PCSR");
1803 return retval;
1804 }
1805
1806
1807 gettimeofday(&now, NULL);
1808 if (sample_count >= max_num_samples || timeval_compare(&now, &timeout) > 0) {
1809 LOG_INFO("Profiling completed. %" PRIu32 " samples.", sample_count);
1810 break;
1811 }
1812 }
1813
1814 *num_samples = sample_count;
1815 return retval;
1816 }
1817
1818
1819 /* REVISIT cache valid/dirty bits are unmaintained. We could set "valid"
1820 * on r/w if the core is not running, and clear on resume or reset ... or
1821 * at least, in a post_restore_context() method.
1822 */
1823
1824 struct dwt_reg_state {
1825 struct target *target;
1826 uint32_t addr;
1827 uint8_t value[4]; /* scratch/cache */
1828 };
1829
1830 static int cortex_m_dwt_get_reg(struct reg *reg)
1831 {
1832 struct dwt_reg_state *state = reg->arch_info;
1833
1834 uint32_t tmp;
1835 int retval = target_read_u32(state->target, state->addr, &tmp);
1836 if (retval != ERROR_OK)
1837 return retval;
1838
1839 buf_set_u32(state->value, 0, 32, tmp);
1840 return ERROR_OK;
1841 }
1842
1843 static int cortex_m_dwt_set_reg(struct reg *reg, uint8_t *buf)
1844 {
1845 struct dwt_reg_state *state = reg->arch_info;
1846
1847 return target_write_u32(state->target, state->addr,
1848 buf_get_u32(buf, 0, reg->size));
1849 }
1850
1851 struct dwt_reg {
1852 uint32_t addr;
1853 const char *name;
1854 unsigned size;
1855 };
1856
1857 static const struct dwt_reg dwt_base_regs[] = {
1858 { DWT_CTRL, "dwt_ctrl", 32, },
1859 /* NOTE that Erratum 532314 (fixed r2p0) affects CYCCNT: it wrongly
1860 * increments while the core is asleep.
1861 */
1862 { DWT_CYCCNT, "dwt_cyccnt", 32, },
1863 /* plus some 8 bit counters, useful for profiling with TPIU */
1864 };
1865
1866 static const struct dwt_reg dwt_comp[] = {
1867 #define DWT_COMPARATOR(i) \
1868 { DWT_COMP0 + 0x10 * (i), "dwt_" #i "_comp", 32, }, \
1869 { DWT_MASK0 + 0x10 * (i), "dwt_" #i "_mask", 4, }, \
1870 { DWT_FUNCTION0 + 0x10 * (i), "dwt_" #i "_function", 32, }
1871 DWT_COMPARATOR(0),
1872 DWT_COMPARATOR(1),
1873 DWT_COMPARATOR(2),
1874 DWT_COMPARATOR(3),
1875 DWT_COMPARATOR(4),
1876 DWT_COMPARATOR(5),
1877 DWT_COMPARATOR(6),
1878 DWT_COMPARATOR(7),
1879 DWT_COMPARATOR(8),
1880 DWT_COMPARATOR(9),
1881 DWT_COMPARATOR(10),
1882 DWT_COMPARATOR(11),
1883 DWT_COMPARATOR(12),
1884 DWT_COMPARATOR(13),
1885 DWT_COMPARATOR(14),
1886 DWT_COMPARATOR(15),
1887 #undef DWT_COMPARATOR
1888 };
1889
1890 static const struct reg_arch_type dwt_reg_type = {
1891 .get = cortex_m_dwt_get_reg,
1892 .set = cortex_m_dwt_set_reg,
1893 };
1894
1895 static void cortex_m_dwt_addreg(struct target *t, struct reg *r, const struct dwt_reg *d)
1896 {
1897 struct dwt_reg_state *state;
1898
1899 state = calloc(1, sizeof(*state));
1900 if (!state)
1901 return;
1902 state->addr = d->addr;
1903 state->target = t;
1904
1905 r->name = d->name;
1906 r->size = d->size;
1907 r->value = state->value;
1908 r->arch_info = state;
1909 r->type = &dwt_reg_type;
1910 }
1911
1912 static void cortex_m_dwt_setup(struct cortex_m_common *cm, struct target *target)
1913 {
1914 uint32_t dwtcr;
1915 struct reg_cache *cache;
1916 struct cortex_m_dwt_comparator *comparator;
1917 int reg;
1918
1919 target_read_u32(target, DWT_CTRL, &dwtcr);
1920 LOG_DEBUG("DWT_CTRL: 0x%" PRIx32, dwtcr);
1921 if (!dwtcr) {
1922 LOG_DEBUG("no DWT");
1923 return;
1924 }
1925
1926 target_read_u32(target, DWT_DEVARCH, &cm->dwt_devarch);
1927 LOG_DEBUG("DWT_DEVARCH: 0x%" PRIx32, cm->dwt_devarch);
1928
1929 cm->dwt_num_comp = (dwtcr >> 28) & 0xF;
1930 cm->dwt_comp_available = cm->dwt_num_comp;
1931 cm->dwt_comparator_list = calloc(cm->dwt_num_comp,
1932 sizeof(struct cortex_m_dwt_comparator));
1933 if (!cm->dwt_comparator_list) {
1934 fail0:
1935 cm->dwt_num_comp = 0;
1936 LOG_ERROR("out of mem");
1937 return;
1938 }
1939
1940 cache = calloc(1, sizeof(*cache));
1941 if (!cache) {
1942 fail1:
1943 free(cm->dwt_comparator_list);
1944 goto fail0;
1945 }
1946 cache->name = "Cortex-M DWT registers";
1947 cache->num_regs = 2 + cm->dwt_num_comp * 3;
1948 cache->reg_list = calloc(cache->num_regs, sizeof(*cache->reg_list));
1949 if (!cache->reg_list) {
1950 free(cache);
1951 goto fail1;
1952 }
1953
1954 for (reg = 0; reg < 2; reg++)
1955 cortex_m_dwt_addreg(target, cache->reg_list + reg,
1956 dwt_base_regs + reg);
1957
1958 comparator = cm->dwt_comparator_list;
1959 for (unsigned int i = 0; i < cm->dwt_num_comp; i++, comparator++) {
1960 int j;
1961
1962 comparator->dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1963 for (j = 0; j < 3; j++, reg++)
1964 cortex_m_dwt_addreg(target, cache->reg_list + reg,
1965 dwt_comp + 3 * i + j);
1966
1967 /* make sure we clear any watchpoints enabled on the target */
1968 target_write_u32(target, comparator->dwt_comparator_address + 8, 0);
1969 }
1970
1971 *register_get_last_cache_p(&target->reg_cache) = cache;
1972 cm->dwt_cache = cache;
1973
1974 LOG_DEBUG("DWT dwtcr 0x%" PRIx32 ", comp %d, watch%s",
1975 dwtcr, cm->dwt_num_comp,
1976 (dwtcr & (0xf << 24)) ? " only" : "/trigger");
1977
1978 /* REVISIT: if num_comp > 1, check whether comparator #1 can
1979 * implement single-address data value watchpoints ... so we
1980 * won't need to check it later, when asked to set one up.
1981 */
1982 }
1983
1984 static void cortex_m_dwt_free(struct target *target)
1985 {
1986 struct cortex_m_common *cm = target_to_cm(target);
1987 struct reg_cache *cache = cm->dwt_cache;
1988
1989 free(cm->dwt_comparator_list);
1990 cm->dwt_comparator_list = NULL;
1991 cm->dwt_num_comp = 0;
1992
1993 if (cache) {
1994 register_unlink_cache(&target->reg_cache, cache);
1995
1996 if (cache->reg_list) {
1997 for (size_t i = 0; i < cache->num_regs; i++)
1998 free(cache->reg_list[i].arch_info);
1999 free(cache->reg_list);
2000 }
2001 free(cache);
2002 }
2003 cm->dwt_cache = NULL;
2004 }
2005
2006 #define MVFR0 0xe000ef40
2007 #define MVFR1 0xe000ef44
2008
2009 #define MVFR0_DEFAULT_M4 0x10110021
2010 #define MVFR1_DEFAULT_M4 0x11000011
2011
2012 #define MVFR0_DEFAULT_M7_SP 0x10110021
2013 #define MVFR0_DEFAULT_M7_DP 0x10110221
2014 #define MVFR1_DEFAULT_M7_SP 0x11000011
2015 #define MVFR1_DEFAULT_M7_DP 0x12000011
2016
2017 static int cortex_m_find_mem_ap(struct adiv5_dap *swjdp,
2018 struct adiv5_ap **debug_ap)
2019 {
2020 if (dap_find_ap(swjdp, AP_TYPE_AHB3_AP, debug_ap) == ERROR_OK)
2021 return ERROR_OK;
2022
2023 return dap_find_ap(swjdp, AP_TYPE_AHB5_AP, debug_ap);
2024 }
2025
2026 int cortex_m_examine(struct target *target)
2027 {
2028 int retval;
2029 uint32_t cpuid, fpcr, mvfr0, mvfr1;
2030 struct cortex_m_common *cortex_m = target_to_cm(target);
2031 struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
2032 struct armv7m_common *armv7m = target_to_armv7m(target);
2033
2034 /* hla_target shares the examine handler but does not support
2035 * all its calls */
2036 if (!armv7m->is_hla_target) {
2037 if (cortex_m->apsel == DP_APSEL_INVALID) {
2038 /* Search for the MEM-AP */
2039 retval = cortex_m_find_mem_ap(swjdp, &armv7m->debug_ap);
2040 if (retval != ERROR_OK) {
2041 LOG_ERROR("Could not find MEM-AP to control the core");
2042 return retval;
2043 }
2044 } else {
2045 armv7m->debug_ap = dap_ap(swjdp, cortex_m->apsel);
2046 }
2047
2048 /* Leave (only) generic DAP stuff for debugport_init(); */
2049 armv7m->debug_ap->memaccess_tck = 8;
2050
2051 retval = mem_ap_init(armv7m->debug_ap);
2052 if (retval != ERROR_OK)
2053 return retval;
2054 }
2055
2056 if (!target_was_examined(target)) {
2057 target_set_examined(target);
2058
2059 /* Read from Device Identification Registers */
2060 retval = target_read_u32(target, CPUID, &cpuid);
2061 if (retval != ERROR_OK)
2062 return retval;
2063
2064 /* Get ARCH and CPU types */
2065 const enum cortex_m_partno core_partno = (cpuid & ARM_CPUID_PARTNO_MASK) >> ARM_CPUID_PARTNO_POS;
2066
2067 for (unsigned int n = 0; n < ARRAY_SIZE(cortex_m_parts); n++) {
2068 if (core_partno == cortex_m_parts[n].partno) {
2069 cortex_m->core_info = &cortex_m_parts[n];
2070 break;
2071 }
2072 }
2073
2074 if (!cortex_m->core_info) {
2075 LOG_ERROR("Cortex-M PARTNO 0x%x is unrecognized", core_partno);
2076 return ERROR_FAIL;
2077 }
2078
2079 armv7m->arm.arch = cortex_m->core_info->arch;
2080
2081 LOG_DEBUG("%s r%" PRId8 "p%" PRId8 " processor detected",
2082 cortex_m->core_info->name, (uint8_t)((cpuid >> 20) & 0xf), (uint8_t)((cpuid >> 0) & 0xf));
2083 cortex_m->maskints_erratum = false;
2084 if (core_partno == CORTEX_M7_PARTNO) {
2085 uint8_t rev, patch;
2086 rev = (cpuid >> 20) & 0xf;
2087 patch = (cpuid >> 0) & 0xf;
2088 if ((rev == 0) && (patch < 2)) {
2089 LOG_WARNING("Silicon bug: single stepping may enter pending exception handler!");
2090 cortex_m->maskints_erratum = true;
2091 }
2092 }
2093 LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
2094
2095 if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV4) {
2096 target_read_u32(target, MVFR0, &mvfr0);
2097 target_read_u32(target, MVFR1, &mvfr1);
2098
2099 /* test for floating point feature on Cortex-M4 */
2100 if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
2101 LOG_DEBUG("%s floating point feature FPv4_SP found", cortex_m->core_info->name);
2102 armv7m->fp_feature = FPV4_SP;
2103 }
2104 } else if (cortex_m->core_info->flags & CORTEX_M_F_HAS_FPV5) {
2105 target_read_u32(target, MVFR0, &mvfr0);
2106 target_read_u32(target, MVFR1, &mvfr1);
2107
2108 /* test for floating point features on Cortex-M7 */
2109 if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
2110 LOG_DEBUG("%s floating point feature FPv5_SP found", cortex_m->core_info->name);
2111 armv7m->fp_feature = FPV5_SP;
2112 } else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
2113 LOG_DEBUG("%s floating point feature FPv5_DP found", cortex_m->core_info->name);
2114 armv7m->fp_feature = FPV5_DP;
2115 }
2116 }
2117
2118 /* VECTRESET is supported only on ARMv7-M cores */
2119 cortex_m->vectreset_supported = armv7m->arm.arch == ARM_ARCH_V7M;
2120
2121 /* Check for FPU, otherwise mark FPU register as non-existent */
2122 if (armv7m->fp_feature == FP_NONE)
2123 for (size_t idx = ARMV7M_FPU_FIRST_REG; idx <= ARMV7M_FPU_LAST_REG; idx++)
2124 armv7m->arm.core_cache->reg_list[idx].exist = false;
2125
2126 if (armv7m->arm.arch != ARM_ARCH_V8M)
2127 for (size_t idx = ARMV8M_FIRST_REG; idx <= ARMV8M_LAST_REG; idx++)
2128 armv7m->arm.core_cache->reg_list[idx].exist = false;
2129
2130 if (!armv7m->is_hla_target) {
2131 if (cortex_m->core_info->flags & CORTEX_M_F_TAR_AUTOINCR_BLOCK_4K)
2132 /* Cortex-M3/M4 have 4096 bytes autoincrement range,
2133 * s. ARM IHI 0031C: MEM-AP 7.2.2 */
2134 armv7m->debug_ap->tar_autoincr_block = (1 << 12);
2135 }
2136
2137 /* Enable debug requests */
2138 retval = target_read_u32(target, DCB_DHCSR, &cortex_m->dcb_dhcsr);
2139 if (retval != ERROR_OK)
2140 return retval;
2141 if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
2142 uint32_t dhcsr = (cortex_m->dcb_dhcsr | C_DEBUGEN) & ~(C_HALT | C_STEP | C_MASKINTS);
2143
2144 retval = target_write_u32(target, DCB_DHCSR, DBGKEY | (dhcsr & 0x0000FFFFUL));
2145 if (retval != ERROR_OK)
2146 return retval;
2147 cortex_m->dcb_dhcsr = dhcsr;
2148 }
2149
2150 /* Configure trace modules */
2151 retval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
2152 if (retval != ERROR_OK)
2153 return retval;
2154
2155 if (armv7m->trace_config.itm_deferred_config)
2156 armv7m_trace_itm_config(target);
2157
2158 /* NOTE: FPB and DWT are both optional. */
2159
2160 /* Setup FPB */
2161 target_read_u32(target, FP_CTRL, &fpcr);
2162 /* bits [14:12] and [7:4] */
2163 cortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF);
2164 cortex_m->fp_num_lit = (fpcr >> 8) & 0xF;
2165 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
2166 Revision is zero base, fp_rev == 1 means Rev.2 ! */
2167 cortex_m->fp_rev = (fpcr >> 28) & 0xf;
2168 free(cortex_m->fp_comparator_list);
2169 cortex_m->fp_comparator_list = calloc(
2170 cortex_m->fp_num_code + cortex_m->fp_num_lit,
2171 sizeof(struct cortex_m_fp_comparator));
2172 cortex_m->fpb_enabled = fpcr & 1;
2173 for (unsigned int i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
2174 cortex_m->fp_comparator_list[i].type =
2175 (i < cortex_m->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
2176 cortex_m->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
2177
2178 /* make sure we clear any breakpoints enabled on the target */
2179 target_write_u32(target, cortex_m->fp_comparator_list[i].fpcr_address, 0);
2180 }
2181 LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i",
2182 fpcr,
2183 cortex_m->fp_num_code,
2184 cortex_m->fp_num_lit);
2185
2186 /* Setup DWT */
2187 cortex_m_dwt_free(target);
2188 cortex_m_dwt_setup(cortex_m, target);
2189
2190 /* These hardware breakpoints only work for code in flash! */
2191 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
2192 target_name(target),
2193 cortex_m->fp_num_code,
2194 cortex_m->dwt_num_comp);
2195 }
2196
2197 return ERROR_OK;
2198 }
2199
2200 static int cortex_m_dcc_read(struct target *target, uint8_t *value, uint8_t *ctrl)
2201 {
2202 struct armv7m_common *armv7m = target_to_armv7m(target);
2203 uint16_t dcrdr;
2204 uint8_t buf[2];
2205 int retval;
2206
2207 retval = mem_ap_read_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);
2208 if (retval != ERROR_OK)
2209 return retval;
2210
2211 dcrdr = target_buffer_get_u16(target, buf);
2212 *ctrl = (uint8_t)dcrdr;
2213 *value = (uint8_t)(dcrdr >> 8);
2214
2215 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
2216
2217 /* write ack back to software dcc register
2218 * signify we have read data */
2219 if (dcrdr & (1 << 0)) {
2220 target_buffer_set_u16(target, buf, 0);
2221 retval = mem_ap_write_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);
2222 if (retval != ERROR_OK)
2223 return retval;
2224 }
2225
2226 return ERROR_OK;
2227 }
2228
2229 static int cortex_m_target_request_data(struct target *target,
2230 uint32_t size, uint8_t *buffer)
2231 {
2232 uint8_t data;
2233 uint8_t ctrl;
2234 uint32_t i;
2235
2236 for (i = 0; i < (size * 4); i++) {
2237 int retval = cortex_m_dcc_read(target, &data, &ctrl);
2238 if (retval != ERROR_OK)
2239 return retval;
2240 buffer[i] = data;
2241 }
2242
2243 return ERROR_OK;
2244 }
2245
2246 static int cortex_m_handle_target_request(void *priv)
2247 {
2248 struct target *target = priv;
2249 if (!target_was_examined(target))
2250 return ERROR_OK;
2251
2252 if (!target->dbg_msg_enabled)
2253 return ERROR_OK;
2254
2255 if (target->state == TARGET_RUNNING) {
2256 uint8_t data;
2257 uint8_t ctrl;
2258 int retval;
2259
2260 retval = cortex_m_dcc_read(target, &data, &ctrl);
2261 if (retval != ERROR_OK)
2262 return retval;
2263
2264 /* check if we have data */
2265 if (ctrl & (1 << 0)) {
2266 uint32_t request;
2267
2268 /* we assume target is quick enough */
2269 request = data;
2270 for (int i = 1; i <= 3; i++) {
2271 retval = cortex_m_dcc_read(target, &data, &ctrl);
2272 if (retval != ERROR_OK)
2273 return retval;
2274 request |= ((uint32_t)data << (i * 8));
2275 }
2276 target_request(target, request);
2277 }
2278 }
2279
2280 return ERROR_OK;
2281 }
2282
2283 static int cortex_m_init_arch_info(struct target *target,
2284 struct cortex_m_common *cortex_m, struct adiv5_dap *dap)
2285 {
2286 struct armv7m_common *armv7m = &cortex_m->armv7m;
2287
2288 armv7m_init_arch_info(target, armv7m);
2289
2290 /* default reset mode is to use srst if fitted
2291 * if not it will use CORTEX_M3_RESET_VECTRESET */
2292 cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;
2293
2294 armv7m->arm.dap = dap;
2295
2296 /* register arch-specific functions */
2297 armv7m->examine_debug_reason = cortex_m_examine_debug_reason;
2298
2299 armv7m->post_debug_entry = NULL;
2300
2301 armv7m->pre_restore_context = NULL;
2302
2303 armv7m->load_core_reg_u32 = cortex_m_load_core_reg_u32;
2304 armv7m->store_core_reg_u32 = cortex_m_store_core_reg_u32;
2305
2306 target_register_timer_callback(cortex_m_handle_target_request, 1,
2307 TARGET_TIMER_TYPE_PERIODIC, target);
2308
2309 return ERROR_OK;
2310 }
2311
2312 static int cortex_m_target_create(struct target *target, Jim_Interp *interp)
2313 {
2314 struct adiv5_private_config *pc;
2315
2316 pc = (struct adiv5_private_config *)target->private_config;
2317 if (adiv5_verify_config(pc) != ERROR_OK)
2318 return ERROR_FAIL;
2319
2320 struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
2321 if (cortex_m == NULL) {
2322 LOG_ERROR("No memory creating target");
2323 return ERROR_FAIL;
2324 }
2325
2326 cortex_m->common_magic = CORTEX_M_COMMON_MAGIC;
2327 cortex_m->apsel = pc->ap_num;
2328
2329 cortex_m_init_arch_info(target, cortex_m, pc->dap);
2330
2331 return ERROR_OK;
2332 }
2333
2334 /*--------------------------------------------------------------------------*/
2335
2336 static int cortex_m_verify_pointer(struct command_invocation *cmd,
2337 struct cortex_m_common *cm)
2338 {
2339 if (cm->common_magic != CORTEX_M_COMMON_MAGIC) {
2340 command_print(cmd, "target is not a Cortex-M");
2341 return ERROR_TARGET_INVALID;
2342 }
2343 return ERROR_OK;
2344 }
2345
2346 /*
2347 * Only stuff below this line should need to verify that its target
2348 * is a Cortex-M3. Everything else should have indirected through the
2349 * cortexm3_target structure, which is only used with CM3 targets.
2350 */
2351
2352 COMMAND_HANDLER(handle_cortex_m_vector_catch_command)
2353 {
2354 struct target *target = get_current_target(CMD_CTX);
2355 struct cortex_m_common *cortex_m = target_to_cm(target);
2356 struct armv7m_common *armv7m = &cortex_m->armv7m;
2357 uint32_t demcr = 0;
2358 int retval;
2359
2360 static const struct {
2361 char name[10];
2362 unsigned mask;
2363 } vec_ids[] = {
2364 { "hard_err", VC_HARDERR, },
2365 { "int_err", VC_INTERR, },
2366 { "bus_err", VC_BUSERR, },
2367 { "state_err", VC_STATERR, },
2368 { "chk_err", VC_CHKERR, },
2369 { "nocp_err", VC_NOCPERR, },
2370 { "mm_err", VC_MMERR, },
2371 { "reset", VC_CORERESET, },
2372 };
2373
2374 retval = cortex_m_verify_pointer(CMD, cortex_m);
2375 if (retval != ERROR_OK)
2376 return retval;
2377
2378 if (!target_was_examined(target)) {
2379 LOG_ERROR("Target not examined yet");
2380 return ERROR_FAIL;
2381 }
2382
2383 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);
2384 if (retval != ERROR_OK)
2385 return retval;
2386
2387 if (CMD_ARGC > 0) {
2388 unsigned catch = 0;
2389
2390 if (CMD_ARGC == 1) {
2391 if (strcmp(CMD_ARGV[0], "all") == 0) {
2392 catch = VC_HARDERR | VC_INTERR | VC_BUSERR
2393 | VC_STATERR | VC_CHKERR | VC_NOCPERR
2394 | VC_MMERR | VC_CORERESET;
2395 goto write;
2396 } else if (strcmp(CMD_ARGV[0], "none") == 0)
2397 goto write;
2398 }
2399 while (CMD_ARGC-- > 0) {
2400 unsigned i;
2401 for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
2402 if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name) != 0)
2403 continue;
2404 catch |= vec_ids[i].mask;
2405 break;
2406 }
2407 if (i == ARRAY_SIZE(vec_ids)) {
2408 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV[CMD_ARGC]);
2409 return ERROR_COMMAND_SYNTAX_ERROR;
2410 }
2411 }
2412 write:
2413 /* For now, armv7m->demcr only stores vector catch flags. */
2414 armv7m->demcr = catch;
2415
2416 demcr &= ~0xffff;
2417 demcr |= catch;
2418
2419 /* write, but don't assume it stuck (why not??) */
2420 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, demcr);
2421 if (retval != ERROR_OK)
2422 return retval;
2423 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);
2424 if (retval != ERROR_OK)
2425 return retval;
2426
2427 /* FIXME be sure to clear DEMCR on clean server shutdown.
2428 * Otherwise the vector catch hardware could fire when there's
2429 * no debugger hooked up, causing much confusion...
2430 */
2431 }
2432
2433 for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) {
2434 command_print(CMD, "%9s: %s", vec_ids[i].name,
2435 (demcr & vec_ids[i].mask) ? "catch" : "ignore");
2436 }
2437
2438 return ERROR_OK;
2439 }
2440
2441 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command)
2442 {
2443 struct target *target = get_current_target(CMD_CTX);
2444 struct cortex_m_common *cortex_m = target_to_cm(target);
2445 int retval;
2446
2447 static const struct jim_nvp nvp_maskisr_modes[] = {
2448 { .name = "auto", .value = CORTEX_M_ISRMASK_AUTO },
2449 { .name = "off", .value = CORTEX_M_ISRMASK_OFF },
2450 { .name = "on", .value = CORTEX_M_ISRMASK_ON },
2451 { .name = "steponly", .value = CORTEX_M_ISRMASK_STEPONLY },
2452 { .name = NULL, .value = -1 },
2453 };
2454 const struct jim_nvp *n;
2455
2456
2457 retval = cortex_m_verify_pointer(CMD, cortex_m);
2458 if (retval != ERROR_OK)
2459 return retval;
2460
2461 if (target->state != TARGET_HALTED) {
2462 command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
2463 return ERROR_OK;
2464 }
2465
2466 if (CMD_ARGC > 0) {
2467 n = jim_nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
2468 if (n->name == NULL)
2469 return ERROR_COMMAND_SYNTAX_ERROR;
2470 cortex_m->isrmasking_mode = n->value;
2471 cortex_m_set_maskints_for_halt(target);
2472 }
2473
2474 n = jim_nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode);
2475 command_print(CMD, "cortex_m interrupt mask %s", n->name);
2476
2477 return ERROR_OK;
2478 }
2479
2480 COMMAND_HANDLER(handle_cortex_m_reset_config_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 char *reset_config;
2486
2487 retval = cortex_m_verify_pointer(CMD, cortex_m);
2488 if (retval != ERROR_OK)
2489 return retval;
2490
2491 if (CMD_ARGC > 0) {
2492 if (strcmp(*CMD_ARGV, "sysresetreq") == 0)
2493 cortex_m->soft_reset_config = CORTEX_M_RESET_SYSRESETREQ;
2494
2495 else if (strcmp(*CMD_ARGV, "vectreset") == 0) {
2496 if (target_was_examined(target)
2497 && !cortex_m->vectreset_supported)
2498 LOG_WARNING("VECTRESET is not supported on your Cortex-M core!");
2499 else
2500 cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;
2501
2502 } else
2503 return ERROR_COMMAND_SYNTAX_ERROR;
2504 }
2505
2506 switch (cortex_m->soft_reset_config) {
2507 case CORTEX_M_RESET_SYSRESETREQ:
2508 reset_config = "sysresetreq";
2509 break;
2510
2511 case CORTEX_M_RESET_VECTRESET:
2512 reset_config = "vectreset";
2513 break;
2514
2515 default:
2516 reset_config = "unknown";
2517 break;
2518 }
2519
2520 command_print(CMD, "cortex_m reset_config %s", reset_config);
2521
2522 return ERROR_OK;
2523 }
2524
2525 static const struct command_registration cortex_m_exec_command_handlers[] = {
2526 {
2527 .name = "maskisr",
2528 .handler = handle_cortex_m_mask_interrupts_command,
2529 .mode = COMMAND_EXEC,
2530 .help = "mask cortex_m interrupts",
2531 .usage = "['auto'|'on'|'off'|'steponly']",
2532 },
2533 {
2534 .name = "vector_catch",
2535 .handler = handle_cortex_m_vector_catch_command,
2536 .mode = COMMAND_EXEC,
2537 .help = "configure hardware vectors to trigger debug entry",
2538 .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2539 },
2540 {
2541 .name = "reset_config",
2542 .handler = handle_cortex_m_reset_config_command,
2543 .mode = COMMAND_ANY,
2544 .help = "configure software reset handling",
2545 .usage = "['sysresetreq'|'vectreset']",
2546 },
2547 COMMAND_REGISTRATION_DONE
2548 };
2549 static const struct command_registration cortex_m_command_handlers[] = {
2550 {
2551 .chain = armv7m_command_handlers,
2552 },
2553 {
2554 .chain = armv7m_trace_command_handlers,
2555 },
2556 /* START_DEPRECATED_TPIU */
2557 {
2558 .chain = arm_tpiu_deprecated_command_handlers,
2559 },
2560 /* END_DEPRECATED_TPIU */
2561 {
2562 .name = "cortex_m",
2563 .mode = COMMAND_EXEC,
2564 .help = "Cortex-M command group",
2565 .usage = "",
2566 .chain = cortex_m_exec_command_handlers,
2567 },
2568 {
2569 .chain = rtt_target_command_handlers,
2570 },
2571 COMMAND_REGISTRATION_DONE
2572 };
2573
2574 struct target_type cortexm_target = {
2575 .name = "cortex_m",
2576
2577 .poll = cortex_m_poll,
2578 .arch_state = armv7m_arch_state,
2579
2580 .target_request_data = cortex_m_target_request_data,
2581
2582 .halt = cortex_m_halt,
2583 .resume = cortex_m_resume,
2584 .step = cortex_m_step,
2585
2586 .assert_reset = cortex_m_assert_reset,
2587 .deassert_reset = cortex_m_deassert_reset,
2588 .soft_reset_halt = cortex_m_soft_reset_halt,
2589
2590 .get_gdb_arch = arm_get_gdb_arch,
2591 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
2592
2593 .read_memory = cortex_m_read_memory,
2594 .write_memory = cortex_m_write_memory,
2595 .checksum_memory = armv7m_checksum_memory,
2596 .blank_check_memory = armv7m_blank_check_memory,
2597
2598 .run_algorithm = armv7m_run_algorithm,
2599 .start_algorithm = armv7m_start_algorithm,
2600 .wait_algorithm = armv7m_wait_algorithm,
2601
2602 .add_breakpoint = cortex_m_add_breakpoint,
2603 .remove_breakpoint = cortex_m_remove_breakpoint,
2604 .add_watchpoint = cortex_m_add_watchpoint,
2605 .remove_watchpoint = cortex_m_remove_watchpoint,
2606 .hit_watchpoint = cortex_m_hit_watchpoint,
2607
2608 .commands = cortex_m_command_handlers,
2609 .target_create = cortex_m_target_create,
2610 .target_jim_configure = adiv5_jim_configure,
2611 .init_target = cortex_m_init_target,
2612 .examine = cortex_m_examine,
2613 .deinit_target = cortex_m_deinit_target,
2614
2615 .profiling = cortex_m_profiling,
2616 };

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)