1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * Copyright (C) 2006 by Magnus Lundin *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
26 #include "replacements.h"
28 #include "cortex_m3.h"
33 #include "target_request.h"
42 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
44 /* forward declarations */
45 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
);
46 void cortex_m3_enable_breakpoints(struct target_s
*target
);
47 void cortex_m3_enable_watchpoints(struct target_s
*target
);
48 void cortex_m3_disable_bkpts_and_wpts(struct target_s
*target
);
49 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
50 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
52 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
53 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
54 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
56 target_type_t cortexm3_target
=
60 .poll
= cortex_m3_poll
,
61 .arch_state
= armv7m_arch_state
,
63 .target_request_data
= cortex_m3_target_request_data
,
65 .halt
= cortex_m3_halt
,
66 .resume
= cortex_m3_resume
,
67 .step
= cortex_m3_step
,
69 .assert_reset
= cortex_m3_assert_reset
,
70 .deassert_reset
= cortex_m3_deassert_reset
,
71 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
72 .prepare_reset_halt
= cortex_m3_prepare_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 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
);
146 /* Enable interrupts */
147 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
149 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
152 /* Disable interrupts */
153 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
155 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
158 int cortex_m3_endreset_event(target_t
*target
)
163 /* get pointers to arch-specific information */
164 armv7m_common_t
*armv7m
= target
->arch_info
;
165 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
166 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
167 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
168 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
170 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
171 DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
173 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
175 /* Enable debug requests */
176 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
177 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
178 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
179 /* Enable trace and dwt */
180 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
181 /* Monitor bus faults */
182 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
185 target_write_u32(target
, FP_CTRL
, 3);
187 /* Restore FPB registers */
188 for ( i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
190 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
193 /* Restore DWT registers */
194 for ( i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
196 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
197 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
198 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
200 swjdp_transaction_endcheck(swjdp
);
202 /* Make sure working_areas are all free */
203 target_free_all_working_areas(target
);
205 /* We are in process context */
206 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
207 armv7m_invalidate_core_regs(target
);
211 int cortex_m3_examine_debug_reason(target_t
*target
)
213 /* get pointers to arch-specific information */
214 armv7m_common_t
*armv7m
= target
->arch_info
;
215 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
217 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
218 /* only check the debug reason if we don't know it already */
220 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
221 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
225 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
227 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
228 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
229 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
231 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
232 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
238 int cortex_m3_examine_exception_reason(target_t
*target
)
240 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
242 /* get pointers to arch-specific information */
243 armv7m_common_t
*armv7m
= target
->arch_info
;
244 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
245 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
247 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
248 switch (armv7m
->exception_number
)
252 case 3: /* Hard Fault */
253 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
254 if (except_sr
& 0x40000000)
256 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
259 case 4: /* Memory Management */
260 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
261 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
263 case 5: /* Bus Fault */
264 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
265 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
267 case 6: /* Usage Fault */
268 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
270 case 11: /* SVCall */
272 case 12: /* Debug Monitor */
273 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
275 case 14: /* PendSV */
277 case 15: /* SysTick */
283 swjdp_transaction_endcheck(swjdp
);
284 DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
285 shcsr
, except_sr
, cfsr
, except_ar
);
289 int cortex_m3_debug_entry(target_t
*target
)
295 /* get pointers to arch-specific information */
296 armv7m_common_t
*armv7m
= target
->arch_info
;
297 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
298 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
301 if (armv7m
->pre_debug_entry
)
302 armv7m
->pre_debug_entry(target
);
304 cortex_m3_clear_halt(target
);
305 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
307 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
310 /* Examine target state and mode */
311 /* First load register acessible through core debug port*/
312 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
314 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
315 armv7m
->read_core_reg(target
, i
);
318 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
320 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
323 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
324 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
328 /* Now we can load SP core registers */
329 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
331 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
332 armv7m
->read_core_reg(target
, i
);
335 /* Are we in an exception handler */
336 armv7m
->core_mode
= (xPSR
& 0x1FF) ? ARMV7M_MODE_HANDLER
: ARMV7M_MODE_THREAD
;
337 armv7m
->exception_number
= xPSR
& 0x1FF;
338 if (armv7m
->exception_number
)
340 cortex_m3_examine_exception_reason(target
);
343 DEBUG("entered debug state at PC 0x%x, target->state: %s ", *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
345 if (armv7m
->post_debug_entry
)
346 armv7m
->post_debug_entry(target
);
351 int cortex_m3_poll(target_t
*target
)
354 u32 prev_target_state
= target
->state
;
356 /* get pointers to arch-specific information */
357 armv7m_common_t
*armv7m
= target
->arch_info
;
358 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
359 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
361 /* Read from Debug Halting Control and Status Register */
362 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
363 if (retval
!= ERROR_OK
)
365 target
->state
= TARGET_UNKNOWN
;
369 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
371 /* check if still in reset */
372 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
374 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
376 target
->state
= TARGET_RESET
;
381 if (target
->state
== TARGET_RESET
)
383 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
384 DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
385 cortex_m3_endreset_event(target
);
386 target
->state
= TARGET_RUNNING
;
387 prev_target_state
= TARGET_RUNNING
;
390 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
392 target
->state
= TARGET_HALTED
;
394 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
396 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
399 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
401 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
404 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
407 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
412 if (cortex_m3->dcb_dhcsr & S_SLEEP)
413 target->state = TARGET_SLEEP;
416 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
417 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
418 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
]);
422 int cortex_m3_halt(target_t
*target
)
424 /* get pointers to arch-specific information */
425 armv7m_common_t
*armv7m
= target
->arch_info
;
426 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
427 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
429 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
431 if (target
->state
== TARGET_HALTED
)
433 WARNING("target was already halted");
434 return ERROR_TARGET_ALREADY_HALTED
;
437 if (target
->state
== TARGET_UNKNOWN
)
439 WARNING("target was in unknown state when halt was requested");
442 if (target
->state
== TARGET_RESET
)
444 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
446 ERROR("can't request a halt while in reset if nSRST pulls nTRST");
447 return ERROR_TARGET_FAILURE
;
451 /* we came here in a reset_halt or reset_init sequence
452 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
454 target
->debug_reason
= DBG_REASON_DBGRQ
;
460 /* Write to Debug Halting Control and Status Register */
461 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
463 target
->debug_reason
= DBG_REASON_DBGRQ
;
468 int cortex_m3_soft_reset_halt(struct target_s
*target
)
470 /* get pointers to arch-specific information */
471 armv7m_common_t
*armv7m
= target
->arch_info
;
472 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
473 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
475 int retval
, timeout
= 0;
477 /* Check that we are using process_context, or change and print warning */
478 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
480 DEBUG("Changing to process contex registers");
481 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
484 /* Enter debug state on reset, cf. end_reset_event() */
485 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
487 /* Request a reset */
488 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
489 target
->state
= TARGET_RESET
;
491 /* registers are now invalid */
492 armv7m_invalidate_core_regs(target
);
494 while (timeout
< 100)
496 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
497 if (retval
== ERROR_OK
)
499 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
500 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
502 DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
503 cortex_m3_poll(target
);
507 DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
516 int cortex_m3_prepare_reset_halt(struct target_s
*target
)
518 armv7m_common_t
*armv7m
= target
->arch_info
;
519 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
520 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
521 u32 dcb_demcr
, dcb_dhcsr
;
523 /* Enable debug requests */
524 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
525 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
526 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
528 /* Enter debug state on reset, cf. end_reset_event() */
529 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
531 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
532 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
533 DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr
, dcb_demcr
);
538 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
540 /* get pointers to arch-specific information */
541 armv7m_common_t
*armv7m
= target
->arch_info
;
542 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
543 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
544 breakpoint_t
*breakpoint
= NULL
;
545 u32 dcb_dhcsr
, resume_pc
;
547 if (target
->state
!= TARGET_HALTED
)
549 WARNING("target not halted");
550 return ERROR_TARGET_NOT_HALTED
;
553 if (!debug_execution
)
555 /* Check that we are using process_context, or change and print warning */
556 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
558 WARNING("Incorrect context in resume");
559 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
562 target_free_all_working_areas(target
);
563 cortex_m3_enable_breakpoints(target
);
564 cortex_m3_enable_watchpoints(target
);
566 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
569 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
572 /* Check that we are using debug_context, or change and print warning */
573 if (armv7m_get_context(target
) != ARMV7M_DEBUG_CONTEXT
)
575 WARNING("Incorrect context in debug_exec resume");
576 armv7m_use_context(target
, ARMV7M_DEBUG_CONTEXT
);
578 /* Disable interrupts */
580 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
581 This is probably the same inssue as Cortex-M3 Errata 377493:
582 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
584 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
585 /* Make sure we are in Thumb mode */
586 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
587 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
590 /* current = 1: continue on current pc, otherwise continue at <address> */
593 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
594 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
595 armv7m
->core_cache
->reg_list
[15].valid
= 1;
598 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
600 armv7m_restore_context(target
);
602 /* the front-end may request us not to handle breakpoints */
603 if (handle_breakpoints
)
605 /* Single step past breakpoint at current address */
606 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
608 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
609 cortex_m3_unset_breakpoint(target
, breakpoint
);
610 cortex_m3_single_step_core(target
);
611 cortex_m3_set_breakpoint(target
, breakpoint
);
615 /* Set/Clear C_MASKINTS in a separate operation */
616 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
617 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
620 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
621 target
->debug_reason
= DBG_REASON_NOTHALTED
;
623 /* registers are now invalid */
624 armv7m_invalidate_core_regs(target
);
625 if (!debug_execution
)
627 target
->state
= TARGET_RUNNING
;
628 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
629 DEBUG("target resumed at 0x%x",resume_pc
);
633 target
->state
= TARGET_DEBUG_RUNNING
;
634 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
635 DEBUG("target debug resumed at 0x%x",resume_pc
);
641 //int irqstepcount=0;
642 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
644 /* get pointers to arch-specific information */
645 armv7m_common_t
*armv7m
= target
->arch_info
;
646 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
647 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
648 breakpoint_t
*breakpoint
= NULL
;
650 if (target
->state
!= TARGET_HALTED
)
652 WARNING("target not halted");
653 return ERROR_TARGET_NOT_HALTED
;
656 /* Check that we are using process_context, or change and print warning */
657 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
659 WARNING("Incorrect context in step, must be process");
660 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
663 /* current = 1: continue on current pc, otherwise continue at <address> */
665 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
667 /* the front-end may request us not to handle breakpoints */
668 if (handle_breakpoints
)
669 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
670 cortex_m3_unset_breakpoint(target
, breakpoint
);
672 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
674 armv7m_restore_context(target
);
676 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
678 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
679 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
680 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
681 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
683 /* If we run in process context then registers are now invalid */
684 if (armv7m_get_context(target
) == ARMV7M_PROCESS_CONTEXT
)
685 armv7m_invalidate_core_regs(target
);
688 cortex_m3_set_breakpoint(target
, breakpoint
);
690 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
692 cortex_m3_debug_entry(target
);
693 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
695 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
699 int cortex_m3_assert_reset(target_t
*target
)
702 armv7m_common_t
*armv7m
= target
->arch_info
;
703 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
704 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
706 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
708 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
710 if (target
->reset_mode
== RESET_RUN
)
712 /* Set/Clear C_MASKINTS in a separate operation */
713 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
714 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
716 cortex_m3_clear_halt(target
);
718 /* Enter debug state on reset, cf. end_reset_event() */
719 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
720 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
723 if (target
->state
== TARGET_HALTED
|| target
->state
== TARGET_UNKNOWN
)
725 /* assert SRST and TRST */
726 /* system would get ouf sync if we didn't reset test-logic, too */
727 if ((retval
= jtag_add_reset(1, 1)) != ERROR_OK
)
729 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
731 WARNING("can't assert srst");
736 ERROR("unknown error");
740 jtag_add_sleep(5000);
741 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
743 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
745 WARNING("srst resets test logic, too");
746 retval
= jtag_add_reset(1, 1);
752 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
754 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
756 WARNING("srst resets test logic, too");
757 retval
= jtag_add_reset(1, 1);
760 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
762 WARNING("can't assert srsrt");
765 else if (retval
!= ERROR_OK
)
767 ERROR("unknown error");
773 target
->state
= TARGET_RESET
;
774 jtag_add_sleep(50000);
776 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
777 armv7m_invalidate_core_regs(target
);
782 int cortex_m3_deassert_reset(target_t
*target
)
784 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
786 /* deassert reset lines */
787 jtag_add_reset(0, 0);
792 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
)
797 void cortex_m3_enable_breakpoints(struct target_s
*target
)
799 breakpoint_t
*breakpoint
= target
->breakpoints
;
801 /* set any pending breakpoints */
804 if (breakpoint
->set
== 0)
805 cortex_m3_set_breakpoint(target
, breakpoint
);
806 breakpoint
= breakpoint
->next
;
810 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
815 /* get pointers to arch-specific information */
816 armv7m_common_t
*armv7m
= target
->arch_info
;
817 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
819 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
823 WARNING("breakpoint already set");
827 if (cortex_m3
->auto_bp_type
)
829 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
832 if (breakpoint
->type
== BKPT_HARD
)
834 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
836 if (fp_num
>= cortex_m3
->fp_num_code
)
838 DEBUG("ERROR Can not find free FP Comparator");
839 WARNING("ERROR Can not find free FP Comparator");
842 breakpoint
->set
= fp_num
+ 1;
843 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
844 comparator_list
[fp_num
].used
= 1;
845 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
846 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
847 DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
849 else if (breakpoint
->type
== BKPT_SOFT
)
852 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
853 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
854 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
855 breakpoint
->set
= 0x11; /* Any nice value but 0 */
861 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
863 /* get pointers to arch-specific information */
864 armv7m_common_t
*armv7m
= target
->arch_info
;
865 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
866 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
868 if (!breakpoint
->set
)
870 WARNING("breakpoint not set");
874 if (breakpoint
->type
== BKPT_HARD
)
876 int fp_num
= breakpoint
->set
- 1;
877 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
879 DEBUG("Invalid FP Comparator number in breakpoint");
882 comparator_list
[fp_num
].used
= 0;
883 comparator_list
[fp_num
].fpcr_value
= 0;
884 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
888 /* restore original instruction (kept in target endianness) */
889 if (breakpoint
->length
== 4)
891 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
895 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
903 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
905 /* get pointers to arch-specific information */
906 armv7m_common_t
*armv7m
= target
->arch_info
;
907 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
909 if (cortex_m3
->auto_bp_type
)
911 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
914 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
916 INFO("flash patch comparator requested outside code memory region");
917 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
920 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
922 INFO("soft breakpoint requested in code (flash) memory region");
923 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
926 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
928 INFO("no flash patch comparator unit available for hardware breakpoint");
929 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
932 if ((breakpoint
->length
!= 2))
934 INFO("only breakpoints of two bytes length supported");
935 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
938 if (breakpoint
->type
== BKPT_HARD
)
939 cortex_m3
->fp_code_available
--;
940 cortex_m3_set_breakpoint(target
, breakpoint
);
945 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
947 /* get pointers to arch-specific information */
948 armv7m_common_t
*armv7m
= target
->arch_info
;
949 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
951 if (target
->state
!= TARGET_HALTED
)
953 WARNING("target not halted");
954 return ERROR_TARGET_NOT_HALTED
;
957 if (cortex_m3
->auto_bp_type
)
959 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
964 cortex_m3_unset_breakpoint(target
, breakpoint
);
967 if (breakpoint
->type
== BKPT_HARD
)
968 cortex_m3
->fp_code_available
++;
973 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
978 /* get pointers to arch-specific information */
979 armv7m_common_t
*armv7m
= target
->arch_info
;
980 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
981 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
985 WARNING("watchpoint already set");
989 if (watchpoint
->mask
== 0xffffffffu
)
991 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
993 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
995 DEBUG("ERROR Can not find free DWT Comparator");
996 WARNING("ERROR Can not find free DWT Comparator");
999 watchpoint
->set
= dwt_num
+ 1;
1001 temp
= watchpoint
->length
;
1007 comparator_list
[dwt_num
].used
= 1;
1008 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1009 comparator_list
[dwt_num
].mask
= mask
;
1010 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1011 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1012 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1013 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1014 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
);
1018 WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1026 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1028 /* get pointers to arch-specific information */
1029 armv7m_common_t
*armv7m
= target
->arch_info
;
1030 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1031 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1034 if (!watchpoint
->set
)
1036 WARNING("watchpoint not set");
1040 dwt_num
= watchpoint
->set
- 1;
1042 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1044 DEBUG("Invalid DWT Comparator number in watchpoint");
1047 comparator_list
[dwt_num
].used
= 0;
1048 comparator_list
[dwt_num
].function
= 0;
1049 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1051 watchpoint
->set
= 0;
1056 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1058 /* get pointers to arch-specific information */
1059 armv7m_common_t
*armv7m
= target
->arch_info
;
1060 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1062 if (target
->state
!= TARGET_HALTED
)
1064 WARNING("target not halted");
1065 return ERROR_TARGET_NOT_HALTED
;
1068 if (cortex_m3
->dwt_comp_available
< 1)
1070 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1073 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1075 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1078 cortex_m3
->dwt_comp_available
--;
1083 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1085 /* get pointers to arch-specific information */
1086 armv7m_common_t
*armv7m
= target
->arch_info
;
1087 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1089 if (target
->state
!= TARGET_HALTED
)
1091 WARNING("target not halted");
1092 return ERROR_TARGET_NOT_HALTED
;
1095 if (watchpoint
->set
)
1097 cortex_m3_unset_watchpoint(target
, watchpoint
);
1100 cortex_m3
->dwt_comp_available
++;
1105 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1107 watchpoint_t
*watchpoint
= target
->watchpoints
;
1109 /* set any pending watchpoints */
1112 if (watchpoint
->set
== 0)
1113 cortex_m3_set_watchpoint(target
, watchpoint
);
1114 watchpoint
= watchpoint
->next
;
1118 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1121 /* get pointers to arch-specific information */
1122 armv7m_common_t
*armv7m
= target
->arch_info
;
1123 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1124 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1126 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1128 /* read a normal core register */
1129 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1131 if (retval
!= ERROR_OK
)
1133 ERROR("JTAG failure %i",retval
);
1134 return ERROR_JTAG_DEVICE_ERROR
;
1136 //DEBUG("load from core reg %i value 0x%x",num,*value);
1138 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1140 /* read other registers */
1141 /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */
1146 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1147 instr
= ARMV7M_T_MRS(0, SYSm
);
1148 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MRS(0, SYSm
));
1149 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1150 cortex_m3_single_step_core(target
);
1151 ahbap_read_coreregister_u32(swjdp
, value
, 0);
1152 armv7m
->core_cache
->reg_list
[0].dirty
= armv7m
->core_cache
->reg_list
[0].valid
;
1153 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1154 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1155 swjdp_transaction_endcheck(swjdp
);
1156 DEBUG("load from special reg %i value 0x%x", SYSm
, *value
);
1158 else return ERROR_INVALID_ARGUMENTS
;
1163 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1167 /* get pointers to arch-specific information */
1168 armv7m_common_t
*armv7m
= target
->arch_info
;
1169 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1170 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1172 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1174 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1175 if (retval
!= ERROR_OK
)
1177 ERROR("JTAG failure %i", retval
);
1178 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1179 return ERROR_JTAG_DEVICE_ERROR
;
1181 DEBUG("write core reg %i value 0x%x", num
, value
);
1183 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1185 /* write other registers */
1186 u32 savedram
, tempr0
;
1190 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1191 instr
= ARMV7M_T_MSR(SYSm
, 0);
1192 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MSR(SYSm
, 0));
1193 ahbap_read_coreregister_u32(swjdp
, &tempr0
, 0);
1194 ahbap_write_coreregister_u32(swjdp
, value
, 0);
1195 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1196 cortex_m3_single_step_core(target
);
1197 ahbap_write_coreregister_u32(swjdp
, tempr0
, 0);
1198 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1199 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1200 swjdp_transaction_endcheck(swjdp
);
1201 DEBUG("write special reg %i value 0x%x ", SYSm
, value
);
1203 else return ERROR_INVALID_ARGUMENTS
;
1208 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1210 /* get pointers to arch-specific information */
1211 armv7m_common_t
*armv7m
= target
->arch_info
;
1212 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1213 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1215 /* sanitize arguments */
1216 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1217 return ERROR_INVALID_ARGUMENTS
;
1219 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1220 return ERROR_TARGET_UNALIGNED_ACCESS
;
1222 /* Is not optimal, autoincrement of tar should be used ( ahbap_block_read and CSW_ADDRINC_SINGLE ) */
1226 /* TODOLATER Check error return value ! */
1228 ahbap_read_buf(swjdp
, buffer
, 4 * count
, address
);
1233 ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1238 ahbap_read_buf(swjdp
, buffer
, count
, address
);
1242 ERROR("BUG: we shouldn't get here");
1249 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1251 /* get pointers to arch-specific information */
1252 armv7m_common_t
*armv7m
= target
->arch_info
;
1253 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1254 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1256 /* sanitize arguments */
1257 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1258 return ERROR_INVALID_ARGUMENTS
;
1260 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1261 return ERROR_TARGET_UNALIGNED_ACCESS
;
1266 /* TODOLATER Check error return value ! */
1268 ahbap_write_buf(swjdp
, buffer
, 4 * count
, address
);
1273 ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1278 ahbap_write_buf(swjdp
, buffer
, count
, address
);
1282 ERROR("BUG: we shouldn't get here");
1289 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1291 cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1296 void cortex_m3_build_reg_cache(target_t
*target
)
1298 armv7m_build_reg_cache(target
);
1301 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1303 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1306 /* get pointers to arch-specific information */
1307 armv7m_common_t
*armv7m
= target
->arch_info
;
1308 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1309 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1311 cortex_m3_build_reg_cache(target
);
1312 ahbap_debugport_init(swjdp
);
1314 /* Read from Device Identification Registers */
1315 target_read_u32(target
, CPUID
, &cpuid
);
1316 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1317 DEBUG("CORTEX-M3 processor detected");
1318 DEBUG("cpuid: 0x%8.8x", cpuid
);
1320 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1321 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1322 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1323 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1325 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1326 DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1330 target_read_u32(target
, FP_CTRL
, &fpcr
);
1331 cortex_m3
->auto_bp_type
= 1;
1332 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1333 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1334 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1335 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1336 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1338 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1339 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1341 DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1344 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1345 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1346 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1347 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1348 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1350 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1356 int cortex_m3_quit()
1362 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1366 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1368 *value
= (u8
)(dcrdr
>> 8);
1370 DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1372 /* write ack back to software dcc register
1373 * signify we have read data */
1375 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1379 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1381 armv7m_common_t
*armv7m
= target
->arch_info
;
1382 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1383 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1388 for (i
= 0; i
< (size
* 4); i
++)
1390 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1397 int cortex_m3_handle_target_request(void *priv
)
1399 target_t
*target
= priv
;
1400 armv7m_common_t
*armv7m
= target
->arch_info
;
1401 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1402 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1404 if (!target
->dbg_msg_enabled
)
1407 if (target
->state
== TARGET_RUNNING
)
1412 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1414 /* check if we have data */
1420 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1421 request
|= (data
<< 8);
1422 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1423 request
|= (data
<< 16);
1424 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1425 request
|= (data
<< 24);
1426 target_request(target
, request
);
1433 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1435 armv7m_common_t
*armv7m
;
1436 armv7m
= &cortex_m3
->armv7m
;
1438 /* prepare JTAG information for the new target */
1439 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1440 cortex_m3
->jtag_info
.scann_size
= 4;
1442 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1443 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1444 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1445 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1447 /* initialize arch-specific breakpoint handling */
1449 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1450 cortex_m3
->arch_info
= NULL
;
1452 /* register arch-specific functions */
1453 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1455 armv7m
->pre_debug_entry
= NULL
;
1456 armv7m
->post_debug_entry
= NULL
;
1458 armv7m
->pre_restore_context
= NULL
;
1459 armv7m
->post_restore_context
= NULL
;
1461 armv7m_init_arch_info(target
, armv7m
);
1462 armv7m
->arch_info
= cortex_m3
;
1463 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1464 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1465 // armv7m->full_context = cortex_m3_full_context;
1467 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1472 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1473 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1476 char *variant
= NULL
;
1477 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1481 ERROR("'target cortex_m3' requires at least one additional argument");
1485 chain_pos
= strtoul(args
[3], NULL
, 0);
1490 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1491 cortex_m3_register_commands(cmd_ctx
);
1496 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1500 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)