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"
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
< ARMV7NUMCOREREGS
; 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 /* Are we in an exception handler */
424 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
425 armv7m
->exception_number
= (xPSR
& 0x1FF);
427 else if (armv7m
->has_spec20
)
429 /* NOTE: CONTROL is bits 31:24 of SPEC20 register, holding
430 * a two-bit field. Unavailable before r2p0...
432 armv7m
->core_mode
= buf_get_u32(
433 armv7m
->core_cache
->reg_list
[ARMV7M_SPEC20
].value
, 24, 2);
434 armv7m
->exception_number
= 0;
437 if (armv7m
->exception_number
)
439 cortex_m3_examine_exception_reason(target
);
442 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
443 armv7m_mode_strings
[armv7m
->core_mode
],
444 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
445 target_state_name(target
));
447 if (armv7m
->post_debug_entry
)
448 armv7m
->post_debug_entry(target
);
453 int cortex_m3_poll(target_t
*target
)
456 enum target_state prev_target_state
= target
->state
;
458 /* get pointers to arch-specific information */
459 armv7m_common_t
*armv7m
= target
->arch_info
;
460 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
461 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
463 /* Read from Debug Halting Control and Status Register */
464 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
465 if (retval
!= ERROR_OK
)
467 target
->state
= TARGET_UNKNOWN
;
471 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
473 /* check if still in reset */
474 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
476 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
478 target
->state
= TARGET_RESET
;
483 if (target
->state
== TARGET_RESET
)
485 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
486 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
487 cortex_m3_endreset_event(target
);
488 target
->state
= TARGET_RUNNING
;
489 prev_target_state
= TARGET_RUNNING
;
492 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
494 target
->state
= TARGET_HALTED
;
496 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
498 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
501 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
503 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
506 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
509 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
513 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
514 * How best to model low power modes?
517 if (target
->state
== TARGET_UNKNOWN
)
519 /* check if processor is retiring instructions */
520 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
522 target
->state
= TARGET_RUNNING
;
530 int cortex_m3_halt(target_t
*target
)
532 LOG_DEBUG("target->state: %s",
533 target_state_name(target
));
535 if (target
->state
== TARGET_HALTED
)
537 LOG_DEBUG("target was already halted");
541 if (target
->state
== TARGET_UNKNOWN
)
543 LOG_WARNING("target was in unknown state when halt was requested");
546 if (target
->state
== TARGET_RESET
)
548 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
550 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
551 return ERROR_TARGET_FAILURE
;
555 /* we came here in a reset_halt or reset_init sequence
556 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
558 target
->debug_reason
= DBG_REASON_DBGRQ
;
564 /* Write to Debug Halting Control and Status Register */
565 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
567 target
->debug_reason
= DBG_REASON_DBGRQ
;
572 int cortex_m3_soft_reset_halt(struct target_s
*target
)
574 /* get pointers to arch-specific information */
575 armv7m_common_t
*armv7m
= target
->arch_info
;
576 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
577 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
578 uint32_t dcb_dhcsr
= 0;
579 int retval
, timeout
= 0;
581 /* Enter debug state on reset, cf. end_reset_event() */
582 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
584 /* Request a reset */
585 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
586 target
->state
= TARGET_RESET
;
588 /* registers are now invalid */
589 armv7m_invalidate_core_regs(target
);
591 while (timeout
< 100)
593 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
594 if (retval
== ERROR_OK
)
596 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
597 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
599 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
600 cortex_m3_poll(target
);
604 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
613 int cortex_m3_resume(struct target_s
*target
, int current
, uint32_t address
, int handle_breakpoints
, int debug_execution
)
615 /* get pointers to arch-specific information */
616 armv7m_common_t
*armv7m
= target
->arch_info
;
617 breakpoint_t
*breakpoint
= NULL
;
620 if (target
->state
!= TARGET_HALTED
)
622 LOG_WARNING("target not halted");
623 return ERROR_TARGET_NOT_HALTED
;
626 if (!debug_execution
)
628 target_free_all_working_areas(target
);
629 cortex_m3_enable_breakpoints(target
);
630 cortex_m3_enable_watchpoints(target
);
635 /* Disable interrupts */
636 /* We disable interrupts in the PRIMASK register instead
637 * of masking with C_MASKINTS,
638 * This is probably the same issue as Cortex-M3 Errata 377493:
639 * C_MASKINTS in parallel with disabled interrupts can cause
640 * local faults to not be taken. (FIXED in r1p0 and later.)
642 * NOTE: PRIMASK is bits 7:0 of SPEC20 register, holding a
643 * one bit field. Available this way for r2p0 and later...
645 if (armv7m
->has_spec20
) {
646 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_SPEC20
]
648 armv7m
->core_cache
->reg_list
[ARMV7M_SPEC20
].dirty
= 1;
649 armv7m
->core_cache
->reg_list
[ARMV7M_SPEC20
].valid
= 1;
652 /* Make sure we are in Thumb mode */
653 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
654 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32)
656 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
657 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
660 /* current = 1: continue on current pc, otherwise continue at <address> */
663 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
664 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
665 armv7m
->core_cache
->reg_list
[15].valid
= 1;
668 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
670 armv7m_restore_context(target
);
672 /* the front-end may request us not to handle breakpoints */
673 if (handle_breakpoints
)
675 /* Single step past breakpoint at current address */
676 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
678 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
680 breakpoint
->unique_id
);
681 cortex_m3_unset_breakpoint(target
, breakpoint
);
682 cortex_m3_single_step_core(target
);
683 cortex_m3_set_breakpoint(target
, breakpoint
);
688 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
690 target
->debug_reason
= DBG_REASON_NOTHALTED
;
692 /* registers are now invalid */
693 armv7m_invalidate_core_regs(target
);
694 if (!debug_execution
)
696 target
->state
= TARGET_RUNNING
;
697 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
698 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
702 target
->state
= TARGET_DEBUG_RUNNING
;
703 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
704 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
710 /* int irqstepcount = 0; */
711 int cortex_m3_step(struct target_s
*target
, int current
, uint32_t address
, int handle_breakpoints
)
713 /* get pointers to arch-specific information */
714 armv7m_common_t
*armv7m
= target
->arch_info
;
715 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
716 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
717 breakpoint_t
*breakpoint
= NULL
;
719 if (target
->state
!= TARGET_HALTED
)
721 LOG_WARNING("target not halted");
722 return ERROR_TARGET_NOT_HALTED
;
725 /* current = 1: continue on current pc, otherwise continue at <address> */
727 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
729 /* the front-end may request us not to handle breakpoints */
730 if (handle_breakpoints
)
731 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
732 cortex_m3_unset_breakpoint(target
, breakpoint
);
734 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
736 armv7m_restore_context(target
);
738 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
740 /* set step and clear halt */
741 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
742 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
744 /* registers are now invalid */
745 armv7m_invalidate_core_regs(target
);
748 cortex_m3_set_breakpoint(target
, breakpoint
);
750 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
752 cortex_m3_debug_entry(target
);
753 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
755 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
759 int cortex_m3_assert_reset(target_t
*target
)
761 armv7m_common_t
*armv7m
= target
->arch_info
;
762 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
763 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
766 LOG_DEBUG("target->state: %s",
767 target_state_name(target
));
769 enum reset_types jtag_reset_config
= jtag_get_reset_config();
770 if (!(jtag_reset_config
& RESET_HAS_SRST
))
772 LOG_ERROR("Can't assert SRST");
776 /* Enable debug requests */
777 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
778 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
779 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
781 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
783 if (!target
->reset_halt
)
785 /* Set/Clear C_MASKINTS in a separate operation */
786 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
787 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
789 /* clear any debug flags before resuming */
790 cortex_m3_clear_halt(target
);
792 /* clear C_HALT in dhcsr reg */
793 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
795 /* Enter debug state on reset, cf. end_reset_event() */
796 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
800 /* Enter debug state on reset, cf. end_reset_event() */
801 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
804 /* following hack is to handle luminary reset
805 * when srst is asserted the luminary device seesm to also clear the debug registers
806 * which does not match the armv7 debug TRM */
808 if (strcmp(target
->variant
, "lm3s") == 0)
810 /* get revision of lm3s target, only early silicon has this issue
811 * Fury Rev B, DustDevil Rev B, Tempest all ok */
815 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
817 switch ((did0
>> 16) & 0xff)
820 /* all Sandstorm suffer issue */
826 /* only Fury/DustDevil rev A suffer reset problems */
827 if (((did0
>> 8) & 0xff) == 0)
836 /* default to asserting srst */
837 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
839 jtag_add_reset(1, 1);
843 jtag_add_reset(0, 1);
848 /* this causes the luminary device to reset using the watchdog */
849 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
850 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
853 /* I do not know why this is necessary, but it fixes strange effects
854 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
856 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
860 target
->state
= TARGET_RESET
;
861 jtag_add_sleep(50000);
863 armv7m_invalidate_core_regs(target
);
865 if (target
->reset_halt
)
868 if ((retval
= target_halt(target
)) != ERROR_OK
)
875 int cortex_m3_deassert_reset(target_t
*target
)
877 LOG_DEBUG("target->state: %s",
878 target_state_name(target
));
880 /* deassert reset lines */
881 jtag_add_reset(0, 0);
886 void cortex_m3_enable_breakpoints(struct target_s
*target
)
888 breakpoint_t
*breakpoint
= target
->breakpoints
;
890 /* set any pending breakpoints */
893 if (breakpoint
->set
== 0)
894 cortex_m3_set_breakpoint(target
, breakpoint
);
895 breakpoint
= breakpoint
->next
;
899 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
905 /* get pointers to arch-specific information */
906 armv7m_common_t
*armv7m
= target
->arch_info
;
907 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
909 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
913 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
917 if (cortex_m3
->auto_bp_type
)
919 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
922 if (breakpoint
->type
== BKPT_HARD
)
924 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
926 if (fp_num
>= cortex_m3
->fp_num_code
)
928 LOG_DEBUG("ERROR Can not find free FP Comparator");
929 LOG_WARNING("ERROR Can not find free FP Comparator");
932 breakpoint
->set
= fp_num
+ 1;
933 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
934 comparator_list
[fp_num
].used
= 1;
935 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
936 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
937 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
938 if (!cortex_m3
->fpb_enabled
)
940 LOG_DEBUG("FPB wasn't enabled, do it now");
941 target_write_u32(target
, FP_CTRL
, 3);
944 else if (breakpoint
->type
== BKPT_SOFT
)
947 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
948 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
952 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
956 breakpoint
->set
= 0x11; /* Any nice value but 0 */
959 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
960 breakpoint
->unique_id
,
961 (int)(breakpoint
->type
),
969 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
972 /* get pointers to arch-specific information */
973 armv7m_common_t
*armv7m
= target
->arch_info
;
974 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
975 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
977 if (!breakpoint
->set
)
979 LOG_WARNING("breakpoint not set");
983 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
984 breakpoint
->unique_id
,
985 (int)(breakpoint
->type
),
990 if (breakpoint
->type
== BKPT_HARD
)
992 int fp_num
= breakpoint
->set
- 1;
993 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
995 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
998 comparator_list
[fp_num
].used
= 0;
999 comparator_list
[fp_num
].fpcr_value
= 0;
1000 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
1004 /* restore original instruction (kept in target endianness) */
1005 if (breakpoint
->length
== 4)
1007 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1014 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1020 breakpoint
->set
= 0;
1025 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1027 /* get pointers to arch-specific information */
1028 armv7m_common_t
*armv7m
= target
->arch_info
;
1029 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1031 if (cortex_m3
->auto_bp_type
)
1033 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1034 #ifdef ARMV7_GDB_HACKS
1035 if (breakpoint
->length
!= 2) {
1036 /* XXX Hack: Replace all breakpoints with length != 2 with
1037 * a hardware breakpoint. */
1038 breakpoint
->type
= BKPT_HARD
;
1039 breakpoint
->length
= 2;
1044 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1046 LOG_INFO("flash patch comparator requested outside code memory region");
1047 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1050 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1052 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1053 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1056 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1058 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1059 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1062 if ((breakpoint
->length
!= 2))
1064 LOG_INFO("only breakpoints of two bytes length supported");
1065 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1068 if (breakpoint
->type
== BKPT_HARD
)
1069 cortex_m3
->fp_code_available
--;
1070 cortex_m3_set_breakpoint(target
, breakpoint
);
1075 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1077 /* get pointers to arch-specific information */
1078 armv7m_common_t
*armv7m
= target
->arch_info
;
1079 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1081 if (target
->state
!= TARGET_HALTED
)
1083 LOG_WARNING("target not halted");
1084 return ERROR_TARGET_NOT_HALTED
;
1087 if (cortex_m3
->auto_bp_type
)
1089 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1092 if (breakpoint
->set
)
1094 cortex_m3_unset_breakpoint(target
, breakpoint
);
1097 if (breakpoint
->type
== BKPT_HARD
)
1098 cortex_m3
->fp_code_available
++;
1103 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1106 uint32_t mask
, temp
;
1108 /* get pointers to arch-specific information */
1109 armv7m_common_t
*armv7m
= target
->arch_info
;
1110 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1111 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1113 if (watchpoint
->set
)
1115 LOG_WARNING("watchpoint (%d) already set", watchpoint
->unique_id
);
1119 if (watchpoint
->mask
== 0xffffffffu
)
1121 while (comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1123 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1125 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1126 LOG_WARNING("ERROR Can not find free DWT Comparator");
1129 watchpoint
->set
= dwt_num
+ 1;
1131 temp
= watchpoint
->length
;
1137 comparator_list
[dwt_num
].used
= 1;
1138 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1139 comparator_list
[dwt_num
].mask
= mask
;
1140 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1141 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1142 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x4, comparator_list
[dwt_num
].mask
);
1143 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1144 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
);
1148 /* Move this test to add_watchpoint */
1149 LOG_WARNING("Cannot watch data values (id: %d)",
1150 watchpoint
->unique_id
);
1153 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1154 watchpoint
->unique_id
, watchpoint
->address
, watchpoint
->set
);
1159 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1161 /* get pointers to arch-specific information */
1162 armv7m_common_t
*armv7m
= target
->arch_info
;
1163 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1164 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1167 if (!watchpoint
->set
)
1169 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint
->unique_id
);
1173 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1174 watchpoint
->unique_id
, watchpoint
->address
,watchpoint
->set
);
1176 dwt_num
= watchpoint
->set
- 1;
1178 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1180 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1183 comparator_list
[dwt_num
].used
= 0;
1184 comparator_list
[dwt_num
].function
= 0;
1185 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1187 watchpoint
->set
= 0;
1192 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1194 /* get pointers to arch-specific information */
1195 armv7m_common_t
*armv7m
= target
->arch_info
;
1196 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1198 if (target
->state
!= TARGET_HALTED
)
1200 LOG_WARNING("target not halted");
1201 return ERROR_TARGET_NOT_HALTED
;
1204 if (cortex_m3
->dwt_comp_available
< 1)
1206 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1209 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1211 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1214 cortex_m3
->dwt_comp_available
--;
1215 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1220 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1222 /* get pointers to arch-specific information */
1223 armv7m_common_t
*armv7m
= target
->arch_info
;
1224 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1226 if (target
->state
!= TARGET_HALTED
)
1228 LOG_WARNING("target not halted");
1229 return ERROR_TARGET_NOT_HALTED
;
1232 if (watchpoint
->set
)
1234 cortex_m3_unset_watchpoint(target
, watchpoint
);
1237 cortex_m3
->dwt_comp_available
++;
1238 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1243 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1245 watchpoint_t
*watchpoint
= target
->watchpoints
;
1247 /* set any pending watchpoints */
1250 if (watchpoint
->set
== 0)
1251 cortex_m3_set_watchpoint(target
, watchpoint
);
1252 watchpoint
= watchpoint
->next
;
1256 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1259 /* get pointers to arch-specific information */
1260 armv7m_common_t
*armv7m
= target
->arch_info
;
1261 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1263 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1265 /* read a normal core register */
1266 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1268 if (retval
!= ERROR_OK
)
1270 LOG_ERROR("JTAG failure %i",retval
);
1271 return ERROR_JTAG_DEVICE_ERROR
;
1273 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1275 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1277 /* read other registers */
1278 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1283 *value
= buf_get_u32((uint8_t*)value
, 0, 8);
1287 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1291 *value
= buf_get_u32((uint8_t*)value
, 16, 8);
1295 *value
= buf_get_u32((uint8_t*)value
, 24, 8);
1299 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1303 return ERROR_INVALID_ARGUMENTS
;
1309 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1314 /* get pointers to arch-specific information */
1315 armv7m_common_t
*armv7m
= target
->arch_info
;
1316 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1318 #ifdef ARMV7_GDB_HACKS
1319 /* If the LR register is being modified, make sure it will put us
1320 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1321 * hack to deal with the fact that gdb will sometimes "forge"
1322 * return addresses, and doesn't set the LSB correctly (i.e., when
1323 * printing expressions containing function calls, it sets LR = 0.) */
1329 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1331 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1332 if (retval
!= ERROR_OK
)
1334 LOG_ERROR("JTAG failure %i", retval
);
1335 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1336 return ERROR_JTAG_DEVICE_ERROR
;
1338 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1340 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1342 /* write other registers */
1344 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1349 buf_set_u32((uint8_t*)®
, 0, 8, value
);
1353 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1357 buf_set_u32((uint8_t*)®
, 16, 8, value
);
1361 buf_set_u32((uint8_t*)®
, 24, 8, value
);
1365 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1367 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1371 return ERROR_INVALID_ARGUMENTS
;
1377 int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
1379 /* get pointers to arch-specific information */
1380 armv7m_common_t
*armv7m
= target
->arch_info
;
1381 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1384 /* sanitize arguments */
1385 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1386 return ERROR_INVALID_ARGUMENTS
;
1388 /* cortex_m3 handles unaligned memory access */
1393 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1396 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1399 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1402 LOG_ERROR("BUG: we shouldn't get here");
1409 int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
1411 /* get pointers to arch-specific information */
1412 armv7m_common_t
*armv7m
= target
->arch_info
;
1413 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1416 /* sanitize arguments */
1417 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1418 return ERROR_INVALID_ARGUMENTS
;
1423 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1426 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1429 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1432 LOG_ERROR("BUG: we shouldn't get here");
1439 int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
, uint32_t count
, uint8_t *buffer
)
1441 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1444 void cortex_m3_build_reg_cache(target_t
*target
)
1446 armv7m_build_reg_cache(target
);
1449 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1451 cortex_m3_build_reg_cache(target
);
1455 int cortex_m3_examine(struct target_s
*target
)
1458 uint32_t cpuid
, fpcr
, dwtcr
, ictr
;
1461 /* get pointers to arch-specific information */
1462 armv7m_common_t
*armv7m
= target
->arch_info
;
1463 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1464 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1466 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1469 if (!target_was_examined(target
))
1471 target_set_examined(target
);
1473 /* Read from Device Identification Registers */
1474 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1477 if (((cpuid
>> 4) & 0xc3f) == 0xc23) {
1478 LOG_DEBUG("CORTEX-M3 processor detected");
1479 if (((cpuid
>> 20) & 0xf) >= 2) {
1480 armv7m
->has_spec20
= true;
1481 LOG_DEBUG("r2p0 or later detected");
1484 LOG_WARNING("not a CORTEX-M3 processor?");
1485 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1487 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1488 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1489 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1490 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1492 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1493 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32
"", i
, cortex_m3
->intsetenable
[i
]);
1497 target_read_u32(target
, FP_CTRL
, &fpcr
);
1498 cortex_m3
->auto_bp_type
= 1;
1499 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1500 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1501 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1502 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1503 cortex_m3
->fpb_enabled
= fpcr
& 1;
1504 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1506 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1507 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1509 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1512 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1513 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1514 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1515 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1516 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1518 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1525 int cortex_m3_quit(void)
1531 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1535 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1536 *ctrl
= (uint8_t)dcrdr
;
1537 *value
= (uint8_t)(dcrdr
>> 8);
1539 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1541 /* write ack back to software dcc register
1542 * signify we have read data */
1543 if (dcrdr
& (1 << 0))
1546 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1552 int cortex_m3_target_request_data(target_t
*target
, uint32_t size
, uint8_t *buffer
)
1554 armv7m_common_t
*armv7m
= target
->arch_info
;
1555 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1560 for (i
= 0; i
< (size
* 4); i
++)
1562 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1569 int cortex_m3_handle_target_request(void *priv
)
1571 target_t
*target
= priv
;
1572 if (!target_was_examined(target
))
1574 armv7m_common_t
*armv7m
= target
->arch_info
;
1575 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1577 if (!target
->dbg_msg_enabled
)
1580 if (target
->state
== TARGET_RUNNING
)
1585 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1587 /* check if we have data */
1588 if (ctrl
& (1 << 0))
1592 /* we assume target is quick enough */
1594 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1595 request
|= (data
<< 8);
1596 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1597 request
|= (data
<< 16);
1598 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1599 request
|= (data
<< 24);
1600 target_request(target
, request
);
1607 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1610 armv7m_common_t
*armv7m
;
1611 armv7m
= &cortex_m3
->armv7m
;
1613 armv7m_init_arch_info(target
, armv7m
);
1615 /* prepare JTAG information for the new target */
1616 cortex_m3
->jtag_info
.tap
= tap
;
1617 cortex_m3
->jtag_info
.scann_size
= 4;
1619 armv7m
->swjdp_info
.dp_select_value
= -1;
1620 armv7m
->swjdp_info
.ap_csw_value
= -1;
1621 armv7m
->swjdp_info
.ap_tar_value
= -1;
1622 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1623 armv7m
->swjdp_info
.memaccess_tck
= 8;
1624 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1626 /* initialize arch-specific breakpoint handling */
1628 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1629 cortex_m3
->arch_info
= NULL
;
1631 /* register arch-specific functions */
1632 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1634 armv7m
->pre_debug_entry
= NULL
;
1635 armv7m
->post_debug_entry
= NULL
;
1637 armv7m
->pre_restore_context
= NULL
;
1638 armv7m
->post_restore_context
= NULL
;
1640 armv7m
->arch_info
= cortex_m3
;
1641 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1642 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1644 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1646 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1654 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1656 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1658 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1664 * REVISIT Thumb2 disassembly should work for all ARMv7 cores, as well
1665 * as at least ARM-1156T2. The interesting thing about Cortex-M is
1666 * that *only* Thumb2 disassembly matters. There are also some small
1667 * additions to Thumb2 that are specific to ARMv7-M.
1670 handle_cortex_m3_disassemble_command(struct command_context_s
*cmd_ctx
,
1671 char *cmd
, char **args
, int argc
)
1673 int retval
= ERROR_OK
;
1674 target_t
*target
= get_current_target(cmd_ctx
);
1676 unsigned long count
;
1677 arm_instruction_t cur_instruction
;
1680 command_print(cmd_ctx
,
1681 "usage: cortex_m3 disassemble <address> <count>");
1686 address
= strtoul(args
[0], NULL
, 0);
1689 count
= strtoul(args
[1], NULL
, 0);
1694 retval
= thumb2_opcode(target
, address
, &cur_instruction
);
1695 if (retval
!= ERROR_OK
)
1697 command_print(cmd_ctx
, "%s", cur_instruction
.text
);
1698 address
+= cur_instruction
.instruction_size
;
1704 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1707 command_t
*cortex_m3_cmd
;
1709 retval
= armv7m_register_commands(cmd_ctx
);
1711 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3",
1712 NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1714 register_command(cmd_ctx
, cortex_m3_cmd
, "disassemble",
1715 handle_cortex_m3_disassemble_command
, COMMAND_EXEC
,
1716 "disassemble Thumb2 instructions <address> <count>");
1717 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr",
1718 handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
,
1719 "mask cortex_m3 interrupts ['on'|'off']");
1724 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1726 target_t
*target
= get_current_target(cmd_ctx
);
1727 armv7m_common_t
*armv7m
= target
->arch_info
;
1728 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1730 if (target
->state
!= TARGET_HALTED
)
1732 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1738 if (!strcmp(args
[0], "on"))
1740 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1742 else if (!strcmp(args
[0], "off"))
1744 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1748 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1752 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1753 (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)