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

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)