Magnus Lundin Thc cortex_m3_poll function does not identify that a target is running...
[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 target_state_name(target));
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 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
516 * How best to model low power modes?
517 */
518
519 if (target->state == TARGET_UNKNOWN)
520 {
521 /* check if processor is retiring instructions */
522 if (cortex_m3->dcb_dhcsr & S_RETIRE_ST)
523 {
524 target->state = TARGET_RUNNING;
525 return ERROR_OK;
526 }
527 }
528
529 return ERROR_OK;
530 }
531
532 int cortex_m3_halt(target_t *target)
533 {
534 LOG_DEBUG("target->state: %s",
535 target_state_name(target));
536
537 if (target->state == TARGET_HALTED)
538 {
539 LOG_DEBUG("target was already halted");
540 return ERROR_OK;
541 }
542
543 if (target->state == TARGET_UNKNOWN)
544 {
545 LOG_WARNING("target was in unknown state when halt was requested");
546 }
547
548 if (target->state == TARGET_RESET)
549 {
550 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
551 {
552 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
553 return ERROR_TARGET_FAILURE;
554 }
555 else
556 {
557 /* we came here in a reset_halt or reset_init sequence
558 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
559 */
560 target->debug_reason = DBG_REASON_DBGRQ;
561
562 return ERROR_OK;
563 }
564 }
565
566 /* Write to Debug Halting Control and Status Register */
567 cortex_m3_write_debug_halt_mask(target, C_HALT, 0);
568
569 target->debug_reason = DBG_REASON_DBGRQ;
570
571 return ERROR_OK;
572 }
573
574 int cortex_m3_soft_reset_halt(struct target_s *target)
575 {
576 /* get pointers to arch-specific information */
577 armv7m_common_t *armv7m = target->arch_info;
578 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
579 swjdp_common_t *swjdp = &armv7m->swjdp_info;
580 uint32_t dcb_dhcsr = 0;
581 int retval, timeout = 0;
582
583 /* Enter debug state on reset, cf. end_reset_event() */
584 mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
585
586 /* Request a reset */
587 mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET);
588 target->state = TARGET_RESET;
589
590 /* registers are now invalid */
591 armv7m_invalidate_core_regs(target);
592
593 while (timeout < 100)
594 {
595 retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
596 if (retval == ERROR_OK)
597 {
598 mem_ap_read_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
599 if ((dcb_dhcsr & S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
600 {
601 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32 ", nvic_dfsr 0x%" PRIx32 "", dcb_dhcsr, cortex_m3->nvic_dfsr);
602 cortex_m3_poll(target);
603 return ERROR_OK;
604 }
605 else
606 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32 ", %i ms", dcb_dhcsr, timeout);
607 }
608 timeout++;
609 alive_sleep(1);
610 }
611
612 return ERROR_OK;
613 }
614
615 int cortex_m3_resume(struct target_s *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
616 {
617 /* get pointers to arch-specific information */
618 armv7m_common_t *armv7m = target->arch_info;
619 breakpoint_t *breakpoint = NULL;
620 uint32_t resume_pc;
621
622 if (target->state != TARGET_HALTED)
623 {
624 LOG_WARNING("target not halted");
625 return ERROR_TARGET_NOT_HALTED;
626 }
627
628 if (!debug_execution)
629 {
630 target_free_all_working_areas(target);
631 cortex_m3_enable_breakpoints(target);
632 cortex_m3_enable_watchpoints(target);
633 }
634
635 if (debug_execution)
636 {
637 /* Disable interrupts */
638 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
639 * This is probably the same issue as Cortex-M3 Errata 377493:
640 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
641 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
642 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1;
643 armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1;
644
645 /* Make sure we are in Thumb mode */
646 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
647 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1 << 24));
648 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
649 armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1;
650 }
651
652 /* current = 1: continue on current pc, otherwise continue at <address> */
653 if (!current)
654 {
655 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
656 armv7m->core_cache->reg_list[15].dirty = 1;
657 armv7m->core_cache->reg_list[15].valid = 1;
658 }
659
660 resume_pc = buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32);
661
662 armv7m_restore_context(target);
663
664 /* the front-end may request us not to handle breakpoints */
665 if (handle_breakpoints)
666 {
667 /* Single step past breakpoint at current address */
668 if ((breakpoint = breakpoint_find(target, resume_pc)))
669 {
670 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
671 breakpoint->address,
672 breakpoint->unique_id );
673 cortex_m3_unset_breakpoint(target, breakpoint);
674 cortex_m3_single_step_core(target);
675 cortex_m3_set_breakpoint(target, breakpoint);
676 }
677 }
678
679 /* Restart core */
680 cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
681
682 target->debug_reason = DBG_REASON_NOTHALTED;
683
684 /* registers are now invalid */
685 armv7m_invalidate_core_regs(target);
686 if (!debug_execution)
687 {
688 target->state = TARGET_RUNNING;
689 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
690 LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
691 }
692 else
693 {
694 target->state = TARGET_DEBUG_RUNNING;
695 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
696 LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
697 }
698
699 return ERROR_OK;
700 }
701
702 /* int irqstepcount = 0; */
703 int cortex_m3_step(struct target_s *target, int current, uint32_t address, int handle_breakpoints)
704 {
705 /* get pointers to arch-specific information */
706 armv7m_common_t *armv7m = target->arch_info;
707 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
708 swjdp_common_t *swjdp = &armv7m->swjdp_info;
709 breakpoint_t *breakpoint = NULL;
710
711 if (target->state != TARGET_HALTED)
712 {
713 LOG_WARNING("target not halted");
714 return ERROR_TARGET_NOT_HALTED;
715 }
716
717 /* current = 1: continue on current pc, otherwise continue at <address> */
718 if (!current)
719 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
720
721 /* the front-end may request us not to handle breakpoints */
722 if (handle_breakpoints)
723 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32))))
724 cortex_m3_unset_breakpoint(target, breakpoint);
725
726 target->debug_reason = DBG_REASON_SINGLESTEP;
727
728 armv7m_restore_context(target);
729
730 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
731
732 /* set step and clear halt */
733 cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
734 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
735
736 /* registers are now invalid */
737 armv7m_invalidate_core_regs(target);
738
739 if (breakpoint)
740 cortex_m3_set_breakpoint(target, breakpoint);
741
742 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32 " nvic_icsr = 0x%" PRIx32 "", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
743
744 cortex_m3_debug_entry(target);
745 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
746
747 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32 " nvic_icsr = 0x%" PRIx32 "", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
748 return ERROR_OK;
749 }
750
751 int cortex_m3_assert_reset(target_t *target)
752 {
753 armv7m_common_t *armv7m = target->arch_info;
754 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
755 swjdp_common_t *swjdp = &armv7m->swjdp_info;
756 int assert_srst = 1;
757
758 LOG_DEBUG("target->state: %s",
759 target_state_name(target));
760
761 enum reset_types jtag_reset_config = jtag_get_reset_config();
762 if (!(jtag_reset_config & RESET_HAS_SRST))
763 {
764 LOG_ERROR("Can't assert SRST");
765 return ERROR_FAIL;
766 }
767
768 /* Enable debug requests */
769 mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
770 if (!(cortex_m3->dcb_dhcsr & C_DEBUGEN))
771 mem_ap_write_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN);
772
773 mem_ap_write_u32(swjdp, DCB_DCRDR, 0);
774
775 if (!target->reset_halt)
776 {
777 /* Set/Clear C_MASKINTS in a separate operation */
778 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
779 mem_ap_write_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT);
780
781 /* clear any debug flags before resuming */
782 cortex_m3_clear_halt(target);
783
784 /* clear C_HALT in dhcsr reg */
785 cortex_m3_write_debug_halt_mask(target, 0, C_HALT);
786
787 /* Enter debug state on reset, cf. end_reset_event() */
788 mem_ap_write_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR);
789 }
790 else
791 {
792 /* Enter debug state on reset, cf. end_reset_event() */
793 mem_ap_write_atomic_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET);
794 }
795
796 /* following hack is to handle luminary reset
797 * when srst is asserted the luminary device seesm to also clear the debug registers
798 * which does not match the armv7 debug TRM */
799
800 if (strcmp(target->variant, "lm3s") == 0)
801 {
802 /* get revision of lm3s target, only early silicon has this issue
803 * Fury Rev B, DustDevil Rev B, Tempest all ok */
804
805 uint32_t did0;
806
807 if (target_read_u32(target, 0x400fe000, &did0) == ERROR_OK)
808 {
809 switch ((did0 >> 16) & 0xff)
810 {
811 case 0:
812 /* all Sandstorm suffer issue */
813 assert_srst = 0;
814 break;
815
816 case 1:
817 case 3:
818 /* only Fury/DustDevil rev A suffer reset problems */
819 if (((did0 >> 8) & 0xff) == 0)
820 assert_srst = 0;
821 break;
822 }
823 }
824 }
825
826 if (assert_srst)
827 {
828 /* default to asserting srst */
829 if (jtag_reset_config & RESET_SRST_PULLS_TRST)
830 {
831 jtag_add_reset(1, 1);
832 }
833 else
834 {
835 jtag_add_reset(0, 1);
836 }
837 }
838 else
839 {
840 /* this causes the luminary device to reset using the watchdog */
841 mem_ap_write_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ);
842 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
843
844 {
845 /* I do not know why this is necessary, but it fixes strange effects
846 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
847 uint32_t tmp;
848 mem_ap_read_atomic_u32(swjdp, NVIC_AIRCR, &tmp);
849 }
850 }
851
852 target->state = TARGET_RESET;
853 jtag_add_sleep(50000);
854
855 armv7m_invalidate_core_regs(target);
856
857 if (target->reset_halt)
858 {
859 int retval;
860 if ((retval = target_halt(target)) != ERROR_OK)
861 return retval;
862 }
863
864 return ERROR_OK;
865 }
866
867 int cortex_m3_deassert_reset(target_t *target)
868 {
869 LOG_DEBUG("target->state: %s",
870 target_state_name(target));
871
872 /* deassert reset lines */
873 jtag_add_reset(0, 0);
874
875 return ERROR_OK;
876 }
877
878 void cortex_m3_enable_breakpoints(struct target_s *target)
879 {
880 breakpoint_t *breakpoint = target->breakpoints;
881
882 /* set any pending breakpoints */
883 while (breakpoint)
884 {
885 if (breakpoint->set == 0)
886 cortex_m3_set_breakpoint(target, breakpoint);
887 breakpoint = breakpoint->next;
888 }
889 }
890
891 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
892 {
893 int retval;
894 int fp_num = 0;
895 uint32_t hilo;
896
897 /* get pointers to arch-specific information */
898 armv7m_common_t *armv7m = target->arch_info;
899 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
900
901 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
902
903 if (breakpoint->set)
904 {
905 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint->unique_id);
906 return ERROR_OK;
907 }
908
909 if (cortex_m3->auto_bp_type)
910 {
911 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
912 }
913
914 if (breakpoint->type == BKPT_HARD)
915 {
916 while (comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
917 fp_num++;
918 if (fp_num >= cortex_m3->fp_num_code)
919 {
920 LOG_DEBUG("ERROR Can not find free FP Comparator");
921 LOG_WARNING("ERROR Can not find free FP Comparator");
922 exit(-1);
923 }
924 breakpoint->set = fp_num + 1;
925 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
926 comparator_list[fp_num].used = 1;
927 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
928 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
929 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32 "", fp_num, comparator_list[fp_num].fpcr_value);
930 if (!cortex_m3->fpb_enabled)
931 {
932 LOG_DEBUG("FPB wasn't enabled, do it now");
933 target_write_u32(target, FP_CTRL, 3);
934 }
935 }
936 else if (breakpoint->type == BKPT_SOFT)
937 {
938 uint8_t code[4];
939 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
940 if ((retval = target_read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK)
941 {
942 return retval;
943 }
944 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code)) != ERROR_OK)
945 {
946 return retval;
947 }
948 breakpoint->set = 0x11; /* Any nice value but 0 */
949 }
950
951 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
952 breakpoint->unique_id,
953 (int)(breakpoint->type),
954 breakpoint->address,
955 breakpoint->length,
956 breakpoint->set);
957
958 return ERROR_OK;
959 }
960
961 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
962 {
963 int retval;
964 /* get pointers to arch-specific information */
965 armv7m_common_t *armv7m = target->arch_info;
966 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
967 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
968
969 if (!breakpoint->set)
970 {
971 LOG_WARNING("breakpoint not set");
972 return ERROR_OK;
973 }
974
975 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32 " Length: %d (set=%d)",
976 breakpoint->unique_id,
977 (int)(breakpoint->type),
978 breakpoint->address,
979 breakpoint->length,
980 breakpoint->set);
981
982 if (breakpoint->type == BKPT_HARD)
983 {
984 int fp_num = breakpoint->set - 1;
985 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
986 {
987 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
988 return ERROR_OK;
989 }
990 comparator_list[fp_num].used = 0;
991 comparator_list[fp_num].fpcr_value = 0;
992 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
993 }
994 else
995 {
996 /* restore original instruction (kept in target endianness) */
997 if (breakpoint->length == 4)
998 {
999 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr)) != ERROR_OK)
1000 {
1001 return retval;
1002 }
1003 }
1004 else
1005 {
1006 if ((retval = target_write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr)) != ERROR_OK)
1007 {
1008 return retval;
1009 }
1010 }
1011 }
1012 breakpoint->set = 0;
1013
1014 return ERROR_OK;
1015 }
1016
1017 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1018 {
1019 /* get pointers to arch-specific information */
1020 armv7m_common_t *armv7m = target->arch_info;
1021 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1022
1023 if (cortex_m3->auto_bp_type)
1024 {
1025 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
1026 #ifdef ARMV7_GDB_HACKS
1027 if (breakpoint->length != 2) {
1028 /* XXX Hack: Replace all breakpoints with length != 2 with
1029 * a hardware breakpoint. */
1030 breakpoint->type = BKPT_HARD;
1031 breakpoint->length = 2;
1032 }
1033 #endif
1034 }
1035
1036 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
1037 {
1038 LOG_INFO("flash patch comparator requested outside code memory region");
1039 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1040 }
1041
1042 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
1043 {
1044 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1045 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1046 }
1047
1048 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
1049 {
1050 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1051 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1052 }
1053
1054 if ((breakpoint->length != 2))
1055 {
1056 LOG_INFO("only breakpoints of two bytes length supported");
1057 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1058 }
1059
1060 if (breakpoint->type == BKPT_HARD)
1061 cortex_m3->fp_code_available--;
1062 cortex_m3_set_breakpoint(target, breakpoint);
1063
1064 return ERROR_OK;
1065 }
1066
1067 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
1068 {
1069 /* get pointers to arch-specific information */
1070 armv7m_common_t *armv7m = target->arch_info;
1071 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1072
1073 if (target->state != TARGET_HALTED)
1074 {
1075 LOG_WARNING("target not halted");
1076 return ERROR_TARGET_NOT_HALTED;
1077 }
1078
1079 if (cortex_m3->auto_bp_type)
1080 {
1081 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
1082 }
1083
1084 if (breakpoint->set)
1085 {
1086 cortex_m3_unset_breakpoint(target, breakpoint);
1087 }
1088
1089 if (breakpoint->type == BKPT_HARD)
1090 cortex_m3->fp_code_available++;
1091
1092 return ERROR_OK;
1093 }
1094
1095 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1096 {
1097 int dwt_num = 0;
1098 uint32_t mask, temp;
1099
1100 /* get pointers to arch-specific information */
1101 armv7m_common_t *armv7m = target->arch_info;
1102 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1103 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1104
1105 if (watchpoint->set)
1106 {
1107 LOG_WARNING("watchpoint (%d) already set", watchpoint->unique_id );
1108 return ERROR_OK;
1109 }
1110
1111 if (watchpoint->mask == 0xffffffffu)
1112 {
1113 while (comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
1114 dwt_num++;
1115 if (dwt_num >= cortex_m3->dwt_num_comp)
1116 {
1117 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1118 LOG_WARNING("ERROR Can not find free DWT Comparator");
1119 return -1;
1120 }
1121 watchpoint->set = dwt_num + 1;
1122 mask = 0;
1123 temp = watchpoint->length;
1124 while (temp > 1)
1125 {
1126 temp = temp / 2;
1127 mask++;
1128 }
1129 comparator_list[dwt_num].used = 1;
1130 comparator_list[dwt_num].comp = watchpoint->address;
1131 comparator_list[dwt_num].mask = mask;
1132 comparator_list[dwt_num].function = watchpoint->rw + 5;
1133 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
1134 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x4, comparator_list[dwt_num].mask);
1135 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x8, comparator_list[dwt_num].function);
1136 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);
1137 }
1138 else
1139 {
1140 /* Move this test to add_watchpoint */
1141 LOG_WARNING("Cannot watch data values (id: %d)",
1142 watchpoint->unique_id );
1143 return ERROR_OK;
1144 }
1145 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
1146 watchpoint->unique_id, watchpoint->address, watchpoint->set );
1147 return ERROR_OK;
1148
1149 }
1150
1151 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1152 {
1153 /* get pointers to arch-specific information */
1154 armv7m_common_t *armv7m = target->arch_info;
1155 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1156 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1157 int dwt_num;
1158
1159 if (!watchpoint->set)
1160 {
1161 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint->unique_id );
1162 return ERROR_OK;
1163 }
1164
1165 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32 " set=%d ",
1166 watchpoint->unique_id, watchpoint->address,watchpoint->set );
1167
1168 dwt_num = watchpoint->set - 1;
1169
1170 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
1171 {
1172 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1173 return ERROR_OK;
1174 }
1175 comparator_list[dwt_num].used = 0;
1176 comparator_list[dwt_num].function = 0;
1177 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address | 0x8, comparator_list[dwt_num].function);
1178
1179 watchpoint->set = 0;
1180
1181 return ERROR_OK;
1182 }
1183
1184 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1185 {
1186 /* get pointers to arch-specific information */
1187 armv7m_common_t *armv7m = target->arch_info;
1188 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1189
1190 if (target->state != TARGET_HALTED)
1191 {
1192 LOG_WARNING("target not halted");
1193 return ERROR_TARGET_NOT_HALTED;
1194 }
1195
1196 if (cortex_m3->dwt_comp_available < 1)
1197 {
1198 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1199 }
1200
1201 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1202 {
1203 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1204 }
1205
1206 cortex_m3->dwt_comp_available--;
1207 LOG_DEBUG("dwt_comp_available: %d", cortex_m3->dwt_comp_available);
1208
1209 return ERROR_OK;
1210 }
1211
1212 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1213 {
1214 /* get pointers to arch-specific information */
1215 armv7m_common_t *armv7m = target->arch_info;
1216 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1217
1218 if (target->state != TARGET_HALTED)
1219 {
1220 LOG_WARNING("target not halted");
1221 return ERROR_TARGET_NOT_HALTED;
1222 }
1223
1224 if (watchpoint->set)
1225 {
1226 cortex_m3_unset_watchpoint(target, watchpoint);
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 void cortex_m3_enable_watchpoints(struct target_s *target)
1236 {
1237 watchpoint_t *watchpoint = target->watchpoints;
1238
1239 /* set any pending watchpoints */
1240 while (watchpoint)
1241 {
1242 if (watchpoint->set == 0)
1243 cortex_m3_set_watchpoint(target, watchpoint);
1244 watchpoint = watchpoint->next;
1245 }
1246 }
1247
1248 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t * value)
1249 {
1250 int retval;
1251 /* get pointers to arch-specific information */
1252 armv7m_common_t *armv7m = target->arch_info;
1253 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1254
1255 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1256 {
1257 /* read a normal core register */
1258 retval = cortexm3_dap_read_coreregister_u32(swjdp, value, num);
1259
1260 if (retval != ERROR_OK)
1261 {
1262 LOG_ERROR("JTAG failure %i",retval);
1263 return ERROR_JTAG_DEVICE_ERROR;
1264 }
1265 LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "",(int)num,*value);
1266 }
1267 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1268 {
1269 /* read other registers */
1270 cortexm3_dap_read_coreregister_u32(swjdp, value, 20);
1271
1272 switch (num)
1273 {
1274 case 19:
1275 *value = buf_get_u32((uint8_t*)value, 0, 8);
1276 break;
1277
1278 case 20:
1279 *value = buf_get_u32((uint8_t*)value, 8, 8);
1280 break;
1281
1282 case 21:
1283 *value = buf_get_u32((uint8_t*)value, 16, 8);
1284 break;
1285
1286 case 22:
1287 *value = buf_get_u32((uint8_t*)value, 24, 8);
1288 break;
1289 }
1290
1291 LOG_DEBUG("load from special reg %i value 0x%" PRIx32 "", (int)num, *value);
1292 }
1293 else
1294 {
1295 return ERROR_INVALID_ARGUMENTS;
1296 }
1297
1298 return ERROR_OK;
1299 }
1300
1301 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, uint32_t num, uint32_t value)
1302 {
1303 int retval;
1304 uint32_t reg;
1305
1306 /* get pointers to arch-specific information */
1307 armv7m_common_t *armv7m = target->arch_info;
1308 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1309
1310 #ifdef ARMV7_GDB_HACKS
1311 /* If the LR register is being modified, make sure it will put us
1312 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1313 * hack to deal with the fact that gdb will sometimes "forge"
1314 * return addresses, and doesn't set the LSB correctly (i.e., when
1315 * printing expressions containing function calls, it sets LR = 0.) */
1316
1317 if (num == 14)
1318 value |= 0x01;
1319 #endif
1320
1321 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1322 {
1323 retval = cortexm3_dap_write_coreregister_u32(swjdp, value, num);
1324 if (retval != ERROR_OK)
1325 {
1326 LOG_ERROR("JTAG failure %i", retval);
1327 armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
1328 return ERROR_JTAG_DEVICE_ERROR;
1329 }
1330 LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value);
1331 }
1332 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1333 {
1334 /* write other registers */
1335
1336 cortexm3_dap_read_coreregister_u32(swjdp, &reg, 20);
1337
1338 switch (num)
1339 {
1340 case 19:
1341 buf_set_u32((uint8_t*)&reg, 0, 8, value);
1342 break;
1343
1344 case 20:
1345 buf_set_u32((uint8_t*)&reg, 8, 8, value);
1346 break;
1347
1348 case 21:
1349 buf_set_u32((uint8_t*)&reg, 16, 8, value);
1350 break;
1351
1352 case 22:
1353 buf_set_u32((uint8_t*)&reg, 24, 8, value);
1354 break;
1355 }
1356
1357 cortexm3_dap_write_coreregister_u32(swjdp, reg, 20);
1358
1359 LOG_DEBUG("write special reg %i value 0x%" PRIx32 " ", (int)num, value);
1360 }
1361 else
1362 {
1363 return ERROR_INVALID_ARGUMENTS;
1364 }
1365
1366 return ERROR_OK;
1367 }
1368
1369 int cortex_m3_read_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
1370 {
1371 /* get pointers to arch-specific information */
1372 armv7m_common_t *armv7m = target->arch_info;
1373 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1374 int retval;
1375
1376 /* sanitize arguments */
1377 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1378 return ERROR_INVALID_ARGUMENTS;
1379
1380 /* cortex_m3 handles unaligned memory access */
1381
1382 switch (size)
1383 {
1384 case 4:
1385 retval = mem_ap_read_buf_u32(swjdp, buffer, 4 * count, address);
1386 break;
1387 case 2:
1388 retval = mem_ap_read_buf_u16(swjdp, buffer, 2 * count, address);
1389 break;
1390 case 1:
1391 retval = mem_ap_read_buf_u8(swjdp, buffer, count, address);
1392 break;
1393 default:
1394 LOG_ERROR("BUG: we shouldn't get here");
1395 exit(-1);
1396 }
1397
1398 return retval;
1399 }
1400
1401 int cortex_m3_write_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
1402 {
1403 /* get pointers to arch-specific information */
1404 armv7m_common_t *armv7m = target->arch_info;
1405 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1406 int retval;
1407
1408 /* sanitize arguments */
1409 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1410 return ERROR_INVALID_ARGUMENTS;
1411
1412 switch (size)
1413 {
1414 case 4:
1415 retval = mem_ap_write_buf_u32(swjdp, buffer, 4 * count, address);
1416 break;
1417 case 2:
1418 retval = mem_ap_write_buf_u16(swjdp, buffer, 2 * count, address);
1419 break;
1420 case 1:
1421 retval = mem_ap_write_buf_u8(swjdp, buffer, count, address);
1422 break;
1423 default:
1424 LOG_ERROR("BUG: we shouldn't get here");
1425 exit(-1);
1426 }
1427
1428 return retval;
1429 }
1430
1431 int cortex_m3_bulk_write_memory(target_t *target, uint32_t address, uint32_t count, uint8_t *buffer)
1432 {
1433 return cortex_m3_write_memory(target, address, 4, count, buffer);
1434 }
1435
1436 void cortex_m3_build_reg_cache(target_t *target)
1437 {
1438 armv7m_build_reg_cache(target);
1439 }
1440
1441 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1442 {
1443 cortex_m3_build_reg_cache(target);
1444 return ERROR_OK;
1445 }
1446
1447 int cortex_m3_examine(struct target_s *target)
1448 {
1449 int retval;
1450 uint32_t cpuid, fpcr, dwtcr, ictr;
1451 int i;
1452
1453 /* get pointers to arch-specific information */
1454 armv7m_common_t *armv7m = target->arch_info;
1455 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1456 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1457
1458 if ((retval = ahbap_debugport_init(swjdp)) != ERROR_OK)
1459 return retval;
1460
1461 if (!target_was_examined(target))
1462 {
1463 target_set_examined(target);
1464
1465 /* Read from Device Identification Registers */
1466 if ((retval = target_read_u32(target, CPUID, &cpuid)) != ERROR_OK)
1467 return retval;
1468
1469 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1470 LOG_DEBUG("CORTEX-M3 processor detected");
1471 LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid);
1472
1473 target_read_u32(target, NVIC_ICTR, &ictr);
1474 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1475 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1476 for (i = 0; i < cortex_m3->intlinesnum; i++)
1477 {
1478 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1479 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32 "", i, cortex_m3->intsetenable[i]);
1480 }
1481
1482 /* Setup FPB */
1483 target_read_u32(target, FP_CTRL, &fpcr);
1484 cortex_m3->auto_bp_type = 1;
1485 cortex_m3->fp_num_code = ((fpcr >> 8) & 0x70) | ((fpcr >> 4) & 0xF); /* bits [14:12] and [7:4] */
1486 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1487 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1488 cortex_m3->fp_comparator_list = calloc(cortex_m3->fp_num_code + cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1489 cortex_m3->fpb_enabled = fpcr & 1;
1490 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1491 {
1492 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1493 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1494 }
1495 LOG_DEBUG("FPB fpcr 0x%" PRIx32 ", numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1496
1497 /* Setup DWT */
1498 target_read_u32(target, DWT_CTRL, &dwtcr);
1499 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1500 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1501 cortex_m3->dwt_comparator_list = calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1502 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1503 {
1504 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1505 }
1506 }
1507
1508 return ERROR_OK;
1509 }
1510
1511 int cortex_m3_quit(void)
1512 {
1513
1514 return ERROR_OK;
1515 }
1516
1517 int cortex_m3_dcc_read(swjdp_common_t *swjdp, uint8_t *value, uint8_t *ctrl)
1518 {
1519 uint16_t dcrdr;
1520
1521 mem_ap_read_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1522 *ctrl = (uint8_t)dcrdr;
1523 *value = (uint8_t)(dcrdr >> 8);
1524
1525 LOG_DEBUG("data 0x%x ctrl 0x%x", *value, *ctrl);
1526
1527 /* write ack back to software dcc register
1528 * signify we have read data */
1529 if (dcrdr & (1 << 0))
1530 {
1531 dcrdr = 0;
1532 mem_ap_write_buf_u16(swjdp, (uint8_t*)&dcrdr, 1, DCB_DCRDR);
1533 }
1534
1535 return ERROR_OK;
1536 }
1537
1538 int cortex_m3_target_request_data(target_t *target, uint32_t size, uint8_t *buffer)
1539 {
1540 armv7m_common_t *armv7m = target->arch_info;
1541 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1542 uint8_t data;
1543 uint8_t ctrl;
1544 uint32_t i;
1545
1546 for (i = 0; i < (size * 4); i++)
1547 {
1548 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1549 buffer[i] = data;
1550 }
1551
1552 return ERROR_OK;
1553 }
1554
1555 int cortex_m3_handle_target_request(void *priv)
1556 {
1557 target_t *target = priv;
1558 if (!target_was_examined(target))
1559 return ERROR_OK;
1560 armv7m_common_t *armv7m = target->arch_info;
1561 swjdp_common_t *swjdp = &armv7m->swjdp_info;
1562
1563 if (!target->dbg_msg_enabled)
1564 return ERROR_OK;
1565
1566 if (target->state == TARGET_RUNNING)
1567 {
1568 uint8_t data;
1569 uint8_t ctrl;
1570
1571 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1572
1573 /* check if we have data */
1574 if (ctrl & (1 << 0))
1575 {
1576 uint32_t request;
1577
1578 /* we assume target is quick enough */
1579 request = data;
1580 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1581 request |= (data << 8);
1582 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1583 request |= (data << 16);
1584 cortex_m3_dcc_read(swjdp, &data, &ctrl);
1585 request |= (data << 24);
1586 target_request(target, request);
1587 }
1588 }
1589
1590 return ERROR_OK;
1591 }
1592
1593 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, jtag_tap_t *tap)
1594 {
1595 int retval;
1596 armv7m_common_t *armv7m;
1597 armv7m = &cortex_m3->armv7m;
1598
1599 armv7m_init_arch_info(target, armv7m);
1600
1601 /* prepare JTAG information for the new target */
1602 cortex_m3->jtag_info.tap = tap;
1603 cortex_m3->jtag_info.scann_size = 4;
1604
1605 armv7m->swjdp_info.dp_select_value = -1;
1606 armv7m->swjdp_info.ap_csw_value = -1;
1607 armv7m->swjdp_info.ap_tar_value = -1;
1608 armv7m->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1609 armv7m->swjdp_info.memaccess_tck = 8;
1610 armv7m->swjdp_info.tar_autoincr_block = (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1611
1612 /* initialize arch-specific breakpoint handling */
1613
1614 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1615 cortex_m3->arch_info = NULL;
1616
1617 /* register arch-specific functions */
1618 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1619
1620 armv7m->pre_debug_entry = NULL;
1621 armv7m->post_debug_entry = NULL;
1622
1623 armv7m->pre_restore_context = NULL;
1624 armv7m->post_restore_context = NULL;
1625
1626 armv7m->arch_info = cortex_m3;
1627 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1628 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1629
1630 target_register_timer_callback(cortex_m3_handle_target_request, 1, 1, target);
1631
1632 if ((retval = arm_jtag_setup_connection(&cortex_m3->jtag_info)) != ERROR_OK)
1633 {
1634 return retval;
1635 }
1636
1637 return ERROR_OK;
1638 }
1639
1640 int cortex_m3_target_create(struct target_s *target, Jim_Interp *interp)
1641 {
1642 cortex_m3_common_t *cortex_m3 = calloc(1,sizeof(cortex_m3_common_t));
1643
1644 cortex_m3_init_arch_info(target, cortex_m3, target->tap);
1645
1646 return ERROR_OK;
1647 }
1648
1649 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1650 {
1651 int retval;
1652 command_t *cortex_m3_cmd;
1653
1654 retval = armv7m_register_commands(cmd_ctx);
1655
1656 cortex_m3_cmd = register_command(cmd_ctx, NULL, "cortex_m3", NULL, COMMAND_ANY, "cortex_m3 specific commands");
1657 register_command(cmd_ctx, cortex_m3_cmd, "maskisr", handle_cortex_m3_mask_interrupts_command, COMMAND_EXEC, "mask cortex_m3 interrupts ['on'|'off']");
1658
1659 return retval;
1660 }
1661
1662 int handle_cortex_m3_mask_interrupts_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1663 {
1664 target_t *target = get_current_target(cmd_ctx);
1665 armv7m_common_t *armv7m = target->arch_info;
1666 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1667
1668 if (target->state != TARGET_HALTED)
1669 {
1670 command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
1671 return ERROR_OK;
1672 }
1673
1674 if (argc > 0)
1675 {
1676 if (!strcmp(args[0], "on"))
1677 {
1678 cortex_m3_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
1679 }
1680 else if (!strcmp(args[0], "off"))
1681 {
1682 cortex_m3_write_debug_halt_mask(target, C_HALT, C_MASKINTS);
1683 }
1684 else
1685 {
1686 command_print(cmd_ctx, "usage: cortex_m3 maskisr ['on'|'off']");
1687 }
1688 }
1689
1690 command_print(cmd_ctx, "cortex_m3 interrupt mask %s",
1691 (cortex_m3->dcb_dhcsr & C_MASKINTS) ? "on" : "off");
1692
1693 return ERROR_OK;
1694 }

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)