debug interface: get rid of unused pre_debug fn
[openocd.git] / src / target / cortex_m3.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2006 by Magnus Lundin *
6 * lundin@mlu.mine.nu *
7 * *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 * *
26 * *
27 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
28 * *
29 ***************************************************************************/
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include "cortex_m3.h"
35 #include "target_request.h"
36 #include "target_type.h"
37 #include "arm_disassembler.h"
38
39
40 #define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof((x)[0])))
41
42
43 /* forward declarations */
44 static int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
45 static int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint);
46 static void cortex_m3_enable_watchpoints(struct target_s *target);
47 static int cortex_m3_store_core_reg_u32(target_t *target,
48 enum armv7m_regtype type, uint32_t num, uint32_t value);
49
50 #ifdef ARMV7_GDB_HACKS
51 extern uint8_t armv7m_gdb_dummy_cpsr_value[];
52 extern reg_t armv7m_gdb_dummy_cpsr_reg;
53 #endif
54
55 static int cortexm3_dap_read_coreregister_u32(swjdp_common_t *swjdp,
56 uint32_t *value, int regnum)
57 {
58 int retval;
59 uint32_t dcrdr;
60
61 /* because the DCB_DCRDR is used for the emulated dcc channel
62 * we have to save/restore the DCB_DCRDR when used */
63
64 mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
65
66 swjdp->trans_mode = TRANS_MODE_COMPOSITE;
67
68 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
69 dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
70 dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum);
71
72 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
73 dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
74 dap_ap_read_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
75
76 retval = swjdp_transaction_endcheck(swjdp);
77
78 /* restore DCB_DCRDR - this needs to be in a seperate
79 * transaction otherwise the emulated DCC channel breaks */
80 if (retval == ERROR_OK)
81 retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
82
83 return retval;
84 }
85
86 static int cortexm3_dap_write_coreregister_u32(swjdp_common_t *swjdp,
87 uint32_t value, int regnum)
88 {
89 int retval;
90 uint32_t dcrdr;
91
92 /* because the DCB_DCRDR is used for the emulated dcc channel
93 * we have to save/restore the DCB_DCRDR when used */
94
95 mem_ap_read_u32(swjdp, DCB_DCRDR, &dcrdr);
96
97 swjdp->trans_mode = TRANS_MODE_COMPOSITE;
98
99 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
100 dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRDR & 0xFFFFFFF0);
101 dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRDR & 0xC), value);
102
103 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
104 dap_setup_accessport(swjdp, CSW_32BIT | CSW_ADDRINC_OFF, DCB_DCRSR & 0xFFFFFFF0);
105 dap_ap_write_reg_u32(swjdp, AP_REG_BD0 | (DCB_DCRSR & 0xC), regnum | DCRSR_WnR);
106
107 retval = swjdp_transaction_endcheck(swjdp);
108
109 /* restore DCB_DCRDR - this needs to be in a seperate
110 * transaction otherwise the emulated DCC channel breaks */
111 if (retval == ERROR_OK)
112 retval = mem_ap_write_atomic_u32(swjdp, DCB_DCRDR, dcrdr);
113
114 return retval;
115 }
116
117 static int cortex_m3_write_debug_halt_mask(target_t *target,
118 uint32_t mask_on, uint32_t mask_off)
119 {
120 /* get pointers to arch-specific information */
121 armv7m_common_t *armv7m = target->arch_info;
122 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
123 swjdp_common_t *swjdp = &armv7m->swjdp_info;
124
125 /* mask off status bits */
126 cortex_m3->dcb_dhcsr &= ~((0xFFFF << 16) | mask_off);
127 /* create new register mask */
128 cortex_m3->dcb_dhcsr |= DBGKEY | C_DEBUGEN | mask_on;
129
130 return mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, cortex_m3->dcb_dhcsr);
131 }
132
133 static int cortex_m3_clear_halt(target_t *target)
134 {
135 /* get pointers to arch-specific information */
136 armv7m_common_t *armv7m = target->arch_info;
137 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
138 swjdp_common_t *swjdp = &armv7m->swjdp_info;
139
140 /* clear step if any */
141 cortex_m3_write_debug_halt_mask(target, C_HALT, C_STEP);
142
143 /* Read Debug Fault Status Register */
144 mem_ap_read_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
145 /* Clear Debug Fault Status */
146 mem_ap_write_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
147 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32 "", cortex_m3->nvic_dfsr);
148
149 return ERROR_OK;
150 }
151
152 static int cortex_m3_single_step_core(target_t *target)
153 {
154 /* get pointers to arch-specific information */
155 armv7m_common_t *armv7m = target->arch_info;
156 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
157 swjdp_common_t *swjdp = &armv7m->swjdp_info;
158 uint32_t dhcsr_save;
159
160 /* backup dhcsr reg */
161 dhcsr_save = cortex_m3->dcb_dhcsr;
162
163 /* mask interrupts if not done already */
164 if (!(cortex_m3->dcb_dhcsr & C_MASKINTS))
165 mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN);
166 mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN);
167 LOG_DEBUG(" ");
168
169 /* restore dhcsr reg */
170 cortex_m3->dcb_dhcsr = dhcsr_save;
171 cortex_m3_clear_halt(target);
172
173 return ERROR_OK;
174 }
175
176 static int cortex_m3_endreset_event(target_t *target)
177 {
178 int i;
179 uint32_t dcb_demcr;
180
181 /* get pointers to arch-specific information */
182 armv7m_common_t *armv7m = target->arch_info;
183 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
184 swjdp_common_t *swjdp = &armv7m->swjdp_info;
185 cortex_m3_fp_comparator_t *fp_list = cortex_m3->fp_comparator_list;
186 cortex_m3_dwt_comparator_t *dwt_list = cortex_m3->dwt_comparator_list;
187
188 mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &dcb_demcr);
189 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32 "",dcb_demcr);
190
191 /* this regsiter is used for emulated dcc channel */
192 mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
193
194 /* Enable debug requests */
195 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
196 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
197 mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
198
199 /* clear any interrupt masking */
200 cortex_m3_write_debug_halt_mask(target, 0, C_MASKINTS);
201
202 /* Enable trace and dwt */
203 mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
204 /* Monitor bus faults */
205 mem_ap_write_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA);
206
207 /* Enable FPB */
208 target_write_u32(target, FP_CTRL, 3);
209 cortex_m3->fpb_enabled = 1;
210
211 /* Restore FPB registers */
212 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
213 {
214 target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
215 }
216
217 /* Restore DWT registers */
218 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
219 {
220 target_write_u32(target, dwt_list[i].dwt_comparator_address, dwt_list[i].comp);
221 target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x4, dwt_list[i].mask);
222 target_write_u32(target, dwt_list[i].dwt_comparator_address | 0x8, dwt_list[i].function);
223 }
224 swjdp_transaction_endcheck(swjdp);
225
226 armv7m_invalidate_core_regs(target);
227
228 /* make sure we have latest dhcsr flags */
229 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
230
231 return ERROR_OK;
232 }
233
234 static int cortex_m3_examine_debug_reason(target_t *target)
235 {
236 /* get pointers to arch-specific information */
237 armv7m_common_t *armv7m = target->arch_info;
238 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
239
240 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
241 /* only check the debug reason if we don't know it already */
242
243 if ((target->debug_reason != DBG_REASON_DBGRQ)
244 && (target->debug_reason != DBG_REASON_SINGLESTEP))
245 {
246 if (cortex_m3->nvic_dfsr & DFSR_BKPT)
247 {
248 target->debug_reason = DBG_REASON_BREAKPOINT;
249 if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
250 target->debug_reason = DBG_REASON_WPTANDBKPT;
251 }
252 else if (cortex_m3->nvic_dfsr & DFSR_DWTTRAP)
253 target->debug_reason = DBG_REASON_WATCHPOINT;
254 else if (cortex_m3->nvic_dfsr & DFSR_VCATCH)
255 target->debug_reason = DBG_REASON_BREAKPOINT;
256 else /* EXTERNAL, HALTED, DWTTRAP w/o BKPT */
257 target->debug_reason = DBG_REASON_UNDEFINED;
258 }
259
260 return ERROR_OK;
261 }
262
263 static int cortex_m3_examine_exception_reason(target_t *target)
264 {
265 uint32_t shcsr, except_sr, cfsr = -1, except_ar = -1;
266
267 /* get pointers to arch-specific information */
268 armv7m_common_t *armv7m = target->arch_info;
269 swjdp_common_t *swjdp = &armv7m->swjdp_info;
270
271 mem_ap_read_u32(swjdp, NVIC_SHCSR, &shcsr);
272 switch (armv7m->exception_number)
273 {
274 case 2: /* NMI */
275 break;
276 case 3: /* Hard Fault */
277 mem_ap_read_atomic_u32(swjdp, NVIC_HFSR, &except_sr);
278 if (except_sr & 0x40000000)
279 {
280 mem_ap_read_u32(swjdp, NVIC_CFSR, &cfsr);
281 }
282 break;
283 case 4: /* Memory Management */
284 mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
285 mem_ap_read_u32(swjdp, NVIC_MMFAR, &except_ar);
286 break;
287 case 5: /* Bus Fault */
288 mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
289 mem_ap_read_u32(swjdp, NVIC_BFAR, &except_ar);
290 break;
291 case 6: /* Usage Fault */
292 mem_ap_read_u32(swjdp, NVIC_CFSR, &except_sr);
293 break;
294 case 11: /* SVCall */
295 break;
296 case 12: /* Debug Monitor */
297 mem_ap_read_u32(swjdp, NVIC_DFSR, &except_sr);
298 break;
299 case 14: /* PendSV */
300 break;
301 case 15: /* SysTick */
302 break;
303 default:
304 except_sr = 0;
305 break;
306 }
307 swjdp_transaction_endcheck(swjdp);
308 LOG_DEBUG("%s SHCSR 0x%" PRIx32 ", SR 0x%" PRIx32 ", CFSR 0x%" PRIx32 ", AR 0x%" PRIx32 "", armv7m_exception_string(armv7m->exception_number), \
309 shcsr, except_sr, cfsr, except_ar);
310 return ERROR_OK;
311 }
312
313 static int cortex_m3_debug_entry(target_t *target)
314 {
315 int i;
316 uint32_t xPSR;
317 int retval;
318
319 /* get pointers to arch-specific information */
320 armv7m_common_t *armv7m = target->arch_info;
321 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
322 swjdp_common_t *swjdp = &armv7m->swjdp_info;
323
324 LOG_DEBUG(" ");
325
326 cortex_m3_clear_halt(target);
327 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
328
329 if ((retval = armv7m->examine_debug_reason(target)) != ERROR_OK)
330 return retval;
331
332 /* Examine target state and mode */
333 /* First load register acessible through core debug port*/
334 int num_regs = armv7m->core_cache->num_regs;
335
336 for (i = 0; i < num_regs; i++)
337 {
338 if (!armv7m->core_cache->reg_list[i].valid)
339 armv7m->read_core_reg(target, i);
340 }
341
342 xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
343
344 #ifdef ARMV7_GDB_HACKS
345 /* copy real xpsr reg for gdb, setting thumb bit */
346 buf_set_u32(armv7m_gdb_dummy_cpsr_value, 0, 32, xPSR);
347 buf_set_u32(armv7m_gdb_dummy_cpsr_value, 5, 1, 1);
348 armv7m_gdb_dummy_cpsr_reg.valid = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid;
349 armv7m_gdb_dummy_cpsr_reg.dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty;
350 #endif
351
352 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
353 if (xPSR & 0xf00)
354 {
355 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = armv7m->core_cache->reg_list[ARMV7M_xPSR].valid;
356 cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff);
357 }
358
359 /* Are we in an exception handler */
360 if (xPSR & 0x1FF)
361 {
362 armv7m->core_mode = ARMV7M_MODE_HANDLER;
363 armv7m->exception_number = (xPSR & 0x1FF);
364 }
365 else
366 {
367 armv7m->core_mode = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1);
368 armv7m->exception_number = 0;
369 }
370
371 if (armv7m->exception_number)
372 {
373 cortex_m3_examine_exception_reason(target);
374 }
375
376 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s",
377 armv7m_mode_strings[armv7m->core_mode],
378 *(uint32_t*)(armv7m->core_cache->reg_list[15].value),
379 target_state_name(target));
380
381 if (armv7m->post_debug_entry)
382 armv7m->post_debug_entry(target);
383
384 return ERROR_OK;
385 }
386
387 static int cortex_m3_poll(target_t *target)
388 {
389 int retval;
390 enum target_state prev_target_state = target->state;
391
392 /* get pointers to arch-specific information */
393 armv7m_common_t *armv7m = target->arch_info;
394 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
395 swjdp_common_t *swjdp = &armv7m->swjdp_info;
396
397 /* Read from Debug Halting Control and Status Register */
398 retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
399 if (retval != ERROR_OK)
400 {
401 target->state = TARGET_UNKNOWN;
402 return retval;
403 }
404
405 if (cortex_m3->dcb_dhcsr & S_RESET_ST)
406 {
407 /* check if still in reset */
408 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
409
410 if (cortex_m3->dcb_dhcsr & S_RESET_ST)
411 {
412 target->state = TARGET_RESET;
413 return ERROR_OK;
414 }
415 }
416
417 if (target->state == TARGET_RESET)
418 {
419 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
420 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32 "", cortex_m3->dcb_dhcsr);
421 cortex_m3_endreset_event(target);
422 target->state = TARGET_RUNNING;
423 prev_target_state = TARGET_RUNNING;
424 }
425
426 if (cortex_m3->dcb_dhcsr & S_HALT)
427 {
428 target->state = TARGET_HALTED;
429
430 if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET))
431 {
432 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
433 return retval;
434
435 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
436 }
437 if (prev_target_state == TARGET_DEBUG_RUNNING)
438 {
439 LOG_DEBUG(" ");
440 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
441 return retval;
442
443 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
444 }
445 }
446
447 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
448 * How best to model low power modes?
449 */
450
451 if (target->state == TARGET_UNKNOWN)
452 {
453 /* check if processor is retiring instructions */
454 if (cortex_m3->dcb_dhcsr & S_RETIRE_ST)
455 {
456 target->state = TARGET_RUNNING;
457 return ERROR_OK;
458 }
459 }
460
461 return ERROR_OK;
462 }
463
464 static int cortex_m3_halt(target_t *target)
465 {
466 LOG_DEBUG("target->state: %s",
467 target_state_name(target));
468
469 if (target->state == TARGET_HALTED)
470 {
471 LOG_DEBUG("target was already halted");
472 return ERROR_OK;
473 }
474
475 if (target->state == TARGET_UNKNOWN)
476 {
477 LOG_WARNING("target was in unknown state when halt was requested");
478 }
479
480 if (target->state == TARGET_RESET)
481 {
482 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
483 {
484 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
485 return ERROR_TARGET_FAILURE;
486 }
487 else
488 {
489 /* we came here in a reset_halt or reset_init sequence
490 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
491 */
492 target->debug_reason = DBG_REASON_DBGRQ;
493
494 return ERROR_OK;
495 }
496 }
497
498 /* Write to Debug Halting Control and Status Register */
499 cortex_m3_write_debug_halt_mask(target, C_HALT, 0);
500
501 target->debug_reason = DBG_REASON_DBGRQ;
502
503 return ERROR_OK;
504 }
505
506 static int cortex_m3_soft_reset_halt(struct target_s *target)
507 {
508 /* get pointers to arch-specific information */
509 armv7m_common_t *armv7m = target->arch_info;
510 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
511 swjdp_common_t *swjdp = &armv7m->swjdp_info;
512 uint32_t dcb_dhcsr = 0;
513 int retval, timeout = 0;
514
515 /* Enter debug state on reset, cf. end_reset_event() */
516 mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
517
518 /* Request a reset */
519 mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET);
520 target->state = TARGET_RESET;
521
522 /* registers are now invalid */
523 armv7m_invalidate_core_regs(target);
524
525 while (timeout < 100)
526 {
527 retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
528 if (retval == ERROR_OK)
529 {
530 mem_ap_read_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
531 if ((dcb_dhcsr & S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
532 {
533 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32 ", nvic_dfsr 0x%" PRIx32 "", dcb_dhcsr, cortex_m3->nvic_dfsr);
534 cortex_m3_poll(target);
535 return ERROR_OK;
536 }
537 else
538 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32 ", %i ms", dcb_dhcsr, timeout);
539 }
540 timeout++;
541 alive_sleep(1);
542 }
543
544 return ERROR_OK;
545 }
546
547 static void cortex_m3_enable_breakpoints(struct target_s *target)
548 {
549 breakpoint_t *breakpoint = target->breakpoints;
550
551 /* set any pending breakpoints */
552 while (breakpoint)
553 {
554 if (breakpoint->set == 0)
555 cortex_m3_set_breakpoint(target, breakpoint);
556 breakpoint = breakpoint->next;
557 }
558 }
559
560 static int cortex_m3_resume(struct target_s *target, int current,
561 uint32_t address, int handle_breakpoints, int debug_execution)
562 {
563 /* get pointers to arch-specific information */
564 armv7m_common_t *armv7m = target->arch_info;
565 breakpoint_t *breakpoint = NULL;
566 uint32_t resume_pc;
567
568 if (target->state != TARGET_HALTED)
569 {
570 LOG_WARNING("target not halted");
571 return ERROR_TARGET_NOT_HALTED;
572 }
573
574 if (!debug_execution)
575 {
576 target_free_all_working_areas(target);
577 cortex_m3_enable_breakpoints(target);
578 cortex_m3_enable_watchpoints(target);
579 }
580
581 if (debug_execution)
582 {
583 /* Disable interrupts */
584 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
585 * This is probably the same issue as Cortex-M3 Errata 377493:
586 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
587 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
588 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1;
589 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1;
590
591 /* Make sure we are in Thumb mode */
592 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
593 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1 << 24));
594 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
595 armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1;
596 }
597
598 /* current = 1: continue on current pc, otherwise continue at <address> */
599 if (!current)
600 {
601 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
602 armv7m->core_cache->reg_list[15].dirty = 1;
603 armv7m->core_cache->reg_list[15].valid = 1;
604 }
605
606 resume_pc = buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32);
607
608 armv7m_restore_context(target);
609
610 /* the front-end may request us not to handle breakpoints */
611 if (handle_breakpoints)
612 {
613 /* Single step past breakpoint at current address */
614 if ((breakpoint = breakpoint_find(target, resume_pc)))
615 {
616 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
617 breakpoint->address,
618 breakpoint->unique_id );
619 cortex_m3_unset_breakpoint(target, breakpoint);
620 cortex_m3_single_step_core(target);
621 cortex_m3_set_breakpoint(target, breakpoint);
622 }
623 }
624
625 /* Restart core */
626 cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
627
628 target->debug_reason = DBG_REASON_NOTHALTED;
629
630 /* registers are now invalid */
631 armv7m_invalidate_core_regs(target);
632 if (!debug_execution)
633 {
634 target->state = TARGET_RUNNING;
635 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
636 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
637 }
638 else
639 {
640 target->state = TARGET_DEBUG_RUNNING;
641 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
642 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
643 }
644
645 return ERROR_OK;
646 }
647
648 /* int irqstepcount = 0; */
649 static int cortex_m3_step(struct target_s *target, int current,
650 uint32_t address, int handle_breakpoints)
651 {
652 /* get pointers to arch-specific information */
653 armv7m_common_t *armv7m = target->arch_info;
654 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
655 swjdp_common_t *swjdp = &armv7m->swjdp_info;
656 breakpoint_t *breakpoint = NULL;
657
658 if (target->state != TARGET_HALTED)
659 {
660 LOG_WARNING("target not halted");
661 return ERROR_TARGET_NOT_HALTED;
662 }
663
664 /* current = 1: continue on current pc, otherwise continue at <address> */
665 if (!current)
666 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
667
668 /* the front-end may request us not to handle breakpoints */
669 if (handle_breakpoints)
670 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32))))
671 cortex_m3_unset_breakpoint(target, breakpoint);
672
673 target->debug_reason = DBG_REASON_SINGLESTEP;
674
675 armv7m_restore_context(target);
676
677 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
678
679 /* set step and clear halt */
680 cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
681 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
682
683 /* registers are now invalid */
684 armv7m_invalidate_core_regs(target);
685
686 if (breakpoint)
687 cortex_m3_set_breakpoint(target, breakpoint);
688
689 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32 " nvic_icsr = 0x%" PRIx32 "", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
690
691 cortex_m3_debug_entry(target);
692 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
693
694 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32 " nvic_icsr = 0x%" PRIx32 "", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
695 return ERROR_OK;
696 }
697
698 static int cortex_m3_assert_reset(target_t *target)
699 {
700 armv7m_common_t *armv7m = target->arch_info;
701 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
702 swjdp_common_t *swjdp = &armv7m->swjdp_info;
703 int assert_srst = 1;
704
705 LOG_DEBUG("target->state: %s",
706 target_state_name(target));
707
708 enum reset_types jtag_reset_config = jtag_get_reset_config();
709
710 /*
711 * We can reset Cortex-M3 targets using just the NVIC without
712 * requiring SRST, getting a SoC reset (or a core-only reset)
713 * instead of a system reset.
714 */
715 if (!(jtag_reset_config & RESET_HAS_SRST))
716 assert_srst = 0;
717
718 /* Enable debug requests */
719 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
720 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
721 mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
722
723 mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
724
725 if (!target->reset_halt)
726 {
727 /* Set/Clear C_MASKINTS in a separate operation */
728 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
729 mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT);
730
731 /* clear any debug flags before resuming */
732 cortex_m3_clear_halt(target);
733
734 /* clear C_HALT in dhcsr reg */
735 cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
736
737 /* Enter debug state on reset, cf. end_reset_event() */
738 mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
739 }
740 else
741 {
742 /* Enter debug state on reset, cf. end_reset_event() */
743 mem_ap_write_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
744 }
745
746 /*
747 * When nRST is asserted on most Stellaris devices, it clears some of
748 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
749 * and OpenOCD depends on those TRMs. So we won't use SRST on those
750 * chips. (Only power-on reset should affect debug state, beyond a
751 * few specified bits; not the chip's nRST input, wired to SRST.)
752 *
753 * REVISIT current errata specs don't seem to cover this issue.
754 * Do we have more details than this email?
755 * https://lists.berlios.de/pipermail
756 * /openocd-development/2008-August/003065.html
757 */
758 if (strcmp(target->variant, "lm3s") == 0)
759 {
760 /* Check for silicon revisions with the issue. */
761 uint32_t did0;
762
763 if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
764 {
765 switch ((did0 >> 16) & 0xff)
766 {
767 case 0:
768 /* all Sandstorm suffer issue */
769 assert_srst = 0;
770 break;
771
772 case 1:
773 case 3:
774 /* Fury and DustDevil rev A have
775 * this nRST problem. It should
776 * be fixed in rev B silicon.
777 */
778 if (((did0 >> 8) & 0xff) == 0)
779 assert_srst = 0;
780 break;
781 case 4:
782 /* Tempest should be fine. */
783 break;
784 }
785 }
786 }
787
788 if (assert_srst)
789 {
790 /* default to asserting srst */
791 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
792 {
793 jtag_add_reset(1, 1);
794 }
795 else
796 {
797 jtag_add_reset(0, 1);
798 }
799 }
800 else
801 {
802 /* Use a standard Cortex-M3 software reset mechanism.
803 * SYSRESETREQ will reset SoC peripherals outside the
804 * core, like watchdog timers, if the SoC wires it up
805 * correctly. Else VECRESET can reset just the core.
806 */
807 mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
808 AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
809 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
810
811 {
812 /* I do not know why this is necessary, but it
813 * fixes strange effects (step/resume cause NMI
814 * after reset) on LM3S6918 -- Michael Schwingen
815 */
816 uint32_t tmp;
817 mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp);
818 }
819 }
820
821 target->state = TARGET_RESET;
822 jtag_add_sleep(50000);
823
824 armv7m_invalidate_core_regs(target);
825
826 if (target->reset_halt)
827 {
828 int retval;
829 if ((retval = target_halt(target)) != ERROR_OK)
830 return retval;
831 }
832
833 return ERROR_OK;
834 }
835
836 static int cortex_m3_deassert_reset(target_t *target)
837 {
838 LOG_DEBUG("target->state: %s",
839 target_state_name(target));
840
841 /* deassert reset lines */
842 jtag_add_reset(0, 0);
843
844 return ERROR_OK;
845 }
846
847 static int
848 cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
849 {
850 int retval;
851 int fp_num = 0;
852 uint32_t hilo;
853
854 /* get pointers to arch-specific information */
855 armv7m_common_t *armv7m = target->arch_info;
856 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
857
858 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
859
860 if (breakpoint->set)
861 {
862 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint->unique_id);
863 return ERROR_OK;
864 }
865
866 if (cortex_m3->auto_bp_type)
867 {
868 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
869 }
870
871 if (breakpoint->type == BKPT_HARD)
872 {
873 while (comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
874 fp_num++;
875 if (fp_num >= cortex_m3->fp_num_code)
876 {
877 LOG_DEBUG("ERROR Can not find free FP Comparator");
878 LOG_WARNING("ERROR Can not find free FP Comparator");
879 exit(-1);
880 }
881 breakpoint->set = fp_num + 1;
882 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
883 comparator_list[fp_num].used = 1;
884 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
885 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
886 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "", fp_num, comparator_list[fp_num].fpcr_value);
887 if (!cortex_m3->fpb_enabled)
888 {
889 LOG_DEBUG("FPB wasn't enabled, do it now");
890 target_write_u32(target, FP_CTRL, 3);
891 }
892 }
893 else if (breakpoint->type == BKPT_SOFT)
894 {
895 uint8_t code[4];
896 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
897 if ((retval = target_read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
898 {
899 return retval;
900 }
901 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code)) != ERROR_OK)
902 {
903 return retval;
904 }
905 breakpoint->set = 0x11; /* Any nice value but 0 */
906 }
907
908 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
909 breakpoint->unique_id,
910 (int)(breakpoint->type),
911 breakpoint->address,
912 breakpoint->length,
913 breakpoint->set);
914
915 return ERROR_OK;
916 }
917
918 static int
919 cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
920 {
921 int retval;
922 /* get pointers to arch-specific information */
923 armv7m_common_t *armv7m = target->arch_info;
924 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
925 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
926
927 if (!breakpoint->set)
928 {
929 LOG_WARNING("breakpoint not set");
930 return ERROR_OK;
931 }
932
933 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
934 breakpoint->unique_id,
935 (int)(breakpoint->type),
936 breakpoint->address,
937 breakpoint->length,
938 breakpoint->set);
939
940 if (breakpoint->type == BKPT_HARD)
941 {
942 int fp_num = breakpoint->set - 1;
943 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
944 {
945 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
946 return ERROR_OK;
947 }
948 comparator_list[fp_num].used = 0;
949 comparator_list[fp_num].fpcr_value = 0;
950 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
951 }
952 else
953 {
954 /* restore original instruction (kept in target endianness) */
955 if (breakpoint->length == 4)
956 {
957 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
958 {
959 return retval;
960 }
961 }
962 else
963 {
964 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
965 {
966 return retval;
967 }
968 }
969 }
970 breakpoint->set = 0;
971
972 return ERROR_OK;
973 }
974
975 static int
976 cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
977 {
978 /* get pointers to arch-specific information */
979 armv7m_common_t *armv7m = target->arch_info;
980 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
981
982 if (cortex_m3->auto_bp_type)
983 {
984 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
985 #ifdef ARMV7_GDB_HACKS
986 if (breakpoint->length != 2) {
987 /* XXX Hack: Replace all breakpoints with length != 2 with
988 * a hardware breakpoint. */
989 breakpoint->type = BKPT_HARD;
990 breakpoint->length = 2;
991 }
992 #endif
993 }
994
995 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
996 {
997 LOG_INFO("flash patch comparator requested outside code memory region");
998 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
999 }
1000
1001 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
1002 {
1003 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1004 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1005 }
1006
1007 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
1008 {
1009 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1010 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1011 }
1012
1013 if ((breakpoint->length != 2))
1014 {
1015 LOG_INFO("only breakpoints of two bytes length supported");
1016 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1017 }
1018
1019 if (breakpoint->type == BKPT_HARD)
1020 cortex_m3->fp_code_available--;
1021 cortex_m3_set_breakpoint(target, breakpoint);
1022
1023 return ERROR_OK;
1024 }
1025
1026 static int
1027 cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1028 {
1029 /* get pointers to arch-specific information */
1030 armv7m_common_t *armv7m = target->arch_info;
1031 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1032
1033 if (target->state != TARGET_HALTED)
1034 {
1035 LOG_WARNING("target not halted");
1036 return ERROR_TARGET_NOT_HALTED;
1037 }
1038
1039 if (cortex_m3->auto_bp_type)
1040 {
1041 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
1042 }
1043
1044 if (breakpoint->set)
1045 {
1046 cortex_m3_unset_breakpoint(target, breakpoint);
1047 }
1048
1049 if (breakpoint->type == BKPT_HARD)
1050 cortex_m3->fp_code_available++;
1051
1052 return ERROR_OK;
1053 }
1054
1055 static int
1056 cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1057 {
1058 int dwt_num = 0;
1059 uint32_t mask, temp;
1060
1061 /* get pointers to arch-specific information */
1062 armv7m_common_t *armv7m = target->arch_info;
1063 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1064 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1065
1066 if (watchpoint->set)
1067 {
1068 LOG_WARNING("watchpoint (%d) already set", watchpoint->unique_id );
1069 return ERROR_OK;
1070 }
1071
1072 if (watchpoint->mask == 0xffffffffu)
1073 {
1074 while (comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
1075 dwt_num++;
1076 if (dwt_num >= cortex_m3->dwt_num_comp)
1077 {
1078 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1079 LOG_WARNING("ERROR Can not find free DWT Comparator");
1080 return -1;
1081 }
1082 watchpoint->set = dwt_num + 1;
1083 mask = 0;
1084 temp = watchpoint->length;
1085 while (temp > 1)
1086 {
1087 temp = temp / 2;
1088 mask++;
1089 }
1090 comparator_list[dwt_num].used = 1;
1091 comparator_list[dwt_num].comp = watchpoint->address;
1092 comparator_list[dwt_num].mask = mask;
1093 comparator_list[dwt_num].function = watchpoint->rw + 5;
1094 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
1095 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x4, comparator_list[dwt_num].mask);
1096 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x8, comparator_list[dwt_num].function);
1097 LOG_DEBUG("dwt_num %i 0x%" PRIx32 " 0x%" PRIx32 " 0x%" PRIx32 "", dwt_num, comparator_list[dwt_num].comp, comparator_list[dwt_num].mask, comparator_list[dwt_num].function);
1098 }
1099 else
1100 {
1101 /* Move this test to add_watchpoint */
1102 LOG_WARNING("Cannot watch data values (id: %d)",
1103 watchpoint->unique_id );
1104 return ERROR_OK;
1105 }
1106 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
1107 watchpoint->unique_id, watchpoint->address, watchpoint->set );
1108 return ERROR_OK;
1109
1110 }
1111
1112 static int
1113 cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1114 {
1115 /* get pointers to arch-specific information */
1116 armv7m_common_t *armv7m = target->arch_info;
1117 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1118 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1119 int dwt_num;
1120
1121 if (!watchpoint->set)
1122 {
1123 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint->unique_id );
1124 return ERROR_OK;
1125 }
1126
1127 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
1128 watchpoint->unique_id, watchpoint->address,watchpoint->set );
1129
1130 dwt_num = watchpoint->set - 1;
1131
1132 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1133 {
1134 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1135 return ERROR_OK;
1136 }
1137 comparator_list[dwt_num].used = 0;
1138 comparator_list[dwt_num].function = 0;
1139 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x8, comparator_list[dwt_num].function);
1140
1141 watchpoint->set = 0;
1142
1143 return ERROR_OK;
1144 }
1145
1146 static int
1147 cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1148 {
1149 /* get pointers to arch-specific information */
1150 armv7m_common_t *armv7m = target->arch_info;
1151 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1152
1153 if (target->state != TARGET_HALTED)
1154 {
1155 LOG_WARNING("target not halted");
1156 return ERROR_TARGET_NOT_HALTED;
1157 }
1158
1159 if (cortex_m3->dwt_comp_available < 1)
1160 {
1161 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1162 }
1163
1164 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1165 {
1166 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1167 }
1168
1169 cortex_m3->dwt_comp_available--;
1170 LOG_DEBUG("dwt_comp_available: %d", cortex_m3->dwt_comp_available);
1171
1172 return ERROR_OK;
1173 }
1174
1175 static int
1176 cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1177 {
1178 /* get pointers to arch-specific information */
1179 armv7m_common_t *armv7m = target->arch_info;
1180 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1181
1182 if (target->state != TARGET_HALTED)
1183 {
1184 LOG_WARNING("target not halted");
1185 return ERROR_TARGET_NOT_HALTED;
1186 }
1187
1188 if (watchpoint->set)
1189 {
1190 cortex_m3_unset_watchpoint(target, watchpoint);
1191 }
1192
1193 cortex_m3->dwt_comp_available++;
1194 LOG_DEBUG("dwt_comp_available: %d", cortex_m3->dwt_comp_available);
1195
1196 return ERROR_OK;
1197 }
1198
1199 static void cortex_m3_enable_watchpoints(struct target_s *target)
1200 {
1201 watchpoint_t *watchpoint = target->watchpoints;
1202
1203 /* set any pending watchpoints */
1204 while (watchpoint)
1205 {
1206 if (watchpoint->set == 0)
1207 cortex_m3_set_watchpoint(target, watchpoint);
1208 watchpoint = watchpoint->next;
1209 }
1210 }
1211
1212 static int cortex_m3_load_core_reg_u32(struct target_s *target,
1213 enum armv7m_regtype type, uint32_t num, uint32_t * value)
1214 {
1215 int retval;
1216 /* get pointers to arch-specific information */
1217 armv7m_common_t *armv7m = target->arch_info;
1218 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1219
1220 /* NOTE: we "know" here that the register identifiers used
1221 * in the v7m header match the Cortex-M3 Debug Core Register
1222 * Selector values for R0..R15, xPSR, MSP, and PSP.
1223 */
1224 switch (num) {
1225 case 0 ... 18:
1226 /* read a normal core register */
1227 retval = cortexm3_dap_read_coreregister_u32(swjdp, value, num);
1228
1229 if (retval != ERROR_OK)
1230 {
1231 LOG_ERROR("JTAG failure %i",retval);
1232 return ERROR_JTAG_DEVICE_ERROR;
1233 }
1234 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "",(int)num,*value);
1235 break;
1236
1237 case ARMV7M_PRIMASK:
1238 case ARMV7M_BASEPRI:
1239 case ARMV7M_FAULTMASK:
1240 case ARMV7M_CONTROL:
1241 /* Cortex-M3 packages these four registers as bitfields
1242 * in one Debug Core register. So say r0 and r2 docs;
1243 * it was removed from r1 docs, but still works.
1244 */
1245 cortexm3_dap_read_coreregister_u32(swjdp, value, 20);
1246
1247 switch (num)
1248 {
1249 case ARMV7M_PRIMASK:
1250 *value = buf_get_u32((uint8_t*)value, 0, 1);
1251 break;
1252
1253 case ARMV7M_BASEPRI:
1254 *value = buf_get_u32((uint8_t*)value, 8, 8);
1255 break;
1256
1257 case ARMV7M_FAULTMASK:
1258 *value = buf_get_u32((uint8_t*)value, 16, 1);
1259 break;
1260
1261 case ARMV7M_CONTROL:
1262 *value = buf_get_u32((uint8_t*)value, 24, 2);
1263 break;
1264 }
1265
1266 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", (int)num, *value);
1267 break;
1268
1269 default:
1270 return ERROR_INVALID_ARGUMENTS;
1271 }
1272
1273 return ERROR_OK;
1274 }
1275
1276 static int cortex_m3_store_core_reg_u32(struct target_s *target,
1277 enum armv7m_regtype type, uint32_t num, uint32_t value)
1278 {
1279 int retval;
1280 uint32_t reg;
1281
1282 /* get pointers to arch-specific information */
1283 armv7m_common_t *armv7m = target->arch_info;
1284 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1285
1286 #ifdef ARMV7_GDB_HACKS
1287 /* If the LR register is being modified, make sure it will put us
1288 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1289 * hack to deal with the fact that gdb will sometimes "forge"
1290 * return addresses, and doesn't set the LSB correctly (i.e., when
1291 * printing expressions containing function calls, it sets LR = 0.)
1292 * Valid exception return codes have bit 0 set too.
1293 */
1294 if (num == ARMV7M_R14)
1295 value |= 0x01;
1296 #endif
1297
1298 /* NOTE: we "know" here that the register identifiers used
1299 * in the v7m header match the Cortex-M3 Debug Core Register
1300 * Selector values for R0..R15, xPSR, MSP, and PSP.
1301 */
1302 switch (num) {
1303 case 0 ... 18:
1304 retval = cortexm3_dap_write_coreregister_u32(swjdp, value, num);
1305 if (retval != ERROR_OK)
1306 {
1307 LOG_ERROR("JTAG failure %i", retval);
1308 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1309 return ERROR_JTAG_DEVICE_ERROR;
1310 }
1311 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
1312 break;
1313
1314 case ARMV7M_PRIMASK:
1315 case ARMV7M_BASEPRI:
1316 case ARMV7M_FAULTMASK:
1317 case ARMV7M_CONTROL:
1318 /* Cortex-M3 packages these four registers as bitfields
1319 * in one Debug Core register. So say r0 and r2 docs;
1320 * it was removed from r1 docs, but still works.
1321 */
1322 cortexm3_dap_read_coreregister_u32(swjdp, &reg, 20);
1323
1324 switch (num)
1325 {
1326 case ARMV7M_PRIMASK:
1327 buf_set_u32((uint8_t*)&reg, 0, 1, value);
1328 break;
1329
1330 case ARMV7M_BASEPRI:
1331 buf_set_u32((uint8_t*)&reg, 8, 8, value);
1332 break;
1333
1334 case ARMV7M_FAULTMASK:
1335 buf_set_u32((uint8_t*)&reg, 16, 1, value);
1336 break;
1337
1338 case ARMV7M_CONTROL:
1339 buf_set_u32((uint8_t*)&reg, 24, 2, value);
1340 break;
1341 }
1342
1343 cortexm3_dap_write_coreregister_u32(swjdp, reg, 20);
1344
1345 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
1346 break;
1347
1348 default:
1349 return ERROR_INVALID_ARGUMENTS;
1350 }
1351
1352 return ERROR_OK;
1353 }
1354
1355 static int cortex_m3_read_memory(struct target_s *target, uint32_t address,
1356 uint32_t size, uint32_t count, uint8_t *buffer)
1357 {
1358 /* get pointers to arch-specific information */
1359 armv7m_common_t *armv7m = target->arch_info;
1360 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1361 int retval;
1362
1363 /* sanitize arguments */
1364 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1365 return ERROR_INVALID_ARGUMENTS;
1366
1367 /* cortex_m3 handles unaligned memory access */
1368
1369 switch (size)
1370 {
1371 case 4:
1372 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1373 break;
1374 case 2:
1375 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1376 break;
1377 case 1:
1378 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1379 break;
1380 default:
1381 LOG_ERROR("BUG: we shouldn't get here");
1382 exit(-1);
1383 }
1384
1385 return retval;
1386 }
1387
1388 static int cortex_m3_write_memory(struct target_s *target, uint32_t address,
1389 uint32_t size, uint32_t count, uint8_t *buffer)
1390 {
1391 /* get pointers to arch-specific information */
1392 armv7m_common_t *armv7m = target->arch_info;
1393 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1394 int retval;
1395
1396 /* sanitize arguments */
1397 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1398 return ERROR_INVALID_ARGUMENTS;
1399
1400 switch (size)
1401 {
1402 case 4:
1403 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1404 break;
1405 case 2:
1406 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1407 break;
1408 case 1:
1409 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1410 break;
1411 default:
1412 LOG_ERROR("BUG: we shouldn't get here");
1413 exit(-1);
1414 }
1415
1416 return retval;
1417 }
1418
1419 static int cortex_m3_bulk_write_memory(target_t *target, uint32_t address,
1420 uint32_t count, uint8_t *buffer)
1421 {
1422 return cortex_m3_write_memory(target, address, 4, count, buffer);
1423 }
1424
1425 static void cortex_m3_build_reg_cache(target_t *target)
1426 {
1427 armv7m_build_reg_cache(target);
1428 }
1429
1430 static int cortex_m3_init_target(struct command_context_s *cmd_ctx,
1431 struct target_s *target)
1432 {
1433 cortex_m3_build_reg_cache(target);
1434 return ERROR_OK;
1435 }
1436
1437 static int cortex_m3_examine(struct target_s *target)
1438 {
1439 int retval;
1440 uint32_t cpuid, fpcr, dwtcr, ictr;
1441 int i;
1442
1443 /* get pointers to arch-specific information */
1444 armv7m_common_t *armv7m = target->arch_info;
1445 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1446 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1447
1448 if ((retval = ahbap_debugport_init(swjdp)) != ERROR_OK)
1449 return retval;
1450
1451 if (!target_was_examined(target))
1452 {
1453 target_set_examined(target);
1454
1455 /* Read from Device Identification Registers */
1456 if ((retval = target_read_u32(target, CPUID, &cpuid)) != ERROR_OK)
1457 return retval;
1458
1459 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1460 LOG_DEBUG("CORTEX-M3 processor detected");
1461 LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
1462
1463 target_read_u32(target, NVIC_ICTR, &ictr);
1464 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1465 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1466 for (i = 0; i < cortex_m3->intlinesnum; i++)
1467 {
1468 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1469 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32 "", i, cortex_m3->intsetenable[i]);
1470 }
1471
1472 /* Setup FPB */
1473 target_read_u32(target, FP_CTRL, &fpcr);
1474 cortex_m3->auto_bp_type = 1;
1475 cortex_m3->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF); /* bits [14:12] and [7:4] */
1476 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1477 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1478 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1479 cortex_m3->fpb_enabled = fpcr & 1;
1480 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1481 {
1482 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1483 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1484 }
1485 LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1486
1487 /* Setup DWT */
1488 target_read_u32(target, DWT_CTRL, &dwtcr);
1489 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1490 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1491 cortex_m3->dwt_comparator_list = calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1492 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1493 {
1494 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1495 }
1496 }
1497
1498 return ERROR_OK;
1499 }
1500
1501 static int cortex_m3_quit(void)
1502 {
1503 return ERROR_OK;
1504 }
1505
1506 static int cortex_m3_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
1507 {
1508 uint16_t dcrdr;
1509
1510 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1511 *ctrl = (uint8_t)dcrdr;
1512 *value = (uint8_t)(dcrdr >> 8);
1513
1514 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1515
1516 /* write ack back to software dcc register
1517 * signify we have read data */
1518 if (dcrdr & (1 << 0))
1519 {
1520 dcrdr = 0;
1521 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1522 }
1523
1524 return ERROR_OK;
1525 }
1526
1527 static int cortex_m3_target_request_data(target_t *target,
1528 uint32_t size, uint8_t *buffer)
1529 {
1530 armv7m_common_t *armv7m = target->arch_info;
1531 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1532 uint8_t data;
1533 uint8_t ctrl;
1534 uint32_t i;
1535
1536 for (i = 0; i < (size * 4); i++)
1537 {
1538 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1539 buffer[i] = data;
1540 }
1541
1542 return ERROR_OK;
1543 }
1544
1545 static int cortex_m3_handle_target_request(void *priv)
1546 {
1547 target_t *target = priv;
1548 if (!target_was_examined(target))
1549 return ERROR_OK;
1550 armv7m_common_t *armv7m = target->arch_info;
1551 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1552
1553 if (!target->dbg_msg_enabled)
1554 return ERROR_OK;
1555
1556 if (target->state == TARGET_RUNNING)
1557 {
1558 uint8_t data;
1559 uint8_t ctrl;
1560
1561 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1562
1563 /* check if we have data */
1564 if (ctrl & (1 << 0))
1565 {
1566 uint32_t request;
1567
1568 /* we assume target is quick enough */
1569 request = data;
1570 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1571 request |= (data << 8);
1572 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1573 request |= (data << 16);
1574 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1575 request |= (data << 24);
1576 target_request(target, request);
1577 }
1578 }
1579
1580 return ERROR_OK;
1581 }
1582
1583 static int cortex_m3_init_arch_info(target_t *target,
1584 cortex_m3_common_t *cortex_m3, jtag_tap_t *tap)
1585 {
1586 int retval;
1587 armv7m_common_t *armv7m;
1588 armv7m = &cortex_m3->armv7m;
1589
1590 armv7m_init_arch_info(target, armv7m);
1591
1592 /* prepare JTAG information for the new target */
1593 cortex_m3->jtag_info.tap = tap;
1594 cortex_m3->jtag_info.scann_size = 4;
1595
1596 armv7m->swjdp_info.dp_select_value = -1;
1597 armv7m->swjdp_info.ap_csw_value = -1;
1598 armv7m->swjdp_info.ap_tar_value = -1;
1599 armv7m->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1600 armv7m->swjdp_info.memaccess_tck = 8;
1601 armv7m->swjdp_info.tar_autoincr_block = (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1602
1603 /* initialize arch-specific breakpoint handling */
1604
1605 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1606 cortex_m3->arch_info = NULL;
1607
1608 /* register arch-specific functions */
1609 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1610
1611 armv7m->post_debug_entry = NULL;
1612
1613 armv7m->pre_restore_context = NULL;
1614 armv7m->post_restore_context = NULL;
1615
1616 armv7m->arch_info = cortex_m3;
1617 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1618 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1619
1620 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1621
1622 if ((retval = arm_jtag_setup_connection(&cortex_m3->jtag_info)) != ERROR_OK)
1623 {
1624 return retval;
1625 }
1626
1627 return ERROR_OK;
1628 }
1629
1630 static int cortex_m3_target_create(struct target_s *target, Jim_Interp *interp)
1631 {
1632 cortex_m3_common_t *cortex_m3 = calloc(1,sizeof(cortex_m3_common_t));
1633
1634 cortex_m3_init_arch_info(target, cortex_m3, target->tap);
1635
1636 return ERROR_OK;
1637 }
1638
1639 /*
1640 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1641 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1642 * that *only* Thumb2 disassembly matters. There are also some small
1643 * additions to Thumb2 that are specific to ARMv7-M.
1644 */
1645 static int
1646 handle_cortex_m3_disassemble_command(struct command_context_s *cmd_ctx,
1647 char *cmd, char **args, int argc)
1648 {
1649 int retval = ERROR_OK;
1650 target_t *target = get_current_target(cmd_ctx);
1651 uint32_t address;
1652 unsigned long count = 1;
1653 arm_instruction_t cur_instruction;
1654
1655 errno = 0;
1656 switch (argc) {
1657 case 2:
1658 count = strtoul(args[1], NULL, 0);
1659 if (errno)
1660 return ERROR_FAIL;
1661 /* FALL THROUGH */
1662 case 1:
1663 address = strtoul(args[0], NULL, 0);
1664 if (errno)
1665 return ERROR_FAIL;
1666 break;
1667 default:
1668 command_print(cmd_ctx,
1669 "usage: cortex_m3 disassemble <address> [<count>]");
1670 return ERROR_OK;
1671 }
1672
1673 while (count--) {
1674 retval = thumb2_opcode(target, address, &cur_instruction);
1675 if (retval != ERROR_OK)
1676 return retval;
1677 command_print(cmd_ctx, "%s", cur_instruction.text);
1678 address += cur_instruction.instruction_size;
1679 }
1680
1681 return ERROR_OK;
1682 }
1683
1684 static const struct {
1685 char name[10];
1686 unsigned mask;
1687 } vec_ids[] = {
1688 { "hard_err", VC_HARDERR, },
1689 { "int_err", VC_INTERR, },
1690 { "bus_err", VC_BUSERR, },
1691 { "state_err", VC_STATERR, },
1692 { "chk_err", VC_CHKERR, },
1693 { "nocp_err", VC_NOCPERR, },
1694 { "mm_err", VC_MMERR, },
1695 { "reset", VC_CORERESET, },
1696 };
1697
1698 static int
1699 handle_cortex_m3_vector_catch_command(struct command_context_s *cmd_ctx,
1700 char *cmd, char **argv, int argc)
1701 {
1702 target_t *target = get_current_target(cmd_ctx);
1703 armv7m_common_t *armv7m = target->arch_info;
1704 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1705 uint32_t demcr = 0;
1706 int i;
1707
1708 mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
1709
1710 if (argc > 0) {
1711 unsigned catch = 0;
1712
1713 if (argc == 1) {
1714 if (strcmp(argv[0], "all") == 0) {
1715 catch = VC_HARDERR | VC_INTERR | VC_BUSERR
1716 | VC_STATERR | VC_CHKERR | VC_NOCPERR
1717 | VC_MMERR | VC_CORERESET;
1718 goto write;
1719 } else if (strcmp(argv[0], "none") == 0) {
1720 goto write;
1721 }
1722 }
1723 while (argc-- > 0) {
1724 for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
1725 if (strcmp(argv[argc], vec_ids[i].name) != 0)
1726 continue;
1727 catch |= vec_ids[i].mask;
1728 break;
1729 }
1730 if (i == ARRAY_SIZE(vec_ids)) {
1731 LOG_ERROR("No CM3 vector '%s'", argv[argc]);
1732 return ERROR_INVALID_ARGUMENTS;
1733 }
1734 }
1735 write:
1736 demcr &= ~0xffff;
1737 demcr |= catch;
1738
1739 /* write, but don't assume it stuck */
1740 mem_ap_write_u32(swjdp, DCB_DEMCR, demcr);
1741 mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
1742 }
1743
1744 for (i = 0; i < ARRAY_SIZE(vec_ids); i++)
1745 command_print(cmd_ctx, "%9s: %s", vec_ids[i].name,
1746 (demcr & vec_ids[i].mask) ? "catch" : "ignore");
1747
1748 return ERROR_OK;
1749 }
1750
1751 static int
1752 handle_cortex_m3_mask_interrupts_command(struct command_context_s *cmd_ctx,
1753 char *cmd, char **args, int argc)
1754 {
1755 target_t *target = get_current_target(cmd_ctx);
1756 armv7m_common_t *armv7m = target->arch_info;
1757 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1758
1759 if (target->state != TARGET_HALTED)
1760 {
1761 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1762 return ERROR_OK;
1763 }
1764
1765 if (argc > 0)
1766 {
1767 if (!strcmp(args[0], "on"))
1768 {
1769 cortex_m3_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
1770 }
1771 else if (!strcmp(args[0], "off"))
1772 {
1773 cortex_m3_write_debug_halt_mask(target, C_HALT, C_MASKINTS);
1774 }
1775 else
1776 {
1777 command_print(cmd_ctx, "usage: cortex_m3 maskisr ['on'|'off']");
1778 }
1779 }
1780
1781 command_print(cmd_ctx, "cortex_m3 interrupt mask %s",
1782 (cortex_m3->dcb_dhcsr & C_MASKINTS) ? "on" : "off");
1783
1784 return ERROR_OK;
1785 }
1786
1787 static int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1788 {
1789 int retval;
1790 command_t *cortex_m3_cmd;
1791
1792 retval = armv7m_register_commands(cmd_ctx);
1793
1794 cortex_m3_cmd = register_command(cmd_ctx, NULL, "cortex_m3",
1795 NULL, COMMAND_ANY, "cortex_m3 specific commands");
1796
1797 register_command(cmd_ctx, cortex_m3_cmd, "disassemble",
1798 handle_cortex_m3_disassemble_command, COMMAND_EXEC,
1799 "disassemble Thumb2 instructions <address> [<count>]");
1800 register_command(cmd_ctx, cortex_m3_cmd, "maskisr",
1801 handle_cortex_m3_mask_interrupts_command, COMMAND_EXEC,
1802 "mask cortex_m3 interrupts ['on'|'off']");
1803 register_command(cmd_ctx, cortex_m3_cmd, "vector_catch",
1804 handle_cortex_m3_vector_catch_command, COMMAND_EXEC,
1805 "catch hardware vectors ['all'|'none'|<list>]");
1806
1807 return retval;
1808 }
1809
1810 target_type_t cortexm3_target =
1811 {
1812 .name = "cortex_m3",
1813
1814 .poll = cortex_m3_poll,
1815 .arch_state = armv7m_arch_state,
1816
1817 .target_request_data = cortex_m3_target_request_data,
1818
1819 .halt = cortex_m3_halt,
1820 .resume = cortex_m3_resume,
1821 .step = cortex_m3_step,
1822
1823 .assert_reset = cortex_m3_assert_reset,
1824 .deassert_reset = cortex_m3_deassert_reset,
1825 .soft_reset_halt = cortex_m3_soft_reset_halt,
1826
1827 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
1828
1829 .read_memory = cortex_m3_read_memory,
1830 .write_memory = cortex_m3_write_memory,
1831 .bulk_write_memory = cortex_m3_bulk_write_memory,
1832 .checksum_memory = armv7m_checksum_memory,
1833 .blank_check_memory = armv7m_blank_check_memory,
1834
1835 .run_algorithm = armv7m_run_algorithm,
1836
1837 .add_breakpoint = cortex_m3_add_breakpoint,
1838 .remove_breakpoint = cortex_m3_remove_breakpoint,
1839 .add_watchpoint = cortex_m3_add_watchpoint,
1840 .remove_watchpoint = cortex_m3_remove_watchpoint,
1841
1842 .register_commands = cortex_m3_register_commands,
1843 .target_create = cortex_m3_target_create,
1844 .init_target = cortex_m3_init_target,
1845 .examine = cortex_m3_examine,
1846 .quit = cortex_m3_quit
1847 };
1848

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)