1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
27 * Cortex-M3(tm) TRM, ARM DDI 0337C *
29 ***************************************************************************/
34 #include "cortex_m3.h"
35 #include "target_request.h"
36 #include "target_type.h"
40 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
41 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
43 /* forward declarations */
44 void cortex_m3_enable_breakpoints(struct target_s
*target
);
45 void cortex_m3_enable_watchpoints(struct target_s
*target
);
46 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
);
47 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
48 int cortex_m3_quit(void);
49 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t *value
);
50 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t value
);
51 int cortex_m3_target_request_data(target_t
*target
, uint32_t size
, uint8_t *buffer
);
52 int cortex_m3_examine(struct target_s
*target
);
54 #ifdef ARMV7_GDB_HACKS
55 extern uint8_t armv7m_gdb_dummy_cpsr_value
[];
56 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
59 target_type_t cortexm3_target
=
63 .poll
= cortex_m3_poll
,
64 .arch_state
= armv7m_arch_state
,
66 .target_request_data
= cortex_m3_target_request_data
,
68 .halt
= cortex_m3_halt
,
69 .resume
= cortex_m3_resume
,
70 .step
= cortex_m3_step
,
72 .assert_reset
= cortex_m3_assert_reset
,
73 .deassert_reset
= cortex_m3_deassert_reset
,
74 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
76 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
78 .read_memory
= cortex_m3_read_memory
,
79 .write_memory
= cortex_m3_write_memory
,
80 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
81 .checksum_memory
= armv7m_checksum_memory
,
82 .blank_check_memory
= armv7m_blank_check_memory
,
84 .run_algorithm
= armv7m_run_algorithm
,
86 .add_breakpoint
= cortex_m3_add_breakpoint
,
87 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
88 .add_watchpoint
= cortex_m3_add_watchpoint
,
89 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
91 .register_commands
= cortex_m3_register_commands
,
92 .target_create
= cortex_m3_target_create
,
93 .init_target
= cortex_m3_init_target
,
94 .examine
= cortex_m3_examine
,
95 .quit
= cortex_m3_quit
98 int cortexm3_dap_read_coreregister_u32(swjdp_common_t
*swjdp
, uint32_t *value
, int regnum
)
103 /* because the DCB_DCRDR is used for the emulated dcc channel
104 * we gave to save/restore the DCB_DCRDR when used */
106 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
108 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
110 /* mem_ap_write_u32(swjdp, DCB_DCRSR, regnum); */
111 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
112 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
);
114 /* mem_ap_read_u32(swjdp, DCB_DCRDR, value); */
115 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
116 dap_ap_read_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
118 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
119 retval
= swjdp_transaction_endcheck(swjdp
);
123 int cortexm3_dap_write_coreregister_u32(swjdp_common_t
*swjdp
, uint32_t value
, int regnum
)
128 /* because the DCB_DCRDR is used for the emulated dcc channel
129 * we gave to save/restore the DCB_DCRDR when used */
131 mem_ap_read_u32(swjdp
, DCB_DCRDR
, &dcrdr
);
133 swjdp
->trans_mode
= TRANS_MODE_COMPOSITE
;
135 /* mem_ap_write_u32(swjdp, DCB_DCRDR, core_regs[i]); */
136 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRDR
& 0xFFFFFFF0);
137 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRDR
& 0xC), value
);
139 /* mem_ap_write_u32(swjdp, DCB_DCRSR, i | DCRSR_WnR); */
140 dap_setup_accessport(swjdp
, CSW_32BIT
| CSW_ADDRINC_OFF
, DCB_DCRSR
& 0xFFFFFFF0);
141 dap_ap_write_reg_u32(swjdp
, AP_REG_BD0
| (DCB_DCRSR
& 0xC), regnum
| DCRSR_WnR
);
143 mem_ap_write_u32(swjdp
, DCB_DCRDR
, dcrdr
);
144 retval
= swjdp_transaction_endcheck(swjdp
);
149 int cortex_m3_write_debug_halt_mask(target_t
*target
, uint32_t mask_on
, uint32_t mask_off
)
151 /* get pointers to arch-specific information */
152 armv7m_common_t
*armv7m
= target
->arch_info
;
153 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
154 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
156 /* mask off status bits */
157 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
158 /* create new register mask */
159 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
161 return mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
164 int cortex_m3_clear_halt(target_t
*target
)
166 /* get pointers to arch-specific information */
167 armv7m_common_t
*armv7m
= target
->arch_info
;
168 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
169 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
171 /* clear step if any */
172 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
174 /* Read Debug Fault Status Register */
175 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
176 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
177 mem_ap_write_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
178 LOG_DEBUG(" NVIC_DFSR 0x%" PRIx32
"", cortex_m3
->nvic_dfsr
);
183 int cortex_m3_single_step_core(target_t
*target
)
185 /* get pointers to arch-specific information */
186 armv7m_common_t
*armv7m
= target
->arch_info
;
187 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
188 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
191 /* backup dhcsr reg */
192 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
194 /* mask interrupts if not done already */
195 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
196 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
197 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
200 /* restore dhcsr reg */
201 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
202 cortex_m3_clear_halt(target
);
207 int cortex_m3_exec_opcode(target_t
*target
,uint32_t opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */)
209 /* get pointers to arch-specific information */
210 armv7m_common_t
*armv7m
= target
->arch_info
;
211 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
215 mem_ap_read_u32(swjdp
, 0x20000000, &savedram
);
216 mem_ap_write_u32(swjdp
, 0x20000000, opcode
);
217 cortexm3_dap_write_coreregister_u32(swjdp
, 0x20000000, 15);
218 cortex_m3_single_step_core(target
);
219 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
220 retvalue
= mem_ap_write_atomic_u32(swjdp
, 0x20000000, savedram
);
226 /* Enable interrupts */
227 int cortex_m3_cpsie(target_t
*target
, uint32_t IF
)
229 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
232 /* Disable interrupts */
233 int cortex_m3_cpsid(target_t
*target
, uint32_t IF
)
235 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
239 int cortex_m3_endreset_event(target_t
*target
)
244 /* get pointers to arch-specific information */
245 armv7m_common_t
*armv7m
= target
->arch_info
;
246 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
247 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
248 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
249 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
251 mem_ap_read_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
252 LOG_DEBUG("DCB_DEMCR = 0x%8.8" PRIx32
"",dcb_demcr
);
254 /* this regsiter is used for emulated dcc channel */
255 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
257 /* Enable debug requests */
258 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
259 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
260 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
262 /* clear any interrupt masking */
263 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
265 /* Enable trace and dwt */
266 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
267 /* Monitor bus faults */
268 mem_ap_write_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
271 target_write_u32(target
, FP_CTRL
, 3);
272 cortex_m3
->fpb_enabled
= 1;
274 /* Restore FPB registers */
275 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
277 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
280 /* Restore DWT registers */
281 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
283 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
284 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
285 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
287 swjdp_transaction_endcheck(swjdp
);
289 armv7m_invalidate_core_regs(target
);
291 /* make sure we have latest dhcsr flags */
292 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
297 int cortex_m3_examine_debug_reason(target_t
*target
)
299 /* get pointers to arch-specific information */
300 armv7m_common_t
*armv7m
= target
->arch_info
;
301 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
303 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
304 /* only check the debug reason if we don't know it already */
306 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
307 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
311 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
313 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
314 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
315 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
317 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
318 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
324 int cortex_m3_examine_exception_reason(target_t
*target
)
326 uint32_t shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
328 /* get pointers to arch-specific information */
329 armv7m_common_t
*armv7m
= target
->arch_info
;
330 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
332 mem_ap_read_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
333 switch (armv7m
->exception_number
)
337 case 3: /* Hard Fault */
338 mem_ap_read_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
339 if (except_sr
& 0x40000000)
341 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &cfsr
);
344 case 4: /* Memory Management */
345 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
346 mem_ap_read_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
348 case 5: /* Bus Fault */
349 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
350 mem_ap_read_u32(swjdp
, NVIC_BFAR
, &except_ar
);
352 case 6: /* Usage Fault */
353 mem_ap_read_u32(swjdp
, NVIC_CFSR
, &except_sr
);
355 case 11: /* SVCall */
357 case 12: /* Debug Monitor */
358 mem_ap_read_u32(swjdp
, NVIC_DFSR
, &except_sr
);
360 case 14: /* PendSV */
362 case 15: /* SysTick */
368 swjdp_transaction_endcheck(swjdp
);
369 LOG_DEBUG("%s SHCSR 0x%" PRIx32
", SR 0x%" PRIx32
", CFSR 0x%" PRIx32
", AR 0x%" PRIx32
"", armv7m_exception_string(armv7m
->exception_number
), \
370 shcsr
, except_sr
, cfsr
, except_ar
);
374 int cortex_m3_debug_entry(target_t
*target
)
380 /* get pointers to arch-specific information */
381 armv7m_common_t
*armv7m
= target
->arch_info
;
382 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
383 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
386 if (armv7m
->pre_debug_entry
)
387 armv7m
->pre_debug_entry(target
);
389 cortex_m3_clear_halt(target
);
390 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
392 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
395 /* Examine target state and mode */
396 /* First load register acessible through core debug port*/
397 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
399 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
400 armv7m
->read_core_reg(target
, i
);
403 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
405 #ifdef ARMV7_GDB_HACKS
406 /* copy real xpsr reg for gdb, setting thumb bit */
407 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
408 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
409 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
410 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
413 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
416 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
417 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
420 /* Now we can load SP core registers */
421 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
423 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
424 armv7m
->read_core_reg(target
, i
);
427 /* Are we in an exception handler */
430 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
431 armv7m
->exception_number
= (xPSR
& 0x1FF);
435 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
436 armv7m
->exception_number
= 0;
439 if (armv7m
->exception_number
)
441 cortex_m3_examine_exception_reason(target
);
444 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
445 armv7m_mode_strings
[armv7m
->core_mode
],
446 *(uint32_t*)(armv7m
->core_cache
->reg_list
[15].value
),
447 target_state_name(target
));
449 if (armv7m
->post_debug_entry
)
450 armv7m
->post_debug_entry(target
);
455 int cortex_m3_poll(target_t
*target
)
458 enum target_state prev_target_state
= target
->state
;
460 /* get pointers to arch-specific information */
461 armv7m_common_t
*armv7m
= target
->arch_info
;
462 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
463 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
465 /* Read from Debug Halting Control and Status Register */
466 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
467 if (retval
!= ERROR_OK
)
469 target
->state
= TARGET_UNKNOWN
;
473 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
475 /* check if still in reset */
476 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
478 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
480 target
->state
= TARGET_RESET
;
485 if (target
->state
== TARGET_RESET
)
487 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
488 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
);
489 cortex_m3_endreset_event(target
);
490 target
->state
= TARGET_RUNNING
;
491 prev_target_state
= TARGET_RUNNING
;
494 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
496 target
->state
= TARGET_HALTED
;
498 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
500 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
503 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
505 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
508 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
511 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
515 /* REVISIT when S_SLEEP is set, it's in a Sleep or DeepSleep state.
516 * How best to model low power modes?
519 if (target
->state
== TARGET_UNKNOWN
)
521 /* check if processor is retiring instructions */
522 if (cortex_m3
->dcb_dhcsr
& S_RETIRE_ST
)
524 target
->state
= TARGET_RUNNING
;
532 int cortex_m3_halt(target_t
*target
)
534 LOG_DEBUG("target->state: %s",
535 target_state_name(target
));
537 if (target
->state
== TARGET_HALTED
)
539 LOG_DEBUG("target was already halted");
543 if (target
->state
== TARGET_UNKNOWN
)
545 LOG_WARNING("target was in unknown state when halt was requested");
548 if (target
->state
== TARGET_RESET
)
550 if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST
) && jtag_get_srst())
552 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
553 return ERROR_TARGET_FAILURE
;
557 /* we came here in a reset_halt or reset_init sequence
558 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
560 target
->debug_reason
= DBG_REASON_DBGRQ
;
566 /* Write to Debug Halting Control and Status Register */
567 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
569 target
->debug_reason
= DBG_REASON_DBGRQ
;
574 int cortex_m3_soft_reset_halt(struct target_s
*target
)
576 /* get pointers to arch-specific information */
577 armv7m_common_t
*armv7m
= target
->arch_info
;
578 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
579 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
580 uint32_t dcb_dhcsr
= 0;
581 int retval
, timeout
= 0;
583 /* Enter debug state on reset, cf. end_reset_event() */
584 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
586 /* Request a reset */
587 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
588 target
->state
= TARGET_RESET
;
590 /* registers are now invalid */
591 armv7m_invalidate_core_regs(target
);
593 while (timeout
< 100)
595 retval
= mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
596 if (retval
== ERROR_OK
)
598 mem_ap_read_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
599 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
601 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%" PRIx32
", nvic_dfsr 0x%" PRIx32
"", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
602 cortex_m3_poll(target
);
606 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%" PRIx32
", %i ms", dcb_dhcsr
, timeout
);
615 int cortex_m3_resume(struct target_s
*target
, int current
, uint32_t address
, int handle_breakpoints
, int debug_execution
)
617 /* get pointers to arch-specific information */
618 armv7m_common_t
*armv7m
= target
->arch_info
;
619 breakpoint_t
*breakpoint
= NULL
;
622 if (target
->state
!= TARGET_HALTED
)
624 LOG_WARNING("target not halted");
625 return ERROR_TARGET_NOT_HALTED
;
628 if (!debug_execution
)
630 target_free_all_working_areas(target
);
631 cortex_m3_enable_breakpoints(target
);
632 cortex_m3_enable_watchpoints(target
);
637 /* Disable interrupts */
638 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
639 * This is probably the same issue as Cortex-M3 Errata 377493:
640 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
641 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
642 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
643 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
645 /* Make sure we are in Thumb mode */
646 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
647 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1 << 24));
648 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
649 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
652 /* current = 1: continue on current pc, otherwise continue at <address> */
655 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
656 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
657 armv7m
->core_cache
->reg_list
[15].valid
= 1;
660 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
662 armv7m_restore_context(target
);
664 /* the front-end may request us not to handle breakpoints */
665 if (handle_breakpoints
)
667 /* Single step past breakpoint at current address */
668 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
670 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
672 breakpoint
->unique_id
);
673 cortex_m3_unset_breakpoint(target
, breakpoint
);
674 cortex_m3_single_step_core(target
);
675 cortex_m3_set_breakpoint(target
, breakpoint
);
680 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
682 target
->debug_reason
= DBG_REASON_NOTHALTED
;
684 /* registers are now invalid */
685 armv7m_invalidate_core_regs(target
);
686 if (!debug_execution
)
688 target
->state
= TARGET_RUNNING
;
689 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
690 LOG_DEBUG("target resumed at 0x%" PRIx32
"", resume_pc
);
694 target
->state
= TARGET_DEBUG_RUNNING
;
695 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
696 LOG_DEBUG("target debug resumed at 0x%" PRIx32
"", resume_pc
);
702 /* int irqstepcount = 0; */
703 int cortex_m3_step(struct target_s
*target
, int current
, uint32_t address
, int handle_breakpoints
)
705 /* get pointers to arch-specific information */
706 armv7m_common_t
*armv7m
= target
->arch_info
;
707 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
708 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
709 breakpoint_t
*breakpoint
= NULL
;
711 if (target
->state
!= TARGET_HALTED
)
713 LOG_WARNING("target not halted");
714 return ERROR_TARGET_NOT_HALTED
;
717 /* current = 1: continue on current pc, otherwise continue at <address> */
719 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
721 /* the front-end may request us not to handle breakpoints */
722 if (handle_breakpoints
)
723 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
724 cortex_m3_unset_breakpoint(target
, breakpoint
);
726 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
728 armv7m_restore_context(target
);
730 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
732 /* set step and clear halt */
733 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
734 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
736 /* registers are now invalid */
737 armv7m_invalidate_core_regs(target
);
740 cortex_m3_set_breakpoint(target
, breakpoint
);
742 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
744 cortex_m3_debug_entry(target
);
745 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
747 LOG_DEBUG("target stepped dcb_dhcsr = 0x%" PRIx32
" nvic_icsr = 0x%" PRIx32
"", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
751 int cortex_m3_assert_reset(target_t
*target
)
753 armv7m_common_t
*armv7m
= target
->arch_info
;
754 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
755 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
758 LOG_DEBUG("target->state: %s",
759 target_state_name(target
));
761 enum reset_types jtag_reset_config
= jtag_get_reset_config();
762 if (!(jtag_reset_config
& RESET_HAS_SRST
))
764 LOG_ERROR("Can't assert SRST");
768 /* Enable debug requests */
769 mem_ap_read_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
770 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
771 mem_ap_write_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
773 mem_ap_write_u32(swjdp
, DCB_DCRDR
, 0);
775 if (!target
->reset_halt
)
777 /* Set/Clear C_MASKINTS in a separate operation */
778 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
779 mem_ap_write_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
781 /* clear any debug flags before resuming */
782 cortex_m3_clear_halt(target
);
784 /* clear C_HALT in dhcsr reg */
785 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
787 /* Enter debug state on reset, cf. end_reset_event() */
788 mem_ap_write_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
792 /* Enter debug state on reset, cf. end_reset_event() */
793 mem_ap_write_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
796 /* following hack is to handle luminary reset
797 * when srst is asserted the luminary device seesm to also clear the debug registers
798 * which does not match the armv7 debug TRM */
800 if (strcmp(target
->variant
, "lm3s") == 0)
802 /* get revision of lm3s target, only early silicon has this issue
803 * Fury Rev B, DustDevil Rev B, Tempest all ok */
807 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
809 switch ((did0
>> 16) & 0xff)
812 /* all Sandstorm suffer issue */
818 /* only Fury/DustDevil rev A suffer reset problems */
819 if (((did0
>> 8) & 0xff) == 0)
828 /* default to asserting srst */
829 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
831 jtag_add_reset(1, 1);
835 jtag_add_reset(0, 1);
840 /* this causes the luminary device to reset using the watchdog */
841 mem_ap_write_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
842 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
845 /* I do not know why this is necessary, but it fixes strange effects
846 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
848 mem_ap_read_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
852 target
->state
= TARGET_RESET
;
853 jtag_add_sleep(50000);
855 armv7m_invalidate_core_regs(target
);
857 if (target
->reset_halt
)
860 if ((retval
= target_halt(target
)) != ERROR_OK
)
867 int cortex_m3_deassert_reset(target_t
*target
)
869 LOG_DEBUG("target->state: %s",
870 target_state_name(target
));
872 /* deassert reset lines */
873 jtag_add_reset(0, 0);
878 void cortex_m3_enable_breakpoints(struct target_s
*target
)
880 breakpoint_t
*breakpoint
= target
->breakpoints
;
882 /* set any pending breakpoints */
885 if (breakpoint
->set
== 0)
886 cortex_m3_set_breakpoint(target
, breakpoint
);
887 breakpoint
= breakpoint
->next
;
891 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
897 /* get pointers to arch-specific information */
898 armv7m_common_t
*armv7m
= target
->arch_info
;
899 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
901 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
905 LOG_WARNING("breakpoint (BPID: %d) already set", breakpoint
->unique_id
);
909 if (cortex_m3
->auto_bp_type
)
911 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
914 if (breakpoint
->type
== BKPT_HARD
)
916 while (comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
918 if (fp_num
>= cortex_m3
->fp_num_code
)
920 LOG_DEBUG("ERROR Can not find free FP Comparator");
921 LOG_WARNING("ERROR Can not find free FP Comparator");
924 breakpoint
->set
= fp_num
+ 1;
925 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
926 comparator_list
[fp_num
].used
= 1;
927 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
928 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
929 LOG_DEBUG("fpc_num %i fpcr_value 0x%" PRIx32
"", fp_num
, comparator_list
[fp_num
].fpcr_value
);
930 if (!cortex_m3
->fpb_enabled
)
932 LOG_DEBUG("FPB wasn't enabled, do it now");
933 target_write_u32(target
, FP_CTRL
, 3);
936 else if (breakpoint
->type
== BKPT_SOFT
)
939 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
940 if ((retval
= target_read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
944 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
948 breakpoint
->set
= 0x11; /* Any nice value but 0 */
951 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
952 breakpoint
->unique_id
,
953 (int)(breakpoint
->type
),
961 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
964 /* get pointers to arch-specific information */
965 armv7m_common_t
*armv7m
= target
->arch_info
;
966 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
967 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
969 if (!breakpoint
->set
)
971 LOG_WARNING("breakpoint not set");
975 LOG_DEBUG("BPID: %d, Type: %d, Address: 0x%08" PRIx32
" Length: %d (set=%d)",
976 breakpoint
->unique_id
,
977 (int)(breakpoint
->type
),
982 if (breakpoint
->type
== BKPT_HARD
)
984 int fp_num
= breakpoint
->set
- 1;
985 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
987 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
990 comparator_list
[fp_num
].used
= 0;
991 comparator_list
[fp_num
].fpcr_value
= 0;
992 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
996 /* restore original instruction (kept in target endianness) */
997 if (breakpoint
->length
== 4)
999 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1006 if ((retval
= target_write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
1012 breakpoint
->set
= 0;
1017 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1019 /* get pointers to arch-specific information */
1020 armv7m_common_t
*armv7m
= target
->arch_info
;
1021 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1023 if (cortex_m3
->auto_bp_type
)
1025 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1026 #ifdef ARMV7_GDB_HACKS
1027 if (breakpoint
->length
!= 2) {
1028 /* XXX Hack: Replace all breakpoints with length != 2 with
1029 * a hardware breakpoint. */
1030 breakpoint
->type
= BKPT_HARD
;
1031 breakpoint
->length
= 2;
1036 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
1038 LOG_INFO("flash patch comparator requested outside code memory region");
1039 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1042 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
1044 LOG_INFO("soft breakpoint requested in code (flash) memory region");
1045 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1048 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
1050 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
1051 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1054 if ((breakpoint
->length
!= 2))
1056 LOG_INFO("only breakpoints of two bytes length supported");
1057 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1060 if (breakpoint
->type
== BKPT_HARD
)
1061 cortex_m3
->fp_code_available
--;
1062 cortex_m3_set_breakpoint(target
, breakpoint
);
1067 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1069 /* get pointers to arch-specific information */
1070 armv7m_common_t
*armv7m
= target
->arch_info
;
1071 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1073 if (target
->state
!= TARGET_HALTED
)
1075 LOG_WARNING("target not halted");
1076 return ERROR_TARGET_NOT_HALTED
;
1079 if (cortex_m3
->auto_bp_type
)
1081 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1084 if (breakpoint
->set
)
1086 cortex_m3_unset_breakpoint(target
, breakpoint
);
1089 if (breakpoint
->type
== BKPT_HARD
)
1090 cortex_m3
->fp_code_available
++;
1095 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1098 uint32_t mask
, temp
;
1100 /* get pointers to arch-specific information */
1101 armv7m_common_t
*armv7m
= target
->arch_info
;
1102 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1103 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1105 if (watchpoint
->set
)
1107 LOG_WARNING("watchpoint (%d) already set", watchpoint
->unique_id
);
1111 if (watchpoint
->mask
== 0xffffffffu
)
1113 while (comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1115 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1117 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1118 LOG_WARNING("ERROR Can not find free DWT Comparator");
1121 watchpoint
->set
= dwt_num
+ 1;
1123 temp
= watchpoint
->length
;
1129 comparator_list
[dwt_num
].used
= 1;
1130 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1131 comparator_list
[dwt_num
].mask
= mask
;
1132 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1133 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1134 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x4, comparator_list
[dwt_num
].mask
);
1135 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1136 LOG_DEBUG("dwt_num %i 0x%" PRIx32
" 0x%" PRIx32
" 0x%" PRIx32
"", dwt_num
, comparator_list
[dwt_num
].comp
, comparator_list
[dwt_num
].mask
, comparator_list
[dwt_num
].function
);
1140 /* Move this test to add_watchpoint */
1141 LOG_WARNING("Cannot watch data values (id: %d)",
1142 watchpoint
->unique_id
);
1145 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1146 watchpoint
->unique_id
, watchpoint
->address
, watchpoint
->set
);
1151 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1153 /* get pointers to arch-specific information */
1154 armv7m_common_t
*armv7m
= target
->arch_info
;
1155 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1156 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1159 if (!watchpoint
->set
)
1161 LOG_WARNING("watchpoint (wpid: %d) not set", watchpoint
->unique_id
);
1165 LOG_DEBUG("Watchpoint (ID: %d) address: 0x%08" PRIx32
" set=%d ",
1166 watchpoint
->unique_id
, watchpoint
->address
,watchpoint
->set
);
1168 dwt_num
= watchpoint
->set
- 1;
1170 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1172 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1175 comparator_list
[dwt_num
].used
= 0;
1176 comparator_list
[dwt_num
].function
= 0;
1177 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
| 0x8, comparator_list
[dwt_num
].function
);
1179 watchpoint
->set
= 0;
1184 int cortex_m3_add_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 (cortex_m3
->dwt_comp_available
< 1)
1198 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1201 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1203 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1206 cortex_m3
->dwt_comp_available
--;
1207 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1212 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1214 /* get pointers to arch-specific information */
1215 armv7m_common_t
*armv7m
= target
->arch_info
;
1216 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1218 if (target
->state
!= TARGET_HALTED
)
1220 LOG_WARNING("target not halted");
1221 return ERROR_TARGET_NOT_HALTED
;
1224 if (watchpoint
->set
)
1226 cortex_m3_unset_watchpoint(target
, watchpoint
);
1229 cortex_m3
->dwt_comp_available
++;
1230 LOG_DEBUG("dwt_comp_available: %d", cortex_m3
->dwt_comp_available
);
1235 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1237 watchpoint_t
*watchpoint
= target
->watchpoints
;
1239 /* set any pending watchpoints */
1242 if (watchpoint
->set
== 0)
1243 cortex_m3_set_watchpoint(target
, watchpoint
);
1244 watchpoint
= watchpoint
->next
;
1248 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t * value
)
1251 /* get pointers to arch-specific information */
1252 armv7m_common_t
*armv7m
= target
->arch_info
;
1253 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1255 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1257 /* read a normal core register */
1258 retval
= cortexm3_dap_read_coreregister_u32(swjdp
, value
, num
);
1260 if (retval
!= ERROR_OK
)
1262 LOG_ERROR("JTAG failure %i",retval
);
1263 return ERROR_JTAG_DEVICE_ERROR
;
1265 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",(int)num
,*value
);
1267 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1269 /* read other registers */
1270 cortexm3_dap_read_coreregister_u32(swjdp
, value
, 20);
1275 *value
= buf_get_u32((uint8_t*)value
, 0, 8);
1279 *value
= buf_get_u32((uint8_t*)value
, 8, 8);
1283 *value
= buf_get_u32((uint8_t*)value
, 16, 8);
1287 *value
= buf_get_u32((uint8_t*)value
, 24, 8);
1291 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"", (int)num
, *value
);
1295 return ERROR_INVALID_ARGUMENTS
;
1301 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, uint32_t num
, uint32_t value
)
1306 /* get pointers to arch-specific information */
1307 armv7m_common_t
*armv7m
= target
->arch_info
;
1308 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1310 #ifdef ARMV7_GDB_HACKS
1311 /* If the LR register is being modified, make sure it will put us
1312 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1313 * hack to deal with the fact that gdb will sometimes "forge"
1314 * return addresses, and doesn't set the LSB correctly (i.e., when
1315 * printing expressions containing function calls, it sets LR = 0.) */
1321 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1323 retval
= cortexm3_dap_write_coreregister_u32(swjdp
, value
, num
);
1324 if (retval
!= ERROR_OK
)
1326 LOG_ERROR("JTAG failure %i", retval
);
1327 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1328 return ERROR_JTAG_DEVICE_ERROR
;
1330 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
1332 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1334 /* write other registers */
1336 cortexm3_dap_read_coreregister_u32(swjdp
, ®
, 20);
1341 buf_set_u32((uint8_t*)®
, 0, 8, value
);
1345 buf_set_u32((uint8_t*)®
, 8, 8, value
);
1349 buf_set_u32((uint8_t*)®
, 16, 8, value
);
1353 buf_set_u32((uint8_t*)®
, 24, 8, value
);
1357 cortexm3_dap_write_coreregister_u32(swjdp
, reg
, 20);
1359 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
1363 return ERROR_INVALID_ARGUMENTS
;
1369 int cortex_m3_read_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
1371 /* get pointers to arch-specific information */
1372 armv7m_common_t
*armv7m
= target
->arch_info
;
1373 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1376 /* sanitize arguments */
1377 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1378 return ERROR_INVALID_ARGUMENTS
;
1380 /* cortex_m3 handles unaligned memory access */
1385 retval
= mem_ap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1388 retval
= mem_ap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1391 retval
= mem_ap_read_buf_u8(swjdp
, buffer
, count
, address
);
1394 LOG_ERROR("BUG: we shouldn't get here");
1401 int cortex_m3_write_memory(struct target_s
*target
, uint32_t address
, uint32_t size
, uint32_t count
, uint8_t *buffer
)
1403 /* get pointers to arch-specific information */
1404 armv7m_common_t
*armv7m
= target
->arch_info
;
1405 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1408 /* sanitize arguments */
1409 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1410 return ERROR_INVALID_ARGUMENTS
;
1415 retval
= mem_ap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1418 retval
= mem_ap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1421 retval
= mem_ap_write_buf_u8(swjdp
, buffer
, count
, address
);
1424 LOG_ERROR("BUG: we shouldn't get here");
1431 int cortex_m3_bulk_write_memory(target_t
*target
, uint32_t address
, uint32_t count
, uint8_t *buffer
)
1433 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1436 void cortex_m3_build_reg_cache(target_t
*target
)
1438 armv7m_build_reg_cache(target
);
1441 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1443 cortex_m3_build_reg_cache(target
);
1447 int cortex_m3_examine(struct target_s
*target
)
1450 uint32_t cpuid
, fpcr
, dwtcr
, ictr
;
1453 /* get pointers to arch-specific information */
1454 armv7m_common_t
*armv7m
= target
->arch_info
;
1455 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1456 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1458 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1461 if (!target_was_examined(target
))
1463 target_set_examined(target
);
1465 /* Read from Device Identification Registers */
1466 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1469 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1470 LOG_DEBUG("CORTEX-M3 processor detected");
1471 LOG_DEBUG("cpuid: 0x%8.8" PRIx32
"", cpuid
);
1473 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1474 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1475 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1476 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1478 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1479 LOG_DEBUG("interrupt enable[%i] = 0x%8.8" PRIx32
"", i
, cortex_m3
->intsetenable
[i
]);
1483 target_read_u32(target
, FP_CTRL
, &fpcr
);
1484 cortex_m3
->auto_bp_type
= 1;
1485 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1486 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1487 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1488 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1489 cortex_m3
->fpb_enabled
= fpcr
& 1;
1490 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1492 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1493 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1495 LOG_DEBUG("FPB fpcr 0x%" PRIx32
", numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1498 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1499 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1500 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1501 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1502 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1504 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1511 int cortex_m3_quit(void)
1517 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, uint8_t *value
, uint8_t *ctrl
)
1521 mem_ap_read_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1522 *ctrl
= (uint8_t)dcrdr
;
1523 *value
= (uint8_t)(dcrdr
>> 8);
1525 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1527 /* write ack back to software dcc register
1528 * signify we have read data */
1529 if (dcrdr
& (1 << 0))
1532 mem_ap_write_buf_u16(swjdp
, (uint8_t*)&dcrdr
, 1, DCB_DCRDR
);
1538 int cortex_m3_target_request_data(target_t
*target
, uint32_t size
, uint8_t *buffer
)
1540 armv7m_common_t
*armv7m
= target
->arch_info
;
1541 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1546 for (i
= 0; i
< (size
* 4); i
++)
1548 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1555 int cortex_m3_handle_target_request(void *priv
)
1557 target_t
*target
= priv
;
1558 if (!target_was_examined(target
))
1560 armv7m_common_t
*armv7m
= target
->arch_info
;
1561 swjdp_common_t
*swjdp
= &armv7m
->swjdp_info
;
1563 if (!target
->dbg_msg_enabled
)
1566 if (target
->state
== TARGET_RUNNING
)
1571 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1573 /* check if we have data */
1574 if (ctrl
& (1 << 0))
1578 /* we assume target is quick enough */
1580 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1581 request
|= (data
<< 8);
1582 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1583 request
|= (data
<< 16);
1584 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1585 request
|= (data
<< 24);
1586 target_request(target
, request
);
1593 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1596 armv7m_common_t
*armv7m
;
1597 armv7m
= &cortex_m3
->armv7m
;
1599 armv7m_init_arch_info(target
, armv7m
);
1601 /* prepare JTAG information for the new target */
1602 cortex_m3
->jtag_info
.tap
= tap
;
1603 cortex_m3
->jtag_info
.scann_size
= 4;
1605 armv7m
->swjdp_info
.dp_select_value
= -1;
1606 armv7m
->swjdp_info
.ap_csw_value
= -1;
1607 armv7m
->swjdp_info
.ap_tar_value
= -1;
1608 armv7m
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1609 armv7m
->swjdp_info
.memaccess_tck
= 8;
1610 armv7m
->swjdp_info
.tar_autoincr_block
= (1 << 12); /* Cortex-M3 has 4096 bytes autoincrement range */
1612 /* initialize arch-specific breakpoint handling */
1614 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1615 cortex_m3
->arch_info
= NULL
;
1617 /* register arch-specific functions */
1618 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1620 armv7m
->pre_debug_entry
= NULL
;
1621 armv7m
->post_debug_entry
= NULL
;
1623 armv7m
->pre_restore_context
= NULL
;
1624 armv7m
->post_restore_context
= NULL
;
1626 armv7m
->arch_info
= cortex_m3
;
1627 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1628 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1630 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1632 if ((retval
= arm_jtag_setup_connection(&cortex_m3
->jtag_info
)) != ERROR_OK
)
1640 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1642 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1644 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1649 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1652 command_t
*cortex_m3_cmd
;
1654 retval
= armv7m_register_commands(cmd_ctx
);
1656 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3", NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1657 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr", handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
, "mask cortex_m3 interrupts ['on'|'off']");
1662 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1664 target_t
*target
= get_current_target(cmd_ctx
);
1665 armv7m_common_t
*armv7m
= target
->arch_info
;
1666 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1668 if (target
->state
!= TARGET_HALTED
)
1670 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1676 if (!strcmp(args
[0], "on"))
1678 cortex_m3_write_debug_halt_mask(target
, C_HALT
| C_MASKINTS
, 0);
1680 else if (!strcmp(args
[0], "off"))
1682 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1686 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1690 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1691 (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)