target/cortex_m: avoid dwt comparator overflow
[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 FBP 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 /**
55 * Returns the type of a break point required by address location
56 */
57 #define BKPT_TYPE_BY_ADDR(addr) ((addr) < 0x20000000 ? BKPT_HARD : BKPT_SOFT)
58
59 /* forward declarations */
60 static int cortex_m_store_core_reg_u32(struct target *target,
61 uint32_t num, uint32_t value);
62 static void cortex_m_dwt_free(struct target *target);
63
64 static int cortexm_dap_read_coreregister_u32(struct target *target,
65 uint32_t *value, int regnum)
66 {
67 struct armv7m_common *armv7m = target_to_armv7m(target);
68 int retval;
69 uint32_t dcrdr;
70
71 /* because the DCB_DCRDR is used for the emulated dcc channel
72 * we have to save/restore the DCB_DCRDR when used */
73 if (target->dbg_msg_enabled) {
74 retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);
75 if (retval != ERROR_OK)
76 return retval;
77 }
78
79 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRSR, regnum);
80 if (retval != ERROR_OK)
81 return retval;
82
83 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DCRDR, value);
84 if (retval != ERROR_OK)
85 return retval;
86
87 if (target->dbg_msg_enabled) {
88 /* restore DCB_DCRDR - this needs to be in a separate
89 * transaction otherwise the emulated DCC channel breaks */
90 if (retval == ERROR_OK)
91 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);
92 }
93
94 return retval;
95 }
96
97 static int cortexm_dap_write_coreregister_u32(struct target *target,
98 uint32_t value, int regnum)
99 {
100 struct armv7m_common *armv7m = target_to_armv7m(target);
101 int retval;
102 uint32_t dcrdr;
103
104 /* because the DCB_DCRDR is used for the emulated dcc channel
105 * we have to save/restore the DCB_DCRDR when used */
106 if (target->dbg_msg_enabled) {
107 retval = mem_ap_read_u32(armv7m->debug_ap, DCB_DCRDR, &dcrdr);
108 if (retval != ERROR_OK)
109 return retval;
110 }
111
112 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, value);
113 if (retval != ERROR_OK)
114 return retval;
115
116 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRSR, regnum | DCRSR_WnR);
117 if (retval != ERROR_OK)
118 return retval;
119
120 if (target->dbg_msg_enabled) {
121 /* restore DCB_DCRDR - this needs to be in a seperate
122 * transaction otherwise the emulated DCC channel breaks */
123 if (retval == ERROR_OK)
124 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DCRDR, dcrdr);
125 }
126
127 return retval;
128 }
129
130 static int cortex_m_write_debug_halt_mask(struct target *target,
131 uint32_t mask_on, uint32_t mask_off)
132 {
133 struct cortex_m_common *cortex_m = target_to_cm(target);
134 struct armv7m_common *armv7m = &cortex_m->armv7m;
135
136 /* mask off status bits */
137 cortex_m->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off);
138 /* create new register mask */
139 cortex_m->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on;
140
141 return mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR, cortex_m->dcb_dhcsr);
142 }
143
144 static int cortex_m_clear_halt(struct target *target)
145 {
146 struct cortex_m_common *cortex_m = target_to_cm(target);
147 struct armv7m_common *armv7m = &cortex_m->armv7m;
148 int retval;
149
150 /* clear step if any */
151 cortex_m_write_debug_halt_mask(target, C_HALT, C_STEP);
152
153 /* Read Debug Fault Status Register */
154 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR, &cortex_m->nvic_dfsr);
155 if (retval != ERROR_OK)
156 return retval;
157
158 /* Clear Debug Fault Status */
159 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_DFSR, cortex_m->nvic_dfsr);
160 if (retval != ERROR_OK)
161 return retval;
162 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32 "", cortex_m->nvic_dfsr);
163
164 return ERROR_OK;
165 }
166
167 static int cortex_m_single_step_core(struct target *target)
168 {
169 struct cortex_m_common *cortex_m = target_to_cm(target);
170 struct armv7m_common *armv7m = &cortex_m->armv7m;
171 int retval;
172
173 /* Mask interrupts before clearing halt, if done already. This avoids
174 * Erratum 377497 (fixed in r1p0) where setting MASKINTS while clearing
175 * HALT can put the core into an unknown state.
176 */
177 if (!(cortex_m->dcb_dhcsr & C_MASKINTS)) {
178 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
179 DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN);
180 if (retval != ERROR_OK)
181 return retval;
182 }
183 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DHCSR,
184 DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN);
185 if (retval != ERROR_OK)
186 return retval;
187 LOG_DEBUG(" ");
188
189 /* restore dhcsr reg */
190 cortex_m_clear_halt(target);
191
192 return ERROR_OK;
193 }
194
195 static int cortex_m_enable_fpb(struct target *target)
196 {
197 int retval = target_write_u32(target, FP_CTRL, 3);
198 if (retval != ERROR_OK)
199 return retval;
200
201 /* check the fpb is actually enabled */
202 uint32_t fpctrl;
203 retval = target_read_u32(target, FP_CTRL, &fpctrl);
204 if (retval != ERROR_OK)
205 return retval;
206
207 if (fpctrl & 1)
208 return ERROR_OK;
209
210 return ERROR_FAIL;
211 }
212
213 static int cortex_m_endreset_event(struct target *target)
214 {
215 int i;
216 int retval;
217 uint32_t dcb_demcr;
218 struct cortex_m_common *cortex_m = target_to_cm(target);
219 struct armv7m_common *armv7m = &cortex_m->armv7m;
220 struct adiv5_dap *swjdp = cortex_m->armv7m.arm.dap;
221 struct cortex_m_fp_comparator *fp_list = cortex_m->fp_comparator_list;
222 struct cortex_m_dwt_comparator *dwt_list = cortex_m->dwt_comparator_list;
223
224 /* REVISIT The four debug monitor bits are currently ignored... */
225 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &dcb_demcr);
226 if (retval != ERROR_OK)
227 return retval;
228 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "", dcb_demcr);
229
230 /* this register is used for emulated dcc channel */
231 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
232 if (retval != ERROR_OK)
233 return retval;
234
235 /* Enable debug requests */
236 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
237 if (retval != ERROR_OK)
238 return retval;
239 if (!(cortex_m->dcb_dhcsr & C_DEBUGEN)) {
240 retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);
241 if (retval != ERROR_OK)
242 return retval;
243 }
244
245 /* clear any interrupt masking */
246 cortex_m_write_debug_halt_mask(target, 0, C_MASKINTS);
247
248 /* Enable features controlled by ITM and DWT blocks, and catch only
249 * the vectors we were told to pay attention to.
250 *
251 * Target firmware is responsible for all fault handling policy
252 * choices *EXCEPT* explicitly scripted overrides like "vector_catch"
253 * or manual updates to the NVIC SHCSR and CCR registers.
254 */
255 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, TRCENA | armv7m->demcr);
256 if (retval != ERROR_OK)
257 return retval;
258
259 /* Paranoia: evidently some (early?) chips don't preserve all the
260 * debug state (including FBP, DWT, etc) across reset...
261 */
262
263 /* Enable FPB */
264 retval = cortex_m_enable_fpb(target);
265 if (retval != ERROR_OK) {
266 LOG_ERROR("Failed to enable the FPB");
267 return retval;
268 }
269
270 cortex_m->fpb_enabled = 1;
271
272 /* Restore FPB registers */
273 for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
274 retval = target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
275 if (retval != ERROR_OK)
276 return retval;
277 }
278
279 /* Restore DWT registers */
280 for (i = 0; i < cortex_m->dwt_num_comp; i++) {
281 retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 0,
282 dwt_list[i].comp);
283 if (retval != ERROR_OK)
284 return retval;
285 retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 4,
286 dwt_list[i].mask);
287 if (retval != ERROR_OK)
288 return retval;
289 retval = target_write_u32(target, dwt_list[i].dwt_comparator_address + 8,
290 dwt_list[i].function);
291 if (retval != ERROR_OK)
292 return retval;
293 }
294 retval = dap_run(swjdp);
295 if (retval != ERROR_OK)
296 return retval;
297
298 register_cache_invalidate(armv7m->arm.core_cache);
299
300 /* make sure we have latest dhcsr flags */
301 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
302
303 return retval;
304 }
305
306 static int cortex_m_examine_debug_reason(struct target *target)
307 {
308 struct cortex_m_common *cortex_m = target_to_cm(target);
309
310 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason
311 * only check the debug reason if we don't know it already */
312
313 if ((target->debug_reason != DBG_REASON_DBGRQ)
314 && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
315 if (cortex_m->nvic_dfsr & DFSR_BKPT) {
316 target->debug_reason = DBG_REASON_BREAKPOINT;
317 if (cortex_m->nvic_dfsr & DFSR_DWTTRAP)
318 target->debug_reason = DBG_REASON_WPTANDBKPT;
319 } else if (cortex_m->nvic_dfsr & DFSR_DWTTRAP)
320 target->debug_reason = DBG_REASON_WATCHPOINT;
321 else if (cortex_m->nvic_dfsr & DFSR_VCATCH)
322 target->debug_reason = DBG_REASON_BREAKPOINT;
323 else /* EXTERNAL, HALTED */
324 target->debug_reason = DBG_REASON_UNDEFINED;
325 }
326
327 return ERROR_OK;
328 }
329
330 static int cortex_m_examine_exception_reason(struct target *target)
331 {
332 uint32_t shcsr = 0, except_sr = 0, cfsr = -1, except_ar = -1;
333 struct armv7m_common *armv7m = target_to_armv7m(target);
334 struct adiv5_dap *swjdp = armv7m->arm.dap;
335 int retval;
336
337 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_SHCSR, &shcsr);
338 if (retval != ERROR_OK)
339 return retval;
340 switch (armv7m->exception_number) {
341 case 2: /* NMI */
342 break;
343 case 3: /* Hard Fault */
344 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_HFSR, &except_sr);
345 if (retval != ERROR_OK)
346 return retval;
347 if (except_sr & 0x40000000) {
348 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &cfsr);
349 if (retval != ERROR_OK)
350 return retval;
351 }
352 break;
353 case 4: /* Memory Management */
354 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);
355 if (retval != ERROR_OK)
356 return retval;
357 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_MMFAR, &except_ar);
358 if (retval != ERROR_OK)
359 return retval;
360 break;
361 case 5: /* Bus Fault */
362 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);
363 if (retval != ERROR_OK)
364 return retval;
365 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_BFAR, &except_ar);
366 if (retval != ERROR_OK)
367 return retval;
368 break;
369 case 6: /* Usage Fault */
370 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_CFSR, &except_sr);
371 if (retval != ERROR_OK)
372 return retval;
373 break;
374 case 11: /* SVCall */
375 break;
376 case 12: /* Debug Monitor */
377 retval = mem_ap_read_u32(armv7m->debug_ap, NVIC_DFSR, &except_sr);
378 if (retval != ERROR_OK)
379 return retval;
380 break;
381 case 14: /* PendSV */
382 break;
383 case 15: /* SysTick */
384 break;
385 default:
386 except_sr = 0;
387 break;
388 }
389 retval = dap_run(swjdp);
390 if (retval == ERROR_OK)
391 LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32
392 ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32,
393 armv7m_exception_string(armv7m->exception_number),
394 shcsr, except_sr, cfsr, except_ar);
395 return retval;
396 }
397
398 static int cortex_m_debug_entry(struct target *target)
399 {
400 int i;
401 uint32_t xPSR;
402 int retval;
403 struct cortex_m_common *cortex_m = target_to_cm(target);
404 struct armv7m_common *armv7m = &cortex_m->armv7m;
405 struct arm *arm = &armv7m->arm;
406 struct reg *r;
407
408 LOG_DEBUG(" ");
409
410 cortex_m_clear_halt(target);
411 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
412 if (retval != ERROR_OK)
413 return retval;
414
415 retval = armv7m->examine_debug_reason(target);
416 if (retval != ERROR_OK)
417 return retval;
418
419 /* Examine target state and mode
420 * First load register accessible through core debug port */
421 int num_regs = arm->core_cache->num_regs;
422
423 for (i = 0; i < num_regs; i++) {
424 r = &armv7m->arm.core_cache->reg_list[i];
425 if (!r->valid)
426 arm->read_core_reg(target, r, i, ARM_MODE_ANY);
427 }
428
429 r = arm->cpsr;
430 xPSR = buf_get_u32(r->value, 0, 32);
431
432 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
433 if (xPSR & 0xf00) {
434 r->dirty = r->valid;
435 cortex_m_store_core_reg_u32(target, 16, xPSR & ~0xff);
436 }
437
438 /* Are we in an exception handler */
439 if (xPSR & 0x1FF) {
440 armv7m->exception_number = (xPSR & 0x1FF);
441
442 arm->core_mode = ARM_MODE_HANDLER;
443 arm->map = armv7m_msp_reg_map;
444 } else {
445 unsigned control = buf_get_u32(arm->core_cache
446 ->reg_list[ARMV7M_CONTROL].value, 0, 2);
447
448 /* is this thread privileged? */
449 arm->core_mode = control & 1
450 ? ARM_MODE_USER_THREAD
451 : ARM_MODE_THREAD;
452
453 /* which stack is it using? */
454 if (control & 2)
455 arm->map = armv7m_psp_reg_map;
456 else
457 arm->map = armv7m_msp_reg_map;
458
459 armv7m->exception_number = 0;
460 }
461
462 if (armv7m->exception_number)
463 cortex_m_examine_exception_reason(target);
464
465 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
466 arm_mode_name(arm->core_mode),
467 buf_get_u32(arm->pc->value, 0, 32),
468 target_state_name(target));
469
470 if (armv7m->post_debug_entry) {
471 retval = armv7m->post_debug_entry(target);
472 if (retval != ERROR_OK)
473 return retval;
474 }
475
476 return ERROR_OK;
477 }
478
479 static int cortex_m_poll(struct target *target)
480 {
481 int detected_failure = ERROR_OK;
482 int retval = ERROR_OK;
483 enum target_state prev_target_state = target->state;
484 struct cortex_m_common *cortex_m = target_to_cm(target);
485 struct armv7m_common *armv7m = &cortex_m->armv7m;
486
487 /* Read from Debug Halting Control and Status Register */
488 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
489 if (retval != ERROR_OK) {
490 target->state = TARGET_UNKNOWN;
491 return retval;
492 }
493
494 /* Recover from lockup. See ARMv7-M architecture spec,
495 * section B1.5.15 "Unrecoverable exception cases".
496 */
497 if (cortex_m->dcb_dhcsr & S_LOCKUP) {
498 LOG_ERROR("%s -- clearing lockup after double fault",
499 target_name(target));
500 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
501 target->debug_reason = DBG_REASON_DBGRQ;
502
503 /* We have to execute the rest (the "finally" equivalent, but
504 * still throw this exception again).
505 */
506 detected_failure = ERROR_FAIL;
507
508 /* refresh status bits */
509 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
510 if (retval != ERROR_OK)
511 return retval;
512 }
513
514 if (cortex_m->dcb_dhcsr & S_RESET_ST) {
515 target->state = TARGET_RESET;
516 return ERROR_OK;
517 }
518
519 if (target->state == TARGET_RESET) {
520 /* Cannot switch context while running so endreset is
521 * called with target->state == TARGET_RESET
522 */
523 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32,
524 cortex_m->dcb_dhcsr);
525 retval = cortex_m_endreset_event(target);
526 if (retval != ERROR_OK) {
527 target->state = TARGET_UNKNOWN;
528 return retval;
529 }
530 target->state = TARGET_RUNNING;
531 prev_target_state = TARGET_RUNNING;
532 }
533
534 if (cortex_m->dcb_dhcsr & S_HALT) {
535 target->state = TARGET_HALTED;
536
537 if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET)) {
538 retval = cortex_m_debug_entry(target);
539 if (retval != ERROR_OK)
540 return retval;
541
542 if (arm_semihosting(target, &retval) != 0)
543 return retval;
544
545 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
546 }
547 if (prev_target_state == TARGET_DEBUG_RUNNING) {
548 LOG_DEBUG(" ");
549 retval = cortex_m_debug_entry(target);
550 if (retval != ERROR_OK)
551 return retval;
552
553 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
554 }
555 }
556
557 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
558 * How best to model low power modes?
559 */
560
561 if (target->state == TARGET_UNKNOWN) {
562 /* check if processor is retiring instructions */
563 if (cortex_m->dcb_dhcsr & S_RETIRE_ST) {
564 target->state = TARGET_RUNNING;
565 retval = ERROR_OK;
566 }
567 }
568
569 /* Did we detect a failure condition that we cleared? */
570 if (detected_failure != ERROR_OK)
571 retval = detected_failure;
572 return retval;
573 }
574
575 static int cortex_m_halt(struct target *target)
576 {
577 LOG_DEBUG("target->state: %s",
578 target_state_name(target));
579
580 if (target->state == TARGET_HALTED) {
581 LOG_DEBUG("target was already halted");
582 return ERROR_OK;
583 }
584
585 if (target->state == TARGET_UNKNOWN)
586 LOG_WARNING("target was in unknown state when halt was requested");
587
588 if (target->state == TARGET_RESET) {
589 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {
590 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
591 return ERROR_TARGET_FAILURE;
592 } else {
593 /* we came here in a reset_halt or reset_init sequence
594 * debug entry was already prepared in cortex_m3_assert_reset()
595 */
596 target->debug_reason = DBG_REASON_DBGRQ;
597
598 return ERROR_OK;
599 }
600 }
601
602 /* Write to Debug Halting Control and Status Register */
603 cortex_m_write_debug_halt_mask(target, C_HALT, 0);
604
605 target->debug_reason = DBG_REASON_DBGRQ;
606
607 return ERROR_OK;
608 }
609
610 static int cortex_m_soft_reset_halt(struct target *target)
611 {
612 struct cortex_m_common *cortex_m = target_to_cm(target);
613 struct armv7m_common *armv7m = &cortex_m->armv7m;
614 uint32_t dcb_dhcsr = 0;
615 int retval, timeout = 0;
616
617 /* soft_reset_halt is deprecated on cortex_m as the same functionality
618 * can be obtained by using 'reset halt' and 'cortex_m reset_config vectreset'
619 * As this reset only used VC_CORERESET it would only ever reset the cortex_m
620 * core, not the peripherals */
621 LOG_WARNING("soft_reset_halt is deprecated, please use 'reset halt' instead.");
622
623 /* Enter debug state on reset; restore DEMCR in endreset_event() */
624 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR,
625 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
626 if (retval != ERROR_OK)
627 return retval;
628
629 /* Request a core-only reset */
630 retval = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
631 AIRCR_VECTKEY | AIRCR_VECTRESET);
632 if (retval != ERROR_OK)
633 return retval;
634 target->state = TARGET_RESET;
635
636 /* registers are now invalid */
637 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
638
639 while (timeout < 100) {
640 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &dcb_dhcsr);
641 if (retval == ERROR_OK) {
642 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_DFSR,
643 &cortex_m->nvic_dfsr);
644 if (retval != ERROR_OK)
645 return retval;
646 if ((dcb_dhcsr & S_HALT)
647 && (cortex_m->nvic_dfsr & DFSR_VCATCH)) {
648 LOG_DEBUG("system reset-halted, DHCSR 0x%08x, "
649 "DFSR 0x%08x",
650 (unsigned) dcb_dhcsr,
651 (unsigned) cortex_m->nvic_dfsr);
652 cortex_m_poll(target);
653 /* FIXME restore user's vector catch config */
654 return ERROR_OK;
655 } else
656 LOG_DEBUG("waiting for system reset-halt, "
657 "DHCSR 0x%08x, %d ms",
658 (unsigned) dcb_dhcsr, timeout);
659 }
660 timeout++;
661 alive_sleep(1);
662 }
663
664 return ERROR_OK;
665 }
666
667 void cortex_m_enable_breakpoints(struct target *target)
668 {
669 struct breakpoint *breakpoint = target->breakpoints;
670
671 /* set any pending breakpoints */
672 while (breakpoint) {
673 if (!breakpoint->set)
674 cortex_m_set_breakpoint(target, breakpoint);
675 breakpoint = breakpoint->next;
676 }
677 }
678
679 static int cortex_m_resume(struct target *target, int current,
680 target_addr_t address, int handle_breakpoints, int debug_execution)
681 {
682 struct armv7m_common *armv7m = target_to_armv7m(target);
683 struct breakpoint *breakpoint = NULL;
684 uint32_t resume_pc;
685 struct reg *r;
686
687 if (target->state != TARGET_HALTED) {
688 LOG_WARNING("target not halted");
689 return ERROR_TARGET_NOT_HALTED;
690 }
691
692 if (!debug_execution) {
693 target_free_all_working_areas(target);
694 cortex_m_enable_breakpoints(target);
695 cortex_m_enable_watchpoints(target);
696 }
697
698 if (debug_execution) {
699 r = armv7m->arm.core_cache->reg_list + ARMV7M_PRIMASK;
700
701 /* Disable interrupts */
702 /* We disable interrupts in the PRIMASK register instead of
703 * masking with C_MASKINTS. This is probably the same issue
704 * as Cortex-M3 Erratum 377493 (fixed in r1p0): C_MASKINTS
705 * in parallel with disabled interrupts can cause local faults
706 * to not be taken.
707 *
708 * REVISIT this clearly breaks non-debug execution, since the
709 * PRIMASK register state isn't saved/restored... workaround
710 * by never resuming app code after debug execution.
711 */
712 buf_set_u32(r->value, 0, 1, 1);
713 r->dirty = true;
714 r->valid = true;
715
716 /* Make sure we are in Thumb mode */
717 r = armv7m->arm.cpsr;
718 buf_set_u32(r->value, 24, 1, 1);
719 r->dirty = true;
720 r->valid = true;
721 }
722
723 /* current = 1: continue on current pc, otherwise continue at <address> */
724 r = armv7m->arm.pc;
725 if (!current) {
726 buf_set_u32(r->value, 0, 32, address);
727 r->dirty = true;
728 r->valid = true;
729 }
730
731 /* if we halted last time due to a bkpt instruction
732 * then we have to manually step over it, otherwise
733 * the core will break again */
734
735 if (!breakpoint_find(target, buf_get_u32(r->value, 0, 32))
736 && !debug_execution)
737 armv7m_maybe_skip_bkpt_inst(target, NULL);
738
739 resume_pc = buf_get_u32(r->value, 0, 32);
740
741 armv7m_restore_context(target);
742
743 /* the front-end may request us not to handle breakpoints */
744 if (handle_breakpoints) {
745 /* Single step past breakpoint at current address */
746 breakpoint = breakpoint_find(target, resume_pc);
747 if (breakpoint) {
748 LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT " (ID: %" PRIu32 ")",
749 breakpoint->address,
750 breakpoint->unique_id);
751 cortex_m_unset_breakpoint(target, breakpoint);
752 cortex_m_single_step_core(target);
753 cortex_m_set_breakpoint(target, breakpoint);
754 }
755 }
756
757 /* Restart core */
758 cortex_m_write_debug_halt_mask(target, 0, C_HALT);
759
760 target->debug_reason = DBG_REASON_NOTHALTED;
761
762 /* registers are now invalid */
763 register_cache_invalidate(armv7m->arm.core_cache);
764
765 if (!debug_execution) {
766 target->state = TARGET_RUNNING;
767 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
768 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
769 } else {
770 target->state = TARGET_DEBUG_RUNNING;
771 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
772 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
773 }
774
775 return ERROR_OK;
776 }
777
778 /* int irqstepcount = 0; */
779 static int cortex_m_step(struct target *target, int current,
780 target_addr_t address, int handle_breakpoints)
781 {
782 struct cortex_m_common *cortex_m = target_to_cm(target);
783 struct armv7m_common *armv7m = &cortex_m->armv7m;
784 struct breakpoint *breakpoint = NULL;
785 struct reg *pc = armv7m->arm.pc;
786 bool bkpt_inst_found = false;
787 int retval;
788 bool isr_timed_out = false;
789
790 if (target->state != TARGET_HALTED) {
791 LOG_WARNING("target not halted");
792 return ERROR_TARGET_NOT_HALTED;
793 }
794
795 /* current = 1: continue on current pc, otherwise continue at <address> */
796 if (!current)
797 buf_set_u32(pc->value, 0, 32, address);
798
799 uint32_t pc_value = buf_get_u32(pc->value, 0, 32);
800
801 /* the front-end may request us not to handle breakpoints */
802 if (handle_breakpoints) {
803 breakpoint = breakpoint_find(target, pc_value);
804 if (breakpoint)
805 cortex_m_unset_breakpoint(target, breakpoint);
806 }
807
808 armv7m_maybe_skip_bkpt_inst(target, &bkpt_inst_found);
809
810 target->debug_reason = DBG_REASON_SINGLESTEP;
811
812 armv7m_restore_context(target);
813
814 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
815
816 /* if no bkpt instruction is found at pc then we can perform
817 * a normal step, otherwise we have to manually step over the bkpt
818 * instruction - as such simulate a step */
819 if (bkpt_inst_found == false) {
820 /* Automatic ISR masking mode off: Just step over the next instruction */
821 if ((cortex_m->isrmasking_mode != CORTEX_M_ISRMASK_AUTO))
822 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
823 else {
824 /* Process interrupts during stepping in a way they don't interfere
825 * debugging.
826 *
827 * Principle:
828 *
829 * Set a temporary break point at the current pc and let the core run
830 * with interrupts enabled. Pending interrupts get served and we run
831 * into the breakpoint again afterwards. Then we step over the next
832 * instruction with interrupts disabled.
833 *
834 * If the pending interrupts don't complete within time, we leave the
835 * core running. This may happen if the interrupts trigger faster
836 * than the core can process them or the handler doesn't return.
837 *
838 * If no more breakpoints are available we simply do a step with
839 * interrupts enabled.
840 *
841 */
842
843 /* 2012-09-29 ph
844 *
845 * If a break point is already set on the lower half word then a break point on
846 * the upper half word will not break again when the core is restarted. So we
847 * just step over the instruction with interrupts disabled.
848 *
849 * The documentation has no information about this, it was found by observation
850 * on STM32F1 and STM32F2. Proper explanation welcome. STM32F0 dosen't seem to
851 * suffer from this problem.
852 *
853 * To add some confusion: pc_value has bit 0 always set, while the breakpoint
854 * address has it always cleared. The former is done to indicate thumb mode
855 * to gdb.
856 *
857 */
858 if ((pc_value & 0x02) && breakpoint_find(target, pc_value & ~0x03)) {
859 LOG_DEBUG("Stepping over next instruction with interrupts disabled");
860 cortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
861 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
862 /* Re-enable interrupts */
863 cortex_m_write_debug_halt_mask(target, C_HALT, C_MASKINTS);
864 }
865 else {
866
867 /* Set a temporary break point */
868 if (breakpoint)
869 retval = cortex_m_set_breakpoint(target, breakpoint);
870 else
871 retval = breakpoint_add(target, pc_value, 2, BKPT_TYPE_BY_ADDR(pc_value));
872 bool tmp_bp_set = (retval == ERROR_OK);
873
874 /* No more breakpoints left, just do a step */
875 if (!tmp_bp_set)
876 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
877 else {
878 /* Start the core */
879 LOG_DEBUG("Starting core to serve pending interrupts");
880 int64_t t_start = timeval_ms();
881 cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP);
882
883 /* Wait for pending handlers to complete or timeout */
884 do {
885 retval = mem_ap_read_atomic_u32(armv7m->debug_ap,
886 DCB_DHCSR,
887 &cortex_m->dcb_dhcsr);
888 if (retval != ERROR_OK) {
889 target->state = TARGET_UNKNOWN;
890 return retval;
891 }
892 isr_timed_out = ((timeval_ms() - t_start) > 500);
893 } while (!((cortex_m->dcb_dhcsr & S_HALT) || isr_timed_out));
894
895 /* only remove breakpoint if we created it */
896 if (breakpoint)
897 cortex_m_unset_breakpoint(target, breakpoint);
898 else {
899 /* Remove the temporary breakpoint */
900 breakpoint_remove(target, pc_value);
901 }
902
903 if (isr_timed_out) {
904 LOG_DEBUG("Interrupt handlers didn't complete within time, "
905 "leaving target running");
906 } else {
907 /* Step over next instruction with interrupts disabled */
908 cortex_m_write_debug_halt_mask(target,
909 C_HALT | C_MASKINTS,
910 0);
911 cortex_m_write_debug_halt_mask(target, C_STEP, C_HALT);
912 /* Re-enable interrupts */
913 cortex_m_write_debug_halt_mask(target, C_HALT, C_MASKINTS);
914 }
915 }
916 }
917 }
918 }
919
920 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
921 if (retval != ERROR_OK)
922 return retval;
923
924 /* registers are now invalid */
925 register_cache_invalidate(armv7m->arm.core_cache);
926
927 if (breakpoint)
928 cortex_m_set_breakpoint(target, breakpoint);
929
930 if (isr_timed_out) {
931 /* Leave the core running. The user has to stop execution manually. */
932 target->debug_reason = DBG_REASON_NOTHALTED;
933 target->state = TARGET_RUNNING;
934 return ERROR_OK;
935 }
936
937 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
938 " nvic_icsr = 0x%" PRIx32,
939 cortex_m->dcb_dhcsr, cortex_m->nvic_icsr);
940
941 retval = cortex_m_debug_entry(target);
942 if (retval != ERROR_OK)
943 return retval;
944 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
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 return ERROR_OK;
951 }
952
953 static int cortex_m_assert_reset(struct target *target)
954 {
955 struct cortex_m_common *cortex_m = target_to_cm(target);
956 struct armv7m_common *armv7m = &cortex_m->armv7m;
957 enum cortex_m_soft_reset_config reset_config = cortex_m->soft_reset_config;
958
959 LOG_DEBUG("target->state: %s",
960 target_state_name(target));
961
962 enum reset_types jtag_reset_config = jtag_get_reset_config();
963
964 if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {
965 /* allow scripts to override the reset event */
966
967 target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
968 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
969 target->state = TARGET_RESET;
970
971 return ERROR_OK;
972 }
973
974 /* some cores support connecting while srst is asserted
975 * use that mode is it has been configured */
976
977 bool srst_asserted = false;
978
979 if (!target_was_examined(target)) {
980 if (jtag_reset_config & RESET_HAS_SRST) {
981 adapter_assert_reset();
982 if (target->reset_halt)
983 LOG_ERROR("Target not examined, will not halt after reset!");
984 return ERROR_OK;
985 } else {
986 LOG_ERROR("Target not examined, reset NOT asserted!");
987 return ERROR_FAIL;
988 }
989 }
990
991 if ((jtag_reset_config & RESET_HAS_SRST) &&
992 (jtag_reset_config & RESET_SRST_NO_GATING)) {
993 adapter_assert_reset();
994 srst_asserted = true;
995 }
996
997 /* Enable debug requests */
998 int retval;
999 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DHCSR, &cortex_m->dcb_dhcsr);
1000 /* Store important errors instead of failing and proceed to reset assert */
1001
1002 if (retval != ERROR_OK || !(cortex_m->dcb_dhcsr & C_DEBUGEN))
1003 retval = cortex_m_write_debug_halt_mask(target, 0, C_HALT | C_STEP | C_MASKINTS);
1004
1005 /* If the processor is sleeping in a WFI or WFE instruction, the
1006 * C_HALT bit must be asserted to regain control */
1007 if (retval == ERROR_OK && (cortex_m->dcb_dhcsr & S_SLEEP))
1008 retval = cortex_m_write_debug_halt_mask(target, C_HALT, 0);
1009
1010 mem_ap_write_u32(armv7m->debug_ap, DCB_DCRDR, 0);
1011 /* Ignore less important errors */
1012
1013 if (!target->reset_halt) {
1014 /* Set/Clear C_MASKINTS in a separate operation */
1015 if (cortex_m->dcb_dhcsr & C_MASKINTS)
1016 cortex_m_write_debug_halt_mask(target, 0, C_MASKINTS);
1017
1018 /* clear any debug flags before resuming */
1019 cortex_m_clear_halt(target);
1020
1021 /* clear C_HALT in dhcsr reg */
1022 cortex_m_write_debug_halt_mask(target, 0, C_HALT);
1023 } else {
1024 /* Halt in debug on reset; endreset_event() restores DEMCR.
1025 *
1026 * REVISIT catching BUSERR presumably helps to defend against
1027 * bad vector table entries. Should this include MMERR or
1028 * other flags too?
1029 */
1030 int retval2;
1031 retval2 = mem_ap_write_atomic_u32(armv7m->debug_ap, DCB_DEMCR,
1032 TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
1033 if (retval != ERROR_OK || retval2 != ERROR_OK)
1034 LOG_INFO("AP write error, reset will not halt");
1035 }
1036
1037 if (jtag_reset_config & RESET_HAS_SRST) {
1038 /* default to asserting srst */
1039 if (!srst_asserted)
1040 adapter_assert_reset();
1041
1042 /* srst is asserted, ignore AP access errors */
1043 retval = ERROR_OK;
1044 } else {
1045 /* Use a standard Cortex-M3 software reset mechanism.
1046 * We default to using VECRESET as it is supported on all current cores.
1047 * This has the disadvantage of not resetting the peripherals, so a
1048 * reset-init event handler is needed to perform any peripheral resets.
1049 */
1050 LOG_DEBUG("Using Cortex-M %s", (reset_config == CORTEX_M_RESET_SYSRESETREQ)
1051 ? "SYSRESETREQ" : "VECTRESET");
1052
1053 if (reset_config == CORTEX_M_RESET_VECTRESET) {
1054 LOG_WARNING("Only resetting the Cortex-M core, use a reset-init event "
1055 "handler to reset any peripherals or configure hardware srst support.");
1056 }
1057
1058 int retval3;
1059 retval3 = mem_ap_write_atomic_u32(armv7m->debug_ap, NVIC_AIRCR,
1060 AIRCR_VECTKEY | ((reset_config == CORTEX_M_RESET_SYSRESETREQ)
1061 ? AIRCR_SYSRESETREQ : AIRCR_VECTRESET));
1062 if (retval3 != ERROR_OK)
1063 LOG_DEBUG("Ignoring AP write error right after reset");
1064
1065 retval3 = dap_dp_init(armv7m->debug_ap->dap);
1066 if (retval3 != ERROR_OK)
1067 LOG_ERROR("DP initialisation failed");
1068
1069 else {
1070 /* I do not know why this is necessary, but it
1071 * fixes strange effects (step/resume cause NMI
1072 * after reset) on LM3S6918 -- Michael Schwingen
1073 */
1074 uint32_t tmp;
1075 mem_ap_read_atomic_u32(armv7m->debug_ap, NVIC_AIRCR, &tmp);
1076 }
1077 }
1078
1079 target->state = TARGET_RESET;
1080 jtag_add_sleep(50000);
1081
1082 register_cache_invalidate(cortex_m->armv7m.arm.core_cache);
1083
1084 /* now return stored error code if any */
1085 if (retval != ERROR_OK)
1086 return retval;
1087
1088 if (target->reset_halt) {
1089 retval = target_halt(target);
1090 if (retval != ERROR_OK)
1091 return retval;
1092 }
1093
1094 return ERROR_OK;
1095 }
1096
1097 static int cortex_m_deassert_reset(struct target *target)
1098 {
1099 struct armv7m_common *armv7m = &target_to_cm(target)->armv7m;
1100
1101 LOG_DEBUG("target->state: %s",
1102 target_state_name(target));
1103
1104 /* deassert reset lines */
1105 adapter_deassert_reset();
1106
1107 enum reset_types jtag_reset_config = jtag_get_reset_config();
1108
1109 if ((jtag_reset_config & RESET_HAS_SRST) &&
1110 !(jtag_reset_config & RESET_SRST_NO_GATING) &&
1111 target_was_examined(target)) {
1112 int retval = dap_dp_init(armv7m->debug_ap->dap);
1113 if (retval != ERROR_OK) {
1114 LOG_ERROR("DP initialisation failed");
1115 return retval;
1116 }
1117 }
1118
1119 return ERROR_OK;
1120 }
1121
1122 int cortex_m_set_breakpoint(struct target *target, struct breakpoint *breakpoint)
1123 {
1124 int retval;
1125 int fp_num = 0;
1126 struct cortex_m_common *cortex_m = target_to_cm(target);
1127 struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
1128
1129 if (breakpoint->set) {
1130 LOG_WARNING("breakpoint (BPID: %" PRIu32 ") already set", breakpoint->unique_id);
1131 return ERROR_OK;
1132 }
1133
1134 if (cortex_m->auto_bp_type)
1135 breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
1136
1137 if (breakpoint->type == BKPT_HARD) {
1138 uint32_t fpcr_value;
1139 while (comparator_list[fp_num].used && (fp_num < cortex_m->fp_num_code))
1140 fp_num++;
1141 if (fp_num >= cortex_m->fp_num_code) {
1142 LOG_ERROR("Can not find free FPB Comparator!");
1143 return ERROR_FAIL;
1144 }
1145 breakpoint->set = fp_num + 1;
1146 fpcr_value = breakpoint->address | 1;
1147 if (cortex_m->fp_rev == 0) {
1148 uint32_t hilo;
1149 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
1150 fpcr_value = (fpcr_value & 0x1FFFFFFC) | hilo | 1;
1151 } else if (cortex_m->fp_rev > 1) {
1152 LOG_ERROR("Unhandled Cortex-M Flash Patch Breakpoint architecture revision");
1153 return ERROR_FAIL;
1154 }
1155 comparator_list[fp_num].used = 1;
1156 comparator_list[fp_num].fpcr_value = fpcr_value;
1157 target_write_u32(target, comparator_list[fp_num].fpcr_address,
1158 comparator_list[fp_num].fpcr_value);
1159 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "",
1160 fp_num,
1161 comparator_list[fp_num].fpcr_value);
1162 if (!cortex_m->fpb_enabled) {
1163 LOG_DEBUG("FPB wasn't enabled, do it now");
1164 retval = cortex_m_enable_fpb(target);
1165 if (retval != ERROR_OK) {
1166 LOG_ERROR("Failed to enable the FPB");
1167 return retval;
1168 }
1169
1170 cortex_m->fpb_enabled = 1;
1171 }
1172 } else if (breakpoint->type == BKPT_SOFT) {
1173 uint8_t code[4];
1174
1175 /* NOTE: on ARMv6-M and ARMv7-M, BKPT(0xab) is used for
1176 * semihosting; don't use that. Otherwise the BKPT
1177 * parameter is arbitrary.
1178 */
1179 buf_set_u32(code, 0, 32, ARMV5_T_BKPT(0x11));
1180 retval = target_read_memory(target,
1181 breakpoint->address & 0xFFFFFFFE,
1182 breakpoint->length, 1,
1183 breakpoint->orig_instr);
1184 if (retval != ERROR_OK)
1185 return retval;
1186 retval = target_write_memory(target,
1187 breakpoint->address & 0xFFFFFFFE,
1188 breakpoint->length, 1,
1189 code);
1190 if (retval != ERROR_OK)
1191 return retval;
1192 breakpoint->set = true;
1193 }
1194
1195 LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
1196 breakpoint->unique_id,
1197 (int)(breakpoint->type),
1198 breakpoint->address,
1199 breakpoint->length,
1200 breakpoint->set);
1201
1202 return ERROR_OK;
1203 }
1204
1205 int cortex_m_unset_breakpoint(struct target *target, struct breakpoint *breakpoint)
1206 {
1207 int retval;
1208 struct cortex_m_common *cortex_m = target_to_cm(target);
1209 struct cortex_m_fp_comparator *comparator_list = cortex_m->fp_comparator_list;
1210
1211 if (!breakpoint->set) {
1212 LOG_WARNING("breakpoint not set");
1213 return ERROR_OK;
1214 }
1215
1216 LOG_DEBUG("BPID: %" PRIu32 ", Type: %d, Address: " TARGET_ADDR_FMT " Length: %d (set=%d)",
1217 breakpoint->unique_id,
1218 (int)(breakpoint->type),
1219 breakpoint->address,
1220 breakpoint->length,
1221 breakpoint->set);
1222
1223 if (breakpoint->type == BKPT_HARD) {
1224 int fp_num = breakpoint->set - 1;
1225 if ((fp_num < 0) || (fp_num >= cortex_m->fp_num_code)) {
1226 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1227 return ERROR_OK;
1228 }
1229 comparator_list[fp_num].used = 0;
1230 comparator_list[fp_num].fpcr_value = 0;
1231 target_write_u32(target, comparator_list[fp_num].fpcr_address,
1232 comparator_list[fp_num].fpcr_value);
1233 } else {
1234 /* restore original instruction (kept in target endianness) */
1235 if (breakpoint->length == 4) {
1236 retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1,
1237 breakpoint->orig_instr);
1238 if (retval != ERROR_OK)
1239 return retval;
1240 } else {
1241 retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1,
1242 breakpoint->orig_instr);
1243 if (retval != ERROR_OK)
1244 return retval;
1245 }
1246 }
1247 breakpoint->set = false;
1248
1249 return ERROR_OK;
1250 }
1251
1252 int cortex_m_add_breakpoint(struct target *target, struct breakpoint *breakpoint)
1253 {
1254 struct cortex_m_common *cortex_m = target_to_cm(target);
1255
1256 if (cortex_m->auto_bp_type)
1257 breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
1258
1259 if (breakpoint->type != BKPT_TYPE_BY_ADDR(breakpoint->address)) {
1260 if (breakpoint->type == BKPT_HARD) {
1261 LOG_INFO("flash patch comparator requested outside code memory region");
1262 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1263 }
1264
1265 if (breakpoint->type == BKPT_SOFT) {
1266 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1267 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1268 }
1269 }
1270
1271 if ((breakpoint->type == BKPT_HARD) && (cortex_m->fp_code_available < 1)) {
1272 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1273 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1274 }
1275
1276 if (breakpoint->length == 3) {
1277 LOG_DEBUG("Using a two byte breakpoint for 32bit Thumb-2 request");
1278 breakpoint->length = 2;
1279 }
1280
1281 if ((breakpoint->length != 2)) {
1282 LOG_INFO("only breakpoints of two bytes length supported");
1283 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1284 }
1285
1286 if (breakpoint->type == BKPT_HARD)
1287 cortex_m->fp_code_available--;
1288
1289 return cortex_m_set_breakpoint(target, breakpoint);
1290 }
1291
1292 int cortex_m_remove_breakpoint(struct target *target, struct breakpoint *breakpoint)
1293 {
1294 struct cortex_m_common *cortex_m = target_to_cm(target);
1295
1296 /* REVISIT why check? FBP can be updated with core running ... */
1297 if (target->state != TARGET_HALTED) {
1298 LOG_WARNING("target not halted");
1299 return ERROR_TARGET_NOT_HALTED;
1300 }
1301
1302 if (cortex_m->auto_bp_type)
1303 breakpoint->type = BKPT_TYPE_BY_ADDR(breakpoint->address);
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 char *name;
1836 unsigned size;
1837 };
1838
1839 static 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 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, 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 < 0) {
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 if (i == 4) {
2050 target_read_u32(target, MVFR0, &mvfr0);
2051 target_read_u32(target, MVFR1, &mvfr1);
2052
2053 /* test for floating point feature on Cortex-M4 */
2054 if ((mvfr0 == MVFR0_DEFAULT_M4) && (mvfr1 == MVFR1_DEFAULT_M4)) {
2055 LOG_DEBUG("Cortex-M%d floating point feature FPv4_SP found", i);
2056 armv7m->fp_feature = FPv4_SP;
2057 }
2058 } else if (i == 7) {
2059 target_read_u32(target, MVFR0, &mvfr0);
2060 target_read_u32(target, MVFR1, &mvfr1);
2061
2062 /* test for floating point features on Cortex-M7 */
2063 if ((mvfr0 == MVFR0_DEFAULT_M7_SP) && (mvfr1 == MVFR1_DEFAULT_M7_SP)) {
2064 LOG_DEBUG("Cortex-M%d floating point feature FPv5_SP found", i);
2065 armv7m->fp_feature = FPv5_SP;
2066 } else if ((mvfr0 == MVFR0_DEFAULT_M7_DP) && (mvfr1 == MVFR1_DEFAULT_M7_DP)) {
2067 LOG_DEBUG("Cortex-M%d floating point feature FPv5_DP found", i);
2068 armv7m->fp_feature = FPv5_DP;
2069 }
2070 } else if (i == 0) {
2071 /* Cortex-M0 does not support unaligned memory access */
2072 armv7m->arm.is_armv6m = true;
2073 }
2074
2075 if (armv7m->fp_feature == FP_NONE &&
2076 armv7m->arm.core_cache->num_regs > ARMV7M_NUM_CORE_REGS_NOFP) {
2077 /* free unavailable FPU registers */
2078 size_t idx;
2079
2080 for (idx = ARMV7M_NUM_CORE_REGS_NOFP;
2081 idx < armv7m->arm.core_cache->num_regs;
2082 idx++) {
2083 free(armv7m->arm.core_cache->reg_list[idx].value);
2084 free(armv7m->arm.core_cache->reg_list[idx].feature);
2085 free(armv7m->arm.core_cache->reg_list[idx].reg_data_type);
2086 }
2087 armv7m->arm.core_cache->num_regs = ARMV7M_NUM_CORE_REGS_NOFP;
2088 }
2089
2090 if (!armv7m->stlink) {
2091 if (i == 3 || i == 4)
2092 /* Cortex-M3/M4 have 4096 bytes autoincrement range,
2093 * s. ARM IHI 0031C: MEM-AP 7.2.2 */
2094 armv7m->debug_ap->tar_autoincr_block = (1 << 12);
2095 else if (i == 7)
2096 /* Cortex-M7 has only 1024 bytes autoincrement range */
2097 armv7m->debug_ap->tar_autoincr_block = (1 << 10);
2098 }
2099
2100 /* Configure trace modules */
2101 retval = target_write_u32(target, DCB_DEMCR, TRCENA | armv7m->demcr);
2102 if (retval != ERROR_OK)
2103 return retval;
2104
2105 if (armv7m->trace_config.config_type != DISABLED) {
2106 armv7m_trace_tpiu_config(target);
2107 armv7m_trace_itm_config(target);
2108 }
2109
2110 /* NOTE: FPB and DWT are both optional. */
2111
2112 /* Setup FPB */
2113 target_read_u32(target, FP_CTRL, &fpcr);
2114 cortex_m->auto_bp_type = 1;
2115 /* bits [14:12] and [7:4] */
2116 cortex_m->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF);
2117 cortex_m->fp_num_lit = (fpcr >> 8) & 0xF;
2118 cortex_m->fp_code_available = cortex_m->fp_num_code;
2119 /* Detect flash patch revision, see RM DDI 0403E.b page C1-817.
2120 Revision is zero base, fp_rev == 1 means Rev.2 ! */
2121 cortex_m->fp_rev = (fpcr >> 28) & 0xf;
2122 free(cortex_m->fp_comparator_list);
2123 cortex_m->fp_comparator_list = calloc(
2124 cortex_m->fp_num_code + cortex_m->fp_num_lit,
2125 sizeof(struct cortex_m_fp_comparator));
2126 cortex_m->fpb_enabled = fpcr & 1;
2127 for (i = 0; i < cortex_m->fp_num_code + cortex_m->fp_num_lit; i++) {
2128 cortex_m->fp_comparator_list[i].type =
2129 (i < cortex_m->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
2130 cortex_m->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
2131
2132 /* make sure we clear any breakpoints enabled on the target */
2133 target_write_u32(target, cortex_m->fp_comparator_list[i].fpcr_address, 0);
2134 }
2135 LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i",
2136 fpcr,
2137 cortex_m->fp_num_code,
2138 cortex_m->fp_num_lit);
2139
2140 /* Setup DWT */
2141 cortex_m_dwt_free(target);
2142 cortex_m_dwt_setup(cortex_m, target);
2143
2144 /* These hardware breakpoints only work for code in flash! */
2145 LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
2146 target_name(target),
2147 cortex_m->fp_num_code,
2148 cortex_m->dwt_num_comp);
2149 }
2150
2151 return ERROR_OK;
2152 }
2153
2154 static int cortex_m_dcc_read(struct target *target, uint8_t *value, uint8_t *ctrl)
2155 {
2156 struct armv7m_common *armv7m = target_to_armv7m(target);
2157 uint16_t dcrdr;
2158 uint8_t buf[2];
2159 int retval;
2160
2161 retval = mem_ap_read_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);
2162 if (retval != ERROR_OK)
2163 return retval;
2164
2165 dcrdr = target_buffer_get_u16(target, buf);
2166 *ctrl = (uint8_t)dcrdr;
2167 *value = (uint8_t)(dcrdr >> 8);
2168
2169 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
2170
2171 /* write ack back to software dcc register
2172 * signify we have read data */
2173 if (dcrdr & (1 << 0)) {
2174 target_buffer_set_u16(target, buf, 0);
2175 retval = mem_ap_write_buf_noincr(armv7m->debug_ap, buf, 2, 1, DCB_DCRDR);
2176 if (retval != ERROR_OK)
2177 return retval;
2178 }
2179
2180 return ERROR_OK;
2181 }
2182
2183 static int cortex_m_target_request_data(struct target *target,
2184 uint32_t size, uint8_t *buffer)
2185 {
2186 uint8_t data;
2187 uint8_t ctrl;
2188 uint32_t i;
2189
2190 for (i = 0; i < (size * 4); i++) {
2191 int retval = cortex_m_dcc_read(target, &data, &ctrl);
2192 if (retval != ERROR_OK)
2193 return retval;
2194 buffer[i] = data;
2195 }
2196
2197 return ERROR_OK;
2198 }
2199
2200 static int cortex_m_handle_target_request(void *priv)
2201 {
2202 struct target *target = priv;
2203 if (!target_was_examined(target))
2204 return ERROR_OK;
2205
2206 if (!target->dbg_msg_enabled)
2207 return ERROR_OK;
2208
2209 if (target->state == TARGET_RUNNING) {
2210 uint8_t data;
2211 uint8_t ctrl;
2212 int retval;
2213
2214 retval = cortex_m_dcc_read(target, &data, &ctrl);
2215 if (retval != ERROR_OK)
2216 return retval;
2217
2218 /* check if we have data */
2219 if (ctrl & (1 << 0)) {
2220 uint32_t request;
2221
2222 /* we assume target is quick enough */
2223 request = data;
2224 for (int i = 1; i <= 3; i++) {
2225 retval = cortex_m_dcc_read(target, &data, &ctrl);
2226 if (retval != ERROR_OK)
2227 return retval;
2228 request |= ((uint32_t)data << (i * 8));
2229 }
2230 target_request(target, request);
2231 }
2232 }
2233
2234 return ERROR_OK;
2235 }
2236
2237 static int cortex_m_init_arch_info(struct target *target,
2238 struct cortex_m_common *cortex_m, struct adiv5_dap *dap)
2239 {
2240 struct armv7m_common *armv7m = &cortex_m->armv7m;
2241
2242 armv7m_init_arch_info(target, armv7m);
2243
2244 /* default reset mode is to use srst if fitted
2245 * if not it will use CORTEX_M3_RESET_VECTRESET */
2246 cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;
2247
2248 armv7m->arm.dap = dap;
2249
2250 /* register arch-specific functions */
2251 armv7m->examine_debug_reason = cortex_m_examine_debug_reason;
2252
2253 armv7m->post_debug_entry = NULL;
2254
2255 armv7m->pre_restore_context = NULL;
2256
2257 armv7m->load_core_reg_u32 = cortex_m_load_core_reg_u32;
2258 armv7m->store_core_reg_u32 = cortex_m_store_core_reg_u32;
2259
2260 target_register_timer_callback(cortex_m_handle_target_request, 1, 1, target);
2261
2262 return ERROR_OK;
2263 }
2264
2265 static int cortex_m_target_create(struct target *target, Jim_Interp *interp)
2266 {
2267 struct cortex_m_common *cortex_m = calloc(1, sizeof(struct cortex_m_common));
2268 cortex_m->common_magic = CORTEX_M_COMMON_MAGIC;
2269 struct adiv5_private_config *pc;
2270
2271 pc = (struct adiv5_private_config *)target->private_config;
2272 if (adiv5_verify_config(pc) != ERROR_OK)
2273 return ERROR_FAIL;
2274
2275 cortex_m->apsel = pc->ap_num;
2276
2277 cortex_m_init_arch_info(target, cortex_m, pc->dap);
2278
2279 return ERROR_OK;
2280 }
2281
2282 /*--------------------------------------------------------------------------*/
2283
2284 static int cortex_m_verify_pointer(struct command_context *cmd_ctx,
2285 struct cortex_m_common *cm)
2286 {
2287 if (cm->common_magic != CORTEX_M_COMMON_MAGIC) {
2288 command_print(cmd_ctx, "target is not a Cortex-M");
2289 return ERROR_TARGET_INVALID;
2290 }
2291 return ERROR_OK;
2292 }
2293
2294 /*
2295 * Only stuff below this line should need to verify that its target
2296 * is a Cortex-M3. Everything else should have indirected through the
2297 * cortexm3_target structure, which is only used with CM3 targets.
2298 */
2299
2300 static const struct {
2301 char name[10];
2302 unsigned mask;
2303 } vec_ids[] = {
2304 { "hard_err", VC_HARDERR, },
2305 { "int_err", VC_INTERR, },
2306 { "bus_err", VC_BUSERR, },
2307 { "state_err", VC_STATERR, },
2308 { "chk_err", VC_CHKERR, },
2309 { "nocp_err", VC_NOCPERR, },
2310 { "mm_err", VC_MMERR, },
2311 { "reset", VC_CORERESET, },
2312 };
2313
2314 COMMAND_HANDLER(handle_cortex_m_vector_catch_command)
2315 {
2316 struct target *target = get_current_target(CMD_CTX);
2317 struct cortex_m_common *cortex_m = target_to_cm(target);
2318 struct armv7m_common *armv7m = &cortex_m->armv7m;
2319 uint32_t demcr = 0;
2320 int retval;
2321
2322 retval = cortex_m_verify_pointer(CMD_CTX, cortex_m);
2323 if (retval != ERROR_OK)
2324 return retval;
2325
2326 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);
2327 if (retval != ERROR_OK)
2328 return retval;
2329
2330 if (CMD_ARGC > 0) {
2331 unsigned catch = 0;
2332
2333 if (CMD_ARGC == 1) {
2334 if (strcmp(CMD_ARGV[0], "all") == 0) {
2335 catch = VC_HARDERR | VC_INTERR | VC_BUSERR
2336 | VC_STATERR | VC_CHKERR | VC_NOCPERR
2337 | VC_MMERR | VC_CORERESET;
2338 goto write;
2339 } else if (strcmp(CMD_ARGV[0], "none") == 0)
2340 goto write;
2341 }
2342 while (CMD_ARGC-- > 0) {
2343 unsigned i;
2344 for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
2345 if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name) != 0)
2346 continue;
2347 catch |= vec_ids[i].mask;
2348 break;
2349 }
2350 if (i == ARRAY_SIZE(vec_ids)) {
2351 LOG_ERROR("No CM3 vector '%s'", CMD_ARGV[CMD_ARGC]);
2352 return ERROR_COMMAND_SYNTAX_ERROR;
2353 }
2354 }
2355 write:
2356 /* For now, armv7m->demcr only stores vector catch flags. */
2357 armv7m->demcr = catch;
2358
2359 demcr &= ~0xffff;
2360 demcr |= catch;
2361
2362 /* write, but don't assume it stuck (why not??) */
2363 retval = mem_ap_write_u32(armv7m->debug_ap, DCB_DEMCR, demcr);
2364 if (retval != ERROR_OK)
2365 return retval;
2366 retval = mem_ap_read_atomic_u32(armv7m->debug_ap, DCB_DEMCR, &demcr);
2367 if (retval != ERROR_OK)
2368 return retval;
2369
2370 /* FIXME be sure to clear DEMCR on clean server shutdown.
2371 * Otherwise the vector catch hardware could fire when there's
2372 * no debugger hooked up, causing much confusion...
2373 */
2374 }
2375
2376 for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) {
2377 command_print(CMD_CTX, "%9s: %s", vec_ids[i].name,
2378 (demcr & vec_ids[i].mask) ? "catch" : "ignore");
2379 }
2380
2381 return ERROR_OK;
2382 }
2383
2384 COMMAND_HANDLER(handle_cortex_m_mask_interrupts_command)
2385 {
2386 struct target *target = get_current_target(CMD_CTX);
2387 struct cortex_m_common *cortex_m = target_to_cm(target);
2388 int retval;
2389
2390 static const Jim_Nvp nvp_maskisr_modes[] = {
2391 { .name = "auto", .value = CORTEX_M_ISRMASK_AUTO },
2392 { .name = "off", .value = CORTEX_M_ISRMASK_OFF },
2393 { .name = "on", .value = CORTEX_M_ISRMASK_ON },
2394 { .name = NULL, .value = -1 },
2395 };
2396 const Jim_Nvp *n;
2397
2398
2399 retval = cortex_m_verify_pointer(CMD_CTX, cortex_m);
2400 if (retval != ERROR_OK)
2401 return retval;
2402
2403 if (target->state != TARGET_HALTED) {
2404 command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
2405 return ERROR_OK;
2406 }
2407
2408 if (CMD_ARGC > 0) {
2409 n = Jim_Nvp_name2value_simple(nvp_maskisr_modes, CMD_ARGV[0]);
2410 if (n->name == NULL)
2411 return ERROR_COMMAND_SYNTAX_ERROR;
2412 cortex_m->isrmasking_mode = n->value;
2413
2414
2415 if (cortex_m->isrmasking_mode == CORTEX_M_ISRMASK_ON)
2416 cortex_m_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
2417 else
2418 cortex_m_write_debug_halt_mask(target, C_HALT, C_MASKINTS);
2419 }
2420
2421 n = Jim_Nvp_value2name_simple(nvp_maskisr_modes, cortex_m->isrmasking_mode);
2422 command_print(CMD_CTX, "cortex_m interrupt mask %s", n->name);
2423
2424 return ERROR_OK;
2425 }
2426
2427 COMMAND_HANDLER(handle_cortex_m_reset_config_command)
2428 {
2429 struct target *target = get_current_target(CMD_CTX);
2430 struct cortex_m_common *cortex_m = target_to_cm(target);
2431 int retval;
2432 char *reset_config;
2433
2434 retval = cortex_m_verify_pointer(CMD_CTX, cortex_m);
2435 if (retval != ERROR_OK)
2436 return retval;
2437
2438 if (CMD_ARGC > 0) {
2439 if (strcmp(*CMD_ARGV, "sysresetreq") == 0)
2440 cortex_m->soft_reset_config = CORTEX_M_RESET_SYSRESETREQ;
2441 else if (strcmp(*CMD_ARGV, "vectreset") == 0)
2442 cortex_m->soft_reset_config = CORTEX_M_RESET_VECTRESET;
2443 }
2444
2445 switch (cortex_m->soft_reset_config) {
2446 case CORTEX_M_RESET_SYSRESETREQ:
2447 reset_config = "sysresetreq";
2448 break;
2449
2450 case CORTEX_M_RESET_VECTRESET:
2451 reset_config = "vectreset";
2452 break;
2453
2454 default:
2455 reset_config = "unknown";
2456 break;
2457 }
2458
2459 command_print(CMD_CTX, "cortex_m reset_config %s", reset_config);
2460
2461 return ERROR_OK;
2462 }
2463
2464 static const struct command_registration cortex_m_exec_command_handlers[] = {
2465 {
2466 .name = "maskisr",
2467 .handler = handle_cortex_m_mask_interrupts_command,
2468 .mode = COMMAND_EXEC,
2469 .help = "mask cortex_m interrupts",
2470 .usage = "['auto'|'on'|'off']",
2471 },
2472 {
2473 .name = "vector_catch",
2474 .handler = handle_cortex_m_vector_catch_command,
2475 .mode = COMMAND_EXEC,
2476 .help = "configure hardware vectors to trigger debug entry",
2477 .usage = "['all'|'none'|('bus_err'|'chk_err'|...)*]",
2478 },
2479 {
2480 .name = "reset_config",
2481 .handler = handle_cortex_m_reset_config_command,
2482 .mode = COMMAND_ANY,
2483 .help = "configure software reset handling",
2484 .usage = "['srst'|'sysresetreq'|'vectreset']",
2485 },
2486 COMMAND_REGISTRATION_DONE
2487 };
2488 static const struct command_registration cortex_m_command_handlers[] = {
2489 {
2490 .chain = armv7m_command_handlers,
2491 },
2492 {
2493 .chain = armv7m_trace_command_handlers,
2494 },
2495 {
2496 .name = "cortex_m",
2497 .mode = COMMAND_EXEC,
2498 .help = "Cortex-M command group",
2499 .usage = "",
2500 .chain = cortex_m_exec_command_handlers,
2501 },
2502 COMMAND_REGISTRATION_DONE
2503 };
2504
2505 struct target_type cortexm_target = {
2506 .name = "cortex_m",
2507 .deprecated_name = "cortex_m3",
2508
2509 .poll = cortex_m_poll,
2510 .arch_state = armv7m_arch_state,
2511
2512 .target_request_data = cortex_m_target_request_data,
2513
2514 .halt = cortex_m_halt,
2515 .resume = cortex_m_resume,
2516 .step = cortex_m_step,
2517
2518 .assert_reset = cortex_m_assert_reset,
2519 .deassert_reset = cortex_m_deassert_reset,
2520 .soft_reset_halt = cortex_m_soft_reset_halt,
2521
2522 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
2523
2524 .read_memory = cortex_m_read_memory,
2525 .write_memory = cortex_m_write_memory,
2526 .checksum_memory = armv7m_checksum_memory,
2527 .blank_check_memory = armv7m_blank_check_memory,
2528
2529 .run_algorithm = armv7m_run_algorithm,
2530 .start_algorithm = armv7m_start_algorithm,
2531 .wait_algorithm = armv7m_wait_algorithm,
2532
2533 .add_breakpoint = cortex_m_add_breakpoint,
2534 .remove_breakpoint = cortex_m_remove_breakpoint,
2535 .add_watchpoint = cortex_m_add_watchpoint,
2536 .remove_watchpoint = cortex_m_remove_watchpoint,
2537
2538 .commands = cortex_m_command_handlers,
2539 .target_create = cortex_m_target_create,
2540 .target_jim_configure = adiv5_jim_configure,
2541 .init_target = cortex_m_init_target,
2542 .examine = cortex_m_examine,
2543 .deinit_target = cortex_m_deinit_target,
2544
2545 .profiling = cortex_m_profiling,
2546 };

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)