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
,
74 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
76 .read_memory
= cortex_m3_read_memory
,
77 .write_memory
= cortex_m3_write_memory
,
78 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
79 .checksum_memory
= armv7m_checksum_memory
,
81 .run_algorithm
= armv7m_run_algorithm
,
83 .add_breakpoint
= cortex_m3_add_breakpoint
,
84 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
85 .add_watchpoint
= cortex_m3_add_watchpoint
,
86 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
88 .register_commands
= cortex_m3_register_commands
,
89 .target_command
= cortex_m3_target_command
,
90 .init_target
= cortex_m3_init_target
,
91 .quit
= cortex_m3_quit
94 int cortex_m3_clear_halt(target_t
*target
)
96 /* get pointers to arch-specific information */
97 armv7m_common_t
*armv7m
= target
->arch_info
;
98 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
99 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
101 /* Read Debug Fault Status Register */
102 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
103 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
104 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
105 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
110 int cortex_m3_single_step_core(target_t
*target
)
112 /* get pointers to arch-specific information */
113 armv7m_common_t
*armv7m
= target
->arch_info
;
114 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
115 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
117 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
118 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
119 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
120 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
122 cortex_m3_clear_halt(target
);
127 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
129 /* get pointers to arch-specific information */
130 armv7m_common_t
*armv7m
= target
->arch_info
;
131 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
132 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
136 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
137 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
138 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
139 cortex_m3_single_step_core(target
);
140 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
141 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);
160 int cortex_m3_endreset_event(target_t
*target
)
165 /* get pointers to arch-specific information */
166 armv7m_common_t
*armv7m
= target
->arch_info
;
167 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
168 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
169 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
170 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
172 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
173 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
175 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
177 /* Enable debug requests */
178 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
179 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
180 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
181 /* Enable trace and dwt */
182 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
183 /* Monitor bus faults */
184 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
187 target_write_u32(target
, FP_CTRL
, 3);
189 /* Restore FPB registers */
190 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
192 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
195 /* Restore DWT registers */
196 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
198 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
199 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
200 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
202 swjdp_transaction_endcheck(swjdp
);
204 /* We are in process context */
205 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
206 armv7m_invalidate_core_regs(target
);
210 int cortex_m3_examine_debug_reason(target_t
*target
)
212 /* get pointers to arch-specific information */
213 armv7m_common_t
*armv7m
= target
->arch_info
;
214 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
216 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
217 /* only check the debug reason if we don't know it already */
219 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
220 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
224 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
226 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
227 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
228 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
230 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
231 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
237 int cortex_m3_examine_exception_reason(target_t
*target
)
239 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
241 /* get pointers to arch-specific information */
242 armv7m_common_t
*armv7m
= target
->arch_info
;
243 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
244 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
246 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
247 switch (armv7m
->exception_number
)
251 case 3: /* Hard Fault */
252 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
253 if (except_sr
& 0x40000000)
255 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
258 case 4: /* Memory Management */
259 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
260 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
262 case 5: /* Bus Fault */
263 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
264 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
266 case 6: /* Usage Fault */
267 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
269 case 11: /* SVCall */
271 case 12: /* Debug Monitor */
272 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
274 case 14: /* PendSV */
276 case 15: /* SysTick */
282 swjdp_transaction_endcheck(swjdp
);
283 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
284 shcsr
, except_sr
, cfsr
, except_ar
);
288 int cortex_m3_debug_entry(target_t
*target
)
294 /* get pointers to arch-specific information */
295 armv7m_common_t
*armv7m
= target
->arch_info
;
296 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
297 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
300 if (armv7m
->pre_debug_entry
)
301 armv7m
->pre_debug_entry(target
);
303 cortex_m3_clear_halt(target
);
304 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
306 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
309 /* Examine target state and mode */
310 /* First load register acessible through core debug port*/
311 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
313 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
314 armv7m
->read_core_reg(target
, i
);
317 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
319 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
322 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
323 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
326 /* Now we can load SP core registers */
327 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
329 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
330 armv7m
->read_core_reg(target
, i
);
333 /* Are we in an exception handler */
334 armv7m
->core_mode
= (xPSR
& 0x1FF) ? ARMV7M_MODE_HANDLER
: ARMV7M_MODE_THREAD
;
335 armv7m
->exception_number
= xPSR
& 0x1FF;
336 if (armv7m
->exception_number
)
338 cortex_m3_examine_exception_reason(target
);
341 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings
[armv7m
->core_mode
], \
342 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
344 if (armv7m
->post_debug_entry
)
345 armv7m
->post_debug_entry(target
);
350 int cortex_m3_poll(target_t
*target
)
353 u32 prev_target_state
= target
->state
;
355 /* get pointers to arch-specific information */
356 armv7m_common_t
*armv7m
= target
->arch_info
;
357 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
358 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
360 /* Read from Debug Halting Control and Status Register */
361 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
362 if (retval
!= ERROR_OK
)
364 target
->state
= TARGET_UNKNOWN
;
368 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
370 /* check if still in reset */
371 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
373 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
375 target
->state
= TARGET_RESET
;
380 if (target
->state
== TARGET_RESET
)
382 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
383 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
384 cortex_m3_endreset_event(target
);
385 target
->state
= TARGET_RUNNING
;
386 prev_target_state
= TARGET_RUNNING
;
389 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
391 target
->state
= TARGET_HALTED
;
393 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
395 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
398 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
400 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
403 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
406 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
411 if (cortex_m3->dcb_dhcsr & S_SLEEP)
412 target->state = TARGET_SLEEP;
415 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
416 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
417 LOG_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
]);
421 int cortex_m3_halt(target_t
*target
)
423 /* get pointers to arch-specific information */
424 armv7m_common_t
*armv7m
= target
->arch_info
;
425 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
426 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
428 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
430 if (target
->state
== TARGET_HALTED
)
432 LOG_WARNING("target was already halted");
436 if (target
->state
== TARGET_UNKNOWN
)
438 LOG_WARNING("target was in unknown state when halt was requested");
441 if (target
->state
== TARGET_RESET
)
443 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
445 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
446 return ERROR_TARGET_FAILURE
;
450 /* we came here in a reset_halt or reset_init sequence
451 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
453 target
->debug_reason
= DBG_REASON_DBGRQ
;
459 /* Write to Debug Halting Control and Status Register */
460 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
462 target
->debug_reason
= DBG_REASON_DBGRQ
;
467 int cortex_m3_soft_reset_halt(struct target_s
*target
)
469 /* get pointers to arch-specific information */
470 armv7m_common_t
*armv7m
= target
->arch_info
;
471 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
472 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
474 int retval
, timeout
= 0;
476 /* Check that we are using process_context, or change and print warning */
477 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
479 LOG_DEBUG("Changing to process contex registers");
480 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
483 /* Enter debug state on reset, cf. end_reset_event() */
484 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
486 /* Request a reset */
487 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
488 target
->state
= TARGET_RESET
;
490 /* registers are now invalid */
491 armv7m_invalidate_core_regs(target
);
493 while (timeout
< 100)
495 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
496 if (retval
== ERROR_OK
)
498 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
499 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
501 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
502 cortex_m3_poll(target
);
506 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
515 int cortex_m3_prepare_reset_halt(struct target_s
*target
)
517 armv7m_common_t
*armv7m
= target
->arch_info
;
518 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
519 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
520 u32 dcb_demcr
, dcb_dhcsr
;
522 /* Enable debug requests */
523 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
524 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
525 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
527 /* Enter debug state on reset, cf. end_reset_event() */
528 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
530 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
531 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
532 LOG_DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr
, dcb_demcr
);
537 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
539 /* get pointers to arch-specific information */
540 armv7m_common_t
*armv7m
= target
->arch_info
;
541 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
542 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
543 breakpoint_t
*breakpoint
= NULL
;
544 u32 dcb_dhcsr
, resume_pc
;
546 if (target
->state
!= TARGET_HALTED
)
548 LOG_WARNING("target not halted");
549 return ERROR_TARGET_NOT_HALTED
;
552 if (!debug_execution
)
554 /* Check that we are using process_context, or change and print warning */
555 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
557 LOG_DEBUG("Incorrect context in resume");
558 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
561 target_free_all_working_areas(target
);
562 cortex_m3_enable_breakpoints(target
);
563 cortex_m3_enable_watchpoints(target
);
565 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
568 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
571 /* Check that we are using debug_context, or change and print warning */
572 if (armv7m_get_context(target
) != ARMV7M_DEBUG_CONTEXT
)
574 LOG_DEBUG("Incorrect context in debug_exec resume");
575 armv7m_use_context(target
, ARMV7M_DEBUG_CONTEXT
);
577 /* Disable interrupts */
579 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
580 This is probably the same inssue as Cortex-M3 Errata 377493:
581 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
583 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
584 /* Make sure we are in Thumb mode */
585 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
586 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
589 /* current = 1: continue on current pc, otherwise continue at <address> */
592 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
593 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
594 armv7m
->core_cache
->reg_list
[15].valid
= 1;
597 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
599 armv7m_restore_context(target
);
601 /* the front-end may request us not to handle breakpoints */
602 if (handle_breakpoints
)
604 /* Single step past breakpoint at current address */
605 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
607 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
608 cortex_m3_unset_breakpoint(target
, breakpoint
);
609 cortex_m3_single_step_core(target
);
610 cortex_m3_set_breakpoint(target
, breakpoint
);
614 /* Set/Clear C_MASKINTS in a separate operation */
615 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
616 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
619 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
620 target
->debug_reason
= DBG_REASON_NOTHALTED
;
622 /* registers are now invalid */
623 armv7m_invalidate_core_regs(target
);
624 if (!debug_execution
)
626 target
->state
= TARGET_RUNNING
;
627 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
628 LOG_DEBUG("target resumed at 0x%x",resume_pc
);
632 target
->state
= TARGET_DEBUG_RUNNING
;
633 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
634 LOG_DEBUG("target debug resumed at 0x%x",resume_pc
);
640 /* int irqstepcount=0; */
641 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
643 /* get pointers to arch-specific information */
644 armv7m_common_t
*armv7m
= target
->arch_info
;
645 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
646 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
647 breakpoint_t
*breakpoint
= NULL
;
649 if (target
->state
!= TARGET_HALTED
)
651 LOG_WARNING("target not halted");
652 return ERROR_TARGET_NOT_HALTED
;
655 /* Check that we are using process_context, or change and print warning */
656 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
658 LOG_WARNING("Incorrect context in step, must be process");
659 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
662 /* current = 1: continue on current pc, otherwise continue at <address> */
664 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
666 /* the front-end may request us not to handle breakpoints */
667 if (handle_breakpoints
)
668 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
669 cortex_m3_unset_breakpoint(target
, breakpoint
);
671 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
673 armv7m_restore_context(target
);
675 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
677 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
678 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
679 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
680 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
682 /* If we run in process context then registers are now invalid */
683 if (armv7m_get_context(target
) == ARMV7M_PROCESS_CONTEXT
)
684 armv7m_invalidate_core_regs(target
);
687 cortex_m3_set_breakpoint(target
, breakpoint
);
689 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
691 cortex_m3_debug_entry(target
);
692 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
694 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
698 int cortex_m3_assert_reset(target_t
*target
)
700 armv7m_common_t
*armv7m
= target
->arch_info
;
701 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
702 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
705 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
707 if (!(jtag_reset_config
& RESET_HAS_SRST
))
709 LOG_ERROR("Can't assert SRST");
712 /* FIX!!! should this be removed as we're asserting trst anyway? */
713 if ((retval
=cortex_m3_prepare_reset_halt(target
))!=ERROR_OK
)
716 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
718 if (target
->reset_mode
== RESET_RUN
)
720 /* Set/Clear C_MASKINTS in a separate operation */
721 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
722 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
724 cortex_m3_clear_halt(target
);
726 /* Enter debug state on reset, cf. end_reset_event() */
727 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
728 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
731 if (target
->state
== TARGET_HALTED
|| target
->state
== TARGET_UNKNOWN
)
733 /* assert SRST and TRST */
734 /* system would get ouf sync if we didn't reset test-logic, too */
735 jtag_add_reset(1, 1);
736 jtag_add_sleep(5000);
739 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
741 jtag_add_reset(1, 1);
744 jtag_add_reset(0, 1);
747 target
->state
= TARGET_RESET
;
748 jtag_add_sleep(50000);
751 if ((target
->reset_mode
==RESET_HALT
)||(target
->reset_mode
==RESET_INIT
))
753 cortex_m3_halt(target
);
756 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
757 armv7m_invalidate_core_regs(target
);
762 int cortex_m3_deassert_reset(target_t
*target
)
764 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
766 /* deassert reset lines */
767 jtag_add_reset(0, 0);
772 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
)
777 void cortex_m3_enable_breakpoints(struct target_s
*target
)
779 breakpoint_t
*breakpoint
= target
->breakpoints
;
781 /* set any pending breakpoints */
784 if (breakpoint
->set
== 0)
785 cortex_m3_set_breakpoint(target
, breakpoint
);
786 breakpoint
= breakpoint
->next
;
790 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
795 /* get pointers to arch-specific information */
796 armv7m_common_t
*armv7m
= target
->arch_info
;
797 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
799 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
803 LOG_WARNING("breakpoint already set");
807 if (cortex_m3
->auto_bp_type
)
809 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
812 if (breakpoint
->type
== BKPT_HARD
)
814 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
816 if (fp_num
>= cortex_m3
->fp_num_code
)
818 LOG_DEBUG("ERROR Can not find free FP Comparator");
819 LOG_WARNING("ERROR Can not find free FP Comparator");
822 breakpoint
->set
= fp_num
+ 1;
823 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
824 comparator_list
[fp_num
].used
= 1;
825 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
826 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
827 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
829 else if (breakpoint
->type
== BKPT_SOFT
)
832 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
833 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
834 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
835 breakpoint
->set
= 0x11; /* Any nice value but 0 */
841 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
843 /* get pointers to arch-specific information */
844 armv7m_common_t
*armv7m
= target
->arch_info
;
845 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
846 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
848 if (!breakpoint
->set
)
850 LOG_WARNING("breakpoint not set");
854 if (breakpoint
->type
== BKPT_HARD
)
856 int fp_num
= breakpoint
->set
- 1;
857 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
859 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
862 comparator_list
[fp_num
].used
= 0;
863 comparator_list
[fp_num
].fpcr_value
= 0;
864 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
868 /* restore original instruction (kept in target endianness) */
869 if (breakpoint
->length
== 4)
871 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
875 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
883 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
885 /* get pointers to arch-specific information */
886 armv7m_common_t
*armv7m
= target
->arch_info
;
887 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
889 if (cortex_m3
->auto_bp_type
)
891 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
894 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
896 LOG_INFO("flash patch comparator requested outside code memory region");
897 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
900 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
902 LOG_INFO("soft breakpoint requested in code (flash) memory region");
903 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
906 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
908 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
909 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
912 if ((breakpoint
->length
!= 2))
914 LOG_INFO("only breakpoints of two bytes length supported");
915 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
918 if (breakpoint
->type
== BKPT_HARD
)
919 cortex_m3
->fp_code_available
--;
920 cortex_m3_set_breakpoint(target
, breakpoint
);
925 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
927 /* get pointers to arch-specific information */
928 armv7m_common_t
*armv7m
= target
->arch_info
;
929 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
931 if (target
->state
!= TARGET_HALTED
)
933 LOG_WARNING("target not halted");
934 return ERROR_TARGET_NOT_HALTED
;
937 if (cortex_m3
->auto_bp_type
)
939 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
944 cortex_m3_unset_breakpoint(target
, breakpoint
);
947 if (breakpoint
->type
== BKPT_HARD
)
948 cortex_m3
->fp_code_available
++;
953 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
958 /* get pointers to arch-specific information */
959 armv7m_common_t
*armv7m
= target
->arch_info
;
960 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
961 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
965 LOG_WARNING("watchpoint already set");
969 if (watchpoint
->mask
== 0xffffffffu
)
971 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
973 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
975 LOG_DEBUG("ERROR Can not find free DWT Comparator");
976 LOG_WARNING("ERROR Can not find free DWT Comparator");
979 watchpoint
->set
= dwt_num
+ 1;
981 temp
= watchpoint
->length
;
987 comparator_list
[dwt_num
].used
= 1;
988 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
989 comparator_list
[dwt_num
].mask
= mask
;
990 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
991 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
992 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
993 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
994 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
);
998 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1006 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1008 /* get pointers to arch-specific information */
1009 armv7m_common_t
*armv7m
= target
->arch_info
;
1010 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1011 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1014 if (!watchpoint
->set
)
1016 LOG_WARNING("watchpoint not set");
1020 dwt_num
= watchpoint
->set
- 1;
1022 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1024 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1027 comparator_list
[dwt_num
].used
= 0;
1028 comparator_list
[dwt_num
].function
= 0;
1029 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1031 watchpoint
->set
= 0;
1036 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1038 /* get pointers to arch-specific information */
1039 armv7m_common_t
*armv7m
= target
->arch_info
;
1040 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1042 if (target
->state
!= TARGET_HALTED
)
1044 LOG_WARNING("target not halted");
1045 return ERROR_TARGET_NOT_HALTED
;
1048 if (cortex_m3
->dwt_comp_available
< 1)
1050 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1053 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1055 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1058 cortex_m3
->dwt_comp_available
--;
1063 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1065 /* get pointers to arch-specific information */
1066 armv7m_common_t
*armv7m
= target
->arch_info
;
1067 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1069 if (target
->state
!= TARGET_HALTED
)
1071 LOG_WARNING("target not halted");
1072 return ERROR_TARGET_NOT_HALTED
;
1075 if (watchpoint
->set
)
1077 cortex_m3_unset_watchpoint(target
, watchpoint
);
1080 cortex_m3
->dwt_comp_available
++;
1085 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1087 watchpoint_t
*watchpoint
= target
->watchpoints
;
1089 /* set any pending watchpoints */
1092 if (watchpoint
->set
== 0)
1093 cortex_m3_set_watchpoint(target
, watchpoint
);
1094 watchpoint
= watchpoint
->next
;
1098 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1101 /* get pointers to arch-specific information */
1102 armv7m_common_t
*armv7m
= target
->arch_info
;
1103 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1104 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1106 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1108 /* read a normal core register */
1109 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1111 if (retval
!= ERROR_OK
)
1113 LOG_ERROR("JTAG failure %i",retval
);
1114 return ERROR_JTAG_DEVICE_ERROR
;
1116 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1118 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1120 /* read other registers */
1126 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1127 instr
= ARMV7M_T_MRS(0, SYSm
);
1128 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MRS(0, SYSm
));
1129 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1130 cortex_m3_single_step_core(target
);
1131 ahbap_read_coreregister_u32(swjdp
, value
, 0);
1132 armv7m
->core_cache
->reg_list
[0].dirty
= armv7m
->core_cache
->reg_list
[0].valid
;
1133 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1134 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1135 swjdp_transaction_endcheck(swjdp
);
1136 LOG_DEBUG("load from special reg %i value 0x%x", SYSm
, *value
);
1140 return ERROR_INVALID_ARGUMENTS
;
1146 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1150 /* get pointers to arch-specific information */
1151 armv7m_common_t
*armv7m
= target
->arch_info
;
1152 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1153 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1155 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1157 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1158 if (retval
!= ERROR_OK
)
1160 LOG_ERROR("JTAG failure %i", retval
);
1161 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1162 return ERROR_JTAG_DEVICE_ERROR
;
1164 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1166 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1168 /* write other registers */
1169 u32 savedram
, tempr0
;
1174 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1175 instr
= ARMV7M_T_MSR(SYSm
, 0);
1176 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MSR(SYSm
, 0));
1177 ahbap_read_coreregister_u32(swjdp
, &tempr0
, 0);
1178 ahbap_write_coreregister_u32(swjdp
, value
, 0);
1179 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1180 cortex_m3_single_step_core(target
);
1181 ahbap_write_coreregister_u32(swjdp
, tempr0
, 0);
1182 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1183 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1184 swjdp_transaction_endcheck(swjdp
);
1185 LOG_DEBUG("write special reg %i value 0x%x ", SYSm
, value
);
1189 return ERROR_INVALID_ARGUMENTS
;
1195 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1197 /* get pointers to arch-specific information */
1198 armv7m_common_t
*armv7m
= target
->arch_info
;
1199 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1200 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1203 /* sanitize arguments */
1204 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1205 return ERROR_INVALID_ARGUMENTS
;
1207 /* cortex_m3 handles unaligned memory access */
1212 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1215 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1218 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1221 LOG_ERROR("BUG: we shouldn't get here");
1228 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1230 /* get pointers to arch-specific information */
1231 armv7m_common_t
*armv7m
= target
->arch_info
;
1232 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1233 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1236 /* sanitize arguments */
1237 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1238 return ERROR_INVALID_ARGUMENTS
;
1243 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1246 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1249 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1252 LOG_ERROR("BUG: we shouldn't get here");
1259 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1261 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1264 void cortex_m3_build_reg_cache(target_t
*target
)
1266 armv7m_build_reg_cache(target
);
1269 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1271 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1274 /* get pointers to arch-specific information */
1275 armv7m_common_t
*armv7m
= target
->arch_info
;
1276 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1277 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1279 cortex_m3_build_reg_cache(target
);
1280 ahbap_debugport_init(swjdp
);
1282 /* Read from Device Identification Registers */
1283 target_read_u32(target
, CPUID
, &cpuid
);
1284 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1285 LOG_DEBUG("CORTEX-M3 processor detected");
1286 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1288 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1289 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1290 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1291 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1293 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1294 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1298 target_read_u32(target
, FP_CTRL
, &fpcr
);
1299 cortex_m3
->auto_bp_type
= 1;
1300 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1301 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1302 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1303 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1304 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1306 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1307 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1309 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1312 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1313 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1314 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1315 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1316 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1318 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1324 int cortex_m3_quit()
1330 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1334 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1336 *value
= (u8
)(dcrdr
>> 8);
1338 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1340 /* write ack back to software dcc register
1341 * signify we have read data */
1342 if (dcrdr
& (1 << 0))
1345 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1351 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1353 armv7m_common_t
*armv7m
= target
->arch_info
;
1354 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1355 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1360 for (i
= 0; i
< (size
* 4); i
++)
1362 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1369 int cortex_m3_handle_target_request(void *priv
)
1371 target_t
*target
= priv
;
1372 armv7m_common_t
*armv7m
= target
->arch_info
;
1373 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1374 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1376 if (!target
->dbg_msg_enabled
)
1379 if (target
->state
== TARGET_RUNNING
)
1384 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1386 /* check if we have data */
1387 if (ctrl
& (1 << 0))
1391 /* we assume target is quick enough */
1393 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1394 request
|= (data
<< 8);
1395 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1396 request
|= (data
<< 16);
1397 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1398 request
|= (data
<< 24);
1399 target_request(target
, request
);
1406 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1408 armv7m_common_t
*armv7m
;
1409 armv7m
= &cortex_m3
->armv7m
;
1411 /* prepare JTAG information for the new target */
1412 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1413 cortex_m3
->jtag_info
.scann_size
= 4;
1415 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1416 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1417 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1418 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1420 /* initialize arch-specific breakpoint handling */
1422 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1423 cortex_m3
->arch_info
= NULL
;
1425 /* register arch-specific functions */
1426 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1428 armv7m
->pre_debug_entry
= NULL
;
1429 armv7m
->post_debug_entry
= NULL
;
1431 armv7m
->pre_restore_context
= NULL
;
1432 armv7m
->post_restore_context
= NULL
;
1434 armv7m_init_arch_info(target
, armv7m
);
1435 armv7m
->arch_info
= cortex_m3
;
1436 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1437 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1439 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1444 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1445 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1448 char *variant
= NULL
;
1449 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1450 memset(cortex_m3
, 0, sizeof(*cortex_m3
));
1454 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1458 chain_pos
= strtoul(args
[3], NULL
, 0);
1463 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1464 cortex_m3_register_commands(cmd_ctx
);
1469 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1473 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)