1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
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. *
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. *
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. *
27 * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) *
29 ***************************************************************************/
34 #include "cortex_m3.h"
35 #include "target_request.h"
36 #include "target_type.h"
37 #include "arm_disassembler.h"
40 #define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof((x)[0])))
43 /* forward declarations */
44 static int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
45 static int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
);
46 static void cortex_m3_enable_watchpoints(struct target_s
*target
);
47 static int cortex_m3_store_core_reg_u32(target_t
*target
,
48 enum armv7m_regtype type
, uint32_t num
, uint32_t value
);
50 #ifdef ARMV7_GDB_HACKS
51 extern uint8_t armv7m_gdb_dummy_cpsr_value
[];
52 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
55 static int cortex_m3_has_mmu(struct target_s
*target
, bool *has_mmu
)
61 static int cortexm3_dap_read_coreregister_u32(swjdp_common_t
*swjdp
,
62 uint32_t *value
, int regnum
)
67 /* because the DCB_DCRDR is used for the emulated dcc channel
68 * we have to save/restore the DCB_DCRDR when used */
70 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
72 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
74 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
75 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
76 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
78 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
79 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
80 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
82 retval
= swjdp_transaction_endcheck(swjdp
);
84 /* restore DCB_DCRDR - this needs to be in a seperate
85 * transaction otherwise the emulated DCC channel breaks */
86 if (retval
== ERROR_OK
)
87 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
92 static int cortexm3_dap_write_coreregister_u32(swjdp_common_t
*swjdp
,
93 uint32_t value
, int regnum
)
98 /* because the DCB_DCRDR is used for the emulated dcc channel
99 * we have to save/restore the DCB_DCRDR when used */
101 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
103 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
105 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
106 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
107 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
109 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
110 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
111 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
113 retval
= swjdp_transaction_endcheck(swjdp
);
115 /* restore DCB_DCRDR - this needs to be in a seperate
116 * transaction otherwise the emulated DCC channel breaks */
117 if (retval
== ERROR_OK
)
118 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
123 static int cortex_m3_write_debug_halt_mask(target_t
*target
,
124 uint32_t mask_on
, uint32_t mask_off
)
126 /* get pointers to arch-specific information */
127 armv7m_common_t
*armv7m
= target
->arch_info
;
128 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
129 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
131 /* mask off status bits */
132 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
133 /* create new register mask */
134 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
136 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
139 static int cortex_m3_clear_halt(target_t
*target
)
141 /* get pointers to arch-specific information */
142 armv7m_common_t
*armv7m
= target
->arch_info
;
143 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
144 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
146 /* clear step if any */
147 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
149 /* Read Debug Fault Status Register */
150 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
151 /* Clear Debug Fault Status */
152 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
153 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
158 static int cortex_m3_single_step_core(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
= &armv7m
->swjdp_info
;
166 /* backup dhcsr reg */
167 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
169 /* mask interrupts if not done already */
170 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
171 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
172 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
175 /* restore dhcsr reg */
176 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
177 cortex_m3_clear_halt(target
);
182 static int cortex_m3_endreset_event(target_t
*target
)
187 /* get pointers to arch-specific information */
188 armv7m_common_t
*armv7m
= target
->arch_info
;
189 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
190 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
191 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
192 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
194 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
195 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
197 /* this regsiter is used for emulated dcc channel */
198 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
200 /* Enable debug requests */
201 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
202 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
203 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
205 /* clear any interrupt masking */
206 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
208 /* Enable trace and dwt */
209 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
210 /* Monitor bus faults */
211 mem_ap_write_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
214 target_write_u32(target
, FP_CTRL
, 3);
215 cortex_m3
->fpb_enabled
= 1;
217 /* Restore FPB registers */
218 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
220 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
223 /* Restore DWT registers */
224 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
226 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
227 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
228 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
230 swjdp_transaction_endcheck(swjdp
);
232 armv7m_invalidate_core_regs(target
);
234 /* make sure we have latest dhcsr flags */
235 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
240 static int cortex_m3_examine_debug_reason(target_t
*target
)
242 /* get pointers to arch-specific information */
243 armv7m_common_t
*armv7m
= target
->arch_info
;
244 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
246 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
247 /* only check the debug reason if we don't know it already */
249 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
250 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
252 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
254 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
255 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
256 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
258 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
259 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
260 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
261 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
262 else /* EXTERNAL, HALTED, DWTTRAP w/o BKPT */
263 target
->debug_reason
= DBG_REASON_UNDEFINED
;
269 static int cortex_m3_examine_exception_reason(target_t
*target
)
271 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
273 /* get pointers to arch-specific information */
274 armv7m_common_t
*armv7m
= target
->arch_info
;
275 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
277 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
278 switch (armv7m
->exception_number
)
282 case 3: /* Hard Fault */
283 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
284 if (except_sr
& 0x40000000)
286 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
289 case 4: /* Memory Management */
290 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
291 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
293 case 5: /* Bus Fault */
294 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
295 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
297 case 6: /* Usage Fault */
298 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
300 case 11: /* SVCall */
302 case 12: /* Debug Monitor */
303 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
305 case 14: /* PendSV */
307 case 15: /* SysTick */
313 swjdp_transaction_endcheck(swjdp
);
314 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
"", armv7m_exception_string(armv7m
->exception_number
), \
315 shcsr
, except_sr
, cfsr
, except_ar
);
319 static int cortex_m3_debug_entry(target_t
*target
)
325 /* get pointers to arch-specific information */
326 armv7m_common_t
*armv7m
= target
->arch_info
;
327 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
328 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
332 cortex_m3_clear_halt(target
);
333 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
335 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
338 /* Examine target state and mode */
339 /* First load register acessible through core debug port*/
340 int num_regs
= armv7m
->core_cache
->num_regs
;
342 for (i
= 0; i
< num_regs
; i
++)
344 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
345 armv7m
->read_core_reg(target
, i
);
348 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
350 #ifdef ARMV7_GDB_HACKS
351 /* copy real xpsr reg for gdb, setting thumb bit */
352 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
353 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
354 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
355 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
358 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
361 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
362 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
365 /* Are we in an exception handler */
368 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
369 armv7m
->exception_number
= (xPSR
& 0x1FF);
373 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
374 armv7m
->exception_number
= 0;
377 if (armv7m
->exception_number
)
379 cortex_m3_examine_exception_reason(target
);
382 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
383 armv7m_mode_strings
[armv7m
->core_mode
],
384 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
385 target_state_name(target
));
387 if (armv7m
->post_debug_entry
)
388 armv7m
->post_debug_entry(target
);
393 static int cortex_m3_poll(target_t
*target
)
396 enum target_state prev_target_state
= target
->state
;
398 /* get pointers to arch-specific information */
399 armv7m_common_t
*armv7m
= target
->arch_info
;
400 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
401 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
403 /* Read from Debug Halting Control and Status Register */
404 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
405 if (retval
!= ERROR_OK
)
407 target
->state
= TARGET_UNKNOWN
;
411 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
413 /* check if still in reset */
414 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
416 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
418 target
->state
= TARGET_RESET
;
423 if (target
->state
== TARGET_RESET
)
425 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
426 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
427 cortex_m3_endreset_event(target
);
428 target
->state
= TARGET_RUNNING
;
429 prev_target_state
= TARGET_RUNNING
;
432 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
434 target
->state
= TARGET_HALTED
;
436 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
438 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
441 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
443 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
446 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
449 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
453 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
454 * How best to model low power modes?
457 if (target
->state
== TARGET_UNKNOWN
)
459 /* check if processor is retiring instructions */
460 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
462 target
->state
= TARGET_RUNNING
;
470 static int cortex_m3_halt(target_t
*target
)
472 LOG_DEBUG("target->state: %s",
473 target_state_name(target
));
475 if (target
->state
== TARGET_HALTED
)
477 LOG_DEBUG("target was already halted");
481 if (target
->state
== TARGET_UNKNOWN
)
483 LOG_WARNING("target was in unknown state when halt was requested");
486 if (target
->state
== TARGET_RESET
)
488 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
490 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
491 return ERROR_TARGET_FAILURE
;
495 /* we came here in a reset_halt or reset_init sequence
496 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
498 target
->debug_reason
= DBG_REASON_DBGRQ
;
504 /* Write to Debug Halting Control and Status Register */
505 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
507 target
->debug_reason
= DBG_REASON_DBGRQ
;
512 static int cortex_m3_soft_reset_halt(struct target_s
*target
)
514 /* get pointers to arch-specific information */
515 armv7m_common_t
*armv7m
= target
->arch_info
;
516 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
517 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
518 uint32_t dcb_dhcsr
= 0;
519 int retval
, timeout
= 0;
521 /* Enter debug state on reset, cf. end_reset_event() */
522 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
524 /* Request a reset */
525 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
526 target
->state
= TARGET_RESET
;
528 /* registers are now invalid */
529 armv7m_invalidate_core_regs(target
);
531 while (timeout
< 100)
533 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
534 if (retval
== ERROR_OK
)
536 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
537 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
539 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
540 cortex_m3_poll(target
);
544 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
553 static void cortex_m3_enable_breakpoints(struct target_s
*target
)
555 breakpoint_t
*breakpoint
= target
->breakpoints
;
557 /* set any pending breakpoints */
560 if (breakpoint
->set
== 0)
561 cortex_m3_set_breakpoint(target
, breakpoint
);
562 breakpoint
= breakpoint
->next
;
566 static int cortex_m3_resume(struct target_s
*target
, int current
,
567 uint32_t address
, int handle_breakpoints
, int debug_execution
)
569 /* get pointers to arch-specific information */
570 armv7m_common_t
*armv7m
= target
->arch_info
;
571 breakpoint_t
*breakpoint
= NULL
;
574 if (target
->state
!= TARGET_HALTED
)
576 LOG_WARNING("target not halted");
577 return ERROR_TARGET_NOT_HALTED
;
580 if (!debug_execution
)
582 target_free_all_working_areas(target
);
583 cortex_m3_enable_breakpoints(target
);
584 cortex_m3_enable_watchpoints(target
);
589 /* Disable interrupts */
590 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
591 * This is probably the same issue as Cortex-M3 Errata 377493:
592 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
593 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
594 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
595 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
597 /* Make sure we are in Thumb mode */
598 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
599 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
600 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
601 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
604 /* current = 1: continue on current pc, otherwise continue at <address> */
607 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
608 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
609 armv7m
->core_cache
->reg_list
[15].valid
= 1;
612 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
614 armv7m_restore_context(target
);
616 /* the front-end may request us not to handle breakpoints */
617 if (handle_breakpoints
)
619 /* Single step past breakpoint at current address */
620 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
622 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
624 breakpoint
->unique_id
);
625 cortex_m3_unset_breakpoint(target
, breakpoint
);
626 cortex_m3_single_step_core(target
);
627 cortex_m3_set_breakpoint(target
, breakpoint
);
632 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
634 target
->debug_reason
= DBG_REASON_NOTHALTED
;
636 /* registers are now invalid */
637 armv7m_invalidate_core_regs(target
);
638 if (!debug_execution
)
640 target
->state
= TARGET_RUNNING
;
641 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
642 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
646 target
->state
= TARGET_DEBUG_RUNNING
;
647 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
648 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
654 /* int irqstepcount = 0; */
655 static int cortex_m3_step(struct target_s
*target
, int current
,
656 uint32_t address
, int handle_breakpoints
)
658 /* get pointers to arch-specific information */
659 armv7m_common_t
*armv7m
= target
->arch_info
;
660 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
661 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
662 breakpoint_t
*breakpoint
= NULL
;
664 if (target
->state
!= TARGET_HALTED
)
666 LOG_WARNING("target not halted");
667 return ERROR_TARGET_NOT_HALTED
;
670 /* current = 1: continue on current pc, otherwise continue at <address> */
672 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
674 /* the front-end may request us not to handle breakpoints */
675 if (handle_breakpoints
)
676 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
677 cortex_m3_unset_breakpoint(target
, breakpoint
);
679 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
681 armv7m_restore_context(target
);
683 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
685 /* set step and clear halt */
686 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
687 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
689 /* registers are now invalid */
690 armv7m_invalidate_core_regs(target
);
693 cortex_m3_set_breakpoint(target
, breakpoint
);
695 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
697 cortex_m3_debug_entry(target
);
698 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
700 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
704 static int cortex_m3_assert_reset(target_t
*target
)
706 armv7m_common_t
*armv7m
= target
->arch_info
;
707 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
708 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
711 LOG_DEBUG("target->state: %s",
712 target_state_name(target
));
714 enum reset_types jtag_reset_config
= jtag_get_reset_config();
717 * We can reset Cortex-M3 targets using just the NVIC without
718 * requiring SRST, getting a SoC reset (or a core-only reset)
719 * instead of a system reset.
721 if (!(jtag_reset_config
& RESET_HAS_SRST
))
724 /* Enable debug requests */
725 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
726 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
727 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
729 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
731 if (!target
->reset_halt
)
733 /* Set/Clear C_MASKINTS in a separate operation */
734 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
735 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
737 /* clear any debug flags before resuming */
738 cortex_m3_clear_halt(target
);
740 /* clear C_HALT in dhcsr reg */
741 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
743 /* Enter debug state on reset, cf. end_reset_event() */
744 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
748 /* Enter debug state on reset, cf. end_reset_event() */
749 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
753 * When nRST is asserted on most Stellaris devices, it clears some of
754 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
755 * and OpenOCD depends on those TRMs. So we won't use SRST on those
756 * chips. (Only power-on reset should affect debug state, beyond a
757 * few specified bits; not the chip's nRST input, wired to SRST.)
759 * REVISIT current errata specs don't seem to cover this issue.
760 * Do we have more details than this email?
761 * https://lists.berlios.de/pipermail
762 * /openocd-development/2008-August/003065.html
764 if (strcmp(target
->variant
, "lm3s") == 0)
766 /* Check for silicon revisions with the issue. */
769 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
771 switch ((did0
>> 16) & 0xff)
774 /* all Sandstorm suffer issue */
780 /* Fury and DustDevil rev A have
781 * this nRST problem. It should
782 * be fixed in rev B silicon.
784 if (((did0
>> 8) & 0xff) == 0)
788 /* Tempest should be fine. */
796 /* default to asserting srst */
797 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
799 jtag_add_reset(1, 1);
803 jtag_add_reset(0, 1);
808 /* Use a standard Cortex-M3 software reset mechanism.
809 * SYSRESETREQ will reset SoC peripherals outside the
810 * core, like watchdog timers, if the SoC wires it up
811 * correctly. Else VECRESET can reset just the core.
813 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
814 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
815 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
818 /* I do not know why this is necessary, but it
819 * fixes strange effects (step/resume cause NMI
820 * after reset) on LM3S6918 -- Michael Schwingen
823 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
827 target
->state
= TARGET_RESET
;
828 jtag_add_sleep(50000);
830 armv7m_invalidate_core_regs(target
);
832 if (target
->reset_halt
)
835 if ((retval
= target_halt(target
)) != ERROR_OK
)
842 static int cortex_m3_deassert_reset(target_t
*target
)
844 LOG_DEBUG("target->state: %s",
845 target_state_name(target
));
847 /* deassert reset lines */
848 jtag_add_reset(0, 0);
854 cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
860 /* get pointers to arch-specific information */
861 armv7m_common_t
*armv7m
= target
->arch_info
;
862 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
864 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
868 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
872 if (cortex_m3
->auto_bp_type
)
874 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
877 if (breakpoint
->type
== BKPT_HARD
)
879 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
881 if (fp_num
>= cortex_m3
->fp_num_code
)
883 LOG_DEBUG("ERROR Can not find free FP Comparator");
884 LOG_WARNING("ERROR Can not find free FP Comparator");
887 breakpoint
->set
= fp_num
+ 1;
888 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
889 comparator_list
[fp_num
].used
= 1;
890 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
891 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
892 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
893 if (!cortex_m3
->fpb_enabled
)
895 LOG_DEBUG("FPB wasn't enabled, do it now");
896 target_write_u32(target
, FP_CTRL
, 3);
899 else if (breakpoint
->type
== BKPT_SOFT
)
902 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
903 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
907 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
911 breakpoint
->set
= 0x11; /* Any nice value but 0 */
914 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
915 breakpoint
->unique_id
,
916 (int)(breakpoint
->type
),
925 cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
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_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
933 if (!breakpoint
->set
)
935 LOG_WARNING("breakpoint not set");
939 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
940 breakpoint
->unique_id
,
941 (int)(breakpoint
->type
),
946 if (breakpoint
->type
== BKPT_HARD
)
948 int fp_num
= breakpoint
->set
- 1;
949 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
951 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
954 comparator_list
[fp_num
].used
= 0;
955 comparator_list
[fp_num
].fpcr_value
= 0;
956 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
960 /* restore original instruction (kept in target endianness) */
961 if (breakpoint
->length
== 4)
963 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
970 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
982 cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
984 /* get pointers to arch-specific information */
985 armv7m_common_t
*armv7m
= target
->arch_info
;
986 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
988 if (cortex_m3
->auto_bp_type
)
990 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
991 #ifdef ARMV7_GDB_HACKS
992 if (breakpoint
->length
!= 2) {
993 /* XXX Hack: Replace all breakpoints with length != 2 with
994 * a hardware breakpoint. */
995 breakpoint
->type
= BKPT_HARD
;
996 breakpoint
->length
= 2;
1001 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1003 LOG_INFO("flash patch comparator requested outside code memory region");
1004 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1007 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1009 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1010 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1013 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1015 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1016 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1019 if ((breakpoint
->length
!= 2))
1021 LOG_INFO("only breakpoints of two bytes length supported");
1022 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1025 if (breakpoint
->type
== BKPT_HARD
)
1026 cortex_m3
->fp_code_available
--;
1027 cortex_m3_set_breakpoint(target
, breakpoint
);
1033 cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
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 LOG_WARNING("target not halted");
1042 return ERROR_TARGET_NOT_HALTED
;
1045 if (cortex_m3
->auto_bp_type
)
1047 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1050 if (breakpoint
->set
)
1052 cortex_m3_unset_breakpoint(target
, breakpoint
);
1055 if (breakpoint
->type
== BKPT_HARD
)
1056 cortex_m3
->fp_code_available
++;
1062 cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1065 uint32_t mask
, temp
;
1067 /* get pointers to arch-specific information */
1068 armv7m_common_t
*armv7m
= target
->arch_info
;
1069 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1070 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1072 if (watchpoint
->set
)
1074 LOG_WARNING("watchpoint (%d) already set", watchpoint
->unique_id
);
1078 if (watchpoint
->mask
== 0xffffffffu
)
1080 while (comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1082 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1084 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1085 LOG_WARNING("ERROR Can not find free DWT Comparator");
1088 watchpoint
->set
= dwt_num
+ 1;
1090 temp
= watchpoint
->length
;
1096 comparator_list
[dwt_num
].used
= 1;
1097 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1098 comparator_list
[dwt_num
].mask
= mask
;
1099 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1100 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1101 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x4, comparator_list
[dwt_num
].mask
);
1102 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1103 LOG_DEBUG("dwt_num %i 0x%" PRIx32
" 0x%" PRIx32
" 0x%" PRIx32
"", dwt_num
, comparator_list
[dwt_num
].comp
, comparator_list
[dwt_num
].mask
, comparator_list
[dwt_num
].function
);
1107 /* Move this test to add_watchpoint */
1108 LOG_WARNING("Cannot watch data values (id: %d)",
1109 watchpoint
->unique_id
);
1112 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1113 watchpoint
->unique_id
, watchpoint
->address
, watchpoint
->set
);
1119 cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1121 /* get pointers to arch-specific information */
1122 armv7m_common_t
*armv7m
= target
->arch_info
;
1123 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1124 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1127 if (!watchpoint
->set
)
1129 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint
->unique_id
);
1133 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1134 watchpoint
->unique_id
, watchpoint
->address
,watchpoint
->set
);
1136 dwt_num
= watchpoint
->set
- 1;
1138 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1140 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1143 comparator_list
[dwt_num
].used
= 0;
1144 comparator_list
[dwt_num
].function
= 0;
1145 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1147 watchpoint
->set
= 0;
1153 cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1155 /* get pointers to arch-specific information */
1156 armv7m_common_t
*armv7m
= target
->arch_info
;
1157 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1159 if (target
->state
!= TARGET_HALTED
)
1161 LOG_WARNING("target not halted");
1162 return ERROR_TARGET_NOT_HALTED
;
1165 if (cortex_m3
->dwt_comp_available
< 1)
1167 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1170 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1172 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1175 cortex_m3
->dwt_comp_available
--;
1176 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1182 cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1184 /* get pointers to arch-specific information */
1185 armv7m_common_t
*armv7m
= target
->arch_info
;
1186 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1188 if (target
->state
!= TARGET_HALTED
)
1190 LOG_WARNING("target not halted");
1191 return ERROR_TARGET_NOT_HALTED
;
1194 if (watchpoint
->set
)
1196 cortex_m3_unset_watchpoint(target
, watchpoint
);
1199 cortex_m3
->dwt_comp_available
++;
1200 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1205 static void cortex_m3_enable_watchpoints(struct target_s
*target
)
1207 watchpoint_t
*watchpoint
= target
->watchpoints
;
1209 /* set any pending watchpoints */
1212 if (watchpoint
->set
== 0)
1213 cortex_m3_set_watchpoint(target
, watchpoint
);
1214 watchpoint
= watchpoint
->next
;
1218 static int cortex_m3_load_core_reg_u32(struct target_s
*target
,
1219 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1222 /* get pointers to arch-specific information */
1223 armv7m_common_t
*armv7m
= target
->arch_info
;
1224 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1226 /* NOTE: we "know" here that the register identifiers used
1227 * in the v7m header match the Cortex-M3 Debug Core Register
1228 * Selector values for R0..R15, xPSR, MSP, and PSP.
1232 /* read a normal core register */
1233 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1235 if (retval
!= ERROR_OK
)
1237 LOG_ERROR("JTAG failure %i",retval
);
1238 return ERROR_JTAG_DEVICE_ERROR
;
1240 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1243 case ARMV7M_PRIMASK
:
1244 case ARMV7M_BASEPRI
:
1245 case ARMV7M_FAULTMASK
:
1246 case ARMV7M_CONTROL
:
1247 /* Cortex-M3 packages these four registers as bitfields
1248 * in one Debug Core register. So say r0 and r2 docs;
1249 * it was removed from r1 docs, but still works.
1251 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1255 case ARMV7M_PRIMASK
:
1256 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1259 case ARMV7M_BASEPRI
:
1260 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1263 case ARMV7M_FAULTMASK
:
1264 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1267 case ARMV7M_CONTROL
:
1268 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1272 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1276 return ERROR_INVALID_ARGUMENTS
;
1282 static int cortex_m3_store_core_reg_u32(struct target_s
*target
,
1283 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1288 /* get pointers to arch-specific information */
1289 armv7m_common_t
*armv7m
= target
->arch_info
;
1290 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
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 * Valid exception return codes have bit 0 set too.
1300 if (num
== ARMV7M_R14
)
1304 /* NOTE: we "know" here that the register identifiers used
1305 * in the v7m header match the Cortex-M3 Debug Core Register
1306 * Selector values for R0..R15, xPSR, MSP, and PSP.
1310 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1311 if (retval
!= ERROR_OK
)
1313 LOG_ERROR("JTAG failure %i", retval
);
1314 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1315 return ERROR_JTAG_DEVICE_ERROR
;
1317 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1320 case ARMV7M_PRIMASK
:
1321 case ARMV7M_BASEPRI
:
1322 case ARMV7M_FAULTMASK
:
1323 case ARMV7M_CONTROL
:
1324 /* Cortex-M3 packages these four registers as bitfields
1325 * in one Debug Core register. So say r0 and r2 docs;
1326 * it was removed from r1 docs, but still works.
1328 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1332 case ARMV7M_PRIMASK
:
1333 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1336 case ARMV7M_BASEPRI
:
1337 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1340 case ARMV7M_FAULTMASK
:
1341 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1344 case ARMV7M_CONTROL
:
1345 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1349 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1351 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1355 return ERROR_INVALID_ARGUMENTS
;
1361 static int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
,
1362 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1364 /* get pointers to arch-specific information */
1365 armv7m_common_t
*armv7m
= target
->arch_info
;
1366 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1369 /* sanitize arguments */
1370 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1371 return ERROR_INVALID_ARGUMENTS
;
1373 /* cortex_m3 handles unaligned memory access */
1378 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1381 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1384 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1387 LOG_ERROR("BUG: we shouldn't get here");
1394 static int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
,
1395 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1397 /* get pointers to arch-specific information */
1398 armv7m_common_t
*armv7m
= target
->arch_info
;
1399 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1402 /* sanitize arguments */
1403 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1404 return ERROR_INVALID_ARGUMENTS
;
1409 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1412 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1415 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1418 LOG_ERROR("BUG: we shouldn't get here");
1425 static int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
,
1426 uint32_t count
, uint8_t *buffer
)
1428 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1431 static void cortex_m3_build_reg_cache(target_t
*target
)
1433 armv7m_build_reg_cache(target
);
1436 static int cortex_m3_init_target(struct command_context_s
*cmd_ctx
,
1437 struct target_s
*target
)
1439 cortex_m3_build_reg_cache(target
);
1443 static int cortex_m3_examine(struct target_s
*target
)
1446 uint32_t cpuid
, fpcr
, dwtcr
, ictr
;
1449 /* get pointers to arch-specific information */
1450 armv7m_common_t
*armv7m
= target
->arch_info
;
1451 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1452 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1454 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1457 if (!target_was_examined(target
))
1459 target_set_examined(target
);
1461 /* Read from Device Identification Registers */
1462 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1465 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1466 LOG_DEBUG("CORTEX-M3 processor detected");
1467 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1469 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1470 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1471 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1472 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1474 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1475 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32
"", i
, cortex_m3
->intsetenable
[i
]);
1479 target_read_u32(target
, FP_CTRL
, &fpcr
);
1480 cortex_m3
->auto_bp_type
= 1;
1481 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1482 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1483 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1484 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1485 cortex_m3
->fpb_enabled
= fpcr
& 1;
1486 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1488 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1489 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1491 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1494 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1495 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1496 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1497 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1498 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1500 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1507 static int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1511 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1512 *ctrl
= (uint8_t)dcrdr
;
1513 *value
= (uint8_t)(dcrdr
>> 8);
1515 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1517 /* write ack back to software dcc register
1518 * signify we have read data */
1519 if (dcrdr
& (1 << 0))
1522 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1528 static int cortex_m3_target_request_data(target_t
*target
,
1529 uint32_t size
, uint8_t *buffer
)
1531 armv7m_common_t
*armv7m
= target
->arch_info
;
1532 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1537 for (i
= 0; i
< (size
* 4); i
++)
1539 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1546 static int cortex_m3_handle_target_request(void *priv
)
1548 target_t
*target
= priv
;
1549 if (!target_was_examined(target
))
1551 armv7m_common_t
*armv7m
= target
->arch_info
;
1552 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1554 if (!target
->dbg_msg_enabled
)
1557 if (target
->state
== TARGET_RUNNING
)
1562 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1564 /* check if we have data */
1565 if (ctrl
& (1 << 0))
1569 /* we assume target is quick enough */
1571 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1572 request
|= (data
<< 8);
1573 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1574 request
|= (data
<< 16);
1575 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1576 request
|= (data
<< 24);
1577 target_request(target
, request
);
1584 static int cortex_m3_init_arch_info(target_t
*target
,
1585 cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1588 armv7m_common_t
*armv7m
;
1589 armv7m
= &cortex_m3
->armv7m
;
1591 armv7m_init_arch_info(target
, armv7m
);
1593 /* prepare JTAG information for the new target */
1594 cortex_m3
->jtag_info
.tap
= tap
;
1595 cortex_m3
->jtag_info
.scann_size
= 4;
1597 armv7m
->swjdp_info
.dp_select_value
= -1;
1598 armv7m
->swjdp_info
.ap_csw_value
= -1;
1599 armv7m
->swjdp_info
.ap_tar_value
= -1;
1600 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1601 armv7m
->swjdp_info
.memaccess_tck
= 8;
1602 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1604 /* initialize arch-specific breakpoint handling */
1606 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1607 cortex_m3
->arch_info
= NULL
;
1609 /* register arch-specific functions */
1610 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1612 armv7m
->post_debug_entry
= NULL
;
1614 armv7m
->pre_restore_context
= NULL
;
1615 armv7m
->post_restore_context
= NULL
;
1617 armv7m
->arch_info
= cortex_m3
;
1618 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1619 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1621 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1623 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1631 static int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1633 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1635 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1641 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1642 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1643 * that *only* Thumb2 disassembly matters. There are also some small
1644 * additions to Thumb2 that are specific to ARMv7-M.
1647 handle_cortex_m3_disassemble_command(struct command_context_s
*cmd_ctx
,
1648 char *cmd
, char **args
, int argc
)
1650 int retval
= ERROR_OK
;
1651 target_t
*target
= get_current_target(cmd_ctx
);
1653 unsigned long count
= 1;
1654 arm_instruction_t cur_instruction
;
1659 count
= strtoul(args
[1], NULL
, 0);
1664 address
= strtoul(args
[0], NULL
, 0);
1669 command_print(cmd_ctx
,
1670 "usage: cortex_m3 disassemble <address> [<count>]");
1675 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1676 if (retval
!= ERROR_OK
)
1678 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
1679 address
+= cur_instruction
.instruction_size
;
1685 static const struct {
1689 { "hard_err", VC_HARDERR
, },
1690 { "int_err", VC_INTERR
, },
1691 { "bus_err", VC_BUSERR
, },
1692 { "state_err", VC_STATERR
, },
1693 { "chk_err", VC_CHKERR
, },
1694 { "nocp_err", VC_NOCPERR
, },
1695 { "mm_err", VC_MMERR
, },
1696 { "reset", VC_CORERESET
, },
1700 handle_cortex_m3_vector_catch_command(struct command_context_s
*cmd_ctx
,
1701 char *cmd
, char **argv
, int argc
)
1703 target_t
*target
= get_current_target(cmd_ctx
);
1704 armv7m_common_t
*armv7m
= target
->arch_info
;
1705 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1709 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1715 if (strcmp(argv
[0], "all") == 0) {
1716 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1717 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1718 | VC_MMERR
| VC_CORERESET
;
1720 } else if (strcmp(argv
[0], "none") == 0) {
1724 while (argc
-- > 0) {
1725 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1726 if (strcmp(argv
[argc
], vec_ids
[i
].name
) != 0)
1728 catch |= vec_ids
[i
].mask
;
1731 if (i
== ARRAY_SIZE(vec_ids
)) {
1732 LOG_ERROR("No CM3 vector '%s'", argv
[argc
]);
1733 return ERROR_INVALID_ARGUMENTS
;
1740 /* write, but don't assume it stuck */
1741 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
1742 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1745 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
1746 command_print(cmd_ctx
, "%9s: %s", vec_ids
[i
].name
,
1747 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
1753 handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
,
1754 char *cmd
, char **args
, int argc
)
1756 target_t
*target
= get_current_target(cmd_ctx
);
1757 armv7m_common_t
*armv7m
= target
->arch_info
;
1758 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1760 if (target
->state
!= TARGET_HALTED
)
1762 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1768 if (!strcmp(args
[0], "on"))
1770 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1772 else if (!strcmp(args
[0], "off"))
1774 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1778 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1782 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1783 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
1788 static int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1791 command_t
*cortex_m3_cmd
;
1793 retval
= armv7m_register_commands(cmd_ctx
);
1795 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3",
1796 NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1798 register_command(cmd_ctx
, cortex_m3_cmd
, "disassemble",
1799 handle_cortex_m3_disassemble_command
, COMMAND_EXEC
,
1800 "disassemble Thumb2 instructions <address> [<count>]");
1801 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr",
1802 handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
,
1803 "mask cortex_m3 interrupts ['on'|'off']");
1804 register_command(cmd_ctx
, cortex_m3_cmd
, "vector_catch",
1805 handle_cortex_m3_vector_catch_command
, COMMAND_EXEC
,
1806 "catch hardware vectors ['all'|'none'|<list>]");
1811 target_type_t cortexm3_target
=
1813 .name
= "cortex_m3",
1815 .poll
= cortex_m3_poll
,
1816 .arch_state
= armv7m_arch_state
,
1818 .target_request_data
= cortex_m3_target_request_data
,
1820 .halt
= cortex_m3_halt
,
1821 .resume
= cortex_m3_resume
,
1822 .step
= cortex_m3_step
,
1824 .assert_reset
= cortex_m3_assert_reset
,
1825 .deassert_reset
= cortex_m3_deassert_reset
,
1826 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
1828 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
1830 .read_memory
= cortex_m3_read_memory
,
1831 .write_memory
= cortex_m3_write_memory
,
1832 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
1833 .checksum_memory
= armv7m_checksum_memory
,
1834 .blank_check_memory
= armv7m_blank_check_memory
,
1836 .run_algorithm
= armv7m_run_algorithm
,
1838 .add_breakpoint
= cortex_m3_add_breakpoint
,
1839 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
1840 .add_watchpoint
= cortex_m3_add_watchpoint
,
1841 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
1843 .register_commands
= cortex_m3_register_commands
,
1844 .target_create
= cortex_m3_target_create
,
1845 .init_target
= cortex_m3_init_target
,
1846 .has_mmu
= cortex_m3_has_mmu
,
1847 .examine
= cortex_m3_examine
,
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)