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

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)