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

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)