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

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)