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

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)