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 "replacements.h"
36 #include "cortex_m3.h"
41 #include "target_request.h"
50 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
51 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 /* forward declarations */
54 void cortex_m3_enable_breakpoints(struct target_s
*target
);
55 void cortex_m3_enable_watchpoints(struct target_s
*target
);
56 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
);
57 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
58 int cortex_m3_quit(void);
59 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
60 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
61 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
62 int cortex_m3_examine(struct target_s
*target
);
64 #ifdef ARMV7_GDB_HACKS
65 extern u8 armv7m_gdb_dummy_cpsr_value
[];
66 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
69 target_type_t cortexm3_target
=
73 .poll
= cortex_m3_poll
,
74 .arch_state
= armv7m_arch_state
,
76 .target_request_data
= cortex_m3_target_request_data
,
78 .halt
= cortex_m3_halt
,
79 .resume
= cortex_m3_resume
,
80 .step
= cortex_m3_step
,
82 .assert_reset
= cortex_m3_assert_reset
,
83 .deassert_reset
= cortex_m3_deassert_reset
,
84 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
86 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
88 .read_memory
= cortex_m3_read_memory
,
89 .write_memory
= cortex_m3_write_memory
,
90 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
91 .checksum_memory
= armv7m_checksum_memory
,
92 .blank_check_memory
= armv7m_blank_check_memory
,
94 .run_algorithm
= armv7m_run_algorithm
,
96 .add_breakpoint
= cortex_m3_add_breakpoint
,
97 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
98 .add_watchpoint
= cortex_m3_add_watchpoint
,
99 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
101 .register_commands
= cortex_m3_register_commands
,
102 .target_create
= cortex_m3_target_create
,
103 .init_target
= cortex_m3_init_target
,
104 .examine
= cortex_m3_examine
,
105 .quit
= cortex_m3_quit
108 int cortexm3_dap_read_coreregister_u32(swjdp_common_t
*swjdp
, u32
*value
, int regnum
)
113 /* because the DCB_DCRDR is used for the emulated dcc channel
114 * we gave to save/restore the DCB_DCRDR when used */
116 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
118 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
120 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
121 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
122 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
124 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
125 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
126 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
128 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
129 retval
= swjdp_transaction_endcheck(swjdp
);
133 int cortexm3_dap_write_coreregister_u32(swjdp_common_t
*swjdp
, u32 value
, int regnum
)
138 /* because the DCB_DCRDR is used for the emulated dcc channel
139 * we gave to save/restore the DCB_DCRDR when used */
141 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
143 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
145 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
146 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
147 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
149 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR ); */
150 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
151 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
153 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
154 retval
= swjdp_transaction_endcheck(swjdp
);
159 int cortex_m3_write_debug_halt_mask(target_t
*target
, u32 mask_on
, u32 mask_off
)
161 /* get pointers to arch-specific information */
162 armv7m_common_t
*armv7m
= target
->arch_info
;
163 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
164 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
166 /* mask off status bits */
167 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
168 /* create new register mask */
169 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
171 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
174 int cortex_m3_clear_halt(target_t
*target
)
176 /* get pointers to arch-specific information */
177 armv7m_common_t
*armv7m
= target
->arch_info
;
178 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
179 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
181 /* clear step if any */
182 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
184 /* Read Debug Fault Status Register */
185 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
186 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
187 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
188 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
193 int cortex_m3_single_step_core(target_t
*target
)
195 /* get pointers to arch-specific information */
196 armv7m_common_t
*armv7m
= target
->arch_info
;
197 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
198 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
201 /* backup dhcsr reg */
202 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
204 /* mask interrupts if not done already */
205 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
206 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
207 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
210 /* restore dhcsr reg */
211 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
212 cortex_m3_clear_halt(target
);
217 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
219 /* get pointers to arch-specific information */
220 armv7m_common_t
*armv7m
= target
->arch_info
;
221 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
225 mem_ap_read_u32(swjdp
, 0x20000000, &savedram
);
226 mem_ap_write_u32(swjdp
, 0x20000000, opcode
);
227 cortexm3_dap_write_coreregister_u32(swjdp
, 0x20000000, 15);
228 cortex_m3_single_step_core(target
);
229 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
230 retvalue
= mem_ap_write_atomic_u32(swjdp
, 0x20000000, savedram
);
236 /* Enable interrupts */
237 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
239 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
242 /* Disable interrupts */
243 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
245 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
249 int cortex_m3_endreset_event(target_t
*target
)
254 /* get pointers to arch-specific information */
255 armv7m_common_t
*armv7m
= target
->arch_info
;
256 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
257 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
258 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
259 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
261 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
262 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
264 /* this regsiter is used for emulated dcc channel */
265 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
267 /* Enable debug requests */
268 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
269 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
270 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
272 /* clear any interrupt masking */
273 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
275 /* Enable trace and dwt */
276 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
277 /* Monitor bus faults */
278 mem_ap_write_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
281 target_write_u32(target
, FP_CTRL
, 3);
282 cortex_m3
->fpb_enabled
= 1;
284 /* Restore FPB registers */
285 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
287 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
290 /* Restore DWT registers */
291 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
293 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
294 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
295 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
297 swjdp_transaction_endcheck(swjdp
);
299 armv7m_invalidate_core_regs(target
);
301 /* make sure we have latest dhcsr flags */
302 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
307 int cortex_m3_examine_debug_reason(target_t
*target
)
309 /* get pointers to arch-specific information */
310 armv7m_common_t
*armv7m
= target
->arch_info
;
311 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
313 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
314 /* only check the debug reason if we don't know it already */
316 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
317 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
321 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
323 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
324 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
325 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
327 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
328 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
334 int cortex_m3_examine_exception_reason(target_t
*target
)
336 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
338 /* get pointers to arch-specific information */
339 armv7m_common_t
*armv7m
= target
->arch_info
;
340 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
342 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
343 switch (armv7m
->exception_number
)
347 case 3: /* Hard Fault */
348 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
349 if (except_sr
& 0x40000000)
351 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
354 case 4: /* Memory Management */
355 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
356 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
358 case 5: /* Bus Fault */
359 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
360 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
362 case 6: /* Usage Fault */
363 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
365 case 11: /* SVCall */
367 case 12: /* Debug Monitor */
368 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
370 case 14: /* PendSV */
372 case 15: /* SysTick */
378 swjdp_transaction_endcheck(swjdp
);
379 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
380 shcsr
, except_sr
, cfsr
, except_ar
);
384 int cortex_m3_debug_entry(target_t
*target
)
390 /* get pointers to arch-specific information */
391 armv7m_common_t
*armv7m
= target
->arch_info
;
392 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
393 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
396 if (armv7m
->pre_debug_entry
)
397 armv7m
->pre_debug_entry(target
);
399 cortex_m3_clear_halt(target
);
400 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
402 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
405 /* Examine target state and mode */
406 /* First load register acessible through core debug port*/
407 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
409 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
410 armv7m
->read_core_reg(target
, i
);
413 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
415 #ifdef ARMV7_GDB_HACKS
416 /* copy real xpsr reg for gdb, setting thumb bit */
417 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
418 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
419 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
420 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
423 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
426 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
427 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
430 /* Now we can load SP core registers */
431 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
433 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
434 armv7m
->read_core_reg(target
, i
);
437 /* Are we in an exception handler */
440 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
441 armv7m
->exception_number
= (xPSR
& 0x1FF);
445 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
446 armv7m
->exception_number
= 0;
449 if (armv7m
->exception_number
)
451 cortex_m3_examine_exception_reason(target
);
454 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
455 armv7m_mode_strings
[armv7m
->core_mode
],
456 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
457 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
459 if (armv7m
->post_debug_entry
)
460 armv7m
->post_debug_entry(target
);
465 int cortex_m3_poll(target_t
*target
)
468 enum target_state prev_target_state
= target
->state
;
470 /* get pointers to arch-specific information */
471 armv7m_common_t
*armv7m
= target
->arch_info
;
472 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
473 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
475 /* Read from Debug Halting Control and Status Register */
476 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
477 if (retval
!= ERROR_OK
)
479 target
->state
= TARGET_UNKNOWN
;
483 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
485 /* check if still in reset */
486 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
488 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
490 target
->state
= TARGET_RESET
;
495 if (target
->state
== TARGET_RESET
)
497 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
498 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
499 cortex_m3_endreset_event(target
);
500 target
->state
= TARGET_RUNNING
;
501 prev_target_state
= TARGET_RUNNING
;
504 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
506 target
->state
= TARGET_HALTED
;
508 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
510 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
513 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
515 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
518 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
521 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
526 if (cortex_m3->dcb_dhcsr & S_SLEEP)
527 target->state = TARGET_SLEEP;
531 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
532 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
533 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
);
539 int cortex_m3_halt(target_t
*target
)
541 LOG_DEBUG("target->state: %s",
542 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
544 if (target
->state
== TARGET_HALTED
)
546 LOG_DEBUG("target was already halted");
550 if (target
->state
== TARGET_UNKNOWN
)
552 LOG_WARNING("target was in unknown state when halt was requested");
555 if (target
->state
== TARGET_RESET
)
557 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
559 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
560 return ERROR_TARGET_FAILURE
;
564 /* we came here in a reset_halt or reset_init sequence
565 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
567 target
->debug_reason
= DBG_REASON_DBGRQ
;
573 /* Write to Debug Halting Control and Status Register */
574 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
576 target
->debug_reason
= DBG_REASON_DBGRQ
;
581 int cortex_m3_soft_reset_halt(struct target_s
*target
)
583 /* get pointers to arch-specific information */
584 armv7m_common_t
*armv7m
= target
->arch_info
;
585 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
586 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
588 int retval
, timeout
= 0;
590 /* Enter debug state on reset, cf. end_reset_event() */
591 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
593 /* Request a reset */
594 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
595 target
->state
= TARGET_RESET
;
597 /* registers are now invalid */
598 armv7m_invalidate_core_regs(target
);
600 while (timeout
< 100)
602 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
603 if (retval
== ERROR_OK
)
605 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
606 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
608 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
609 cortex_m3_poll(target
);
613 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
622 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
624 /* get pointers to arch-specific information */
625 armv7m_common_t
*armv7m
= target
->arch_info
;
626 breakpoint_t
*breakpoint
= NULL
;
629 if (target
->state
!= TARGET_HALTED
)
631 LOG_WARNING("target not halted");
632 return ERROR_TARGET_NOT_HALTED
;
635 if (!debug_execution
)
637 target_free_all_working_areas(target
);
638 cortex_m3_enable_breakpoints(target
);
639 cortex_m3_enable_watchpoints(target
);
644 /* Disable interrupts */
645 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
646 * This is probably the same issue as Cortex-M3 Errata 377493:
647 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
648 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
649 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
650 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].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) | (1<<24));
655 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
656 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
659 /* current = 1: continue on current pc, otherwise continue at <address> */
662 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
663 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
664 armv7m
->core_cache
->reg_list
[15].valid
= 1;
667 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
669 armv7m_restore_context(target
);
671 /* the front-end may request us not to handle breakpoints */
672 if (handle_breakpoints
)
674 /* Single step past breakpoint at current address */
675 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
677 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
678 cortex_m3_unset_breakpoint(target
, breakpoint
);
679 cortex_m3_single_step_core(target
);
680 cortex_m3_set_breakpoint(target
, breakpoint
);
685 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
687 target
->debug_reason
= DBG_REASON_NOTHALTED
;
689 /* registers are now invalid */
690 armv7m_invalidate_core_regs(target
);
691 if (!debug_execution
)
693 target
->state
= TARGET_RUNNING
;
694 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
695 LOG_DEBUG("target resumed at 0x%x", resume_pc
);
699 target
->state
= TARGET_DEBUG_RUNNING
;
700 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
701 LOG_DEBUG("target debug resumed at 0x%x", resume_pc
);
707 /* int irqstepcount=0; */
708 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
710 /* get pointers to arch-specific information */
711 armv7m_common_t
*armv7m
= target
->arch_info
;
712 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
713 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
714 breakpoint_t
*breakpoint
= NULL
;
716 if (target
->state
!= TARGET_HALTED
)
718 LOG_WARNING("target not halted");
719 return ERROR_TARGET_NOT_HALTED
;
722 /* current = 1: continue on current pc, otherwise continue at <address> */
724 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
726 /* the front-end may request us not to handle breakpoints */
727 if (handle_breakpoints
)
728 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
729 cortex_m3_unset_breakpoint(target
, breakpoint
);
731 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
733 armv7m_restore_context(target
);
735 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
737 /* set step and clear halt */
738 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
739 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
741 /* registers are now invalid */
742 armv7m_invalidate_core_regs(target
);
745 cortex_m3_set_breakpoint(target
, breakpoint
);
747 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
749 cortex_m3_debug_entry(target
);
750 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
752 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
756 int cortex_m3_assert_reset(target_t
*target
)
758 armv7m_common_t
*armv7m
= target
->arch_info
;
759 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
760 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
763 LOG_DEBUG("target->state: %s",
764 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
766 if (!(jtag_reset_config
& RESET_HAS_SRST
))
768 LOG_ERROR("Can't assert SRST");
772 /* Enable debug requests */
773 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
774 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
775 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
777 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0 );
779 if (!target
->reset_halt
)
781 /* Set/Clear C_MASKINTS in a separate operation */
782 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
783 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
785 /* clear any debug flags before resuming */
786 cortex_m3_clear_halt(target
);
788 /* clear C_HALT in dhcsr reg */
789 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
791 /* Enter debug state on reset, cf. end_reset_event() */
792 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
796 /* Enter debug state on reset, cf. end_reset_event() */
797 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
800 /* following hack is to handle luminary reset
801 * when srst is asserted the luminary device seesm to also clear the debug registers
802 * which does not match the armv7 debug TRM */
804 if (strcmp(target
->variant
, "lm3s") == 0)
806 /* get revision of lm3s target, only early silicon has this issue
807 * Fury Rev B, DustDevil Rev B, Tempest all ok */
811 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
813 switch ((did0
>> 16) & 0xff)
816 /* all Sandstorm suffer issue */
822 /* only Fury/DustDevil rev A suffer reset problems */
823 if (((did0
>> 8) & 0xff) == 0)
832 /* default to asserting srst */
833 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
835 jtag_add_reset(1, 1);
839 jtag_add_reset(0, 1);
844 /* this causes the luminary device to reset using the watchdog */
845 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
846 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
849 /* I do not know why this is necessary, but it fixes strange effects
850 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
852 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
856 target
->state
= TARGET_RESET
;
857 jtag_add_sleep(50000);
859 armv7m_invalidate_core_regs(target
);
861 if (target
->reset_halt
)
864 if ((retval
= target_halt(target
))!=ERROR_OK
)
871 int cortex_m3_deassert_reset(target_t
*target
)
873 LOG_DEBUG("target->state: %s",
874 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
876 /* deassert reset lines */
877 jtag_add_reset(0, 0);
882 void cortex_m3_enable_breakpoints(struct target_s
*target
)
884 breakpoint_t
*breakpoint
= target
->breakpoints
;
886 /* set any pending breakpoints */
889 if (breakpoint
->set
== 0)
890 cortex_m3_set_breakpoint(target
, breakpoint
);
891 breakpoint
= breakpoint
->next
;
895 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
901 /* get pointers to arch-specific information */
902 armv7m_common_t
*armv7m
= target
->arch_info
;
903 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
905 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
909 LOG_WARNING("breakpoint already set");
913 if (cortex_m3
->auto_bp_type
)
915 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
918 if (breakpoint
->type
== BKPT_HARD
)
920 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
922 if (fp_num
>= cortex_m3
->fp_num_code
)
924 LOG_DEBUG("ERROR Can not find free FP Comparator");
925 LOG_WARNING("ERROR Can not find free FP Comparator");
928 breakpoint
->set
= fp_num
+ 1;
929 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
930 comparator_list
[fp_num
].used
= 1;
931 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
932 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
933 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
934 if (!cortex_m3
->fpb_enabled
)
936 LOG_DEBUG("FPB wasn't enabled, do it now");
937 target_write_u32(target
, FP_CTRL
, 3);
940 else if (breakpoint
->type
== BKPT_SOFT
)
943 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
944 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
948 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
952 breakpoint
->set
= 0x11; /* Any nice value but 0 */
958 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
961 /* get pointers to arch-specific information */
962 armv7m_common_t
*armv7m
= target
->arch_info
;
963 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
964 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
966 if (!breakpoint
->set
)
968 LOG_WARNING("breakpoint not set");
972 if (breakpoint
->type
== BKPT_HARD
)
974 int fp_num
= breakpoint
->set
- 1;
975 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
977 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
980 comparator_list
[fp_num
].used
= 0;
981 comparator_list
[fp_num
].fpcr_value
= 0;
982 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
986 /* restore original instruction (kept in target endianness) */
987 if (breakpoint
->length
== 4)
989 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
996 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1002 breakpoint
->set
= 0;
1007 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1009 /* get pointers to arch-specific information */
1010 armv7m_common_t
*armv7m
= target
->arch_info
;
1011 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1013 if (cortex_m3
->auto_bp_type
)
1015 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1016 #ifdef ARMV7_GDB_HACKS
1017 if (breakpoint
->length
!= 2) {
1018 /* XXX Hack: Replace all breakpoints with length != 2 with
1019 * a hardware breakpoint. */
1020 breakpoint
->type
= BKPT_HARD
;
1021 breakpoint
->length
= 2;
1026 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1028 LOG_INFO("flash patch comparator requested outside code memory region");
1029 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1032 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1034 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1035 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1038 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1040 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1041 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1044 if ((breakpoint
->length
!= 2))
1046 LOG_INFO("only breakpoints of two bytes length supported");
1047 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1050 if (breakpoint
->type
== BKPT_HARD
)
1051 cortex_m3
->fp_code_available
--;
1052 cortex_m3_set_breakpoint(target
, breakpoint
);
1057 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1059 /* get pointers to arch-specific information */
1060 armv7m_common_t
*armv7m
= target
->arch_info
;
1061 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1063 if (target
->state
!= TARGET_HALTED
)
1065 LOG_WARNING("target not halted");
1066 return ERROR_TARGET_NOT_HALTED
;
1069 if (cortex_m3
->auto_bp_type
)
1071 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1074 if (breakpoint
->set
)
1076 cortex_m3_unset_breakpoint(target
, breakpoint
);
1079 if (breakpoint
->type
== BKPT_HARD
)
1080 cortex_m3
->fp_code_available
++;
1085 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1090 /* get pointers to arch-specific information */
1091 armv7m_common_t
*armv7m
= target
->arch_info
;
1092 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1093 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1095 if (watchpoint
->set
)
1097 LOG_WARNING("watchpoint already set");
1101 if (watchpoint
->mask
== 0xffffffffu
)
1103 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1105 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1107 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1108 LOG_WARNING("ERROR Can not find free DWT Comparator");
1111 watchpoint
->set
= dwt_num
+ 1;
1113 temp
= watchpoint
->length
;
1119 comparator_list
[dwt_num
].used
= 1;
1120 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1121 comparator_list
[dwt_num
].mask
= mask
;
1122 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1123 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1124 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1125 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1126 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
);
1130 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1138 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1140 /* get pointers to arch-specific information */
1141 armv7m_common_t
*armv7m
= target
->arch_info
;
1142 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1143 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1146 if (!watchpoint
->set
)
1148 LOG_WARNING("watchpoint not set");
1152 dwt_num
= watchpoint
->set
- 1;
1154 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1156 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1159 comparator_list
[dwt_num
].used
= 0;
1160 comparator_list
[dwt_num
].function
= 0;
1161 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1163 watchpoint
->set
= 0;
1168 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1170 /* get pointers to arch-specific information */
1171 armv7m_common_t
*armv7m
= target
->arch_info
;
1172 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1174 if (target
->state
!= TARGET_HALTED
)
1176 LOG_WARNING("target not halted");
1177 return ERROR_TARGET_NOT_HALTED
;
1180 if (cortex_m3
->dwt_comp_available
< 1)
1182 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1185 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1187 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1190 cortex_m3
->dwt_comp_available
--;
1195 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1197 /* get pointers to arch-specific information */
1198 armv7m_common_t
*armv7m
= target
->arch_info
;
1199 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1201 if (target
->state
!= TARGET_HALTED
)
1203 LOG_WARNING("target not halted");
1204 return ERROR_TARGET_NOT_HALTED
;
1207 if (watchpoint
->set
)
1209 cortex_m3_unset_watchpoint(target
, watchpoint
);
1212 cortex_m3
->dwt_comp_available
++;
1217 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1219 watchpoint_t
*watchpoint
= target
->watchpoints
;
1221 /* set any pending watchpoints */
1224 if (watchpoint
->set
== 0)
1225 cortex_m3_set_watchpoint(target
, watchpoint
);
1226 watchpoint
= watchpoint
->next
;
1230 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1233 /* get pointers to arch-specific information */
1234 armv7m_common_t
*armv7m
= target
->arch_info
;
1235 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1237 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1239 /* read a normal core register */
1240 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1242 if (retval
!= ERROR_OK
)
1244 LOG_ERROR("JTAG failure %i",retval
);
1245 return ERROR_JTAG_DEVICE_ERROR
;
1247 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1249 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1251 /* read other registers */
1252 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1257 *value
= buf_get_u32((u8
*)value
, 0, 8);
1261 *value
= buf_get_u32((u8
*)value
, 8, 8);
1265 *value
= buf_get_u32((u8
*)value
, 16, 8);
1269 *value
= buf_get_u32((u8
*)value
, 24, 8);
1273 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1277 return ERROR_INVALID_ARGUMENTS
;
1283 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1288 /* get pointers to arch-specific information */
1289 armv7m_common_t
*armv7m
= target
->arch_info
;
1290 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1292 #ifdef ARMV7_GDB_HACKS
1293 /* If the LR register is being modified, make sure it will put us
1294 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1295 * hack to deal with the fact that gdb will sometimes "forge"
1296 * return addresses, and doesn't set the LSB correctly (i.e., when
1297 * printing expressions containing function calls, it sets LR=0.) */
1303 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1305 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1306 if (retval
!= ERROR_OK
)
1308 LOG_ERROR("JTAG failure %i", retval
);
1309 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1310 return ERROR_JTAG_DEVICE_ERROR
;
1312 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1314 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1316 /* write other registers */
1318 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1323 buf_set_u32((u8
*)®
, 0, 8, value
);
1327 buf_set_u32((u8
*)®
, 8, 8, value
);
1331 buf_set_u32((u8
*)®
, 16, 8, value
);
1335 buf_set_u32((u8
*)®
, 24, 8, value
);
1339 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1341 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1345 return ERROR_INVALID_ARGUMENTS
;
1351 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1353 /* get pointers to arch-specific information */
1354 armv7m_common_t
*armv7m
= target
->arch_info
;
1355 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1358 /* sanitize arguments */
1359 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1360 return ERROR_INVALID_ARGUMENTS
;
1362 /* cortex_m3 handles unaligned memory access */
1367 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1370 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1373 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1376 LOG_ERROR("BUG: we shouldn't get here");
1383 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1385 /* get pointers to arch-specific information */
1386 armv7m_common_t
*armv7m
= target
->arch_info
;
1387 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1390 /* sanitize arguments */
1391 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1392 return ERROR_INVALID_ARGUMENTS
;
1397 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1400 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1403 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1406 LOG_ERROR("BUG: we shouldn't get here");
1413 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1415 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1418 void cortex_m3_build_reg_cache(target_t
*target
)
1420 armv7m_build_reg_cache(target
);
1423 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1425 cortex_m3_build_reg_cache(target
);
1429 int cortex_m3_examine(struct target_s
*target
)
1432 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1435 /* get pointers to arch-specific information */
1436 armv7m_common_t
*armv7m
= target
->arch_info
;
1437 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1438 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1440 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1443 if (!target
->type
->examined
)
1445 target
->type
->examined
= 1;
1447 /* Read from Device Identification Registers */
1448 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1451 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1452 LOG_DEBUG("CORTEX-M3 processor detected");
1453 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1455 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1456 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1457 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1458 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1460 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1461 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1465 target_read_u32(target
, FP_CTRL
, &fpcr
);
1466 cortex_m3
->auto_bp_type
= 1;
1467 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1468 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1469 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1470 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1471 cortex_m3
->fpb_enabled
= fpcr
& 1;
1472 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1474 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1475 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1477 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1480 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1481 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1482 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1483 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1484 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1486 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1493 int cortex_m3_quit(void)
1499 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1503 mem_ap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1505 *value
= (u8
)(dcrdr
>> 8);
1507 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1509 /* write ack back to software dcc register
1510 * signify we have read data */
1511 if (dcrdr
& (1 << 0))
1514 mem_ap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1520 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1522 armv7m_common_t
*armv7m
= target
->arch_info
;
1523 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1528 for (i
= 0; i
< (size
* 4); i
++)
1530 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1537 int cortex_m3_handle_target_request(void *priv
)
1539 target_t
*target
= priv
;
1540 if (!target
->type
->examined
)
1542 armv7m_common_t
*armv7m
= target
->arch_info
;
1543 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1545 if (!target
->dbg_msg_enabled
)
1548 if (target
->state
== TARGET_RUNNING
)
1553 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1555 /* check if we have data */
1556 if (ctrl
& (1 << 0))
1560 /* we assume target is quick enough */
1562 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1563 request
|= (data
<< 8);
1564 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1565 request
|= (data
<< 16);
1566 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1567 request
|= (data
<< 24);
1568 target_request(target
, request
);
1575 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1577 armv7m_common_t
*armv7m
;
1578 armv7m
= &cortex_m3
->armv7m
;
1580 /* prepare JTAG information for the new target */
1581 cortex_m3
->jtag_info
.tap
= tap
;
1582 cortex_m3
->jtag_info
.scann_size
= 4;
1584 armv7m
->swjdp_info
.dp_select_value
= -1;
1585 armv7m
->swjdp_info
.ap_csw_value
= -1;
1586 armv7m
->swjdp_info
.ap_tar_value
= -1;
1587 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1589 /* initialize arch-specific breakpoint handling */
1591 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1592 cortex_m3
->arch_info
= NULL
;
1594 /* register arch-specific functions */
1595 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1597 armv7m
->pre_debug_entry
= NULL
;
1598 armv7m
->post_debug_entry
= NULL
;
1600 armv7m
->pre_restore_context
= NULL
;
1601 armv7m
->post_restore_context
= NULL
;
1603 armv7m_init_arch_info(target
, armv7m
);
1604 armv7m
->arch_info
= cortex_m3
;
1605 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1606 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1608 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1613 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1615 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1617 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1622 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1625 command_t
*cortex_m3_cmd
;
1627 retval
= armv7m_register_commands(cmd_ctx
);
1629 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3", NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1630 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr", handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
, "mask cortex_m3 interrupts ['on'|'off']");
1635 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1637 target_t
*target
= get_current_target(cmd_ctx
);
1638 armv7m_common_t
*armv7m
= target
->arch_info
;
1639 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1641 if (target
->state
!= TARGET_HALTED
)
1643 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1649 if (!strcmp(args
[0], "on"))
1651 cortex_m3_write_debug_halt_mask(target
, C_HALT
|C_MASKINTS
, 0);
1653 else if (!strcmp(args
[0], "off"))
1655 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1659 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1663 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1664 (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)