1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
30 #include "replacements.h"
32 #include "cortex_m3.h"
37 #include "target_request.h"
46 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
48 /* forward declarations */
49 void cortex_m3_enable_breakpoints(struct target_s
*target
);
50 void cortex_m3_enable_watchpoints(struct target_s
*target
);
51 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
);
52 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
53 int cortex_m3_quit(void);
54 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
55 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
56 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
57 int cortex_m3_examine(struct target_s
*target
);
59 #ifdef ARMV7_GDB_HACKS
60 extern u8 armv7m_gdb_dummy_cpsr_value
[];
61 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
64 target_type_t cortexm3_target
=
68 .poll
= cortex_m3_poll
,
69 .arch_state
= armv7m_arch_state
,
71 .target_request_data
= cortex_m3_target_request_data
,
73 .halt
= cortex_m3_halt
,
74 .resume
= cortex_m3_resume
,
75 .step
= cortex_m3_step
,
77 .assert_reset
= cortex_m3_assert_reset
,
78 .deassert_reset
= cortex_m3_deassert_reset
,
79 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
81 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
83 .read_memory
= cortex_m3_read_memory
,
84 .write_memory
= cortex_m3_write_memory
,
85 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
86 .checksum_memory
= armv7m_checksum_memory
,
87 .blank_check_memory
= armv7m_blank_check_memory
,
89 .run_algorithm
= armv7m_run_algorithm
,
91 .add_breakpoint
= cortex_m3_add_breakpoint
,
92 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
93 .add_watchpoint
= cortex_m3_add_watchpoint
,
94 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
96 .register_commands
= cortex_m3_register_commands
,
97 .target_create
= cortex_m3_target_create
,
98 .init_target
= cortex_m3_init_target
,
99 .examine
= cortex_m3_examine
,
100 .quit
= cortex_m3_quit
103 int cortex_m3_clear_halt(target_t
*target
)
105 /* get pointers to arch-specific information */
106 armv7m_common_t
*armv7m
= target
->arch_info
;
107 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
108 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
110 /* Read Debug Fault Status Register */
111 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
112 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
113 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
114 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
119 int cortex_m3_single_step_core(target_t
*target
)
121 /* get pointers to arch-specific information */
122 armv7m_common_t
*armv7m
= target
->arch_info
;
123 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
124 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
126 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
127 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
128 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
129 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
131 cortex_m3_clear_halt(target
);
136 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
138 /* get pointers to arch-specific information */
139 armv7m_common_t
*armv7m
= target
->arch_info
;
140 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
141 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
145 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
146 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
147 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
148 cortex_m3_single_step_core(target
);
149 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
150 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
156 /* Enable interrupts */
157 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
159 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
162 /* Disable interrupts */
163 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
165 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
169 int cortex_m3_endreset_event(target_t
*target
)
174 /* get pointers to arch-specific information */
175 armv7m_common_t
*armv7m
= target
->arch_info
;
176 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
177 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
178 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
179 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
181 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
182 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
184 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
186 /* Enable debug requests */
187 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
188 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
189 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
190 /* Enable trace and dwt */
191 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
192 /* Monitor bus faults */
193 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
196 target_write_u32(target
, FP_CTRL
, 3);
198 /* Restore FPB registers */
199 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
201 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
204 /* Restore DWT registers */
205 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
207 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
208 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
209 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
211 swjdp_transaction_endcheck(swjdp
);
213 armv7m_invalidate_core_regs(target
);
217 int cortex_m3_examine_debug_reason(target_t
*target
)
219 /* get pointers to arch-specific information */
220 armv7m_common_t
*armv7m
= target
->arch_info
;
221 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
223 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
224 /* only check the debug reason if we don't know it already */
226 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
227 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
231 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
233 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
234 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
235 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
237 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
238 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
244 int cortex_m3_examine_exception_reason(target_t
*target
)
246 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
248 /* get pointers to arch-specific information */
249 armv7m_common_t
*armv7m
= target
->arch_info
;
250 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
251 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
253 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
254 switch (armv7m
->exception_number
)
258 case 3: /* Hard Fault */
259 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
260 if (except_sr
& 0x40000000)
262 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
265 case 4: /* Memory Management */
266 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
267 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
269 case 5: /* Bus Fault */
270 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
271 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
273 case 6: /* Usage Fault */
274 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
276 case 11: /* SVCall */
278 case 12: /* Debug Monitor */
279 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
281 case 14: /* PendSV */
283 case 15: /* SysTick */
289 swjdp_transaction_endcheck(swjdp
);
290 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
291 shcsr
, except_sr
, cfsr
, except_ar
);
295 int cortex_m3_debug_entry(target_t
*target
)
301 /* get pointers to arch-specific information */
302 armv7m_common_t
*armv7m
= target
->arch_info
;
303 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
304 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
307 if (armv7m
->pre_debug_entry
)
308 armv7m
->pre_debug_entry(target
);
310 cortex_m3_clear_halt(target
);
311 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
313 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
316 /* Examine target state and mode */
317 /* First load register acessible through core debug port*/
318 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
320 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
321 armv7m
->read_core_reg(target
, i
);
324 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
326 #ifdef ARMV7_GDB_HACKS
327 /* copy real xpsr reg for gdb, setting thumb bit */
328 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
329 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
330 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
331 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
334 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
337 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
338 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
341 /* Now we can load SP core registers */
342 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
344 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
345 armv7m
->read_core_reg(target
, i
);
348 /* Are we in an exception handler */
351 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
352 armv7m
->exception_number
= (xPSR
& 0x1FF);
356 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
357 armv7m
->exception_number
= 0;
360 if (armv7m
->exception_number
)
362 cortex_m3_examine_exception_reason(target
);
365 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
366 armv7m_mode_strings
[armv7m
->core_mode
],
367 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
368 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
370 if (armv7m
->post_debug_entry
)
371 armv7m
->post_debug_entry(target
);
376 int cortex_m3_poll(target_t
*target
)
379 u32 prev_target_state
= target
->state
;
381 /* get pointers to arch-specific information */
382 armv7m_common_t
*armv7m
= target
->arch_info
;
383 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
384 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
386 /* Read from Debug Halting Control and Status Register */
387 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
388 if (retval
!= ERROR_OK
)
390 target
->state
= TARGET_UNKNOWN
;
394 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
396 /* check if still in reset */
397 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
399 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
401 target
->state
= TARGET_RESET
;
406 if (target
->state
== TARGET_RESET
)
408 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
409 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
410 cortex_m3_endreset_event(target
);
411 target
->state
= TARGET_RUNNING
;
412 prev_target_state
= TARGET_RUNNING
;
415 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
417 target
->state
= TARGET_HALTED
;
419 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
421 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
424 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
426 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
429 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
432 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
437 if (cortex_m3->dcb_dhcsr & S_SLEEP)
438 target->state = TARGET_SLEEP;
442 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
443 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
444 LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_dfsr
, Jim_Nvp_value2name( nvp_target_state
, target
->state
)->name
);
450 int cortex_m3_halt(target_t
*target
)
452 /* get pointers to arch-specific information */
453 armv7m_common_t
*armv7m
= target
->arch_info
;
454 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
455 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
457 LOG_DEBUG("target->state: %s",
458 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
460 if (target
->state
== TARGET_HALTED
)
462 LOG_DEBUG("target was already halted");
466 if (target
->state
== TARGET_UNKNOWN
)
468 LOG_WARNING("target was in unknown state when halt was requested");
471 if (target
->state
== TARGET_RESET
)
473 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
475 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
476 return ERROR_TARGET_FAILURE
;
480 /* we came here in a reset_halt or reset_init sequence
481 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
483 target
->debug_reason
= DBG_REASON_DBGRQ
;
489 /* Write to Debug Halting Control and Status Register */
490 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
492 target
->debug_reason
= DBG_REASON_DBGRQ
;
497 int cortex_m3_soft_reset_halt(struct target_s
*target
)
499 /* get pointers to arch-specific information */
500 armv7m_common_t
*armv7m
= target
->arch_info
;
501 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
502 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
504 int retval
, timeout
= 0;
506 /* Enter debug state on reset, cf. end_reset_event() */
507 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
509 /* Request a reset */
510 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
511 target
->state
= TARGET_RESET
;
513 /* registers are now invalid */
514 armv7m_invalidate_core_regs(target
);
516 while (timeout
< 100)
518 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
519 if (retval
== ERROR_OK
)
521 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
522 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
524 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
525 cortex_m3_poll(target
);
529 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
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 LOG_WARNING("target not halted");
550 return ERROR_TARGET_NOT_HALTED
;
553 if (!debug_execution
)
555 target_free_all_working_areas(target
);
556 cortex_m3_enable_breakpoints(target
);
557 cortex_m3_enable_watchpoints(target
);
559 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
562 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
565 /* Disable interrupts */
567 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
568 This is probably the same inssue as Cortex-M3 Errata 377493:
569 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
571 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
572 /* Make sure we are in Thumb mode */
573 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
574 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
577 /* current = 1: continue on current pc, otherwise continue at <address> */
580 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
581 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
582 armv7m
->core_cache
->reg_list
[15].valid
= 1;
585 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
587 armv7m_restore_context(target
);
589 /* the front-end may request us not to handle breakpoints */
590 if (handle_breakpoints
)
592 /* Single step past breakpoint at current address */
593 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
595 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
596 cortex_m3_unset_breakpoint(target
, breakpoint
);
597 cortex_m3_single_step_core(target
);
598 cortex_m3_set_breakpoint(target
, breakpoint
);
602 /* Set/Clear C_MASKINTS in a separate operation */
603 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
604 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
607 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
608 target
->debug_reason
= DBG_REASON_NOTHALTED
;
610 /* registers are now invalid */
611 armv7m_invalidate_core_regs(target
);
612 if (!debug_execution
)
614 target
->state
= TARGET_RUNNING
;
615 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
616 LOG_DEBUG("target resumed at 0x%x",resume_pc
);
620 target
->state
= TARGET_DEBUG_RUNNING
;
621 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
622 LOG_DEBUG("target debug resumed at 0x%x",resume_pc
);
628 /* int irqstepcount=0; */
629 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
631 /* get pointers to arch-specific information */
632 armv7m_common_t
*armv7m
= target
->arch_info
;
633 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
634 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
635 breakpoint_t
*breakpoint
= NULL
;
637 if (target
->state
!= TARGET_HALTED
)
639 LOG_WARNING("target not halted");
640 return ERROR_TARGET_NOT_HALTED
;
643 /* current = 1: continue on current pc, otherwise continue at <address> */
645 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
647 /* the front-end may request us not to handle breakpoints */
648 if (handle_breakpoints
)
649 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
650 cortex_m3_unset_breakpoint(target
, breakpoint
);
652 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
654 armv7m_restore_context(target
);
656 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
658 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
659 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
660 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
661 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
663 /* registers are now invalid */
664 armv7m_invalidate_core_regs(target
);
667 cortex_m3_set_breakpoint(target
, breakpoint
);
669 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
671 cortex_m3_debug_entry(target
);
672 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
674 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
678 int cortex_m3_assert_reset(target_t
*target
)
680 armv7m_common_t
*armv7m
= target
->arch_info
;
681 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
682 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
685 LOG_DEBUG("target->state: %s",
686 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
688 if (!(jtag_reset_config
& RESET_HAS_SRST
))
690 LOG_ERROR("Can't assert SRST");
694 /* Enable debug requests */
695 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
696 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
697 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
699 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
701 if (!target
->reset_halt
)
703 /* Set/Clear C_MASKINTS in a separate operation */
704 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
705 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
707 cortex_m3_clear_halt(target
);
709 /* Enter debug state on reset, cf. end_reset_event() */
710 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
714 /* Enter debug state on reset, cf. end_reset_event() */
715 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
718 /* following hack is to handle luminary reset
719 * when srst is asserted the luminary device seesm to also clear the debug registers
720 * which does not match the armv7 debug TRM */
722 if (strcmp(cortex_m3
->variant
, "lm3s") == 0)
724 /* get revision of lm3s target, only early silicon has this issue
725 * Fury Rev B, DustDevil Rev B, Tempest all ok */
729 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
731 switch ((did0
>> 16) & 0xff)
734 /* all Sandstorm suffer issue */
740 /* only Fury/DustDevil rev A suffer reset problems */
741 if (((did0
>> 8) & 0xff) == 0)
750 /* default to asserting srst */
751 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
753 jtag_add_reset(1, 1);
757 jtag_add_reset(0, 1);
762 /* this causes the luminary device to reset using the watchdog */
763 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
764 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
767 target
->state
= TARGET_RESET
;
768 jtag_add_sleep(50000);
770 armv7m_invalidate_core_regs(target
);
772 if (target
->reset_halt
)
775 if ((retval
= target_halt(target
))!=ERROR_OK
)
782 int cortex_m3_deassert_reset(target_t
*target
)
784 LOG_DEBUG("target->state: %s",
785 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
787 /* deassert reset lines */
788 jtag_add_reset(0, 0);
793 void cortex_m3_enable_breakpoints(struct target_s
*target
)
795 breakpoint_t
*breakpoint
= target
->breakpoints
;
797 /* set any pending breakpoints */
800 if (breakpoint
->set
== 0)
801 cortex_m3_set_breakpoint(target
, breakpoint
);
802 breakpoint
= breakpoint
->next
;
806 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
811 /* get pointers to arch-specific information */
812 armv7m_common_t
*armv7m
= target
->arch_info
;
813 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
815 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
819 LOG_WARNING("breakpoint already set");
823 if (cortex_m3
->auto_bp_type
)
825 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
828 if (breakpoint
->type
== BKPT_HARD
)
830 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
832 if (fp_num
>= cortex_m3
->fp_num_code
)
834 LOG_DEBUG("ERROR Can not find free FP Comparator");
835 LOG_WARNING("ERROR Can not find free FP Comparator");
838 breakpoint
->set
= fp_num
+ 1;
839 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
840 comparator_list
[fp_num
].used
= 1;
841 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
842 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
843 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
845 else if (breakpoint
->type
== BKPT_SOFT
)
848 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
849 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
850 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
851 breakpoint
->set
= 0x11; /* Any nice value but 0 */
857 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
859 /* get pointers to arch-specific information */
860 armv7m_common_t
*armv7m
= target
->arch_info
;
861 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
862 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
864 if (!breakpoint
->set
)
866 LOG_WARNING("breakpoint not set");
870 if (breakpoint
->type
== BKPT_HARD
)
872 int fp_num
= breakpoint
->set
- 1;
873 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
875 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
878 comparator_list
[fp_num
].used
= 0;
879 comparator_list
[fp_num
].fpcr_value
= 0;
880 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
884 /* restore original instruction (kept in target endianness) */
885 if (breakpoint
->length
== 4)
887 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
891 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
899 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
901 /* get pointers to arch-specific information */
902 armv7m_common_t
*armv7m
= target
->arch_info
;
903 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
905 if (cortex_m3
->auto_bp_type
)
907 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
908 #ifdef ARMV7_GDB_HACKS
909 if (breakpoint
->length
!= 2) {
910 /* XXX Hack: Replace all breakpoints with length != 2 with
911 * a hardware breakpoint. */
912 breakpoint
->type
= BKPT_HARD
;
913 breakpoint
->length
= 2;
918 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
920 LOG_INFO("flash patch comparator requested outside code memory region");
921 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
924 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
926 LOG_INFO("soft breakpoint requested in code (flash) memory region");
927 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
930 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
932 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
933 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
936 if ((breakpoint
->length
!= 2))
938 LOG_INFO("only breakpoints of two bytes length supported");
939 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
942 if (breakpoint
->type
== BKPT_HARD
)
943 cortex_m3
->fp_code_available
--;
944 cortex_m3_set_breakpoint(target
, breakpoint
);
949 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
951 /* get pointers to arch-specific information */
952 armv7m_common_t
*armv7m
= target
->arch_info
;
953 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
955 if (target
->state
!= TARGET_HALTED
)
957 LOG_WARNING("target not halted");
958 return ERROR_TARGET_NOT_HALTED
;
961 if (cortex_m3
->auto_bp_type
)
963 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
968 cortex_m3_unset_breakpoint(target
, breakpoint
);
971 if (breakpoint
->type
== BKPT_HARD
)
972 cortex_m3
->fp_code_available
++;
977 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
982 /* get pointers to arch-specific information */
983 armv7m_common_t
*armv7m
= target
->arch_info
;
984 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
985 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
989 LOG_WARNING("watchpoint already set");
993 if (watchpoint
->mask
== 0xffffffffu
)
995 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
997 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
999 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1000 LOG_WARNING("ERROR Can not find free DWT Comparator");
1003 watchpoint
->set
= dwt_num
+ 1;
1005 temp
= watchpoint
->length
;
1011 comparator_list
[dwt_num
].used
= 1;
1012 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1013 comparator_list
[dwt_num
].mask
= mask
;
1014 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1015 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1016 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1017 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1018 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
);
1022 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1030 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1032 /* get pointers to arch-specific information */
1033 armv7m_common_t
*armv7m
= target
->arch_info
;
1034 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1035 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1038 if (!watchpoint
->set
)
1040 LOG_WARNING("watchpoint not set");
1044 dwt_num
= watchpoint
->set
- 1;
1046 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1048 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1051 comparator_list
[dwt_num
].used
= 0;
1052 comparator_list
[dwt_num
].function
= 0;
1053 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1055 watchpoint
->set
= 0;
1060 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1062 /* get pointers to arch-specific information */
1063 armv7m_common_t
*armv7m
= target
->arch_info
;
1064 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1066 if (target
->state
!= TARGET_HALTED
)
1068 LOG_WARNING("target not halted");
1069 return ERROR_TARGET_NOT_HALTED
;
1072 if (cortex_m3
->dwt_comp_available
< 1)
1074 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1077 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1079 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1082 cortex_m3
->dwt_comp_available
--;
1087 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1089 /* get pointers to arch-specific information */
1090 armv7m_common_t
*armv7m
= target
->arch_info
;
1091 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1093 if (target
->state
!= TARGET_HALTED
)
1095 LOG_WARNING("target not halted");
1096 return ERROR_TARGET_NOT_HALTED
;
1099 if (watchpoint
->set
)
1101 cortex_m3_unset_watchpoint(target
, watchpoint
);
1104 cortex_m3
->dwt_comp_available
++;
1109 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1111 watchpoint_t
*watchpoint
= target
->watchpoints
;
1113 /* set any pending watchpoints */
1116 if (watchpoint
->set
== 0)
1117 cortex_m3_set_watchpoint(target
, watchpoint
);
1118 watchpoint
= watchpoint
->next
;
1122 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1125 /* get pointers to arch-specific information */
1126 armv7m_common_t
*armv7m
= target
->arch_info
;
1127 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1128 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1130 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1132 /* read a normal core register */
1133 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1135 if (retval
!= ERROR_OK
)
1137 LOG_ERROR("JTAG failure %i",retval
);
1138 return ERROR_JTAG_DEVICE_ERROR
;
1140 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1142 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1144 /* read other registers */
1145 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1150 *value
= buf_get_u32((u8
*)value
, 0, 8);
1154 *value
= buf_get_u32((u8
*)value
, 8, 8);
1158 *value
= buf_get_u32((u8
*)value
, 16, 8);
1162 *value
= buf_get_u32((u8
*)value
, 24, 8);
1166 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1170 return ERROR_INVALID_ARGUMENTS
;
1176 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1181 /* get pointers to arch-specific information */
1182 armv7m_common_t
*armv7m
= target
->arch_info
;
1183 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1184 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1186 #ifdef ARMV7_GDB_HACKS
1187 /* If the LR register is being modified, make sure it will put us
1188 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1189 * hack to deal with the fact that gdb will sometimes "forge"
1190 * return addresses, and doesn't set the LSB correctly (i.e., when
1191 * printing expressions containing function calls, it sets LR=0.) */
1197 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1199 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1200 if (retval
!= ERROR_OK
)
1202 LOG_ERROR("JTAG failure %i", retval
);
1203 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1204 return ERROR_JTAG_DEVICE_ERROR
;
1206 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1208 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1210 /* write other registers */
1212 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1217 buf_set_u32((u8
*)®
, 0, 8, value
);
1221 buf_set_u32((u8
*)®
, 8, 8, value
);
1225 buf_set_u32((u8
*)®
, 16, 8, value
);
1229 buf_set_u32((u8
*)®
, 24, 8, value
);
1233 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1235 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1239 return ERROR_INVALID_ARGUMENTS
;
1245 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1247 /* get pointers to arch-specific information */
1248 armv7m_common_t
*armv7m
= target
->arch_info
;
1249 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1250 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1253 /* sanitize arguments */
1254 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1255 return ERROR_INVALID_ARGUMENTS
;
1257 /* cortex_m3 handles unaligned memory access */
1262 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1265 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1268 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1271 LOG_ERROR("BUG: we shouldn't get here");
1278 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1280 /* get pointers to arch-specific information */
1281 armv7m_common_t
*armv7m
= target
->arch_info
;
1282 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1283 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1286 /* sanitize arguments */
1287 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1288 return ERROR_INVALID_ARGUMENTS
;
1293 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1296 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1299 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1302 LOG_ERROR("BUG: we shouldn't get here");
1309 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1311 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1314 void cortex_m3_build_reg_cache(target_t
*target
)
1316 armv7m_build_reg_cache(target
);
1319 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1321 cortex_m3_build_reg_cache(target
);
1325 int cortex_m3_examine(struct target_s
*target
)
1328 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1331 /* get pointers to arch-specific information */
1332 armv7m_common_t
*armv7m
= target
->arch_info
;
1333 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1334 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1336 target
->type
->examined
= 1;
1338 if ((retval
=ahbap_debugport_init(swjdp
))!=ERROR_OK
)
1341 /* Read from Device Identification Registers */
1342 if ((retval
=target_read_u32(target
, CPUID
, &cpuid
))!=ERROR_OK
)
1345 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1346 LOG_DEBUG("CORTEX-M3 processor detected");
1347 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1349 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1350 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1351 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1352 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1354 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1355 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1359 target_read_u32(target
, FP_CTRL
, &fpcr
);
1360 cortex_m3
->auto_bp_type
= 1;
1361 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1362 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1363 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1364 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1365 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1367 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1368 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1370 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1373 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1374 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1375 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1376 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1377 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1379 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1385 int cortex_m3_quit(void)
1391 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1395 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1397 *value
= (u8
)(dcrdr
>> 8);
1399 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1401 /* write ack back to software dcc register
1402 * signify we have read data */
1403 if (dcrdr
& (1 << 0))
1406 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1412 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1414 armv7m_common_t
*armv7m
= target
->arch_info
;
1415 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1416 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1421 for (i
= 0; i
< (size
* 4); i
++)
1423 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1430 int cortex_m3_handle_target_request(void *priv
)
1432 target_t
*target
= priv
;
1433 if (!target
->type
->examined
)
1435 armv7m_common_t
*armv7m
= target
->arch_info
;
1436 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1437 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1439 if (!target
->dbg_msg_enabled
)
1442 if (target
->state
== TARGET_RUNNING
)
1447 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1449 /* check if we have data */
1450 if (ctrl
& (1 << 0))
1454 /* we assume target is quick enough */
1456 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1457 request
|= (data
<< 8);
1458 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1459 request
|= (data
<< 16);
1460 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1461 request
|= (data
<< 24);
1462 target_request(target
, request
);
1469 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, const char *variant
)
1471 armv7m_common_t
*armv7m
;
1472 armv7m
= &cortex_m3
->armv7m
;
1474 /* prepare JTAG information for the new target */
1475 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1476 cortex_m3
->jtag_info
.scann_size
= 4;
1478 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1479 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1480 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1481 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1483 /* initialize arch-specific breakpoint handling */
1485 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1486 cortex_m3
->arch_info
= NULL
;
1488 /* register arch-specific functions */
1489 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1491 armv7m
->pre_debug_entry
= NULL
;
1492 armv7m
->post_debug_entry
= NULL
;
1494 armv7m
->pre_restore_context
= NULL
;
1495 armv7m
->post_restore_context
= NULL
;
1499 cortex_m3
->variant
= strdup(variant
);
1503 cortex_m3
->variant
= strdup("");
1506 armv7m_init_arch_info(target
, armv7m
);
1507 armv7m
->arch_info
= cortex_m3
;
1508 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1509 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1511 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1516 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1518 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1520 cortex_m3_init_arch_info(target
, cortex_m3
, target
->chain_position
, target
->variant
);
1525 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1529 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)