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"
41 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
43 /* forward declarations */
44 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
);
45 void cortex_m3_enable_breakpoints(struct target_s
*target
);
46 void cortex_m3_enable_watchpoints(struct target_s
*target
);
47 void cortex_m3_disable_bkpts_and_wpts(struct target_s
*target
);
48 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
49 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
51 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
52 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
54 target_type_t cortexm3_target
=
58 .poll
= cortex_m3_poll
,
59 .arch_state
= armv7m_arch_state
,
61 .target_request_data
= NULL
,
63 .halt
= cortex_m3_halt
,
64 .resume
= cortex_m3_resume
,
65 .step
= cortex_m3_step
,
67 .assert_reset
= cortex_m3_assert_reset
,
68 .deassert_reset
= cortex_m3_deassert_reset
,
69 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
70 .prepare_reset_halt
= cortex_m3_prepare_reset_halt
,
72 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
74 .read_memory
= cortex_m3_read_memory
,
75 .write_memory
= cortex_m3_write_memory
,
76 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
77 .checksum_memory
= armv7m_checksum_memory
,
79 .run_algorithm
= armv7m_run_algorithm
,
81 .add_breakpoint
= cortex_m3_add_breakpoint
,
82 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
83 .add_watchpoint
= cortex_m3_add_watchpoint
,
84 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
86 .register_commands
= cortex_m3_register_commands
,
87 .target_command
= cortex_m3_target_command
,
88 .init_target
= cortex_m3_init_target
,
89 .quit
= cortex_m3_quit
92 int cortex_m3_clear_halt(target_t
*target
)
94 /* get pointers to arch-specific information */
95 armv7m_common_t
*armv7m
= target
->arch_info
;
96 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
97 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
99 /* Read Debug Fault Status Register */
100 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
101 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
102 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
103 DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
108 int cortex_m3_single_step_core(target_t
*target
)
110 /* get pointers to arch-specific information */
111 armv7m_common_t
*armv7m
= target
->arch_info
;
112 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
113 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
115 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
116 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
117 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
118 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
120 cortex_m3_clear_halt(target
);
125 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
127 /* get pointers to arch-specific information */
128 armv7m_common_t
*armv7m
= target
->arch_info
;
129 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
130 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
134 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
135 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
136 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
137 cortex_m3_single_step_core(target
);
138 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
139 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
144 /* Enable interrupts */
145 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
147 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
150 /* Disable interrupts */
151 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
153 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
156 int cortex_m3_endreset_event(target_t
*target
)
161 /* get pointers to arch-specific information */
162 armv7m_common_t
*armv7m
= target
->arch_info
;
163 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
164 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
165 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
166 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
168 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
169 DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
171 /* Enable debug requests */
172 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
173 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
174 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
175 /* Enable trace and dwt */
176 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
177 /* Monitor bus faults */
178 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
181 target_write_u32(target
, FP_CTRL
, 3);
183 /* Restore FPB registers */
184 for ( i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
186 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
189 /* Restore DWT registers */
190 for ( i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
192 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
193 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
194 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
196 swjdp_transaction_endcheck(swjdp
);
198 /* Make sure working_areas are all free */
199 target_free_all_working_areas(target
);
201 /* We are in process context */
202 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
203 armv7m_invalidate_core_regs(target
);
207 int cortex_m3_examine_debug_reason(target_t
*target
)
209 /* get pointers to arch-specific information */
210 armv7m_common_t
*armv7m
= target
->arch_info
;
211 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
213 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
214 /* only check the debug reason if we don't know it already */
216 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
217 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
221 if (cortex_m3
->nvic_dfsr
& 0x2)
223 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
224 if (cortex_m3
->nvic_dfsr
& 0x4)
225 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
227 else if (cortex_m3
->nvic_dfsr
& 0x4)
228 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
234 int cortex_m3_examine_exception_reason(target_t
*target
)
236 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
238 /* get pointers to arch-specific information */
239 armv7m_common_t
*armv7m
= target
->arch_info
;
240 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
241 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
243 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
244 switch (armv7m
->exception_number
)
248 case 3: /* Hard Fault */
249 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
250 if (except_sr
& 0x40000000)
252 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
255 case 4: /* Memory Management */
256 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
257 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
259 case 5: /* Bus Fault */
260 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
261 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
263 case 6: /* Usage Fault */
264 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
266 case 11: /* SVCall */
268 case 12: /* Debug Monitor */
269 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
271 case 14: /* PendSV */
273 case 15: /* SysTick */
279 swjdp_transaction_endcheck(swjdp
);
280 DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
281 shcsr
, except_sr
, cfsr
, except_ar
);
285 int cortex_m3_debug_entry(target_t
*target
)
291 /* get pointers to arch-specific information */
292 armv7m_common_t
*armv7m
= target
->arch_info
;
293 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
294 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
297 if (armv7m
->pre_debug_entry
)
298 armv7m
->pre_debug_entry(target
);
300 cortex_m3_clear_halt(target
);
301 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
303 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
306 /* Examine target state and mode */
307 /* First load register acessible through core debug port*/
308 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
310 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
311 armv7m
->read_core_reg(target
, i
);
314 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
316 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec*/
319 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
320 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
324 /* Now we can load SP core registers */
325 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
327 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
328 armv7m
->read_core_reg(target
, i
);
331 /* Are we in an exception handler */
332 armv7m
->core_mode
= (xPSR
& 0x1FF) ? ARMV7M_MODE_HANDLER
: ARMV7M_MODE_THREAD
;
333 armv7m
->exception_number
= xPSR
& 0x1FF;
334 if (armv7m
->exception_number
)
336 cortex_m3_examine_exception_reason(target
);
339 DEBUG("entered debug state at PC 0x%x, target->state: %s ", *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
341 if (armv7m
->post_debug_entry
)
342 armv7m
->post_debug_entry(target
);
347 enum target_state
cortex_m3_poll(target_t
*target
)
350 u32 prev_target_state
= target
->state
;
352 /* get pointers to arch-specific information */
353 armv7m_common_t
*armv7m
= target
->arch_info
;
354 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
355 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
357 /* Read from Debug Halting Control and Status Register */
358 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
359 if (retval
!= ERROR_OK
)
361 target
->state
= TARGET_UNKNOWN
;
362 return TARGET_UNKNOWN
;
365 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
367 /* check if still in reset */
368 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
370 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
372 target
->state
= TARGET_RESET
;
373 return target
->state
;
377 if (target
->state
== TARGET_RESET
)
379 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
380 DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
381 cortex_m3_endreset_event(target
);
382 target
->state
= TARGET_RUNNING
;
383 prev_target_state
= TARGET_RUNNING
;
386 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
388 target
->state
= TARGET_HALTED
;
390 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
392 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
393 return TARGET_UNKNOWN
;
395 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
397 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
400 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
401 return TARGET_UNKNOWN
;
403 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
408 if (cortex_m3->dcb_dhcsr & S_SLEEP)
409 target->state = TARGET_SLEEP;
412 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
413 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
414 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
]);
415 return target
->state
;
418 int cortex_m3_halt(target_t
*target
)
420 /* get pointers to arch-specific information */
421 armv7m_common_t
*armv7m
= target
->arch_info
;
422 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
423 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
425 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
427 if (target
->state
== TARGET_HALTED
)
429 WARNING("target was already halted");
430 return ERROR_TARGET_ALREADY_HALTED
;
433 if (target
->state
== TARGET_UNKNOWN
)
435 WARNING("target was in unknown state when halt was requested");
438 if (target
->state
== TARGET_RESET
)
440 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
442 ERROR("can't request a halt while in reset if nSRST pulls nTRST");
443 return ERROR_TARGET_FAILURE
;
447 /* we came here in a reset_halt or reset_init sequence
448 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
450 target
->debug_reason
= DBG_REASON_DBGRQ
;
456 /* Write to Debug Halting Control and Status Register */
457 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
459 target
->debug_reason
= DBG_REASON_DBGRQ
;
464 int cortex_m3_soft_reset_halt(struct target_s
*target
)
466 /* get pointers to arch-specific information */
467 armv7m_common_t
*armv7m
= target
->arch_info
;
468 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
469 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
471 int retval
, timeout
= 0;
473 /* Check that we are using process_context, or change and print warning */
474 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
476 DEBUG("Changing to process contex registers");
477 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
480 /* Enter debug state on reset, cf. end_reset_event() */
481 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
483 /* Request a reset */
484 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
485 target
->state
= TARGET_RESET
;
487 /* registers are now invalid */
488 armv7m_invalidate_core_regs(target
);
490 while (timeout
< 100)
492 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
493 if (retval
== ERROR_OK
)
495 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
496 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
498 DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
499 cortex_m3_poll(target
);
503 DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
512 int cortex_m3_prepare_reset_halt(struct target_s
*target
)
514 armv7m_common_t
*armv7m
= target
->arch_info
;
515 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
516 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
517 u32 dcb_demcr
, dcb_dhcsr
;
519 /* Enable debug requests */
520 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
521 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
522 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
524 /* Enter debug state on reset, cf. end_reset_event() */
525 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
527 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
528 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
529 DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr
, dcb_demcr
);
534 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
536 /* get pointers to arch-specific information */
537 armv7m_common_t
*armv7m
= target
->arch_info
;
538 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
539 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
540 breakpoint_t
*breakpoint
= NULL
;
541 u32 dcb_dhcsr
, resume_pc
;
543 if (target
->state
!= TARGET_HALTED
)
545 WARNING("target not halted");
546 return ERROR_TARGET_NOT_HALTED
;
549 if (!debug_execution
)
551 /* Check that we are using process_context, or change and print warning */
552 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
554 WARNING("Incorrect context in resume");
555 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
558 target_free_all_working_areas(target
);
559 cortex_m3_enable_breakpoints(target
);
560 cortex_m3_enable_watchpoints(target
);
562 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
565 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
568 /* Check that we are using debug_context, or change and print warning */
569 if (armv7m_get_context(target
) != ARMV7M_DEBUG_CONTEXT
)
571 WARNING("Incorrect context in debug_exec resume");
572 armv7m_use_context(target
, ARMV7M_DEBUG_CONTEXT
);
574 /* Disable interrupts */
576 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
577 This is probably the same inssue as Cortex-M3 Errata 377493:
578 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
580 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
581 /* Make sure we are in Thumb mode */
582 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
583 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
586 /* current = 1: continue on current pc, otherwise continue at <address> */
589 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
590 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
591 armv7m
->core_cache
->reg_list
[15].valid
= 1;
594 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
596 armv7m_restore_context(target
);
598 /* the front-end may request us not to handle breakpoints */
599 if (handle_breakpoints
)
601 /* Single step past breakpoint at current address */
602 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
604 DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
605 cortex_m3_unset_breakpoint(target
, breakpoint
);
606 cortex_m3_single_step_core(target
);
607 cortex_m3_set_breakpoint(target
, breakpoint
);
611 /* Set/Clear C_MASKINTS in a separate operation */
612 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
613 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
616 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
617 target
->debug_reason
= DBG_REASON_NOTHALTED
;
619 /* registers are now invalid */
620 armv7m_invalidate_core_regs(target
);
621 if (!debug_execution
)
623 target
->state
= TARGET_RUNNING
;
624 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
625 DEBUG("target resumed at 0x%x",resume_pc
);
629 target
->state
= TARGET_DEBUG_RUNNING
;
630 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
631 DEBUG("target debug resumed at 0x%x",resume_pc
);
637 //int irqstepcount=0;
638 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
640 /* get pointers to arch-specific information */
641 armv7m_common_t
*armv7m
= target
->arch_info
;
642 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
643 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
644 breakpoint_t
*breakpoint
= NULL
;
646 if (target
->state
!= TARGET_HALTED
)
648 WARNING("target not halted");
649 return ERROR_TARGET_NOT_HALTED
;
652 /* Check that we are using process_context, or change and print warning */
653 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
655 WARNING("Incorrect context in step, must be process");
656 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
659 /* current = 1: continue on current pc, otherwise continue at <address> */
661 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
663 /* the front-end may request us not to handle breakpoints */
664 if (handle_breakpoints
)
665 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
666 cortex_m3_unset_breakpoint(target
, breakpoint
);
668 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
670 armv7m_restore_context(target
);
672 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
674 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
675 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
676 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
677 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
679 /* If we run in process context then registers are now invalid */
680 if (armv7m_get_context(target
) == ARMV7M_PROCESS_CONTEXT
)
681 armv7m_invalidate_core_regs(target
);
684 cortex_m3_set_breakpoint(target
, breakpoint
);
686 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
688 cortex_m3_debug_entry(target
);
689 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
691 DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
695 int cortex_m3_assert_reset(target_t
*target
)
698 armv7m_common_t
*armv7m
= target
->arch_info
;
699 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
700 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
702 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
704 if (target
->reset_mode
== RESET_RUN
)
706 /* Set/Clear C_MASKINTS in a separate operation */
707 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
708 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
710 cortex_m3_clear_halt(target
);
712 /* Enter debug state on reset, cf. end_reset_event() */
713 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
714 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
717 if (target
->state
== TARGET_HALTED
|| target
->state
== TARGET_UNKNOWN
)
719 /* assert SRST and TRST */
720 /* system would get ouf sync if we didn't reset test-logic, too */
721 if ((retval
= jtag_add_reset(1, 1)) != ERROR_OK
)
723 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
725 WARNING("can't assert srst");
730 ERROR("unknown error");
734 jtag_add_sleep(5000);
735 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
737 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
739 WARNING("srst resets test logic, too");
740 retval
= jtag_add_reset(1, 1);
746 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
748 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
750 WARNING("srst resets test logic, too");
751 retval
= jtag_add_reset(1, 1);
754 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
756 WARNING("can't assert srsrt");
759 else if (retval
!= ERROR_OK
)
761 ERROR("unknown error");
767 target
->state
= TARGET_RESET
;
768 jtag_add_sleep(50000);
770 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
771 armv7m_invalidate_core_regs(target
);
776 int cortex_m3_deassert_reset(target_t
*target
)
778 DEBUG("target->state: %s", target_state_strings
[target
->state
]);
780 /* deassert reset lines */
781 jtag_add_reset(0, 0);
786 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
)
791 void cortex_m3_enable_breakpoints(struct target_s
*target
)
793 breakpoint_t
*breakpoint
= target
->breakpoints
;
795 /* set any pending breakpoints */
798 if (breakpoint
->set
== 0)
799 cortex_m3_set_breakpoint(target
, breakpoint
);
800 breakpoint
= breakpoint
->next
;
804 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
809 /* get pointers to arch-specific information */
810 armv7m_common_t
*armv7m
= target
->arch_info
;
811 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
813 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
817 WARNING("breakpoint already set");
821 if (cortex_m3
->auto_bp_type
)
823 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
826 if (breakpoint
->type
== BKPT_HARD
)
828 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
830 if (fp_num
>= cortex_m3
->fp_num_code
)
832 DEBUG("ERROR Can not find free FP Comparator");
833 WARNING("ERROR Can not find free FP Comparator");
836 breakpoint
->set
= fp_num
+ 1;
837 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
838 comparator_list
[fp_num
].used
= 1;
839 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
840 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
841 DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
843 else if (breakpoint
->type
== BKPT_SOFT
)
846 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
847 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
848 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
849 breakpoint
->set
= 0x11; /* Any nice value but 0 */
855 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
857 /* get pointers to arch-specific information */
858 armv7m_common_t
*armv7m
= target
->arch_info
;
859 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
860 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
862 if (!breakpoint
->set
)
864 WARNING("breakpoint not set");
868 if (breakpoint
->type
== BKPT_HARD
)
870 int fp_num
= breakpoint
->set
- 1;
871 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
873 DEBUG("Invalid FP Comparator number in breakpoint");
876 comparator_list
[fp_num
].used
= 0;
877 comparator_list
[fp_num
].fpcr_value
= 0;
878 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
882 /* restore original instruction (kept in target endianness) */
883 if (breakpoint
->length
== 4)
885 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
889 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
897 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
899 /* get pointers to arch-specific information */
900 armv7m_common_t
*armv7m
= target
->arch_info
;
901 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
903 if (cortex_m3
->auto_bp_type
)
905 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
908 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
910 INFO("flash patch comparator requested outside code memory region");
911 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
914 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
916 INFO("soft breakpoint requested in code (flash) memory region");
917 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
920 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
922 INFO("no flash patch comparator unit available for hardware breakpoint");
923 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
926 if ((breakpoint
->length
!= 2))
928 INFO("only breakpoints of two bytes length supported");
929 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
932 if (breakpoint
->type
== BKPT_HARD
)
933 cortex_m3
->fp_code_available
--;
934 cortex_m3_set_breakpoint(target
, breakpoint
);
939 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
941 /* get pointers to arch-specific information */
942 armv7m_common_t
*armv7m
= target
->arch_info
;
943 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
945 if (target
->state
!= TARGET_HALTED
)
947 WARNING("target not halted");
948 return ERROR_TARGET_NOT_HALTED
;
951 if (cortex_m3
->auto_bp_type
)
953 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
958 cortex_m3_unset_breakpoint(target
, breakpoint
);
961 if (breakpoint
->type
== BKPT_HARD
)
962 cortex_m3
->fp_code_available
++;
967 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
972 /* get pointers to arch-specific information */
973 armv7m_common_t
*armv7m
= target
->arch_info
;
974 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
975 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
979 WARNING("watchpoint already set");
983 if (watchpoint
->mask
== 0xffffffffu
)
985 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
987 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
989 DEBUG("ERROR Can not find free DWT Comparator");
990 WARNING("ERROR Can not find free DWT Comparator");
993 watchpoint
->set
= dwt_num
+ 1;
995 temp
= watchpoint
->length
;
1001 comparator_list
[dwt_num
].used
= 1;
1002 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1003 comparator_list
[dwt_num
].mask
= mask
;
1004 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1005 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1006 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1007 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1008 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
);
1012 WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1020 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1022 /* get pointers to arch-specific information */
1023 armv7m_common_t
*armv7m
= target
->arch_info
;
1024 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1025 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1028 if (!watchpoint
->set
)
1030 WARNING("watchpoint not set");
1034 dwt_num
= watchpoint
->set
- 1;
1036 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1038 DEBUG("Invalid DWT Comparator number in watchpoint");
1041 comparator_list
[dwt_num
].used
= 0;
1042 comparator_list
[dwt_num
].function
= 0;
1043 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1045 watchpoint
->set
= 0;
1050 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1052 /* get pointers to arch-specific information */
1053 armv7m_common_t
*armv7m
= target
->arch_info
;
1054 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1056 if (target
->state
!= TARGET_HALTED
)
1058 WARNING("target not halted");
1059 return ERROR_TARGET_NOT_HALTED
;
1062 if (cortex_m3
->dwt_comp_available
< 1)
1064 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1067 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1069 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1072 cortex_m3
->dwt_comp_available
--;
1077 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1079 /* get pointers to arch-specific information */
1080 armv7m_common_t
*armv7m
= target
->arch_info
;
1081 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1083 if (target
->state
!= TARGET_HALTED
)
1085 WARNING("target not halted");
1086 return ERROR_TARGET_NOT_HALTED
;
1089 if (watchpoint
->set
)
1091 cortex_m3_unset_watchpoint(target
, watchpoint
);
1094 cortex_m3
->dwt_comp_available
++;
1099 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1101 watchpoint_t
*watchpoint
= target
->watchpoints
;
1103 /* set any pending watchpoints */
1106 if (watchpoint
->set
== 0)
1107 cortex_m3_set_watchpoint(target
, watchpoint
);
1108 watchpoint
= watchpoint
->next
;
1112 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1115 /* get pointers to arch-specific information */
1116 armv7m_common_t
*armv7m
= target
->arch_info
;
1117 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1118 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1120 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1122 /* read a normal core register */
1123 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1125 if (retval
!= ERROR_OK
)
1127 ERROR("JTAG failure %i",retval
);
1128 return ERROR_JTAG_DEVICE_ERROR
;
1130 //DEBUG("load from core reg %i value 0x%x",num,*value);
1132 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1134 /* read other registers */
1135 /* cortex_m3_MRS(struct target_s *target, int num, u32* value) */
1140 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1141 instr
= ARMV7M_T_MRS(0, SYSm
);
1142 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MRS(0, SYSm
));
1143 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1144 cortex_m3_single_step_core(target
);
1145 ahbap_read_coreregister_u32(swjdp
, value
, 0);
1146 armv7m
->core_cache
->reg_list
[0].dirty
= 1;
1147 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
1148 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1149 swjdp_transaction_endcheck(swjdp
);
1150 DEBUG("load from special reg %i value 0x%x", SYSm
, *value
);
1152 else return ERROR_INVALID_ARGUMENTS
;
1157 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1161 /* get pointers to arch-specific information */
1162 armv7m_common_t
*armv7m
= target
->arch_info
;
1163 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1164 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1166 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1168 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1169 if (retval
!= ERROR_OK
)
1171 ERROR("JTAG failure %i", retval
);
1172 armv7m
->core_cache
->reg_list
[num
].dirty
= 1;
1173 return ERROR_JTAG_DEVICE_ERROR
;
1175 DEBUG("write core reg %i value 0x%x", num
, value
);
1177 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1179 /* write other registers */
1180 u32 savedram
, tempr0
;
1184 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1185 instr
= ARMV7M_T_MSR(SYSm
, 0);
1186 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MSR(SYSm
, 0));
1187 ahbap_read_coreregister_u32(swjdp
, &tempr0
, 0);
1188 ahbap_write_coreregister_u32(swjdp
, value
, 0);
1189 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1190 cortex_m3_single_step_core(target
);
1191 ahbap_write_coreregister_u32(swjdp
, tempr0
, 0);
1192 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
1193 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1194 swjdp_transaction_endcheck(swjdp
);
1195 DEBUG("write special reg %i value 0x%x ", SYSm
, value
);
1197 else return ERROR_INVALID_ARGUMENTS
;
1202 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1204 /* get pointers to arch-specific information */
1205 armv7m_common_t
*armv7m
= target
->arch_info
;
1206 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1207 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1209 /* sanitize arguments */
1210 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1211 return ERROR_INVALID_ARGUMENTS
;
1213 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1214 return ERROR_TARGET_UNALIGNED_ACCESS
;
1216 /* Is not optimal, autoincrement of tar should be used ( ahbap_block_read and CSW_ADDRINC_SINGLE ) */
1220 /* TODOLATER Check error return value ! */
1222 ahbap_read_buf(swjdp
, buffer
, 4 * count
, address
);
1227 ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1232 ahbap_read_buf(swjdp
, buffer
, count
, address
);
1236 ERROR("BUG: we shouldn't get here");
1243 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1245 /* get pointers to arch-specific information */
1246 armv7m_common_t
*armv7m
= target
->arch_info
;
1247 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1248 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1250 /* sanitize arguments */
1251 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1252 return ERROR_INVALID_ARGUMENTS
;
1254 if (((size
== 4) && (address
& 0x3u
)) || ((size
== 2) && (address
& 0x1u
)))
1255 return ERROR_TARGET_UNALIGNED_ACCESS
;
1260 /* TODOLATER Check error return value ! */
1262 ahbap_write_buf(swjdp
, buffer
, 4 * count
, address
);
1267 ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1272 ahbap_write_buf(swjdp
, buffer
, count
, address
);
1276 ERROR("BUG: we shouldn't get here");
1283 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1285 cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1290 void cortex_m3_build_reg_cache(target_t
*target
)
1292 armv7m_build_reg_cache(target
);
1295 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1297 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1300 /* get pointers to arch-specific information */
1301 armv7m_common_t
*armv7m
= target
->arch_info
;
1302 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1303 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1305 cortex_m3_build_reg_cache(target
);
1306 ahbap_debugport_init(swjdp
);
1308 /* Read from Device Identification Registers */
1309 target_read_u32(target
, CPUID
, &cpuid
);
1310 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1311 DEBUG("CORTEX-M3 processor detected");
1312 DEBUG("cpuid: 0x%8.8x", cpuid
);
1314 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1315 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1316 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1317 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1319 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1320 DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1324 target_read_u32(target
, FP_CTRL
, &fpcr
);
1325 cortex_m3
->auto_bp_type
= 1;
1326 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1327 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1328 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1329 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1330 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1332 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1333 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1335 DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1338 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1339 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1340 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1341 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1342 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1344 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1350 int cortex_m3_quit()
1356 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1358 armv7m_common_t
*armv7m
;
1359 armv7m
= &cortex_m3
->armv7m
;
1361 /* prepare JTAG information for the new target */
1362 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1363 cortex_m3
->jtag_info
.scann_size
= 4;
1365 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1366 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1367 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1368 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1370 /* initialize arch-specific breakpoint handling */
1372 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1373 cortex_m3
->arch_info
= NULL
;
1375 /* register arch-specific functions */
1376 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1378 armv7m
->pre_debug_entry
= NULL
;
1379 armv7m
->post_debug_entry
= NULL
;
1381 armv7m
->pre_restore_context
= NULL
;
1382 armv7m
->post_restore_context
= NULL
;
1384 armv7m_init_arch_info(target
, armv7m
);
1385 armv7m
->arch_info
= cortex_m3
;
1386 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1387 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1388 // armv7m->full_context = cortex_m3_full_context;
1393 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1394 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1397 char *variant
= NULL
;
1398 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1402 ERROR("'target cortex_m3' requires at least one additional argument");
1406 chain_pos
= strtoul(args
[3], NULL
, 0);
1411 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1412 cortex_m3_register_commands(cmd_ctx
);
1417 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1421 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)