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"
43 int cortex_m3_register_commands(struct command_context_s *cmd_ctx);
45 /* forward declarations */
46 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target);
47 void cortex_m3_enable_breakpoints(struct target_s *target);
48 void cortex_m3_enable_watchpoints(struct target_s *target);
49 void cortex_m3_disable_bkpts_and_wpts(struct target_s *target);
50 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target);
51 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target);
53 int cortex_m3_load_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 *value);
54 int cortex_m3_store_core_reg_u32(target_t *target, enum armv7m_regtype type, u32 num, u32 value);
56 target_type_t cortexm3_target =
60 .poll = cortex_m3_poll,
61 .arch_state = armv7m_arch_state,
63 .halt = cortex_m3_halt,
64 .resume = cortex_m3_resume,
65 .step = cortex_m3_step,
67 .assert_reset = cortex_m3_assert_reset,
68 .deassert_reset = cortex_m3_deassert_reset,
69 .soft_reset_halt = cortex_m3_soft_reset_halt,
71 .get_gdb_reg_list = armv7m_get_gdb_reg_list,
73 .read_memory = cortex_m3_read_memory,
74 .write_memory = cortex_m3_write_memory,
75 .bulk_write_memory = cortex_m3_bulk_write_memory,
77 .run_algorithm = armv7m_run_algorithm,
79 .add_breakpoint = cortex_m3_add_breakpoint,
80 .remove_breakpoint = cortex_m3_remove_breakpoint,
81 .add_watchpoint = cortex_m3_add_watchpoint,
82 .remove_watchpoint = cortex_m3_remove_watchpoint,
84 .register_commands = cortex_m3_register_commands,
85 .target_command = cortex_m3_target_command,
86 .init_target = cortex_m3_init_target,
87 .quit = cortex_m3_quit
90 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 */
266 case 12: /* Debug Monitor */
267 ahbap_read_system_u32(swjdp, NVIC_DFSR, &except_sr);
269 case 14: /* PendSV */
271 case 15: /* SysTick */
277 swjdp_transaction_endcheck(swjdp);
278 DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m->exception_number), \
279 shcsr, except_sr, cfsr, except_ar);
283 int cortex_m3_debug_entry(target_t *target)
285 int i, irq_is_pending;
289 /* get pointers to arch-specific information */
290 armv7m_common_t *armv7m = target->arch_info;
291 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
292 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
295 if (armv7m->pre_debug_entry)
296 armv7m->pre_debug_entry(target);
298 cortex_m3_clear_halt(target);
299 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
301 if ((retval = armv7m->examine_debug_reason(target)) != ERROR_OK)
304 /* Examine target state and mode */
305 /* First load register acessible through core debug port*/
306 for (i = 0; i < ARMV7M_PRIMASK; i++)
308 if (!armv7m->core_cache->reg_list[i].valid)
309 armv7m->read_core_reg(target, i);
312 xPSR = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32);
314 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
317 armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1;
318 cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff);
322 /* Now we can load SP core registers */
324 for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++)
326 if (!armv7m->core_cache->reg_list[i].valid)
327 armv7m->read_core_reg(target, i);
331 /* Are we in an exception handler */
332 armv7m->core_mode = (xPSR & 0x1FF) ? ARMV7M_MODE_HANDLER : ARMV7M_MODE_THREAD;
333 armv7m->exception_number = xPSR & 0x1FF;
334 if (armv7m->exception_number)
336 cortex_m3_examine_exception_reason(target);
339 DEBUG("entered debug state at PC 0x%x, target->state: %s ", *(u32*)(armv7m->core_cache->reg_list[15].value), target_state_strings[target->state]);
341 if (armv7m->post_debug_entry)
342 armv7m->post_debug_entry(target);
347 int cortex_m3_restore_context(target_t *target)
351 /* get pointers to arch-specific information */
352 armv7m_common_t *armv7m = target->arch_info;
353 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
357 if (armv7m->pre_restore_context)
358 armv7m->pre_restore_context(target);
361 for (i = ARMV7NUMCOREREGS; i >= 0; i--)
363 for (i = ARMV7M_PSP; i >= 0; i--)
366 if (armv7m->core_cache->reg_list[i].dirty)
368 armv7m->write_core_reg(target, i);
372 if (armv7m->post_restore_context)
373 armv7m->post_restore_context(target);
378 enum target_state cortex_m3_poll(target_t *target)
381 u32 prev_target_state = target->state;
383 /* get pointers to arch-specific information */
384 armv7m_common_t *armv7m = target->arch_info;
385 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
386 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
388 /* Read from Debug Halting Control and Status Register */
389 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
390 if (retval != ERROR_OK)
392 target->state = TARGET_UNKNOWN;
393 return TARGET_UNKNOWN;
396 if (cortex_m3->dcb_dhcsr&S_RESET_ST)
398 target->state = TARGET_RESET;
399 return target->state;
401 else if (target->state==TARGET_RESET)
403 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
404 DEBUG("Exit from reset with dcb_dhcsr %x", cortex_m3->dcb_dhcsr);
405 cortex_m3_endreset_event(target);
406 target->state = TARGET_RUNNING;
407 prev_target_state = TARGET_RUNNING;
410 if (cortex_m3->dcb_dhcsr&S_HALT)
412 target->state = TARGET_HALTED;
414 if ((prev_target_state == TARGET_RUNNING) || (prev_target_state == TARGET_RESET))
416 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
419 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
421 if (prev_target_state == TARGET_DEBUG_RUNNING)
424 if ((retval = cortex_m3_debug_entry(target)) != ERROR_OK)
427 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
432 if (cortex_m3->dcb_dhcsr&S_SLEEP)
433 target->state = TARGET_SLEEP;
436 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
437 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
438 DEBUG("dcb_dhcsr %x, nvic_dfsr %x, target->state: %s", cortex_m3->dcb_dhcsr, cortex_m3->nvic_dfsr, target_state_strings[target->state]);
439 return target->state;
442 int cortex_m3_halt(target_t *target)
444 /* get pointers to arch-specific information */
445 armv7m_common_t *armv7m = target->arch_info;
446 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
447 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
449 DEBUG("target->state: %s", target_state_strings[target->state]);
451 /* Write to Debug Halting Control and Status Register */
452 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_DEBUGEN | C_HALT );
454 target->debug_reason = DBG_REASON_DBGRQ;
459 int cortex_m3_soft_reset_halt(struct target_s *target)
461 /* get pointers to arch-specific information */
462 armv7m_common_t *armv7m = target->arch_info;
463 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
464 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
466 int retval, timeout = 0;
468 /* Check that we are using process_context, or change and print warning */
469 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
471 DEBUG("Changing to process contex registers");
472 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
475 /* Enter debug state on reset, cf. end_reset_event() */
476 ahbap_write_system_u32(swjdp, DCB_DEMCR, TRCENA | VC_HARDERR | VC_BUSERR | VC_CORERESET );
478 /* Request a reset */
479 ahbap_write_system_atomic_u32(swjdp, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_VECTRESET );
480 target->state = TARGET_RESET;
482 /* registers are now invalid */
483 armv7m_invalidate_core_regs(target);
487 retval = ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &dcb_dhcsr);
488 if (retval == ERROR_OK)
490 ahbap_read_system_atomic_u32(swjdp, NVIC_DFSR, &cortex_m3->nvic_dfsr);
491 if ((dcb_dhcsr&S_HALT) && (cortex_m3->nvic_dfsr & DFSR_VCATCH))
493 DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr, cortex_m3->nvic_dfsr);
494 cortex_m3_poll(target);
498 DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr, timeout);
507 int cortex_m3_resume(struct target_s *target, int current, u32 address, int handle_breakpoints, int debug_execution)
509 /* get pointers to arch-specific information */
510 armv7m_common_t *armv7m = target->arch_info;
511 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
512 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
513 breakpoint_t *breakpoint = NULL;
514 u32 dcb_dhcsr, resume_pc;
516 if (target->state != TARGET_HALTED)
518 WARNING("target not halted");
519 return ERROR_TARGET_NOT_HALTED;
522 if (!debug_execution)
524 /* Check that we are using process_context, or change and print warning */
525 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
527 WARNING("Incorrect context in resume");
528 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
531 target_free_all_working_areas(target);
532 cortex_m3_enable_breakpoints(target);
533 cortex_m3_enable_watchpoints(target);
535 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
538 dcb_dhcsr = DBGKEY | C_DEBUGEN;
541 /* Check that we are using debug_context, or change and print warning */
542 if (armv7m_get_context(target) != ARMV7M_DEBUG_CONTEXT)
544 WARNING("Incorrect context in debug_exec resume");
545 armv7m_use_context(target, ARMV7M_DEBUG_CONTEXT);
547 /* Disable interrupts */
549 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
550 This is probably the same inssue as Cortex-M3 Errata 377493:
551 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
553 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1);
554 /* Make sure we are in Thumb mode */
555 buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32,
556 buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1<<24));
559 /* current = 1: continue on current pc, otherwise continue at <address> */
562 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
563 armv7m->core_cache->reg_list[15].dirty = 1;
564 armv7m->core_cache->reg_list[15].valid = 1;
567 resume_pc = buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32);
569 cortex_m3_restore_context(target);
571 /* the front-end may request us not to handle breakpoints */
572 if (handle_breakpoints)
574 /* Single step past breakpoint at current address */
575 if ((breakpoint = breakpoint_find(target, resume_pc)))
577 DEBUG("unset breakpoint at 0x%8.8x", breakpoint->address);
578 cortex_m3_unset_breakpoint(target, breakpoint);
579 cortex_m3_single_step_core(target);
580 cortex_m3_set_breakpoint(target, breakpoint);
584 /* Set/Clear C_MASKINTS in a separate operation */
585 if ((cortex_m3->dcb_dhcsr & C_MASKINTS) != (dcb_dhcsr & C_MASKINTS))
586 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr | C_HALT );
588 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, dcb_dhcsr );
589 target->debug_reason = DBG_REASON_NOTHALTED;
591 /* registers are now invalid */
592 armv7m_invalidate_core_regs(target);
593 if (!debug_execution)
595 target->state = TARGET_RUNNING;
596 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
597 DEBUG("target resumed at 0x%x",resume_pc);
601 target->state = TARGET_DEBUG_RUNNING;
602 target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
603 DEBUG("target debug resumed at 0x%x",resume_pc);
609 //int irqstepcount=0;
610 int cortex_m3_step(struct target_s *target, int current, u32 address, int handle_breakpoints)
612 /* get pointers to arch-specific information */
613 armv7m_common_t *armv7m = target->arch_info;
614 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
615 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
616 breakpoint_t *breakpoint = NULL;
618 if (target->state != TARGET_HALTED)
620 WARNING("target not halted");
621 return ERROR_TARGET_NOT_HALTED;
624 /* Check that we are using process_context, or change and print warning */
625 if (armv7m_get_context(target) != ARMV7M_PROCESS_CONTEXT)
627 WARNING("Incorrect context in step, must be process");
628 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
631 /* current = 1: continue on current pc, otherwise continue at <address> */
633 buf_set_u32(armv7m->core_cache->reg_list[15].value, 0, 32, address);
635 /* the front-end may request us not to handle breakpoints */
636 if (handle_breakpoints)
637 if ((breakpoint = breakpoint_find(target, buf_get_u32(armv7m->core_cache->reg_list[15].value, 0, 32))))
638 cortex_m3_unset_breakpoint(target, breakpoint);
640 target->debug_reason = DBG_REASON_SINGLESTEP;
642 cortex_m3_restore_context(target);
644 target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
646 if (cortex_m3->dcb_dhcsr & C_MASKINTS)
647 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY | C_HALT | C_DEBUGEN );
648 ahbap_write_system_atomic_u32(swjdp, DCB_DHCSR, DBGKEY| C_STEP | C_DEBUGEN);
649 ahbap_read_system_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
651 /* If we run in process context then registers are now invalid */
652 if (armv7m_get_context(target) == ARMV7M_PROCESS_CONTEXT)
653 armv7m_invalidate_core_regs(target);
656 cortex_m3_set_breakpoint(target, breakpoint);
658 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
660 cortex_m3_debug_entry(target);
661 target_call_event_callbacks(target, TARGET_EVENT_HALTED);
663 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3->dcb_dhcsr, cortex_m3->nvic_icsr);
667 int cortex_m3_assert_reset(target_t *target)
671 DEBUG("target->state: %s", target_state_strings[target->state]);
673 if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
675 /* assert SRST and TRST */
676 /* system would get ouf sync if we didn't reset test-logic, too */
677 if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
679 if (retval == ERROR_JTAG_RESET_CANT_SRST)
681 WARNING("can't assert srst");
686 ERROR("unknown error");
690 jtag_add_sleep(5000);
691 if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
693 if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
695 WARNING("srst resets test logic, too");
696 retval = jtag_add_reset(1, 1);
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);
710 if (retval == ERROR_JTAG_RESET_CANT_SRST)
712 WARNING("can't assert srsrt");
715 else if (retval != ERROR_OK)
717 ERROR("unknown error");
723 target->state = TARGET_RESET;
724 jtag_add_sleep(50000);
726 armv7m_use_context(target, ARMV7M_PROCESS_CONTEXT);
727 armv7m_invalidate_core_regs(target);
732 int cortex_m3_deassert_reset(target_t *target)
734 DEBUG("target->state: %s", target_state_strings[target->state]);
736 /* deassert reset lines */
737 jtag_add_reset(0, 0);
742 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s *target)
747 void cortex_m3_enable_breakpoints(struct target_s *target)
749 breakpoint_t *breakpoint = target->breakpoints;
751 /* set any pending breakpoints */
754 if (breakpoint->set == 0)
755 cortex_m3_set_breakpoint(target, breakpoint);
756 breakpoint = breakpoint->next;
760 int cortex_m3_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
765 /* get pointers to arch-specific information */
766 armv7m_common_t *armv7m = target->arch_info;
767 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
769 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
773 WARNING("breakpoint already set");
777 if (cortex_m3->auto_bp_type)
779 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
782 if (breakpoint->type == BKPT_HARD)
784 while(comparator_list[fp_num].used && (fp_num < cortex_m3->fp_num_code))
786 if (fp_num >= cortex_m3->fp_num_code)
788 DEBUG("ERROR Can not find free FP Comparator");
789 WARNING("ERROR Can not find free FP Comparator");
792 breakpoint->set = fp_num + 1;
793 hilo = (breakpoint->address & 0x2) ? FPCR_REPLACE_BKPT_HIGH : FPCR_REPLACE_BKPT_LOW;
794 comparator_list[fp_num].used = 1;
795 comparator_list[fp_num].fpcr_value = (breakpoint->address & 0x1FFFFFFC) | hilo | 1;
796 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
797 DEBUG("fpc_num %i fpcr_value 0x%x", fp_num, comparator_list[fp_num].fpcr_value);
799 else if (breakpoint->type == BKPT_SOFT)
802 buf_set_u32(code, 0, 32, ARMV7M_T_BKPT(0x11));
803 target->type->read_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, breakpoint->orig_instr);
804 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, breakpoint->length, 1, code);
805 breakpoint->set = 0x11; /* Any nice value but 0 */
811 int cortex_m3_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
813 /* get pointers to arch-specific information */
814 armv7m_common_t *armv7m = target->arch_info;
815 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
816 cortex_m3_fp_comparator_t * comparator_list = cortex_m3->fp_comparator_list;
818 if (!breakpoint->set)
820 WARNING("breakpoint not set");
824 if (breakpoint->type == BKPT_HARD)
826 int fp_num = breakpoint->set - 1;
827 if ((fp_num < 0) || (fp_num >= cortex_m3->fp_num_code))
829 DEBUG("Invalid FP Comparator number in breakpoint");
832 comparator_list[fp_num].used = 0;
833 comparator_list[fp_num].fpcr_value = 0;
834 target_write_u32(target, comparator_list[fp_num].fpcr_address, comparator_list[fp_num].fpcr_value);
838 /* restore original instruction (kept in target endianness) */
839 if (breakpoint->length == 4)
841 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 4, 1, breakpoint->orig_instr);
845 target->type->write_memory(target, breakpoint->address & 0xFFFFFFFE, 2, 1, breakpoint->orig_instr);
853 int cortex_m3_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
855 /* get pointers to arch-specific information */
856 armv7m_common_t *armv7m = target->arch_info;
857 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
859 if (cortex_m3->auto_bp_type)
861 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
864 if ((breakpoint->type == BKPT_HARD) && (breakpoint->address >= 0x20000000))
866 INFO("flash patch comparator requested outside code memory region");
867 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
870 if ((breakpoint->type == BKPT_SOFT) && (breakpoint->address < 0x20000000))
872 INFO("soft breakpoint requested in code (flash) memory region");
873 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
876 if ((breakpoint->type == BKPT_HARD) && (cortex_m3->fp_code_available < 1))
878 INFO("no flash patch comparator unit available for hardware breakpoint");
879 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
882 if ((breakpoint->length != 2))
884 INFO("only breakpoints of two bytes length supported");
885 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
888 if (breakpoint->type == BKPT_HARD)
889 cortex_m3->fp_code_available--;
890 cortex_m3_set_breakpoint(target, breakpoint);
895 int cortex_m3_remove_breakpoint(struct target_s *target, breakpoint_t *breakpoint)
897 /* get pointers to arch-specific information */
898 armv7m_common_t *armv7m = target->arch_info;
899 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
901 if (target->state != TARGET_HALTED)
903 WARNING("target not halted");
904 return ERROR_TARGET_NOT_HALTED;
907 if (cortex_m3->auto_bp_type)
909 breakpoint->type = (breakpoint->address < 0x20000000) ? BKPT_HARD : BKPT_SOFT;
914 cortex_m3_unset_breakpoint(target, breakpoint);
917 if (breakpoint->type == BKPT_HARD)
918 cortex_m3->fp_code_available++;
923 int cortex_m3_set_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
928 /* get pointers to arch-specific information */
929 armv7m_common_t *armv7m = target->arch_info;
930 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
931 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
935 WARNING("watchpoint already set");
939 if (watchpoint->mask == 0xffffffffu)
941 while(comparator_list[dwt_num].used && (dwt_num < cortex_m3->dwt_num_comp))
943 if (dwt_num >= cortex_m3->dwt_num_comp)
945 DEBUG("ERROR Can not find free DWT Comparator");
946 WARNING("ERROR Can not find free DWT Comparator");
949 watchpoint->set = dwt_num + 1;
951 temp = watchpoint->length;
957 comparator_list[dwt_num].used = 1;
958 comparator_list[dwt_num].comp = watchpoint->address;
959 comparator_list[dwt_num].mask = mask;
960 comparator_list[dwt_num].function = watchpoint->rw + 5;
961 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address, comparator_list[dwt_num].comp);
962 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x4, comparator_list[dwt_num].mask);
963 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
964 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);
968 WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
976 int cortex_m3_unset_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
978 /* get pointers to arch-specific information */
979 armv7m_common_t *armv7m = target->arch_info;
980 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
981 cortex_m3_dwt_comparator_t * comparator_list = cortex_m3->dwt_comparator_list;
984 if (!watchpoint->set)
986 WARNING("watchpoint not set");
990 dwt_num = watchpoint->set - 1;
992 if ((dwt_num < 0) || (dwt_num >= cortex_m3->dwt_num_comp))
994 DEBUG("Invalid DWT Comparator number in watchpoint");
997 comparator_list[dwt_num].used = 0;
998 comparator_list[dwt_num].function = 0;
999 target_write_u32(target, comparator_list[dwt_num].dwt_comparator_address|0x8, comparator_list[dwt_num].function);
1001 watchpoint->set = 0;
1006 int cortex_m3_add_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1008 /* get pointers to arch-specific information */
1009 armv7m_common_t *armv7m = target->arch_info;
1010 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1012 if (target->state != TARGET_HALTED)
1014 WARNING("target not halted");
1015 return ERROR_TARGET_NOT_HALTED;
1018 if (cortex_m3->dwt_comp_available < 1)
1020 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1023 if ((watchpoint->length != 1) && (watchpoint->length != 2) && (watchpoint->length != 4))
1025 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1028 cortex_m3->dwt_comp_available--;
1033 int cortex_m3_remove_watchpoint(struct target_s *target, watchpoint_t *watchpoint)
1035 /* get pointers to arch-specific information */
1036 armv7m_common_t *armv7m = target->arch_info;
1037 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1039 if (target->state != TARGET_HALTED)
1041 WARNING("target not halted");
1042 return ERROR_TARGET_NOT_HALTED;
1045 if (watchpoint->set)
1047 cortex_m3_unset_watchpoint(target, watchpoint);
1050 cortex_m3->dwt_comp_available++;
1055 void cortex_m3_enable_watchpoints(struct target_s *target)
1057 watchpoint_t *watchpoint = target->watchpoints;
1059 /* set any pending watchpoints */
1062 if (watchpoint->set == 0)
1063 cortex_m3_set_watchpoint(target, watchpoint);
1064 watchpoint = watchpoint->next;
1068 int cortex_m3_load_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 * value)
1071 /* get pointers to arch-specific information */
1072 armv7m_common_t *armv7m = target->arch_info;
1073 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1074 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1076 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1078 /* read a normal core register */
1079 retval = ahbap_read_coreregister_u32(swjdp, value, num);
1081 if (retval != ERROR_OK)
1083 ERROR("JTAG failure %i",retval);
1084 return ERROR_JTAG_DEVICE_ERROR;
1086 //DEBUG("load from core reg %i value 0x%x",num,*value);
1088 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1090 /* read other registers */
1091 /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */
1096 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1097 instr = ARMV7M_T_MRS(0, SYSm);
1098 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MRS(0, SYSm));
1099 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1100 cortex_m3_single_step_core(target);
1101 ahbap_read_coreregister_u32(swjdp, value, 0);
1102 armv7m->core_cache->reg_list[0].dirty = 1;
1103 armv7m->core_cache->reg_list[15].dirty = 1;
1104 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1105 swjdp_transaction_endcheck(swjdp);
1106 DEBUG("load from special reg %i value 0x%x", SYSm, *value);
1108 else return ERROR_INVALID_ARGUMENTS;
1113 int cortex_m3_store_core_reg_u32(struct target_s *target, enum armv7m_regtype type, u32 num, u32 value)
1117 /* get pointers to arch-specific information */
1118 armv7m_common_t *armv7m = target->arch_info;
1119 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1120 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1122 if ((type == ARMV7M_REGISTER_CORE_GP) && (num <= ARMV7M_PSP))
1124 retval = ahbap_write_coreregister_u32(swjdp, value, num);
1125 if (retval != ERROR_OK)
1127 ERROR("JTAG failure %i", retval);
1128 armv7m->core_cache->reg_list[num].dirty = 1;
1129 return ERROR_JTAG_DEVICE_ERROR;
1131 DEBUG("write core reg %i value 0x%x", num, value);
1133 else if (type == ARMV7M_REGISTER_CORE_SP) /* Special purpose core register */
1135 /* write other registers */
1136 u32 savedram , tempr0;
1140 ahbap_read_system_u32(swjdp, 0x20000000, &savedram);
1141 instr = ARMV7M_T_MSR(SYSm, 0);
1142 ahbap_write_system_u32(swjdp, 0x20000000, ARMV7M_T_MSR(SYSm, 0));
1143 ahbap_read_coreregister_u32(swjdp, &tempr0, 0);
1144 ahbap_write_coreregister_u32(swjdp, value, 0);
1145 ahbap_write_coreregister_u32(swjdp, 0x20000000, 15);
1146 cortex_m3_single_step_core(target);
1147 ahbap_write_coreregister_u32(swjdp, tempr0, 0);
1148 armv7m->core_cache->reg_list[15].dirty = 1;
1149 ahbap_write_system_u32(swjdp, 0x20000000, savedram);
1150 swjdp_transaction_endcheck(swjdp);
1151 DEBUG("write special reg %i value 0x%x ", SYSm, value);
1153 else return ERROR_INVALID_ARGUMENTS;
1158 int cortex_m3_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1160 /* get pointers to arch-specific information */
1161 armv7m_common_t *armv7m = target->arch_info;
1162 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1163 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1165 /* sanitize arguments */
1166 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1167 return ERROR_INVALID_ARGUMENTS;
1169 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1170 return ERROR_TARGET_UNALIGNED_ACCESS;
1172 /* Is not optimal, autoincrement of tar should be used ( ahbap_block_read and CSW_ADDRINC_SINGLE ) */
1176 /* TODOLATER Check error return value ! */
1178 ahbap_read_buf(swjdp, buffer, 4 * count, address);
1183 ahbap_read_buf_u16(swjdp, buffer, 2 * count, address);
1188 ahbap_read_buf(swjdp, buffer, count, address);
1192 ERROR("BUG: we shouldn't get here");
1199 int cortex_m3_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer)
1201 /* get pointers to arch-specific information */
1202 armv7m_common_t *armv7m = target->arch_info;
1203 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1204 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1206 /* sanitize arguments */
1207 if (((size != 4) && (size != 2) && (size != 1)) || (count == 0) || !(buffer))
1208 return ERROR_INVALID_ARGUMENTS;
1210 if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
1211 return ERROR_TARGET_UNALIGNED_ACCESS;
1216 /* TODOLATER Check error return value ! */
1218 ahbap_write_buf(swjdp, buffer, 4 * count, address);
1223 ahbap_write_buf_u16(swjdp, buffer, 2 * count, address);
1228 ahbap_write_buf(swjdp, buffer, count, address);
1232 ERROR("BUG: we shouldn't get here");
1239 int cortex_m3_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buffer)
1241 cortex_m3_write_memory(target, address, 4, count, buffer);
1246 void cortex_m3_build_reg_cache(target_t *target)
1248 armv7m_build_reg_cache(target);
1251 int cortex_m3_init_target(struct command_context_s *cmd_ctx, struct target_s *target)
1253 u32 did1, dc0, cpuid, fpcr, dwtcr, ictr;
1256 /* get pointers to arch-specific information */
1257 armv7m_common_t *armv7m = target->arch_info;
1258 cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
1259 swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
1261 cortex_m3_build_reg_cache(target);
1262 ahbap_debugport_init(swjdp);
1264 /* Read from Device Identification Registers */
1265 target_read_u32(target, CPUID, &cpuid);
1266 if (((cpuid >> 4) & 0xc3f) == 0xc23)
1267 DEBUG("CORTEX-M3 processor detected");
1268 DEBUG("cpuid %x", cpuid);
1270 target_read_u32(target, NVIC_ICTR, &ictr);
1271 cortex_m3->intlinesnum = (ictr & 0x1F) + 1;
1272 cortex_m3->intsetenable = calloc(cortex_m3->intlinesnum, 4);
1273 for (i = 0; i < cortex_m3->intlinesnum; i++)
1275 target_read_u32(target, NVIC_ISE0 + 4 * i, cortex_m3->intsetenable + i);
1276 DEBUG("interrupt enable[%i] = 0x%x", i, cortex_m3->intsetenable[i]);
1280 target_read_u32(target, FP_CTRL, &fpcr);
1281 cortex_m3->auto_bp_type = 1;
1282 cortex_m3->fp_num_code = (fpcr >> 4) & 0xF;
1283 cortex_m3->fp_num_lit = (fpcr >> 8) & 0xF;
1284 cortex_m3->fp_code_available = cortex_m3->fp_num_code;
1285 cortex_m3->fp_comparator_list=calloc(cortex_m3->fp_num_code+cortex_m3->fp_num_lit, sizeof(cortex_m3_fp_comparator_t));
1286 for (i = 0; i < cortex_m3->fp_num_code + cortex_m3->fp_num_lit; i++)
1288 cortex_m3->fp_comparator_list[i].type = (i < cortex_m3->fp_num_code) ? FPCR_CODE : FPCR_LITERAL;
1289 cortex_m3->fp_comparator_list[i].fpcr_address = FP_COMP0 + 4 * i;
1291 DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr, cortex_m3->fp_num_code, cortex_m3->fp_num_lit);
1294 target_read_u32(target, DWT_CTRL, &dwtcr);
1295 cortex_m3->dwt_num_comp = (dwtcr >> 28) & 0xF;
1296 cortex_m3->dwt_comp_available = cortex_m3->dwt_num_comp;
1297 cortex_m3->dwt_comparator_list=calloc(cortex_m3->dwt_num_comp, sizeof(cortex_m3_dwt_comparator_t));
1298 for (i = 0; i < cortex_m3->dwt_num_comp; i++)
1300 cortex_m3->dwt_comparator_list[i].dwt_comparator_address = DWT_COMP0 + 0x10 * i;
1306 int cortex_m3_quit()
1312 int cortex_m3_init_arch_info(target_t *target, cortex_m3_common_t *cortex_m3, int chain_pos, char *variant)
1314 armv7m_common_t *armv7m;
1315 armv7m = &cortex_m3->armv7m;
1317 arm_jtag_t *jtag_info = &cortex_m3->jtag_info;
1319 /* prepare JTAG information for the new target */
1320 cortex_m3->jtag_info.chain_pos = chain_pos;
1321 cortex_m3->jtag_info.scann_size = 4;
1323 cortex_m3->swjdp_info.dp_select_value = -1;
1324 cortex_m3->swjdp_info.ap_csw_value = -1;
1325 cortex_m3->swjdp_info.ap_tar_value = -1;
1326 cortex_m3->swjdp_info.jtag_info = &cortex_m3->jtag_info;
1328 /* initialize arch-specific breakpoint handling */
1330 cortex_m3->common_magic = CORTEX_M3_COMMON_MAGIC;
1331 cortex_m3->arch_info = NULL;
1333 /* register arch-specific functions */
1334 armv7m->examine_debug_reason = cortex_m3_examine_debug_reason;
1336 armv7m->pre_debug_entry = NULL;
1337 armv7m->post_debug_entry = NULL;
1339 armv7m->pre_restore_context = NULL;
1340 armv7m->post_restore_context = NULL;
1342 armv7m_init_arch_info(target, armv7m);
1343 armv7m->arch_info = cortex_m3;
1344 armv7m->load_core_reg_u32 = cortex_m3_load_core_reg_u32;
1345 armv7m->store_core_reg_u32 = cortex_m3_store_core_reg_u32;
1346 // armv7m->full_context = cortex_m3_full_context;
1351 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1352 int cortex_m3_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target)
1355 char *variant = NULL;
1356 cortex_m3_common_t *cortex_m3 = malloc(sizeof(cortex_m3_common_t));
1360 ERROR("'target cortex_m3' requires at least one additional argument");
1364 chain_pos = strtoul(args[3], NULL, 0);
1369 cortex_m3_init_arch_info(target, cortex_m3, chain_pos, variant);
1370 cortex_m3_register_commands(cmd_ctx);
1375 int cortex_m3_register_commands(struct command_context_s *cmd_ctx)
1379 retval = armv7m_register_commands(cmd_ctx);