1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
27 #include "replacements.h"
29 #include "cortex_m3.h"
34 #include "target_request.h"
43 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
45 /* forward declarations */
46 void cortex_m3_enable_breakpoints(struct target_s
*target
);
47 void cortex_m3_enable_watchpoints(struct target_s
*target
);
48 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
49 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
50 int cortex_m3_quit(void);
51 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
52 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
53 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
54 int cortex_m3_examine(struct target_s
*target
);
56 #ifdef ARMV7_GDB_HACKS
57 extern u8 armv7m_gdb_dummy_cpsr_value
[];
58 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
61 target_type_t cortexm3_target
=
65 .poll
= cortex_m3_poll
,
66 .arch_state
= armv7m_arch_state
,
68 .target_request_data
= cortex_m3_target_request_data
,
70 .halt
= cortex_m3_halt
,
71 .resume
= cortex_m3_resume
,
72 .step
= cortex_m3_step
,
74 .assert_reset
= cortex_m3_assert_reset
,
75 .deassert_reset
= cortex_m3_deassert_reset
,
76 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
78 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
80 .read_memory
= cortex_m3_read_memory
,
81 .write_memory
= cortex_m3_write_memory
,
82 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
83 .checksum_memory
= armv7m_checksum_memory
,
84 .blank_check_memory
= armv7m_blank_check_memory
,
86 .run_algorithm
= armv7m_run_algorithm
,
88 .add_breakpoint
= cortex_m3_add_breakpoint
,
89 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
90 .add_watchpoint
= cortex_m3_add_watchpoint
,
91 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
93 .register_commands
= cortex_m3_register_commands
,
94 .target_command
= cortex_m3_target_command
,
95 .init_target
= cortex_m3_init_target
,
96 .examine
= cortex_m3_examine
,
97 .quit
= cortex_m3_quit
100 int cortex_m3_clear_halt(target_t
*target
)
102 /* get pointers to arch-specific information */
103 armv7m_common_t
*armv7m
= target
->arch_info
;
104 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
105 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
107 /* Read Debug Fault Status Register */
108 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
109 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
110 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
111 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
116 int cortex_m3_single_step_core(target_t
*target
)
118 /* get pointers to arch-specific information */
119 armv7m_common_t
*armv7m
= target
->arch_info
;
120 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
121 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
123 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
124 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
125 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
126 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
128 cortex_m3_clear_halt(target
);
133 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
135 /* get pointers to arch-specific information */
136 armv7m_common_t
*armv7m
= target
->arch_info
;
137 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
138 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
142 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
143 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
144 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
145 cortex_m3_single_step_core(target
);
146 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
147 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
153 /* Enable interrupts */
154 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
156 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
159 /* Disable interrupts */
160 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
162 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
166 int cortex_m3_endreset_event(target_t
*target
)
171 /* get pointers to arch-specific information */
172 armv7m_common_t
*armv7m
= target
->arch_info
;
173 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
174 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
175 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
176 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
178 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
179 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
181 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
183 /* Enable debug requests */
184 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
185 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
186 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
187 /* Enable trace and dwt */
188 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
189 /* Monitor bus faults */
190 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
193 target_write_u32(target
, FP_CTRL
, 3);
195 /* Restore FPB registers */
196 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
198 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
201 /* Restore DWT registers */
202 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
204 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
205 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
206 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
208 swjdp_transaction_endcheck(swjdp
);
210 armv7m_invalidate_core_regs(target
);
214 int cortex_m3_examine_debug_reason(target_t
*target
)
216 /* get pointers to arch-specific information */
217 armv7m_common_t
*armv7m
= target
->arch_info
;
218 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
220 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
221 /* only check the debug reason if we don't know it already */
223 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
224 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
228 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
230 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
231 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
232 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
234 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
235 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
241 int cortex_m3_examine_exception_reason(target_t
*target
)
243 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
245 /* get pointers to arch-specific information */
246 armv7m_common_t
*armv7m
= target
->arch_info
;
247 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
248 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
250 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
251 switch (armv7m
->exception_number
)
255 case 3: /* Hard Fault */
256 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
257 if (except_sr
& 0x40000000)
259 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
262 case 4: /* Memory Management */
263 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
264 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
266 case 5: /* Bus Fault */
267 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
268 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
270 case 6: /* Usage Fault */
271 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
273 case 11: /* SVCall */
275 case 12: /* Debug Monitor */
276 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
278 case 14: /* PendSV */
280 case 15: /* SysTick */
286 swjdp_transaction_endcheck(swjdp
);
287 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
288 shcsr
, except_sr
, cfsr
, except_ar
);
292 int cortex_m3_debug_entry(target_t
*target
)
298 /* get pointers to arch-specific information */
299 armv7m_common_t
*armv7m
= target
->arch_info
;
300 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
301 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
304 if (armv7m
->pre_debug_entry
)
305 armv7m
->pre_debug_entry(target
);
307 cortex_m3_clear_halt(target
);
308 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
310 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
313 /* Examine target state and mode */
314 /* First load register acessible through core debug port*/
315 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
317 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
318 armv7m
->read_core_reg(target
, i
);
321 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
323 #ifdef ARMV7_GDB_HACKS
324 /* copy real xpsr reg for gdb, setting thumb bit */
325 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
326 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
327 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
328 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
331 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
334 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
335 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
338 /* Now we can load SP core registers */
339 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
341 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
342 armv7m
->read_core_reg(target
, i
);
345 /* Are we in an exception handler */
348 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
349 armv7m
->exception_number
= (xPSR
& 0x1FF);
353 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
354 armv7m
->exception_number
= 0;
357 if (armv7m
->exception_number
)
359 cortex_m3_examine_exception_reason(target
);
362 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
363 armv7m_mode_strings
[armv7m
->core_mode
],
364 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
365 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
367 if (armv7m
->post_debug_entry
)
368 armv7m
->post_debug_entry(target
);
373 int cortex_m3_poll(target_t
*target
)
376 u32 prev_target_state
= target
->state
;
378 /* get pointers to arch-specific information */
379 armv7m_common_t
*armv7m
= target
->arch_info
;
380 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
381 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
383 /* Read from Debug Halting Control and Status Register */
384 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
385 if (retval
!= ERROR_OK
)
387 target
->state
= TARGET_UNKNOWN
;
391 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
393 /* check if still in reset */
394 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
396 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
398 target
->state
= TARGET_RESET
;
403 if (target
->state
== TARGET_RESET
)
405 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
406 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
407 cortex_m3_endreset_event(target
);
408 target
->state
= TARGET_RUNNING
;
409 prev_target_state
= TARGET_RUNNING
;
412 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
414 target
->state
= TARGET_HALTED
;
416 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
418 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
421 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
423 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
426 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
429 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
434 if (cortex_m3->dcb_dhcsr & S_SLEEP)
435 target->state = TARGET_SLEEP;
439 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
440 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
441 LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_dfsr
, Jim_Nvp_value2name( nvp_target_state
, target
->state
)->name
);
447 int cortex_m3_halt(target_t
*target
)
449 /* get pointers to arch-specific information */
450 armv7m_common_t
*armv7m
= target
->arch_info
;
451 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
452 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
454 LOG_DEBUG("target->state: %s",
455 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
457 if (target
->state
== TARGET_HALTED
)
459 LOG_DEBUG("target was already halted");
463 if (target
->state
== TARGET_UNKNOWN
)
465 LOG_WARNING("target was in unknown state when halt was requested");
468 if (target
->state
== TARGET_RESET
)
470 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
472 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
473 return ERROR_TARGET_FAILURE
;
477 /* we came here in a reset_halt or reset_init sequence
478 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
480 target
->debug_reason
= DBG_REASON_DBGRQ
;
486 /* Write to Debug Halting Control and Status Register */
487 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
489 target
->debug_reason
= DBG_REASON_DBGRQ
;
494 int cortex_m3_soft_reset_halt(struct target_s
*target
)
496 /* get pointers to arch-specific information */
497 armv7m_common_t
*armv7m
= target
->arch_info
;
498 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
499 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
501 int retval
, timeout
= 0;
503 /* Enter debug state on reset, cf. end_reset_event() */
504 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
506 /* Request a reset */
507 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
508 target
->state
= TARGET_RESET
;
510 /* registers are now invalid */
511 armv7m_invalidate_core_regs(target
);
513 while (timeout
< 100)
515 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
516 if (retval
== ERROR_OK
)
518 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
519 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
521 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
522 cortex_m3_poll(target
);
526 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
535 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
537 /* get pointers to arch-specific information */
538 armv7m_common_t
*armv7m
= target
->arch_info
;
539 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
540 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
541 breakpoint_t
*breakpoint
= NULL
;
542 u32 dcb_dhcsr
, resume_pc
;
544 if (target
->state
!= TARGET_HALTED
)
546 LOG_WARNING("target not halted");
547 return ERROR_TARGET_NOT_HALTED
;
550 if (!debug_execution
)
552 target_free_all_working_areas(target
);
553 cortex_m3_enable_breakpoints(target
);
554 cortex_m3_enable_watchpoints(target
);
556 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
559 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
562 /* Disable interrupts */
564 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
565 This is probably the same inssue as Cortex-M3 Errata 377493:
566 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
568 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
569 /* Make sure we are in Thumb mode */
570 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
571 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
574 /* current = 1: continue on current pc, otherwise continue at <address> */
577 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
578 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
579 armv7m
->core_cache
->reg_list
[15].valid
= 1;
582 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
584 armv7m_restore_context(target
);
586 /* the front-end may request us not to handle breakpoints */
587 if (handle_breakpoints
)
589 /* Single step past breakpoint at current address */
590 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
592 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
593 cortex_m3_unset_breakpoint(target
, breakpoint
);
594 cortex_m3_single_step_core(target
);
595 cortex_m3_set_breakpoint(target
, breakpoint
);
599 /* Set/Clear C_MASKINTS in a separate operation */
600 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
601 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
604 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
605 target
->debug_reason
= DBG_REASON_NOTHALTED
;
607 /* registers are now invalid */
608 armv7m_invalidate_core_regs(target
);
609 if (!debug_execution
)
611 target
->state
= TARGET_RUNNING
;
612 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
613 LOG_DEBUG("target resumed at 0x%x",resume_pc
);
617 target
->state
= TARGET_DEBUG_RUNNING
;
618 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
619 LOG_DEBUG("target debug resumed at 0x%x",resume_pc
);
625 /* int irqstepcount=0; */
626 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
628 /* get pointers to arch-specific information */
629 armv7m_common_t
*armv7m
= target
->arch_info
;
630 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
631 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
632 breakpoint_t
*breakpoint
= NULL
;
634 if (target
->state
!= TARGET_HALTED
)
636 LOG_WARNING("target not halted");
637 return ERROR_TARGET_NOT_HALTED
;
640 /* current = 1: continue on current pc, otherwise continue at <address> */
642 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
644 /* the front-end may request us not to handle breakpoints */
645 if (handle_breakpoints
)
646 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
647 cortex_m3_unset_breakpoint(target
, breakpoint
);
649 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
651 armv7m_restore_context(target
);
653 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
655 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
656 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
657 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
658 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
660 /* registers are now invalid */
661 armv7m_invalidate_core_regs(target
);
664 cortex_m3_set_breakpoint(target
, breakpoint
);
666 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
668 cortex_m3_debug_entry(target
);
669 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
671 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
675 int cortex_m3_assert_reset(target_t
*target
)
677 armv7m_common_t
*armv7m
= target
->arch_info
;
678 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
679 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
682 LOG_DEBUG("target->state: %s",
683 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
685 if (!(jtag_reset_config
& RESET_HAS_SRST
))
687 LOG_ERROR("Can't assert SRST");
691 /* Enable debug requests */
692 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
693 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
694 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
696 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
698 if (!target
->reset_halt
)
700 /* Set/Clear C_MASKINTS in a separate operation */
701 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
702 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
704 cortex_m3_clear_halt(target
);
706 /* Enter debug state on reset, cf. end_reset_event() */
707 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
711 /* Enter debug state on reset, cf. end_reset_event() */
712 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
715 /* following hack is to handle luminary reset
716 * when srst is asserted the luminary device seesm to also clear the debug registers
717 * which does not match the armv7 debug TRM */
719 if (strcmp(cortex_m3
->variant
, "lm3s") == 0)
721 /* get revision of lm3s target, only early silicon has this issue
722 * Fury Rev B, DustDevil Rev B, Tempest all ok */
726 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
728 switch ((did0
>> 16) & 0xff)
731 /* all Sandstorm suffer issue */
737 /* only Fury/DustDevil rev A suffer reset problems */
738 if (((did0
>> 8) & 0xff) == 0)
747 /* default to asserting srst */
748 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
750 jtag_add_reset(1, 1);
754 jtag_add_reset(0, 1);
759 /* this causes the luminary device to reset using the watchdog */
760 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
761 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
764 target
->state
= TARGET_RESET
;
765 jtag_add_sleep(50000);
767 armv7m_invalidate_core_regs(target
);
769 if (target
->reset_halt
)
772 if ((retval
= target_halt(target
))!=ERROR_OK
)
779 int cortex_m3_deassert_reset(target_t
*target
)
781 LOG_DEBUG("target->state: %s",
782 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
784 /* deassert reset lines */
785 jtag_add_reset(0, 0);
790 void cortex_m3_enable_breakpoints(struct target_s
*target
)
792 breakpoint_t
*breakpoint
= target
->breakpoints
;
794 /* set any pending breakpoints */
797 if (breakpoint
->set
== 0)
798 cortex_m3_set_breakpoint(target
, breakpoint
);
799 breakpoint
= breakpoint
->next
;
803 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
808 /* get pointers to arch-specific information */
809 armv7m_common_t
*armv7m
= target
->arch_info
;
810 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
812 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
816 LOG_WARNING("breakpoint already set");
820 if (cortex_m3
->auto_bp_type
)
822 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
825 if (breakpoint
->type
== BKPT_HARD
)
827 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
829 if (fp_num
>= cortex_m3
->fp_num_code
)
831 LOG_DEBUG("ERROR Can not find free FP Comparator");
832 LOG_WARNING("ERROR Can not find free FP Comparator");
835 breakpoint
->set
= fp_num
+ 1;
836 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
837 comparator_list
[fp_num
].used
= 1;
838 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
839 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
840 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
842 else if (breakpoint
->type
== BKPT_SOFT
)
845 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
846 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
847 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
848 breakpoint
->set
= 0x11; /* Any nice value but 0 */
854 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
856 /* get pointers to arch-specific information */
857 armv7m_common_t
*armv7m
= target
->arch_info
;
858 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
859 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
861 if (!breakpoint
->set
)
863 LOG_WARNING("breakpoint not set");
867 if (breakpoint
->type
== BKPT_HARD
)
869 int fp_num
= breakpoint
->set
- 1;
870 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
872 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
875 comparator_list
[fp_num
].used
= 0;
876 comparator_list
[fp_num
].fpcr_value
= 0;
877 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
881 /* restore original instruction (kept in target endianness) */
882 if (breakpoint
->length
== 4)
884 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
888 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
896 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
898 /* get pointers to arch-specific information */
899 armv7m_common_t
*armv7m
= target
->arch_info
;
900 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
902 if (cortex_m3
->auto_bp_type
)
904 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
905 #ifdef ARMV7_GDB_HACKS
906 if (breakpoint
->length
!= 2) {
907 /* XXX Hack: Replace all breakpoints with length != 2 with
908 * a hardware breakpoint. */
909 breakpoint
->type
= BKPT_HARD
;
910 breakpoint
->length
= 2;
915 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
917 LOG_INFO("flash patch comparator requested outside code memory region");
918 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
921 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
923 LOG_INFO("soft breakpoint requested in code (flash) memory region");
924 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
927 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
929 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
930 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
933 if ((breakpoint
->length
!= 2))
935 LOG_INFO("only breakpoints of two bytes length supported");
936 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
939 if (breakpoint
->type
== BKPT_HARD
)
940 cortex_m3
->fp_code_available
--;
941 cortex_m3_set_breakpoint(target
, breakpoint
);
946 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
948 /* get pointers to arch-specific information */
949 armv7m_common_t
*armv7m
= target
->arch_info
;
950 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
952 if (target
->state
!= TARGET_HALTED
)
954 LOG_WARNING("target not halted");
955 return ERROR_TARGET_NOT_HALTED
;
958 if (cortex_m3
->auto_bp_type
)
960 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
965 cortex_m3_unset_breakpoint(target
, breakpoint
);
968 if (breakpoint
->type
== BKPT_HARD
)
969 cortex_m3
->fp_code_available
++;
974 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
979 /* get pointers to arch-specific information */
980 armv7m_common_t
*armv7m
= target
->arch_info
;
981 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
982 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
986 LOG_WARNING("watchpoint already set");
990 if (watchpoint
->mask
== 0xffffffffu
)
992 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
994 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
996 LOG_DEBUG("ERROR Can not find free DWT Comparator");
997 LOG_WARNING("ERROR Can not find free DWT Comparator");
1000 watchpoint
->set
= dwt_num
+ 1;
1002 temp
= watchpoint
->length
;
1008 comparator_list
[dwt_num
].used
= 1;
1009 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1010 comparator_list
[dwt_num
].mask
= mask
;
1011 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1012 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1013 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1014 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1015 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
);
1019 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1027 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1029 /* get pointers to arch-specific information */
1030 armv7m_common_t
*armv7m
= target
->arch_info
;
1031 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1032 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1035 if (!watchpoint
->set
)
1037 LOG_WARNING("watchpoint not set");
1041 dwt_num
= watchpoint
->set
- 1;
1043 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1045 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1048 comparator_list
[dwt_num
].used
= 0;
1049 comparator_list
[dwt_num
].function
= 0;
1050 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1052 watchpoint
->set
= 0;
1057 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
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
->dwt_comp_available
< 1)
1071 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1074 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1076 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1079 cortex_m3
->dwt_comp_available
--;
1084 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1086 /* get pointers to arch-specific information */
1087 armv7m_common_t
*armv7m
= target
->arch_info
;
1088 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1090 if (target
->state
!= TARGET_HALTED
)
1092 LOG_WARNING("target not halted");
1093 return ERROR_TARGET_NOT_HALTED
;
1096 if (watchpoint
->set
)
1098 cortex_m3_unset_watchpoint(target
, watchpoint
);
1101 cortex_m3
->dwt_comp_available
++;
1106 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1108 watchpoint_t
*watchpoint
= target
->watchpoints
;
1110 /* set any pending watchpoints */
1113 if (watchpoint
->set
== 0)
1114 cortex_m3_set_watchpoint(target
, watchpoint
);
1115 watchpoint
= watchpoint
->next
;
1119 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1122 /* get pointers to arch-specific information */
1123 armv7m_common_t
*armv7m
= target
->arch_info
;
1124 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1125 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1127 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1129 /* read a normal core register */
1130 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1132 if (retval
!= ERROR_OK
)
1134 LOG_ERROR("JTAG failure %i",retval
);
1135 return ERROR_JTAG_DEVICE_ERROR
;
1137 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1139 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1141 /* read other registers */
1142 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1147 *value
= buf_get_u32((u8
*)value
, 0, 8);
1151 *value
= buf_get_u32((u8
*)value
, 8, 8);
1155 *value
= buf_get_u32((u8
*)value
, 16, 8);
1159 *value
= buf_get_u32((u8
*)value
, 24, 8);
1163 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1167 return ERROR_INVALID_ARGUMENTS
;
1173 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1178 /* get pointers to arch-specific information */
1179 armv7m_common_t
*armv7m
= target
->arch_info
;
1180 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1181 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1183 #ifdef ARMV7_GDB_HACKS
1184 /* If the LR register is being modified, make sure it will put us
1185 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1186 * hack to deal with the fact that gdb will sometimes "forge"
1187 * return addresses, and doesn't set the LSB correctly (i.e., when
1188 * printing expressions containing function calls, it sets LR=0.) */
1194 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1196 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1197 if (retval
!= ERROR_OK
)
1199 LOG_ERROR("JTAG failure %i", retval
);
1200 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1201 return ERROR_JTAG_DEVICE_ERROR
;
1203 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1205 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1207 /* write other registers */
1209 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1214 buf_set_u32((u8
*)®
, 0, 8, value
);
1218 buf_set_u32((u8
*)®
, 8, 8, value
);
1222 buf_set_u32((u8
*)®
, 16, 8, value
);
1226 buf_set_u32((u8
*)®
, 24, 8, value
);
1230 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1232 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1236 return ERROR_INVALID_ARGUMENTS
;
1242 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1244 /* get pointers to arch-specific information */
1245 armv7m_common_t
*armv7m
= target
->arch_info
;
1246 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1247 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1250 /* sanitize arguments */
1251 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1252 return ERROR_INVALID_ARGUMENTS
;
1254 /* cortex_m3 handles unaligned memory access */
1259 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1262 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1265 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1268 LOG_ERROR("BUG: we shouldn't get here");
1275 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1277 /* get pointers to arch-specific information */
1278 armv7m_common_t
*armv7m
= target
->arch_info
;
1279 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1280 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1283 /* sanitize arguments */
1284 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1285 return ERROR_INVALID_ARGUMENTS
;
1290 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1293 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1296 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1299 LOG_ERROR("BUG: we shouldn't get here");
1306 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1308 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1311 void cortex_m3_build_reg_cache(target_t
*target
)
1313 armv7m_build_reg_cache(target
);
1316 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1318 cortex_m3_build_reg_cache(target
);
1322 int cortex_m3_examine(struct target_s
*target
)
1325 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1328 /* get pointers to arch-specific information */
1329 armv7m_common_t
*armv7m
= target
->arch_info
;
1330 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1331 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1333 target
->type
->examined
= 1;
1335 if ((retval
=ahbap_debugport_init(swjdp
))!=ERROR_OK
)
1338 /* Read from Device Identification Registers */
1339 if ((retval
=target_read_u32(target
, CPUID
, &cpuid
))!=ERROR_OK
)
1342 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1343 LOG_DEBUG("CORTEX-M3 processor detected");
1344 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1346 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1347 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1348 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1349 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1351 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1352 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1356 target_read_u32(target
, FP_CTRL
, &fpcr
);
1357 cortex_m3
->auto_bp_type
= 1;
1358 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1359 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1360 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1361 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1362 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1364 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1365 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1367 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1370 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1371 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1372 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1373 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1374 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1376 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1382 int cortex_m3_quit(void)
1388 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1392 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1394 *value
= (u8
)(dcrdr
>> 8);
1396 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1398 /* write ack back to software dcc register
1399 * signify we have read data */
1400 if (dcrdr
& (1 << 0))
1403 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1409 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1411 armv7m_common_t
*armv7m
= target
->arch_info
;
1412 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1413 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1418 for (i
= 0; i
< (size
* 4); i
++)
1420 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1427 int cortex_m3_handle_target_request(void *priv
)
1429 target_t
*target
= priv
;
1430 if (!target
->type
->examined
)
1432 armv7m_common_t
*armv7m
= target
->arch_info
;
1433 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1434 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1436 if (!target
->dbg_msg_enabled
)
1439 if (target
->state
== TARGET_RUNNING
)
1444 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1446 /* check if we have data */
1447 if (ctrl
& (1 << 0))
1451 /* we assume target is quick enough */
1453 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1454 request
|= (data
<< 8);
1455 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1456 request
|= (data
<< 16);
1457 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1458 request
|= (data
<< 24);
1459 target_request(target
, request
);
1466 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1468 armv7m_common_t
*armv7m
;
1469 armv7m
= &cortex_m3
->armv7m
;
1471 /* prepare JTAG information for the new target */
1472 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1473 cortex_m3
->jtag_info
.scann_size
= 4;
1475 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1476 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1477 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1478 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1480 /* initialize arch-specific breakpoint handling */
1482 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1483 cortex_m3
->arch_info
= NULL
;
1485 /* register arch-specific functions */
1486 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1488 armv7m
->pre_debug_entry
= NULL
;
1489 armv7m
->post_debug_entry
= NULL
;
1491 armv7m
->pre_restore_context
= NULL
;
1492 armv7m
->post_restore_context
= NULL
;
1496 cortex_m3
->variant
= strdup(variant
);
1500 cortex_m3
->variant
= strdup("");
1503 armv7m_init_arch_info(target
, armv7m
);
1504 armv7m
->arch_info
= cortex_m3
;
1505 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1506 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1508 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1513 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1514 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1517 char *variant
= NULL
;
1518 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1519 memset(cortex_m3
, 0, sizeof(*cortex_m3
));
1523 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1527 chain_pos
= strtoul(args
[3], NULL
, 0);
1532 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1537 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1541 retval
= armv7m_register_commands(cmd_ctx
);
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)