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
);
47 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
49 /* forward declarations */
50 void cortex_m3_enable_breakpoints(struct target_s
*target
);
51 void cortex_m3_enable_watchpoints(struct target_s
*target
);
52 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
);
53 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
54 int cortex_m3_quit(void);
55 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
56 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
57 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
58 int cortex_m3_examine(struct target_s
*target
);
60 #ifdef ARMV7_GDB_HACKS
61 extern u8 armv7m_gdb_dummy_cpsr_value
[];
62 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
65 target_type_t cortexm3_target
=
69 .poll
= cortex_m3_poll
,
70 .arch_state
= armv7m_arch_state
,
72 .target_request_data
= cortex_m3_target_request_data
,
74 .halt
= cortex_m3_halt
,
75 .resume
= cortex_m3_resume
,
76 .step
= cortex_m3_step
,
78 .assert_reset
= cortex_m3_assert_reset
,
79 .deassert_reset
= cortex_m3_deassert_reset
,
80 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
82 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
84 .read_memory
= cortex_m3_read_memory
,
85 .write_memory
= cortex_m3_write_memory
,
86 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
87 .checksum_memory
= armv7m_checksum_memory
,
88 .blank_check_memory
= armv7m_blank_check_memory
,
90 .run_algorithm
= armv7m_run_algorithm
,
92 .add_breakpoint
= cortex_m3_add_breakpoint
,
93 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
94 .add_watchpoint
= cortex_m3_add_watchpoint
,
95 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
97 .register_commands
= cortex_m3_register_commands
,
98 .target_create
= cortex_m3_target_create
,
99 .init_target
= cortex_m3_init_target
,
100 .examine
= cortex_m3_examine
,
101 .quit
= cortex_m3_quit
104 int cortex_m3_write_debug_halt_mask(target_t
*target
, u32 mask_on
, u32 mask_off
)
106 /* get pointers to arch-specific information */
107 armv7m_common_t
*armv7m
= target
->arch_info
;
108 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
109 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
111 /* mask off status bits */
112 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
113 /* create new register mask */
114 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
116 return ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
119 int cortex_m3_clear_halt(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 /* clear step if any */
127 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
129 /* Read Debug Fault Status Register */
130 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
131 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
132 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
133 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
138 int cortex_m3_single_step_core(target_t
*target
)
140 /* get pointers to arch-specific information */
141 armv7m_common_t
*armv7m
= target
->arch_info
;
142 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
143 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
146 /* backup dhcsr reg */
147 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
149 /* mask interrupts if not done already */
150 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
151 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
152 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
155 /* restore dhcsr reg */
156 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
157 cortex_m3_clear_halt(target
);
162 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
164 /* get pointers to arch-specific information */
165 armv7m_common_t
*armv7m
= target
->arch_info
;
166 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
167 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
171 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
172 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
173 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
174 cortex_m3_single_step_core(target
);
175 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
176 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
182 /* Enable interrupts */
183 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
185 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
188 /* Disable interrupts */
189 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
191 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
195 int cortex_m3_endreset_event(target_t
*target
)
200 /* get pointers to arch-specific information */
201 armv7m_common_t
*armv7m
= target
->arch_info
;
202 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
203 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
204 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
205 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
207 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
208 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
210 /* this regsiter is used for emulated dcc channel */
211 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0);
213 /* Enable debug requests */
214 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
215 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
216 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
218 /* clear any interrupt masking */
219 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
221 /* Enable trace and dwt */
222 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
223 /* Monitor bus faults */
224 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
227 target_write_u32(target
, FP_CTRL
, 3);
229 /* Restore FPB registers */
230 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
232 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
235 /* Restore DWT registers */
236 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
238 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
239 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
240 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
242 swjdp_transaction_endcheck(swjdp
);
244 armv7m_invalidate_core_regs(target
);
248 int cortex_m3_examine_debug_reason(target_t
*target
)
250 /* get pointers to arch-specific information */
251 armv7m_common_t
*armv7m
= target
->arch_info
;
252 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
254 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
255 /* only check the debug reason if we don't know it already */
257 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
258 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
262 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
264 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
265 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
266 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
268 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
269 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
275 int cortex_m3_examine_exception_reason(target_t
*target
)
277 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
279 /* get pointers to arch-specific information */
280 armv7m_common_t
*armv7m
= target
->arch_info
;
281 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
282 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
284 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
285 switch (armv7m
->exception_number
)
289 case 3: /* Hard Fault */
290 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
291 if (except_sr
& 0x40000000)
293 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
296 case 4: /* Memory Management */
297 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
298 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
300 case 5: /* Bus Fault */
301 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
302 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
304 case 6: /* Usage Fault */
305 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
307 case 11: /* SVCall */
309 case 12: /* Debug Monitor */
310 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
312 case 14: /* PendSV */
314 case 15: /* SysTick */
320 swjdp_transaction_endcheck(swjdp
);
321 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
322 shcsr
, except_sr
, cfsr
, except_ar
);
326 int cortex_m3_debug_entry(target_t
*target
)
332 /* get pointers to arch-specific information */
333 armv7m_common_t
*armv7m
= target
->arch_info
;
334 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
335 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
338 if (armv7m
->pre_debug_entry
)
339 armv7m
->pre_debug_entry(target
);
341 cortex_m3_clear_halt(target
);
342 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
344 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
347 /* Examine target state and mode */
348 /* First load register acessible through core debug port*/
349 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
351 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
352 armv7m
->read_core_reg(target
, i
);
355 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
357 #ifdef ARMV7_GDB_HACKS
358 /* copy real xpsr reg for gdb, setting thumb bit */
359 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
360 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
361 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
362 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
365 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
368 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
369 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
372 /* Now we can load SP core registers */
373 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
375 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
376 armv7m
->read_core_reg(target
, i
);
379 /* Are we in an exception handler */
382 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
383 armv7m
->exception_number
= (xPSR
& 0x1FF);
387 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
388 armv7m
->exception_number
= 0;
391 if (armv7m
->exception_number
)
393 cortex_m3_examine_exception_reason(target
);
396 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
397 armv7m_mode_strings
[armv7m
->core_mode
],
398 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
399 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
401 if (armv7m
->post_debug_entry
)
402 armv7m
->post_debug_entry(target
);
407 int cortex_m3_poll(target_t
*target
)
410 enum target_state prev_target_state
= target
->state
;
412 /* get pointers to arch-specific information */
413 armv7m_common_t
*armv7m
= target
->arch_info
;
414 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
415 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
417 /* Read from Debug Halting Control and Status Register */
418 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
419 if (retval
!= ERROR_OK
)
421 target
->state
= TARGET_UNKNOWN
;
425 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
427 /* check if still in reset */
428 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
430 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
432 target
->state
= TARGET_RESET
;
437 if (target
->state
== TARGET_RESET
)
439 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
440 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
441 cortex_m3_endreset_event(target
);
442 target
->state
= TARGET_RUNNING
;
443 prev_target_state
= TARGET_RUNNING
;
446 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
448 target
->state
= TARGET_HALTED
;
450 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
452 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
455 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
457 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
460 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
463 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
468 if (cortex_m3->dcb_dhcsr & S_SLEEP)
469 target->state = TARGET_SLEEP;
473 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
474 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
475 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
);
481 int cortex_m3_halt(target_t
*target
)
483 LOG_DEBUG("target->state: %s",
484 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
486 if (target
->state
== TARGET_HALTED
)
488 LOG_DEBUG("target was already halted");
492 if (target
->state
== TARGET_UNKNOWN
)
494 LOG_WARNING("target was in unknown state when halt was requested");
497 if (target
->state
== TARGET_RESET
)
499 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
501 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
502 return ERROR_TARGET_FAILURE
;
506 /* we came here in a reset_halt or reset_init sequence
507 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
509 target
->debug_reason
= DBG_REASON_DBGRQ
;
515 /* Write to Debug Halting Control and Status Register */
516 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
518 target
->debug_reason
= DBG_REASON_DBGRQ
;
523 int cortex_m3_soft_reset_halt(struct target_s
*target
)
525 /* get pointers to arch-specific information */
526 armv7m_common_t
*armv7m
= target
->arch_info
;
527 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
528 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
530 int retval
, timeout
= 0;
532 /* Enter debug state on reset, cf. end_reset_event() */
533 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
535 /* Request a reset */
536 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
537 target
->state
= TARGET_RESET
;
539 /* registers are now invalid */
540 armv7m_invalidate_core_regs(target
);
542 while (timeout
< 100)
544 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
545 if (retval
== ERROR_OK
)
547 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
548 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
550 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
551 cortex_m3_poll(target
);
555 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
564 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
566 /* get pointers to arch-specific information */
567 armv7m_common_t
*armv7m
= target
->arch_info
;
568 breakpoint_t
*breakpoint
= NULL
;
571 if (target
->state
!= TARGET_HALTED
)
573 LOG_WARNING("target not halted");
574 return ERROR_TARGET_NOT_HALTED
;
577 if (!debug_execution
)
579 target_free_all_working_areas(target
);
580 cortex_m3_enable_breakpoints(target
);
581 cortex_m3_enable_watchpoints(target
);
586 /* Disable interrupts */
587 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
588 * This is probably the same issue as Cortex-M3 Errata 377493:
589 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
590 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
591 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
592 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
594 /* Make sure we are in Thumb mode */
595 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
596 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
597 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
598 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
601 /* current = 1: continue on current pc, otherwise continue at <address> */
604 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
605 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
606 armv7m
->core_cache
->reg_list
[15].valid
= 1;
609 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
611 armv7m_restore_context(target
);
613 /* the front-end may request us not to handle breakpoints */
614 if (handle_breakpoints
)
616 /* Single step past breakpoint at current address */
617 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
619 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
620 cortex_m3_unset_breakpoint(target
, breakpoint
);
621 cortex_m3_single_step_core(target
);
622 cortex_m3_set_breakpoint(target
, breakpoint
);
627 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
629 target
->debug_reason
= DBG_REASON_NOTHALTED
;
631 /* registers are now invalid */
632 armv7m_invalidate_core_regs(target
);
633 if (!debug_execution
)
635 target
->state
= TARGET_RUNNING
;
636 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
637 LOG_DEBUG("target resumed at 0x%x", resume_pc
);
641 target
->state
= TARGET_DEBUG_RUNNING
;
642 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
643 LOG_DEBUG("target debug resumed at 0x%x", resume_pc
);
649 /* int irqstepcount=0; */
650 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
652 /* get pointers to arch-specific information */
653 armv7m_common_t
*armv7m
= target
->arch_info
;
654 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
655 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
656 breakpoint_t
*breakpoint
= NULL
;
658 if (target
->state
!= TARGET_HALTED
)
660 LOG_WARNING("target not halted");
661 return ERROR_TARGET_NOT_HALTED
;
664 /* current = 1: continue on current pc, otherwise continue at <address> */
666 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
668 /* the front-end may request us not to handle breakpoints */
669 if (handle_breakpoints
)
670 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
671 cortex_m3_unset_breakpoint(target
, breakpoint
);
673 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
675 armv7m_restore_context(target
);
677 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
679 /* set step and clear halt */
680 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
681 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
683 /* registers are now invalid */
684 armv7m_invalidate_core_regs(target
);
687 cortex_m3_set_breakpoint(target
, breakpoint
);
689 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
691 cortex_m3_debug_entry(target
);
692 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
694 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
698 int cortex_m3_assert_reset(target_t
*target
)
700 armv7m_common_t
*armv7m
= target
->arch_info
;
701 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
702 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
705 LOG_DEBUG("target->state: %s",
706 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
708 if (!(jtag_reset_config
& RESET_HAS_SRST
))
710 LOG_ERROR("Can't assert SRST");
714 /* Enable debug requests */
715 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
716 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
717 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
719 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
721 if (!target
->reset_halt
)
723 /* Set/Clear C_MASKINTS in a separate operation */
724 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
725 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
727 cortex_m3_clear_halt(target
);
729 /* Enter debug state on reset, cf. end_reset_event() */
730 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
734 /* Enter debug state on reset, cf. end_reset_event() */
735 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
738 /* following hack is to handle luminary reset
739 * when srst is asserted the luminary device seesm to also clear the debug registers
740 * which does not match the armv7 debug TRM */
742 if (strcmp(cortex_m3
->variant
, "lm3s") == 0)
744 /* get revision of lm3s target, only early silicon has this issue
745 * Fury Rev B, DustDevil Rev B, Tempest all ok */
749 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
751 switch ((did0
>> 16) & 0xff)
754 /* all Sandstorm suffer issue */
760 /* only Fury/DustDevil rev A suffer reset problems */
761 if (((did0
>> 8) & 0xff) == 0)
770 /* default to asserting srst */
771 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
773 jtag_add_reset(1, 1);
777 jtag_add_reset(0, 1);
782 /* this causes the luminary device to reset using the watchdog */
783 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
784 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
787 /* I do not know why this is necessary, but it fixes strange effects
788 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
790 ahbap_read_system_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
794 target
->state
= TARGET_RESET
;
795 jtag_add_sleep(50000);
797 armv7m_invalidate_core_regs(target
);
799 if (target
->reset_halt
)
802 if ((retval
= target_halt(target
))!=ERROR_OK
)
809 int cortex_m3_deassert_reset(target_t
*target
)
811 LOG_DEBUG("target->state: %s",
812 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
814 /* deassert reset lines */
815 jtag_add_reset(0, 0);
820 void cortex_m3_enable_breakpoints(struct target_s
*target
)
822 breakpoint_t
*breakpoint
= target
->breakpoints
;
824 /* set any pending breakpoints */
827 if (breakpoint
->set
== 0)
828 cortex_m3_set_breakpoint(target
, breakpoint
);
829 breakpoint
= breakpoint
->next
;
833 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
839 /* get pointers to arch-specific information */
840 armv7m_common_t
*armv7m
= target
->arch_info
;
841 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
843 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
847 LOG_WARNING("breakpoint already set");
851 if (cortex_m3
->auto_bp_type
)
853 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
856 if (breakpoint
->type
== BKPT_HARD
)
858 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
860 if (fp_num
>= cortex_m3
->fp_num_code
)
862 LOG_DEBUG("ERROR Can not find free FP Comparator");
863 LOG_WARNING("ERROR Can not find free FP Comparator");
866 breakpoint
->set
= fp_num
+ 1;
867 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
868 comparator_list
[fp_num
].used
= 1;
869 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
870 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
871 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
873 else if (breakpoint
->type
== BKPT_SOFT
)
876 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
877 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
881 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
885 breakpoint
->set
= 0x11; /* Any nice value but 0 */
891 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
894 /* get pointers to arch-specific information */
895 armv7m_common_t
*armv7m
= target
->arch_info
;
896 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
897 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
899 if (!breakpoint
->set
)
901 LOG_WARNING("breakpoint not set");
905 if (breakpoint
->type
== BKPT_HARD
)
907 int fp_num
= breakpoint
->set
- 1;
908 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
910 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
913 comparator_list
[fp_num
].used
= 0;
914 comparator_list
[fp_num
].fpcr_value
= 0;
915 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
919 /* restore original instruction (kept in target endianness) */
920 if (breakpoint
->length
== 4)
922 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
929 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
940 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
942 /* get pointers to arch-specific information */
943 armv7m_common_t
*armv7m
= target
->arch_info
;
944 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
946 if (cortex_m3
->auto_bp_type
)
948 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
949 #ifdef ARMV7_GDB_HACKS
950 if (breakpoint
->length
!= 2) {
951 /* XXX Hack: Replace all breakpoints with length != 2 with
952 * a hardware breakpoint. */
953 breakpoint
->type
= BKPT_HARD
;
954 breakpoint
->length
= 2;
959 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
961 LOG_INFO("flash patch comparator requested outside code memory region");
962 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
965 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
967 LOG_INFO("soft breakpoint requested in code (flash) memory region");
968 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
971 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
973 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
974 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
977 if ((breakpoint
->length
!= 2))
979 LOG_INFO("only breakpoints of two bytes length supported");
980 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
983 if (breakpoint
->type
== BKPT_HARD
)
984 cortex_m3
->fp_code_available
--;
985 cortex_m3_set_breakpoint(target
, breakpoint
);
990 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
992 /* get pointers to arch-specific information */
993 armv7m_common_t
*armv7m
= target
->arch_info
;
994 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
996 if (target
->state
!= TARGET_HALTED
)
998 LOG_WARNING("target not halted");
999 return ERROR_TARGET_NOT_HALTED
;
1002 if (cortex_m3
->auto_bp_type
)
1004 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1007 if (breakpoint
->set
)
1009 cortex_m3_unset_breakpoint(target
, breakpoint
);
1012 if (breakpoint
->type
== BKPT_HARD
)
1013 cortex_m3
->fp_code_available
++;
1018 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1023 /* get pointers to arch-specific information */
1024 armv7m_common_t
*armv7m
= target
->arch_info
;
1025 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1026 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1028 if (watchpoint
->set
)
1030 LOG_WARNING("watchpoint already set");
1034 if (watchpoint
->mask
== 0xffffffffu
)
1036 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1038 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1040 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1041 LOG_WARNING("ERROR Can not find free DWT Comparator");
1044 watchpoint
->set
= dwt_num
+ 1;
1046 temp
= watchpoint
->length
;
1052 comparator_list
[dwt_num
].used
= 1;
1053 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1054 comparator_list
[dwt_num
].mask
= mask
;
1055 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1056 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1057 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1058 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1059 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
);
1063 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1071 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1073 /* get pointers to arch-specific information */
1074 armv7m_common_t
*armv7m
= target
->arch_info
;
1075 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1076 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1079 if (!watchpoint
->set
)
1081 LOG_WARNING("watchpoint not set");
1085 dwt_num
= watchpoint
->set
- 1;
1087 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1089 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1092 comparator_list
[dwt_num
].used
= 0;
1093 comparator_list
[dwt_num
].function
= 0;
1094 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1096 watchpoint
->set
= 0;
1101 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1103 /* get pointers to arch-specific information */
1104 armv7m_common_t
*armv7m
= target
->arch_info
;
1105 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1107 if (target
->state
!= TARGET_HALTED
)
1109 LOG_WARNING("target not halted");
1110 return ERROR_TARGET_NOT_HALTED
;
1113 if (cortex_m3
->dwt_comp_available
< 1)
1115 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1118 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1120 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1123 cortex_m3
->dwt_comp_available
--;
1128 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1130 /* get pointers to arch-specific information */
1131 armv7m_common_t
*armv7m
= target
->arch_info
;
1132 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1134 if (target
->state
!= TARGET_HALTED
)
1136 LOG_WARNING("target not halted");
1137 return ERROR_TARGET_NOT_HALTED
;
1140 if (watchpoint
->set
)
1142 cortex_m3_unset_watchpoint(target
, watchpoint
);
1145 cortex_m3
->dwt_comp_available
++;
1150 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1152 watchpoint_t
*watchpoint
= target
->watchpoints
;
1154 /* set any pending watchpoints */
1157 if (watchpoint
->set
== 0)
1158 cortex_m3_set_watchpoint(target
, watchpoint
);
1159 watchpoint
= watchpoint
->next
;
1163 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1166 /* get pointers to arch-specific information */
1167 armv7m_common_t
*armv7m
= target
->arch_info
;
1168 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1169 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1171 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1173 /* read a normal core register */
1174 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1176 if (retval
!= ERROR_OK
)
1178 LOG_ERROR("JTAG failure %i",retval
);
1179 return ERROR_JTAG_DEVICE_ERROR
;
1181 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1183 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1185 /* read other registers */
1186 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1191 *value
= buf_get_u32((u8
*)value
, 0, 8);
1195 *value
= buf_get_u32((u8
*)value
, 8, 8);
1199 *value
= buf_get_u32((u8
*)value
, 16, 8);
1203 *value
= buf_get_u32((u8
*)value
, 24, 8);
1207 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1211 return ERROR_INVALID_ARGUMENTS
;
1217 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1222 /* get pointers to arch-specific information */
1223 armv7m_common_t
*armv7m
= target
->arch_info
;
1224 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1225 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1227 #ifdef ARMV7_GDB_HACKS
1228 /* If the LR register is being modified, make sure it will put us
1229 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1230 * hack to deal with the fact that gdb will sometimes "forge"
1231 * return addresses, and doesn't set the LSB correctly (i.e., when
1232 * printing expressions containing function calls, it sets LR=0.) */
1238 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1240 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1241 if (retval
!= ERROR_OK
)
1243 LOG_ERROR("JTAG failure %i", retval
);
1244 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1245 return ERROR_JTAG_DEVICE_ERROR
;
1247 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1249 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1251 /* write other registers */
1253 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1258 buf_set_u32((u8
*)®
, 0, 8, value
);
1262 buf_set_u32((u8
*)®
, 8, 8, value
);
1266 buf_set_u32((u8
*)®
, 16, 8, value
);
1270 buf_set_u32((u8
*)®
, 24, 8, value
);
1274 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1276 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1280 return ERROR_INVALID_ARGUMENTS
;
1286 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1288 /* get pointers to arch-specific information */
1289 armv7m_common_t
*armv7m
= target
->arch_info
;
1290 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1291 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1294 /* sanitize arguments */
1295 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1296 return ERROR_INVALID_ARGUMENTS
;
1298 /* cortex_m3 handles unaligned memory access */
1303 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1306 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1309 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1312 LOG_ERROR("BUG: we shouldn't get here");
1319 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1321 /* get pointers to arch-specific information */
1322 armv7m_common_t
*armv7m
= target
->arch_info
;
1323 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1324 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1327 /* sanitize arguments */
1328 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1329 return ERROR_INVALID_ARGUMENTS
;
1334 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1337 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1340 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1343 LOG_ERROR("BUG: we shouldn't get here");
1350 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1352 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1355 void cortex_m3_build_reg_cache(target_t
*target
)
1357 armv7m_build_reg_cache(target
);
1360 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1362 cortex_m3_build_reg_cache(target
);
1366 int cortex_m3_examine(struct target_s
*target
)
1369 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1372 /* get pointers to arch-specific information */
1373 armv7m_common_t
*armv7m
= target
->arch_info
;
1374 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1375 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1377 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1380 if (!target
->type
->examined
)
1382 target
->type
->examined
= 1;
1384 /* Read from Device Identification Registers */
1385 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1388 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1389 LOG_DEBUG("CORTEX-M3 processor detected");
1390 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1392 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1393 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1394 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1395 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1397 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1398 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1402 target_read_u32(target
, FP_CTRL
, &fpcr
);
1403 cortex_m3
->auto_bp_type
= 1;
1404 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1405 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1406 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1407 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1408 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1410 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1411 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1413 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1416 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1417 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1418 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1419 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1420 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1422 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1429 int cortex_m3_quit(void)
1435 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1439 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1441 *value
= (u8
)(dcrdr
>> 8);
1443 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1445 /* write ack back to software dcc register
1446 * signify we have read data */
1447 if (dcrdr
& (1 << 0))
1450 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1456 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1458 armv7m_common_t
*armv7m
= target
->arch_info
;
1459 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1460 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1465 for (i
= 0; i
< (size
* 4); i
++)
1467 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1474 int cortex_m3_handle_target_request(void *priv
)
1476 target_t
*target
= priv
;
1477 if (!target
->type
->examined
)
1479 armv7m_common_t
*armv7m
= target
->arch_info
;
1480 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1481 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1483 if (!target
->dbg_msg_enabled
)
1486 if (target
->state
== TARGET_RUNNING
)
1491 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1493 /* check if we have data */
1494 if (ctrl
& (1 << 0))
1498 /* we assume target is quick enough */
1500 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1501 request
|= (data
<< 8);
1502 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1503 request
|= (data
<< 16);
1504 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1505 request
|= (data
<< 24);
1506 target_request(target
, request
);
1513 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, const char *variant
)
1515 armv7m_common_t
*armv7m
;
1516 armv7m
= &cortex_m3
->armv7m
;
1518 /* prepare JTAG information for the new target */
1519 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1520 cortex_m3
->jtag_info
.scann_size
= 4;
1522 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1523 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1524 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1525 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1527 /* initialize arch-specific breakpoint handling */
1529 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1530 cortex_m3
->arch_info
= NULL
;
1532 /* register arch-specific functions */
1533 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1535 armv7m
->pre_debug_entry
= NULL
;
1536 armv7m
->post_debug_entry
= NULL
;
1538 armv7m
->pre_restore_context
= NULL
;
1539 armv7m
->post_restore_context
= NULL
;
1543 cortex_m3
->variant
= strdup(variant
);
1547 cortex_m3
->variant
= strdup("");
1550 armv7m_init_arch_info(target
, armv7m
);
1551 armv7m
->arch_info
= cortex_m3
;
1552 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1553 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1555 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1560 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1562 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1564 cortex_m3_init_arch_info(target
, cortex_m3
, target
->chain_position
, target
->variant
);
1569 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1572 command_t
*cortex_m3_cmd
;
1574 retval
= armv7m_register_commands(cmd_ctx
);
1576 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3", NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1577 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr", handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
, "mask cortex_m3 interrupts ['on'|'off']");
1582 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1584 target_t
*target
= get_current_target(cmd_ctx
);
1585 armv7m_common_t
*armv7m
= target
->arch_info
;
1586 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1588 if (target
->state
!= TARGET_HALTED
)
1590 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1596 if (!strcmp(args
[0], "on"))
1598 cortex_m3_write_debug_halt_mask(target
, C_HALT
|C_MASKINTS
, 0);
1600 else if (!strcmp(args
[0], "off"))
1602 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1606 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1610 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1611 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
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)