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
;
325 if (armv7m
->pre_debug_entry
)
326 armv7m
->pre_debug_entry(target
);
328 cortex_m3_clear_halt(target
);
329 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
331 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
334 /* Examine target state and mode */
335 /* First load register acessible through core debug port*/
336 int num_regs
= armv7m
->core_cache
->num_regs
;
338 for (i
= 0; i
< num_regs
; i
++)
340 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
341 armv7m
->read_core_reg(target
, i
);
344 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
346 #ifdef ARMV7_GDB_HACKS
347 /* copy real xpsr reg for gdb, setting thumb bit */
348 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
349 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
350 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
351 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
354 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
357 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
358 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
361 /* Are we in an exception handler */
364 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
365 armv7m
->exception_number
= (xPSR
& 0x1FF);
369 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
370 armv7m
->exception_number
= 0;
373 if (armv7m
->exception_number
)
375 cortex_m3_examine_exception_reason(target
);
378 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
379 armv7m_mode_strings
[armv7m
->core_mode
],
380 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
381 target_state_name(target
));
383 if (armv7m
->post_debug_entry
)
384 armv7m
->post_debug_entry(target
);
389 static int cortex_m3_poll(target_t
*target
)
392 enum target_state prev_target_state
= target
->state
;
394 /* get pointers to arch-specific information */
395 armv7m_common_t
*armv7m
= target
->arch_info
;
396 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
397 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
399 /* Read from Debug Halting Control and Status Register */
400 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
401 if (retval
!= ERROR_OK
)
403 target
->state
= TARGET_UNKNOWN
;
407 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
409 /* check if still in reset */
410 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
412 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
414 target
->state
= TARGET_RESET
;
419 if (target
->state
== TARGET_RESET
)
421 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
422 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
423 cortex_m3_endreset_event(target
);
424 target
->state
= TARGET_RUNNING
;
425 prev_target_state
= TARGET_RUNNING
;
428 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
430 target
->state
= TARGET_HALTED
;
432 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
434 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
437 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
439 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
442 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
445 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
449 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
450 * How best to model low power modes?
453 if (target
->state
== TARGET_UNKNOWN
)
455 /* check if processor is retiring instructions */
456 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
458 target
->state
= TARGET_RUNNING
;
466 static int cortex_m3_halt(target_t
*target
)
468 LOG_DEBUG("target->state: %s",
469 target_state_name(target
));
471 if (target
->state
== TARGET_HALTED
)
473 LOG_DEBUG("target was already halted");
477 if (target
->state
== TARGET_UNKNOWN
)
479 LOG_WARNING("target was in unknown state when halt was requested");
482 if (target
->state
== TARGET_RESET
)
484 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
486 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
487 return ERROR_TARGET_FAILURE
;
491 /* we came here in a reset_halt or reset_init sequence
492 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
494 target
->debug_reason
= DBG_REASON_DBGRQ
;
500 /* Write to Debug Halting Control and Status Register */
501 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
503 target
->debug_reason
= DBG_REASON_DBGRQ
;
508 static int cortex_m3_soft_reset_halt(struct target_s
*target
)
510 /* get pointers to arch-specific information */
511 armv7m_common_t
*armv7m
= target
->arch_info
;
512 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
513 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
514 uint32_t dcb_dhcsr
= 0;
515 int retval
, timeout
= 0;
517 /* Enter debug state on reset, cf. end_reset_event() */
518 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
520 /* Request a reset */
521 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
522 target
->state
= TARGET_RESET
;
524 /* registers are now invalid */
525 armv7m_invalidate_core_regs(target
);
527 while (timeout
< 100)
529 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
530 if (retval
== ERROR_OK
)
532 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
533 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
535 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
536 cortex_m3_poll(target
);
540 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
549 static void cortex_m3_enable_breakpoints(struct target_s
*target
)
551 breakpoint_t
*breakpoint
= target
->breakpoints
;
553 /* set any pending breakpoints */
556 if (breakpoint
->set
== 0)
557 cortex_m3_set_breakpoint(target
, breakpoint
);
558 breakpoint
= breakpoint
->next
;
562 static int cortex_m3_resume(struct target_s
*target
, int current
,
563 uint32_t address
, int handle_breakpoints
, int debug_execution
)
565 /* get pointers to arch-specific information */
566 armv7m_common_t
*armv7m
= target
->arch_info
;
567 breakpoint_t
*breakpoint
= NULL
;
570 if (target
->state
!= TARGET_HALTED
)
572 LOG_WARNING("target not halted");
573 return ERROR_TARGET_NOT_HALTED
;
576 if (!debug_execution
)
578 target_free_all_working_areas(target
);
579 cortex_m3_enable_breakpoints(target
);
580 cortex_m3_enable_watchpoints(target
);
585 /* Disable interrupts */
586 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
587 * This is probably the same issue as Cortex-M3 Errata 377493:
588 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
589 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
590 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
591 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
593 /* Make sure we are in Thumb mode */
594 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
595 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
596 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
597 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
600 /* current = 1: continue on current pc, otherwise continue at <address> */
603 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
604 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
605 armv7m
->core_cache
->reg_list
[15].valid
= 1;
608 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
610 armv7m_restore_context(target
);
612 /* the front-end may request us not to handle breakpoints */
613 if (handle_breakpoints
)
615 /* Single step past breakpoint at current address */
616 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
618 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
620 breakpoint
->unique_id
);
621 cortex_m3_unset_breakpoint(target
, breakpoint
);
622 cortex_m3_single_step_core(target
);
623 cortex_m3_set_breakpoint(target
, breakpoint
);
628 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
630 target
->debug_reason
= DBG_REASON_NOTHALTED
;
632 /* registers are now invalid */
633 armv7m_invalidate_core_regs(target
);
634 if (!debug_execution
)
636 target
->state
= TARGET_RUNNING
;
637 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
638 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
642 target
->state
= TARGET_DEBUG_RUNNING
;
643 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
644 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
650 /* int irqstepcount = 0; */
651 static int cortex_m3_step(struct target_s
*target
, int current
,
652 uint32_t address
, int handle_breakpoints
)
654 /* get pointers to arch-specific information */
655 armv7m_common_t
*armv7m
= target
->arch_info
;
656 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
657 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
658 breakpoint_t
*breakpoint
= NULL
;
660 if (target
->state
!= TARGET_HALTED
)
662 LOG_WARNING("target not halted");
663 return ERROR_TARGET_NOT_HALTED
;
666 /* current = 1: continue on current pc, otherwise continue at <address> */
668 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
670 /* the front-end may request us not to handle breakpoints */
671 if (handle_breakpoints
)
672 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
673 cortex_m3_unset_breakpoint(target
, breakpoint
);
675 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
677 armv7m_restore_context(target
);
679 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
681 /* set step and clear halt */
682 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
683 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
685 /* registers are now invalid */
686 armv7m_invalidate_core_regs(target
);
689 cortex_m3_set_breakpoint(target
, breakpoint
);
691 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
693 cortex_m3_debug_entry(target
);
694 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
696 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
700 static int cortex_m3_assert_reset(target_t
*target
)
702 armv7m_common_t
*armv7m
= target
->arch_info
;
703 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
704 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
707 LOG_DEBUG("target->state: %s",
708 target_state_name(target
));
710 enum reset_types jtag_reset_config
= jtag_get_reset_config();
713 * We can reset Cortex-M3 targets using just the NVIC without
714 * requiring SRST, getting a SoC reset (or a core-only reset)
715 * instead of a system reset.
717 if (!(jtag_reset_config
& RESET_HAS_SRST
))
720 /* Enable debug requests */
721 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
722 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
723 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
725 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
727 if (!target
->reset_halt
)
729 /* Set/Clear C_MASKINTS in a separate operation */
730 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
731 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
733 /* clear any debug flags before resuming */
734 cortex_m3_clear_halt(target
);
736 /* clear C_HALT in dhcsr reg */
737 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
739 /* Enter debug state on reset, cf. end_reset_event() */
740 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
744 /* Enter debug state on reset, cf. end_reset_event() */
745 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
749 * When nRST is asserted on most Stellaris devices, it clears some of
750 * the debug state. The ARMv7M and Cortex-M3 TRMs say that's wrong;
751 * and OpenOCD depends on those TRMs. So we won't use SRST on those
752 * chips. (Only power-on reset should affect debug state, beyond a
753 * few specified bits; not the chip's nRST input, wired to SRST.)
755 * REVISIT current errata specs don't seem to cover this issue.
756 * Do we have more details than this email?
757 * https://lists.berlios.de/pipermail
758 * /openocd-development/2008-August/003065.html
760 if (strcmp(target
->variant
, "lm3s") == 0)
762 /* Check for silicon revisions with the issue. */
765 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
767 switch ((did0
>> 16) & 0xff)
770 /* all Sandstorm suffer issue */
776 /* Fury and DustDevil rev A have
777 * this nRST problem. It should
778 * be fixed in rev B silicon.
780 if (((did0
>> 8) & 0xff) == 0)
784 /* Tempest should be fine. */
792 /* default to asserting srst */
793 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
795 jtag_add_reset(1, 1);
799 jtag_add_reset(0, 1);
804 /* Use a standard Cortex-M3 software reset mechanism.
805 * SYSRESETREQ will reset SoC peripherals outside the
806 * core, like watchdog timers, if the SoC wires it up
807 * correctly. Else VECRESET can reset just the core.
809 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
,
810 AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
811 LOG_DEBUG("Using Cortex-M3 SYSRESETREQ");
814 /* I do not know why this is necessary, but it
815 * fixes strange effects (step/resume cause NMI
816 * after reset) on LM3S6918 -- Michael Schwingen
819 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
823 target
->state
= TARGET_RESET
;
824 jtag_add_sleep(50000);
826 armv7m_invalidate_core_regs(target
);
828 if (target
->reset_halt
)
831 if ((retval
= target_halt(target
)) != ERROR_OK
)
838 static int cortex_m3_deassert_reset(target_t
*target
)
840 LOG_DEBUG("target->state: %s",
841 target_state_name(target
));
843 /* deassert reset lines */
844 jtag_add_reset(0, 0);
850 cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
856 /* get pointers to arch-specific information */
857 armv7m_common_t
*armv7m
= target
->arch_info
;
858 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
860 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
864 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
868 if (cortex_m3
->auto_bp_type
)
870 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
873 if (breakpoint
->type
== BKPT_HARD
)
875 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
877 if (fp_num
>= cortex_m3
->fp_num_code
)
879 LOG_DEBUG("ERROR Can not find free FP Comparator");
880 LOG_WARNING("ERROR Can not find free FP Comparator");
883 breakpoint
->set
= fp_num
+ 1;
884 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
885 comparator_list
[fp_num
].used
= 1;
886 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
887 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
888 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
889 if (!cortex_m3
->fpb_enabled
)
891 LOG_DEBUG("FPB wasn't enabled, do it now");
892 target_write_u32(target
, FP_CTRL
, 3);
895 else if (breakpoint
->type
== BKPT_SOFT
)
898 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
899 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
903 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
907 breakpoint
->set
= 0x11; /* Any nice value but 0 */
910 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
911 breakpoint
->unique_id
,
912 (int)(breakpoint
->type
),
921 cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
924 /* get pointers to arch-specific information */
925 armv7m_common_t
*armv7m
= target
->arch_info
;
926 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
927 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
929 if (!breakpoint
->set
)
931 LOG_WARNING("breakpoint not set");
935 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
936 breakpoint
->unique_id
,
937 (int)(breakpoint
->type
),
942 if (breakpoint
->type
== BKPT_HARD
)
944 int fp_num
= breakpoint
->set
- 1;
945 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
947 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
950 comparator_list
[fp_num
].used
= 0;
951 comparator_list
[fp_num
].fpcr_value
= 0;
952 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
956 /* restore original instruction (kept in target endianness) */
957 if (breakpoint
->length
== 4)
959 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
966 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
978 cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
980 /* get pointers to arch-specific information */
981 armv7m_common_t
*armv7m
= target
->arch_info
;
982 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
984 if (cortex_m3
->auto_bp_type
)
986 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
987 #ifdef ARMV7_GDB_HACKS
988 if (breakpoint
->length
!= 2) {
989 /* XXX Hack: Replace all breakpoints with length != 2 with
990 * a hardware breakpoint. */
991 breakpoint
->type
= BKPT_HARD
;
992 breakpoint
->length
= 2;
997 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
999 LOG_INFO("flash patch comparator requested outside code memory region");
1000 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1003 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1005 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1006 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1009 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1011 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1012 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1015 if ((breakpoint
->length
!= 2))
1017 LOG_INFO("only breakpoints of two bytes length supported");
1018 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1021 if (breakpoint
->type
== BKPT_HARD
)
1022 cortex_m3
->fp_code_available
--;
1023 cortex_m3_set_breakpoint(target
, breakpoint
);
1029 cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1031 /* get pointers to arch-specific information */
1032 armv7m_common_t
*armv7m
= target
->arch_info
;
1033 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1035 if (target
->state
!= TARGET_HALTED
)
1037 LOG_WARNING("target not halted");
1038 return ERROR_TARGET_NOT_HALTED
;
1041 if (cortex_m3
->auto_bp_type
)
1043 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1046 if (breakpoint
->set
)
1048 cortex_m3_unset_breakpoint(target
, breakpoint
);
1051 if (breakpoint
->type
== BKPT_HARD
)
1052 cortex_m3
->fp_code_available
++;
1058 cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1061 uint32_t mask
, temp
;
1063 /* get pointers to arch-specific information */
1064 armv7m_common_t
*armv7m
= target
->arch_info
;
1065 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1066 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1068 if (watchpoint
->set
)
1070 LOG_WARNING("watchpoint (%d) already set", watchpoint
->unique_id
);
1074 if (watchpoint
->mask
== 0xffffffffu
)
1076 while (comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1078 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1080 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1081 LOG_WARNING("ERROR Can not find free DWT Comparator");
1084 watchpoint
->set
= dwt_num
+ 1;
1086 temp
= watchpoint
->length
;
1092 comparator_list
[dwt_num
].used
= 1;
1093 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1094 comparator_list
[dwt_num
].mask
= mask
;
1095 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1096 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1097 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x4, comparator_list
[dwt_num
].mask
);
1098 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1099 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
);
1103 /* Move this test to add_watchpoint */
1104 LOG_WARNING("Cannot watch data values (id: %d)",
1105 watchpoint
->unique_id
);
1108 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1109 watchpoint
->unique_id
, watchpoint
->address
, watchpoint
->set
);
1115 cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1117 /* get pointers to arch-specific information */
1118 armv7m_common_t
*armv7m
= target
->arch_info
;
1119 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1120 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1123 if (!watchpoint
->set
)
1125 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint
->unique_id
);
1129 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1130 watchpoint
->unique_id
, watchpoint
->address
,watchpoint
->set
);
1132 dwt_num
= watchpoint
->set
- 1;
1134 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1136 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1139 comparator_list
[dwt_num
].used
= 0;
1140 comparator_list
[dwt_num
].function
= 0;
1141 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1143 watchpoint
->set
= 0;
1149 cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1151 /* get pointers to arch-specific information */
1152 armv7m_common_t
*armv7m
= target
->arch_info
;
1153 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1155 if (target
->state
!= TARGET_HALTED
)
1157 LOG_WARNING("target not halted");
1158 return ERROR_TARGET_NOT_HALTED
;
1161 if (cortex_m3
->dwt_comp_available
< 1)
1163 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1166 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1168 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1171 cortex_m3
->dwt_comp_available
--;
1172 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1178 cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1180 /* get pointers to arch-specific information */
1181 armv7m_common_t
*armv7m
= target
->arch_info
;
1182 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1184 if (target
->state
!= TARGET_HALTED
)
1186 LOG_WARNING("target not halted");
1187 return ERROR_TARGET_NOT_HALTED
;
1190 if (watchpoint
->set
)
1192 cortex_m3_unset_watchpoint(target
, watchpoint
);
1195 cortex_m3
->dwt_comp_available
++;
1196 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1201 static void cortex_m3_enable_watchpoints(struct target_s
*target
)
1203 watchpoint_t
*watchpoint
= target
->watchpoints
;
1205 /* set any pending watchpoints */
1208 if (watchpoint
->set
== 0)
1209 cortex_m3_set_watchpoint(target
, watchpoint
);
1210 watchpoint
= watchpoint
->next
;
1214 static int cortex_m3_load_core_reg_u32(struct target_s
*target
,
1215 enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1218 /* get pointers to arch-specific information */
1219 armv7m_common_t
*armv7m
= target
->arch_info
;
1220 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1222 /* NOTE: we "know" here that the register identifiers used
1223 * in the v7m header match the Cortex-M3 Debug Core Register
1224 * Selector values for R0..R15, xPSR, MSP, and PSP.
1228 /* read a normal core register */
1229 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1231 if (retval
!= ERROR_OK
)
1233 LOG_ERROR("JTAG failure %i",retval
);
1234 return ERROR_JTAG_DEVICE_ERROR
;
1236 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1239 case ARMV7M_PRIMASK
:
1240 case ARMV7M_BASEPRI
:
1241 case ARMV7M_FAULTMASK
:
1242 case ARMV7M_CONTROL
:
1243 /* Cortex-M3 packages these four registers as bitfields
1244 * in one Debug Core register. So say r0 and r2 docs;
1245 * it was removed from r1 docs, but still works.
1247 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1251 case ARMV7M_PRIMASK
:
1252 *value
= buf_get_u32((uint8_t*)value
, 0, 1);
1255 case ARMV7M_BASEPRI
:
1256 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1259 case ARMV7M_FAULTMASK
:
1260 *value
= buf_get_u32((uint8_t*)value
, 16, 1);
1263 case ARMV7M_CONTROL
:
1264 *value
= buf_get_u32((uint8_t*)value
, 24, 2);
1268 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1272 return ERROR_INVALID_ARGUMENTS
;
1278 static int cortex_m3_store_core_reg_u32(struct target_s
*target
,
1279 enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1284 /* get pointers to arch-specific information */
1285 armv7m_common_t
*armv7m
= target
->arch_info
;
1286 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1288 #ifdef ARMV7_GDB_HACKS
1289 /* If the LR register is being modified, make sure it will put us
1290 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1291 * hack to deal with the fact that gdb will sometimes "forge"
1292 * return addresses, and doesn't set the LSB correctly (i.e., when
1293 * printing expressions containing function calls, it sets LR = 0.)
1294 * Valid exception return codes have bit 0 set too.
1296 if (num
== ARMV7M_R14
)
1300 /* NOTE: we "know" here that the register identifiers used
1301 * in the v7m header match the Cortex-M3 Debug Core Register
1302 * Selector values for R0..R15, xPSR, MSP, and PSP.
1306 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1307 if (retval
!= ERROR_OK
)
1309 LOG_ERROR("JTAG failure %i", retval
);
1310 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1311 return ERROR_JTAG_DEVICE_ERROR
;
1313 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1316 case ARMV7M_PRIMASK
:
1317 case ARMV7M_BASEPRI
:
1318 case ARMV7M_FAULTMASK
:
1319 case ARMV7M_CONTROL
:
1320 /* Cortex-M3 packages these four registers as bitfields
1321 * in one Debug Core register. So say r0 and r2 docs;
1322 * it was removed from r1 docs, but still works.
1324 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1328 case ARMV7M_PRIMASK
:
1329 buf_set_u32((uint8_t*)®
, 0, 1, value
);
1332 case ARMV7M_BASEPRI
:
1333 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1336 case ARMV7M_FAULTMASK
:
1337 buf_set_u32((uint8_t*)®
, 16, 1, value
);
1340 case ARMV7M_CONTROL
:
1341 buf_set_u32((uint8_t*)®
, 24, 2, value
);
1345 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1347 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1351 return ERROR_INVALID_ARGUMENTS
;
1357 static int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
,
1358 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1360 /* get pointers to arch-specific information */
1361 armv7m_common_t
*armv7m
= target
->arch_info
;
1362 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1365 /* sanitize arguments */
1366 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1367 return ERROR_INVALID_ARGUMENTS
;
1369 /* cortex_m3 handles unaligned memory access */
1374 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1377 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1380 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1383 LOG_ERROR("BUG: we shouldn't get here");
1390 static int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
,
1391 uint32_t size
, uint32_t count
, uint8_t *buffer
)
1393 /* get pointers to arch-specific information */
1394 armv7m_common_t
*armv7m
= target
->arch_info
;
1395 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1398 /* sanitize arguments */
1399 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1400 return ERROR_INVALID_ARGUMENTS
;
1405 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1408 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1411 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1414 LOG_ERROR("BUG: we shouldn't get here");
1421 static int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
,
1422 uint32_t count
, uint8_t *buffer
)
1424 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1427 static void cortex_m3_build_reg_cache(target_t
*target
)
1429 armv7m_build_reg_cache(target
);
1432 static int cortex_m3_init_target(struct command_context_s
*cmd_ctx
,
1433 struct target_s
*target
)
1435 cortex_m3_build_reg_cache(target
);
1439 static int cortex_m3_examine(struct target_s
*target
)
1442 uint32_t cpuid
, fpcr
, dwtcr
, ictr
;
1445 /* get pointers to arch-specific information */
1446 armv7m_common_t
*armv7m
= target
->arch_info
;
1447 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1448 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1450 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1453 if (!target_was_examined(target
))
1455 target_set_examined(target
);
1457 /* Read from Device Identification Registers */
1458 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1461 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1462 LOG_DEBUG("CORTEX-M3 processor detected");
1463 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1465 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1466 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1467 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1468 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1470 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1471 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32
"", i
, cortex_m3
->intsetenable
[i
]);
1475 target_read_u32(target
, FP_CTRL
, &fpcr
);
1476 cortex_m3
->auto_bp_type
= 1;
1477 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1478 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1479 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1480 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1481 cortex_m3
->fpb_enabled
= fpcr
& 1;
1482 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1484 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1485 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1487 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1490 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1491 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1492 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1493 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1494 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1496 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1503 static int cortex_m3_quit(void)
1508 static int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1512 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1513 *ctrl
= (uint8_t)dcrdr
;
1514 *value
= (uint8_t)(dcrdr
>> 8);
1516 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1518 /* write ack back to software dcc register
1519 * signify we have read data */
1520 if (dcrdr
& (1 << 0))
1523 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1529 static int cortex_m3_target_request_data(target_t
*target
,
1530 uint32_t size
, uint8_t *buffer
)
1532 armv7m_common_t
*armv7m
= target
->arch_info
;
1533 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1538 for (i
= 0; i
< (size
* 4); i
++)
1540 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1547 static int cortex_m3_handle_target_request(void *priv
)
1549 target_t
*target
= priv
;
1550 if (!target_was_examined(target
))
1552 armv7m_common_t
*armv7m
= target
->arch_info
;
1553 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1555 if (!target
->dbg_msg_enabled
)
1558 if (target
->state
== TARGET_RUNNING
)
1563 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1565 /* check if we have data */
1566 if (ctrl
& (1 << 0))
1570 /* we assume target is quick enough */
1572 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1573 request
|= (data
<< 8);
1574 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1575 request
|= (data
<< 16);
1576 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1577 request
|= (data
<< 24);
1578 target_request(target
, request
);
1585 static int cortex_m3_init_arch_info(target_t
*target
,
1586 cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1589 armv7m_common_t
*armv7m
;
1590 armv7m
= &cortex_m3
->armv7m
;
1592 armv7m_init_arch_info(target
, armv7m
);
1594 /* prepare JTAG information for the new target */
1595 cortex_m3
->jtag_info
.tap
= tap
;
1596 cortex_m3
->jtag_info
.scann_size
= 4;
1598 armv7m
->swjdp_info
.dp_select_value
= -1;
1599 armv7m
->swjdp_info
.ap_csw_value
= -1;
1600 armv7m
->swjdp_info
.ap_tar_value
= -1;
1601 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1602 armv7m
->swjdp_info
.memaccess_tck
= 8;
1603 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1605 /* initialize arch-specific breakpoint handling */
1607 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1608 cortex_m3
->arch_info
= NULL
;
1610 /* register arch-specific functions */
1611 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1613 armv7m
->pre_debug_entry
= NULL
;
1614 armv7m
->post_debug_entry
= NULL
;
1616 armv7m
->pre_restore_context
= NULL
;
1617 armv7m
->post_restore_context
= NULL
;
1619 armv7m
->arch_info
= cortex_m3
;
1620 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1621 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1623 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1625 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1633 static int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1635 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1637 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1643 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1644 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1645 * that *only* Thumb2 disassembly matters. There are also some small
1646 * additions to Thumb2 that are specific to ARMv7-M.
1649 handle_cortex_m3_disassemble_command(struct command_context_s
*cmd_ctx
,
1650 char *cmd
, char **args
, int argc
)
1652 int retval
= ERROR_OK
;
1653 target_t
*target
= get_current_target(cmd_ctx
);
1655 unsigned long count
= 1;
1656 arm_instruction_t cur_instruction
;
1661 count
= strtoul(args
[1], NULL
, 0);
1666 address
= strtoul(args
[0], NULL
, 0);
1671 command_print(cmd_ctx
,
1672 "usage: cortex_m3 disassemble <address> [<count>]");
1677 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1678 if (retval
!= ERROR_OK
)
1680 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
1681 address
+= cur_instruction
.instruction_size
;
1687 static const struct {
1691 { "hard_err", VC_HARDERR
, },
1692 { "int_err", VC_INTERR
, },
1693 { "bus_err", VC_BUSERR
, },
1694 { "state_err", VC_STATERR
, },
1695 { "chk_err", VC_CHKERR
, },
1696 { "nocp_err", VC_NOCPERR
, },
1697 { "mm_err", VC_MMERR
, },
1698 { "reset", VC_CORERESET
, },
1702 handle_cortex_m3_vector_catch_command(struct command_context_s
*cmd_ctx
,
1703 char *cmd
, char **argv
, int argc
)
1705 target_t
*target
= get_current_target(cmd_ctx
);
1706 armv7m_common_t
*armv7m
= target
->arch_info
;
1707 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1711 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1717 if (strcmp(argv
[0], "all") == 0) {
1718 catch = VC_HARDERR
| VC_INTERR
| VC_BUSERR
1719 | VC_STATERR
| VC_CHKERR
| VC_NOCPERR
1720 | VC_MMERR
| VC_CORERESET
;
1722 } else if (strcmp(argv
[0], "none") == 0) {
1726 while (argc
-- > 0) {
1727 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++) {
1728 if (strcmp(argv
[argc
], vec_ids
[i
].name
) != 0)
1730 catch |= vec_ids
[i
].mask
;
1733 if (i
== ARRAY_SIZE(vec_ids
)) {
1734 LOG_ERROR("No CM3 vector '%s'", argv
[argc
]);
1735 return ERROR_INVALID_ARGUMENTS
;
1742 /* write, but don't assume it stuck */
1743 mem_ap_write_u32(swjdp
, DCB_DEMCR
, demcr
);
1744 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &demcr
);
1747 for (i
= 0; i
< ARRAY_SIZE(vec_ids
); i
++)
1748 command_print(cmd_ctx
, "%9s: %s", vec_ids
[i
].name
,
1749 (demcr
& vec_ids
[i
].mask
) ? "catch" : "ignore");
1755 handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
,
1756 char *cmd
, char **args
, int argc
)
1758 target_t
*target
= get_current_target(cmd_ctx
);
1759 armv7m_common_t
*armv7m
= target
->arch_info
;
1760 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1762 if (target
->state
!= TARGET_HALTED
)
1764 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1770 if (!strcmp(args
[0], "on"))
1772 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1774 else if (!strcmp(args
[0], "off"))
1776 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1780 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1784 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1785 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
1790 static int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1793 command_t
*cortex_m3_cmd
;
1795 retval
= armv7m_register_commands(cmd_ctx
);
1797 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3",
1798 NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1800 register_command(cmd_ctx
, cortex_m3_cmd
, "disassemble",
1801 handle_cortex_m3_disassemble_command
, COMMAND_EXEC
,
1802 "disassemble Thumb2 instructions <address> [<count>]");
1803 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr",
1804 handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
,
1805 "mask cortex_m3 interrupts ['on'|'off']");
1806 register_command(cmd_ctx
, cortex_m3_cmd
, "vector_catch",
1807 handle_cortex_m3_vector_catch_command
, COMMAND_EXEC
,
1808 "catch hardware vectors ['all'|'none'|<list>]");
1813 target_type_t cortexm3_target
=
1815 .name
= "cortex_m3",
1817 .poll
= cortex_m3_poll
,
1818 .arch_state
= armv7m_arch_state
,
1820 .target_request_data
= cortex_m3_target_request_data
,
1822 .halt
= cortex_m3_halt
,
1823 .resume
= cortex_m3_resume
,
1824 .step
= cortex_m3_step
,
1826 .assert_reset
= cortex_m3_assert_reset
,
1827 .deassert_reset
= cortex_m3_deassert_reset
,
1828 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
1830 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
1832 .read_memory
= cortex_m3_read_memory
,
1833 .write_memory
= cortex_m3_write_memory
,
1834 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
1835 .checksum_memory
= armv7m_checksum_memory
,
1836 .blank_check_memory
= armv7m_blank_check_memory
,
1838 .run_algorithm
= armv7m_run_algorithm
,
1840 .add_breakpoint
= cortex_m3_add_breakpoint
,
1841 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
1842 .add_watchpoint
= cortex_m3_add_watchpoint
,
1843 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
1845 .register_commands
= cortex_m3_register_commands
,
1846 .target_create
= cortex_m3_target_create
,
1847 .init_target
= cortex_m3_init_target
,
1848 .examine
= cortex_m3_examine
,
1849 .quit
= cortex_m3_quit
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)