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

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)