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
+ 0,
228 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 4,
230 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
+ 8,
231 dwt_list
[i
].function
);
233 swjdp_transaction_endcheck(swjdp
);
235 armv7m_invalidate_core_regs(target
);
237 /* make sure we have latest dhcsr flags */
238 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
243 static int cortex_m3_examine_debug_reason(target_t
*target
)
245 /* get pointers to arch-specific information */
246 armv7m_common_t
*armv7m
= target
->arch_info
;
247 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
249 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
250 /* only check the debug reason if we don't know it already */
252 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
253 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
255 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
257 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
258 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
259 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
261 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
262 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
263 else if (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
)
264 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
265 else /* EXTERNAL, HALTED */
266 target
->debug_reason
= DBG_REASON_UNDEFINED
;
272 static int cortex_m3_examine_exception_reason(target_t
*target
)
274 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
276 /* get pointers to arch-specific information */
277 armv7m_common_t
*armv7m
= target
->arch_info
;
278 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
280 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
281 switch (armv7m
->exception_number
)
285 case 3: /* Hard Fault */
286 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
287 if (except_sr
& 0x40000000)
289 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
292 case 4: /* Memory Management */
293 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
294 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
296 case 5: /* Bus Fault */
297 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
298 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
300 case 6: /* Usage Fault */
301 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
303 case 11: /* SVCall */
305 case 12: /* Debug Monitor */
306 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
308 case 14: /* PendSV */
310 case 15: /* SysTick */
316 swjdp_transaction_endcheck(swjdp
);
317 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
"", armv7m_exception_string(armv7m
->exception_number
), \
318 shcsr
, except_sr
, cfsr
, except_ar
);
322 static int cortex_m3_debug_entry(target_t
*target
)
328 /* get pointers to arch-specific information */
329 armv7m_common_t
*armv7m
= target
->arch_info
;
330 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
331 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
335 cortex_m3_clear_halt(target
);
336 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
338 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
341 /* Examine target state and mode */
342 /* First load register acessible through core debug port*/
343 int num_regs
= armv7m
->core_cache
->num_regs
;
345 for (i
= 0; i
< num_regs
; i
++)
347 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
348 armv7m
->read_core_reg(target
, i
);
351 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
353 #ifdef ARMV7_GDB_HACKS
354 /* copy real xpsr reg for gdb, setting thumb bit */
355 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
356 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
357 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
358 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
361 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
364 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
365 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
368 /* Are we in an exception handler */
371 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
372 armv7m
->exception_number
= (xPSR
& 0x1FF);
376 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
377 armv7m
->exception_number
= 0;
380 if (armv7m
->exception_number
)
382 cortex_m3_examine_exception_reason(target
);
385 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
386 armv7m_mode_strings
[armv7m
->core_mode
],
387 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
388 target_state_name(target
));
390 if (armv7m
->post_debug_entry
)
391 armv7m
->post_debug_entry(target
);
396 static int cortex_m3_poll(target_t
*target
)
399 enum target_state prev_target_state
= target
->state
;
401 /* get pointers to arch-specific information */
402 armv7m_common_t
*armv7m
= target
->arch_info
;
403 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
404 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
406 /* Read from Debug Halting Control and Status Register */
407 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
408 if (retval
!= ERROR_OK
)
410 target
->state
= TARGET_UNKNOWN
;
414 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
416 /* check if still in reset */
417 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
419 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
421 target
->state
= TARGET_RESET
;
426 if (target
->state
== TARGET_RESET
)
428 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
429 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
430 cortex_m3_endreset_event(target
);
431 target
->state
= TARGET_RUNNING
;
432 prev_target_state
= TARGET_RUNNING
;
435 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
437 target
->state
= TARGET_HALTED
;
439 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
441 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
444 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
446 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
449 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
452 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
456 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
457 * How best to model low power modes?
460 if (target
->state
== TARGET_UNKNOWN
)
462 /* check if processor is retiring instructions */
463 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
465 target
->state
= TARGET_RUNNING
;
473 static int cortex_m3_halt(target_t
*target
)
475 LOG_DEBUG("target->state: %s",
476 target_state_name(target
));
478 if (target
->state
== TARGET_HALTED
)
480 LOG_DEBUG("target was already halted");
484 if (target
->state
== TARGET_UNKNOWN
)
486 LOG_WARNING("target was in unknown state when halt was requested");
489 if (target
->state
== TARGET_RESET
)
491 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
493 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
494 return ERROR_TARGET_FAILURE
;
498 /* we came here in a reset_halt or reset_init sequence
499 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
501 target
->debug_reason
= DBG_REASON_DBGRQ
;
507 /* Write to Debug Halting Control and Status Register */
508 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
510 target
->debug_reason
= DBG_REASON_DBGRQ
;
515 static int cortex_m3_soft_reset_halt(struct target_s
*target
)
517 /* get pointers to arch-specific information */
518 armv7m_common_t
*armv7m
= target
->arch_info
;
519 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
520 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
521 uint32_t dcb_dhcsr
= 0;
522 int retval
, timeout
= 0;
524 /* Enter debug state on reset, cf. end_reset_event() */
525 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
527 /* Request a reset */
528 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
529 target
->state
= TARGET_RESET
;
531 /* registers are now invalid */
532 armv7m_invalidate_core_regs(target
);
534 while (timeout
< 100)
536 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
537 if (retval
== ERROR_OK
)
539 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
540 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
542 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
543 cortex_m3_poll(target
);
547 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
556 static void cortex_m3_enable_breakpoints(struct target_s
*target
)
558 breakpoint_t
*breakpoint
= target
->breakpoints
;
560 /* set any pending breakpoints */
563 if (breakpoint
->set
== 0)
564 cortex_m3_set_breakpoint(target
, breakpoint
);
565 breakpoint
= breakpoint
->next
;
569 static int cortex_m3_resume(struct target_s
*target
, int current
,
570 uint32_t address
, int handle_breakpoints
, int debug_execution
)
572 /* get pointers to arch-specific information */
573 armv7m_common_t
*armv7m
= target
->arch_info
;
574 breakpoint_t
*breakpoint
= NULL
;
577 if (target
->state
!= TARGET_HALTED
)
579 LOG_WARNING("target not halted");
580 return ERROR_TARGET_NOT_HALTED
;
583 if (!debug_execution
)
585 target_free_all_working_areas(target
);
586 cortex_m3_enable_breakpoints(target
);
587 cortex_m3_enable_watchpoints(target
);
592 /* Disable interrupts */
593 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
594 * This is probably the same issue as Cortex-M3 Errata 377493:
595 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
596 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
597 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
598 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
600 /* Make sure we are in Thumb mode */
601 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
602 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
603 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
604 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
607 /* current = 1: continue on current pc, otherwise continue at <address> */
610 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
611 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
612 armv7m
->core_cache
->reg_list
[15].valid
= 1;
615 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
617 armv7m_restore_context(target
);
619 /* the front-end may request us not to handle breakpoints */
620 if (handle_breakpoints
)
622 /* Single step past breakpoint at current address */
623 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
625 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
627 breakpoint
->unique_id
);
628 cortex_m3_unset_breakpoint(target
, breakpoint
);
629 cortex_m3_single_step_core(target
);
630 cortex_m3_set_breakpoint(target
, breakpoint
);
635 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
637 target
->debug_reason
= DBG_REASON_NOTHALTED
;
639 /* registers are now invalid */
640 armv7m_invalidate_core_regs(target
);
641 if (!debug_execution
)
643 target
->state
= TARGET_RUNNING
;
644 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
645 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
649 target
->state
= TARGET_DEBUG_RUNNING
;
650 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
651 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
657 /* int irqstepcount = 0; */
658 static int cortex_m3_step(struct target_s
*target
, int current
,
659 uint32_t address
, int handle_breakpoints
)
661 /* get pointers to arch-specific information */
662 armv7m_common_t
*armv7m
= target
->arch_info
;
663 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
664 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
665 breakpoint_t
*breakpoint
= NULL
;
667 if (target
->state
!= TARGET_HALTED
)
669 LOG_WARNING("target not halted");
670 return ERROR_TARGET_NOT_HALTED
;
673 /* current = 1: continue on current pc, otherwise continue at <address> */
675 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
677 /* the front-end may request us not to handle breakpoints */
678 if (handle_breakpoints
)
679 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
680 cortex_m3_unset_breakpoint(target
, breakpoint
);
682 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
684 armv7m_restore_context(target
);
686 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
688 /* set step and clear halt */
689 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
690 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
692 /* registers are now invalid */
693 armv7m_invalidate_core_regs(target
);
696 cortex_m3_set_breakpoint(target
, breakpoint
);
698 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
700 cortex_m3_debug_entry(target
);
701 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
703 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
707 static int cortex_m3_assert_reset(target_t
*target
)
709 armv7m_common_t
*armv7m
= target
->arch_info
;
710 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
711 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
714 LOG_DEBUG("target->state: %s",
715 target_state_name(target
));
717 enum reset_types jtag_reset_config
= jtag_get_reset_config();
720 * We can reset Cortex-M3 targets using just the NVIC without
721 * requiring SRST, getting a SoC reset (or a core-only reset)
722 * instead of a system reset.
724 if (!(jtag_reset_config
& RESET_HAS_SRST
))
727 /* Enable debug requests */
728 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
729 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
730 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
732 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
734 if (!target
->reset_halt
)
736 /* Set/Clear C_MASKINTS in a separate operation */
737 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
738 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
740 /* clear any debug flags before resuming */
741 cortex_m3_clear_halt(target
);
743 /* clear C_HALT in dhcsr reg */
744 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
746 /* Enter debug state on reset, cf. end_reset_event() */
747 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
751 /* Enter debug state on reset, cf. end_reset_event() */
752 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
756 * When nRST is asserted on most Stellaris devices, it clears some of
757 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
758 * and OpenOCD depends on those TRMs. So we won't use SRST on those
759 * chips. (Only power-on reset should affect debug state, beyond a
760 * few specified bits; not the chip's nRST input, wired to SRST.)
762 * REVISIT current errata specs don't seem to cover this issue.
763 * Do we have more details than this email?
764 * https://lists.berlios.de/pipermail
765 * /openocd-development/2008-August/003065.html
767 if (strcmp(target
->variant
, "lm3s") == 0)
769 /* Check for silicon revisions with the issue. */
772 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
774 switch ((did0
>> 16) & 0xff)
777 /* all Sandstorm suffer issue */
783 /* Fury and DustDevil rev A have
784 * this nRST problem. It should
785 * be fixed in rev B silicon.
787 if (((did0
>> 8) & 0xff) == 0)
791 /* Tempest should be fine. */
799 /* default to asserting srst */
800 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
802 jtag_add_reset(1, 1);
806 jtag_add_reset(0, 1);
811 /* Use a standard Cortex-M3 software reset mechanism.
812 * SYSRESETREQ will reset SoC peripherals outside the
813 * core, like watchdog timers, if the SoC wires it up
814 * correctly. Else VECRESET can reset just the core.
816 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
817 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
818 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
821 /* I do not know why this is necessary, but it
822 * fixes strange effects (step/resume cause NMI
823 * after reset) on LM3S6918 -- Michael Schwingen
826 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
830 target
->state
= TARGET_RESET
;
831 jtag_add_sleep(50000);
833 armv7m_invalidate_core_regs(target
);
835 if (target
->reset_halt
)
838 if ((retval
= target_halt(target
)) != ERROR_OK
)
845 static int cortex_m3_deassert_reset(target_t
*target
)
847 LOG_DEBUG("target->state: %s",
848 target_state_name(target
));
850 /* deassert reset lines */
851 jtag_add_reset(0, 0);
857 cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
863 /* get pointers to arch-specific information */
864 armv7m_common_t
*armv7m
= target
->arch_info
;
865 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
867 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
871 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
875 if (cortex_m3
->auto_bp_type
)
877 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
880 if (breakpoint
->type
== BKPT_HARD
)
882 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
884 if (fp_num
>= cortex_m3
->fp_num_code
)
886 LOG_DEBUG("ERROR Can not find free FP Comparator");
887 LOG_WARNING("ERROR Can not find free FP Comparator");
890 breakpoint
->set
= fp_num
+ 1;
891 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
892 comparator_list
[fp_num
].used
= 1;
893 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
894 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
895 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
896 if (!cortex_m3
->fpb_enabled
)
898 LOG_DEBUG("FPB wasn't enabled, do it now");
899 target_write_u32(target
, FP_CTRL
, 3);
902 else if (breakpoint
->type
== BKPT_SOFT
)
905 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
906 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
910 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
914 breakpoint
->set
= 0x11; /* Any nice value but 0 */
917 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
918 breakpoint
->unique_id
,
919 (int)(breakpoint
->type
),
928 cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
931 /* get pointers to arch-specific information */
932 armv7m_common_t
*armv7m
= target
->arch_info
;
933 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
934 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
936 if (!breakpoint
->set
)
938 LOG_WARNING("breakpoint not set");
942 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
943 breakpoint
->unique_id
,
944 (int)(breakpoint
->type
),
949 if (breakpoint
->type
== BKPT_HARD
)
951 int fp_num
= breakpoint
->set
- 1;
952 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
954 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
957 comparator_list
[fp_num
].used
= 0;
958 comparator_list
[fp_num
].fpcr_value
= 0;
959 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
963 /* restore original instruction (kept in target endianness) */
964 if (breakpoint
->length
== 4)
966 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
973 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
985 cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
987 /* get pointers to arch-specific information */
988 armv7m_common_t
*armv7m
= target
->arch_info
;
989 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
991 if (cortex_m3
->auto_bp_type
)
993 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
994 #ifdef ARMV7_GDB_HACKS
995 if (breakpoint
->length
!= 2) {
996 /* XXX Hack: Replace all breakpoints with length != 2 with
997 * a hardware breakpoint. */
998 breakpoint
->type
= BKPT_HARD
;
999 breakpoint
->length
= 2;
1004 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1006 LOG_INFO("flash patch comparator requested outside code memory region");
1007 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1010 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1012 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1013 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1016 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1018 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1019 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1022 if ((breakpoint
->length
!= 2))
1024 LOG_INFO("only breakpoints of two bytes length supported");
1025 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1028 if (breakpoint
->type
== BKPT_HARD
)
1029 cortex_m3
->fp_code_available
--;
1030 cortex_m3_set_breakpoint(target
, breakpoint
);
1036 cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1038 /* get pointers to arch-specific information */
1039 armv7m_common_t
*armv7m
= target
->arch_info
;
1040 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1042 /* REVISIT why check? FBP can be updated with core running ... */
1043 if (target
->state
!= TARGET_HALTED
)
1045 LOG_WARNING("target not halted");
1046 return ERROR_TARGET_NOT_HALTED
;
1049 if (cortex_m3
->auto_bp_type
)
1051 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1054 if (breakpoint
->set
)
1056 cortex_m3_unset_breakpoint(target
, breakpoint
);
1059 if (breakpoint
->type
== BKPT_HARD
)
1060 cortex_m3
->fp_code_available
++;
1066 cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1069 uint32_t mask
, temp
;
1071 /* get pointers to arch-specific information */
1072 armv7m_common_t
*armv7m
= target
->arch_info
;
1073 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1075 /* watchpoint params were validated earlier */
1077 temp
= watchpoint
->length
;
1084 /* REVISIT Don't fully trust these "not used" records ... users
1085 * may set up breakpoints by hand, e.g. dual-address data value
1086 * watchpoint using comparator #1; comparator #0 matching cycle
1087 * count; send data trace info through ITM and TPIU; etc
1089 cortex_m3_dwt_comparator_t
*comparator
;
1091 for (comparator
= cortex_m3
->dwt_comparator_list
;
1092 comparator
->used
&& dwt_num
< cortex_m3
->dwt_num_comp
;
1093 comparator
++, dwt_num
++)
1095 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1097 LOG_ERROR("Can not find free DWT Comparator");
1100 comparator
->used
= 1;
1101 watchpoint
->set
= dwt_num
+ 1;
1103 comparator
->comp
= watchpoint
->address
;
1104 target_write_u32(target
, comparator
->dwt_comparator_address
+ 0,
1107 comparator
->mask
= mask
;
1108 target_write_u32(target
, comparator
->dwt_comparator_address
+ 4,
1111 switch (watchpoint
->rw
) {
1113 comparator
->function
= 5;
1116 comparator
->function
= 6;
1119 comparator
->function
= 7;
1122 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1123 comparator
->function
);
1125 LOG_DEBUG("Watchpoint (ID %d) DWT%d 0x%08x 0x%x 0x%05x",
1126 watchpoint
->unique_id
, dwt_num
,
1127 (unsigned) comparator
->comp
,
1128 (unsigned) comparator
->mask
,
1129 (unsigned) comparator
->function
);
1134 cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1136 /* get pointers to arch-specific information */
1137 armv7m_common_t
*armv7m
= target
->arch_info
;
1138 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1139 cortex_m3_dwt_comparator_t
*comparator
;
1142 if (!watchpoint
->set
)
1144 LOG_WARNING("watchpoint (wpid: %d) not set",
1145 watchpoint
->unique_id
);
1149 dwt_num
= watchpoint
->set
- 1;
1151 LOG_DEBUG("Watchpoint (ID %d) DWT%d address: 0x%08x clear",
1152 watchpoint
->unique_id
, dwt_num
,
1153 (unsigned) watchpoint
->address
);
1155 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1157 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1161 comparator
= cortex_m3
->dwt_comparator_list
+ dwt_num
;
1162 comparator
->used
= 0;
1163 comparator
->function
= 0;
1164 target_write_u32(target
, comparator
->dwt_comparator_address
+ 8,
1165 comparator
->function
);
1167 watchpoint
->set
= 0;
1173 cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1175 /* get pointers to arch-specific information */
1176 armv7m_common_t
*armv7m
= target
->arch_info
;
1177 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1179 /* REVISIT why check? DWT can be updated with core running ... */
1180 if (target
->state
!= TARGET_HALTED
)
1182 LOG_WARNING("target not halted");
1183 return ERROR_TARGET_NOT_HALTED
;
1186 if (cortex_m3
->dwt_comp_available
< 1)
1188 LOG_DEBUG("no comparators?");
1189 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1192 /* hardware doesn't support data value masking */
1193 if (watchpoint
->mask
!= ~(uint32_t)0) {
1194 LOG_DEBUG("watchpoint value masks not supported");
1195 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1198 /* hardware allows address masks of up to 32K */
1201 for (mask
= 0; mask
< 16; mask
++) {
1202 if ((1 << mask
) == watchpoint
->length
)
1206 LOG_DEBUG("unsupported watchpoint length");
1207 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1209 if (watchpoint
->address
& ((1 << mask
) - 1)) {
1210 LOG_DEBUG("watchpoint address is unaligned");
1211 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1214 /* Caller doesn't seem to be able to describe watching for data
1215 * values of zero; that flags "no value".
1217 * REVISIT This DWT may well be able to watch for specific data
1218 * values. Requires comparator #1 to set DATAVMATCH and match
1219 * the data, and another comparator (DATAVADDR0) matching addr.
1221 if (watchpoint
->value
) {
1222 LOG_DEBUG("data value watchpoint not YET supported");
1223 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1226 cortex_m3
->dwt_comp_available
--;
1227 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1233 cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1235 /* get pointers to arch-specific information */
1236 armv7m_common_t
*armv7m
= target
->arch_info
;
1237 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1239 /* REVISIT why check? DWT can be updated with core running ... */
1240 if (target
->state
!= TARGET_HALTED
)
1242 LOG_WARNING("target not halted");
1243 return ERROR_TARGET_NOT_HALTED
;
1246 if (watchpoint
->set
)
1248 cortex_m3_unset_watchpoint(target
, watchpoint
);
1251 cortex_m3
->dwt_comp_available
++;
1252 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1257 static void cortex_m3_enable_watchpoints(struct target_s
*target
)
1259 watchpoint_t
*watchpoint
= target
->watchpoints
;
1261 /* set any pending watchpoints */
1264 if (watchpoint
->set
== 0)
1265 cortex_m3_set_watchpoint(target
, watchpoint
);
1266 watchpoint
= watchpoint
->next
;
1270 static int cortex_m3_load_core_reg_u32(struct target_s
*target
,
1271 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1274 /* get pointers to arch-specific information */
1275 armv7m_common_t
*armv7m
= target
->arch_info
;
1276 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1278 /* NOTE: we "know" here that the register identifiers used
1279 * in the v7m header match the Cortex-M3 Debug Core Register
1280 * Selector values for R0..R15, xPSR, MSP, and PSP.
1284 /* read a normal core register */
1285 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1287 if (retval
!= ERROR_OK
)
1289 LOG_ERROR("JTAG failure %i",retval
);
1290 return ERROR_JTAG_DEVICE_ERROR
;
1292 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1295 case ARMV7M_PRIMASK
:
1296 case ARMV7M_BASEPRI
:
1297 case ARMV7M_FAULTMASK
:
1298 case ARMV7M_CONTROL
:
1299 /* Cortex-M3 packages these four registers as bitfields
1300 * in one Debug Core register. So say r0 and r2 docs;
1301 * it was removed from r1 docs, but still works.
1303 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1307 case ARMV7M_PRIMASK
:
1308 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1311 case ARMV7M_BASEPRI
:
1312 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1315 case ARMV7M_FAULTMASK
:
1316 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1319 case ARMV7M_CONTROL
:
1320 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1324 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1328 return ERROR_INVALID_ARGUMENTS
;
1334 static int cortex_m3_store_core_reg_u32(struct target_s
*target
,
1335 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1340 /* get pointers to arch-specific information */
1341 armv7m_common_t
*armv7m
= target
->arch_info
;
1342 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1344 #ifdef ARMV7_GDB_HACKS
1345 /* If the LR register is being modified, make sure it will put us
1346 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1347 * hack to deal with the fact that gdb will sometimes "forge"
1348 * return addresses, and doesn't set the LSB correctly (i.e., when
1349 * printing expressions containing function calls, it sets LR = 0.)
1350 * Valid exception return codes have bit 0 set too.
1352 if (num
== ARMV7M_R14
)
1356 /* NOTE: we "know" here that the register identifiers used
1357 * in the v7m header match the Cortex-M3 Debug Core Register
1358 * Selector values for R0..R15, xPSR, MSP, and PSP.
1362 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1363 if (retval
!= ERROR_OK
)
1365 LOG_ERROR("JTAG failure %i", retval
);
1366 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1367 return ERROR_JTAG_DEVICE_ERROR
;
1369 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1372 case ARMV7M_PRIMASK
:
1373 case ARMV7M_BASEPRI
:
1374 case ARMV7M_FAULTMASK
:
1375 case ARMV7M_CONTROL
:
1376 /* Cortex-M3 packages these four registers as bitfields
1377 * in one Debug Core register. So say r0 and r2 docs;
1378 * it was removed from r1 docs, but still works.
1380 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1384 case ARMV7M_PRIMASK
:
1385 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1388 case ARMV7M_BASEPRI
:
1389 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1392 case ARMV7M_FAULTMASK
:
1393 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1396 case ARMV7M_CONTROL
:
1397 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1401 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1403 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1407 return ERROR_INVALID_ARGUMENTS
;
1413 static int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
,
1414 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1416 /* get pointers to arch-specific information */
1417 armv7m_common_t
*armv7m
= target
->arch_info
;
1418 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1421 /* sanitize arguments */
1422 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1423 return ERROR_INVALID_ARGUMENTS
;
1425 /* cortex_m3 handles unaligned memory access */
1430 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1433 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1436 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1439 LOG_ERROR("BUG: we shouldn't get here");
1446 static int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
,
1447 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1449 /* get pointers to arch-specific information */
1450 armv7m_common_t
*armv7m
= target
->arch_info
;
1451 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1454 /* sanitize arguments */
1455 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1456 return ERROR_INVALID_ARGUMENTS
;
1461 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1464 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1467 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1470 LOG_ERROR("BUG: we shouldn't get here");
1477 static int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
,
1478 uint32_t count
, uint8_t *buffer
)
1480 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1483 static void cortex_m3_build_reg_cache(target_t
*target
)
1485 armv7m_build_reg_cache(target
);
1488 static int cortex_m3_init_target(struct command_context_s
*cmd_ctx
,
1489 struct target_s
*target
)
1491 cortex_m3_build_reg_cache(target
);
1495 static int cortex_m3_examine(struct target_s
*target
)
1498 uint32_t cpuid
, fpcr
, dwtcr
, ictr
;
1501 /* get pointers to arch-specific information */
1502 armv7m_common_t
*armv7m
= target
->arch_info
;
1503 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1504 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1506 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1509 if (!target_was_examined(target
))
1511 target_set_examined(target
);
1513 /* Read from Device Identification Registers */
1514 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1517 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1518 LOG_DEBUG("CORTEX-M3 processor detected");
1519 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1521 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1522 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1523 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1524 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1526 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1527 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32
"", i
, cortex_m3
->intsetenable
[i
]);
1531 target_read_u32(target
, FP_CTRL
, &fpcr
);
1532 cortex_m3
->auto_bp_type
= 1;
1533 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1534 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1535 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1536 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1537 cortex_m3
->fpb_enabled
= fpcr
& 1;
1538 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1540 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1541 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1543 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1546 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1547 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1548 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1549 cortex_m3
->dwt_comparator_list
= calloc(
1550 cortex_m3
->dwt_num_comp
,
1551 sizeof(cortex_m3_dwt_comparator_t
));
1552 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1554 cortex_m3
->dwt_comparator_list
[i
]
1555 .dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1557 if (cortex_m3
->dwt_num_comp
)
1558 LOG_DEBUG("DWT dwtcr 0x%" PRIx32
", comp %d, watch%s",
1559 dwtcr
, cortex_m3
->dwt_num_comp
,
1560 (dwtcr
& (0xf << 24)) ? " only" : "/trigger");
1566 static int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1570 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1571 *ctrl
= (uint8_t)dcrdr
;
1572 *value
= (uint8_t)(dcrdr
>> 8);
1574 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1576 /* write ack back to software dcc register
1577 * signify we have read data */
1578 if (dcrdr
& (1 << 0))
1581 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1587 static int cortex_m3_target_request_data(target_t
*target
,
1588 uint32_t size
, uint8_t *buffer
)
1590 armv7m_common_t
*armv7m
= target
->arch_info
;
1591 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1596 for (i
= 0; i
< (size
* 4); i
++)
1598 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1605 static int cortex_m3_handle_target_request(void *priv
)
1607 target_t
*target
= priv
;
1608 if (!target_was_examined(target
))
1610 armv7m_common_t
*armv7m
= target
->arch_info
;
1611 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1613 if (!target
->dbg_msg_enabled
)
1616 if (target
->state
== TARGET_RUNNING
)
1621 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1623 /* check if we have data */
1624 if (ctrl
& (1 << 0))
1628 /* we assume target is quick enough */
1630 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1631 request
|= (data
<< 8);
1632 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1633 request
|= (data
<< 16);
1634 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1635 request
|= (data
<< 24);
1636 target_request(target
, request
);
1643 static int cortex_m3_init_arch_info(target_t
*target
,
1644 cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1647 armv7m_common_t
*armv7m
;
1648 armv7m
= &cortex_m3
->armv7m
;
1650 armv7m_init_arch_info(target
, armv7m
);
1652 /* prepare JTAG information for the new target */
1653 cortex_m3
->jtag_info
.tap
= tap
;
1654 cortex_m3
->jtag_info
.scann_size
= 4;
1656 armv7m
->swjdp_info
.dp_select_value
= -1;
1657 armv7m
->swjdp_info
.ap_csw_value
= -1;
1658 armv7m
->swjdp_info
.ap_tar_value
= -1;
1659 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1660 armv7m
->swjdp_info
.memaccess_tck
= 8;
1661 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1663 /* initialize arch-specific breakpoint handling */
1665 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1666 cortex_m3
->arch_info
= NULL
;
1668 /* register arch-specific functions */
1669 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1671 armv7m
->post_debug_entry
= NULL
;
1673 armv7m
->pre_restore_context
= NULL
;
1674 armv7m
->post_restore_context
= NULL
;
1676 armv7m
->arch_info
= cortex_m3
;
1677 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1678 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1680 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1682 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1690 static int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1692 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1694 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1700 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1701 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1702 * that *only* Thumb2 disassembly matters. There are also some small
1703 * additions to Thumb2 that are specific to ARMv7-M.
1706 handle_cortex_m3_disassemble_command(struct command_context_s
*cmd_ctx
,
1707 char *cmd
, char **args
, int argc
)
1709 int retval
= ERROR_OK
;
1710 target_t
*target
= get_current_target(cmd_ctx
);
1712 unsigned long count
= 1;
1713 arm_instruction_t cur_instruction
;
1718 count
= strtoul(args
[1], NULL
, 0);
1723 address
= strtoul(args
[0], NULL
, 0);
1728 command_print(cmd_ctx
,
1729 "usage: cortex_m3 disassemble <address> [<count>]");
1734 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1735 if (retval
!= ERROR_OK
)
1737 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
1738 address
+= cur_instruction
.instruction_size
;
1744 static const struct {
1748 { "hard_err", VC_HARDERR
, },
1749 { "int_err", VC_INTERR
, },
1750 { "bus_err", VC_BUSERR
, },
1751 { "state_err", VC_STATERR
, },
1752 { "chk_err", VC_CHKERR
, },
1753 { "nocp_err", VC_NOCPERR
, },
1754 { "mm_err", VC_MMERR
, },
1755 { "reset", VC_CORERESET
, },
1759 handle_cortex_m3_vector_catch_command(struct command_context_s
*cmd_ctx
,
1760 char *cmd
, char **argv
, int argc
)
1762 target_t
*target
= get_current_target(cmd_ctx
);
1763 armv7m_common_t
*armv7m
= target
->arch_info
;
1764 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1768 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1774 if (strcmp(argv
[0], "all") == 0) {
1775 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1776 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1777 | VC_MMERR
| VC_CORERESET
;
1779 } else if (strcmp(argv
[0], "none") == 0) {
1783 while (argc
-- > 0) {
1784 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1785 if (strcmp(argv
[argc
], vec_ids
[i
].name
) != 0)
1787 catch |= vec_ids
[i
].mask
;
1790 if (i
== ARRAY_SIZE(vec_ids
)) {
1791 LOG_ERROR("No CM3 vector '%s'", argv
[argc
]);
1792 return ERROR_INVALID_ARGUMENTS
;
1799 /* write, but don't assume it stuck */
1800 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
1801 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1804 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
1805 command_print(cmd_ctx
, "%9s: %s", vec_ids
[i
].name
,
1806 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
1812 handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
,
1813 char *cmd
, char **args
, int argc
)
1815 target_t
*target
= get_current_target(cmd_ctx
);
1816 armv7m_common_t
*armv7m
= target
->arch_info
;
1817 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1819 if (target
->state
!= TARGET_HALTED
)
1821 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1827 if (!strcmp(args
[0], "on"))
1829 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1831 else if (!strcmp(args
[0], "off"))
1833 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1837 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1841 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1842 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
1847 static int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1850 command_t
*cortex_m3_cmd
;
1852 retval
= armv7m_register_commands(cmd_ctx
);
1854 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3",
1855 NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1857 register_command(cmd_ctx
, cortex_m3_cmd
, "disassemble",
1858 handle_cortex_m3_disassemble_command
, COMMAND_EXEC
,
1859 "disassemble Thumb2 instructions <address> [<count>]");
1860 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr",
1861 handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
,
1862 "mask cortex_m3 interrupts ['on'|'off']");
1863 register_command(cmd_ctx
, cortex_m3_cmd
, "vector_catch",
1864 handle_cortex_m3_vector_catch_command
, COMMAND_EXEC
,
1865 "catch hardware vectors ['all'|'none'|<list>]");
1870 target_type_t cortexm3_target
=
1872 .name
= "cortex_m3",
1874 .poll
= cortex_m3_poll
,
1875 .arch_state
= armv7m_arch_state
,
1877 .target_request_data
= cortex_m3_target_request_data
,
1879 .halt
= cortex_m3_halt
,
1880 .resume
= cortex_m3_resume
,
1881 .step
= cortex_m3_step
,
1883 .assert_reset
= cortex_m3_assert_reset
,
1884 .deassert_reset
= cortex_m3_deassert_reset
,
1885 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
1887 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
1889 .read_memory
= cortex_m3_read_memory
,
1890 .write_memory
= cortex_m3_write_memory
,
1891 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
1892 .checksum_memory
= armv7m_checksum_memory
,
1893 .blank_check_memory
= armv7m_blank_check_memory
,
1895 .run_algorithm
= armv7m_run_algorithm
,
1897 .add_breakpoint
= cortex_m3_add_breakpoint
,
1898 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
1899 .add_watchpoint
= cortex_m3_add_watchpoint
,
1900 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
1902 .register_commands
= cortex_m3_register_commands
,
1903 .target_create
= cortex_m3_target_create
,
1904 .init_target
= cortex_m3_init_target
,
1905 .has_mmu
= cortex_m3_has_mmu
,
1906 .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)