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_unset_all_breakpoints_and_watchpoints(struct target_s
*target
);
47 void cortex_m3_enable_breakpoints(struct target_s
*target
);
48 void cortex_m3_enable_watchpoints(struct target_s
*target
);
49 void cortex_m3_disable_bkpts_and_wpts(struct target_s
*target
);
50 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
51 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
53 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
54 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
55 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
57 target_type_t cortexm3_target
=
61 .poll
= cortex_m3_poll
,
62 .arch_state
= armv7m_arch_state
,
64 .target_request_data
= cortex_m3_target_request_data
,
66 .halt
= cortex_m3_halt
,
67 .resume
= cortex_m3_resume
,
68 .step
= cortex_m3_step
,
70 .assert_reset
= cortex_m3_assert_reset
,
71 .deassert_reset
= cortex_m3_deassert_reset
,
72 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
73 .prepare_reset_halt
= cortex_m3_prepare_reset_halt
,
75 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
77 .read_memory
= cortex_m3_read_memory
,
78 .write_memory
= cortex_m3_write_memory
,
79 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
80 .checksum_memory
= armv7m_checksum_memory
,
82 .run_algorithm
= armv7m_run_algorithm
,
84 .add_breakpoint
= cortex_m3_add_breakpoint
,
85 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
86 .add_watchpoint
= cortex_m3_add_watchpoint
,
87 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
89 .register_commands
= cortex_m3_register_commands
,
90 .target_command
= cortex_m3_target_command
,
91 .init_target
= cortex_m3_init_target
,
92 .quit
= cortex_m3_quit
95 int cortex_m3_clear_halt(target_t
*target
)
97 /* get pointers to arch-specific information */
98 armv7m_common_t
*armv7m
= target
->arch_info
;
99 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
100 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
102 /* Read Debug Fault Status Register */
103 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
104 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
105 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
106 DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
111 int cortex_m3_single_step_core(target_t
*target
)
113 /* get pointers to arch-specific information */
114 armv7m_common_t
*armv7m
= target
->arch_info
;
115 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
116 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
118 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
119 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
120 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
121 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
123 cortex_m3_clear_halt(target
);
128 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
130 /* get pointers to arch-specific information */
131 armv7m_common_t
*armv7m
= target
->arch_info
;
132 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
133 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
137 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
138 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
139 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
140 cortex_m3_single_step_core(target
);
141 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
142 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
147 /* Enable interrupts */
148 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
150 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
153 /* Disable interrupts */
154 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
156 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
159 int cortex_m3_endreset_event(target_t
*target
)
164 /* get pointers to arch-specific information */
165 armv7m_common_t
*armv7m
= target
->arch_info
;
166 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
167 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
168 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
169 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
171 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
172 DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
174 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
176 /* Enable debug requests */
177 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
178 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
179 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
180 /* Enable trace and dwt */
181 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
182 /* Monitor bus faults */
183 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
186 target_write_u32(target
, FP_CTRL
, 3);
188 /* Restore FPB registers */
189 for ( i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
191 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
194 /* Restore DWT registers */
195 for ( i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
197 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
198 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
199 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
201 swjdp_transaction_endcheck(swjdp
);
203 /* Make sure working_areas are all free */
204 target_free_all_working_areas(target
);
206 /* We are in process context */
207 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
208 armv7m_invalidate_core_regs(target
);
212 int cortex_m3_examine_debug_reason(target_t
*target
)
214 /* get pointers to arch-specific information */
215 armv7m_common_t
*armv7m
= target
->arch_info
;
216 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
218 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
219 /* only check the debug reason if we don't know it already */
221 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
222 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
226 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
228 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
229 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
230 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
232 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
233 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
239 int cortex_m3_examine_exception_reason(target_t
*target
)
241 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
243 /* get pointers to arch-specific information */
244 armv7m_common_t
*armv7m
= target
->arch_info
;
245 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
246 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
248 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
249 switch (armv7m
->exception_number
)
253 case 3: /* Hard Fault */
254 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
255 if (except_sr
& 0x40000000)
257 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
260 case 4: /* Memory Management */
261 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
262 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
264 case 5: /* Bus Fault */
265 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
266 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
268 case 6: /* Usage Fault */
269 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
271 case 11: /* SVCall */
273 case 12: /* Debug Monitor */
274 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
276 case 14: /* PendSV */
278 case 15: /* SysTick */
284 swjdp_transaction_endcheck(swjdp
);
285 DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
286 shcsr
, except_sr
, cfsr
, except_ar
);
290 int cortex_m3_debug_entry(target_t
*target
)
296 /* get pointers to arch-specific information */
297 armv7m_common_t
*armv7m
= target
->arch_info
;
298 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
299 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
302 if (armv7m
->pre_debug_entry
)
303 armv7m
->pre_debug_entry(target
);
305 cortex_m3_clear_halt(target
);
306 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
308 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
311 /* Examine target state and mode */
312 /* First load register acessible through core debug port*/
313 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
315 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
316 armv7m
->read_core_reg(target
, i
);
319 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
321 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
324 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
325 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
329 /* Now we can load SP core registers */
330 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
332 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
333 armv7m
->read_core_reg(target
, i
);
336 /* Are we in an exception handler */
337 armv7m
->core_mode
= (xPSR
& 0x1FF) ? ARMV7M_MODE_HANDLER
: ARMV7M_MODE_THREAD
;
338 armv7m
->exception_number
= xPSR
& 0x1FF;
339 if (armv7m
->exception_number
)
341 cortex_m3_examine_exception_reason(target
);
344 DEBUG("entered debug state at PC 0x%x, target->state: %s ", *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
346 if (armv7m
->post_debug_entry
)
347 armv7m
->post_debug_entry(target
);
352 int cortex_m3_poll(target_t
*target
)
355 u32 prev_target_state
= target
->state
;
357 /* get pointers to arch-specific information */
358 armv7m_common_t
*armv7m
= target
->arch_info
;
359 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
360 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
362 /* Read from Debug Halting Control and Status Register */
363 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
364 if (retval
!= ERROR_OK
)
366 target
->state
= TARGET_UNKNOWN
;
370 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
372 /* check if still in reset */
373 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
375 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
377 target
->state
= TARGET_RESET
;
382 if (target
->state
== TARGET_RESET
)
384 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
385 DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
386 cortex_m3_endreset_event(target
);
387 target
->state
= TARGET_RUNNING
;
388 prev_target_state
= TARGET_RUNNING
;
391 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
393 target
->state
= TARGET_HALTED
;
395 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
397 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
400 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
402 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
405 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
408 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
413 if (cortex_m3->dcb_dhcsr & S_SLEEP)
414 target->state = TARGET_SLEEP;
417 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
418 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
419 DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_dfsr
, target_state_strings
[target
->state
]);
423 int cortex_m3_halt(target_t
*target
)
425 /* get pointers to arch-specific information */
426 armv7m_common_t
*armv7m
= target
->arch_info
;
427 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
428 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
430 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
432 if (target
->state
== TARGET_HALTED
)
434 WARNING("target was already halted");
435 return ERROR_TARGET_ALREADY_HALTED
;
438 if (target
->state
== TARGET_UNKNOWN
)
440 WARNING("target was in unknown state when halt was requested");
443 if (target
->state
== TARGET_RESET
)
445 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
447 ERROR("can't request a halt while in reset if nSRST pulls nTRST");
448 return ERROR_TARGET_FAILURE
;
452 /* we came here in a reset_halt or reset_init sequence
453 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
455 target
->debug_reason
= DBG_REASON_DBGRQ
;
461 /* Write to Debug Halting Control and Status Register */
462 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
464 target
->debug_reason
= DBG_REASON_DBGRQ
;
469 int cortex_m3_soft_reset_halt(struct target_s
*target
)
471 /* get pointers to arch-specific information */
472 armv7m_common_t
*armv7m
= target
->arch_info
;
473 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
474 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
476 int retval
, timeout
= 0;
478 /* Check that we are using process_context, or change and print warning */
479 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
481 DEBUG("Changing to process contex registers");
482 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
485 /* Enter debug state on reset, cf. end_reset_event() */
486 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
488 /* Request a reset */
489 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
490 target
->state
= TARGET_RESET
;
492 /* registers are now invalid */
493 armv7m_invalidate_core_regs(target
);
495 while (timeout
< 100)
497 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
498 if (retval
== ERROR_OK
)
500 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
501 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
503 DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
504 cortex_m3_poll(target
);
508 DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
517 int cortex_m3_prepare_reset_halt(struct target_s
*target
)
519 armv7m_common_t
*armv7m
= target
->arch_info
;
520 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
521 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
522 u32 dcb_demcr
, dcb_dhcsr
;
524 /* Enable debug requests */
525 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
526 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
527 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
529 /* Enter debug state on reset, cf. end_reset_event() */
530 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
532 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
533 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
534 DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr
, dcb_demcr
);
539 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
541 /* get pointers to arch-specific information */
542 armv7m_common_t
*armv7m
= target
->arch_info
;
543 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
544 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
545 breakpoint_t
*breakpoint
= NULL
;
546 u32 dcb_dhcsr
, resume_pc
;
548 if (target
->state
!= TARGET_HALTED
)
550 WARNING("target not halted");
551 return ERROR_TARGET_NOT_HALTED
;
554 if (!debug_execution
)
556 /* Check that we are using process_context, or change and print warning */
557 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
559 WARNING("Incorrect context in resume");
560 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
563 target_free_all_working_areas(target
);
564 cortex_m3_enable_breakpoints(target
);
565 cortex_m3_enable_watchpoints(target
);
567 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
570 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
573 /* Check that we are using debug_context, or change and print warning */
574 if (armv7m_get_context(target
) != ARMV7M_DEBUG_CONTEXT
)
576 WARNING("Incorrect context in debug_exec resume");
577 armv7m_use_context(target
, ARMV7M_DEBUG_CONTEXT
);
579 /* Disable interrupts */
581 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
582 This is probably the same inssue as Cortex-M3 Errata 377493:
583 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
585 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
586 /* Make sure we are in Thumb mode */
587 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
588 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
591 /* current = 1: continue on current pc, otherwise continue at <address> */
594 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
595 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
596 armv7m
->core_cache
->reg_list
[15].valid
= 1;
599 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
601 armv7m_restore_context(target
);
603 /* the front-end may request us not to handle breakpoints */
604 if (handle_breakpoints
)
606 /* Single step past breakpoint at current address */
607 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
609 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
610 cortex_m3_unset_breakpoint(target
, breakpoint
);
611 cortex_m3_single_step_core(target
);
612 cortex_m3_set_breakpoint(target
, breakpoint
);
616 /* Set/Clear C_MASKINTS in a separate operation */
617 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
618 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
621 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
622 target
->debug_reason
= DBG_REASON_NOTHALTED
;
624 /* registers are now invalid */
625 armv7m_invalidate_core_regs(target
);
626 if (!debug_execution
)
628 target
->state
= TARGET_RUNNING
;
629 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
630 DEBUG("target resumed at 0x%x",resume_pc
);
634 target
->state
= TARGET_DEBUG_RUNNING
;
635 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
636 DEBUG("target debug resumed at 0x%x",resume_pc
);
642 /* int irqstepcount=0; */
643 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
645 /* get pointers to arch-specific information */
646 armv7m_common_t
*armv7m
= target
->arch_info
;
647 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
648 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
649 breakpoint_t
*breakpoint
= NULL
;
651 if (target
->state
!= TARGET_HALTED
)
653 WARNING("target not halted");
654 return ERROR_TARGET_NOT_HALTED
;
657 /* Check that we are using process_context, or change and print warning */
658 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
660 WARNING("Incorrect context in step, must be process");
661 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
664 /* current = 1: continue on current pc, otherwise continue at <address> */
666 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
668 /* the front-end may request us not to handle breakpoints */
669 if (handle_breakpoints
)
670 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
671 cortex_m3_unset_breakpoint(target
, breakpoint
);
673 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
675 armv7m_restore_context(target
);
677 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
679 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
680 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
681 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
682 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
684 /* If we run in process context then registers are now invalid */
685 if (armv7m_get_context(target
) == ARMV7M_PROCESS_CONTEXT
)
686 armv7m_invalidate_core_regs(target
);
689 cortex_m3_set_breakpoint(target
, breakpoint
);
691 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
693 cortex_m3_debug_entry(target
);
694 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
696 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
700 int cortex_m3_assert_reset(target_t
*target
)
703 armv7m_common_t
*armv7m
= target
->arch_info
;
704 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
705 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
707 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
709 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
711 if (target
->reset_mode
== RESET_RUN
)
713 /* Set/Clear C_MASKINTS in a separate operation */
714 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
715 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
717 cortex_m3_clear_halt(target
);
719 /* Enter debug state on reset, cf. end_reset_event() */
720 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
721 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
724 if (target
->state
== TARGET_HALTED
|| target
->state
== TARGET_UNKNOWN
)
726 /* assert SRST and TRST */
727 /* system would get ouf sync if we didn't reset test-logic, too */
728 if ((retval
= jtag_add_reset(1, 1)) != ERROR_OK
)
730 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
732 WARNING("can't assert srst");
737 ERROR("unknown error");
741 jtag_add_sleep(5000);
742 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
744 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
746 WARNING("srst resets test logic, too");
747 retval
= jtag_add_reset(1, 1);
753 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
755 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
757 WARNING("srst resets test logic, too");
758 retval
= jtag_add_reset(1, 1);
761 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
763 WARNING("can't assert srsrt");
766 else if (retval
!= ERROR_OK
)
768 ERROR("unknown error");
774 target
->state
= TARGET_RESET
;
775 jtag_add_sleep(50000);
777 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
778 armv7m_invalidate_core_regs(target
);
783 int cortex_m3_deassert_reset(target_t
*target
)
785 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
787 /* deassert reset lines */
788 jtag_add_reset(0, 0);
793 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
)
798 void cortex_m3_enable_breakpoints(struct target_s
*target
)
800 breakpoint_t
*breakpoint
= target
->breakpoints
;
802 /* set any pending breakpoints */
805 if (breakpoint
->set
== 0)
806 cortex_m3_set_breakpoint(target
, breakpoint
);
807 breakpoint
= breakpoint
->next
;
811 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
816 /* get pointers to arch-specific information */
817 armv7m_common_t
*armv7m
= target
->arch_info
;
818 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
820 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
824 WARNING("breakpoint already set");
828 if (cortex_m3
->auto_bp_type
)
830 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
833 if (breakpoint
->type
== BKPT_HARD
)
835 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
837 if (fp_num
>= cortex_m3
->fp_num_code
)
839 DEBUG("ERROR Can not find free FP Comparator");
840 WARNING("ERROR Can not find free FP Comparator");
843 breakpoint
->set
= fp_num
+ 1;
844 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
845 comparator_list
[fp_num
].used
= 1;
846 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
847 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
848 DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
850 else if (breakpoint
->type
== BKPT_SOFT
)
853 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
854 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
855 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
856 breakpoint
->set
= 0x11; /* Any nice value but 0 */
862 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
864 /* get pointers to arch-specific information */
865 armv7m_common_t
*armv7m
= target
->arch_info
;
866 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
867 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
869 if (!breakpoint
->set
)
871 WARNING("breakpoint not set");
875 if (breakpoint
->type
== BKPT_HARD
)
877 int fp_num
= breakpoint
->set
- 1;
878 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
880 DEBUG("Invalid FP Comparator number in breakpoint");
883 comparator_list
[fp_num
].used
= 0;
884 comparator_list
[fp_num
].fpcr_value
= 0;
885 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
889 /* restore original instruction (kept in target endianness) */
890 if (breakpoint
->length
== 4)
892 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
896 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
904 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
906 /* get pointers to arch-specific information */
907 armv7m_common_t
*armv7m
= target
->arch_info
;
908 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
910 if (cortex_m3
->auto_bp_type
)
912 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
915 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
917 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 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 INFO("no flash patch comparator unit available for hardware breakpoint");
930 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
933 if ((breakpoint
->length
!= 2))
935 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 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 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 DEBUG("ERROR Can not find free DWT Comparator");
997 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 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 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 WARNING("watchpoint not set");
1041 dwt_num
= watchpoint
->set
- 1;
1043 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1045 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 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 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 ERROR("JTAG failure %i",retval
);
1135 return ERROR_JTAG_DEVICE_ERROR
;
1137 /* 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 /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */
1147 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1148 instr
= ARMV7M_T_MRS(0, SYSm
);
1149 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MRS(0, SYSm
));
1150 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1151 cortex_m3_single_step_core(target
);
1152 ahbap_read_coreregister_u32(swjdp
, value
, 0);
1153 armv7m
->core_cache
->reg_list
[0].dirty
= armv7m
->core_cache
->reg_list
[0].valid
;
1154 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1155 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1156 swjdp_transaction_endcheck(swjdp
);
1157 DEBUG("load from special reg %i value 0x%x", SYSm
, *value
);
1159 else return ERROR_INVALID_ARGUMENTS
;
1164 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1168 /* get pointers to arch-specific information */
1169 armv7m_common_t
*armv7m
= target
->arch_info
;
1170 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1171 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1173 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1175 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1176 if (retval
!= ERROR_OK
)
1178 ERROR("JTAG failure %i", retval
);
1179 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1180 return ERROR_JTAG_DEVICE_ERROR
;
1182 DEBUG("write core reg %i value 0x%x", num
, value
);
1184 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1186 /* write other registers */
1187 u32 savedram
, tempr0
;
1191 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1192 instr
= ARMV7M_T_MSR(SYSm
, 0);
1193 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MSR(SYSm
, 0));
1194 ahbap_read_coreregister_u32(swjdp
, &tempr0
, 0);
1195 ahbap_write_coreregister_u32(swjdp
, value
, 0);
1196 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1197 cortex_m3_single_step_core(target
);
1198 ahbap_write_coreregister_u32(swjdp
, tempr0
, 0);
1199 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1200 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1201 swjdp_transaction_endcheck(swjdp
);
1202 DEBUG("write special reg %i value 0x%x ", SYSm
, value
);
1204 else return ERROR_INVALID_ARGUMENTS
;
1209 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1211 /* get pointers to arch-specific information */
1212 armv7m_common_t
*armv7m
= target
->arch_info
;
1213 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1214 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1216 /* sanitize arguments */
1217 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1218 return ERROR_INVALID_ARGUMENTS
;
1220 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1221 return ERROR_TARGET_UNALIGNED_ACCESS
;
1223 /* Is not optimal, autoincrement of tar should be used ( ahbap_block_read and CSW_ADDRINC_SINGLE ) */
1227 /* TODOLATER Check error return value ! */
1229 ahbap_read_buf(swjdp
, buffer
, 4 * count
, address
);
1234 ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1239 ahbap_read_buf(swjdp
, buffer
, count
, address
);
1243 ERROR("BUG: we shouldn't get here");
1250 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1252 /* get pointers to arch-specific information */
1253 armv7m_common_t
*armv7m
= target
->arch_info
;
1254 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1255 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1257 /* sanitize arguments */
1258 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1259 return ERROR_INVALID_ARGUMENTS
;
1261 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1262 return ERROR_TARGET_UNALIGNED_ACCESS
;
1267 /* TODOLATER Check error return value ! */
1269 ahbap_write_buf(swjdp
, buffer
, 4 * count
, address
);
1274 ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1279 ahbap_write_buf(swjdp
, buffer
, count
, address
);
1283 ERROR("BUG: we shouldn't get here");
1290 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1292 cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1297 void cortex_m3_build_reg_cache(target_t
*target
)
1299 armv7m_build_reg_cache(target
);
1302 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1304 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1307 /* get pointers to arch-specific information */
1308 armv7m_common_t
*armv7m
= target
->arch_info
;
1309 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1310 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1312 cortex_m3_build_reg_cache(target
);
1313 ahbap_debugport_init(swjdp
);
1315 /* Read from Device Identification Registers */
1316 target_read_u32(target
, CPUID
, &cpuid
);
1317 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1318 DEBUG("CORTEX-M3 processor detected");
1319 DEBUG("cpuid: 0x%8.8x", cpuid
);
1321 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1322 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1323 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1324 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1326 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1327 DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1331 target_read_u32(target
, FP_CTRL
, &fpcr
);
1332 cortex_m3
->auto_bp_type
= 1;
1333 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1334 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1335 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1336 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1337 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1339 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1340 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1342 DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1345 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1346 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1347 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1348 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1349 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1351 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1357 int cortex_m3_quit()
1363 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1367 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1369 *value
= (u8
)(dcrdr
>> 8);
1371 DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1373 /* write ack back to software dcc register
1374 * signify we have read data */
1375 if (dcrdr
& (1 << 0))
1378 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1384 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1386 armv7m_common_t
*armv7m
= target
->arch_info
;
1387 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1388 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1393 for (i
= 0; i
< (size
* 4); i
++)
1395 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1402 int cortex_m3_handle_target_request(void *priv
)
1404 target_t
*target
= priv
;
1405 armv7m_common_t
*armv7m
= target
->arch_info
;
1406 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1407 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1409 if (!target
->dbg_msg_enabled
)
1412 if (target
->state
== TARGET_RUNNING
)
1417 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1419 /* check if we have data */
1420 if (ctrl
& (1 << 0))
1424 /* we assume target is quick enough */
1426 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1427 request
|= (data
<< 8);
1428 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1429 request
|= (data
<< 16);
1430 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1431 request
|= (data
<< 24);
1432 target_request(target
, request
);
1439 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1441 armv7m_common_t
*armv7m
;
1442 armv7m
= &cortex_m3
->armv7m
;
1444 /* prepare JTAG information for the new target */
1445 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1446 cortex_m3
->jtag_info
.scann_size
= 4;
1448 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1449 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1450 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1451 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1453 /* initialize arch-specific breakpoint handling */
1455 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1456 cortex_m3
->arch_info
= NULL
;
1458 /* register arch-specific functions */
1459 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1461 armv7m
->pre_debug_entry
= NULL
;
1462 armv7m
->post_debug_entry
= NULL
;
1464 armv7m
->pre_restore_context
= NULL
;
1465 armv7m
->post_restore_context
= NULL
;
1467 armv7m_init_arch_info(target
, armv7m
);
1468 armv7m
->arch_info
= cortex_m3
;
1469 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1470 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1471 /* armv7m->full_context = cortex_m3_full_context; */
1473 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1478 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1479 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1482 char *variant
= NULL
;
1483 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1484 memset(cortex_m3
, 0, sizeof(*cortex_m3
));
1488 ERROR("'target cortex_m3' requires at least one additional argument");
1492 chain_pos
= strtoul(args
[3], NULL
, 0);
1497 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1498 cortex_m3_register_commands(cmd_ctx
);
1503 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1507 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)