1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * Copyright (C) 2006 by Magnus Lundin *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
28 #include "replacements.h"
30 #include "cortex_m3.h"
42 int cortex_m3_register_commands(struct command_context_s *cmd_ctx);
44 /* forward declarations */
45 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target);
46 void cortex_m3_enable_breakpoints(struct target_s *target);
47 void cortex_m3_enable_watchpoints(struct target_s *target);
48 void cortex_m3_disable_bkpts_and_wpts(struct target_s *target);
49 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
50 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
52 int cortex_m3_load_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 *value);
53 int cortex_m3_store_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 value);
55 target_type_t cortexm3_target =
59 .poll = cortex_m3_poll,
60 .arch_state = armv7m_arch_state,
62 .halt = cortex_m3_halt,
63 .resume = cortex_m3_resume,
64 .step = cortex_m3_step,
66 .assert_reset = cortex_m3_assert_reset,
67 .deassert_reset = cortex_m3_deassert_reset,
68 .soft_reset_halt = cortex_m3_soft_reset_halt,
70 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
72 .read_memory = cortex_m3_read_memory,
73 .write_memory = cortex_m3_write_memory,
74 .bulk_write_memory = cortex_m3_bulk_write_memory,
76 .run_algorithm = armv7m_run_algorithm,
78 .add_breakpoint = cortex_m3_add_breakpoint,
79 .remove_breakpoint = cortex_m3_remove_breakpoint,
80 .add_watchpoint = cortex_m3_add_watchpoint,
81 .remove_watchpoint = cortex_m3_remove_watchpoint,
83 .register_commands = cortex_m3_register_commands,
84 .target_command = cortex_m3_target_command,
85 .init_target = cortex_m3_init_target,
86 .quit = cortex_m3_quit
89 int cortex_m3_clear_halt(target_t *target)
92 /* get pointers to arch-specific information */
93 armv7m_common_t *armv7m = target->arch_info;
94 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
95 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
97 /* Read Debug Fault Status Register */
98 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
99 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
100 ahbap_write_system_atomic_u32(swjdp, NVIC_DFSR, cortex_m3->nvic_dfsr);
101 DEBUG(" NVIC_DFSR 0x%x",cortex_m3->nvic_dfsr);
106 int cortex_m3_single_step_core(target_t *target)
108 /* get pointers to arch-specific information */
109 armv7m_common_t *armv7m = target->arch_info;
110 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
111 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
113 if (!(cortex_m3->dcb_dhcsr&C_MASKINTS))
114 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_HALT | C_DEBUGEN );
115 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_MASKINTS | C_STEP | C_DEBUGEN );
116 cortex_m3->dcb_dhcsr |= C_MASKINTS;
118 cortex_m3_clear_halt(target);
123 int cortex_m3_exec_opcode(target_t *target,u32 opcode, int len /* MODE, r0_invalue, &r0_outvalue */ )
125 /* get pointers to arch-specific information */
126 armv7m_common_t *armv7m = target->arch_info;
127 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
128 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
133 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
134 ahbap_write_system_u32(swjdp, 0x20000000, opcode);
135 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
136 cortex_m3_single_step_core(target);
137 armv7m->core_cache->reg_list[15].dirty=1;
138 retvalue = ahbap_write_system_atomic_u32(swjdp, 0x20000000, savedram);
144 /* Enable interrupts */
145 int cortex_m3_cpsie(target_t *target, u32 IF)
147 return cortex_m3_exec_opcode(target, ARMV7M_T_CPSIE(IF), 2);
150 /* Disable interrupts */
151 int cortex_m3_cpsid(target_t *target, u32 IF)
153 return cortex_m3_exec_opcode(target, ARMV7M_T_CPSID(IF), 2);
156 int cortex_m3_endreset_event(target_t *target)
160 /* get pointers to arch-specific information */
161 armv7m_common_t *armv7m = target->arch_info;
162 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
163 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
164 cortex_m3_fp_comparator_t *fp_list = cortex_m3->fp_comparator_list;
165 cortex_m3_dwt_comparator_t * dwt_list = cortex_m3->dwt_comparator_list;
168 /* Enable debug requests */
169 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
170 if (!(cortex_m3->dcb_dhcsr&C_DEBUGEN))
171 ahbap_write_system_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN );
172 /* Enable trace and dwt */
173 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA|VC_HARDERR|VC_BUSERR|VC_CORERESET );
174 /* Monitor bus faults */
175 ahbap_write_system_u32(swjdp, NVIC_SHCSR, SHCSR_BUSFAULTENA );
178 target_write_u32(target, FP_CTRL, 3);
180 /* Restore FPB registers */
181 for (i=0;i<cortex_m3->fp_num_code+cortex_m3->fp_num_lit;i++)
183 target_write_u32(target, fp_list[i].fpcr_address, fp_list[i].fpcr_value);
186 /* Restore DWT registers */
187 for (i=0;i<cortex_m3->dwt_num_comp;i++)
189 target_write_u32(target, dwt_list[i].dwt_comparator_address, dwt_list[i].comp);
190 target_write_u32(target, dwt_list[i].dwt_comparator_address|0x4, dwt_list[i].mask);
191 target_write_u32(target, dwt_list[i].dwt_comparator_address|0x8, dwt_list[i].function);
194 /* Make sure working_areas are all free */
195 target_free_all_working_areas(target);
197 /* We are in process context */
198 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
199 armv7m_invalidate_core_regs(target);
203 int cortex_m3_examine_debug_reason(target_t *target)
205 /* get pointers to arch-specific information */
206 armv7m_common_t *armv7m = target->arch_info;
207 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
208 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
210 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
211 /* only check the debug reason if we don't know it already */
213 if ((target->debug_reason != DBG_REASON_DBGRQ)
214 && (target->debug_reason != DBG_REASON_SINGLESTEP))
219 if (cortex_m3->nvic_dfsr & 0x2)
221 target->debug_reason = DBG_REASON_BREAKPOINT;
222 if (cortex_m3->nvic_dfsr & 0x4)
223 target->debug_reason = DBG_REASON_WPTANDBKPT;
225 else if (cortex_m3->nvic_dfsr & 0x4)
226 target->debug_reason = DBG_REASON_WATCHPOINT;
232 int cortex_m3_examine_exception_reason(target_t *target)
234 u32 shcsr,except_sr,cfsr=-1,except_ar=-1;
236 /* get pointers to arch-specific information */
237 armv7m_common_t *armv7m = target->arch_info;
238 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
239 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
241 ahbap_read_system_u32(swjdp, NVIC_SHCSR, &shcsr);
242 switch (armv7m->exception_number)
246 case 3: /* Hard Fault */
247 ahbap_read_system_atomic_u32(swjdp, NVIC_HFSR, &except_sr);
248 if (except_sr&0x40000000)
250 ahbap_read_system_u32(swjdp, NVIC_CFSR, &cfsr);
253 case 4: /* Memory Management */
254 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
255 ahbap_read_system_u32(swjdp, NVIC_MMFAR, &except_ar);
257 case 5: /* Bus Fault */
258 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
259 ahbap_read_system_u32(swjdp, NVIC_BFAR, &except_ar);
261 case 6: /* Usage Fault */
262 ahbap_read_system_u32(swjdp, NVIC_CFSR, &except_sr);
264 case 11: /* SVCall */
267 case 12: /* Debug Monitor */
268 ahbap_read_system_u32(swjdp, NVIC_DFSR, &except_sr);
270 case 14: /* PendSV */
273 case 15: /* SysTick */
281 swjdp_transaction_endcheck(swjdp);
282 DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x",armv7m_exception_string(armv7m->exception_number),shcsr,except_sr,cfsr, except_ar);
287 int cortex_m3_debug_entry(target_t *target)
289 int i, irq_is_pending;
293 /* get pointers to arch-specific information */
294 armv7m_common_t *armv7m = target->arch_info;
295 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
296 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
299 if (armv7m->pre_debug_entry)
300 armv7m->pre_debug_entry(target);
302 cortex_m3_clear_halt(target);
303 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
305 if ((retval = armv7m->examine_debug_reason(target)) != ERROR_OK)
308 /* Examine target state and mode */
309 /* First load register acessible through core debug port*/
310 for (i = 0; i < ARMV7M_PRIMASK; i++)
312 if (!armv7m->core_cache->reg_list[i].valid)
313 armv7m->read_core_reg(target, i);
316 xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
318 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
321 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
322 cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR&~0xff);
326 /* Now we can load SP core registers */
328 for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++)
330 if (!armv7m->core_cache->reg_list[i].valid)
331 armv7m->read_core_reg(target, i);
335 /* Are we in an exception handler */
336 armv7m->core_mode = (xPSR&0x1FF)?ARMV7M_MODE_HANDLER:ARMV7M_MODE_THREAD;
337 armv7m->exception_number = xPSR&0x1FF;;
338 if (armv7m->exception_number)
340 cortex_m3_examine_exception_reason(target);
343 DEBUG("entered debug state at PC 0x%x ", *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]);
345 if (armv7m->post_debug_entry)
346 armv7m->post_debug_entry(target);
351 int cortex_m3_restore_context(target_t *target)
355 /* get pointers to arch-specific information */
356 armv7m_common_t *armv7m = target->arch_info;
357 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
361 if (armv7m->pre_restore_context)
362 armv7m->pre_restore_context(target);
365 for (i = ARMV7NUMCOREREGS; i >= 0; i--)
367 for (i = ARMV7M_PSP; i >= 0; i--)
370 if (armv7m->core_cache->reg_list[i].dirty)
372 armv7m->write_core_reg(target, i);
376 if (armv7m->post_restore_context)
377 armv7m->post_restore_context(target);
383 enum target_state cortex_m3_poll(target_t *target)
386 u32 prev_target_state = target->state;
388 /* get pointers to arch-specific information */
389 armv7m_common_t *armv7m = target->arch_info;
390 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
391 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
393 /* Read from Debug Halting Control and Status Register */
394 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
395 if (retval != ERROR_OK)
397 target->state = TARGET_UNKNOWN;
398 return TARGET_UNKNOWN;
401 if (cortex_m3->dcb_dhcsr&S_RESET_ST)
403 target->state = TARGET_RESET;
404 return target->state;
406 else if (target->state==TARGET_RESET)
408 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
409 DEBUG("Exit from reset with dcb_dhcsr %x", cortex_m3->dcb_dhcsr);
410 cortex_m3_endreset_event(target);
411 target->state = TARGET_RUNNING;
412 prev_target_state = TARGET_RUNNING;
415 if (cortex_m3->dcb_dhcsr&S_HALT)
417 target->state = TARGET_HALTED;
419 if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET))
421 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
424 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
426 if (prev_target_state == TARGET_DEBUG_RUNNING)
429 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
432 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
438 if (cortex_m3->dcb_dhcsr&S_SLEEP)
439 target->state = TARGET_SLEEP;
443 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
444 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
445 DEBUG("dcb_dhcsr %x, nvic_dfsr %x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]);
446 return target->state;
449 int cortex_m3_halt(target_t *target)
451 /* get pointers to arch-specific information */
452 armv7m_common_t *armv7m = target->arch_info;
453 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
454 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
456 DEBUG("target->state: %s", target_state_strings[target->state]);
458 /* Write to Debug Halting Control and Status Register */
459 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
461 target->debug_reason = DBG_REASON_DBGRQ;
466 int cortex_m3_soft_reset_halt(struct target_s *target)
468 /* get pointers to arch-specific information */
469 armv7m_common_t *armv7m = target->arch_info;
470 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
471 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
473 int retval, timeout=0;
475 /* Check that we are using process_context, or change and print warning */
476 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
478 DEBUG("Changing to process contex registers");
479 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
482 /* Enter debug state on reset, cf. end_reset_event() */
483 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA|VC_HARDERR|VC_BUSERR|VC_CORERESET );
485 /* Request a reset */
486 ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET );
487 target->state = TARGET_RESET;
489 /* registers are now invalid */
490 armv7m_invalidate_core_regs(target);
494 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
495 if (retval == ERROR_OK)
497 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
498 if ( (dcb_dhcsr&S_HALT)&&(cortex_m3->nvic_dfsr&DFSR_VCATCH) )
500 DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x",dcb_dhcsr,cortex_m3->nvic_dfsr);
501 cortex_m3_poll(target);
505 DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms",dcb_dhcsr,timeout);
514 int cortex_m3_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
516 /* get pointers to arch-specific information */
517 armv7m_common_t *armv7m = target->arch_info;
518 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
519 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
520 breakpoint_t *breakpoint = NULL;
521 u32 dcb_dhcsr, resume_pc;
523 if (target->state != TARGET_HALTED)
525 WARNING("target not halted");
526 return ERROR_TARGET_NOT_HALTED;
529 if (!debug_execution)
531 /* Check that we are using process_context, or change and print warning */
532 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
534 WARNING("Incorrect context in resume");
535 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
539 target_free_all_working_areas(target);
540 cortex_m3_enable_breakpoints(target);
541 cortex_m3_enable_watchpoints(target);
543 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
547 dcb_dhcsr = DBGKEY | C_DEBUGEN;
550 /* Check that we are using debug_context, or change and print warning */
551 if (armv7m_get_context(target) != ARMV7M_DEBUG_CONTEXT)
553 WARNING("Incorrect context in debug_exec resume");
554 armv7m_use_context(target, ARMV7M_DEBUG_CONTEXT);
556 /* Disable interrupts */
558 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
559 This is probably the same inssue as Cortex-M3 Errata 377493:
560 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
562 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
563 /* Make sure we are in Thumb mode */
564 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
565 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32)|(1<<24));
568 /* current = 1: continue on current pc, otherwise continue at <address> */
571 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
572 armv7m->core_cache->reg_list[15].dirty = 1;
573 armv7m->core_cache->reg_list[15].valid = 1;
576 resume_pc = buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32);
578 cortex_m3_restore_context(target);
580 /* the front-end may request us not to handle breakpoints */
581 if (handle_breakpoints)
583 /* Single step past breakpoint at current address */
584 if ((breakpoint = breakpoint_find(target, resume_pc)))
586 DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
587 cortex_m3_unset_breakpoint(target, breakpoint);
588 cortex_m3_single_step_core(target);
589 cortex_m3_set_breakpoint(target, breakpoint);
593 /* Set/Clear C_MASKINTS in a separate operation */
594 if ((cortex_m3->dcb_dhcsr&C_MASKINTS) != (dcb_dhcsr&C_MASKINTS))
595 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr | C_HALT );
597 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr );
598 target->debug_reason = DBG_REASON_NOTHALTED;
600 /* registers are now invalid */
601 armv7m_invalidate_core_regs(target);
602 if (!debug_execution)
604 target->state = TARGET_RUNNING;
605 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
606 DEBUG("target resumed at 0x%x",resume_pc);
610 target->state = TARGET_DEBUG_RUNNING;
611 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
612 DEBUG("target debug resumed at 0x%x",resume_pc);
620 int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
622 /* get pointers to arch-specific information */
623 armv7m_common_t *armv7m = target->arch_info;
624 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
625 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
626 breakpoint_t *breakpoint = NULL;
628 if (target->state != TARGET_HALTED)
630 WARNING("target not halted");
631 return ERROR_TARGET_NOT_HALTED;
634 /* Check that we are using process_context, or change and print warning */
635 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
637 WARNING("Incorrect context in step, must be process");
638 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
641 /* current = 1: continue on current pc, otherwise continue at <address> */
643 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
645 /* the front-end may request us not to handle breakpoints */
646 if (handle_breakpoints)
647 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32))))
648 cortex_m3_unset_breakpoint(target, breakpoint);
650 target->debug_reason = DBG_REASON_SINGLESTEP;
652 cortex_m3_restore_context(target);
654 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
656 if (cortex_m3->dcb_dhcsr&C_MASKINTS)
657 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
658 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
659 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
661 /* If we run in process context then registers are now invalid */
662 if (armv7m_get_context(target) == ARMV7M_PROCESS_CONTEXT)
663 armv7m_invalidate_core_regs(target);
666 cortex_m3_set_breakpoint(target, breakpoint);
668 DEBUG("target stepped dcb_dhcsr=0x%x nvic_icsr=0x%x",cortex_m3->dcb_dhcsr,cortex_m3->nvic_icsr);
670 cortex_m3_debug_entry(target);
671 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
673 DEBUG("target stepped dcb_dhcsr=0x%x nvic_icsr=0x%x",cortex_m3->dcb_dhcsr,cortex_m3->nvic_icsr);
678 int cortex_m3_assert_reset(target_t *target)
682 DEBUG("target->state: %s", target_state_strings[target->state]);
684 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
686 /* assert SRST and TRST */
687 /* system would get ouf sync if we didn't reset test-logic, too */
688 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
690 if (retval == ERROR_JTAG_RESET_CANT_SRST)
692 WARNING("can't assert srst");
697 ERROR("unknown error");
701 jtag_add_sleep(5000);
702 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
704 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
706 WARNING("srst resets test logic, too");
707 retval = jtag_add_reset(1, 1);
713 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
715 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
717 WARNING("srst resets test logic, too");
718 retval = jtag_add_reset(1, 1);
721 if (retval == ERROR_JTAG_RESET_CANT_SRST)
723 WARNING("can't assert srsrt");
726 else if (retval != ERROR_OK)
728 ERROR("unknown error");
734 target->state = TARGET_RESET;
735 jtag_add_sleep(50000);
737 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
738 armv7m_invalidate_core_regs(target);
744 int cortex_m3_deassert_reset(target_t *target)
746 DEBUG("target->state: %s", target_state_strings[target->state]);
748 /* deassert reset lines */
749 jtag_add_reset(0, 0);
755 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target)
759 void cortex_m3_enable_breakpoints(struct target_s *target)
761 breakpoint_t *breakpoint = target->breakpoints;
763 /* set any pending breakpoints */
766 if (breakpoint->set == 0)
767 cortex_m3_set_breakpoint(target, breakpoint);
768 breakpoint = breakpoint->next;
772 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
777 /* get pointers to arch-specific information */
778 armv7m_common_t *armv7m = target->arch_info;
779 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
781 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
785 WARNING("breakpoint already set");
789 if (cortex_m3->auto_bp_type)
791 breakpoint->type = (breakpoint->address<0x20000000)?BKPT_HARD:BKPT_SOFT;
794 if (breakpoint->type == BKPT_HARD)
796 while(comparator_list[fp_num].used && (fp_num<cortex_m3->fp_num_code))
798 if (fp_num>=cortex_m3->fp_num_code)
800 DEBUG("ERROR Can not find free FP Comparator");
801 WARNING("ERROR Can not find free FP Comparator");
804 breakpoint->set = fp_num+1;
805 hilo = (breakpoint->address & 0x2)? FPCR_REPLACE_BKPT_HIGH:FPCR_REPLACE_BKPT_LOW;
806 comparator_list[fp_num].used = 1;
807 comparator_list[fp_num].fpcr_value = breakpoint->address&0x1FFFFFFC | hilo | 1;
808 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
809 DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
811 else if (breakpoint->type == BKPT_SOFT)
814 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
815 target->type->read_memory(target, breakpoint->address&0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
816 target->type->write_memory(target, breakpoint->address&0xFFFFFFFE, breakpoint->length, 1, code);
817 breakpoint->set = 0x11; /* Any nice value but 0 */
824 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
826 /* get pointers to arch-specific information */
827 armv7m_common_t *armv7m = target->arch_info;
828 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
829 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
831 if (!breakpoint->set)
833 WARNING("breakpoint not set");
837 if (breakpoint->type == BKPT_HARD)
839 int fp_num = breakpoint->set-1;
840 if ((fp_num<0)||(fp_num>=cortex_m3->fp_num_code))
842 DEBUG("Invalid FP Comparator number in breakpoint");
845 comparator_list[fp_num].used = 0;
846 comparator_list[fp_num].fpcr_value = 0;
847 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
851 /* restore original instruction (kept in target endianness) */
852 if (breakpoint->length == 4)
854 target->type->write_memory(target, breakpoint->address&0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
858 target->type->write_memory(target, breakpoint->address&0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
867 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
869 /* get pointers to arch-specific information */
870 armv7m_common_t *armv7m = target->arch_info;
871 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
873 if (cortex_m3->auto_bp_type)
875 breakpoint->type = (breakpoint->address<0x20000000)?BKPT_HARD:BKPT_SOFT;
878 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address>=0x20000000))
880 INFO("flash patch comparator requested outside code memory region");
881 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
884 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address<0x20000000))
886 INFO("soft breakpoint requested in code (flash) memory region");
887 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
890 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
892 INFO("no flash patch comparator unit available for hardware breakpoint");
893 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
896 if ((breakpoint->length != 2))
898 INFO("only breakpoints of two bytes length supported");
899 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
902 if (breakpoint->type == BKPT_HARD)
903 cortex_m3->fp_code_available--;
904 cortex_m3_set_breakpoint(target, breakpoint);
909 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
911 /* get pointers to arch-specific information */
912 armv7m_common_t *armv7m = target->arch_info;
913 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
915 if (target->state != TARGET_HALTED)
917 WARNING("target not halted");
918 return ERROR_TARGET_NOT_HALTED;
921 if (cortex_m3->auto_bp_type)
923 breakpoint->type = (breakpoint->address<0x20000000)?BKPT_HARD:BKPT_SOFT;
928 cortex_m3_unset_breakpoint(target, breakpoint);
931 if (breakpoint->type == BKPT_HARD)
932 cortex_m3->fp_code_available++;
937 void cortex_m3_enable_watchpoints(struct target_s *target)
939 watchpoint_t *watchpoint = target->watchpoints;
941 /* set any pending watchpoints */
944 if (watchpoint->set == 0)
945 cortex_m3_set_watchpoint(target, watchpoint);
946 watchpoint = watchpoint->next;
950 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
955 /* get pointers to arch-specific information */
956 armv7m_common_t *armv7m = target->arch_info;
957 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
958 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
962 WARNING("watchpoint already set");
966 if (watchpoint->mask == 0xffffffffu)
968 while(comparator_list[dwt_num].used && (dwt_num<cortex_m3->dwt_num_comp))
970 if (dwt_num>=cortex_m3->dwt_num_comp)
972 DEBUG("ERROR Can not find free DWT Comparator");
973 WARNING("ERROR Can not find free DWT Comparator");
976 watchpoint->set = dwt_num+1;
978 temp = watchpoint->length;
984 comparator_list[dwt_num].used = 1;
985 comparator_list[dwt_num].comp = watchpoint->address;
986 comparator_list[dwt_num].mask = mask;
987 comparator_list[dwt_num].function = watchpoint->rw+5;
988 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
989 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
990 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
991 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);
995 WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1003 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1005 /* get pointers to arch-specific information */
1006 armv7m_common_t *armv7m = target->arch_info;
1007 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1008 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
1011 if (!watchpoint->set)
1013 WARNING("watchpoint not set");
1017 dwt_num = watchpoint->set-1;
1019 if ((dwt_num<0)||(dwt_num>=cortex_m3->dwt_num_comp))
1021 DEBUG("Invalid DWT Comparator number in watchpoint");
1024 comparator_list[dwt_num].used = 0;
1025 comparator_list[dwt_num].function = 0;
1026 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1028 watchpoint->set = 0;
1035 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1037 /* get pointers to arch-specific information */
1038 armv7m_common_t *armv7m = target->arch_info;
1039 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1041 if (target->state != TARGET_HALTED)
1043 WARNING("target not halted");
1044 return ERROR_TARGET_NOT_HALTED;
1047 if (cortex_m3->dwt_comp_available < 1)
1049 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1052 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1054 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1057 cortex_m3->dwt_comp_available--;
1062 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1064 /* get pointers to arch-specific information */
1065 armv7m_common_t *armv7m = target->arch_info;
1066 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1068 if (target->state != TARGET_HALTED)
1070 WARNING("target not halted");
1071 return ERROR_TARGET_NOT_HALTED;
1074 if (watchpoint->set)
1076 cortex_m3_unset_watchpoint(target, watchpoint);
1079 cortex_m3->dwt_comp_available++;
1085 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
1088 /* get pointers to arch-specific information */
1089 armv7m_common_t *armv7m = target->arch_info;
1090 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1091 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1093 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1095 /* read a normal core register */
1096 retval = ahbap_read_coreregister_u32(swjdp, value, num);
1098 if (retval != ERROR_OK)
1100 ERROR("JTAG failure %i",retval);
1101 return ERROR_JTAG_DEVICE_ERROR;
1103 //DEBUG("load from core reg %i value 0x%x",num,*value);
1105 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1107 /* read other registers */
1108 /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */
1113 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1114 instr = ARMV7M_T_MRS(0, SYSm);
1115 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MRS(0, SYSm));
1116 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1117 cortex_m3_single_step_core(target);
1118 ahbap_read_coreregister_u32(swjdp, value, 0);
1119 armv7m->core_cache->reg_list[0].dirty=1;
1120 armv7m->core_cache->reg_list[15].dirty=1;
1121 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1122 swjdp_transaction_endcheck(swjdp);
1123 DEBUG("load from special reg %i value 0x%x",SYSm, *value);
1125 else return ERROR_INVALID_ARGUMENTS;
1131 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
1135 /* get pointers to arch-specific information */
1136 armv7m_common_t *armv7m = target->arch_info;
1137 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1138 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1140 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1142 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1143 if (retval != ERROR_OK)
1145 ERROR("JTAG failure %i",retval);
1146 armv7m->core_cache->reg_list[num].dirty=1;
1147 return ERROR_JTAG_DEVICE_ERROR;
1149 DEBUG("write core reg %i value 0x%x",num, value);
1151 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1153 /* write other registers */
1154 u32 savedram , tempr0;
1158 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1159 instr = ARMV7M_T_MSR(SYSm, 0);
1160 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MSR(SYSm, 0));
1161 ahbap_read_coreregister_u32(swjdp, &tempr0, 0);
1162 ahbap_write_coreregister_u32(swjdp, value, 0);
1163 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1164 cortex_m3_single_step_core(target);
1165 ahbap_write_coreregister_u32(swjdp, tempr0, 0);
1166 armv7m->core_cache->reg_list[15].dirty=1;
1167 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1168 swjdp_transaction_endcheck(swjdp);
1169 DEBUG("write special reg %i value 0x%x ",SYSm, value);
1171 else return ERROR_INVALID_ARGUMENTS;
1178 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1181 /* get pointers to arch-specific information */
1182 armv7m_common_t *armv7m = target->arch_info;
1183 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1184 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1186 /* sanitize arguments */
1187 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1188 return ERROR_INVALID_ARGUMENTS;
1190 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1191 return ERROR_TARGET_UNALIGNED_ACCESS;
1193 /* Is not optimal, autoincrement of tar should be used ( ahbap_block_read and CSW_ADDRINC_SINGLE ) */
1197 /* TODOLATER Check error return value ! */
1199 ahbap_read_buf(swjdp, buffer, 4*count, address);
1204 ahbap_read_buf(swjdp, buffer, 2*count, address);
1209 ahbap_read_buf(swjdp, buffer, count, address);
1213 ERROR("BUG: we shouldn't get here");
1221 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1224 /* get pointers to arch-specific information */
1225 armv7m_common_t *armv7m = target->arch_info;
1226 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1227 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1229 /* sanitize arguments */
1230 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1231 return ERROR_INVALID_ARGUMENTS;
1233 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1234 return ERROR_TARGET_UNALIGNED_ACCESS;
1239 /* TODOLATER Check error return value ! */
1241 ahbap_write_buf(swjdp, buffer, 4*count, address);
1246 ahbap_write_buf(swjdp, buffer, 2*count, address);
1251 ahbap_write_buf(swjdp, buffer, count, address);
1255 ERROR("BUG: we shouldn't get here");
1262 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1265 cortex_m3_write_memory(target, address, 4,count,buffer);
1272 void cortex_m3_build_reg_cache(target_t *target)
1274 armv7m_build_reg_cache(target);
1277 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1279 u32 did1, dc0, cpuid, fpcr, dwtcr, ictr;
1282 /* get pointers to arch-specific information */
1283 armv7m_common_t *armv7m = target->arch_info;
1284 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1285 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1287 cortex_m3_build_reg_cache(target);
1288 ahbap_debugport_init(swjdp);
1290 /* Read from Device Identification Registers, IS THIS CORTEX OR Luminary Micro SPECIFIC ?? */
1291 target_read_u32(target, CPUID, &cpuid );
1292 if (cpuid == 0x410fc231)
1293 DEBUG("CORTEX-M3 processor");
1294 DEBUG("cpuid %x",cpuid);
1295 /* Probably only valid for LMI parts, move to flash/stellaris ? */
1296 target_read_u32(target, SYSTEM_CONTROL_BASE|0x04, &did1);
1297 target_read_u32(target,SYSTEM_CONTROL_BASE|0x08,&dc0);
1298 DEBUG("did1 %x",did1);
1299 DEBUG("dc0 %x",dc0);
1301 target_read_u32(target,NVIC_ICTR,&ictr);
1302 cortex_m3->intlinesnum = (ictr&0x1F) + 1;
1303 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum,4);
1304 for (i=0;i<cortex_m3->intlinesnum;i++)
1306 target_read_u32(target,NVIC_ISE0+4*i,cortex_m3->intsetenable+i);
1307 DEBUG(" interrupt enable[%i]=0x%x",i,cortex_m3->intsetenable[i]);
1311 target_read_u32(target, FP_CTRL, &fpcr);
1312 cortex_m3->auto_bp_type = 1;
1313 cortex_m3->fp_num_code = (fpcr>>4)&0xF;
1314 cortex_m3->fp_num_lit = (fpcr>>8)&0xF;
1315 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1316 cortex_m3->fp_comparator_list=calloc(cortex_m3->fp_num_code+cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1317 for (i=0;i<cortex_m3->fp_num_code+cortex_m3->fp_num_lit;i++)
1319 cortex_m3->fp_comparator_list[i].type = (i<cortex_m3->fp_num_code)?FPCR_CODE:FPCR_LITERAL;
1320 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0+4*i;
1322 DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i",fpcr,cortex_m3->fp_num_code,cortex_m3->fp_num_lit);
1325 target_read_u32(target, DWT_CTRL, &dwtcr);
1326 cortex_m3->dwt_num_comp = (dwtcr>>28)&0xF;
1327 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1328 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1329 for (i=0; i<cortex_m3->dwt_num_comp; i++)
1331 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0+0x10*i;
1337 int cortex_m3_quit()
1343 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
1345 armv7m_common_t *armv7m;
1346 armv7m = &cortex_m3->armv7m;
1348 arm_jtag_t * jtag_info = &cortex_m3->jtag_info;
1350 /* prepare JTAG information for the new target */
1351 cortex_m3->jtag_info.chain_pos = chain_pos;
1352 cortex_m3->jtag_info.scann_size = 4;
1354 cortex_m3->swjdp_info.dp_select_value = -1;
1355 cortex_m3->swjdp_info.ap_csw_value = -1;
1356 cortex_m3->swjdp_info.ap_tar_value = -1;
1357 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1359 /* initialize arch-specific breakpoint handling */
1361 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1362 cortex_m3->arch_info = NULL;
1364 /* register arch-specific functions */
1365 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1367 armv7m->pre_debug_entry = NULL;
1368 armv7m->post_debug_entry = NULL;
1370 armv7m->pre_restore_context = NULL;
1371 armv7m->post_restore_context = NULL;
1373 armv7m_init_arch_info(target, armv7m);
1374 armv7m->arch_info = cortex_m3;
1375 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1376 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1377 // armv7m->full_context = cortex_m3_full_context;
1382 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1383 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1386 char *variant = NULL;
1387 cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
1391 ERROR("'target cortex_m3' requires at least one additional argument");
1395 chain_pos = strtoul(args[3], NULL, 0);
1400 cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
1401 cortex_m3_register_commands(cmd_ctx);
1406 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1410 retval = armv7m_register_commands(cmd_ctx);