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

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)