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

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)