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 0337C *
29 ***************************************************************************/
34 #include "cortex_m3.h"
35 #include "target_request.h"
36 #include "target_type.h"
37 #include "arm_disassembler.h"
41 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
42 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
44 /* forward declarations */
45 void cortex_m3_enable_breakpoints(struct target_s
*target
);
46 void cortex_m3_enable_watchpoints(struct target_s
*target
);
47 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
);
48 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
49 int cortex_m3_quit(void);
50 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t *value
);
51 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t value
);
52 int cortex_m3_target_request_data(target_t
*target
, uint32_t size
, uint8_t *buffer
);
53 int cortex_m3_examine(struct target_s
*target
);
55 #ifdef ARMV7_GDB_HACKS
56 extern uint8_t armv7m_gdb_dummy_cpsr_value
[];
57 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
60 target_type_t cortexm3_target
=
64 .poll
= cortex_m3_poll
,
65 .arch_state
= armv7m_arch_state
,
67 .target_request_data
= cortex_m3_target_request_data
,
69 .halt
= cortex_m3_halt
,
70 .resume
= cortex_m3_resume
,
71 .step
= cortex_m3_step
,
73 .assert_reset
= cortex_m3_assert_reset
,
74 .deassert_reset
= cortex_m3_deassert_reset
,
75 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
77 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
79 .read_memory
= cortex_m3_read_memory
,
80 .write_memory
= cortex_m3_write_memory
,
81 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
82 .checksum_memory
= armv7m_checksum_memory
,
83 .blank_check_memory
= armv7m_blank_check_memory
,
85 .run_algorithm
= armv7m_run_algorithm
,
87 .add_breakpoint
= cortex_m3_add_breakpoint
,
88 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
89 .add_watchpoint
= cortex_m3_add_watchpoint
,
90 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
92 .register_commands
= cortex_m3_register_commands
,
93 .target_create
= cortex_m3_target_create
,
94 .init_target
= cortex_m3_init_target
,
95 .examine
= cortex_m3_examine
,
96 .quit
= cortex_m3_quit
99 int cortexm3_dap_read_coreregister_u32(swjdp_common_t
*swjdp
, uint32_t *value
, int regnum
)
104 /* because the DCB_DCRDR is used for the emulated dcc channel
105 * we gave to save/restore the DCB_DCRDR when used */
107 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
109 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
111 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
112 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
113 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
115 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
116 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
117 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
119 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
120 retval
= swjdp_transaction_endcheck(swjdp
);
124 int cortexm3_dap_write_coreregister_u32(swjdp_common_t
*swjdp
, uint32_t value
, int regnum
)
129 /* because the DCB_DCRDR is used for the emulated dcc channel
130 * we gave to save/restore the DCB_DCRDR when used */
132 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
134 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
136 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
137 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
138 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
140 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
141 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
142 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
144 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
145 retval
= swjdp_transaction_endcheck(swjdp
);
150 int cortex_m3_write_debug_halt_mask(target_t
*target
, uint32_t mask_on
, uint32_t mask_off
)
152 /* get pointers to arch-specific information */
153 armv7m_common_t
*armv7m
= target
->arch_info
;
154 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
155 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
157 /* mask off status bits */
158 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
159 /* create new register mask */
160 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
162 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
165 int cortex_m3_clear_halt(target_t
*target
)
167 /* get pointers to arch-specific information */
168 armv7m_common_t
*armv7m
= target
->arch_info
;
169 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
170 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
172 /* clear step if any */
173 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
175 /* Read Debug Fault Status Register */
176 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
177 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
178 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
179 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
184 int cortex_m3_single_step_core(target_t
*target
)
186 /* get pointers to arch-specific information */
187 armv7m_common_t
*armv7m
= target
->arch_info
;
188 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
189 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
192 /* backup dhcsr reg */
193 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
195 /* mask interrupts if not done already */
196 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
197 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
198 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
201 /* restore dhcsr reg */
202 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
203 cortex_m3_clear_halt(target
);
208 int cortex_m3_exec_opcode(target_t
*target
,uint32_t opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */)
210 /* get pointers to arch-specific information */
211 armv7m_common_t
*armv7m
= target
->arch_info
;
212 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
216 mem_ap_read_u32(swjdp
, 0x20000000, &savedram
);
217 mem_ap_write_u32(swjdp
, 0x20000000, opcode
);
218 cortexm3_dap_write_coreregister_u32(swjdp
, 0x20000000, 15);
219 cortex_m3_single_step_core(target
);
220 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
221 retvalue
= mem_ap_write_atomic_u32(swjdp
, 0x20000000, savedram
);
227 /* Enable interrupts */
228 int cortex_m3_cpsie(target_t
*target
, uint32_t IF
)
230 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
233 /* Disable interrupts */
234 int cortex_m3_cpsid(target_t
*target
, uint32_t IF
)
236 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
240 int cortex_m3_endreset_event(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
;
248 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
249 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
250 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
252 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
253 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
255 /* this regsiter is used for emulated dcc channel */
256 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
258 /* Enable debug requests */
259 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
260 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
261 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
263 /* clear any interrupt masking */
264 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
266 /* Enable trace and dwt */
267 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
268 /* Monitor bus faults */
269 mem_ap_write_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
272 target_write_u32(target
, FP_CTRL
, 3);
273 cortex_m3
->fpb_enabled
= 1;
275 /* Restore FPB registers */
276 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
278 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
281 /* Restore DWT registers */
282 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
284 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
285 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
286 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
288 swjdp_transaction_endcheck(swjdp
);
290 armv7m_invalidate_core_regs(target
);
292 /* make sure we have latest dhcsr flags */
293 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
298 int cortex_m3_examine_debug_reason(target_t
*target
)
300 /* get pointers to arch-specific information */
301 armv7m_common_t
*armv7m
= target
->arch_info
;
302 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
304 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
305 /* only check the debug reason if we don't know it already */
307 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
308 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
312 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
314 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
315 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
316 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
318 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
319 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
325 int cortex_m3_examine_exception_reason(target_t
*target
)
327 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
329 /* get pointers to arch-specific information */
330 armv7m_common_t
*armv7m
= target
->arch_info
;
331 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
333 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
334 switch (armv7m
->exception_number
)
338 case 3: /* Hard Fault */
339 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
340 if (except_sr
& 0x40000000)
342 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
345 case 4: /* Memory Management */
346 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
347 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
349 case 5: /* Bus Fault */
350 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
351 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
353 case 6: /* Usage Fault */
354 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
356 case 11: /* SVCall */
358 case 12: /* Debug Monitor */
359 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
361 case 14: /* PendSV */
363 case 15: /* SysTick */
369 swjdp_transaction_endcheck(swjdp
);
370 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
"", armv7m_exception_string(armv7m
->exception_number
), \
371 shcsr
, except_sr
, cfsr
, except_ar
);
375 int cortex_m3_debug_entry(target_t
*target
)
381 /* get pointers to arch-specific information */
382 armv7m_common_t
*armv7m
= target
->arch_info
;
383 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
384 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
387 if (armv7m
->pre_debug_entry
)
388 armv7m
->pre_debug_entry(target
);
390 cortex_m3_clear_halt(target
);
391 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
393 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
396 /* Examine target state and mode */
397 /* First load register acessible through core debug port*/
398 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
400 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
401 armv7m
->read_core_reg(target
, i
);
404 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
406 #ifdef ARMV7_GDB_HACKS
407 /* copy real xpsr reg for gdb, setting thumb bit */
408 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
409 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
410 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
411 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
414 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
417 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
418 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
421 /* Now we can load SP core registers */
422 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
424 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
425 armv7m
->read_core_reg(target
, i
);
428 /* Are we in an exception handler */
431 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
432 armv7m
->exception_number
= (xPSR
& 0x1FF);
436 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
437 armv7m
->exception_number
= 0;
440 if (armv7m
->exception_number
)
442 cortex_m3_examine_exception_reason(target
);
445 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
446 armv7m_mode_strings
[armv7m
->core_mode
],
447 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
448 target_state_name(target
));
450 if (armv7m
->post_debug_entry
)
451 armv7m
->post_debug_entry(target
);
456 int cortex_m3_poll(target_t
*target
)
459 enum target_state prev_target_state
= target
->state
;
461 /* get pointers to arch-specific information */
462 armv7m_common_t
*armv7m
= target
->arch_info
;
463 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
464 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
466 /* Read from Debug Halting Control and Status Register */
467 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
468 if (retval
!= ERROR_OK
)
470 target
->state
= TARGET_UNKNOWN
;
474 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
476 /* check if still in reset */
477 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
479 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
481 target
->state
= TARGET_RESET
;
486 if (target
->state
== TARGET_RESET
)
488 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
489 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
490 cortex_m3_endreset_event(target
);
491 target
->state
= TARGET_RUNNING
;
492 prev_target_state
= TARGET_RUNNING
;
495 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
497 target
->state
= TARGET_HALTED
;
499 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
501 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
504 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
506 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
509 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
512 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
516 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
517 * How best to model low power modes?
520 if (target
->state
== TARGET_UNKNOWN
)
522 /* check if processor is retiring instructions */
523 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
525 target
->state
= TARGET_RUNNING
;
533 int cortex_m3_halt(target_t
*target
)
535 LOG_DEBUG("target->state: %s",
536 target_state_name(target
));
538 if (target
->state
== TARGET_HALTED
)
540 LOG_DEBUG("target was already halted");
544 if (target
->state
== TARGET_UNKNOWN
)
546 LOG_WARNING("target was in unknown state when halt was requested");
549 if (target
->state
== TARGET_RESET
)
551 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
553 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
554 return ERROR_TARGET_FAILURE
;
558 /* we came here in a reset_halt or reset_init sequence
559 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
561 target
->debug_reason
= DBG_REASON_DBGRQ
;
567 /* Write to Debug Halting Control and Status Register */
568 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
570 target
->debug_reason
= DBG_REASON_DBGRQ
;
575 int cortex_m3_soft_reset_halt(struct target_s
*target
)
577 /* get pointers to arch-specific information */
578 armv7m_common_t
*armv7m
= target
->arch_info
;
579 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
580 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
581 uint32_t dcb_dhcsr
= 0;
582 int retval
, timeout
= 0;
584 /* Enter debug state on reset, cf. end_reset_event() */
585 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
587 /* Request a reset */
588 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
589 target
->state
= TARGET_RESET
;
591 /* registers are now invalid */
592 armv7m_invalidate_core_regs(target
);
594 while (timeout
< 100)
596 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
597 if (retval
== ERROR_OK
)
599 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
600 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
602 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
603 cortex_m3_poll(target
);
607 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
616 int cortex_m3_resume(struct target_s
*target
, int current
, uint32_t address
, int handle_breakpoints
, int debug_execution
)
618 /* get pointers to arch-specific information */
619 armv7m_common_t
*armv7m
= target
->arch_info
;
620 breakpoint_t
*breakpoint
= NULL
;
623 if (target
->state
!= TARGET_HALTED
)
625 LOG_WARNING("target not halted");
626 return ERROR_TARGET_NOT_HALTED
;
629 if (!debug_execution
)
631 target_free_all_working_areas(target
);
632 cortex_m3_enable_breakpoints(target
);
633 cortex_m3_enable_watchpoints(target
);
638 /* Disable interrupts */
639 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
640 * This is probably the same issue as Cortex-M3 Errata 377493:
641 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
642 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
643 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
644 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
646 /* Make sure we are in Thumb mode */
647 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
648 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
649 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
650 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
653 /* current = 1: continue on current pc, otherwise continue at <address> */
656 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
657 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
658 armv7m
->core_cache
->reg_list
[15].valid
= 1;
661 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
663 armv7m_restore_context(target
);
665 /* the front-end may request us not to handle breakpoints */
666 if (handle_breakpoints
)
668 /* Single step past breakpoint at current address */
669 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
671 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
673 breakpoint
->unique_id
);
674 cortex_m3_unset_breakpoint(target
, breakpoint
);
675 cortex_m3_single_step_core(target
);
676 cortex_m3_set_breakpoint(target
, breakpoint
);
681 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
683 target
->debug_reason
= DBG_REASON_NOTHALTED
;
685 /* registers are now invalid */
686 armv7m_invalidate_core_regs(target
);
687 if (!debug_execution
)
689 target
->state
= TARGET_RUNNING
;
690 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
691 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
695 target
->state
= TARGET_DEBUG_RUNNING
;
696 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
697 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
703 /* int irqstepcount = 0; */
704 int cortex_m3_step(struct target_s
*target
, int current
, uint32_t address
, int handle_breakpoints
)
706 /* get pointers to arch-specific information */
707 armv7m_common_t
*armv7m
= target
->arch_info
;
708 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
709 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
710 breakpoint_t
*breakpoint
= NULL
;
712 if (target
->state
!= TARGET_HALTED
)
714 LOG_WARNING("target not halted");
715 return ERROR_TARGET_NOT_HALTED
;
718 /* current = 1: continue on current pc, otherwise continue at <address> */
720 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
722 /* the front-end may request us not to handle breakpoints */
723 if (handle_breakpoints
)
724 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
725 cortex_m3_unset_breakpoint(target
, breakpoint
);
727 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
729 armv7m_restore_context(target
);
731 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
733 /* set step and clear halt */
734 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
735 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
737 /* registers are now invalid */
738 armv7m_invalidate_core_regs(target
);
741 cortex_m3_set_breakpoint(target
, breakpoint
);
743 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
745 cortex_m3_debug_entry(target
);
746 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
748 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
752 int cortex_m3_assert_reset(target_t
*target
)
754 armv7m_common_t
*armv7m
= target
->arch_info
;
755 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
756 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
759 LOG_DEBUG("target->state: %s",
760 target_state_name(target
));
762 enum reset_types jtag_reset_config
= jtag_get_reset_config();
763 if (!(jtag_reset_config
& RESET_HAS_SRST
))
765 LOG_ERROR("Can't assert SRST");
769 /* Enable debug requests */
770 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
771 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
772 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
774 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
776 if (!target
->reset_halt
)
778 /* Set/Clear C_MASKINTS in a separate operation */
779 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
780 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
782 /* clear any debug flags before resuming */
783 cortex_m3_clear_halt(target
);
785 /* clear C_HALT in dhcsr reg */
786 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
788 /* Enter debug state on reset, cf. end_reset_event() */
789 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
793 /* Enter debug state on reset, cf. end_reset_event() */
794 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
797 /* following hack is to handle luminary reset
798 * when srst is asserted the luminary device seesm to also clear the debug registers
799 * which does not match the armv7 debug TRM */
801 if (strcmp(target
->variant
, "lm3s") == 0)
803 /* get revision of lm3s target, only early silicon has this issue
804 * Fury Rev B, DustDevil Rev B, Tempest all ok */
808 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
810 switch ((did0
>> 16) & 0xff)
813 /* all Sandstorm suffer issue */
819 /* only Fury/DustDevil rev A suffer reset problems */
820 if (((did0
>> 8) & 0xff) == 0)
829 /* default to asserting srst */
830 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
832 jtag_add_reset(1, 1);
836 jtag_add_reset(0, 1);
841 /* this causes the luminary device to reset using the watchdog */
842 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
843 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
846 /* I do not know why this is necessary, but it fixes strange effects
847 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
849 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
853 target
->state
= TARGET_RESET
;
854 jtag_add_sleep(50000);
856 armv7m_invalidate_core_regs(target
);
858 if (target
->reset_halt
)
861 if ((retval
= target_halt(target
)) != ERROR_OK
)
868 int cortex_m3_deassert_reset(target_t
*target
)
870 LOG_DEBUG("target->state: %s",
871 target_state_name(target
));
873 /* deassert reset lines */
874 jtag_add_reset(0, 0);
879 void cortex_m3_enable_breakpoints(struct target_s
*target
)
881 breakpoint_t
*breakpoint
= target
->breakpoints
;
883 /* set any pending breakpoints */
886 if (breakpoint
->set
== 0)
887 cortex_m3_set_breakpoint(target
, breakpoint
);
888 breakpoint
= breakpoint
->next
;
892 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
898 /* get pointers to arch-specific information */
899 armv7m_common_t
*armv7m
= target
->arch_info
;
900 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
902 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
906 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
910 if (cortex_m3
->auto_bp_type
)
912 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
915 if (breakpoint
->type
== BKPT_HARD
)
917 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
919 if (fp_num
>= cortex_m3
->fp_num_code
)
921 LOG_DEBUG("ERROR Can not find free FP Comparator");
922 LOG_WARNING("ERROR Can not find free FP Comparator");
925 breakpoint
->set
= fp_num
+ 1;
926 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
927 comparator_list
[fp_num
].used
= 1;
928 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
929 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
930 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
931 if (!cortex_m3
->fpb_enabled
)
933 LOG_DEBUG("FPB wasn't enabled, do it now");
934 target_write_u32(target
, FP_CTRL
, 3);
937 else if (breakpoint
->type
== BKPT_SOFT
)
940 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
941 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
945 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
949 breakpoint
->set
= 0x11; /* Any nice value but 0 */
952 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
953 breakpoint
->unique_id
,
954 (int)(breakpoint
->type
),
962 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
965 /* get pointers to arch-specific information */
966 armv7m_common_t
*armv7m
= target
->arch_info
;
967 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
968 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
970 if (!breakpoint
->set
)
972 LOG_WARNING("breakpoint not set");
976 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
977 breakpoint
->unique_id
,
978 (int)(breakpoint
->type
),
983 if (breakpoint
->type
== BKPT_HARD
)
985 int fp_num
= breakpoint
->set
- 1;
986 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
988 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
991 comparator_list
[fp_num
].used
= 0;
992 comparator_list
[fp_num
].fpcr_value
= 0;
993 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
997 /* restore original instruction (kept in target endianness) */
998 if (breakpoint
->length
== 4)
1000 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1007 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1013 breakpoint
->set
= 0;
1018 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1020 /* get pointers to arch-specific information */
1021 armv7m_common_t
*armv7m
= target
->arch_info
;
1022 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1024 if (cortex_m3
->auto_bp_type
)
1026 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1027 #ifdef ARMV7_GDB_HACKS
1028 if (breakpoint
->length
!= 2) {
1029 /* XXX Hack: Replace all breakpoints with length != 2 with
1030 * a hardware breakpoint. */
1031 breakpoint
->type
= BKPT_HARD
;
1032 breakpoint
->length
= 2;
1037 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1039 LOG_INFO("flash patch comparator requested outside code memory region");
1040 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1043 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1045 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1046 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1049 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1051 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1052 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1055 if ((breakpoint
->length
!= 2))
1057 LOG_INFO("only breakpoints of two bytes length supported");
1058 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1061 if (breakpoint
->type
== BKPT_HARD
)
1062 cortex_m3
->fp_code_available
--;
1063 cortex_m3_set_breakpoint(target
, breakpoint
);
1068 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1070 /* get pointers to arch-specific information */
1071 armv7m_common_t
*armv7m
= target
->arch_info
;
1072 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1074 if (target
->state
!= TARGET_HALTED
)
1076 LOG_WARNING("target not halted");
1077 return ERROR_TARGET_NOT_HALTED
;
1080 if (cortex_m3
->auto_bp_type
)
1082 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1085 if (breakpoint
->set
)
1087 cortex_m3_unset_breakpoint(target
, breakpoint
);
1090 if (breakpoint
->type
== BKPT_HARD
)
1091 cortex_m3
->fp_code_available
++;
1096 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1099 uint32_t mask
, temp
;
1101 /* get pointers to arch-specific information */
1102 armv7m_common_t
*armv7m
= target
->arch_info
;
1103 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1104 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1106 if (watchpoint
->set
)
1108 LOG_WARNING("watchpoint (%d) already set", watchpoint
->unique_id
);
1112 if (watchpoint
->mask
== 0xffffffffu
)
1114 while (comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1116 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1118 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1119 LOG_WARNING("ERROR Can not find free DWT Comparator");
1122 watchpoint
->set
= dwt_num
+ 1;
1124 temp
= watchpoint
->length
;
1130 comparator_list
[dwt_num
].used
= 1;
1131 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1132 comparator_list
[dwt_num
].mask
= mask
;
1133 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1134 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1135 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x4, comparator_list
[dwt_num
].mask
);
1136 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1137 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
);
1141 /* Move this test to add_watchpoint */
1142 LOG_WARNING("Cannot watch data values (id: %d)",
1143 watchpoint
->unique_id
);
1146 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1147 watchpoint
->unique_id
, watchpoint
->address
, watchpoint
->set
);
1152 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1154 /* get pointers to arch-specific information */
1155 armv7m_common_t
*armv7m
= target
->arch_info
;
1156 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1157 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1160 if (!watchpoint
->set
)
1162 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint
->unique_id
);
1166 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1167 watchpoint
->unique_id
, watchpoint
->address
,watchpoint
->set
);
1169 dwt_num
= watchpoint
->set
- 1;
1171 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1173 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1176 comparator_list
[dwt_num
].used
= 0;
1177 comparator_list
[dwt_num
].function
= 0;
1178 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1180 watchpoint
->set
= 0;
1185 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1187 /* get pointers to arch-specific information */
1188 armv7m_common_t
*armv7m
= target
->arch_info
;
1189 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1191 if (target
->state
!= TARGET_HALTED
)
1193 LOG_WARNING("target not halted");
1194 return ERROR_TARGET_NOT_HALTED
;
1197 if (cortex_m3
->dwt_comp_available
< 1)
1199 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1202 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1204 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1207 cortex_m3
->dwt_comp_available
--;
1208 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1213 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1215 /* get pointers to arch-specific information */
1216 armv7m_common_t
*armv7m
= target
->arch_info
;
1217 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1219 if (target
->state
!= TARGET_HALTED
)
1221 LOG_WARNING("target not halted");
1222 return ERROR_TARGET_NOT_HALTED
;
1225 if (watchpoint
->set
)
1227 cortex_m3_unset_watchpoint(target
, watchpoint
);
1230 cortex_m3
->dwt_comp_available
++;
1231 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1236 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1238 watchpoint_t
*watchpoint
= target
->watchpoints
;
1240 /* set any pending watchpoints */
1243 if (watchpoint
->set
== 0)
1244 cortex_m3_set_watchpoint(target
, watchpoint
);
1245 watchpoint
= watchpoint
->next
;
1249 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1252 /* get pointers to arch-specific information */
1253 armv7m_common_t
*armv7m
= target
->arch_info
;
1254 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1256 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1258 /* read a normal core register */
1259 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1261 if (retval
!= ERROR_OK
)
1263 LOG_ERROR("JTAG failure %i",retval
);
1264 return ERROR_JTAG_DEVICE_ERROR
;
1266 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1268 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1270 /* read other registers */
1271 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1276 *value
= buf_get_u32((uint8_t*)value
, 0, 8);
1280 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1284 *value
= buf_get_u32((uint8_t*)value
, 16, 8);
1288 *value
= buf_get_u32((uint8_t*)value
, 24, 8);
1292 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1296 return ERROR_INVALID_ARGUMENTS
;
1302 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1307 /* get pointers to arch-specific information */
1308 armv7m_common_t
*armv7m
= target
->arch_info
;
1309 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1311 #ifdef ARMV7_GDB_HACKS
1312 /* If the LR register is being modified, make sure it will put us
1313 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1314 * hack to deal with the fact that gdb will sometimes "forge"
1315 * return addresses, and doesn't set the LSB correctly (i.e., when
1316 * printing expressions containing function calls, it sets LR = 0.) */
1322 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1324 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1325 if (retval
!= ERROR_OK
)
1327 LOG_ERROR("JTAG failure %i", retval
);
1328 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1329 return ERROR_JTAG_DEVICE_ERROR
;
1331 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1333 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1335 /* write other registers */
1337 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1342 buf_set_u32((uint8_t*)®
, 0, 8, value
);
1346 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1350 buf_set_u32((uint8_t*)®
, 16, 8, value
);
1354 buf_set_u32((uint8_t*)®
, 24, 8, value
);
1358 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1360 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1364 return ERROR_INVALID_ARGUMENTS
;
1370 int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
1372 /* get pointers to arch-specific information */
1373 armv7m_common_t
*armv7m
= target
->arch_info
;
1374 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1377 /* sanitize arguments */
1378 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1379 return ERROR_INVALID_ARGUMENTS
;
1381 /* cortex_m3 handles unaligned memory access */
1386 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1389 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1392 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1395 LOG_ERROR("BUG: we shouldn't get here");
1402 int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
1404 /* get pointers to arch-specific information */
1405 armv7m_common_t
*armv7m
= target
->arch_info
;
1406 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1409 /* sanitize arguments */
1410 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1411 return ERROR_INVALID_ARGUMENTS
;
1416 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1419 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1422 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1425 LOG_ERROR("BUG: we shouldn't get here");
1432 int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
, uint32_t count
, uint8_t *buffer
)
1434 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1437 void cortex_m3_build_reg_cache(target_t
*target
)
1439 armv7m_build_reg_cache(target
);
1442 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1444 cortex_m3_build_reg_cache(target
);
1448 int cortex_m3_examine(struct target_s
*target
)
1451 uint32_t cpuid
, fpcr
, dwtcr
, ictr
;
1454 /* get pointers to arch-specific information */
1455 armv7m_common_t
*armv7m
= target
->arch_info
;
1456 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1457 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1459 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1462 if (!target_was_examined(target
))
1464 target_set_examined(target
);
1466 /* Read from Device Identification Registers */
1467 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1470 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1471 LOG_DEBUG("CORTEX-M3 processor detected");
1472 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1474 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1475 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1476 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1477 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1479 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1480 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32
"", i
, cortex_m3
->intsetenable
[i
]);
1484 target_read_u32(target
, FP_CTRL
, &fpcr
);
1485 cortex_m3
->auto_bp_type
= 1;
1486 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1487 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1488 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1489 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1490 cortex_m3
->fpb_enabled
= fpcr
& 1;
1491 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1493 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1494 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1496 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1499 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1500 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1501 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1502 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1503 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1505 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1512 int cortex_m3_quit(void)
1518 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1522 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1523 *ctrl
= (uint8_t)dcrdr
;
1524 *value
= (uint8_t)(dcrdr
>> 8);
1526 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1528 /* write ack back to software dcc register
1529 * signify we have read data */
1530 if (dcrdr
& (1 << 0))
1533 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1539 int cortex_m3_target_request_data(target_t
*target
, uint32_t size
, uint8_t *buffer
)
1541 armv7m_common_t
*armv7m
= target
->arch_info
;
1542 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1547 for (i
= 0; i
< (size
* 4); i
++)
1549 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1556 int cortex_m3_handle_target_request(void *priv
)
1558 target_t
*target
= priv
;
1559 if (!target_was_examined(target
))
1561 armv7m_common_t
*armv7m
= target
->arch_info
;
1562 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1564 if (!target
->dbg_msg_enabled
)
1567 if (target
->state
== TARGET_RUNNING
)
1572 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1574 /* check if we have data */
1575 if (ctrl
& (1 << 0))
1579 /* we assume target is quick enough */
1581 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1582 request
|= (data
<< 8);
1583 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1584 request
|= (data
<< 16);
1585 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1586 request
|= (data
<< 24);
1587 target_request(target
, request
);
1594 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1597 armv7m_common_t
*armv7m
;
1598 armv7m
= &cortex_m3
->armv7m
;
1600 armv7m_init_arch_info(target
, armv7m
);
1602 /* prepare JTAG information for the new target */
1603 cortex_m3
->jtag_info
.tap
= tap
;
1604 cortex_m3
->jtag_info
.scann_size
= 4;
1606 armv7m
->swjdp_info
.dp_select_value
= -1;
1607 armv7m
->swjdp_info
.ap_csw_value
= -1;
1608 armv7m
->swjdp_info
.ap_tar_value
= -1;
1609 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1610 armv7m
->swjdp_info
.memaccess_tck
= 8;
1611 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1613 /* initialize arch-specific breakpoint handling */
1615 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1616 cortex_m3
->arch_info
= NULL
;
1618 /* register arch-specific functions */
1619 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1621 armv7m
->pre_debug_entry
= NULL
;
1622 armv7m
->post_debug_entry
= NULL
;
1624 armv7m
->pre_restore_context
= NULL
;
1625 armv7m
->post_restore_context
= NULL
;
1627 armv7m
->arch_info
= cortex_m3
;
1628 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1629 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1631 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1633 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1641 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1643 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1645 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1651 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1652 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1653 * that *only* Thumb2 disassembly matters. There are also some small
1654 * additions to Thumb2 that are specific to ARMv7-M.
1657 handle_cortex_m3_disassemble_command(struct command_context_s
*cmd_ctx
,
1658 char *cmd
, char **args
, int argc
)
1660 int retval
= ERROR_OK
;
1661 target_t
*target
= get_current_target(cmd_ctx
);
1663 unsigned long count
;
1664 arm_instruction_t cur_instruction
;
1667 command_print(cmd_ctx
,
1668 "usage: cortex_m3 disassemble <address> <count>");
1673 address
= strtoul(args
[0], NULL
, 0);
1676 count
= strtoul(args
[1], NULL
, 0);
1681 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1682 if (retval
!= ERROR_OK
)
1684 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
1685 address
+= cur_instruction
.instruction_size
;
1691 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1694 command_t
*cortex_m3_cmd
;
1696 retval
= armv7m_register_commands(cmd_ctx
);
1698 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3",
1699 NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1701 register_command(cmd_ctx
, cortex_m3_cmd
, "disassemble",
1702 handle_cortex_m3_disassemble_command
, COMMAND_EXEC
,
1703 "disassemble Thumb2 instructions <address> <count>");
1704 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr",
1705 handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
,
1706 "mask cortex_m3 interrupts ['on'|'off']");
1711 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1713 target_t
*target
= get_current_target(cmd_ctx
);
1714 armv7m_common_t
*armv7m
= target
->arch_info
;
1715 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1717 if (target
->state
!= TARGET_HALTED
)
1719 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1725 if (!strcmp(args
[0], "on"))
1727 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1729 else if (!strcmp(args
[0], "off"))
1731 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1735 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1739 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1740 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
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)