1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
27 #include "replacements.h"
29 #include "cortex_m3.h"
34 #include "target_request.h"
43 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
45 /* forward declarations */
46 void cortex_m3_enable_breakpoints(struct target_s
*target
);
47 void cortex_m3_enable_watchpoints(struct target_s
*target
);
48 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
);
49 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
51 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
52 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
53 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
54 int cortex_m3_examine(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
56 #ifdef ARMV7_GDB_HACKS
57 extern u8 armv7m_gdb_dummy_cpsr_value
[];
58 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
61 target_type_t cortexm3_target
=
65 .poll
= cortex_m3_poll
,
66 .arch_state
= armv7m_arch_state
,
68 .target_request_data
= cortex_m3_target_request_data
,
70 .halt
= cortex_m3_halt
,
71 .resume
= cortex_m3_resume
,
72 .step
= cortex_m3_step
,
74 .assert_reset
= cortex_m3_assert_reset
,
75 .deassert_reset
= cortex_m3_deassert_reset
,
76 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
78 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
80 .read_memory
= cortex_m3_read_memory
,
81 .write_memory
= cortex_m3_write_memory
,
82 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
83 .checksum_memory
= armv7m_checksum_memory
,
84 .blank_check_memory
= armv7m_blank_check_memory
,
86 .run_algorithm
= armv7m_run_algorithm
,
88 .add_breakpoint
= cortex_m3_add_breakpoint
,
89 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
90 .add_watchpoint
= cortex_m3_add_watchpoint
,
91 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
93 .register_commands
= cortex_m3_register_commands
,
94 .target_command
= cortex_m3_target_command
,
95 .init_target
= cortex_m3_init_target
,
96 .examine
= cortex_m3_examine
,
97 .quit
= cortex_m3_quit
100 int cortex_m3_clear_halt(target_t
*target
)
102 /* get pointers to arch-specific information */
103 armv7m_common_t
*armv7m
= target
->arch_info
;
104 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
105 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
107 /* Read Debug Fault Status Register */
108 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
109 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
110 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
111 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
116 int cortex_m3_single_step_core(target_t
*target
)
118 /* get pointers to arch-specific information */
119 armv7m_common_t
*armv7m
= target
->arch_info
;
120 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
121 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
123 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
124 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
125 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
126 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
128 cortex_m3_clear_halt(target
);
133 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
135 /* get pointers to arch-specific information */
136 armv7m_common_t
*armv7m
= target
->arch_info
;
137 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
138 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
142 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
143 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
144 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
145 cortex_m3_single_step_core(target
);
146 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
147 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
153 /* Enable interrupts */
154 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
156 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
159 /* Disable interrupts */
160 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
162 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
166 int cortex_m3_endreset_event(target_t
*target
)
171 /* get pointers to arch-specific information */
172 armv7m_common_t
*armv7m
= target
->arch_info
;
173 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
174 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
175 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
176 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
178 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
179 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
181 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
183 /* Enable debug requests */
184 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
185 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
186 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
187 /* Enable trace and dwt */
188 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
189 /* Monitor bus faults */
190 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
193 target_write_u32(target
, FP_CTRL
, 3);
195 /* Restore FPB registers */
196 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
198 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
201 /* Restore DWT registers */
202 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
204 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
205 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
206 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
208 swjdp_transaction_endcheck(swjdp
);
210 armv7m_invalidate_core_regs(target
);
214 int cortex_m3_examine_debug_reason(target_t
*target
)
216 /* get pointers to arch-specific information */
217 armv7m_common_t
*armv7m
= target
->arch_info
;
218 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
220 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
221 /* only check the debug reason if we don't know it already */
223 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
224 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
228 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
230 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
231 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
232 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
234 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
235 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
241 int cortex_m3_examine_exception_reason(target_t
*target
)
243 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
245 /* get pointers to arch-specific information */
246 armv7m_common_t
*armv7m
= target
->arch_info
;
247 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
248 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
250 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
251 switch (armv7m
->exception_number
)
255 case 3: /* Hard Fault */
256 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
257 if (except_sr
& 0x40000000)
259 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
262 case 4: /* Memory Management */
263 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
264 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
266 case 5: /* Bus Fault */
267 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
268 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
270 case 6: /* Usage Fault */
271 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
273 case 11: /* SVCall */
275 case 12: /* Debug Monitor */
276 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
278 case 14: /* PendSV */
280 case 15: /* SysTick */
286 swjdp_transaction_endcheck(swjdp
);
287 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
288 shcsr
, except_sr
, cfsr
, except_ar
);
292 int cortex_m3_debug_entry(target_t
*target
)
298 /* get pointers to arch-specific information */
299 armv7m_common_t
*armv7m
= target
->arch_info
;
300 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
301 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
304 if (armv7m
->pre_debug_entry
)
305 armv7m
->pre_debug_entry(target
);
307 cortex_m3_clear_halt(target
);
308 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
310 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
313 /* Examine target state and mode */
314 /* First load register acessible through core debug port*/
315 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
317 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
318 armv7m
->read_core_reg(target
, i
);
321 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
323 #ifdef ARMV7_GDB_HACKS
324 /* copy real xpsr reg for gdb, setting thumb bit */
325 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
326 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
327 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
328 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
331 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
334 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
335 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
338 /* Now we can load SP core registers */
339 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
341 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
342 armv7m
->read_core_reg(target
, i
);
345 /* Are we in an exception handler */
348 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
349 armv7m
->exception_number
= (xPSR
& 0x1FF);
353 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
354 armv7m
->exception_number
= 0;
357 if (armv7m
->exception_number
)
359 cortex_m3_examine_exception_reason(target
);
362 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings
[armv7m
->core_mode
], \
363 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
365 if (armv7m
->post_debug_entry
)
366 armv7m
->post_debug_entry(target
);
371 int cortex_m3_poll(target_t
*target
)
374 u32 prev_target_state
= target
->state
;
376 /* get pointers to arch-specific information */
377 armv7m_common_t
*armv7m
= target
->arch_info
;
378 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
379 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
381 /* Read from Debug Halting Control and Status Register */
382 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
383 if (retval
!= ERROR_OK
)
385 target
->state
= TARGET_UNKNOWN
;
389 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
391 /* check if still in reset */
392 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
394 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
396 target
->state
= TARGET_RESET
;
401 if (target
->state
== TARGET_RESET
)
403 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
404 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
405 cortex_m3_endreset_event(target
);
406 target
->state
= TARGET_RUNNING
;
407 prev_target_state
= TARGET_RUNNING
;
410 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
412 target
->state
= TARGET_HALTED
;
414 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
416 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
419 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
421 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
424 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
427 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
432 if (cortex_m3->dcb_dhcsr & S_SLEEP)
433 target->state = TARGET_SLEEP;
437 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
438 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
439 LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_dfsr
, target_state_strings
[target
->state
]);
445 int cortex_m3_halt(target_t
*target
)
447 /* get pointers to arch-specific information */
448 armv7m_common_t
*armv7m
= target
->arch_info
;
449 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
450 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
452 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
454 if (target
->state
== TARGET_HALTED
)
456 LOG_DEBUG("target was already halted");
460 if (target
->state
== TARGET_UNKNOWN
)
462 LOG_WARNING("target was in unknown state when halt was requested");
465 if (target
->state
== TARGET_RESET
)
467 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
469 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
470 return ERROR_TARGET_FAILURE
;
474 /* we came here in a reset_halt or reset_init sequence
475 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
477 target
->debug_reason
= DBG_REASON_DBGRQ
;
483 /* Write to Debug Halting Control and Status Register */
484 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
486 target
->debug_reason
= DBG_REASON_DBGRQ
;
491 int cortex_m3_soft_reset_halt(struct target_s
*target
)
493 /* get pointers to arch-specific information */
494 armv7m_common_t
*armv7m
= target
->arch_info
;
495 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
496 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
498 int retval
, timeout
= 0;
500 /* Enter debug state on reset, cf. end_reset_event() */
501 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
503 /* Request a reset */
504 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
505 target
->state
= TARGET_RESET
;
507 /* registers are now invalid */
508 armv7m_invalidate_core_regs(target
);
510 while (timeout
< 100)
512 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
513 if (retval
== ERROR_OK
)
515 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
516 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
518 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
519 cortex_m3_poll(target
);
523 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
532 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
534 /* get pointers to arch-specific information */
535 armv7m_common_t
*armv7m
= target
->arch_info
;
536 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
537 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
538 breakpoint_t
*breakpoint
= NULL
;
539 u32 dcb_dhcsr
, resume_pc
;
541 if (target
->state
!= TARGET_HALTED
)
543 LOG_WARNING("target not halted");
544 return ERROR_TARGET_NOT_HALTED
;
547 if (!debug_execution
)
549 target_free_all_working_areas(target
);
550 cortex_m3_enable_breakpoints(target
);
551 cortex_m3_enable_watchpoints(target
);
553 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
556 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
559 /* Disable interrupts */
561 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
562 This is probably the same inssue as Cortex-M3 Errata 377493:
563 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
565 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
566 /* Make sure we are in Thumb mode */
567 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
568 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
571 /* current = 1: continue on current pc, otherwise continue at <address> */
574 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
575 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
576 armv7m
->core_cache
->reg_list
[15].valid
= 1;
579 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
581 armv7m_restore_context(target
);
583 /* the front-end may request us not to handle breakpoints */
584 if (handle_breakpoints
)
586 /* Single step past breakpoint at current address */
587 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
589 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
590 cortex_m3_unset_breakpoint(target
, breakpoint
);
591 cortex_m3_single_step_core(target
);
592 cortex_m3_set_breakpoint(target
, breakpoint
);
596 /* Set/Clear C_MASKINTS in a separate operation */
597 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
598 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
601 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
602 target
->debug_reason
= DBG_REASON_NOTHALTED
;
604 /* registers are now invalid */
605 armv7m_invalidate_core_regs(target
);
606 if (!debug_execution
)
608 target
->state
= TARGET_RUNNING
;
609 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
610 LOG_DEBUG("target resumed at 0x%x",resume_pc
);
614 target
->state
= TARGET_DEBUG_RUNNING
;
615 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
616 LOG_DEBUG("target debug resumed at 0x%x",resume_pc
);
622 /* int irqstepcount=0; */
623 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
625 /* get pointers to arch-specific information */
626 armv7m_common_t
*armv7m
= target
->arch_info
;
627 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
628 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
629 breakpoint_t
*breakpoint
= NULL
;
631 if (target
->state
!= TARGET_HALTED
)
633 LOG_WARNING("target not halted");
634 return ERROR_TARGET_NOT_HALTED
;
637 /* current = 1: continue on current pc, otherwise continue at <address> */
639 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
641 /* the front-end may request us not to handle breakpoints */
642 if (handle_breakpoints
)
643 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
644 cortex_m3_unset_breakpoint(target
, breakpoint
);
646 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
648 armv7m_restore_context(target
);
650 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
652 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
653 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
654 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
655 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
657 /* registers are now invalid */
658 armv7m_invalidate_core_regs(target
);
661 cortex_m3_set_breakpoint(target
, breakpoint
);
663 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
665 cortex_m3_debug_entry(target
);
666 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
668 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
672 int cortex_m3_assert_reset(target_t
*target
)
674 armv7m_common_t
*armv7m
= target
->arch_info
;
675 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
676 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
679 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
681 if (!(jtag_reset_config
& RESET_HAS_SRST
))
683 LOG_ERROR("Can't assert SRST");
687 /* Enable debug requests */
688 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
689 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
690 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
692 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
694 if (!target
->reset_halt
)
696 /* Set/Clear C_MASKINTS in a separate operation */
697 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
698 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
700 cortex_m3_clear_halt(target
);
702 /* Enter debug state on reset, cf. end_reset_event() */
703 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
707 /* Enter debug state on reset, cf. end_reset_event() */
708 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
711 /* following hack is to handle luminary reset
712 * when srst is asserted the luminary device seesm to also clear the debug registers
713 * which does not match the armv7 debug TRM */
715 if (strcmp(cortex_m3
->variant
, "lm3s") == 0)
717 /* get revision of lm3s target, only early silicon has this issue
718 * Fury Rev B, DustDevil Rev B, Tempest all ok */
722 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
724 switch ((did0
>> 16) & 0xff)
727 /* all Sandstorm suffer issue */
733 /* only Fury/DustDevil rev A suffer reset problems */
734 if (((did0
>> 8) & 0xff) == 0)
743 /* default to asserting srst */
744 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
746 jtag_add_reset(1, 1);
750 jtag_add_reset(0, 1);
755 /* this causes the luminary device to reset using the watchdog */
756 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
757 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
760 target
->state
= TARGET_RESET
;
761 jtag_add_sleep(50000);
763 armv7m_invalidate_core_regs(target
);
768 int cortex_m3_deassert_reset(target_t
*target
)
770 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
772 /* deassert reset lines */
773 jtag_add_reset(0, 0);
778 void cortex_m3_enable_breakpoints(struct target_s
*target
)
780 breakpoint_t
*breakpoint
= target
->breakpoints
;
782 /* set any pending breakpoints */
785 if (breakpoint
->set
== 0)
786 cortex_m3_set_breakpoint(target
, breakpoint
);
787 breakpoint
= breakpoint
->next
;
791 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
796 /* get pointers to arch-specific information */
797 armv7m_common_t
*armv7m
= target
->arch_info
;
798 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
800 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
804 LOG_WARNING("breakpoint already set");
808 if (cortex_m3
->auto_bp_type
)
810 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
813 if (breakpoint
->type
== BKPT_HARD
)
815 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
817 if (fp_num
>= cortex_m3
->fp_num_code
)
819 LOG_DEBUG("ERROR Can not find free FP Comparator");
820 LOG_WARNING("ERROR Can not find free FP Comparator");
823 breakpoint
->set
= fp_num
+ 1;
824 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
825 comparator_list
[fp_num
].used
= 1;
826 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
827 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
828 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
830 else if (breakpoint
->type
== BKPT_SOFT
)
833 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
834 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
835 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
836 breakpoint
->set
= 0x11; /* Any nice value but 0 */
842 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
844 /* get pointers to arch-specific information */
845 armv7m_common_t
*armv7m
= target
->arch_info
;
846 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
847 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
849 if (!breakpoint
->set
)
851 LOG_WARNING("breakpoint not set");
855 if (breakpoint
->type
== BKPT_HARD
)
857 int fp_num
= breakpoint
->set
- 1;
858 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
860 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
863 comparator_list
[fp_num
].used
= 0;
864 comparator_list
[fp_num
].fpcr_value
= 0;
865 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
869 /* restore original instruction (kept in target endianness) */
870 if (breakpoint
->length
== 4)
872 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
876 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
884 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
886 /* get pointers to arch-specific information */
887 armv7m_common_t
*armv7m
= target
->arch_info
;
888 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
890 if (cortex_m3
->auto_bp_type
)
892 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
893 #ifdef ARMV7_GDB_HACKS
894 if (breakpoint
->length
!= 2) {
895 /* XXX Hack: Replace all breakpoints with length != 2 with
896 * a hardware breakpoint. */
897 breakpoint
->type
= BKPT_HARD
;
898 breakpoint
->length
= 2;
903 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
905 LOG_INFO("flash patch comparator requested outside code memory region");
906 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
909 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
911 LOG_INFO("soft breakpoint requested in code (flash) memory region");
912 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
915 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
917 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
918 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
921 if ((breakpoint
->length
!= 2))
923 LOG_INFO("only breakpoints of two bytes length supported");
924 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
927 if (breakpoint
->type
== BKPT_HARD
)
928 cortex_m3
->fp_code_available
--;
929 cortex_m3_set_breakpoint(target
, breakpoint
);
934 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
936 /* get pointers to arch-specific information */
937 armv7m_common_t
*armv7m
= target
->arch_info
;
938 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
940 if (target
->state
!= TARGET_HALTED
)
942 LOG_WARNING("target not halted");
943 return ERROR_TARGET_NOT_HALTED
;
946 if (cortex_m3
->auto_bp_type
)
948 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
953 cortex_m3_unset_breakpoint(target
, breakpoint
);
956 if (breakpoint
->type
== BKPT_HARD
)
957 cortex_m3
->fp_code_available
++;
962 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
967 /* get pointers to arch-specific information */
968 armv7m_common_t
*armv7m
= target
->arch_info
;
969 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
970 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
974 LOG_WARNING("watchpoint already set");
978 if (watchpoint
->mask
== 0xffffffffu
)
980 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
982 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
984 LOG_DEBUG("ERROR Can not find free DWT Comparator");
985 LOG_WARNING("ERROR Can not find free DWT Comparator");
988 watchpoint
->set
= dwt_num
+ 1;
990 temp
= watchpoint
->length
;
996 comparator_list
[dwt_num
].used
= 1;
997 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
998 comparator_list
[dwt_num
].mask
= mask
;
999 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1000 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1001 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1002 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1003 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
);
1007 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1015 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1017 /* get pointers to arch-specific information */
1018 armv7m_common_t
*armv7m
= target
->arch_info
;
1019 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1020 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1023 if (!watchpoint
->set
)
1025 LOG_WARNING("watchpoint not set");
1029 dwt_num
= watchpoint
->set
- 1;
1031 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1033 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1036 comparator_list
[dwt_num
].used
= 0;
1037 comparator_list
[dwt_num
].function
= 0;
1038 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1040 watchpoint
->set
= 0;
1045 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1047 /* get pointers to arch-specific information */
1048 armv7m_common_t
*armv7m
= target
->arch_info
;
1049 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1051 if (target
->state
!= TARGET_HALTED
)
1053 LOG_WARNING("target not halted");
1054 return ERROR_TARGET_NOT_HALTED
;
1057 if (cortex_m3
->dwt_comp_available
< 1)
1059 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1062 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1064 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1067 cortex_m3
->dwt_comp_available
--;
1072 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1074 /* get pointers to arch-specific information */
1075 armv7m_common_t
*armv7m
= target
->arch_info
;
1076 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1078 if (target
->state
!= TARGET_HALTED
)
1080 LOG_WARNING("target not halted");
1081 return ERROR_TARGET_NOT_HALTED
;
1084 if (watchpoint
->set
)
1086 cortex_m3_unset_watchpoint(target
, watchpoint
);
1089 cortex_m3
->dwt_comp_available
++;
1094 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1096 watchpoint_t
*watchpoint
= target
->watchpoints
;
1098 /* set any pending watchpoints */
1101 if (watchpoint
->set
== 0)
1102 cortex_m3_set_watchpoint(target
, watchpoint
);
1103 watchpoint
= watchpoint
->next
;
1107 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1110 /* get pointers to arch-specific information */
1111 armv7m_common_t
*armv7m
= target
->arch_info
;
1112 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1113 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1115 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1117 /* read a normal core register */
1118 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1120 if (retval
!= ERROR_OK
)
1122 LOG_ERROR("JTAG failure %i",retval
);
1123 return ERROR_JTAG_DEVICE_ERROR
;
1125 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1127 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1129 /* read other registers */
1130 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1135 *value
= buf_get_u32((u8
*)value
, 0, 8);
1139 *value
= buf_get_u32((u8
*)value
, 8, 8);
1143 *value
= buf_get_u32((u8
*)value
, 16, 8);
1147 *value
= buf_get_u32((u8
*)value
, 24, 8);
1151 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1155 return ERROR_INVALID_ARGUMENTS
;
1161 int cortex_m3_store_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 #ifdef ARMV7_GDB_HACKS
1172 /* If the LR register is being modified, make sure it will put us
1173 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1174 * hack to deal with the fact that gdb will sometimes "forge"
1175 * return addresses, and doesn't set the LSB correctly (i.e., when
1176 * printing expressions containing function calls, it sets LR=0.) */
1182 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1184 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1185 if (retval
!= ERROR_OK
)
1187 LOG_ERROR("JTAG failure %i", retval
);
1188 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1189 return ERROR_JTAG_DEVICE_ERROR
;
1191 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1193 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1195 /* write other registers */
1197 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1202 buf_set_u32((u8
*)®
, 0, 8, value
);
1206 buf_set_u32((u8
*)®
, 8, 8, value
);
1210 buf_set_u32((u8
*)®
, 16, 8, value
);
1214 buf_set_u32((u8
*)®
, 24, 8, value
);
1218 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1220 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1224 return ERROR_INVALID_ARGUMENTS
;
1230 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1232 /* get pointers to arch-specific information */
1233 armv7m_common_t
*armv7m
= target
->arch_info
;
1234 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1235 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1238 /* sanitize arguments */
1239 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1240 return ERROR_INVALID_ARGUMENTS
;
1242 /* cortex_m3 handles unaligned memory access */
1247 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1250 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1253 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1256 LOG_ERROR("BUG: we shouldn't get here");
1263 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1265 /* get pointers to arch-specific information */
1266 armv7m_common_t
*armv7m
= target
->arch_info
;
1267 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1268 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1271 /* sanitize arguments */
1272 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1273 return ERROR_INVALID_ARGUMENTS
;
1278 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1281 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1284 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1287 LOG_ERROR("BUG: we shouldn't get here");
1294 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1296 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1299 void cortex_m3_build_reg_cache(target_t
*target
)
1301 armv7m_build_reg_cache(target
);
1304 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1306 cortex_m3_build_reg_cache(target
);
1310 int cortex_m3_examine(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1313 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1316 /* get pointers to arch-specific information */
1317 armv7m_common_t
*armv7m
= target
->arch_info
;
1318 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1319 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1321 target
->type
->examined
= 1;
1323 if ((retval
=ahbap_debugport_init(swjdp
))!=ERROR_OK
)
1326 /* Read from Device Identification Registers */
1327 if ((retval
=target_read_u32(target
, CPUID
, &cpuid
))!=ERROR_OK
)
1330 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1331 LOG_DEBUG("CORTEX-M3 processor detected");
1332 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1334 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1335 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1336 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1337 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1339 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1340 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1344 target_read_u32(target
, FP_CTRL
, &fpcr
);
1345 cortex_m3
->auto_bp_type
= 1;
1346 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1347 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1348 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1349 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1350 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1352 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1353 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1355 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1358 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1359 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1360 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1361 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1362 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1364 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1370 int cortex_m3_quit()
1376 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1380 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1382 *value
= (u8
)(dcrdr
>> 8);
1384 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1386 /* write ack back to software dcc register
1387 * signify we have read data */
1388 if (dcrdr
& (1 << 0))
1391 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1397 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1399 armv7m_common_t
*armv7m
= target
->arch_info
;
1400 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1401 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1406 for (i
= 0; i
< (size
* 4); i
++)
1408 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1415 int cortex_m3_handle_target_request(void *priv
)
1417 target_t
*target
= priv
;
1418 if (!target
->type
->examined
)
1420 armv7m_common_t
*armv7m
= target
->arch_info
;
1421 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1422 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1424 if (!target
->dbg_msg_enabled
)
1427 if (target
->state
== TARGET_RUNNING
)
1432 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1434 /* check if we have data */
1435 if (ctrl
& (1 << 0))
1439 /* we assume target is quick enough */
1441 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1442 request
|= (data
<< 8);
1443 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1444 request
|= (data
<< 16);
1445 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1446 request
|= (data
<< 24);
1447 target_request(target
, request
);
1454 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1456 armv7m_common_t
*armv7m
;
1457 armv7m
= &cortex_m3
->armv7m
;
1459 /* prepare JTAG information for the new target */
1460 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1461 cortex_m3
->jtag_info
.scann_size
= 4;
1463 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1464 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1465 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1466 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1468 /* initialize arch-specific breakpoint handling */
1470 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1471 cortex_m3
->arch_info
= NULL
;
1473 /* register arch-specific functions */
1474 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1476 armv7m
->pre_debug_entry
= NULL
;
1477 armv7m
->post_debug_entry
= NULL
;
1479 armv7m
->pre_restore_context
= NULL
;
1480 armv7m
->post_restore_context
= NULL
;
1484 cortex_m3
->variant
= strdup(variant
);
1488 cortex_m3
->variant
= strdup("");
1491 armv7m_init_arch_info(target
, armv7m
);
1492 armv7m
->arch_info
= cortex_m3
;
1493 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1494 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1496 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1501 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1502 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1505 char *variant
= NULL
;
1506 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1507 memset(cortex_m3
, 0, sizeof(*cortex_m3
));
1511 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1515 chain_pos
= strtoul(args
[3], NULL
, 0);
1520 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1525 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1529 retval
= armv7m_register_commands(cmd_ctx
);