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_write_debug_halt_mask(target_t
*target
, u32 mask_on
, u32 mask_off
)
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 /* mask off status bits */
111 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
112 /* create new register mask */
113 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
115 return ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
118 int cortex_m3_clear_halt(target_t
*target
)
120 /* get pointers to arch-specific information */
121 armv7m_common_t
*armv7m
= target
->arch_info
;
122 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
123 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
125 /* clear step if any */
126 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
128 /* Read Debug Fault Status Register */
129 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
130 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
131 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
132 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
137 int cortex_m3_single_step_core(target_t
*target
)
139 /* get pointers to arch-specific information */
140 armv7m_common_t
*armv7m
= target
->arch_info
;
141 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
142 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
145 /* backup dhcsr reg */
146 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
148 /* mask interrupts if not done already */
149 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
150 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
151 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
154 /* restore dhcsr reg */
155 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
156 cortex_m3_clear_halt(target
);
161 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
163 /* get pointers to arch-specific information */
164 armv7m_common_t
*armv7m
= target
->arch_info
;
165 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
166 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
170 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
171 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
172 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
173 cortex_m3_single_step_core(target
);
174 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
175 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
181 /* Enable interrupts */
182 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
184 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
187 /* Disable interrupts */
188 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
190 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
194 int cortex_m3_endreset_event(target_t
*target
)
199 /* get pointers to arch-specific information */
200 armv7m_common_t
*armv7m
= target
->arch_info
;
201 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
202 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
203 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
204 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
206 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
207 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
209 /* this regsiter is used for emulated dcc channel */
210 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0);
212 /* Enable debug requests */
213 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
214 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
215 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
217 /* clear any interrupt masking */
218 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
220 /* Enable trace and dwt */
221 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
222 /* Monitor bus faults */
223 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
226 target_write_u32(target
, FP_CTRL
, 3);
228 /* Restore FPB registers */
229 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
231 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
234 /* Restore DWT registers */
235 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
237 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
238 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
239 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
241 swjdp_transaction_endcheck(swjdp
);
243 armv7m_invalidate_core_regs(target
);
247 int cortex_m3_examine_debug_reason(target_t
*target
)
249 /* get pointers to arch-specific information */
250 armv7m_common_t
*armv7m
= target
->arch_info
;
251 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
253 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
254 /* only check the debug reason if we don't know it already */
256 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
257 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
261 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
263 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
264 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
265 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
267 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
268 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
274 int cortex_m3_examine_exception_reason(target_t
*target
)
276 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
278 /* get pointers to arch-specific information */
279 armv7m_common_t
*armv7m
= target
->arch_info
;
280 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
281 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
283 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
284 switch (armv7m
->exception_number
)
288 case 3: /* Hard Fault */
289 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
290 if (except_sr
& 0x40000000)
292 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
295 case 4: /* Memory Management */
296 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
297 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
299 case 5: /* Bus Fault */
300 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
301 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
303 case 6: /* Usage Fault */
304 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
306 case 11: /* SVCall */
308 case 12: /* Debug Monitor */
309 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
311 case 14: /* PendSV */
313 case 15: /* SysTick */
319 swjdp_transaction_endcheck(swjdp
);
320 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
321 shcsr
, except_sr
, cfsr
, except_ar
);
325 int cortex_m3_debug_entry(target_t
*target
)
331 /* get pointers to arch-specific information */
332 armv7m_common_t
*armv7m
= target
->arch_info
;
333 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
334 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
337 if (armv7m
->pre_debug_entry
)
338 armv7m
->pre_debug_entry(target
);
340 cortex_m3_clear_halt(target
);
341 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
343 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
346 /* Examine target state and mode */
347 /* First load register acessible through core debug port*/
348 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
350 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
351 armv7m
->read_core_reg(target
, i
);
354 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
356 #ifdef ARMV7_GDB_HACKS
357 /* copy real xpsr reg for gdb, setting thumb bit */
358 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
359 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
360 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
361 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
364 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
367 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
368 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
371 /* Now we can load SP core registers */
372 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
374 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
375 armv7m
->read_core_reg(target
, i
);
378 /* Are we in an exception handler */
381 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
382 armv7m
->exception_number
= (xPSR
& 0x1FF);
386 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
387 armv7m
->exception_number
= 0;
390 if (armv7m
->exception_number
)
392 cortex_m3_examine_exception_reason(target
);
395 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
396 armv7m_mode_strings
[armv7m
->core_mode
],
397 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
398 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
400 if (armv7m
->post_debug_entry
)
401 armv7m
->post_debug_entry(target
);
406 int cortex_m3_poll(target_t
*target
)
409 enum target_state prev_target_state
= target
->state
;
411 /* get pointers to arch-specific information */
412 armv7m_common_t
*armv7m
= target
->arch_info
;
413 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
414 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
416 /* Read from Debug Halting Control and Status Register */
417 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
418 if (retval
!= ERROR_OK
)
420 target
->state
= TARGET_UNKNOWN
;
424 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
426 /* check if still in reset */
427 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
429 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
431 target
->state
= TARGET_RESET
;
436 if (target
->state
== TARGET_RESET
)
438 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
439 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
440 cortex_m3_endreset_event(target
);
441 target
->state
= TARGET_RUNNING
;
442 prev_target_state
= TARGET_RUNNING
;
445 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
447 target
->state
= TARGET_HALTED
;
449 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
451 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
454 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
456 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
459 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
462 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
467 if (cortex_m3->dcb_dhcsr & S_SLEEP)
468 target->state = TARGET_SLEEP;
472 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
473 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
474 LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_dfsr
, Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
480 int cortex_m3_halt(target_t
*target
)
482 LOG_DEBUG("target->state: %s",
483 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
485 if (target
->state
== TARGET_HALTED
)
487 LOG_DEBUG("target was already halted");
491 if (target
->state
== TARGET_UNKNOWN
)
493 LOG_WARNING("target was in unknown state when halt was requested");
496 if (target
->state
== TARGET_RESET
)
498 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
500 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
501 return ERROR_TARGET_FAILURE
;
505 /* we came here in a reset_halt or reset_init sequence
506 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
508 target
->debug_reason
= DBG_REASON_DBGRQ
;
514 /* Write to Debug Halting Control and Status Register */
515 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
517 target
->debug_reason
= DBG_REASON_DBGRQ
;
522 int cortex_m3_soft_reset_halt(struct target_s
*target
)
524 /* get pointers to arch-specific information */
525 armv7m_common_t
*armv7m
= target
->arch_info
;
526 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
527 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
529 int retval
, timeout
= 0;
531 /* Enter debug state on reset, cf. end_reset_event() */
532 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
534 /* Request a reset */
535 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
536 target
->state
= TARGET_RESET
;
538 /* registers are now invalid */
539 armv7m_invalidate_core_regs(target
);
541 while (timeout
< 100)
543 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
544 if (retval
== ERROR_OK
)
546 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
547 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
549 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
550 cortex_m3_poll(target
);
554 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
563 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
565 /* get pointers to arch-specific information */
566 armv7m_common_t
*armv7m
= target
->arch_info
;
567 breakpoint_t
*breakpoint
= NULL
;
570 if (target
->state
!= TARGET_HALTED
)
572 LOG_WARNING("target not halted");
573 return ERROR_TARGET_NOT_HALTED
;
576 if (!debug_execution
)
578 target_free_all_working_areas(target
);
579 cortex_m3_enable_breakpoints(target
);
580 cortex_m3_enable_watchpoints(target
);
585 /* Disable interrupts */
586 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
587 * This is probably the same issue as Cortex-M3 Errata 377493:
588 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
589 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
590 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
591 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
593 /* Make sure we are in Thumb mode */
594 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
595 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
596 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
597 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
600 /* current = 1: continue on current pc, otherwise continue at <address> */
603 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
604 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
605 armv7m
->core_cache
->reg_list
[15].valid
= 1;
608 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
610 armv7m_restore_context(target
);
612 /* the front-end may request us not to handle breakpoints */
613 if (handle_breakpoints
)
615 /* Single step past breakpoint at current address */
616 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
618 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
619 cortex_m3_unset_breakpoint(target
, breakpoint
);
620 cortex_m3_single_step_core(target
);
621 cortex_m3_set_breakpoint(target
, breakpoint
);
626 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
628 target
->debug_reason
= DBG_REASON_NOTHALTED
;
630 /* registers are now invalid */
631 armv7m_invalidate_core_regs(target
);
632 if (!debug_execution
)
634 target
->state
= TARGET_RUNNING
;
635 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
636 LOG_DEBUG("target resumed at 0x%x", resume_pc
);
640 target
->state
= TARGET_DEBUG_RUNNING
;
641 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
642 LOG_DEBUG("target debug resumed at 0x%x", resume_pc
);
648 /* int irqstepcount=0; */
649 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
651 /* get pointers to arch-specific information */
652 armv7m_common_t
*armv7m
= target
->arch_info
;
653 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
654 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
655 breakpoint_t
*breakpoint
= NULL
;
657 if (target
->state
!= TARGET_HALTED
)
659 LOG_WARNING("target not halted");
660 return ERROR_TARGET_NOT_HALTED
;
663 /* current = 1: continue on current pc, otherwise continue at <address> */
665 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
667 /* the front-end may request us not to handle breakpoints */
668 if (handle_breakpoints
)
669 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
670 cortex_m3_unset_breakpoint(target
, breakpoint
);
672 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
674 armv7m_restore_context(target
);
676 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
678 /* set step and clear halt */
679 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
680 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
682 /* registers are now invalid */
683 armv7m_invalidate_core_regs(target
);
686 cortex_m3_set_breakpoint(target
, breakpoint
);
688 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
690 cortex_m3_debug_entry(target
);
691 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
693 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
697 int cortex_m3_assert_reset(target_t
*target
)
699 armv7m_common_t
*armv7m
= target
->arch_info
;
700 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
701 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
704 LOG_DEBUG("target->state: %s",
705 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
707 if (!(jtag_reset_config
& RESET_HAS_SRST
))
709 LOG_ERROR("Can't assert SRST");
713 /* Enable debug requests */
714 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
715 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
716 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
718 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
720 if (!target
->reset_halt
)
722 /* Set/Clear C_MASKINTS in a separate operation */
723 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
724 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
726 cortex_m3_clear_halt(target
);
728 /* Enter debug state on reset, cf. end_reset_event() */
729 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
733 /* Enter debug state on reset, cf. end_reset_event() */
734 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
737 /* following hack is to handle luminary reset
738 * when srst is asserted the luminary device seesm to also clear the debug registers
739 * which does not match the armv7 debug TRM */
741 if (strcmp(cortex_m3
->variant
, "lm3s") == 0)
743 /* get revision of lm3s target, only early silicon has this issue
744 * Fury Rev B, DustDevil Rev B, Tempest all ok */
748 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
750 switch ((did0
>> 16) & 0xff)
753 /* all Sandstorm suffer issue */
759 /* only Fury/DustDevil rev A suffer reset problems */
760 if (((did0
>> 8) & 0xff) == 0)
769 /* default to asserting srst */
770 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
772 jtag_add_reset(1, 1);
776 jtag_add_reset(0, 1);
781 /* this causes the luminary device to reset using the watchdog */
782 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
783 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
786 /* I do not know why this is necessary, but it fixes strange effects
787 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
789 ahbap_read_system_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
793 target
->state
= TARGET_RESET
;
794 jtag_add_sleep(50000);
796 armv7m_invalidate_core_regs(target
);
798 if (target
->reset_halt
)
801 if ((retval
= target_halt(target
))!=ERROR_OK
)
808 int cortex_m3_deassert_reset(target_t
*target
)
810 LOG_DEBUG("target->state: %s",
811 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
813 /* deassert reset lines */
814 jtag_add_reset(0, 0);
819 void cortex_m3_enable_breakpoints(struct target_s
*target
)
821 breakpoint_t
*breakpoint
= target
->breakpoints
;
823 /* set any pending breakpoints */
826 if (breakpoint
->set
== 0)
827 cortex_m3_set_breakpoint(target
, breakpoint
);
828 breakpoint
= breakpoint
->next
;
832 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
838 /* get pointers to arch-specific information */
839 armv7m_common_t
*armv7m
= target
->arch_info
;
840 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
842 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
846 LOG_WARNING("breakpoint already set");
850 if (cortex_m3
->auto_bp_type
)
852 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
855 if (breakpoint
->type
== BKPT_HARD
)
857 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
859 if (fp_num
>= cortex_m3
->fp_num_code
)
861 LOG_DEBUG("ERROR Can not find free FP Comparator");
862 LOG_WARNING("ERROR Can not find free FP Comparator");
865 breakpoint
->set
= fp_num
+ 1;
866 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
867 comparator_list
[fp_num
].used
= 1;
868 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
869 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
870 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
872 else if (breakpoint
->type
== BKPT_SOFT
)
875 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
876 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
880 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
884 breakpoint
->set
= 0x11; /* Any nice value but 0 */
890 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
893 /* get pointers to arch-specific information */
894 armv7m_common_t
*armv7m
= target
->arch_info
;
895 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
896 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
898 if (!breakpoint
->set
)
900 LOG_WARNING("breakpoint not set");
904 if (breakpoint
->type
== BKPT_HARD
)
906 int fp_num
= breakpoint
->set
- 1;
907 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
909 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
912 comparator_list
[fp_num
].used
= 0;
913 comparator_list
[fp_num
].fpcr_value
= 0;
914 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
918 /* restore original instruction (kept in target endianness) */
919 if (breakpoint
->length
== 4)
921 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
928 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
939 int cortex_m3_add_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 (cortex_m3
->auto_bp_type
)
947 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
948 #ifdef ARMV7_GDB_HACKS
949 if (breakpoint
->length
!= 2) {
950 /* XXX Hack: Replace all breakpoints with length != 2 with
951 * a hardware breakpoint. */
952 breakpoint
->type
= BKPT_HARD
;
953 breakpoint
->length
= 2;
958 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
960 LOG_INFO("flash patch comparator requested outside code memory region");
961 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
964 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
966 LOG_INFO("soft breakpoint requested in code (flash) memory region");
967 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
970 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
972 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
973 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
976 if ((breakpoint
->length
!= 2))
978 LOG_INFO("only breakpoints of two bytes length supported");
979 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
982 if (breakpoint
->type
== BKPT_HARD
)
983 cortex_m3
->fp_code_available
--;
984 cortex_m3_set_breakpoint(target
, breakpoint
);
989 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
991 /* get pointers to arch-specific information */
992 armv7m_common_t
*armv7m
= target
->arch_info
;
993 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
995 if (target
->state
!= TARGET_HALTED
)
997 LOG_WARNING("target not halted");
998 return ERROR_TARGET_NOT_HALTED
;
1001 if (cortex_m3
->auto_bp_type
)
1003 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1006 if (breakpoint
->set
)
1008 cortex_m3_unset_breakpoint(target
, breakpoint
);
1011 if (breakpoint
->type
== BKPT_HARD
)
1012 cortex_m3
->fp_code_available
++;
1017 int cortex_m3_set_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
;
1027 if (watchpoint
->set
)
1029 LOG_WARNING("watchpoint already set");
1033 if (watchpoint
->mask
== 0xffffffffu
)
1035 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1037 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1039 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1040 LOG_WARNING("ERROR Can not find free DWT Comparator");
1043 watchpoint
->set
= dwt_num
+ 1;
1045 temp
= watchpoint
->length
;
1051 comparator_list
[dwt_num
].used
= 1;
1052 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1053 comparator_list
[dwt_num
].mask
= mask
;
1054 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1055 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1056 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1057 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1058 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
);
1062 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1070 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1072 /* get pointers to arch-specific information */
1073 armv7m_common_t
*armv7m
= target
->arch_info
;
1074 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1075 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1078 if (!watchpoint
->set
)
1080 LOG_WARNING("watchpoint not set");
1084 dwt_num
= watchpoint
->set
- 1;
1086 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1088 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1091 comparator_list
[dwt_num
].used
= 0;
1092 comparator_list
[dwt_num
].function
= 0;
1093 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1095 watchpoint
->set
= 0;
1100 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1102 /* get pointers to arch-specific information */
1103 armv7m_common_t
*armv7m
= target
->arch_info
;
1104 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1106 if (target
->state
!= TARGET_HALTED
)
1108 LOG_WARNING("target not halted");
1109 return ERROR_TARGET_NOT_HALTED
;
1112 if (cortex_m3
->dwt_comp_available
< 1)
1114 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1117 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1119 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1122 cortex_m3
->dwt_comp_available
--;
1127 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1129 /* get pointers to arch-specific information */
1130 armv7m_common_t
*armv7m
= target
->arch_info
;
1131 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1133 if (target
->state
!= TARGET_HALTED
)
1135 LOG_WARNING("target not halted");
1136 return ERROR_TARGET_NOT_HALTED
;
1139 if (watchpoint
->set
)
1141 cortex_m3_unset_watchpoint(target
, watchpoint
);
1144 cortex_m3
->dwt_comp_available
++;
1149 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1151 watchpoint_t
*watchpoint
= target
->watchpoints
;
1153 /* set any pending watchpoints */
1156 if (watchpoint
->set
== 0)
1157 cortex_m3_set_watchpoint(target
, watchpoint
);
1158 watchpoint
= watchpoint
->next
;
1162 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1165 /* get pointers to arch-specific information */
1166 armv7m_common_t
*armv7m
= target
->arch_info
;
1167 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1168 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1170 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1172 /* read a normal core register */
1173 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1175 if (retval
!= ERROR_OK
)
1177 LOG_ERROR("JTAG failure %i",retval
);
1178 return ERROR_JTAG_DEVICE_ERROR
;
1180 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1182 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1184 /* read other registers */
1185 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1190 *value
= buf_get_u32((u8
*)value
, 0, 8);
1194 *value
= buf_get_u32((u8
*)value
, 8, 8);
1198 *value
= buf_get_u32((u8
*)value
, 16, 8);
1202 *value
= buf_get_u32((u8
*)value
, 24, 8);
1206 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1210 return ERROR_INVALID_ARGUMENTS
;
1216 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1221 /* get pointers to arch-specific information */
1222 armv7m_common_t
*armv7m
= target
->arch_info
;
1223 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1224 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1226 #ifdef ARMV7_GDB_HACKS
1227 /* If the LR register is being modified, make sure it will put us
1228 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1229 * hack to deal with the fact that gdb will sometimes "forge"
1230 * return addresses, and doesn't set the LSB correctly (i.e., when
1231 * printing expressions containing function calls, it sets LR=0.) */
1237 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1239 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1240 if (retval
!= ERROR_OK
)
1242 LOG_ERROR("JTAG failure %i", retval
);
1243 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1244 return ERROR_JTAG_DEVICE_ERROR
;
1246 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1248 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1250 /* write other registers */
1252 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1257 buf_set_u32((u8
*)®
, 0, 8, value
);
1261 buf_set_u32((u8
*)®
, 8, 8, value
);
1265 buf_set_u32((u8
*)®
, 16, 8, value
);
1269 buf_set_u32((u8
*)®
, 24, 8, value
);
1273 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1275 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1279 return ERROR_INVALID_ARGUMENTS
;
1285 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1287 /* get pointers to arch-specific information */
1288 armv7m_common_t
*armv7m
= target
->arch_info
;
1289 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1290 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1293 /* sanitize arguments */
1294 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1295 return ERROR_INVALID_ARGUMENTS
;
1297 /* cortex_m3 handles unaligned memory access */
1302 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1305 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1308 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1311 LOG_ERROR("BUG: we shouldn't get here");
1318 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1320 /* get pointers to arch-specific information */
1321 armv7m_common_t
*armv7m
= target
->arch_info
;
1322 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1323 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1326 /* sanitize arguments */
1327 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1328 return ERROR_INVALID_ARGUMENTS
;
1333 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1336 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1339 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1342 LOG_ERROR("BUG: we shouldn't get here");
1349 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1351 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1354 void cortex_m3_build_reg_cache(target_t
*target
)
1356 armv7m_build_reg_cache(target
);
1359 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1361 cortex_m3_build_reg_cache(target
);
1365 int cortex_m3_examine(struct target_s
*target
)
1368 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1371 /* get pointers to arch-specific information */
1372 armv7m_common_t
*armv7m
= target
->arch_info
;
1373 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1374 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1376 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1379 if (!target
->type
->examined
)
1381 target
->type
->examined
= 1;
1383 /* Read from Device Identification Registers */
1384 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1387 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1388 LOG_DEBUG("CORTEX-M3 processor detected");
1389 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1391 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1392 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1393 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1394 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1396 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1397 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1401 target_read_u32(target
, FP_CTRL
, &fpcr
);
1402 cortex_m3
->auto_bp_type
= 1;
1403 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1404 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1405 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1406 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1407 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1409 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1410 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1412 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1415 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1416 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1417 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1418 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1419 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1421 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1428 int cortex_m3_quit(void)
1434 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1438 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1440 *value
= (u8
)(dcrdr
>> 8);
1442 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1444 /* write ack back to software dcc register
1445 * signify we have read data */
1446 if (dcrdr
& (1 << 0))
1449 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1455 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1457 armv7m_common_t
*armv7m
= target
->arch_info
;
1458 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1459 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1464 for (i
= 0; i
< (size
* 4); i
++)
1466 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1473 int cortex_m3_handle_target_request(void *priv
)
1475 target_t
*target
= priv
;
1476 if (!target
->type
->examined
)
1478 armv7m_common_t
*armv7m
= target
->arch_info
;
1479 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1480 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1482 if (!target
->dbg_msg_enabled
)
1485 if (target
->state
== TARGET_RUNNING
)
1490 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1492 /* check if we have data */
1493 if (ctrl
& (1 << 0))
1497 /* we assume target is quick enough */
1499 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1500 request
|= (data
<< 8);
1501 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1502 request
|= (data
<< 16);
1503 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1504 request
|= (data
<< 24);
1505 target_request(target
, request
);
1512 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, const char *variant
)
1514 armv7m_common_t
*armv7m
;
1515 armv7m
= &cortex_m3
->armv7m
;
1517 /* prepare JTAG information for the new target */
1518 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1519 cortex_m3
->jtag_info
.scann_size
= 4;
1521 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1522 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1523 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1524 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1526 /* initialize arch-specific breakpoint handling */
1528 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1529 cortex_m3
->arch_info
= NULL
;
1531 /* register arch-specific functions */
1532 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1534 armv7m
->pre_debug_entry
= NULL
;
1535 armv7m
->post_debug_entry
= NULL
;
1537 armv7m
->pre_restore_context
= NULL
;
1538 armv7m
->post_restore_context
= NULL
;
1542 cortex_m3
->variant
= strdup(variant
);
1546 cortex_m3
->variant
= strdup("");
1549 armv7m_init_arch_info(target
, armv7m
);
1550 armv7m
->arch_info
= cortex_m3
;
1551 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1552 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1554 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1559 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1561 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1563 cortex_m3_init_arch_info(target
, cortex_m3
, target
->chain_position
, target
->variant
);
1568 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1572 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)