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

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)