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 cortexm3_dap_read_coreregister_u32(swjdp_common_t
*swjdp
,
56 uint32_t *value
, int regnum
)
61 /* because the DCB_DCRDR is used for the emulated dcc channel
62 * we have to save/restore the DCB_DCRDR when used */
64 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
66 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
68 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
69 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
70 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
72 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
73 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
74 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
76 retval
= swjdp_transaction_endcheck(swjdp
);
78 /* restore DCB_DCRDR - this needs to be in a seperate
79 * transaction otherwise the emulated DCC channel breaks */
80 if (retval
== ERROR_OK
)
81 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
86 static int cortexm3_dap_write_coreregister_u32(swjdp_common_t
*swjdp
,
87 uint32_t value
, int regnum
)
92 /* because the DCB_DCRDR is used for the emulated dcc channel
93 * we have to save/restore the DCB_DCRDR when used */
95 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
97 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
99 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
100 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
101 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
103 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
104 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
105 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
107 retval
= swjdp_transaction_endcheck(swjdp
);
109 /* restore DCB_DCRDR - this needs to be in a seperate
110 * transaction otherwise the emulated DCC channel breaks */
111 if (retval
== ERROR_OK
)
112 retval
= mem_ap_write_atomic_u32(swjdp
, DCB_DCRDR
, dcrdr
);
117 static int cortex_m3_write_debug_halt_mask(target_t
*target
,
118 uint32_t mask_on
, uint32_t mask_off
)
120 /* get pointers to arch-specific information */
121 armv7m_common_t
*armv7m
= target
->arch_info
;
122 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
123 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
125 /* mask off status bits */
126 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
127 /* create new register mask */
128 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
130 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
133 static int cortex_m3_clear_halt(target_t
*target
)
135 /* get pointers to arch-specific information */
136 armv7m_common_t
*armv7m
= target
->arch_info
;
137 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
138 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
140 /* clear step if any */
141 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
143 /* Read Debug Fault Status Register */
144 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
145 /* Clear Debug Fault Status */
146 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
147 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
152 static int cortex_m3_single_step_core(target_t
*target
)
154 /* get pointers to arch-specific information */
155 armv7m_common_t
*armv7m
= target
->arch_info
;
156 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
157 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
160 /* backup dhcsr reg */
161 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
163 /* mask interrupts if not done already */
164 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
165 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
166 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
169 /* restore dhcsr reg */
170 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
171 cortex_m3_clear_halt(target
);
176 static int cortex_m3_endreset_event(target_t
*target
)
181 /* get pointers to arch-specific information */
182 armv7m_common_t
*armv7m
= target
->arch_info
;
183 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
184 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
185 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
186 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
188 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
189 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
191 /* this regsiter is used for emulated dcc channel */
192 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
194 /* Enable debug requests */
195 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
196 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
197 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
199 /* clear any interrupt masking */
200 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
202 /* Enable trace and dwt */
203 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
204 /* Monitor bus faults */
205 mem_ap_write_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
208 target_write_u32(target
, FP_CTRL
, 3);
209 cortex_m3
->fpb_enabled
= 1;
211 /* Restore FPB registers */
212 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
214 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
217 /* Restore DWT registers */
218 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
220 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
221 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
222 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
224 swjdp_transaction_endcheck(swjdp
);
226 armv7m_invalidate_core_regs(target
);
228 /* make sure we have latest dhcsr flags */
229 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
234 static int cortex_m3_examine_debug_reason(target_t
*target
)
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
;
240 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
241 /* only check the debug reason if we don't know it already */
243 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
244 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
246 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
248 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
249 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
250 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
252 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
253 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
254 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
255 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
256 else /* EXTERNAL, HALTED, DWTTRAP w/o BKPT */
257 target
->debug_reason
= DBG_REASON_UNDEFINED
;
263 static int cortex_m3_examine_exception_reason(target_t
*target
)
265 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
267 /* get pointers to arch-specific information */
268 armv7m_common_t
*armv7m
= target
->arch_info
;
269 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
271 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
272 switch (armv7m
->exception_number
)
276 case 3: /* Hard Fault */
277 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
278 if (except_sr
& 0x40000000)
280 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
283 case 4: /* Memory Management */
284 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
285 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
287 case 5: /* Bus Fault */
288 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
289 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
291 case 6: /* Usage Fault */
292 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
294 case 11: /* SVCall */
296 case 12: /* Debug Monitor */
297 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
299 case 14: /* PendSV */
301 case 15: /* SysTick */
307 swjdp_transaction_endcheck(swjdp
);
308 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
"", armv7m_exception_string(armv7m
->exception_number
), \
309 shcsr
, except_sr
, cfsr
, except_ar
);
313 static int cortex_m3_debug_entry(target_t
*target
)
319 /* get pointers to arch-specific information */
320 armv7m_common_t
*armv7m
= target
->arch_info
;
321 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
322 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
326 cortex_m3_clear_halt(target
);
327 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
329 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
332 /* Examine target state and mode */
333 /* First load register acessible through core debug port*/
334 int num_regs
= armv7m
->core_cache
->num_regs
;
336 for (i
= 0; i
< num_regs
; i
++)
338 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
339 armv7m
->read_core_reg(target
, i
);
342 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
344 #ifdef ARMV7_GDB_HACKS
345 /* copy real xpsr reg for gdb, setting thumb bit */
346 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
347 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
348 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
349 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
352 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
355 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
356 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
359 /* Are we in an exception handler */
362 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
363 armv7m
->exception_number
= (xPSR
& 0x1FF);
367 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
368 armv7m
->exception_number
= 0;
371 if (armv7m
->exception_number
)
373 cortex_m3_examine_exception_reason(target
);
376 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
377 armv7m_mode_strings
[armv7m
->core_mode
],
378 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
379 target_state_name(target
));
381 if (armv7m
->post_debug_entry
)
382 armv7m
->post_debug_entry(target
);
387 static int cortex_m3_poll(target_t
*target
)
390 enum target_state prev_target_state
= target
->state
;
392 /* get pointers to arch-specific information */
393 armv7m_common_t
*armv7m
= target
->arch_info
;
394 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
395 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
397 /* Read from Debug Halting Control and Status Register */
398 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
399 if (retval
!= ERROR_OK
)
401 target
->state
= TARGET_UNKNOWN
;
405 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
407 /* check if still in reset */
408 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
410 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
412 target
->state
= TARGET_RESET
;
417 if (target
->state
== TARGET_RESET
)
419 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
420 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
421 cortex_m3_endreset_event(target
);
422 target
->state
= TARGET_RUNNING
;
423 prev_target_state
= TARGET_RUNNING
;
426 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
428 target
->state
= TARGET_HALTED
;
430 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
432 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
435 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
437 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
440 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
443 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
447 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
448 * How best to model low power modes?
451 if (target
->state
== TARGET_UNKNOWN
)
453 /* check if processor is retiring instructions */
454 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
456 target
->state
= TARGET_RUNNING
;
464 static int cortex_m3_halt(target_t
*target
)
466 LOG_DEBUG("target->state: %s",
467 target_state_name(target
));
469 if (target
->state
== TARGET_HALTED
)
471 LOG_DEBUG("target was already halted");
475 if (target
->state
== TARGET_UNKNOWN
)
477 LOG_WARNING("target was in unknown state when halt was requested");
480 if (target
->state
== TARGET_RESET
)
482 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
484 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
485 return ERROR_TARGET_FAILURE
;
489 /* we came here in a reset_halt or reset_init sequence
490 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
492 target
->debug_reason
= DBG_REASON_DBGRQ
;
498 /* Write to Debug Halting Control and Status Register */
499 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
501 target
->debug_reason
= DBG_REASON_DBGRQ
;
506 static int cortex_m3_soft_reset_halt(struct target_s
*target
)
508 /* get pointers to arch-specific information */
509 armv7m_common_t
*armv7m
= target
->arch_info
;
510 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
511 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
512 uint32_t dcb_dhcsr
= 0;
513 int retval
, timeout
= 0;
515 /* Enter debug state on reset, cf. end_reset_event() */
516 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
518 /* Request a reset */
519 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
520 target
->state
= TARGET_RESET
;
522 /* registers are now invalid */
523 armv7m_invalidate_core_regs(target
);
525 while (timeout
< 100)
527 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
528 if (retval
== ERROR_OK
)
530 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
531 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
533 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
534 cortex_m3_poll(target
);
538 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
547 static void cortex_m3_enable_breakpoints(struct target_s
*target
)
549 breakpoint_t
*breakpoint
= target
->breakpoints
;
551 /* set any pending breakpoints */
554 if (breakpoint
->set
== 0)
555 cortex_m3_set_breakpoint(target
, breakpoint
);
556 breakpoint
= breakpoint
->next
;
560 static int cortex_m3_resume(struct target_s
*target
, int current
,
561 uint32_t address
, int handle_breakpoints
, int debug_execution
)
563 /* get pointers to arch-specific information */
564 armv7m_common_t
*armv7m
= target
->arch_info
;
565 breakpoint_t
*breakpoint
= NULL
;
568 if (target
->state
!= TARGET_HALTED
)
570 LOG_WARNING("target not halted");
571 return ERROR_TARGET_NOT_HALTED
;
574 if (!debug_execution
)
576 target_free_all_working_areas(target
);
577 cortex_m3_enable_breakpoints(target
);
578 cortex_m3_enable_watchpoints(target
);
583 /* Disable interrupts */
584 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
585 * This is probably the same issue as Cortex-M3 Errata 377493:
586 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
587 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
588 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
589 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
591 /* Make sure we are in Thumb mode */
592 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
593 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
594 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
595 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
598 /* current = 1: continue on current pc, otherwise continue at <address> */
601 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
602 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
603 armv7m
->core_cache
->reg_list
[15].valid
= 1;
606 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
608 armv7m_restore_context(target
);
610 /* the front-end may request us not to handle breakpoints */
611 if (handle_breakpoints
)
613 /* Single step past breakpoint at current address */
614 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
616 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
618 breakpoint
->unique_id
);
619 cortex_m3_unset_breakpoint(target
, breakpoint
);
620 cortex_m3_single_step_core(target
);
621 cortex_m3_set_breakpoint(target
, breakpoint
);
626 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
628 target
->debug_reason
= DBG_REASON_NOTHALTED
;
630 /* registers are now invalid */
631 armv7m_invalidate_core_regs(target
);
632 if (!debug_execution
)
634 target
->state
= TARGET_RUNNING
;
635 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
636 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
640 target
->state
= TARGET_DEBUG_RUNNING
;
641 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
642 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
648 /* int irqstepcount = 0; */
649 static int cortex_m3_step(struct target_s
*target
, int current
,
650 uint32_t address
, int handle_breakpoints
)
652 /* get pointers to arch-specific information */
653 armv7m_common_t
*armv7m
= target
->arch_info
;
654 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
655 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
656 breakpoint_t
*breakpoint
= NULL
;
658 if (target
->state
!= TARGET_HALTED
)
660 LOG_WARNING("target not halted");
661 return ERROR_TARGET_NOT_HALTED
;
664 /* current = 1: continue on current pc, otherwise continue at <address> */
666 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
668 /* the front-end may request us not to handle breakpoints */
669 if (handle_breakpoints
)
670 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
671 cortex_m3_unset_breakpoint(target
, breakpoint
);
673 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
675 armv7m_restore_context(target
);
677 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
679 /* set step and clear halt */
680 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
681 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
683 /* registers are now invalid */
684 armv7m_invalidate_core_regs(target
);
687 cortex_m3_set_breakpoint(target
, breakpoint
);
689 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
691 cortex_m3_debug_entry(target
);
692 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
694 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
698 static int cortex_m3_assert_reset(target_t
*target
)
700 armv7m_common_t
*armv7m
= target
->arch_info
;
701 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
702 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
705 LOG_DEBUG("target->state: %s",
706 target_state_name(target
));
708 enum reset_types jtag_reset_config
= jtag_get_reset_config();
711 * We can reset Cortex-M3 targets using just the NVIC without
712 * requiring SRST, getting a SoC reset (or a core-only reset)
713 * instead of a system reset.
715 if (!(jtag_reset_config
& RESET_HAS_SRST
))
718 /* Enable debug requests */
719 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
720 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
721 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
723 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
725 if (!target
->reset_halt
)
727 /* Set/Clear C_MASKINTS in a separate operation */
728 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
729 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
731 /* clear any debug flags before resuming */
732 cortex_m3_clear_halt(target
);
734 /* clear C_HALT in dhcsr reg */
735 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
737 /* Enter debug state on reset, cf. end_reset_event() */
738 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
742 /* Enter debug state on reset, cf. end_reset_event() */
743 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
747 * When nRST is asserted on most Stellaris devices, it clears some of
748 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
749 * and OpenOCD depends on those TRMs. So we won't use SRST on those
750 * chips. (Only power-on reset should affect debug state, beyond a
751 * few specified bits; not the chip's nRST input, wired to SRST.)
753 * REVISIT current errata specs don't seem to cover this issue.
754 * Do we have more details than this email?
755 * https://lists.berlios.de/pipermail
756 * /openocd-development/2008-August/003065.html
758 if (strcmp(target
->variant
, "lm3s") == 0)
760 /* Check for silicon revisions with the issue. */
763 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
765 switch ((did0
>> 16) & 0xff)
768 /* all Sandstorm suffer issue */
774 /* Fury and DustDevil rev A have
775 * this nRST problem. It should
776 * be fixed in rev B silicon.
778 if (((did0
>> 8) & 0xff) == 0)
782 /* Tempest should be fine. */
790 /* default to asserting srst */
791 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
793 jtag_add_reset(1, 1);
797 jtag_add_reset(0, 1);
802 /* Use a standard Cortex-M3 software reset mechanism.
803 * SYSRESETREQ will reset SoC peripherals outside the
804 * core, like watchdog timers, if the SoC wires it up
805 * correctly. Else VECRESET can reset just the core.
807 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
808 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
809 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
812 /* I do not know why this is necessary, but it
813 * fixes strange effects (step/resume cause NMI
814 * after reset) on LM3S6918 -- Michael Schwingen
817 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
821 target
->state
= TARGET_RESET
;
822 jtag_add_sleep(50000);
824 armv7m_invalidate_core_regs(target
);
826 if (target
->reset_halt
)
829 if ((retval
= target_halt(target
)) != ERROR_OK
)
836 static int cortex_m3_deassert_reset(target_t
*target
)
838 LOG_DEBUG("target->state: %s",
839 target_state_name(target
));
841 /* deassert reset lines */
842 jtag_add_reset(0, 0);
848 cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
854 /* get pointers to arch-specific information */
855 armv7m_common_t
*armv7m
= target
->arch_info
;
856 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
858 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
862 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
866 if (cortex_m3
->auto_bp_type
)
868 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
871 if (breakpoint
->type
== BKPT_HARD
)
873 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
875 if (fp_num
>= cortex_m3
->fp_num_code
)
877 LOG_DEBUG("ERROR Can not find free FP Comparator");
878 LOG_WARNING("ERROR Can not find free FP Comparator");
881 breakpoint
->set
= fp_num
+ 1;
882 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
883 comparator_list
[fp_num
].used
= 1;
884 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
885 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
886 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
887 if (!cortex_m3
->fpb_enabled
)
889 LOG_DEBUG("FPB wasn't enabled, do it now");
890 target_write_u32(target
, FP_CTRL
, 3);
893 else if (breakpoint
->type
== BKPT_SOFT
)
896 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
897 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
901 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
905 breakpoint
->set
= 0x11; /* Any nice value but 0 */
908 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
909 breakpoint
->unique_id
,
910 (int)(breakpoint
->type
),
919 cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
922 /* get pointers to arch-specific information */
923 armv7m_common_t
*armv7m
= target
->arch_info
;
924 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
925 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
927 if (!breakpoint
->set
)
929 LOG_WARNING("breakpoint not set");
933 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
934 breakpoint
->unique_id
,
935 (int)(breakpoint
->type
),
940 if (breakpoint
->type
== BKPT_HARD
)
942 int fp_num
= breakpoint
->set
- 1;
943 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
945 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
948 comparator_list
[fp_num
].used
= 0;
949 comparator_list
[fp_num
].fpcr_value
= 0;
950 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
954 /* restore original instruction (kept in target endianness) */
955 if (breakpoint
->length
== 4)
957 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
964 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
976 cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
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
;
982 if (cortex_m3
->auto_bp_type
)
984 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
985 #ifdef ARMV7_GDB_HACKS
986 if (breakpoint
->length
!= 2) {
987 /* XXX Hack: Replace all breakpoints with length != 2 with
988 * a hardware breakpoint. */
989 breakpoint
->type
= BKPT_HARD
;
990 breakpoint
->length
= 2;
995 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
997 LOG_INFO("flash patch comparator requested outside code memory region");
998 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1001 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1003 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1004 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1007 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1009 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1010 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1013 if ((breakpoint
->length
!= 2))
1015 LOG_INFO("only breakpoints of two bytes length supported");
1016 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1019 if (breakpoint
->type
== BKPT_HARD
)
1020 cortex_m3
->fp_code_available
--;
1021 cortex_m3_set_breakpoint(target
, breakpoint
);
1027 cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1029 /* get pointers to arch-specific information */
1030 armv7m_common_t
*armv7m
= target
->arch_info
;
1031 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1033 if (target
->state
!= TARGET_HALTED
)
1035 LOG_WARNING("target not halted");
1036 return ERROR_TARGET_NOT_HALTED
;
1039 if (cortex_m3
->auto_bp_type
)
1041 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1044 if (breakpoint
->set
)
1046 cortex_m3_unset_breakpoint(target
, breakpoint
);
1049 if (breakpoint
->type
== BKPT_HARD
)
1050 cortex_m3
->fp_code_available
++;
1056 cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1059 uint32_t mask
, temp
;
1061 /* get pointers to arch-specific information */
1062 armv7m_common_t
*armv7m
= target
->arch_info
;
1063 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1064 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1066 if (watchpoint
->set
)
1068 LOG_WARNING("watchpoint (%d) already set", watchpoint
->unique_id
);
1072 if (watchpoint
->mask
== 0xffffffffu
)
1074 while (comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1076 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1078 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1079 LOG_WARNING("ERROR Can not find free DWT Comparator");
1082 watchpoint
->set
= dwt_num
+ 1;
1084 temp
= watchpoint
->length
;
1090 comparator_list
[dwt_num
].used
= 1;
1091 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1092 comparator_list
[dwt_num
].mask
= mask
;
1093 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1094 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1095 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x4, comparator_list
[dwt_num
].mask
);
1096 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1097 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
);
1101 /* Move this test to add_watchpoint */
1102 LOG_WARNING("Cannot watch data values (id: %d)",
1103 watchpoint
->unique_id
);
1106 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1107 watchpoint
->unique_id
, watchpoint
->address
, watchpoint
->set
);
1113 cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1115 /* get pointers to arch-specific information */
1116 armv7m_common_t
*armv7m
= target
->arch_info
;
1117 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1118 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1121 if (!watchpoint
->set
)
1123 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint
->unique_id
);
1127 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1128 watchpoint
->unique_id
, watchpoint
->address
,watchpoint
->set
);
1130 dwt_num
= watchpoint
->set
- 1;
1132 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1134 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1137 comparator_list
[dwt_num
].used
= 0;
1138 comparator_list
[dwt_num
].function
= 0;
1139 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1141 watchpoint
->set
= 0;
1147 cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1149 /* get pointers to arch-specific information */
1150 armv7m_common_t
*armv7m
= target
->arch_info
;
1151 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1153 if (target
->state
!= TARGET_HALTED
)
1155 LOG_WARNING("target not halted");
1156 return ERROR_TARGET_NOT_HALTED
;
1159 if (cortex_m3
->dwt_comp_available
< 1)
1161 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1164 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1166 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1169 cortex_m3
->dwt_comp_available
--;
1170 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1176 cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1178 /* get pointers to arch-specific information */
1179 armv7m_common_t
*armv7m
= target
->arch_info
;
1180 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1182 if (target
->state
!= TARGET_HALTED
)
1184 LOG_WARNING("target not halted");
1185 return ERROR_TARGET_NOT_HALTED
;
1188 if (watchpoint
->set
)
1190 cortex_m3_unset_watchpoint(target
, watchpoint
);
1193 cortex_m3
->dwt_comp_available
++;
1194 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1199 static void cortex_m3_enable_watchpoints(struct target_s
*target
)
1201 watchpoint_t
*watchpoint
= target
->watchpoints
;
1203 /* set any pending watchpoints */
1206 if (watchpoint
->set
== 0)
1207 cortex_m3_set_watchpoint(target
, watchpoint
);
1208 watchpoint
= watchpoint
->next
;
1212 static int cortex_m3_load_core_reg_u32(struct target_s
*target
,
1213 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1216 /* get pointers to arch-specific information */
1217 armv7m_common_t
*armv7m
= target
->arch_info
;
1218 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1220 /* NOTE: we "know" here that the register identifiers used
1221 * in the v7m header match the Cortex-M3 Debug Core Register
1222 * Selector values for R0..R15, xPSR, MSP, and PSP.
1226 /* read a normal core register */
1227 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1229 if (retval
!= ERROR_OK
)
1231 LOG_ERROR("JTAG failure %i",retval
);
1232 return ERROR_JTAG_DEVICE_ERROR
;
1234 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1237 case ARMV7M_PRIMASK
:
1238 case ARMV7M_BASEPRI
:
1239 case ARMV7M_FAULTMASK
:
1240 case ARMV7M_CONTROL
:
1241 /* Cortex-M3 packages these four registers as bitfields
1242 * in one Debug Core register. So say r0 and r2 docs;
1243 * it was removed from r1 docs, but still works.
1245 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1249 case ARMV7M_PRIMASK
:
1250 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1253 case ARMV7M_BASEPRI
:
1254 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1257 case ARMV7M_FAULTMASK
:
1258 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1261 case ARMV7M_CONTROL
:
1262 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1266 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1270 return ERROR_INVALID_ARGUMENTS
;
1276 static int cortex_m3_store_core_reg_u32(struct target_s
*target
,
1277 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1282 /* get pointers to arch-specific information */
1283 armv7m_common_t
*armv7m
= target
->arch_info
;
1284 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1286 #ifdef ARMV7_GDB_HACKS
1287 /* If the LR register is being modified, make sure it will put us
1288 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1289 * hack to deal with the fact that gdb will sometimes "forge"
1290 * return addresses, and doesn't set the LSB correctly (i.e., when
1291 * printing expressions containing function calls, it sets LR = 0.)
1292 * Valid exception return codes have bit 0 set too.
1294 if (num
== ARMV7M_R14
)
1298 /* NOTE: we "know" here that the register identifiers used
1299 * in the v7m header match the Cortex-M3 Debug Core Register
1300 * Selector values for R0..R15, xPSR, MSP, and PSP.
1304 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1305 if (retval
!= ERROR_OK
)
1307 LOG_ERROR("JTAG failure %i", retval
);
1308 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1309 return ERROR_JTAG_DEVICE_ERROR
;
1311 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1314 case ARMV7M_PRIMASK
:
1315 case ARMV7M_BASEPRI
:
1316 case ARMV7M_FAULTMASK
:
1317 case ARMV7M_CONTROL
:
1318 /* Cortex-M3 packages these four registers as bitfields
1319 * in one Debug Core register. So say r0 and r2 docs;
1320 * it was removed from r1 docs, but still works.
1322 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1326 case ARMV7M_PRIMASK
:
1327 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1330 case ARMV7M_BASEPRI
:
1331 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1334 case ARMV7M_FAULTMASK
:
1335 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1338 case ARMV7M_CONTROL
:
1339 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1343 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1345 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1349 return ERROR_INVALID_ARGUMENTS
;
1355 static int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
,
1356 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1358 /* get pointers to arch-specific information */
1359 armv7m_common_t
*armv7m
= target
->arch_info
;
1360 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1363 /* sanitize arguments */
1364 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1365 return ERROR_INVALID_ARGUMENTS
;
1367 /* cortex_m3 handles unaligned memory access */
1372 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1375 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1378 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1381 LOG_ERROR("BUG: we shouldn't get here");
1388 static int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
,
1389 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1391 /* get pointers to arch-specific information */
1392 armv7m_common_t
*armv7m
= target
->arch_info
;
1393 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1396 /* sanitize arguments */
1397 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1398 return ERROR_INVALID_ARGUMENTS
;
1403 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1406 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1409 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1412 LOG_ERROR("BUG: we shouldn't get here");
1419 static int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
,
1420 uint32_t count
, uint8_t *buffer
)
1422 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1425 static void cortex_m3_build_reg_cache(target_t
*target
)
1427 armv7m_build_reg_cache(target
);
1430 static int cortex_m3_init_target(struct command_context_s
*cmd_ctx
,
1431 struct target_s
*target
)
1433 cortex_m3_build_reg_cache(target
);
1437 static int cortex_m3_examine(struct target_s
*target
)
1440 uint32_t cpuid
, fpcr
, dwtcr
, ictr
;
1443 /* get pointers to arch-specific information */
1444 armv7m_common_t
*armv7m
= target
->arch_info
;
1445 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1446 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1448 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1451 if (!target_was_examined(target
))
1453 target_set_examined(target
);
1455 /* Read from Device Identification Registers */
1456 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1459 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1460 LOG_DEBUG("CORTEX-M3 processor detected");
1461 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1463 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1464 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1465 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1466 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1468 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1469 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32
"", i
, cortex_m3
->intsetenable
[i
]);
1473 target_read_u32(target
, FP_CTRL
, &fpcr
);
1474 cortex_m3
->auto_bp_type
= 1;
1475 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1476 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1477 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1478 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1479 cortex_m3
->fpb_enabled
= fpcr
& 1;
1480 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1482 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1483 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1485 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1488 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1489 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1490 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1491 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1492 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1494 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1501 static int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1505 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1506 *ctrl
= (uint8_t)dcrdr
;
1507 *value
= (uint8_t)(dcrdr
>> 8);
1509 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1511 /* write ack back to software dcc register
1512 * signify we have read data */
1513 if (dcrdr
& (1 << 0))
1516 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1522 static int cortex_m3_target_request_data(target_t
*target
,
1523 uint32_t size
, uint8_t *buffer
)
1525 armv7m_common_t
*armv7m
= target
->arch_info
;
1526 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1531 for (i
= 0; i
< (size
* 4); i
++)
1533 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1540 static int cortex_m3_handle_target_request(void *priv
)
1542 target_t
*target
= priv
;
1543 if (!target_was_examined(target
))
1545 armv7m_common_t
*armv7m
= target
->arch_info
;
1546 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1548 if (!target
->dbg_msg_enabled
)
1551 if (target
->state
== TARGET_RUNNING
)
1556 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1558 /* check if we have data */
1559 if (ctrl
& (1 << 0))
1563 /* we assume target is quick enough */
1565 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1566 request
|= (data
<< 8);
1567 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1568 request
|= (data
<< 16);
1569 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1570 request
|= (data
<< 24);
1571 target_request(target
, request
);
1578 static int cortex_m3_init_arch_info(target_t
*target
,
1579 cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1582 armv7m_common_t
*armv7m
;
1583 armv7m
= &cortex_m3
->armv7m
;
1585 armv7m_init_arch_info(target
, armv7m
);
1587 /* prepare JTAG information for the new target */
1588 cortex_m3
->jtag_info
.tap
= tap
;
1589 cortex_m3
->jtag_info
.scann_size
= 4;
1591 armv7m
->swjdp_info
.dp_select_value
= -1;
1592 armv7m
->swjdp_info
.ap_csw_value
= -1;
1593 armv7m
->swjdp_info
.ap_tar_value
= -1;
1594 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1595 armv7m
->swjdp_info
.memaccess_tck
= 8;
1596 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1598 /* initialize arch-specific breakpoint handling */
1600 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1601 cortex_m3
->arch_info
= NULL
;
1603 /* register arch-specific functions */
1604 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1606 armv7m
->post_debug_entry
= NULL
;
1608 armv7m
->pre_restore_context
= NULL
;
1609 armv7m
->post_restore_context
= NULL
;
1611 armv7m
->arch_info
= cortex_m3
;
1612 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1613 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1615 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1617 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1625 static int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1627 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1629 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1635 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1636 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1637 * that *only* Thumb2 disassembly matters. There are also some small
1638 * additions to Thumb2 that are specific to ARMv7-M.
1641 handle_cortex_m3_disassemble_command(struct command_context_s
*cmd_ctx
,
1642 char *cmd
, char **args
, int argc
)
1644 int retval
= ERROR_OK
;
1645 target_t
*target
= get_current_target(cmd_ctx
);
1647 unsigned long count
= 1;
1648 arm_instruction_t cur_instruction
;
1653 count
= strtoul(args
[1], NULL
, 0);
1658 address
= strtoul(args
[0], NULL
, 0);
1663 command_print(cmd_ctx
,
1664 "usage: cortex_m3 disassemble <address> [<count>]");
1669 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1670 if (retval
!= ERROR_OK
)
1672 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
1673 address
+= cur_instruction
.instruction_size
;
1679 static const struct {
1683 { "hard_err", VC_HARDERR
, },
1684 { "int_err", VC_INTERR
, },
1685 { "bus_err", VC_BUSERR
, },
1686 { "state_err", VC_STATERR
, },
1687 { "chk_err", VC_CHKERR
, },
1688 { "nocp_err", VC_NOCPERR
, },
1689 { "mm_err", VC_MMERR
, },
1690 { "reset", VC_CORERESET
, },
1694 handle_cortex_m3_vector_catch_command(struct command_context_s
*cmd_ctx
,
1695 char *cmd
, char **argv
, int argc
)
1697 target_t
*target
= get_current_target(cmd_ctx
);
1698 armv7m_common_t
*armv7m
= target
->arch_info
;
1699 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1703 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1709 if (strcmp(argv
[0], "all") == 0) {
1710 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1711 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1712 | VC_MMERR
| VC_CORERESET
;
1714 } else if (strcmp(argv
[0], "none") == 0) {
1718 while (argc
-- > 0) {
1719 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1720 if (strcmp(argv
[argc
], vec_ids
[i
].name
) != 0)
1722 catch |= vec_ids
[i
].mask
;
1725 if (i
== ARRAY_SIZE(vec_ids
)) {
1726 LOG_ERROR("No CM3 vector '%s'", argv
[argc
]);
1727 return ERROR_INVALID_ARGUMENTS
;
1734 /* write, but don't assume it stuck */
1735 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
1736 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1739 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
1740 command_print(cmd_ctx
, "%9s: %s", vec_ids
[i
].name
,
1741 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
1747 handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
,
1748 char *cmd
, char **args
, int argc
)
1750 target_t
*target
= get_current_target(cmd_ctx
);
1751 armv7m_common_t
*armv7m
= target
->arch_info
;
1752 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1754 if (target
->state
!= TARGET_HALTED
)
1756 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1762 if (!strcmp(args
[0], "on"))
1764 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1766 else if (!strcmp(args
[0], "off"))
1768 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1772 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1776 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1777 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
1782 static int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1785 command_t
*cortex_m3_cmd
;
1787 retval
= armv7m_register_commands(cmd_ctx
);
1789 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3",
1790 NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1792 register_command(cmd_ctx
, cortex_m3_cmd
, "disassemble",
1793 handle_cortex_m3_disassemble_command
, COMMAND_EXEC
,
1794 "disassemble Thumb2 instructions <address> [<count>]");
1795 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr",
1796 handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
,
1797 "mask cortex_m3 interrupts ['on'|'off']");
1798 register_command(cmd_ctx
, cortex_m3_cmd
, "vector_catch",
1799 handle_cortex_m3_vector_catch_command
, COMMAND_EXEC
,
1800 "catch hardware vectors ['all'|'none'|<list>]");
1805 target_type_t cortexm3_target
=
1807 .name
= "cortex_m3",
1809 .poll
= cortex_m3_poll
,
1810 .arch_state
= armv7m_arch_state
,
1812 .target_request_data
= cortex_m3_target_request_data
,
1814 .halt
= cortex_m3_halt
,
1815 .resume
= cortex_m3_resume
,
1816 .step
= cortex_m3_step
,
1818 .assert_reset
= cortex_m3_assert_reset
,
1819 .deassert_reset
= cortex_m3_deassert_reset
,
1820 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
1822 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
1824 .read_memory
= cortex_m3_read_memory
,
1825 .write_memory
= cortex_m3_write_memory
,
1826 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
1827 .checksum_memory
= armv7m_checksum_memory
,
1828 .blank_check_memory
= armv7m_blank_check_memory
,
1830 .run_algorithm
= armv7m_run_algorithm
,
1832 .add_breakpoint
= cortex_m3_add_breakpoint
,
1833 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
1834 .add_watchpoint
= cortex_m3_add_watchpoint
,
1835 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
1837 .register_commands
= cortex_m3_register_commands
,
1838 .target_create
= cortex_m3_target_create
,
1839 .init_target
= cortex_m3_init_target
,
1840 .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)