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"
39 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
40 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
42 /* forward declarations */
43 void cortex_m3_enable_breakpoints(struct target_s
*target
);
44 void cortex_m3_enable_watchpoints(struct target_s
*target
);
45 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
);
46 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
47 int cortex_m3_quit(void);
48 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
49 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
50 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
51 int cortex_m3_examine(struct target_s
*target
);
53 #ifdef ARMV7_GDB_HACKS
54 extern u8 armv7m_gdb_dummy_cpsr_value
[];
55 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
58 target_type_t cortexm3_target
=
62 .poll
= cortex_m3_poll
,
63 .arch_state
= armv7m_arch_state
,
65 .target_request_data
= cortex_m3_target_request_data
,
67 .halt
= cortex_m3_halt
,
68 .resume
= cortex_m3_resume
,
69 .step
= cortex_m3_step
,
71 .assert_reset
= cortex_m3_assert_reset
,
72 .deassert_reset
= cortex_m3_deassert_reset
,
73 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
75 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
77 .read_memory
= cortex_m3_read_memory
,
78 .write_memory
= cortex_m3_write_memory
,
79 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
80 .checksum_memory
= armv7m_checksum_memory
,
81 .blank_check_memory
= armv7m_blank_check_memory
,
83 .run_algorithm
= armv7m_run_algorithm
,
85 .add_breakpoint
= cortex_m3_add_breakpoint
,
86 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
87 .add_watchpoint
= cortex_m3_add_watchpoint
,
88 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
90 .register_commands
= cortex_m3_register_commands
,
91 .target_create
= cortex_m3_target_create
,
92 .init_target
= cortex_m3_init_target
,
93 .examine
= cortex_m3_examine
,
94 .quit
= cortex_m3_quit
97 int cortexm3_dap_read_coreregister_u32(swjdp_common_t
*swjdp
, u32
*value
, int regnum
)
102 /* because the DCB_DCRDR is used for the emulated dcc channel
103 * we gave to save/restore the DCB_DCRDR when used */
105 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
107 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
109 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
110 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
111 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
113 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
114 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
115 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
117 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
118 retval
= swjdp_transaction_endcheck(swjdp
);
122 int cortexm3_dap_write_coreregister_u32(swjdp_common_t
*swjdp
, u32 value
, int regnum
)
127 /* because the DCB_DCRDR is used for the emulated dcc channel
128 * we gave to save/restore the DCB_DCRDR when used */
130 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
132 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
134 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
135 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
136 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
138 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR ); */
139 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
140 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
142 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
143 retval
= swjdp_transaction_endcheck(swjdp
);
148 int cortex_m3_write_debug_halt_mask(target_t
*target
, u32 mask_on
, u32 mask_off
)
150 /* get pointers to arch-specific information */
151 armv7m_common_t
*armv7m
= target
->arch_info
;
152 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
153 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
155 /* mask off status bits */
156 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
157 /* create new register mask */
158 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
160 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
163 int cortex_m3_clear_halt(target_t
*target
)
165 /* get pointers to arch-specific information */
166 armv7m_common_t
*armv7m
= target
->arch_info
;
167 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
168 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
170 /* clear step if any */
171 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
173 /* Read Debug Fault Status Register */
174 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
175 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
176 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
177 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
182 int cortex_m3_single_step_core(target_t
*target
)
184 /* get pointers to arch-specific information */
185 armv7m_common_t
*armv7m
= target
->arch_info
;
186 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
187 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
190 /* backup dhcsr reg */
191 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
193 /* mask interrupts if not done already */
194 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
195 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
196 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
199 /* restore dhcsr reg */
200 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
201 cortex_m3_clear_halt(target
);
206 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
208 /* get pointers to arch-specific information */
209 armv7m_common_t
*armv7m
= target
->arch_info
;
210 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
214 mem_ap_read_u32(swjdp
, 0x20000000, &savedram
);
215 mem_ap_write_u32(swjdp
, 0x20000000, opcode
);
216 cortexm3_dap_write_coreregister_u32(swjdp
, 0x20000000, 15);
217 cortex_m3_single_step_core(target
);
218 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
219 retvalue
= mem_ap_write_atomic_u32(swjdp
, 0x20000000, savedram
);
225 /* Enable interrupts */
226 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
228 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
231 /* Disable interrupts */
232 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
234 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
238 int cortex_m3_endreset_event(target_t
*target
)
243 /* get pointers to arch-specific information */
244 armv7m_common_t
*armv7m
= target
->arch_info
;
245 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
246 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
247 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
248 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
250 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
251 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
253 /* this regsiter is used for emulated dcc channel */
254 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
256 /* Enable debug requests */
257 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
258 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
259 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
261 /* clear any interrupt masking */
262 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
264 /* Enable trace and dwt */
265 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
266 /* Monitor bus faults */
267 mem_ap_write_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
270 target_write_u32(target
, FP_CTRL
, 3);
271 cortex_m3
->fpb_enabled
= 1;
273 /* Restore FPB registers */
274 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
276 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
279 /* Restore DWT registers */
280 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
282 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
283 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
284 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
286 swjdp_transaction_endcheck(swjdp
);
288 armv7m_invalidate_core_regs(target
);
290 /* make sure we have latest dhcsr flags */
291 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
296 int cortex_m3_examine_debug_reason(target_t
*target
)
298 /* get pointers to arch-specific information */
299 armv7m_common_t
*armv7m
= target
->arch_info
;
300 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
302 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
303 /* only check the debug reason if we don't know it already */
305 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
306 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
310 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
312 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
313 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
314 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
316 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
317 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
323 int cortex_m3_examine_exception_reason(target_t
*target
)
325 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
327 /* get pointers to arch-specific information */
328 armv7m_common_t
*armv7m
= target
->arch_info
;
329 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
331 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
332 switch (armv7m
->exception_number
)
336 case 3: /* Hard Fault */
337 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
338 if (except_sr
& 0x40000000)
340 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
343 case 4: /* Memory Management */
344 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
345 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
347 case 5: /* Bus Fault */
348 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
349 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
351 case 6: /* Usage Fault */
352 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
354 case 11: /* SVCall */
356 case 12: /* Debug Monitor */
357 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
359 case 14: /* PendSV */
361 case 15: /* SysTick */
367 swjdp_transaction_endcheck(swjdp
);
368 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
369 shcsr
, except_sr
, cfsr
, except_ar
);
373 int cortex_m3_debug_entry(target_t
*target
)
379 /* get pointers to arch-specific information */
380 armv7m_common_t
*armv7m
= target
->arch_info
;
381 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
382 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
385 if (armv7m
->pre_debug_entry
)
386 armv7m
->pre_debug_entry(target
);
388 cortex_m3_clear_halt(target
);
389 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
391 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
394 /* Examine target state and mode */
395 /* First load register acessible through core debug port*/
396 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
398 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
399 armv7m
->read_core_reg(target
, i
);
402 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
404 #ifdef ARMV7_GDB_HACKS
405 /* copy real xpsr reg for gdb, setting thumb bit */
406 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
407 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
408 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
409 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
412 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
415 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
416 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
419 /* Now we can load SP core registers */
420 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
422 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
423 armv7m
->read_core_reg(target
, i
);
426 /* Are we in an exception handler */
429 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
430 armv7m
->exception_number
= (xPSR
& 0x1FF);
434 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
435 armv7m
->exception_number
= 0;
438 if (armv7m
->exception_number
)
440 cortex_m3_examine_exception_reason(target
);
443 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
444 armv7m_mode_strings
[armv7m
->core_mode
],
445 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
446 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
448 if (armv7m
->post_debug_entry
)
449 armv7m
->post_debug_entry(target
);
454 int cortex_m3_poll(target_t
*target
)
457 enum target_state prev_target_state
= target
->state
;
459 /* get pointers to arch-specific information */
460 armv7m_common_t
*armv7m
= target
->arch_info
;
461 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
462 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
464 /* Read from Debug Halting Control and Status Register */
465 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
466 if (retval
!= ERROR_OK
)
468 target
->state
= TARGET_UNKNOWN
;
472 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
474 /* check if still in reset */
475 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
477 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
479 target
->state
= TARGET_RESET
;
484 if (target
->state
== TARGET_RESET
)
486 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
487 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
488 cortex_m3_endreset_event(target
);
489 target
->state
= TARGET_RUNNING
;
490 prev_target_state
= TARGET_RUNNING
;
493 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
495 target
->state
= TARGET_HALTED
;
497 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
499 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
502 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
504 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
507 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
510 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
515 if (cortex_m3->dcb_dhcsr & S_SLEEP)
516 target->state = TARGET_SLEEP;
520 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
521 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
522 LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_dfsr
, Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
528 int cortex_m3_halt(target_t
*target
)
530 LOG_DEBUG("target->state: %s",
531 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
533 if (target
->state
== TARGET_HALTED
)
535 LOG_DEBUG("target was already halted");
539 if (target
->state
== TARGET_UNKNOWN
)
541 LOG_WARNING("target was in unknown state when halt was requested");
544 if (target
->state
== TARGET_RESET
)
546 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
548 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
549 return ERROR_TARGET_FAILURE
;
553 /* we came here in a reset_halt or reset_init sequence
554 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
556 target
->debug_reason
= DBG_REASON_DBGRQ
;
562 /* Write to Debug Halting Control and Status Register */
563 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
565 target
->debug_reason
= DBG_REASON_DBGRQ
;
570 int cortex_m3_soft_reset_halt(struct target_s
*target
)
572 /* get pointers to arch-specific information */
573 armv7m_common_t
*armv7m
= target
->arch_info
;
574 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
575 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
577 int retval
, timeout
= 0;
579 /* Enter debug state on reset, cf. end_reset_event() */
580 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
582 /* Request a reset */
583 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
584 target
->state
= TARGET_RESET
;
586 /* registers are now invalid */
587 armv7m_invalidate_core_regs(target
);
589 while (timeout
< 100)
591 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
592 if (retval
== ERROR_OK
)
594 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
595 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
597 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
598 cortex_m3_poll(target
);
602 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
611 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
613 /* get pointers to arch-specific information */
614 armv7m_common_t
*armv7m
= target
->arch_info
;
615 breakpoint_t
*breakpoint
= NULL
;
618 if (target
->state
!= TARGET_HALTED
)
620 LOG_WARNING("target not halted");
621 return ERROR_TARGET_NOT_HALTED
;
624 if (!debug_execution
)
626 target_free_all_working_areas(target
);
627 cortex_m3_enable_breakpoints(target
);
628 cortex_m3_enable_watchpoints(target
);
633 /* Disable interrupts */
634 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
635 * This is probably the same issue as Cortex-M3 Errata 377493:
636 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
637 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
638 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
639 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
641 /* Make sure we are in Thumb mode */
642 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
643 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
644 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
645 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
648 /* current = 1: continue on current pc, otherwise continue at <address> */
651 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
652 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
653 armv7m
->core_cache
->reg_list
[15].valid
= 1;
656 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
658 armv7m_restore_context(target
);
660 /* the front-end may request us not to handle breakpoints */
661 if (handle_breakpoints
)
663 /* Single step past breakpoint at current address */
664 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
666 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
667 cortex_m3_unset_breakpoint(target
, breakpoint
);
668 cortex_m3_single_step_core(target
);
669 cortex_m3_set_breakpoint(target
, breakpoint
);
674 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
676 target
->debug_reason
= DBG_REASON_NOTHALTED
;
678 /* registers are now invalid */
679 armv7m_invalidate_core_regs(target
);
680 if (!debug_execution
)
682 target
->state
= TARGET_RUNNING
;
683 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
684 LOG_DEBUG("target resumed at 0x%x", resume_pc
);
688 target
->state
= TARGET_DEBUG_RUNNING
;
689 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
690 LOG_DEBUG("target debug resumed at 0x%x", resume_pc
);
696 /* int irqstepcount=0; */
697 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
699 /* get pointers to arch-specific information */
700 armv7m_common_t
*armv7m
= target
->arch_info
;
701 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
702 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
703 breakpoint_t
*breakpoint
= NULL
;
705 if (target
->state
!= TARGET_HALTED
)
707 LOG_WARNING("target not halted");
708 return ERROR_TARGET_NOT_HALTED
;
711 /* current = 1: continue on current pc, otherwise continue at <address> */
713 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
715 /* the front-end may request us not to handle breakpoints */
716 if (handle_breakpoints
)
717 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
718 cortex_m3_unset_breakpoint(target
, breakpoint
);
720 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
722 armv7m_restore_context(target
);
724 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
726 /* set step and clear halt */
727 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
728 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
730 /* registers are now invalid */
731 armv7m_invalidate_core_regs(target
);
734 cortex_m3_set_breakpoint(target
, breakpoint
);
736 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
738 cortex_m3_debug_entry(target
);
739 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
741 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
745 int cortex_m3_assert_reset(target_t
*target
)
747 armv7m_common_t
*armv7m
= target
->arch_info
;
748 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
749 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
752 LOG_DEBUG("target->state: %s",
753 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
755 if (!(jtag_reset_config
& RESET_HAS_SRST
))
757 LOG_ERROR("Can't assert SRST");
761 /* Enable debug requests */
762 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
763 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
764 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
766 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0 );
768 if (!target
->reset_halt
)
770 /* Set/Clear C_MASKINTS in a separate operation */
771 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
772 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
774 /* clear any debug flags before resuming */
775 cortex_m3_clear_halt(target
);
777 /* clear C_HALT in dhcsr reg */
778 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
780 /* Enter debug state on reset, cf. end_reset_event() */
781 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
785 /* Enter debug state on reset, cf. end_reset_event() */
786 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
789 /* following hack is to handle luminary reset
790 * when srst is asserted the luminary device seesm to also clear the debug registers
791 * which does not match the armv7 debug TRM */
793 if (strcmp(target
->variant
, "lm3s") == 0)
795 /* get revision of lm3s target, only early silicon has this issue
796 * Fury Rev B, DustDevil Rev B, Tempest all ok */
800 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
802 switch ((did0
>> 16) & 0xff)
805 /* all Sandstorm suffer issue */
811 /* only Fury/DustDevil rev A suffer reset problems */
812 if (((did0
>> 8) & 0xff) == 0)
821 /* default to asserting srst */
822 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
824 jtag_add_reset(1, 1);
828 jtag_add_reset(0, 1);
833 /* this causes the luminary device to reset using the watchdog */
834 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
835 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
838 /* I do not know why this is necessary, but it fixes strange effects
839 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
841 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
845 target
->state
= TARGET_RESET
;
846 jtag_add_sleep(50000);
848 armv7m_invalidate_core_regs(target
);
850 if (target
->reset_halt
)
853 if ((retval
= target_halt(target
))!=ERROR_OK
)
860 int cortex_m3_deassert_reset(target_t
*target
)
862 LOG_DEBUG("target->state: %s",
863 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
865 /* deassert reset lines */
866 jtag_add_reset(0, 0);
871 void cortex_m3_enable_breakpoints(struct target_s
*target
)
873 breakpoint_t
*breakpoint
= target
->breakpoints
;
875 /* set any pending breakpoints */
878 if (breakpoint
->set
== 0)
879 cortex_m3_set_breakpoint(target
, breakpoint
);
880 breakpoint
= breakpoint
->next
;
884 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
890 /* get pointers to arch-specific information */
891 armv7m_common_t
*armv7m
= target
->arch_info
;
892 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
894 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
898 LOG_WARNING("breakpoint already set");
902 if (cortex_m3
->auto_bp_type
)
904 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
907 if (breakpoint
->type
== BKPT_HARD
)
909 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
911 if (fp_num
>= cortex_m3
->fp_num_code
)
913 LOG_DEBUG("ERROR Can not find free FP Comparator");
914 LOG_WARNING("ERROR Can not find free FP Comparator");
917 breakpoint
->set
= fp_num
+ 1;
918 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
919 comparator_list
[fp_num
].used
= 1;
920 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
921 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
922 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
923 if (!cortex_m3
->fpb_enabled
)
925 LOG_DEBUG("FPB wasn't enabled, do it now");
926 target_write_u32(target
, FP_CTRL
, 3);
929 else if (breakpoint
->type
== BKPT_SOFT
)
932 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
933 if((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
937 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
941 breakpoint
->set
= 0x11; /* Any nice value but 0 */
947 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
950 /* get pointers to arch-specific information */
951 armv7m_common_t
*armv7m
= target
->arch_info
;
952 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
953 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
955 if (!breakpoint
->set
)
957 LOG_WARNING("breakpoint not set");
961 if (breakpoint
->type
== BKPT_HARD
)
963 int fp_num
= breakpoint
->set
- 1;
964 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
966 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
969 comparator_list
[fp_num
].used
= 0;
970 comparator_list
[fp_num
].fpcr_value
= 0;
971 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
975 /* restore original instruction (kept in target endianness) */
976 if (breakpoint
->length
== 4)
978 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
985 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
996 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
998 /* get pointers to arch-specific information */
999 armv7m_common_t
*armv7m
= target
->arch_info
;
1000 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1002 if (cortex_m3
->auto_bp_type
)
1004 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1005 #ifdef ARMV7_GDB_HACKS
1006 if (breakpoint
->length
!= 2) {
1007 /* XXX Hack: Replace all breakpoints with length != 2 with
1008 * a hardware breakpoint. */
1009 breakpoint
->type
= BKPT_HARD
;
1010 breakpoint
->length
= 2;
1015 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1017 LOG_INFO("flash patch comparator requested outside code memory region");
1018 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1021 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1023 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1024 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1027 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1029 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1030 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1033 if ((breakpoint
->length
!= 2))
1035 LOG_INFO("only breakpoints of two bytes length supported");
1036 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1039 if (breakpoint
->type
== BKPT_HARD
)
1040 cortex_m3
->fp_code_available
--;
1041 cortex_m3_set_breakpoint(target
, breakpoint
);
1046 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1048 /* get pointers to arch-specific information */
1049 armv7m_common_t
*armv7m
= target
->arch_info
;
1050 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1052 if (target
->state
!= TARGET_HALTED
)
1054 LOG_WARNING("target not halted");
1055 return ERROR_TARGET_NOT_HALTED
;
1058 if (cortex_m3
->auto_bp_type
)
1060 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1063 if (breakpoint
->set
)
1065 cortex_m3_unset_breakpoint(target
, breakpoint
);
1068 if (breakpoint
->type
== BKPT_HARD
)
1069 cortex_m3
->fp_code_available
++;
1074 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1079 /* get pointers to arch-specific information */
1080 armv7m_common_t
*armv7m
= target
->arch_info
;
1081 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1082 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1084 if (watchpoint
->set
)
1086 LOG_WARNING("watchpoint already set");
1090 if (watchpoint
->mask
== 0xffffffffu
)
1092 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1094 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1096 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1097 LOG_WARNING("ERROR Can not find free DWT Comparator");
1100 watchpoint
->set
= dwt_num
+ 1;
1102 temp
= watchpoint
->length
;
1108 comparator_list
[dwt_num
].used
= 1;
1109 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1110 comparator_list
[dwt_num
].mask
= mask
;
1111 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1112 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1113 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1114 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1115 LOG_DEBUG("dwt_num %i 0x%x 0x%x 0x%x", dwt_num
, comparator_list
[dwt_num
].comp
, comparator_list
[dwt_num
].mask
, comparator_list
[dwt_num
].function
);
1119 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1127 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1129 /* get pointers to arch-specific information */
1130 armv7m_common_t
*armv7m
= target
->arch_info
;
1131 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1132 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1135 if (!watchpoint
->set
)
1137 LOG_WARNING("watchpoint not set");
1141 dwt_num
= watchpoint
->set
- 1;
1143 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1145 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1148 comparator_list
[dwt_num
].used
= 0;
1149 comparator_list
[dwt_num
].function
= 0;
1150 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1152 watchpoint
->set
= 0;
1157 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1159 /* get pointers to arch-specific information */
1160 armv7m_common_t
*armv7m
= target
->arch_info
;
1161 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1163 if (target
->state
!= TARGET_HALTED
)
1165 LOG_WARNING("target not halted");
1166 return ERROR_TARGET_NOT_HALTED
;
1169 if (cortex_m3
->dwt_comp_available
< 1)
1171 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1174 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1176 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1179 cortex_m3
->dwt_comp_available
--;
1184 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1186 /* get pointers to arch-specific information */
1187 armv7m_common_t
*armv7m
= target
->arch_info
;
1188 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1190 if (target
->state
!= TARGET_HALTED
)
1192 LOG_WARNING("target not halted");
1193 return ERROR_TARGET_NOT_HALTED
;
1196 if (watchpoint
->set
)
1198 cortex_m3_unset_watchpoint(target
, watchpoint
);
1201 cortex_m3
->dwt_comp_available
++;
1206 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1208 watchpoint_t
*watchpoint
= target
->watchpoints
;
1210 /* set any pending watchpoints */
1213 if (watchpoint
->set
== 0)
1214 cortex_m3_set_watchpoint(target
, watchpoint
);
1215 watchpoint
= watchpoint
->next
;
1219 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1222 /* get pointers to arch-specific information */
1223 armv7m_common_t
*armv7m
= target
->arch_info
;
1224 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1226 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1228 /* read a normal core register */
1229 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1231 if (retval
!= ERROR_OK
)
1233 LOG_ERROR("JTAG failure %i",retval
);
1234 return ERROR_JTAG_DEVICE_ERROR
;
1236 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1238 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1240 /* read other registers */
1241 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1246 *value
= buf_get_u32((u8
*)value
, 0, 8);
1250 *value
= buf_get_u32((u8
*)value
, 8, 8);
1254 *value
= buf_get_u32((u8
*)value
, 16, 8);
1258 *value
= buf_get_u32((u8
*)value
, 24, 8);
1262 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1266 return ERROR_INVALID_ARGUMENTS
;
1272 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1277 /* get pointers to arch-specific information */
1278 armv7m_common_t
*armv7m
= target
->arch_info
;
1279 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1281 #ifdef ARMV7_GDB_HACKS
1282 /* If the LR register is being modified, make sure it will put us
1283 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1284 * hack to deal with the fact that gdb will sometimes "forge"
1285 * return addresses, and doesn't set the LSB correctly (i.e., when
1286 * printing expressions containing function calls, it sets LR=0.) */
1292 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1294 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1295 if (retval
!= ERROR_OK
)
1297 LOG_ERROR("JTAG failure %i", retval
);
1298 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1299 return ERROR_JTAG_DEVICE_ERROR
;
1301 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1303 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1305 /* write other registers */
1307 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1312 buf_set_u32((u8
*)®
, 0, 8, value
);
1316 buf_set_u32((u8
*)®
, 8, 8, value
);
1320 buf_set_u32((u8
*)®
, 16, 8, value
);
1324 buf_set_u32((u8
*)®
, 24, 8, value
);
1328 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1330 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1334 return ERROR_INVALID_ARGUMENTS
;
1340 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1342 /* get pointers to arch-specific information */
1343 armv7m_common_t
*armv7m
= target
->arch_info
;
1344 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1347 /* sanitize arguments */
1348 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1349 return ERROR_INVALID_ARGUMENTS
;
1351 /* cortex_m3 handles unaligned memory access */
1356 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1359 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1362 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1365 LOG_ERROR("BUG: we shouldn't get here");
1372 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1374 /* get pointers to arch-specific information */
1375 armv7m_common_t
*armv7m
= target
->arch_info
;
1376 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1379 /* sanitize arguments */
1380 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1381 return ERROR_INVALID_ARGUMENTS
;
1386 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1389 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1392 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1395 LOG_ERROR("BUG: we shouldn't get here");
1402 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1404 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1407 void cortex_m3_build_reg_cache(target_t
*target
)
1409 armv7m_build_reg_cache(target
);
1412 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1414 cortex_m3_build_reg_cache(target
);
1418 int cortex_m3_examine(struct target_s
*target
)
1421 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1424 /* get pointers to arch-specific information */
1425 armv7m_common_t
*armv7m
= target
->arch_info
;
1426 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1427 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1429 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1432 if (!target
->type
->examined
)
1434 target
->type
->examined
= 1;
1436 /* Read from Device Identification Registers */
1437 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1440 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1441 LOG_DEBUG("CORTEX-M3 processor detected");
1442 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1444 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1445 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1446 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1447 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1449 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1450 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1454 target_read_u32(target
, FP_CTRL
, &fpcr
);
1455 cortex_m3
->auto_bp_type
= 1;
1456 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1457 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1458 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1459 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1460 cortex_m3
->fpb_enabled
= fpcr
& 1;
1461 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1463 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1464 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1466 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1469 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1470 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1471 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1472 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1473 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1475 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1482 int cortex_m3_quit(void)
1488 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1492 mem_ap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1494 *value
= (u8
)(dcrdr
>> 8);
1496 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1498 /* write ack back to software dcc register
1499 * signify we have read data */
1500 if (dcrdr
& (1 << 0))
1503 mem_ap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1509 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1511 armv7m_common_t
*armv7m
= target
->arch_info
;
1512 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1517 for (i
= 0; i
< (size
* 4); i
++)
1519 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1526 int cortex_m3_handle_target_request(void *priv
)
1528 target_t
*target
= priv
;
1529 if (!target
->type
->examined
)
1531 armv7m_common_t
*armv7m
= target
->arch_info
;
1532 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1534 if (!target
->dbg_msg_enabled
)
1537 if (target
->state
== TARGET_RUNNING
)
1542 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1544 /* check if we have data */
1545 if (ctrl
& (1 << 0))
1549 /* we assume target is quick enough */
1551 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1552 request
|= (data
<< 8);
1553 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1554 request
|= (data
<< 16);
1555 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1556 request
|= (data
<< 24);
1557 target_request(target
, request
);
1564 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1566 armv7m_common_t
*armv7m
;
1567 armv7m
= &cortex_m3
->armv7m
;
1569 /* prepare JTAG information for the new target */
1570 cortex_m3
->jtag_info
.tap
= tap
;
1571 cortex_m3
->jtag_info
.scann_size
= 4;
1573 armv7m
->swjdp_info
.dp_select_value
= -1;
1574 armv7m
->swjdp_info
.ap_csw_value
= -1;
1575 armv7m
->swjdp_info
.ap_tar_value
= -1;
1576 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1578 /* initialize arch-specific breakpoint handling */
1580 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1581 cortex_m3
->arch_info
= NULL
;
1583 /* register arch-specific functions */
1584 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1586 armv7m
->pre_debug_entry
= NULL
;
1587 armv7m
->post_debug_entry
= NULL
;
1589 armv7m
->pre_restore_context
= NULL
;
1590 armv7m
->post_restore_context
= NULL
;
1592 armv7m_init_arch_info(target
, armv7m
);
1593 armv7m
->arch_info
= cortex_m3
;
1594 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1595 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1597 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1602 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1604 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1606 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1611 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1614 command_t
*cortex_m3_cmd
;
1616 retval
= armv7m_register_commands(cmd_ctx
);
1618 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3", NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1619 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr", handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
, "mask cortex_m3 interrupts ['on'|'off']");
1624 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1626 target_t
*target
= get_current_target(cmd_ctx
);
1627 armv7m_common_t
*armv7m
= target
->arch_info
;
1628 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1630 if (target
->state
!= TARGET_HALTED
)
1632 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1638 if (!strcmp(args
[0], "on"))
1640 cortex_m3_write_debug_halt_mask(target
, C_HALT
|C_MASKINTS
, 0);
1642 else if (!strcmp(args
[0], "off"))
1644 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1648 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1652 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1653 (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)