1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
27 #include "replacements.h"
29 #include "cortex_m3.h"
34 #include "target_request.h"
43 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
45 /* forward declarations */
46 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
);
47 void cortex_m3_enable_breakpoints(struct target_s
*target
);
48 void cortex_m3_enable_watchpoints(struct target_s
*target
);
49 void cortex_m3_disable_bkpts_and_wpts(struct target_s
*target
);
50 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
51 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
53 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
54 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
55 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
57 target_type_t cortexm3_target
=
61 .poll
= cortex_m3_poll
,
62 .arch_state
= armv7m_arch_state
,
64 .target_request_data
= cortex_m3_target_request_data
,
66 .halt
= cortex_m3_halt
,
67 .resume
= cortex_m3_resume
,
68 .step
= cortex_m3_step
,
70 .assert_reset
= cortex_m3_assert_reset
,
71 .deassert_reset
= cortex_m3_deassert_reset
,
72 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
73 .prepare_reset_halt
= cortex_m3_prepare_reset_halt
,
75 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
77 .read_memory
= cortex_m3_read_memory
,
78 .write_memory
= cortex_m3_write_memory
,
79 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
80 .checksum_memory
= armv7m_checksum_memory
,
82 .run_algorithm
= armv7m_run_algorithm
,
84 .add_breakpoint
= cortex_m3_add_breakpoint
,
85 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
86 .add_watchpoint
= cortex_m3_add_watchpoint
,
87 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
89 .register_commands
= cortex_m3_register_commands
,
90 .target_command
= cortex_m3_target_command
,
91 .init_target
= cortex_m3_init_target
,
92 .quit
= cortex_m3_quit
95 int cortex_m3_clear_halt(target_t
*target
)
97 /* get pointers to arch-specific information */
98 armv7m_common_t
*armv7m
= target
->arch_info
;
99 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
100 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
102 /* Read Debug Fault Status Register */
103 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
104 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
105 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
106 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
111 int cortex_m3_single_step_core(target_t
*target
)
113 /* get pointers to arch-specific information */
114 armv7m_common_t
*armv7m
= target
->arch_info
;
115 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
116 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
118 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
119 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
120 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
121 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
123 cortex_m3_clear_halt(target
);
128 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
130 /* get pointers to arch-specific information */
131 armv7m_common_t
*armv7m
= target
->arch_info
;
132 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
133 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
137 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
138 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
139 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
140 cortex_m3_single_step_core(target
);
141 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
142 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
148 /* Enable interrupts */
149 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
151 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
154 /* Disable interrupts */
155 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
157 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
161 int cortex_m3_endreset_event(target_t
*target
)
166 /* get pointers to arch-specific information */
167 armv7m_common_t
*armv7m
= target
->arch_info
;
168 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
169 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
170 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
171 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
173 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
174 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
176 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
178 /* Enable debug requests */
179 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
180 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
181 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
182 /* Enable trace and dwt */
183 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
184 /* Monitor bus faults */
185 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
188 target_write_u32(target
, FP_CTRL
, 3);
190 /* Restore FPB registers */
191 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
193 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
196 /* Restore DWT registers */
197 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
199 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
200 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
201 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
203 swjdp_transaction_endcheck(swjdp
);
205 /* Make sure working_areas are all free */
206 target_free_all_working_areas(target
);
208 /* We are in process context */
209 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
210 armv7m_invalidate_core_regs(target
);
214 int cortex_m3_examine_debug_reason(target_t
*target
)
216 /* get pointers to arch-specific information */
217 armv7m_common_t
*armv7m
= target
->arch_info
;
218 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
220 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
221 /* only check the debug reason if we don't know it already */
223 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
224 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
228 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
230 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
231 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
232 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
234 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
235 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
241 int cortex_m3_examine_exception_reason(target_t
*target
)
243 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
245 /* get pointers to arch-specific information */
246 armv7m_common_t
*armv7m
= target
->arch_info
;
247 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
248 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
250 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
251 switch (armv7m
->exception_number
)
255 case 3: /* Hard Fault */
256 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
257 if (except_sr
& 0x40000000)
259 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
262 case 4: /* Memory Management */
263 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
264 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
266 case 5: /* Bus Fault */
267 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
268 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
270 case 6: /* Usage Fault */
271 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
273 case 11: /* SVCall */
275 case 12: /* Debug Monitor */
276 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
278 case 14: /* PendSV */
280 case 15: /* SysTick */
286 swjdp_transaction_endcheck(swjdp
);
287 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
288 shcsr
, except_sr
, cfsr
, except_ar
);
292 int cortex_m3_debug_entry(target_t
*target
)
298 /* get pointers to arch-specific information */
299 armv7m_common_t
*armv7m
= target
->arch_info
;
300 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
301 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
304 if (armv7m
->pre_debug_entry
)
305 armv7m
->pre_debug_entry(target
);
307 cortex_m3_clear_halt(target
);
308 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
310 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
313 /* Examine target state and mode */
314 /* First load register acessible through core debug port*/
315 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
317 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
318 armv7m
->read_core_reg(target
, i
);
321 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
323 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
326 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
327 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
330 /* Now we can load SP core registers */
331 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
333 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
334 armv7m
->read_core_reg(target
, i
);
337 /* Are we in an exception handler */
338 armv7m
->core_mode
= (xPSR
& 0x1FF) ? ARMV7M_MODE_HANDLER
: ARMV7M_MODE_THREAD
;
339 armv7m
->exception_number
= xPSR
& 0x1FF;
340 if (armv7m
->exception_number
)
342 cortex_m3_examine_exception_reason(target
);
345 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings
[armv7m
->core_mode
], \
346 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
348 if (armv7m
->post_debug_entry
)
349 armv7m
->post_debug_entry(target
);
354 int cortex_m3_poll(target_t
*target
)
357 u32 prev_target_state
= target
->state
;
359 /* get pointers to arch-specific information */
360 armv7m_common_t
*armv7m
= target
->arch_info
;
361 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
362 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
364 /* Read from Debug Halting Control and Status Register */
365 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
366 if (retval
!= ERROR_OK
)
368 target
->state
= TARGET_UNKNOWN
;
372 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
374 /* check if still in reset */
375 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
377 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
379 target
->state
= TARGET_RESET
;
384 if (target
->state
== TARGET_RESET
)
386 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
387 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
388 cortex_m3_endreset_event(target
);
389 target
->state
= TARGET_RUNNING
;
390 prev_target_state
= TARGET_RUNNING
;
393 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
395 target
->state
= TARGET_HALTED
;
397 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
399 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
402 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
404 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
407 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
410 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
415 if (cortex_m3->dcb_dhcsr & S_SLEEP)
416 target->state = TARGET_SLEEP;
419 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
420 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
421 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
]);
425 int cortex_m3_halt(target_t
*target
)
427 /* get pointers to arch-specific information */
428 armv7m_common_t
*armv7m
= target
->arch_info
;
429 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
430 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
432 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
434 if (target
->state
== TARGET_HALTED
)
436 LOG_WARNING("target was already halted");
440 if (target
->state
== TARGET_UNKNOWN
)
442 LOG_WARNING("target was in unknown state when halt was requested");
445 if (target
->state
== TARGET_RESET
)
447 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
449 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
450 return ERROR_TARGET_FAILURE
;
454 /* we came here in a reset_halt or reset_init sequence
455 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
457 target
->debug_reason
= DBG_REASON_DBGRQ
;
463 /* Write to Debug Halting Control and Status Register */
464 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
466 target
->debug_reason
= DBG_REASON_DBGRQ
;
471 int cortex_m3_soft_reset_halt(struct target_s
*target
)
473 /* get pointers to arch-specific information */
474 armv7m_common_t
*armv7m
= target
->arch_info
;
475 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
476 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
478 int retval
, timeout
= 0;
480 /* Check that we are using process_context, or change and print warning */
481 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
483 LOG_DEBUG("Changing to process contex registers");
484 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
487 /* Enter debug state on reset, cf. end_reset_event() */
488 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
490 /* Request a reset */
491 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
492 target
->state
= TARGET_RESET
;
494 /* registers are now invalid */
495 armv7m_invalidate_core_regs(target
);
497 while (timeout
< 100)
499 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
500 if (retval
== ERROR_OK
)
502 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
503 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
505 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
506 cortex_m3_poll(target
);
510 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
519 int cortex_m3_prepare_reset_halt(struct target_s
*target
)
521 armv7m_common_t
*armv7m
= target
->arch_info
;
522 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
523 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
524 u32 dcb_demcr
, dcb_dhcsr
;
526 /* Enable debug requests */
527 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
528 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
529 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
531 /* Enter debug state on reset, cf. end_reset_event() */
532 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
534 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
535 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
536 LOG_DEBUG("dcb_dhcsr 0x%x, dcb_demcr 0x%x, ", dcb_dhcsr
, dcb_demcr
);
541 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
543 /* get pointers to arch-specific information */
544 armv7m_common_t
*armv7m
= target
->arch_info
;
545 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
546 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
547 breakpoint_t
*breakpoint
= NULL
;
548 u32 dcb_dhcsr
, resume_pc
;
550 if (target
->state
!= TARGET_HALTED
)
552 LOG_WARNING("target not halted");
553 return ERROR_TARGET_NOT_HALTED
;
556 if (!debug_execution
)
558 /* Check that we are using process_context, or change and print warning */
559 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
561 LOG_DEBUG("Incorrect context in resume");
562 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
565 target_free_all_working_areas(target
);
566 cortex_m3_enable_breakpoints(target
);
567 cortex_m3_enable_watchpoints(target
);
569 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
572 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
575 /* Check that we are using debug_context, or change and print warning */
576 if (armv7m_get_context(target
) != ARMV7M_DEBUG_CONTEXT
)
578 LOG_DEBUG("Incorrect context in debug_exec resume");
579 armv7m_use_context(target
, ARMV7M_DEBUG_CONTEXT
);
581 /* Disable interrupts */
583 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
584 This is probably the same inssue as Cortex-M3 Errata 377493:
585 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
587 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
588 /* Make sure we are in Thumb mode */
589 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
590 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
593 /* current = 1: continue on current pc, otherwise continue at <address> */
596 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
597 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
598 armv7m
->core_cache
->reg_list
[15].valid
= 1;
601 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
603 armv7m_restore_context(target
);
605 /* the front-end may request us not to handle breakpoints */
606 if (handle_breakpoints
)
608 /* Single step past breakpoint at current address */
609 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
611 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
612 cortex_m3_unset_breakpoint(target
, breakpoint
);
613 cortex_m3_single_step_core(target
);
614 cortex_m3_set_breakpoint(target
, breakpoint
);
618 /* Set/Clear C_MASKINTS in a separate operation */
619 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
620 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
623 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
624 target
->debug_reason
= DBG_REASON_NOTHALTED
;
626 /* registers are now invalid */
627 armv7m_invalidate_core_regs(target
);
628 if (!debug_execution
)
630 target
->state
= TARGET_RUNNING
;
631 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
632 LOG_DEBUG("target resumed at 0x%x",resume_pc
);
636 target
->state
= TARGET_DEBUG_RUNNING
;
637 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
638 LOG_DEBUG("target debug resumed at 0x%x",resume_pc
);
644 /* int irqstepcount=0; */
645 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
647 /* get pointers to arch-specific information */
648 armv7m_common_t
*armv7m
= target
->arch_info
;
649 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
650 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
651 breakpoint_t
*breakpoint
= NULL
;
653 if (target
->state
!= TARGET_HALTED
)
655 LOG_WARNING("target not halted");
656 return ERROR_TARGET_NOT_HALTED
;
659 /* Check that we are using process_context, or change and print warning */
660 if (armv7m_get_context(target
) != ARMV7M_PROCESS_CONTEXT
)
662 LOG_WARNING("Incorrect context in step, must be process");
663 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
666 /* current = 1: continue on current pc, otherwise continue at <address> */
668 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
670 /* the front-end may request us not to handle breakpoints */
671 if (handle_breakpoints
)
672 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
673 cortex_m3_unset_breakpoint(target
, breakpoint
);
675 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
677 armv7m_restore_context(target
);
679 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
681 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
682 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
683 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
684 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
686 /* If we run in process context then registers are now invalid */
687 if (armv7m_get_context(target
) == ARMV7M_PROCESS_CONTEXT
)
688 armv7m_invalidate_core_regs(target
);
691 cortex_m3_set_breakpoint(target
, breakpoint
);
693 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
695 cortex_m3_debug_entry(target
);
696 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
698 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
702 int cortex_m3_assert_reset(target_t
*target
)
705 armv7m_common_t
*armv7m
= target
->arch_info
;
706 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
707 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
709 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
711 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
713 if (target
->reset_mode
== RESET_RUN
)
715 /* Set/Clear C_MASKINTS in a separate operation */
716 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
717 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
719 cortex_m3_clear_halt(target
);
721 /* Enter debug state on reset, cf. end_reset_event() */
722 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
723 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
726 if (target
->state
== TARGET_HALTED
|| target
->state
== TARGET_UNKNOWN
)
728 /* assert SRST and TRST */
729 /* system would get ouf sync if we didn't reset test-logic, too */
730 if ((retval
= jtag_add_reset(1, 1)) != ERROR_OK
)
732 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
738 LOG_ERROR("unknown error");
742 jtag_add_sleep(5000);
743 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
745 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
747 retval
= jtag_add_reset(1, 1);
753 if ((retval
= jtag_add_reset(0, 1)) != ERROR_OK
)
755 if (retval
== ERROR_JTAG_RESET_WOULD_ASSERT_TRST
)
757 retval
= jtag_add_reset(1, 1);
760 if (retval
== ERROR_JTAG_RESET_CANT_SRST
)
764 else if (retval
!= ERROR_OK
)
766 LOG_ERROR("unknown error");
772 target
->state
= TARGET_RESET
;
773 jtag_add_sleep(50000);
775 armv7m_use_context(target
, ARMV7M_PROCESS_CONTEXT
);
776 armv7m_invalidate_core_regs(target
);
781 int cortex_m3_deassert_reset(target_t
*target
)
783 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
785 /* deassert reset lines */
786 jtag_add_reset(0, 0);
791 void cortex_m3_unset_all_breakpoints_and_watchpoints(struct target_s
*target
)
796 void cortex_m3_enable_breakpoints(struct target_s
*target
)
798 breakpoint_t
*breakpoint
= target
->breakpoints
;
800 /* set any pending breakpoints */
803 if (breakpoint
->set
== 0)
804 cortex_m3_set_breakpoint(target
, breakpoint
);
805 breakpoint
= breakpoint
->next
;
809 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
814 /* get pointers to arch-specific information */
815 armv7m_common_t
*armv7m
= target
->arch_info
;
816 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
818 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
822 LOG_WARNING("breakpoint already set");
826 if (cortex_m3
->auto_bp_type
)
828 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
831 if (breakpoint
->type
== BKPT_HARD
)
833 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
835 if (fp_num
>= cortex_m3
->fp_num_code
)
837 LOG_DEBUG("ERROR Can not find free FP Comparator");
838 LOG_WARNING("ERROR Can not find free FP Comparator");
841 breakpoint
->set
= fp_num
+ 1;
842 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
843 comparator_list
[fp_num
].used
= 1;
844 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
845 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
846 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
848 else if (breakpoint
->type
== BKPT_SOFT
)
851 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
852 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
853 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
854 breakpoint
->set
= 0x11; /* Any nice value but 0 */
860 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
862 /* get pointers to arch-specific information */
863 armv7m_common_t
*armv7m
= target
->arch_info
;
864 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
865 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
867 if (!breakpoint
->set
)
869 LOG_WARNING("breakpoint not set");
873 if (breakpoint
->type
== BKPT_HARD
)
875 int fp_num
= breakpoint
->set
- 1;
876 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
878 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
881 comparator_list
[fp_num
].used
= 0;
882 comparator_list
[fp_num
].fpcr_value
= 0;
883 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
887 /* restore original instruction (kept in target endianness) */
888 if (breakpoint
->length
== 4)
890 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
894 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
902 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
904 /* get pointers to arch-specific information */
905 armv7m_common_t
*armv7m
= target
->arch_info
;
906 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
908 if (cortex_m3
->auto_bp_type
)
910 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
913 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
915 LOG_INFO("flash patch comparator requested outside code memory region");
916 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
919 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
921 LOG_INFO("soft breakpoint requested in code (flash) memory region");
922 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
925 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
927 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
928 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
931 if ((breakpoint
->length
!= 2))
933 LOG_INFO("only breakpoints of two bytes length supported");
934 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
937 if (breakpoint
->type
== BKPT_HARD
)
938 cortex_m3
->fp_code_available
--;
939 cortex_m3_set_breakpoint(target
, breakpoint
);
944 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
946 /* get pointers to arch-specific information */
947 armv7m_common_t
*armv7m
= target
->arch_info
;
948 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
950 if (target
->state
!= TARGET_HALTED
)
952 LOG_WARNING("target not halted");
953 return ERROR_TARGET_NOT_HALTED
;
956 if (cortex_m3
->auto_bp_type
)
958 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
963 cortex_m3_unset_breakpoint(target
, breakpoint
);
966 if (breakpoint
->type
== BKPT_HARD
)
967 cortex_m3
->fp_code_available
++;
972 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
977 /* get pointers to arch-specific information */
978 armv7m_common_t
*armv7m
= target
->arch_info
;
979 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
980 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
984 LOG_WARNING("watchpoint already set");
988 if (watchpoint
->mask
== 0xffffffffu
)
990 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
992 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
994 LOG_DEBUG("ERROR Can not find free DWT Comparator");
995 LOG_WARNING("ERROR Can not find free DWT Comparator");
998 watchpoint
->set
= dwt_num
+ 1;
1000 temp
= watchpoint
->length
;
1006 comparator_list
[dwt_num
].used
= 1;
1007 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1008 comparator_list
[dwt_num
].mask
= mask
;
1009 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1010 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1011 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1012 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1013 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
);
1017 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1025 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1027 /* get pointers to arch-specific information */
1028 armv7m_common_t
*armv7m
= target
->arch_info
;
1029 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1030 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1033 if (!watchpoint
->set
)
1035 LOG_WARNING("watchpoint not set");
1039 dwt_num
= watchpoint
->set
- 1;
1041 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1043 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1046 comparator_list
[dwt_num
].used
= 0;
1047 comparator_list
[dwt_num
].function
= 0;
1048 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1050 watchpoint
->set
= 0;
1055 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1057 /* get pointers to arch-specific information */
1058 armv7m_common_t
*armv7m
= target
->arch_info
;
1059 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1061 if (target
->state
!= TARGET_HALTED
)
1063 LOG_WARNING("target not halted");
1064 return ERROR_TARGET_NOT_HALTED
;
1067 if (cortex_m3
->dwt_comp_available
< 1)
1069 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1072 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1074 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1077 cortex_m3
->dwt_comp_available
--;
1082 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1084 /* get pointers to arch-specific information */
1085 armv7m_common_t
*armv7m
= target
->arch_info
;
1086 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1088 if (target
->state
!= TARGET_HALTED
)
1090 LOG_WARNING("target not halted");
1091 return ERROR_TARGET_NOT_HALTED
;
1094 if (watchpoint
->set
)
1096 cortex_m3_unset_watchpoint(target
, watchpoint
);
1099 cortex_m3
->dwt_comp_available
++;
1104 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1106 watchpoint_t
*watchpoint
= target
->watchpoints
;
1108 /* set any pending watchpoints */
1111 if (watchpoint
->set
== 0)
1112 cortex_m3_set_watchpoint(target
, watchpoint
);
1113 watchpoint
= watchpoint
->next
;
1117 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1120 /* get pointers to arch-specific information */
1121 armv7m_common_t
*armv7m
= target
->arch_info
;
1122 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1123 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1125 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1127 /* read a normal core register */
1128 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1130 if (retval
!= ERROR_OK
)
1132 LOG_ERROR("JTAG failure %i",retval
);
1133 return ERROR_JTAG_DEVICE_ERROR
;
1135 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1137 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1139 /* read other registers */
1145 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1146 instr
= ARMV7M_T_MRS(0, SYSm
);
1147 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MRS(0, SYSm
));
1148 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1149 cortex_m3_single_step_core(target
);
1150 ahbap_read_coreregister_u32(swjdp
, value
, 0);
1151 armv7m
->core_cache
->reg_list
[0].dirty
= armv7m
->core_cache
->reg_list
[0].valid
;
1152 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1153 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1154 swjdp_transaction_endcheck(swjdp
);
1155 LOG_DEBUG("load from special reg %i value 0x%x", SYSm
, *value
);
1159 return ERROR_INVALID_ARGUMENTS
;
1165 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1169 /* get pointers to arch-specific information */
1170 armv7m_common_t
*armv7m
= target
->arch_info
;
1171 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1172 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1174 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1176 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1177 if (retval
!= ERROR_OK
)
1179 LOG_ERROR("JTAG failure %i", retval
);
1180 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1181 return ERROR_JTAG_DEVICE_ERROR
;
1183 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1185 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1187 /* write other registers */
1188 u32 savedram
, tempr0
;
1193 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
1194 instr
= ARMV7M_T_MSR(SYSm
, 0);
1195 ahbap_write_system_u32(swjdp
, 0x20000000, ARMV7M_T_MSR(SYSm
, 0));
1196 ahbap_read_coreregister_u32(swjdp
, &tempr0
, 0);
1197 ahbap_write_coreregister_u32(swjdp
, value
, 0);
1198 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
1199 cortex_m3_single_step_core(target
);
1200 ahbap_write_coreregister_u32(swjdp
, tempr0
, 0);
1201 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
1202 ahbap_write_system_u32(swjdp
, 0x20000000, savedram
);
1203 swjdp_transaction_endcheck(swjdp
);
1204 LOG_DEBUG("write special reg %i value 0x%x ", SYSm
, value
);
1208 return ERROR_INVALID_ARGUMENTS
;
1214 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1216 /* get pointers to arch-specific information */
1217 armv7m_common_t
*armv7m
= target
->arch_info
;
1218 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1219 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1222 /* sanitize arguments */
1223 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1224 return ERROR_INVALID_ARGUMENTS
;
1226 /* cortex_m3 handles unaligned memory access */
1231 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1234 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1237 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1240 LOG_ERROR("BUG: we shouldn't get here");
1247 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1249 /* get pointers to arch-specific information */
1250 armv7m_common_t
*armv7m
= target
->arch_info
;
1251 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1252 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1255 /* sanitize arguments */
1256 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1257 return ERROR_INVALID_ARGUMENTS
;
1262 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1265 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1268 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1271 LOG_ERROR("BUG: we shouldn't get here");
1278 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1280 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1283 void cortex_m3_build_reg_cache(target_t
*target
)
1285 armv7m_build_reg_cache(target
);
1288 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1290 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1293 /* get pointers to arch-specific information */
1294 armv7m_common_t
*armv7m
= target
->arch_info
;
1295 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1296 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1298 cortex_m3_build_reg_cache(target
);
1299 ahbap_debugport_init(swjdp
);
1301 /* Read from Device Identification Registers */
1302 target_read_u32(target
, CPUID
, &cpuid
);
1303 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1304 LOG_DEBUG("CORTEX-M3 processor detected");
1305 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1307 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1308 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1309 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1310 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1312 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1313 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1317 target_read_u32(target
, FP_CTRL
, &fpcr
);
1318 cortex_m3
->auto_bp_type
= 1;
1319 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1320 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1321 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1322 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1323 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1325 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1326 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1328 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1331 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1332 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1333 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1334 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1335 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1337 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1343 int cortex_m3_quit()
1349 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1353 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1355 *value
= (u8
)(dcrdr
>> 8);
1357 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1359 /* write ack back to software dcc register
1360 * signify we have read data */
1361 if (dcrdr
& (1 << 0))
1364 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1370 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
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
;
1379 for (i
= 0; i
< (size
* 4); i
++)
1381 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1388 int cortex_m3_handle_target_request(void *priv
)
1390 target_t
*target
= priv
;
1391 armv7m_common_t
*armv7m
= target
->arch_info
;
1392 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1393 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1395 if (!target
->dbg_msg_enabled
)
1398 if (target
->state
== TARGET_RUNNING
)
1403 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1405 /* check if we have data */
1406 if (ctrl
& (1 << 0))
1410 /* we assume target is quick enough */
1412 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1413 request
|= (data
<< 8);
1414 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1415 request
|= (data
<< 16);
1416 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1417 request
|= (data
<< 24);
1418 target_request(target
, request
);
1425 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1427 armv7m_common_t
*armv7m
;
1428 armv7m
= &cortex_m3
->armv7m
;
1430 /* prepare JTAG information for the new target */
1431 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1432 cortex_m3
->jtag_info
.scann_size
= 4;
1434 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1435 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1436 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1437 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1439 /* initialize arch-specific breakpoint handling */
1441 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1442 cortex_m3
->arch_info
= NULL
;
1444 /* register arch-specific functions */
1445 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1447 armv7m
->pre_debug_entry
= NULL
;
1448 armv7m
->post_debug_entry
= NULL
;
1450 armv7m
->pre_restore_context
= NULL
;
1451 armv7m
->post_restore_context
= NULL
;
1453 armv7m_init_arch_info(target
, armv7m
);
1454 armv7m
->arch_info
= cortex_m3
;
1455 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1456 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1458 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1463 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1464 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1467 char *variant
= NULL
;
1468 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1469 memset(cortex_m3
, 0, sizeof(*cortex_m3
));
1473 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1477 chain_pos
= strtoul(args
[3], NULL
, 0);
1482 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1483 cortex_m3_register_commands(cmd_ctx
);
1488 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1492 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)