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
,
85 .run_algorithm
= armv7m_run_algorithm
,
87 .add_breakpoint
= cortex_m3_add_breakpoint
,
88 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
89 .add_watchpoint
= cortex_m3_add_watchpoint
,
90 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
92 .register_commands
= cortex_m3_register_commands
,
93 .target_command
= cortex_m3_target_command
,
94 .init_target
= cortex_m3_init_target
,
95 .examine
= cortex_m3_examine
,
96 .quit
= cortex_m3_quit
99 int cortex_m3_clear_halt(target_t
*target
)
101 /* get pointers to arch-specific information */
102 armv7m_common_t
*armv7m
= target
->arch_info
;
103 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
104 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
106 /* Read Debug Fault Status Register */
107 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
108 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
109 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
110 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
115 int cortex_m3_single_step_core(target_t
*target
)
117 /* get pointers to arch-specific information */
118 armv7m_common_t
*armv7m
= target
->arch_info
;
119 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
120 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
122 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
123 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
124 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
125 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
127 cortex_m3_clear_halt(target
);
132 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
134 /* get pointers to arch-specific information */
135 armv7m_common_t
*armv7m
= target
->arch_info
;
136 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
137 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
141 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
142 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
143 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
144 cortex_m3_single_step_core(target
);
145 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
146 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
152 /* Enable interrupts */
153 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
155 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
158 /* Disable interrupts */
159 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
161 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
165 int cortex_m3_endreset_event(target_t
*target
)
170 /* get pointers to arch-specific information */
171 armv7m_common_t
*armv7m
= target
->arch_info
;
172 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
173 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
174 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
175 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
177 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
178 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
180 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
182 /* Enable debug requests */
183 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
184 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
185 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
186 /* Enable trace and dwt */
187 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
188 /* Monitor bus faults */
189 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
192 target_write_u32(target
, FP_CTRL
, 3);
194 /* Restore FPB registers */
195 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
197 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
200 /* Restore DWT registers */
201 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
203 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
204 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
205 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
207 swjdp_transaction_endcheck(swjdp
);
209 armv7m_invalidate_core_regs(target
);
213 int cortex_m3_examine_debug_reason(target_t
*target
)
215 /* get pointers to arch-specific information */
216 armv7m_common_t
*armv7m
= target
->arch_info
;
217 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
219 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
220 /* only check the debug reason if we don't know it already */
222 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
223 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
227 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
229 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
230 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
231 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
233 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
234 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
240 int cortex_m3_examine_exception_reason(target_t
*target
)
242 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
244 /* get pointers to arch-specific information */
245 armv7m_common_t
*armv7m
= target
->arch_info
;
246 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
247 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
249 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
250 switch (armv7m
->exception_number
)
254 case 3: /* Hard Fault */
255 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
256 if (except_sr
& 0x40000000)
258 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
261 case 4: /* Memory Management */
262 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
263 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
265 case 5: /* Bus Fault */
266 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
267 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
269 case 6: /* Usage Fault */
270 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
272 case 11: /* SVCall */
274 case 12: /* Debug Monitor */
275 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
277 case 14: /* PendSV */
279 case 15: /* SysTick */
285 swjdp_transaction_endcheck(swjdp
);
286 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
287 shcsr
, except_sr
, cfsr
, except_ar
);
291 int cortex_m3_debug_entry(target_t
*target
)
297 /* get pointers to arch-specific information */
298 armv7m_common_t
*armv7m
= target
->arch_info
;
299 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
300 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
303 if (armv7m
->pre_debug_entry
)
304 armv7m
->pre_debug_entry(target
);
306 cortex_m3_clear_halt(target
);
307 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
309 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
312 /* Examine target state and mode */
313 /* First load register acessible through core debug port*/
314 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
316 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
317 armv7m
->read_core_reg(target
, i
);
320 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
322 #ifdef ARMV7_GDB_HACKS
323 /* copy real xpsr reg for gdb, setting thumb bit */
324 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
325 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
326 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
327 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
330 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
333 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
334 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
337 /* Now we can load SP core registers */
338 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
340 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
341 armv7m
->read_core_reg(target
, i
);
344 /* Are we in an exception handler */
347 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
348 armv7m
->exception_number
= (xPSR
& 0x1FF);
352 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
353 armv7m
->exception_number
= 0;
356 if (armv7m
->exception_number
)
358 cortex_m3_examine_exception_reason(target
);
361 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings
[armv7m
->core_mode
], \
362 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
364 if (armv7m
->post_debug_entry
)
365 armv7m
->post_debug_entry(target
);
370 int cortex_m3_poll(target_t
*target
)
373 u32 prev_target_state
= target
->state
;
375 /* get pointers to arch-specific information */
376 armv7m_common_t
*armv7m
= target
->arch_info
;
377 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
378 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
380 /* Read from Debug Halting Control and Status Register */
381 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
382 if (retval
!= ERROR_OK
)
384 target
->state
= TARGET_UNKNOWN
;
388 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
390 /* check if still in reset */
391 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
393 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
395 target
->state
= TARGET_RESET
;
400 if (target
->state
== TARGET_RESET
)
402 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
403 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
404 cortex_m3_endreset_event(target
);
405 target
->state
= TARGET_RUNNING
;
406 prev_target_state
= TARGET_RUNNING
;
409 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
411 target
->state
= TARGET_HALTED
;
413 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
415 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
418 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
420 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
423 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
426 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
431 if (cortex_m3->dcb_dhcsr & S_SLEEP)
432 target->state = TARGET_SLEEP;
436 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
437 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
438 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
]);
444 int cortex_m3_halt(target_t
*target
)
446 /* get pointers to arch-specific information */
447 armv7m_common_t
*armv7m
= target
->arch_info
;
448 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
449 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
451 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
453 if (target
->state
== TARGET_HALTED
)
455 LOG_DEBUG("target was already halted");
459 if (target
->state
== TARGET_UNKNOWN
)
461 LOG_WARNING("target was in unknown state when halt was requested");
464 if (target
->state
== TARGET_RESET
)
466 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
468 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
469 return ERROR_TARGET_FAILURE
;
473 /* we came here in a reset_halt or reset_init sequence
474 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
476 target
->debug_reason
= DBG_REASON_DBGRQ
;
482 /* Write to Debug Halting Control and Status Register */
483 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
485 target
->debug_reason
= DBG_REASON_DBGRQ
;
490 int cortex_m3_soft_reset_halt(struct target_s
*target
)
492 /* get pointers to arch-specific information */
493 armv7m_common_t
*armv7m
= target
->arch_info
;
494 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
495 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
497 int retval
, timeout
= 0;
499 /* Enter debug state on reset, cf. end_reset_event() */
500 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
502 /* Request a reset */
503 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
504 target
->state
= TARGET_RESET
;
506 /* registers are now invalid */
507 armv7m_invalidate_core_regs(target
);
509 while (timeout
< 100)
511 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
512 if (retval
== ERROR_OK
)
514 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
515 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
517 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
518 cortex_m3_poll(target
);
522 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
531 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
533 /* get pointers to arch-specific information */
534 armv7m_common_t
*armv7m
= target
->arch_info
;
535 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
536 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
537 breakpoint_t
*breakpoint
= NULL
;
538 u32 dcb_dhcsr
, resume_pc
;
540 if (target
->state
!= TARGET_HALTED
)
542 LOG_WARNING("target not halted");
543 return ERROR_TARGET_NOT_HALTED
;
546 if (!debug_execution
)
548 target_free_all_working_areas(target
);
549 cortex_m3_enable_breakpoints(target
);
550 cortex_m3_enable_watchpoints(target
);
552 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
555 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
558 /* Disable interrupts */
560 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
561 This is probably the same inssue as Cortex-M3 Errata 377493:
562 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
564 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
565 /* Make sure we are in Thumb mode */
566 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
567 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
570 /* current = 1: continue on current pc, otherwise continue at <address> */
573 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
574 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
575 armv7m
->core_cache
->reg_list
[15].valid
= 1;
578 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
580 armv7m_restore_context(target
);
582 /* the front-end may request us not to handle breakpoints */
583 if (handle_breakpoints
)
585 /* Single step past breakpoint at current address */
586 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
588 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
589 cortex_m3_unset_breakpoint(target
, breakpoint
);
590 cortex_m3_single_step_core(target
);
591 cortex_m3_set_breakpoint(target
, breakpoint
);
595 /* Set/Clear C_MASKINTS in a separate operation */
596 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
597 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
600 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
601 target
->debug_reason
= DBG_REASON_NOTHALTED
;
603 /* registers are now invalid */
604 armv7m_invalidate_core_regs(target
);
605 if (!debug_execution
)
607 target
->state
= TARGET_RUNNING
;
608 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
609 LOG_DEBUG("target resumed at 0x%x",resume_pc
);
613 target
->state
= TARGET_DEBUG_RUNNING
;
614 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
615 LOG_DEBUG("target debug resumed at 0x%x",resume_pc
);
621 /* int irqstepcount=0; */
622 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
624 /* get pointers to arch-specific information */
625 armv7m_common_t
*armv7m
= target
->arch_info
;
626 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
627 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
628 breakpoint_t
*breakpoint
= NULL
;
630 if (target
->state
!= TARGET_HALTED
)
632 LOG_WARNING("target not halted");
633 return ERROR_TARGET_NOT_HALTED
;
636 /* current = 1: continue on current pc, otherwise continue at <address> */
638 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
640 /* the front-end may request us not to handle breakpoints */
641 if (handle_breakpoints
)
642 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
643 cortex_m3_unset_breakpoint(target
, breakpoint
);
645 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
647 armv7m_restore_context(target
);
649 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
651 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
652 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
653 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
654 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
656 /* registers are now invalid */
657 armv7m_invalidate_core_regs(target
);
660 cortex_m3_set_breakpoint(target
, breakpoint
);
662 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
664 cortex_m3_debug_entry(target
);
665 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
667 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
671 int cortex_m3_assert_reset(target_t
*target
)
673 armv7m_common_t
*armv7m
= target
->arch_info
;
674 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
675 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
677 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
679 if (!(jtag_reset_config
& RESET_HAS_SRST
))
681 LOG_ERROR("Can't assert SRST");
685 /* Enable debug requests */
686 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
687 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
688 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
690 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
692 if (target
->reset_mode
== RESET_RUN
)
694 /* Set/Clear C_MASKINTS in a separate operation */
695 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
696 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
698 cortex_m3_clear_halt(target
);
700 /* Enter debug state on reset, cf. end_reset_event() */
701 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
705 /* Enter debug state on reset, cf. end_reset_event() */
706 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
709 /* following hack is to handle luminary reset
710 * when srst is asserted the luminary device seesm to also clear the debug registers
711 * which does not match the armv7 debug TRM */
713 if (strcmp(cortex_m3
->variant
, "luminary") == 0)
715 /* this causes the luminary device to reset using the watchdog */
716 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
717 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
721 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
723 jtag_add_reset(1, 1);
727 jtag_add_reset(0, 1);
731 target
->state
= TARGET_RESET
;
732 jtag_add_sleep(50000);
734 armv7m_invalidate_core_regs(target
);
739 int cortex_m3_deassert_reset(target_t
*target
)
741 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
743 /* deassert reset lines */
744 jtag_add_reset(0, 0);
749 void cortex_m3_enable_breakpoints(struct target_s
*target
)
751 breakpoint_t
*breakpoint
= target
->breakpoints
;
753 /* set any pending breakpoints */
756 if (breakpoint
->set
== 0)
757 cortex_m3_set_breakpoint(target
, breakpoint
);
758 breakpoint
= breakpoint
->next
;
762 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
767 /* get pointers to arch-specific information */
768 armv7m_common_t
*armv7m
= target
->arch_info
;
769 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
771 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
775 LOG_WARNING("breakpoint already set");
779 if (cortex_m3
->auto_bp_type
)
781 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
784 if (breakpoint
->type
== BKPT_HARD
)
786 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
788 if (fp_num
>= cortex_m3
->fp_num_code
)
790 LOG_DEBUG("ERROR Can not find free FP Comparator");
791 LOG_WARNING("ERROR Can not find free FP Comparator");
794 breakpoint
->set
= fp_num
+ 1;
795 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
796 comparator_list
[fp_num
].used
= 1;
797 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
798 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
799 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
801 else if (breakpoint
->type
== BKPT_SOFT
)
804 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
805 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
806 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
807 breakpoint
->set
= 0x11; /* Any nice value but 0 */
813 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
815 /* get pointers to arch-specific information */
816 armv7m_common_t
*armv7m
= target
->arch_info
;
817 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
818 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
820 if (!breakpoint
->set
)
822 LOG_WARNING("breakpoint not set");
826 if (breakpoint
->type
== BKPT_HARD
)
828 int fp_num
= breakpoint
->set
- 1;
829 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
831 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
834 comparator_list
[fp_num
].used
= 0;
835 comparator_list
[fp_num
].fpcr_value
= 0;
836 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
840 /* restore original instruction (kept in target endianness) */
841 if (breakpoint
->length
== 4)
843 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
847 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
855 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
857 /* get pointers to arch-specific information */
858 armv7m_common_t
*armv7m
= target
->arch_info
;
859 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
861 if (cortex_m3
->auto_bp_type
)
863 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
864 #ifdef ARMV7_GDB_HACKS
865 if (breakpoint
->length
!= 2) {
866 /* XXX Hack: Replace all breakpoints with length != 2 with
867 * a hardware breakpoint. */
868 breakpoint
->type
= BKPT_HARD
;
869 breakpoint
->length
= 2;
874 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
876 LOG_INFO("flash patch comparator requested outside code memory region");
877 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
880 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
882 LOG_INFO("soft breakpoint requested in code (flash) memory region");
883 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
886 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
888 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
889 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
892 if ((breakpoint
->length
!= 2))
894 LOG_INFO("only breakpoints of two bytes length supported");
895 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
898 if (breakpoint
->type
== BKPT_HARD
)
899 cortex_m3
->fp_code_available
--;
900 cortex_m3_set_breakpoint(target
, breakpoint
);
905 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
907 /* get pointers to arch-specific information */
908 armv7m_common_t
*armv7m
= target
->arch_info
;
909 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
911 if (target
->state
!= TARGET_HALTED
)
913 LOG_WARNING("target not halted");
914 return ERROR_TARGET_NOT_HALTED
;
917 if (cortex_m3
->auto_bp_type
)
919 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
924 cortex_m3_unset_breakpoint(target
, breakpoint
);
927 if (breakpoint
->type
== BKPT_HARD
)
928 cortex_m3
->fp_code_available
++;
933 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
938 /* get pointers to arch-specific information */
939 armv7m_common_t
*armv7m
= target
->arch_info
;
940 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
941 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
945 LOG_WARNING("watchpoint already set");
949 if (watchpoint
->mask
== 0xffffffffu
)
951 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
953 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
955 LOG_DEBUG("ERROR Can not find free DWT Comparator");
956 LOG_WARNING("ERROR Can not find free DWT Comparator");
959 watchpoint
->set
= dwt_num
+ 1;
961 temp
= watchpoint
->length
;
967 comparator_list
[dwt_num
].used
= 1;
968 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
969 comparator_list
[dwt_num
].mask
= mask
;
970 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
971 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
972 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
973 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
974 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
);
978 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
986 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
988 /* get pointers to arch-specific information */
989 armv7m_common_t
*armv7m
= target
->arch_info
;
990 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
991 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
994 if (!watchpoint
->set
)
996 LOG_WARNING("watchpoint not set");
1000 dwt_num
= watchpoint
->set
- 1;
1002 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1004 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1007 comparator_list
[dwt_num
].used
= 0;
1008 comparator_list
[dwt_num
].function
= 0;
1009 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1011 watchpoint
->set
= 0;
1016 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1018 /* get pointers to arch-specific information */
1019 armv7m_common_t
*armv7m
= target
->arch_info
;
1020 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1022 if (target
->state
!= TARGET_HALTED
)
1024 LOG_WARNING("target not halted");
1025 return ERROR_TARGET_NOT_HALTED
;
1028 if (cortex_m3
->dwt_comp_available
< 1)
1030 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1033 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1035 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1038 cortex_m3
->dwt_comp_available
--;
1043 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1045 /* get pointers to arch-specific information */
1046 armv7m_common_t
*armv7m
= target
->arch_info
;
1047 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1049 if (target
->state
!= TARGET_HALTED
)
1051 LOG_WARNING("target not halted");
1052 return ERROR_TARGET_NOT_HALTED
;
1055 if (watchpoint
->set
)
1057 cortex_m3_unset_watchpoint(target
, watchpoint
);
1060 cortex_m3
->dwt_comp_available
++;
1065 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1067 watchpoint_t
*watchpoint
= target
->watchpoints
;
1069 /* set any pending watchpoints */
1072 if (watchpoint
->set
== 0)
1073 cortex_m3_set_watchpoint(target
, watchpoint
);
1074 watchpoint
= watchpoint
->next
;
1078 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1081 /* get pointers to arch-specific information */
1082 armv7m_common_t
*armv7m
= target
->arch_info
;
1083 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1084 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1086 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1088 /* read a normal core register */
1089 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1091 if (retval
!= ERROR_OK
)
1093 LOG_ERROR("JTAG failure %i",retval
);
1094 return ERROR_JTAG_DEVICE_ERROR
;
1096 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1098 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1100 /* read other registers */
1101 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1106 *value
= buf_get_u32((u8
*)value
, 0, 8);
1110 *value
= buf_get_u32((u8
*)value
, 8, 8);
1114 *value
= buf_get_u32((u8
*)value
, 16, 8);
1118 *value
= buf_get_u32((u8
*)value
, 24, 8);
1122 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1126 return ERROR_INVALID_ARGUMENTS
;
1132 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1137 /* get pointers to arch-specific information */
1138 armv7m_common_t
*armv7m
= target
->arch_info
;
1139 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1140 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1142 #ifdef ARMV7_GDB_HACKS
1143 /* If the LR register is being modified, make sure it will put us
1144 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1145 * hack to deal with the fact that gdb will sometimes "forge"
1146 * return addresses, and doesn't set the LSB correctly (i.e., when
1147 * printing expressions containing function calls, it sets LR=0.) */
1153 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1155 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1156 if (retval
!= ERROR_OK
)
1158 LOG_ERROR("JTAG failure %i", retval
);
1159 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1160 return ERROR_JTAG_DEVICE_ERROR
;
1162 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1164 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1166 /* write other registers */
1168 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1173 buf_set_u32((u8
*)®
, 0, 8, value
);
1177 buf_set_u32((u8
*)®
, 8, 8, value
);
1181 buf_set_u32((u8
*)®
, 16, 8, value
);
1185 buf_set_u32((u8
*)®
, 24, 8, value
);
1189 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1191 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1195 return ERROR_INVALID_ARGUMENTS
;
1201 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1203 /* get pointers to arch-specific information */
1204 armv7m_common_t
*armv7m
= target
->arch_info
;
1205 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1206 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1209 /* sanitize arguments */
1210 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1211 return ERROR_INVALID_ARGUMENTS
;
1213 /* cortex_m3 handles unaligned memory access */
1218 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1221 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1224 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1227 LOG_ERROR("BUG: we shouldn't get here");
1234 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1236 /* get pointers to arch-specific information */
1237 armv7m_common_t
*armv7m
= target
->arch_info
;
1238 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1239 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1242 /* sanitize arguments */
1243 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1244 return ERROR_INVALID_ARGUMENTS
;
1249 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1252 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1255 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1258 LOG_ERROR("BUG: we shouldn't get here");
1265 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1267 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1270 void cortex_m3_build_reg_cache(target_t
*target
)
1272 armv7m_build_reg_cache(target
);
1275 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1277 cortex_m3_build_reg_cache(target
);
1281 int cortex_m3_examine(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1284 u32 cpuid
, fpcr
, dwtcr
, ictr
;
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
;
1292 target
->type
->examined
= 1;
1294 if ((retval
=ahbap_debugport_init(swjdp
))!=ERROR_OK
)
1297 /* Read from Device Identification Registers */
1298 if ((retval
=target_read_u32(target
, CPUID
, &cpuid
))!=ERROR_OK
)
1301 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1302 LOG_DEBUG("CORTEX-M3 processor detected");
1303 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1305 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1306 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1307 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1308 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1310 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1311 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1315 target_read_u32(target
, FP_CTRL
, &fpcr
);
1316 cortex_m3
->auto_bp_type
= 1;
1317 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1318 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1319 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1320 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1321 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1323 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1324 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1326 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1329 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1330 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1331 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1332 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1333 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1335 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1342 int cortex_m3_quit()
1348 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1352 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1354 *value
= (u8
)(dcrdr
>> 8);
1356 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1358 /* write ack back to software dcc register
1359 * signify we have read data */
1360 if (dcrdr
& (1 << 0))
1363 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1369 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1371 armv7m_common_t
*armv7m
= target
->arch_info
;
1372 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1373 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1378 for (i
= 0; i
< (size
* 4); i
++)
1380 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1387 int cortex_m3_handle_target_request(void *priv
)
1389 target_t
*target
= priv
;
1390 if (!target
->type
->examined
)
1392 armv7m_common_t
*armv7m
= target
->arch_info
;
1393 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1394 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1396 if (!target
->dbg_msg_enabled
)
1399 if (target
->state
== TARGET_RUNNING
)
1404 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1406 /* check if we have data */
1407 if (ctrl
& (1 << 0))
1411 /* we assume target is quick enough */
1413 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1414 request
|= (data
<< 8);
1415 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1416 request
|= (data
<< 16);
1417 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1418 request
|= (data
<< 24);
1419 target_request(target
, request
);
1426 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1428 armv7m_common_t
*armv7m
;
1429 armv7m
= &cortex_m3
->armv7m
;
1431 /* prepare JTAG information for the new target */
1432 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1433 cortex_m3
->jtag_info
.scann_size
= 4;
1435 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1436 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1437 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1438 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1440 /* initialize arch-specific breakpoint handling */
1442 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1443 cortex_m3
->arch_info
= NULL
;
1445 /* register arch-specific functions */
1446 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1448 armv7m
->pre_debug_entry
= NULL
;
1449 armv7m
->post_debug_entry
= NULL
;
1451 armv7m
->pre_restore_context
= NULL
;
1452 armv7m
->post_restore_context
= NULL
;
1456 cortex_m3
->variant
= strdup(variant
);
1460 cortex_m3
->variant
= strdup("");
1463 armv7m_init_arch_info(target
, armv7m
);
1464 armv7m
->arch_info
= cortex_m3
;
1465 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1466 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1468 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1473 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1474 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1477 char *variant
= NULL
;
1478 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1479 memset(cortex_m3
, 0, sizeof(*cortex_m3
));
1483 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1487 chain_pos
= strtoul(args
[3], NULL
, 0);
1492 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1493 cortex_m3_register_commands(cmd_ctx
);
1498 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1502 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)