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
);
55 target_type_t cortexm3_target
=
59 .poll
= cortex_m3_poll
,
60 .arch_state
= armv7m_arch_state
,
62 .target_request_data
= cortex_m3_target_request_data
,
64 .halt
= cortex_m3_halt
,
65 .resume
= cortex_m3_resume
,
66 .step
= cortex_m3_step
,
68 .assert_reset
= cortex_m3_assert_reset
,
69 .deassert_reset
= cortex_m3_deassert_reset
,
70 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
72 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
74 .read_memory
= cortex_m3_read_memory
,
75 .write_memory
= cortex_m3_write_memory
,
76 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
77 .checksum_memory
= armv7m_checksum_memory
,
79 .run_algorithm
= armv7m_run_algorithm
,
81 .add_breakpoint
= cortex_m3_add_breakpoint
,
82 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
83 .add_watchpoint
= cortex_m3_add_watchpoint
,
84 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
86 .register_commands
= cortex_m3_register_commands
,
87 .target_command
= cortex_m3_target_command
,
88 .init_target
= cortex_m3_init_target
,
89 .quit
= cortex_m3_quit
92 int cortex_m3_clear_halt(target_t
*target
)
94 /* get pointers to arch-specific information */
95 armv7m_common_t
*armv7m
= target
->arch_info
;
96 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
97 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
99 /* Read Debug Fault Status Register */
100 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
101 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
102 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
103 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
108 int cortex_m3_single_step_core(target_t
*target
)
110 /* get pointers to arch-specific information */
111 armv7m_common_t
*armv7m
= target
->arch_info
;
112 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
113 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
115 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
116 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
117 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
118 cortex_m3
->dcb_dhcsr
|= C_MASKINTS
;
120 cortex_m3_clear_halt(target
);
125 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
127 /* get pointers to arch-specific information */
128 armv7m_common_t
*armv7m
= target
->arch_info
;
129 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
130 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
134 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
135 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
136 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
137 cortex_m3_single_step_core(target
);
138 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
139 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
145 /* Enable interrupts */
146 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
148 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
151 /* Disable interrupts */
152 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
154 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
158 int cortex_m3_endreset_event(target_t
*target
)
163 /* get pointers to arch-specific information */
164 armv7m_common_t
*armv7m
= target
->arch_info
;
165 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
166 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
167 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
168 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
170 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
171 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
173 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
175 /* Enable debug requests */
176 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
177 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
178 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
179 /* Enable trace and dwt */
180 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
181 /* Monitor bus faults */
182 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
185 target_write_u32(target
, FP_CTRL
, 3);
187 /* Restore FPB registers */
188 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
190 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
193 /* Restore DWT registers */
194 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
196 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
197 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
198 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
200 swjdp_transaction_endcheck(swjdp
);
202 armv7m_invalidate_core_regs(target
);
206 int cortex_m3_examine_debug_reason(target_t
*target
)
208 /* get pointers to arch-specific information */
209 armv7m_common_t
*armv7m
= target
->arch_info
;
210 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
212 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
213 /* only check the debug reason if we don't know it already */
215 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
216 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
220 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
222 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
223 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
224 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
226 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
227 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
233 int cortex_m3_examine_exception_reason(target_t
*target
)
235 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
237 /* get pointers to arch-specific information */
238 armv7m_common_t
*armv7m
= target
->arch_info
;
239 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
240 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
242 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
243 switch (armv7m
->exception_number
)
247 case 3: /* Hard Fault */
248 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
249 if (except_sr
& 0x40000000)
251 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
254 case 4: /* Memory Management */
255 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
256 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
258 case 5: /* Bus Fault */
259 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
260 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
262 case 6: /* Usage Fault */
263 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
265 case 11: /* SVCall */
267 case 12: /* Debug Monitor */
268 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
270 case 14: /* PendSV */
272 case 15: /* SysTick */
278 swjdp_transaction_endcheck(swjdp
);
279 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
280 shcsr
, except_sr
, cfsr
, except_ar
);
284 int cortex_m3_debug_entry(target_t
*target
)
290 /* get pointers to arch-specific information */
291 armv7m_common_t
*armv7m
= target
->arch_info
;
292 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
293 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
296 if (armv7m
->pre_debug_entry
)
297 armv7m
->pre_debug_entry(target
);
299 cortex_m3_clear_halt(target
);
300 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
302 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
305 /* Examine target state and mode */
306 /* First load register acessible through core debug port*/
307 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
309 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
310 armv7m
->read_core_reg(target
, i
);
313 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
315 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
318 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
319 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
322 /* Now we can load SP core registers */
323 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
325 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
326 armv7m
->read_core_reg(target
, i
);
329 /* Are we in an exception handler */
332 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
333 armv7m
->exception_number
= (xPSR
& 0x1FF);
337 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
338 armv7m
->exception_number
= 0;
341 if (armv7m
->exception_number
)
343 cortex_m3_examine_exception_reason(target
);
346 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s", armv7m_mode_strings
[armv7m
->core_mode
], \
347 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
), target_state_strings
[target
->state
]);
349 if (armv7m
->post_debug_entry
)
350 armv7m
->post_debug_entry(target
);
355 int cortex_m3_poll(target_t
*target
)
358 u32 prev_target_state
= target
->state
;
360 /* get pointers to arch-specific information */
361 armv7m_common_t
*armv7m
= target
->arch_info
;
362 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
363 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
365 /* Read from Debug Halting Control and Status Register */
366 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
367 if (retval
!= ERROR_OK
)
369 target
->state
= TARGET_UNKNOWN
;
373 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
375 /* check if still in reset */
376 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
378 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
380 target
->state
= TARGET_RESET
;
385 if (target
->state
== TARGET_RESET
)
387 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
388 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
389 cortex_m3_endreset_event(target
);
390 target
->state
= TARGET_RUNNING
;
391 prev_target_state
= TARGET_RUNNING
;
394 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
396 target
->state
= TARGET_HALTED
;
398 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
400 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
403 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
405 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
408 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
411 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
416 if (cortex_m3->dcb_dhcsr & S_SLEEP)
417 target->state = TARGET_SLEEP;
421 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
422 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
423 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
]);
429 int cortex_m3_halt(target_t
*target
)
431 /* get pointers to arch-specific information */
432 armv7m_common_t
*armv7m
= target
->arch_info
;
433 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
434 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
436 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
438 if (target
->state
== TARGET_HALTED
)
440 LOG_DEBUG("target was already halted");
444 if (target
->state
== TARGET_UNKNOWN
)
446 LOG_WARNING("target was in unknown state when halt was requested");
449 if (target
->state
== TARGET_RESET
)
451 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
453 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
454 return ERROR_TARGET_FAILURE
;
458 /* we came here in a reset_halt or reset_init sequence
459 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
461 target
->debug_reason
= DBG_REASON_DBGRQ
;
467 /* Write to Debug Halting Control and Status Register */
468 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
470 target
->debug_reason
= DBG_REASON_DBGRQ
;
475 int cortex_m3_soft_reset_halt(struct target_s
*target
)
477 /* get pointers to arch-specific information */
478 armv7m_common_t
*armv7m
= target
->arch_info
;
479 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
480 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
482 int retval
, timeout
= 0;
484 /* Enter debug state on reset, cf. end_reset_event() */
485 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
487 /* Request a reset */
488 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
489 target
->state
= TARGET_RESET
;
491 /* registers are now invalid */
492 armv7m_invalidate_core_regs(target
);
494 while (timeout
< 100)
496 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
497 if (retval
== ERROR_OK
)
499 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
500 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
502 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
503 cortex_m3_poll(target
);
507 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
516 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
518 /* get pointers to arch-specific information */
519 armv7m_common_t
*armv7m
= target
->arch_info
;
520 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
521 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
522 breakpoint_t
*breakpoint
= NULL
;
523 u32 dcb_dhcsr
, resume_pc
;
525 if (target
->state
!= TARGET_HALTED
)
527 LOG_WARNING("target not halted");
528 return ERROR_TARGET_NOT_HALTED
;
531 if (!debug_execution
)
533 target_free_all_working_areas(target
);
534 cortex_m3_enable_breakpoints(target
);
535 cortex_m3_enable_watchpoints(target
);
537 /* TODOLATER Interrupt handling/disable for debug execution, cache ... ... */
540 dcb_dhcsr
= DBGKEY
| C_DEBUGEN
;
543 /* Disable interrupts */
545 We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
546 This is probably the same inssue as Cortex-M3 Errata 377493:
547 C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken.
549 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
550 /* Make sure we are in Thumb mode */
551 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
552 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
555 /* current = 1: continue on current pc, otherwise continue at <address> */
558 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
559 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
560 armv7m
->core_cache
->reg_list
[15].valid
= 1;
563 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
565 armv7m_restore_context(target
);
567 /* the front-end may request us not to handle breakpoints */
568 if (handle_breakpoints
)
570 /* Single step past breakpoint at current address */
571 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
573 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
574 cortex_m3_unset_breakpoint(target
, breakpoint
);
575 cortex_m3_single_step_core(target
);
576 cortex_m3_set_breakpoint(target
, breakpoint
);
580 /* Set/Clear C_MASKINTS in a separate operation */
581 if ((cortex_m3
->dcb_dhcsr
& C_MASKINTS
) != (dcb_dhcsr
& C_MASKINTS
))
582 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
| C_HALT
);
585 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, dcb_dhcsr
);
586 target
->debug_reason
= DBG_REASON_NOTHALTED
;
588 /* registers are now invalid */
589 armv7m_invalidate_core_regs(target
);
590 if (!debug_execution
)
592 target
->state
= TARGET_RUNNING
;
593 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
594 LOG_DEBUG("target resumed at 0x%x",resume_pc
);
598 target
->state
= TARGET_DEBUG_RUNNING
;
599 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
600 LOG_DEBUG("target debug resumed at 0x%x",resume_pc
);
606 /* int irqstepcount=0; */
607 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
609 /* get pointers to arch-specific information */
610 armv7m_common_t
*armv7m
= target
->arch_info
;
611 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
612 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
613 breakpoint_t
*breakpoint
= NULL
;
615 if (target
->state
!= TARGET_HALTED
)
617 LOG_WARNING("target not halted");
618 return ERROR_TARGET_NOT_HALTED
;
621 /* current = 1: continue on current pc, otherwise continue at <address> */
623 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
625 /* the front-end may request us not to handle breakpoints */
626 if (handle_breakpoints
)
627 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
628 cortex_m3_unset_breakpoint(target
, breakpoint
);
630 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
632 armv7m_restore_context(target
);
634 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
636 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
637 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_HALT
| C_DEBUGEN
);
638 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_STEP
| C_DEBUGEN
);
639 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
641 /* registers are now invalid */
642 armv7m_invalidate_core_regs(target
);
645 cortex_m3_set_breakpoint(target
, breakpoint
);
647 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
649 cortex_m3_debug_entry(target
);
650 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
652 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
656 int cortex_m3_assert_reset(target_t
*target
)
658 armv7m_common_t
*armv7m
= target
->arch_info
;
659 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
660 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
662 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
664 if (!(jtag_reset_config
& RESET_HAS_SRST
))
666 LOG_ERROR("Can't assert SRST");
670 /* Enable debug requests */
671 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
672 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
673 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
675 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
677 if (target
->reset_mode
== RESET_RUN
)
679 /* Set/Clear C_MASKINTS in a separate operation */
680 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
681 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
683 cortex_m3_clear_halt(target
);
685 /* Enter debug state on reset, cf. end_reset_event() */
686 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
690 /* Enter debug state on reset, cf. end_reset_event() */
691 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
694 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
696 jtag_add_reset(1, 1);
700 jtag_add_reset(0, 1);
703 target
->state
= TARGET_RESET
;
704 jtag_add_sleep(50000);
706 armv7m_invalidate_core_regs(target
);
711 int cortex_m3_deassert_reset(target_t
*target
)
713 LOG_DEBUG("target->state: %s", target_state_strings
[target
->state
]);
715 /* deassert reset lines */
716 jtag_add_reset(0, 0);
721 void cortex_m3_enable_breakpoints(struct target_s
*target
)
723 breakpoint_t
*breakpoint
= target
->breakpoints
;
725 /* set any pending breakpoints */
728 if (breakpoint
->set
== 0)
729 cortex_m3_set_breakpoint(target
, breakpoint
);
730 breakpoint
= breakpoint
->next
;
734 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
739 /* get pointers to arch-specific information */
740 armv7m_common_t
*armv7m
= target
->arch_info
;
741 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
743 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
747 LOG_WARNING("breakpoint already set");
751 if (cortex_m3
->auto_bp_type
)
753 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
756 if (breakpoint
->type
== BKPT_HARD
)
758 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
760 if (fp_num
>= cortex_m3
->fp_num_code
)
762 LOG_DEBUG("ERROR Can not find free FP Comparator");
763 LOG_WARNING("ERROR Can not find free FP Comparator");
766 breakpoint
->set
= fp_num
+ 1;
767 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
768 comparator_list
[fp_num
].used
= 1;
769 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
770 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
771 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
773 else if (breakpoint
->type
== BKPT_SOFT
)
776 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
777 target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
);
778 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
);
779 breakpoint
->set
= 0x11; /* Any nice value but 0 */
785 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
787 /* get pointers to arch-specific information */
788 armv7m_common_t
*armv7m
= target
->arch_info
;
789 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
790 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
792 if (!breakpoint
->set
)
794 LOG_WARNING("breakpoint not set");
798 if (breakpoint
->type
== BKPT_HARD
)
800 int fp_num
= breakpoint
->set
- 1;
801 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
803 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
806 comparator_list
[fp_num
].used
= 0;
807 comparator_list
[fp_num
].fpcr_value
= 0;
808 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
812 /* restore original instruction (kept in target endianness) */
813 if (breakpoint
->length
== 4)
815 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
);
819 target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
);
827 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
829 /* get pointers to arch-specific information */
830 armv7m_common_t
*armv7m
= target
->arch_info
;
831 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
833 if (cortex_m3
->auto_bp_type
)
835 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
838 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
840 LOG_INFO("flash patch comparator requested outside code memory region");
841 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
844 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
846 LOG_INFO("soft breakpoint requested in code (flash) memory region");
847 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
850 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
852 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
853 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
856 if ((breakpoint
->length
!= 2))
858 LOG_INFO("only breakpoints of two bytes length supported");
859 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
862 if (breakpoint
->type
== BKPT_HARD
)
863 cortex_m3
->fp_code_available
--;
864 cortex_m3_set_breakpoint(target
, breakpoint
);
869 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
871 /* get pointers to arch-specific information */
872 armv7m_common_t
*armv7m
= target
->arch_info
;
873 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
875 if (target
->state
!= TARGET_HALTED
)
877 LOG_WARNING("target not halted");
878 return ERROR_TARGET_NOT_HALTED
;
881 if (cortex_m3
->auto_bp_type
)
883 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
888 cortex_m3_unset_breakpoint(target
, breakpoint
);
891 if (breakpoint
->type
== BKPT_HARD
)
892 cortex_m3
->fp_code_available
++;
897 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
902 /* get pointers to arch-specific information */
903 armv7m_common_t
*armv7m
= target
->arch_info
;
904 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
905 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
909 LOG_WARNING("watchpoint already set");
913 if (watchpoint
->mask
== 0xffffffffu
)
915 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
917 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
919 LOG_DEBUG("ERROR Can not find free DWT Comparator");
920 LOG_WARNING("ERROR Can not find free DWT Comparator");
923 watchpoint
->set
= dwt_num
+ 1;
925 temp
= watchpoint
->length
;
931 comparator_list
[dwt_num
].used
= 1;
932 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
933 comparator_list
[dwt_num
].mask
= mask
;
934 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
935 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
936 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
937 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
938 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
);
942 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
950 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
952 /* get pointers to arch-specific information */
953 armv7m_common_t
*armv7m
= target
->arch_info
;
954 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
955 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
958 if (!watchpoint
->set
)
960 LOG_WARNING("watchpoint not set");
964 dwt_num
= watchpoint
->set
- 1;
966 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
968 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
971 comparator_list
[dwt_num
].used
= 0;
972 comparator_list
[dwt_num
].function
= 0;
973 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
980 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
982 /* get pointers to arch-specific information */
983 armv7m_common_t
*armv7m
= target
->arch_info
;
984 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
986 if (target
->state
!= TARGET_HALTED
)
988 LOG_WARNING("target not halted");
989 return ERROR_TARGET_NOT_HALTED
;
992 if (cortex_m3
->dwt_comp_available
< 1)
994 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
997 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
999 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1002 cortex_m3
->dwt_comp_available
--;
1007 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1009 /* get pointers to arch-specific information */
1010 armv7m_common_t
*armv7m
= target
->arch_info
;
1011 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1013 if (target
->state
!= TARGET_HALTED
)
1015 LOG_WARNING("target not halted");
1016 return ERROR_TARGET_NOT_HALTED
;
1019 if (watchpoint
->set
)
1021 cortex_m3_unset_watchpoint(target
, watchpoint
);
1024 cortex_m3
->dwt_comp_available
++;
1029 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1031 watchpoint_t
*watchpoint
= target
->watchpoints
;
1033 /* set any pending watchpoints */
1036 if (watchpoint
->set
== 0)
1037 cortex_m3_set_watchpoint(target
, watchpoint
);
1038 watchpoint
= watchpoint
->next
;
1042 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
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
;
1048 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1050 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1052 /* read a normal core register */
1053 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1055 if (retval
!= ERROR_OK
)
1057 LOG_ERROR("JTAG failure %i",retval
);
1058 return ERROR_JTAG_DEVICE_ERROR
;
1060 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1062 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1064 /* read other registers */
1065 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1070 *value
= buf_get_u32((u8
*)value
, 0, 8);
1074 *value
= buf_get_u32((u8
*)value
, 8, 8);
1078 *value
= buf_get_u32((u8
*)value
, 16, 8);
1082 *value
= buf_get_u32((u8
*)value
, 24, 8);
1086 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1090 return ERROR_INVALID_ARGUMENTS
;
1096 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1101 /* get pointers to arch-specific information */
1102 armv7m_common_t
*armv7m
= target
->arch_info
;
1103 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1104 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1106 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1108 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1109 if (retval
!= ERROR_OK
)
1111 LOG_ERROR("JTAG failure %i", retval
);
1112 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1113 return ERROR_JTAG_DEVICE_ERROR
;
1115 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1117 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1119 /* write other registers */
1121 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1126 buf_set_u32((u8
*)®
, 0, 8, value
);
1130 buf_set_u32((u8
*)®
, 8, 8, value
);
1134 buf_set_u32((u8
*)®
, 16, 8, value
);
1138 buf_set_u32((u8
*)®
, 24, 8, value
);
1142 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1144 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1148 return ERROR_INVALID_ARGUMENTS
;
1154 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1156 /* get pointers to arch-specific information */
1157 armv7m_common_t
*armv7m
= target
->arch_info
;
1158 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1159 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1162 /* sanitize arguments */
1163 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1164 return ERROR_INVALID_ARGUMENTS
;
1166 /* cortex_m3 handles unaligned memory access */
1171 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1174 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1177 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1180 LOG_ERROR("BUG: we shouldn't get here");
1187 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1189 /* get pointers to arch-specific information */
1190 armv7m_common_t
*armv7m
= target
->arch_info
;
1191 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1192 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1195 /* sanitize arguments */
1196 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1197 return ERROR_INVALID_ARGUMENTS
;
1202 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1205 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1208 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1211 LOG_ERROR("BUG: we shouldn't get here");
1218 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1220 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1223 void cortex_m3_build_reg_cache(target_t
*target
)
1225 armv7m_build_reg_cache(target
);
1228 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1230 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1233 /* get pointers to arch-specific information */
1234 armv7m_common_t
*armv7m
= target
->arch_info
;
1235 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1236 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1238 cortex_m3_build_reg_cache(target
);
1239 ahbap_debugport_init(swjdp
);
1241 /* Read from Device Identification Registers */
1242 target_read_u32(target
, CPUID
, &cpuid
);
1243 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1244 LOG_DEBUG("CORTEX-M3 processor detected");
1245 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1247 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1248 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1249 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1250 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1252 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1253 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1257 target_read_u32(target
, FP_CTRL
, &fpcr
);
1258 cortex_m3
->auto_bp_type
= 1;
1259 cortex_m3
->fp_num_code
= (fpcr
>> 4) & 0xF;
1260 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1261 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1262 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1263 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1265 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1266 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1268 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1271 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1272 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1273 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1274 cortex_m3
->dwt_comparator_list
=calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1275 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1277 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1283 int cortex_m3_quit()
1289 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1293 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1295 *value
= (u8
)(dcrdr
>> 8);
1297 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1299 /* write ack back to software dcc register
1300 * signify we have read data */
1301 if (dcrdr
& (1 << 0))
1304 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1310 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1312 armv7m_common_t
*armv7m
= target
->arch_info
;
1313 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1314 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1319 for (i
= 0; i
< (size
* 4); i
++)
1321 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1328 int cortex_m3_handle_target_request(void *priv
)
1330 target_t
*target
= priv
;
1331 if (!target
->type
->examined
)
1333 armv7m_common_t
*armv7m
= target
->arch_info
;
1334 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1335 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1337 if (!target
->dbg_msg_enabled
)
1340 if (target
->state
== TARGET_RUNNING
)
1345 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1347 /* check if we have data */
1348 if (ctrl
& (1 << 0))
1352 /* we assume target is quick enough */
1354 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1355 request
|= (data
<< 8);
1356 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1357 request
|= (data
<< 16);
1358 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1359 request
|= (data
<< 24);
1360 target_request(target
, request
);
1367 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, int chain_pos
, char *variant
)
1369 armv7m_common_t
*armv7m
;
1370 armv7m
= &cortex_m3
->armv7m
;
1372 /* prepare JTAG information for the new target */
1373 cortex_m3
->jtag_info
.chain_pos
= chain_pos
;
1374 cortex_m3
->jtag_info
.scann_size
= 4;
1376 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1377 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1378 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1379 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1381 /* initialize arch-specific breakpoint handling */
1383 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1384 cortex_m3
->arch_info
= NULL
;
1386 /* register arch-specific functions */
1387 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1389 armv7m
->pre_debug_entry
= NULL
;
1390 armv7m
->post_debug_entry
= NULL
;
1392 armv7m
->pre_restore_context
= NULL
;
1393 armv7m
->post_restore_context
= NULL
;
1395 armv7m_init_arch_info(target
, armv7m
);
1396 armv7m
->arch_info
= cortex_m3
;
1397 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1398 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1400 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1405 /* target cortex_m3 <endianess> <startup_mode> <chain_pos> <variant>*/
1406 int cortex_m3_target_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct target_s
*target
)
1409 char *variant
= NULL
;
1410 cortex_m3_common_t
*cortex_m3
= malloc(sizeof(cortex_m3_common_t
));
1411 memset(cortex_m3
, 0, sizeof(*cortex_m3
));
1415 LOG_ERROR("'target cortex_m3' requires at least one additional argument");
1419 chain_pos
= strtoul(args
[3], NULL
, 0);
1424 cortex_m3_init_arch_info(target
, cortex_m3
, chain_pos
, variant
);
1425 cortex_m3_register_commands(cmd_ctx
);
1430 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1434 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)