David Brownell <david-b@pacbell.net> Clean up some Cortex-M3 reset handling.
[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
764 /*
765 * We can reset Cortex-M3 targets using just the NVIC without
766 * requiring SRST, getting a SoC reset (or a core-only reset)
767 * instead of a system reset.
768 */
769 if (!(jtag_reset_config & RESET_HAS_SRST))
770 assert_srst = 0;
771
772 /* Enable debug requests */
773 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
774 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
775 mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
776
777 mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
778
779 if (!target->reset_halt)
780 {
781 /* Set/Clear C_MASKINTS in a separate operation */
782 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
783 mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT);
784
785 /* clear any debug flags before resuming */
786 cortex_m3_clear_halt(target);
787
788 /* clear C_HALT in dhcsr reg */
789 cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
790
791 /* Enter debug state on reset, cf. end_reset_event() */
792 mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
793 }
794 else
795 {
796 /* Enter debug state on reset, cf. end_reset_event() */
797 mem_ap_write_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
798 }
799
800 /*
801 * When nRST is asserted on most Stellaris devices, it clears some of
802 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
803 * and OpenOCD depends on those TRMs. So we won't use SRST on those
804 * chips. (Only power-on reset should affect debug state, beyond a
805 * few specified bits; not the chip's nRST input, wired to SRST.)
806 *
807 * REVISIT current errata specs don't seem to cover this issue.
808 * Do we have more details than this email?
809 * https://lists.berlios.de/pipermail
810 * /openocd-development/2008-August/003065.html
811 */
812 if (strcmp(target->variant, "lm3s") == 0)
813 {
814 /* Check for silicon revisions with the issue. */
815 uint32_t did0;
816
817 if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
818 {
819 switch ((did0 >> 16) & 0xff)
820 {
821 case 0:
822 /* all Sandstorm suffer issue */
823 assert_srst = 0;
824 break;
825
826 case 1:
827 case 3:
828 /* Fury and DustDevil rev A have
829 * this nRST problem. It should
830 * be fixed in rev B silicon.
831 */
832 if (((did0 >> 8) & 0xff) == 0)
833 assert_srst = 0;
834 break;
835 case 4:
836 /* Tempest should be fine. */
837 break;
838 }
839 }
840 }
841
842 if (assert_srst)
843 {
844 /* default to asserting srst */
845 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
846 {
847 jtag_add_reset(1, 1);
848 }
849 else
850 {
851 jtag_add_reset(0, 1);
852 }
853 }
854 else
855 {
856 /* Use a standard Cortex-M3 software reset mechanism.
857 * SYSRESETREQ will reset SoC peripherals outside the
858 * core, like watchdog timers, if the SoC wires it up
859 * correctly. Else VECRESET can reset just the core.
860 */
861 mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR,
862 AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
863 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
864
865 {
866 /* I do not know why this is necessary, but it
867 * fixes strange effects (step/resume cause NMI
868 * after reset) on LM3S6918 -- Michael Schwingen
869 */
870 uint32_t tmp;
871 mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp);
872 }
873 }
874
875 target->state = TARGET_RESET;
876 jtag_add_sleep(50000);
877
878 armv7m_invalidate_core_regs(target);
879
880 if (target->reset_halt)
881 {
882 int retval;
883 if ((retval = target_halt(target)) != ERROR_OK)
884 return retval;
885 }
886
887 return ERROR_OK;
888 }
889
890 int cortex_m3_deassert_reset(target_t *target)
891 {
892 LOG_DEBUG("target->state: %s",
893 target_state_name(target));
894
895 /* deassert reset lines */
896 jtag_add_reset(0, 0);
897
898 return ERROR_OK;
899 }
900
901 void cortex_m3_enable_breakpoints(struct target_s *target)
902 {
903 breakpoint_t *breakpoint = target->breakpoints;
904
905 /* set any pending breakpoints */
906 while (breakpoint)
907 {
908 if (breakpoint->set == 0)
909 cortex_m3_set_breakpoint(target, breakpoint);
910 breakpoint = breakpoint->next;
911 }
912 }
913
914 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
915 {
916 int retval;
917 int fp_num = 0;
918 uint32_t hilo;
919
920 /* get pointers to arch-specific information */
921 armv7m_common_t *armv7m = target->arch_info;
922 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
923
924 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
925
926 if (breakpoint->set)
927 {
928 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint->unique_id);
929 return ERROR_OK;
930 }
931
932 if (cortex_m3->auto_bp_type)
933 {
934 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
935 }
936
937 if (breakpoint->type == BKPT_HARD)
938 {
939 while (comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
940 fp_num++;
941 if (fp_num >= cortex_m3->fp_num_code)
942 {
943 LOG_DEBUG("ERROR Can not find free FP Comparator");
944 LOG_WARNING("ERROR Can not find free FP Comparator");
945 exit(-1);
946 }
947 breakpoint->set = fp_num + 1;
948 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
949 comparator_list[fp_num].used = 1;
950 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
951 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
952 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "", fp_num, comparator_list[fp_num].fpcr_value);
953 if (!cortex_m3->fpb_enabled)
954 {
955 LOG_DEBUG("FPB wasn't enabled, do it now");
956 target_write_u32(target, FP_CTRL, 3);
957 }
958 }
959 else if (breakpoint->type == BKPT_SOFT)
960 {
961 uint8_t code[4];
962 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
963 if ((retval = target_read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
964 {
965 return retval;
966 }
967 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code)) != ERROR_OK)
968 {
969 return retval;
970 }
971 breakpoint->set = 0x11; /* Any nice value but 0 */
972 }
973
974 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
975 breakpoint->unique_id,
976 (int)(breakpoint->type),
977 breakpoint->address,
978 breakpoint->length,
979 breakpoint->set);
980
981 return ERROR_OK;
982 }
983
984 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
985 {
986 int retval;
987 /* get pointers to arch-specific information */
988 armv7m_common_t *armv7m = target->arch_info;
989 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
990 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
991
992 if (!breakpoint->set)
993 {
994 LOG_WARNING("breakpoint not set");
995 return ERROR_OK;
996 }
997
998 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
999 breakpoint->unique_id,
1000 (int)(breakpoint->type),
1001 breakpoint->address,
1002 breakpoint->length,
1003 breakpoint->set);
1004
1005 if (breakpoint->type == BKPT_HARD)
1006 {
1007 int fp_num = breakpoint->set - 1;
1008 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
1009 {
1010 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
1011 return ERROR_OK;
1012 }
1013 comparator_list[fp_num].used = 0;
1014 comparator_list[fp_num].fpcr_value = 0;
1015 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
1016 }
1017 else
1018 {
1019 /* restore original instruction (kept in target endianness) */
1020 if (breakpoint->length == 4)
1021 {
1022 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
1023 {
1024 return retval;
1025 }
1026 }
1027 else
1028 {
1029 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
1030 {
1031 return retval;
1032 }
1033 }
1034 }
1035 breakpoint->set = 0;
1036
1037 return ERROR_OK;
1038 }
1039
1040 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1041 {
1042 /* get pointers to arch-specific information */
1043 armv7m_common_t *armv7m = target->arch_info;
1044 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1045
1046 if (cortex_m3->auto_bp_type)
1047 {
1048 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
1049 #ifdef ARMV7_GDB_HACKS
1050 if (breakpoint->length != 2) {
1051 /* XXX Hack: Replace all breakpoints with length != 2 with
1052 * a hardware breakpoint. */
1053 breakpoint->type = BKPT_HARD;
1054 breakpoint->length = 2;
1055 }
1056 #endif
1057 }
1058
1059 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
1060 {
1061 LOG_INFO("flash patch comparator requested outside code memory region");
1062 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1063 }
1064
1065 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
1066 {
1067 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1068 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1069 }
1070
1071 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
1072 {
1073 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1074 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1075 }
1076
1077 if ((breakpoint->length != 2))
1078 {
1079 LOG_INFO("only breakpoints of two bytes length supported");
1080 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1081 }
1082
1083 if (breakpoint->type == BKPT_HARD)
1084 cortex_m3->fp_code_available--;
1085 cortex_m3_set_breakpoint(target, breakpoint);
1086
1087 return ERROR_OK;
1088 }
1089
1090 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1091 {
1092 /* get pointers to arch-specific information */
1093 armv7m_common_t *armv7m = target->arch_info;
1094 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1095
1096 if (target->state != TARGET_HALTED)
1097 {
1098 LOG_WARNING("target not halted");
1099 return ERROR_TARGET_NOT_HALTED;
1100 }
1101
1102 if (cortex_m3->auto_bp_type)
1103 {
1104 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
1105 }
1106
1107 if (breakpoint->set)
1108 {
1109 cortex_m3_unset_breakpoint(target, breakpoint);
1110 }
1111
1112 if (breakpoint->type == BKPT_HARD)
1113 cortex_m3->fp_code_available++;
1114
1115 return ERROR_OK;
1116 }
1117
1118 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1119 {
1120 int dwt_num = 0;
1121 uint32_t mask, temp;
1122
1123 /* get pointers to arch-specific information */
1124 armv7m_common_t *armv7m = target->arch_info;
1125 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1126 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1127
1128 if (watchpoint->set)
1129 {
1130 LOG_WARNING("watchpoint (%d) already set", watchpoint->unique_id );
1131 return ERROR_OK;
1132 }
1133
1134 if (watchpoint->mask == 0xffffffffu)
1135 {
1136 while (comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
1137 dwt_num++;
1138 if (dwt_num >= cortex_m3->dwt_num_comp)
1139 {
1140 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1141 LOG_WARNING("ERROR Can not find free DWT Comparator");
1142 return -1;
1143 }
1144 watchpoint->set = dwt_num + 1;
1145 mask = 0;
1146 temp = watchpoint->length;
1147 while (temp > 1)
1148 {
1149 temp = temp / 2;
1150 mask++;
1151 }
1152 comparator_list[dwt_num].used = 1;
1153 comparator_list[dwt_num].comp = watchpoint->address;
1154 comparator_list[dwt_num].mask = mask;
1155 comparator_list[dwt_num].function = watchpoint->rw + 5;
1156 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
1157 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x4, comparator_list[dwt_num].mask);
1158 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x8, comparator_list[dwt_num].function);
1159 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);
1160 }
1161 else
1162 {
1163 /* Move this test to add_watchpoint */
1164 LOG_WARNING("Cannot watch data values (id: %d)",
1165 watchpoint->unique_id );
1166 return ERROR_OK;
1167 }
1168 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
1169 watchpoint->unique_id, watchpoint->address, watchpoint->set );
1170 return ERROR_OK;
1171
1172 }
1173
1174 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1175 {
1176 /* get pointers to arch-specific information */
1177 armv7m_common_t *armv7m = target->arch_info;
1178 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1179 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1180 int dwt_num;
1181
1182 if (!watchpoint->set)
1183 {
1184 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint->unique_id );
1185 return ERROR_OK;
1186 }
1187
1188 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
1189 watchpoint->unique_id, watchpoint->address,watchpoint->set );
1190
1191 dwt_num = watchpoint->set - 1;
1192
1193 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1194 {
1195 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1196 return ERROR_OK;
1197 }
1198 comparator_list[dwt_num].used = 0;
1199 comparator_list[dwt_num].function = 0;
1200 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x8, comparator_list[dwt_num].function);
1201
1202 watchpoint->set = 0;
1203
1204 return ERROR_OK;
1205 }
1206
1207 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1208 {
1209 /* get pointers to arch-specific information */
1210 armv7m_common_t *armv7m = target->arch_info;
1211 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1212
1213 if (target->state != TARGET_HALTED)
1214 {
1215 LOG_WARNING("target not halted");
1216 return ERROR_TARGET_NOT_HALTED;
1217 }
1218
1219 if (cortex_m3->dwt_comp_available < 1)
1220 {
1221 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1222 }
1223
1224 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1225 {
1226 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1227 }
1228
1229 cortex_m3->dwt_comp_available--;
1230 LOG_DEBUG("dwt_comp_available: %d", cortex_m3->dwt_comp_available);
1231
1232 return ERROR_OK;
1233 }
1234
1235 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1236 {
1237 /* get pointers to arch-specific information */
1238 armv7m_common_t *armv7m = target->arch_info;
1239 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1240
1241 if (target->state != TARGET_HALTED)
1242 {
1243 LOG_WARNING("target not halted");
1244 return ERROR_TARGET_NOT_HALTED;
1245 }
1246
1247 if (watchpoint->set)
1248 {
1249 cortex_m3_unset_watchpoint(target, watchpoint);
1250 }
1251
1252 cortex_m3->dwt_comp_available++;
1253 LOG_DEBUG("dwt_comp_available: %d", cortex_m3->dwt_comp_available);
1254
1255 return ERROR_OK;
1256 }
1257
1258 void cortex_m3_enable_watchpoints(struct target_s *target)
1259 {
1260 watchpoint_t *watchpoint = target->watchpoints;
1261
1262 /* set any pending watchpoints */
1263 while (watchpoint)
1264 {
1265 if (watchpoint->set == 0)
1266 cortex_m3_set_watchpoint(target, watchpoint);
1267 watchpoint = watchpoint->next;
1268 }
1269 }
1270
1271 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t * value)
1272 {
1273 int retval;
1274 /* get pointers to arch-specific information */
1275 armv7m_common_t *armv7m = target->arch_info;
1276 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1277
1278 /* NOTE: we "know" here that the register identifiers used
1279 * in the v7m header match the Cortex-M3 Debug Core Register
1280 * Selector values for R0..R15, xPSR, MSP, and PSP.
1281 */
1282 switch (num) {
1283 case 0 ... 18:
1284 /* read a normal core register */
1285 retval = cortexm3_dap_read_coreregister_u32(swjdp, value, num);
1286
1287 if (retval != ERROR_OK)
1288 {
1289 LOG_ERROR("JTAG failure %i",retval);
1290 return ERROR_JTAG_DEVICE_ERROR;
1291 }
1292 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "",(int)num,*value);
1293 break;
1294
1295 case ARMV7M_PRIMASK:
1296 case ARMV7M_BASEPRI:
1297 case ARMV7M_FAULTMASK:
1298 case ARMV7M_CONTROL:
1299 /* Cortex-M3 packages these four registers as bitfields
1300 * in one Debug Core register. So say r0 and r2 docs;
1301 * it was removed from r1 docs, but still works.
1302 */
1303 cortexm3_dap_read_coreregister_u32(swjdp, value, 20);
1304
1305 switch (num)
1306 {
1307 case ARMV7M_PRIMASK:
1308 *value = buf_get_u32((uint8_t*)value, 0, 1);
1309 break;
1310
1311 case ARMV7M_BASEPRI:
1312 *value = buf_get_u32((uint8_t*)value, 8, 8);
1313 break;
1314
1315 case ARMV7M_FAULTMASK:
1316 *value = buf_get_u32((uint8_t*)value, 16, 1);
1317 break;
1318
1319 case ARMV7M_CONTROL:
1320 *value = buf_get_u32((uint8_t*)value, 24, 2);
1321 break;
1322 }
1323
1324 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", (int)num, *value);
1325 break;
1326
1327 default:
1328 return ERROR_INVALID_ARGUMENTS;
1329 }
1330
1331 return ERROR_OK;
1332 }
1333
1334 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t value)
1335 {
1336 int retval;
1337 uint32_t reg;
1338
1339 /* get pointers to arch-specific information */
1340 armv7m_common_t *armv7m = target->arch_info;
1341 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1342
1343 #ifdef ARMV7_GDB_HACKS
1344 /* If the LR register is being modified, make sure it will put us
1345 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1346 * hack to deal with the fact that gdb will sometimes "forge"
1347 * return addresses, and doesn't set the LSB correctly (i.e., when
1348 * printing expressions containing function calls, it sets LR = 0.)
1349 * Valid exception return codes have bit 0 set too.
1350 */
1351 if (num == ARMV7M_R14)
1352 value |= 0x01;
1353 #endif
1354
1355 /* NOTE: we "know" here that the register identifiers used
1356 * in the v7m header match the Cortex-M3 Debug Core Register
1357 * Selector values for R0..R15, xPSR, MSP, and PSP.
1358 */
1359 switch (num) {
1360 case 0 ... 18:
1361 retval = cortexm3_dap_write_coreregister_u32(swjdp, value, num);
1362 if (retval != ERROR_OK)
1363 {
1364 LOG_ERROR("JTAG failure %i", retval);
1365 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1366 return ERROR_JTAG_DEVICE_ERROR;
1367 }
1368 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
1369 break;
1370
1371 case ARMV7M_PRIMASK:
1372 case ARMV7M_BASEPRI:
1373 case ARMV7M_FAULTMASK:
1374 case ARMV7M_CONTROL:
1375 /* Cortex-M3 packages these four registers as bitfields
1376 * in one Debug Core register. So say r0 and r2 docs;
1377 * it was removed from r1 docs, but still works.
1378 */
1379 cortexm3_dap_read_coreregister_u32(swjdp, &reg, 20);
1380
1381 switch (num)
1382 {
1383 case ARMV7M_PRIMASK:
1384 buf_set_u32((uint8_t*)&reg, 0, 1, value);
1385 break;
1386
1387 case ARMV7M_BASEPRI:
1388 buf_set_u32((uint8_t*)&reg, 8, 8, value);
1389 break;
1390
1391 case ARMV7M_FAULTMASK:
1392 buf_set_u32((uint8_t*)&reg, 16, 1, value);
1393 break;
1394
1395 case ARMV7M_CONTROL:
1396 buf_set_u32((uint8_t*)&reg, 24, 2, value);
1397 break;
1398 }
1399
1400 cortexm3_dap_write_coreregister_u32(swjdp, reg, 20);
1401
1402 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
1403 break;
1404
1405 default:
1406 return ERROR_INVALID_ARGUMENTS;
1407 }
1408
1409 return ERROR_OK;
1410 }
1411
1412 int cortex_m3_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
1413 {
1414 /* get pointers to arch-specific information */
1415 armv7m_common_t *armv7m = target->arch_info;
1416 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1417 int retval;
1418
1419 /* sanitize arguments */
1420 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1421 return ERROR_INVALID_ARGUMENTS;
1422
1423 /* cortex_m3 handles unaligned memory access */
1424
1425 switch (size)
1426 {
1427 case 4:
1428 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1429 break;
1430 case 2:
1431 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1432 break;
1433 case 1:
1434 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1435 break;
1436 default:
1437 LOG_ERROR("BUG: we shouldn't get here");
1438 exit(-1);
1439 }
1440
1441 return retval;
1442 }
1443
1444 int cortex_m3_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
1445 {
1446 /* get pointers to arch-specific information */
1447 armv7m_common_t *armv7m = target->arch_info;
1448 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1449 int retval;
1450
1451 /* sanitize arguments */
1452 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1453 return ERROR_INVALID_ARGUMENTS;
1454
1455 switch (size)
1456 {
1457 case 4:
1458 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1459 break;
1460 case 2:
1461 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1462 break;
1463 case 1:
1464 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1465 break;
1466 default:
1467 LOG_ERROR("BUG: we shouldn't get here");
1468 exit(-1);
1469 }
1470
1471 return retval;
1472 }
1473
1474 int cortex_m3_bulk_write_memory(target_t *target, uint32_t address, uint32_t count, uint8_t *buffer)
1475 {
1476 return cortex_m3_write_memory(target, address, 4, count, buffer);
1477 }
1478
1479 void cortex_m3_build_reg_cache(target_t *target)
1480 {
1481 armv7m_build_reg_cache(target);
1482 }
1483
1484 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1485 {
1486 cortex_m3_build_reg_cache(target);
1487 return ERROR_OK;
1488 }
1489
1490 int cortex_m3_examine(struct target_s *target)
1491 {
1492 int retval;
1493 uint32_t cpuid, fpcr, dwtcr, ictr;
1494 int i;
1495
1496 /* get pointers to arch-specific information */
1497 armv7m_common_t *armv7m = target->arch_info;
1498 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1499 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1500
1501 if ((retval = ahbap_debugport_init(swjdp)) != ERROR_OK)
1502 return retval;
1503
1504 if (!target_was_examined(target))
1505 {
1506 target_set_examined(target);
1507
1508 /* Read from Device Identification Registers */
1509 if ((retval = target_read_u32(target, CPUID, &cpuid)) != ERROR_OK)
1510 return retval;
1511
1512 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1513 LOG_DEBUG("CORTEX-M3 processor detected");
1514 LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
1515
1516 target_read_u32(target, NVIC_ICTR, &ictr);
1517 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1518 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1519 for (i = 0; i < cortex_m3->intlinesnum; i++)
1520 {
1521 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1522 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32 "", i, cortex_m3->intsetenable[i]);
1523 }
1524
1525 /* Setup FPB */
1526 target_read_u32(target, FP_CTRL, &fpcr);
1527 cortex_m3->auto_bp_type = 1;
1528 cortex_m3->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF); /* bits [14:12] and [7:4] */
1529 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1530 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1531 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1532 cortex_m3->fpb_enabled = fpcr & 1;
1533 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1534 {
1535 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1536 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1537 }
1538 LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1539
1540 /* Setup DWT */
1541 target_read_u32(target, DWT_CTRL, &dwtcr);
1542 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1543 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1544 cortex_m3->dwt_comparator_list = calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1545 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1546 {
1547 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1548 }
1549 }
1550
1551 return ERROR_OK;
1552 }
1553
1554 int cortex_m3_quit(void)
1555 {
1556
1557 return ERROR_OK;
1558 }
1559
1560 int cortex_m3_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
1561 {
1562 uint16_t dcrdr;
1563
1564 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1565 *ctrl = (uint8_t)dcrdr;
1566 *value = (uint8_t)(dcrdr >> 8);
1567
1568 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1569
1570 /* write ack back to software dcc register
1571 * signify we have read data */
1572 if (dcrdr & (1 << 0))
1573 {
1574 dcrdr = 0;
1575 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1576 }
1577
1578 return ERROR_OK;
1579 }
1580
1581 int cortex_m3_target_request_data(target_t *target, uint32_t size, uint8_t *buffer)
1582 {
1583 armv7m_common_t *armv7m = target->arch_info;
1584 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1585 uint8_t data;
1586 uint8_t ctrl;
1587 uint32_t i;
1588
1589 for (i = 0; i < (size * 4); i++)
1590 {
1591 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1592 buffer[i] = data;
1593 }
1594
1595 return ERROR_OK;
1596 }
1597
1598 int cortex_m3_handle_target_request(void *priv)
1599 {
1600 target_t *target = priv;
1601 if (!target_was_examined(target))
1602 return ERROR_OK;
1603 armv7m_common_t *armv7m = target->arch_info;
1604 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1605
1606 if (!target->dbg_msg_enabled)
1607 return ERROR_OK;
1608
1609 if (target->state == TARGET_RUNNING)
1610 {
1611 uint8_t data;
1612 uint8_t ctrl;
1613
1614 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1615
1616 /* check if we have data */
1617 if (ctrl & (1 << 0))
1618 {
1619 uint32_t request;
1620
1621 /* we assume target is quick enough */
1622 request = data;
1623 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1624 request |= (data << 8);
1625 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1626 request |= (data << 16);
1627 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1628 request |= (data << 24);
1629 target_request(target, request);
1630 }
1631 }
1632
1633 return ERROR_OK;
1634 }
1635
1636 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, jtag_tap_t *tap)
1637 {
1638 int retval;
1639 armv7m_common_t *armv7m;
1640 armv7m = &cortex_m3->armv7m;
1641
1642 armv7m_init_arch_info(target, armv7m);
1643
1644 /* prepare JTAG information for the new target */
1645 cortex_m3->jtag_info.tap = tap;
1646 cortex_m3->jtag_info.scann_size = 4;
1647
1648 armv7m->swjdp_info.dp_select_value = -1;
1649 armv7m->swjdp_info.ap_csw_value = -1;
1650 armv7m->swjdp_info.ap_tar_value = -1;
1651 armv7m->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1652 armv7m->swjdp_info.memaccess_tck = 8;
1653 armv7m->swjdp_info.tar_autoincr_block = (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1654
1655 /* initialize arch-specific breakpoint handling */
1656
1657 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1658 cortex_m3->arch_info = NULL;
1659
1660 /* register arch-specific functions */
1661 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1662
1663 armv7m->pre_debug_entry = NULL;
1664 armv7m->post_debug_entry = NULL;
1665
1666 armv7m->pre_restore_context = NULL;
1667 armv7m->post_restore_context = NULL;
1668
1669 armv7m->arch_info = cortex_m3;
1670 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1671 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1672
1673 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1674
1675 if ((retval = arm_jtag_setup_connection(&cortex_m3->jtag_info)) != ERROR_OK)
1676 {
1677 return retval;
1678 }
1679
1680 return ERROR_OK;
1681 }
1682
1683 int cortex_m3_target_create(struct target_s *target, Jim_Interp *interp)
1684 {
1685 cortex_m3_common_t *cortex_m3 = calloc(1,sizeof(cortex_m3_common_t));
1686
1687 cortex_m3_init_arch_info(target, cortex_m3, target->tap);
1688
1689 return ERROR_OK;
1690 }
1691
1692 /*
1693 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1694 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1695 * that *only* Thumb2 disassembly matters. There are also some small
1696 * additions to Thumb2 that are specific to ARMv7-M.
1697 */
1698 static int
1699 handle_cortex_m3_disassemble_command(struct command_context_s *cmd_ctx,
1700 char *cmd, char **args, int argc)
1701 {
1702 int retval = ERROR_OK;
1703 target_t *target = get_current_target(cmd_ctx);
1704 uint32_t address;
1705 unsigned long count;
1706 arm_instruction_t cur_instruction;
1707
1708 if (argc != 2) {
1709 command_print(cmd_ctx,
1710 "usage: cortex_m3 disassemble <address> <count>");
1711 return ERROR_OK;
1712 }
1713
1714 errno = 0;
1715 address = strtoul(args[0], NULL, 0);
1716 if (errno)
1717 return ERROR_FAIL;
1718 count = strtoul(args[1], NULL, 0);
1719 if (errno)
1720 return ERROR_FAIL;
1721
1722 while (count--) {
1723 retval = thumb2_opcode(target, address, &cur_instruction);
1724 if (retval != ERROR_OK)
1725 return retval;
1726 command_print(cmd_ctx, "%s", cur_instruction.text);
1727 address += cur_instruction.instruction_size;
1728 }
1729
1730 return ERROR_OK;
1731 }
1732
1733 static const struct {
1734 char name[10];
1735 unsigned mask;
1736 } vec_ids[] = {
1737 { "hard_err", VC_HARDERR, },
1738 { "int_err", VC_INTERR, },
1739 { "bus_err", VC_BUSERR, },
1740 { "state_err", VC_STATERR, },
1741 { "chk_err", VC_CHKERR, },
1742 { "nocp_err", VC_NOCPERR, },
1743 { "mm_err", VC_MMERR, },
1744 { "reset", VC_CORERESET, },
1745 };
1746
1747 static int
1748 handle_cortex_m3_vector_catch_command(struct command_context_s *cmd_ctx,
1749 char *cmd, char **argv, int argc)
1750 {
1751 target_t *target = get_current_target(cmd_ctx);
1752 armv7m_common_t *armv7m = target->arch_info;
1753 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1754 uint32_t demcr = 0;
1755 int i;
1756
1757 mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
1758
1759 if (argc > 0) {
1760 unsigned catch = 0;
1761
1762 if (argc == 1) {
1763 if (strcmp(argv[0], "all") == 0) {
1764 catch = VC_HARDERR | VC_INTERR | VC_BUSERR
1765 | VC_STATERR | VC_CHKERR | VC_NOCPERR
1766 | VC_MMERR | VC_CORERESET;
1767 goto write;
1768 } else if (strcmp(argv[0], "none") == 0) {
1769 goto write;
1770 }
1771 }
1772 while (argc-- > 0) {
1773 for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
1774 if (strcmp(argv[argc], vec_ids[i].name) != 0)
1775 continue;
1776 catch |= vec_ids[i].mask;
1777 break;
1778 }
1779 if (i == ARRAY_SIZE(vec_ids)) {
1780 LOG_ERROR("No CM3 vector '%s'", argv[argc]);
1781 return ERROR_INVALID_ARGUMENTS;
1782 }
1783 }
1784 write:
1785 demcr &= ~0xffff;
1786 demcr |= catch;
1787
1788 /* write, but don't assume it stuck */
1789 mem_ap_write_u32(swjdp, DCB_DEMCR, demcr);
1790 mem_ap_read_atomic_u32(swjdp, DCB_DEMCR, &demcr);
1791 }
1792
1793 for (i = 0; i < ARRAY_SIZE(vec_ids); i++)
1794 command_print(cmd_ctx, "%9s: %s", vec_ids[i].name,
1795 (demcr & vec_ids[i].mask) ? "catch" : "ignore");
1796
1797 return ERROR_OK;
1798 }
1799
1800 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1801 {
1802 int retval;
1803 command_t *cortex_m3_cmd;
1804
1805 retval = armv7m_register_commands(cmd_ctx);
1806
1807 cortex_m3_cmd = register_command(cmd_ctx, NULL, "cortex_m3",
1808 NULL, COMMAND_ANY, "cortex_m3 specific commands");
1809
1810 register_command(cmd_ctx, cortex_m3_cmd, "disassemble",
1811 handle_cortex_m3_disassemble_command, COMMAND_EXEC,
1812 "disassemble Thumb2 instructions <address> <count>");
1813 register_command(cmd_ctx, cortex_m3_cmd, "maskisr",
1814 handle_cortex_m3_mask_interrupts_command, COMMAND_EXEC,
1815 "mask cortex_m3 interrupts ['on'|'off']");
1816 register_command(cmd_ctx, cortex_m3_cmd, "vector_catch",
1817 handle_cortex_m3_vector_catch_command, COMMAND_EXEC,
1818 "catch hardware vectors ['all'|'none'|<list>]");
1819
1820 return retval;
1821 }
1822
1823 int handle_cortex_m3_mask_interrupts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1824 {
1825 target_t *target = get_current_target(cmd_ctx);
1826 armv7m_common_t *armv7m = target->arch_info;
1827 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1828
1829 if (target->state != TARGET_HALTED)
1830 {
1831 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1832 return ERROR_OK;
1833 }
1834
1835 if (argc > 0)
1836 {
1837 if (!strcmp(args[0], "on"))
1838 {
1839 cortex_m3_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
1840 }
1841 else if (!strcmp(args[0], "off"))
1842 {
1843 cortex_m3_write_debug_halt_mask(target, C_HALT, C_MASKINTS);
1844 }
1845 else
1846 {
1847 command_print(cmd_ctx, "usage: cortex_m3 maskisr ['on'|'off']");
1848 }
1849 }
1850
1851 command_print(cmd_ctx, "cortex_m3 interrupt mask %s",
1852 (cortex_m3->dcb_dhcsr & C_MASKINTS) ? "on" : "off");
1853
1854 return ERROR_OK;
1855 }

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)