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

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)