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

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)