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

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)