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

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)