1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2006 by Magnus Lundin *
8 * Copyright (C) 2008 by Spencer Oliver *
9 * spen@spen-soft.co.uk *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
30 #include "replacements.h"
32 #include "cortex_m3.h"
37 #include "target_request.h"
46 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
);
47 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
49 /* forward declarations */
50 void cortex_m3_enable_breakpoints(struct target_s
*target
);
51 void cortex_m3_enable_watchpoints(struct target_s
*target
);
52 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
);
53 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
);
54 int cortex_m3_quit(void);
55 int cortex_m3_load_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32
*value
);
56 int cortex_m3_store_core_reg_u32(target_t
*target
, enum armv7m_regtype type
, u32 num
, u32 value
);
57 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
);
58 int cortex_m3_examine(struct target_s
*target
);
60 #ifdef ARMV7_GDB_HACKS
61 extern u8 armv7m_gdb_dummy_cpsr_value
[];
62 extern reg_t armv7m_gdb_dummy_cpsr_reg
;
65 target_type_t cortexm3_target
=
69 .poll
= cortex_m3_poll
,
70 .arch_state
= armv7m_arch_state
,
72 .target_request_data
= cortex_m3_target_request_data
,
74 .halt
= cortex_m3_halt
,
75 .resume
= cortex_m3_resume
,
76 .step
= cortex_m3_step
,
78 .assert_reset
= cortex_m3_assert_reset
,
79 .deassert_reset
= cortex_m3_deassert_reset
,
80 .soft_reset_halt
= cortex_m3_soft_reset_halt
,
82 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
84 .read_memory
= cortex_m3_read_memory
,
85 .write_memory
= cortex_m3_write_memory
,
86 .bulk_write_memory
= cortex_m3_bulk_write_memory
,
87 .checksum_memory
= armv7m_checksum_memory
,
88 .blank_check_memory
= armv7m_blank_check_memory
,
90 .run_algorithm
= armv7m_run_algorithm
,
92 .add_breakpoint
= cortex_m3_add_breakpoint
,
93 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
94 .add_watchpoint
= cortex_m3_add_watchpoint
,
95 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
97 .register_commands
= cortex_m3_register_commands
,
98 .target_create
= cortex_m3_target_create
,
99 .init_target
= cortex_m3_init_target
,
100 .examine
= cortex_m3_examine
,
101 .quit
= cortex_m3_quit
104 int cortex_m3_write_debug_halt_mask(target_t
*target
, u32 mask_on
, u32 mask_off
)
106 /* get pointers to arch-specific information */
107 armv7m_common_t
*armv7m
= target
->arch_info
;
108 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
109 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
111 /* mask off status bits */
112 cortex_m3
->dcb_dhcsr
&= ~((0xFFFF << 16) | mask_off
);
113 /* create new register mask */
114 cortex_m3
->dcb_dhcsr
|= DBGKEY
| C_DEBUGEN
| mask_on
;
116 return ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, cortex_m3
->dcb_dhcsr
);
119 int cortex_m3_clear_halt(target_t
*target
)
121 /* get pointers to arch-specific information */
122 armv7m_common_t
*armv7m
= target
->arch_info
;
123 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
124 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
126 /* clear step if any */
127 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_STEP
);
129 /* Read Debug Fault Status Register */
130 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
131 /* Write Debug Fault Status Register to enable processing to resume ?? Try with and without this !! */
132 ahbap_write_system_atomic_u32(swjdp
, NVIC_DFSR
, cortex_m3
->nvic_dfsr
);
133 LOG_DEBUG(" NVIC_DFSR 0x%x", cortex_m3
->nvic_dfsr
);
138 int cortex_m3_single_step_core(target_t
*target
)
140 /* get pointers to arch-specific information */
141 armv7m_common_t
*armv7m
= target
->arch_info
;
142 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
143 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
146 /* backup dhcsr reg */
147 dhcsr_save
= cortex_m3
->dcb_dhcsr
;
149 /* mask interrupts if not done already */
150 if (!(cortex_m3
->dcb_dhcsr
& C_MASKINTS
))
151 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_HALT
| C_DEBUGEN
);
152 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_MASKINTS
| C_STEP
| C_DEBUGEN
);
155 /* restore dhcsr reg */
156 cortex_m3
->dcb_dhcsr
= dhcsr_save
;
157 cortex_m3_clear_halt(target
);
162 int cortex_m3_exec_opcode(target_t
*target
,u32 opcode
, int len
/* MODE, r0_invalue, &r0_outvalue */ )
164 /* get pointers to arch-specific information */
165 armv7m_common_t
*armv7m
= target
->arch_info
;
166 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
167 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
171 ahbap_read_system_u32(swjdp
, 0x20000000, &savedram
);
172 ahbap_write_system_u32(swjdp
, 0x20000000, opcode
);
173 ahbap_write_coreregister_u32(swjdp
, 0x20000000, 15);
174 cortex_m3_single_step_core(target
);
175 armv7m
->core_cache
->reg_list
[15].dirty
= armv7m
->core_cache
->reg_list
[15].valid
;
176 retvalue
= ahbap_write_system_atomic_u32(swjdp
, 0x20000000, savedram
);
182 /* Enable interrupts */
183 int cortex_m3_cpsie(target_t
*target
, u32 IF
)
185 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSIE(IF
), 2);
188 /* Disable interrupts */
189 int cortex_m3_cpsid(target_t
*target
, u32 IF
)
191 return cortex_m3_exec_opcode(target
, ARMV7M_T_CPSID(IF
), 2);
195 int cortex_m3_endreset_event(target_t
*target
)
200 /* get pointers to arch-specific information */
201 armv7m_common_t
*armv7m
= target
->arch_info
;
202 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
203 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
204 cortex_m3_fp_comparator_t
*fp_list
= cortex_m3
->fp_comparator_list
;
205 cortex_m3_dwt_comparator_t
*dwt_list
= cortex_m3
->dwt_comparator_list
;
207 ahbap_read_system_atomic_u32(swjdp
, DCB_DEMCR
, &dcb_demcr
);
208 LOG_DEBUG("DCB_DEMCR = 0x%8.8x",dcb_demcr
);
210 /* this regsiter is used for emulated dcc channel */
211 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0);
213 /* Enable debug requests */
214 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
215 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
216 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
218 /* clear any interrupt masking */
219 cortex_m3_write_debug_halt_mask(target
, 0, C_MASKINTS
);
221 /* Enable trace and dwt */
222 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
223 /* Monitor bus faults */
224 ahbap_write_system_u32(swjdp
, NVIC_SHCSR
, SHCSR_BUSFAULTENA
);
227 target_write_u32(target
, FP_CTRL
, 3);
228 cortex_m3
->fpb_enabled
= 1;
230 /* Restore FPB registers */
231 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
233 target_write_u32(target
, fp_list
[i
].fpcr_address
, fp_list
[i
].fpcr_value
);
236 /* Restore DWT registers */
237 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
239 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
, dwt_list
[i
].comp
);
240 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x4, dwt_list
[i
].mask
);
241 target_write_u32(target
, dwt_list
[i
].dwt_comparator_address
| 0x8, dwt_list
[i
].function
);
243 swjdp_transaction_endcheck(swjdp
);
245 armv7m_invalidate_core_regs(target
);
249 int cortex_m3_examine_debug_reason(target_t
*target
)
251 /* get pointers to arch-specific information */
252 armv7m_common_t
*armv7m
= target
->arch_info
;
253 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
255 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
256 /* only check the debug reason if we don't know it already */
258 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
259 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
263 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
265 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
266 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
267 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
269 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
270 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
276 int cortex_m3_examine_exception_reason(target_t
*target
)
278 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
280 /* get pointers to arch-specific information */
281 armv7m_common_t
*armv7m
= target
->arch_info
;
282 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
283 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
285 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
286 switch (armv7m
->exception_number
)
290 case 3: /* Hard Fault */
291 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
292 if (except_sr
& 0x40000000)
294 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
297 case 4: /* Memory Management */
298 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
299 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
301 case 5: /* Bus Fault */
302 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
303 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
305 case 6: /* Usage Fault */
306 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
308 case 11: /* SVCall */
310 case 12: /* Debug Monitor */
311 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
313 case 14: /* PendSV */
315 case 15: /* SysTick */
321 swjdp_transaction_endcheck(swjdp
);
322 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
323 shcsr
, except_sr
, cfsr
, except_ar
);
327 int cortex_m3_debug_entry(target_t
*target
)
333 /* get pointers to arch-specific information */
334 armv7m_common_t
*armv7m
= target
->arch_info
;
335 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
336 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
339 if (armv7m
->pre_debug_entry
)
340 armv7m
->pre_debug_entry(target
);
342 cortex_m3_clear_halt(target
);
343 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
345 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
348 /* Examine target state and mode */
349 /* First load register acessible through core debug port*/
350 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
352 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
353 armv7m
->read_core_reg(target
, i
);
356 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
358 #ifdef ARMV7_GDB_HACKS
359 /* copy real xpsr reg for gdb, setting thumb bit */
360 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
361 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
362 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
363 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
366 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
369 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
370 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
373 /* Now we can load SP core registers */
374 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
376 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
377 armv7m
->read_core_reg(target
, i
);
380 /* Are we in an exception handler */
383 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
384 armv7m
->exception_number
= (xPSR
& 0x1FF);
388 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
389 armv7m
->exception_number
= 0;
392 if (armv7m
->exception_number
)
394 cortex_m3_examine_exception_reason(target
);
397 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
398 armv7m_mode_strings
[armv7m
->core_mode
],
399 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
400 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
402 if (armv7m
->post_debug_entry
)
403 armv7m
->post_debug_entry(target
);
408 int cortex_m3_poll(target_t
*target
)
411 enum target_state prev_target_state
= target
->state
;
413 /* get pointers to arch-specific information */
414 armv7m_common_t
*armv7m
= target
->arch_info
;
415 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
416 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
418 /* Read from Debug Halting Control and Status Register */
419 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
420 if (retval
!= ERROR_OK
)
422 target
->state
= TARGET_UNKNOWN
;
426 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
428 /* check if still in reset */
429 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
431 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
433 target
->state
= TARGET_RESET
;
438 if (target
->state
== TARGET_RESET
)
440 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
441 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
442 cortex_m3_endreset_event(target
);
443 target
->state
= TARGET_RUNNING
;
444 prev_target_state
= TARGET_RUNNING
;
447 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
449 target
->state
= TARGET_HALTED
;
451 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
453 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
456 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
458 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
461 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
464 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
469 if (cortex_m3->dcb_dhcsr & S_SLEEP)
470 target->state = TARGET_SLEEP;
474 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
475 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
476 LOG_DEBUG("dcb_dhcsr 0x%x, nvic_dfsr 0x%x, target->state: %s", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_dfsr
, Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
482 int cortex_m3_halt(target_t
*target
)
484 LOG_DEBUG("target->state: %s",
485 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
487 if (target
->state
== TARGET_HALTED
)
489 LOG_DEBUG("target was already halted");
493 if (target
->state
== TARGET_UNKNOWN
)
495 LOG_WARNING("target was in unknown state when halt was requested");
498 if (target
->state
== TARGET_RESET
)
500 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
502 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
503 return ERROR_TARGET_FAILURE
;
507 /* we came here in a reset_halt or reset_init sequence
508 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
510 target
->debug_reason
= DBG_REASON_DBGRQ
;
516 /* Write to Debug Halting Control and Status Register */
517 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
519 target
->debug_reason
= DBG_REASON_DBGRQ
;
524 int cortex_m3_soft_reset_halt(struct target_s
*target
)
526 /* get pointers to arch-specific information */
527 armv7m_common_t
*armv7m
= target
->arch_info
;
528 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
529 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
531 int retval
, timeout
= 0;
533 /* Enter debug state on reset, cf. end_reset_event() */
534 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
536 /* Request a reset */
537 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
538 target
->state
= TARGET_RESET
;
540 /* registers are now invalid */
541 armv7m_invalidate_core_regs(target
);
543 while (timeout
< 100)
545 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
546 if (retval
== ERROR_OK
)
548 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
549 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
551 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
552 cortex_m3_poll(target
);
556 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
565 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
567 /* get pointers to arch-specific information */
568 armv7m_common_t
*armv7m
= target
->arch_info
;
569 breakpoint_t
*breakpoint
= NULL
;
572 if (target
->state
!= TARGET_HALTED
)
574 LOG_WARNING("target not halted");
575 return ERROR_TARGET_NOT_HALTED
;
578 if (!debug_execution
)
580 target_free_all_working_areas(target
);
581 cortex_m3_enable_breakpoints(target
);
582 cortex_m3_enable_watchpoints(target
);
587 /* Disable interrupts */
588 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
589 * This is probably the same issue as Cortex-M3 Errata 377493:
590 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
591 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
592 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
593 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
595 /* Make sure we are in Thumb mode */
596 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
597 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
598 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
599 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
602 /* current = 1: continue on current pc, otherwise continue at <address> */
605 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
606 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
607 armv7m
->core_cache
->reg_list
[15].valid
= 1;
610 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
612 armv7m_restore_context(target
);
614 /* the front-end may request us not to handle breakpoints */
615 if (handle_breakpoints
)
617 /* Single step past breakpoint at current address */
618 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
620 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
621 cortex_m3_unset_breakpoint(target
, breakpoint
);
622 cortex_m3_single_step_core(target
);
623 cortex_m3_set_breakpoint(target
, breakpoint
);
628 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
630 target
->debug_reason
= DBG_REASON_NOTHALTED
;
632 /* registers are now invalid */
633 armv7m_invalidate_core_regs(target
);
634 if (!debug_execution
)
636 target
->state
= TARGET_RUNNING
;
637 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
638 LOG_DEBUG("target resumed at 0x%x", resume_pc
);
642 target
->state
= TARGET_DEBUG_RUNNING
;
643 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
644 LOG_DEBUG("target debug resumed at 0x%x", resume_pc
);
650 /* int irqstepcount=0; */
651 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
653 /* get pointers to arch-specific information */
654 armv7m_common_t
*armv7m
= target
->arch_info
;
655 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
656 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
657 breakpoint_t
*breakpoint
= NULL
;
659 if (target
->state
!= TARGET_HALTED
)
661 LOG_WARNING("target not halted");
662 return ERROR_TARGET_NOT_HALTED
;
665 /* current = 1: continue on current pc, otherwise continue at <address> */
667 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
669 /* the front-end may request us not to handle breakpoints */
670 if (handle_breakpoints
)
671 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
672 cortex_m3_unset_breakpoint(target
, breakpoint
);
674 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
676 armv7m_restore_context(target
);
678 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
680 /* set step and clear halt */
681 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
682 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
684 /* registers are now invalid */
685 armv7m_invalidate_core_regs(target
);
688 cortex_m3_set_breakpoint(target
, breakpoint
);
690 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
692 cortex_m3_debug_entry(target
);
693 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
695 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
699 int cortex_m3_assert_reset(target_t
*target
)
701 armv7m_common_t
*armv7m
= target
->arch_info
;
702 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
703 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
706 LOG_DEBUG("target->state: %s",
707 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
709 if (!(jtag_reset_config
& RESET_HAS_SRST
))
711 LOG_ERROR("Can't assert SRST");
715 /* Enable debug requests */
716 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
717 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
718 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
720 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
722 if (!target
->reset_halt
)
724 /* Set/Clear C_MASKINTS in a separate operation */
725 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
726 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
728 cortex_m3_clear_halt(target
);
730 /* Enter debug state on reset, cf. end_reset_event() */
731 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
735 /* Enter debug state on reset, cf. end_reset_event() */
736 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
739 /* following hack is to handle luminary reset
740 * when srst is asserted the luminary device seesm to also clear the debug registers
741 * which does not match the armv7 debug TRM */
743 if (strcmp(cortex_m3
->variant
, "lm3s") == 0)
745 /* get revision of lm3s target, only early silicon has this issue
746 * Fury Rev B, DustDevil Rev B, Tempest all ok */
750 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
752 switch ((did0
>> 16) & 0xff)
755 /* all Sandstorm suffer issue */
761 /* only Fury/DustDevil rev A suffer reset problems */
762 if (((did0
>> 8) & 0xff) == 0)
771 /* default to asserting srst */
772 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
774 jtag_add_reset(1, 1);
778 jtag_add_reset(0, 1);
783 /* this causes the luminary device to reset using the watchdog */
784 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
785 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
788 /* I do not know why this is necessary, but it fixes strange effects
789 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
791 ahbap_read_system_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
795 target
->state
= TARGET_RESET
;
796 jtag_add_sleep(50000);
798 armv7m_invalidate_core_regs(target
);
800 if (target
->reset_halt
)
803 if ((retval
= target_halt(target
))!=ERROR_OK
)
810 int cortex_m3_deassert_reset(target_t
*target
)
812 LOG_DEBUG("target->state: %s",
813 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
815 /* deassert reset lines */
816 jtag_add_reset(0, 0);
821 void cortex_m3_enable_breakpoints(struct target_s
*target
)
823 breakpoint_t
*breakpoint
= target
->breakpoints
;
825 /* set any pending breakpoints */
828 if (breakpoint
->set
== 0)
829 cortex_m3_set_breakpoint(target
, breakpoint
);
830 breakpoint
= breakpoint
->next
;
834 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
840 /* get pointers to arch-specific information */
841 armv7m_common_t
*armv7m
= target
->arch_info
;
842 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
844 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
848 LOG_WARNING("breakpoint already set");
852 if (cortex_m3
->auto_bp_type
)
854 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
857 if (breakpoint
->type
== BKPT_HARD
)
859 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
861 if (fp_num
>= cortex_m3
->fp_num_code
)
863 LOG_DEBUG("ERROR Can not find free FP Comparator");
864 LOG_WARNING("ERROR Can not find free FP Comparator");
867 breakpoint
->set
= fp_num
+ 1;
868 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
869 comparator_list
[fp_num
].used
= 1;
870 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
871 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
872 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
873 if (!cortex_m3
->fpb_enabled
)
875 LOG_DEBUG("FPB wasn't enabled, do it now");
876 target_write_u32(target
, FP_CTRL
, 3);
879 else if (breakpoint
->type
== BKPT_SOFT
)
882 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
883 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
887 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
891 breakpoint
->set
= 0x11; /* Any nice value but 0 */
897 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
900 /* get pointers to arch-specific information */
901 armv7m_common_t
*armv7m
= target
->arch_info
;
902 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
903 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
905 if (!breakpoint
->set
)
907 LOG_WARNING("breakpoint not set");
911 if (breakpoint
->type
== BKPT_HARD
)
913 int fp_num
= breakpoint
->set
- 1;
914 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
916 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
919 comparator_list
[fp_num
].used
= 0;
920 comparator_list
[fp_num
].fpcr_value
= 0;
921 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
925 /* restore original instruction (kept in target endianness) */
926 if (breakpoint
->length
== 4)
928 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
935 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
946 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
948 /* get pointers to arch-specific information */
949 armv7m_common_t
*armv7m
= target
->arch_info
;
950 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
952 if (cortex_m3
->auto_bp_type
)
954 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
955 #ifdef ARMV7_GDB_HACKS
956 if (breakpoint
->length
!= 2) {
957 /* XXX Hack: Replace all breakpoints with length != 2 with
958 * a hardware breakpoint. */
959 breakpoint
->type
= BKPT_HARD
;
960 breakpoint
->length
= 2;
965 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
967 LOG_INFO("flash patch comparator requested outside code memory region");
968 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
971 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
973 LOG_INFO("soft breakpoint requested in code (flash) memory region");
974 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
977 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
979 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
980 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
983 if ((breakpoint
->length
!= 2))
985 LOG_INFO("only breakpoints of two bytes length supported");
986 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
989 if (breakpoint
->type
== BKPT_HARD
)
990 cortex_m3
->fp_code_available
--;
991 cortex_m3_set_breakpoint(target
, breakpoint
);
996 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
998 /* get pointers to arch-specific information */
999 armv7m_common_t
*armv7m
= target
->arch_info
;
1000 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1002 if (target
->state
!= TARGET_HALTED
)
1004 LOG_WARNING("target not halted");
1005 return ERROR_TARGET_NOT_HALTED
;
1008 if (cortex_m3
->auto_bp_type
)
1010 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1013 if (breakpoint
->set
)
1015 cortex_m3_unset_breakpoint(target
, breakpoint
);
1018 if (breakpoint
->type
== BKPT_HARD
)
1019 cortex_m3
->fp_code_available
++;
1024 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1029 /* get pointers to arch-specific information */
1030 armv7m_common_t
*armv7m
= target
->arch_info
;
1031 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1032 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1034 if (watchpoint
->set
)
1036 LOG_WARNING("watchpoint already set");
1040 if (watchpoint
->mask
== 0xffffffffu
)
1042 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1044 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1046 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1047 LOG_WARNING("ERROR Can not find free DWT Comparator");
1050 watchpoint
->set
= dwt_num
+ 1;
1052 temp
= watchpoint
->length
;
1058 comparator_list
[dwt_num
].used
= 1;
1059 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1060 comparator_list
[dwt_num
].mask
= mask
;
1061 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1062 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1063 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1064 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1065 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
);
1069 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1077 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1079 /* get pointers to arch-specific information */
1080 armv7m_common_t
*armv7m
= target
->arch_info
;
1081 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1082 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1085 if (!watchpoint
->set
)
1087 LOG_WARNING("watchpoint not set");
1091 dwt_num
= watchpoint
->set
- 1;
1093 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1095 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1098 comparator_list
[dwt_num
].used
= 0;
1099 comparator_list
[dwt_num
].function
= 0;
1100 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1102 watchpoint
->set
= 0;
1107 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1109 /* get pointers to arch-specific information */
1110 armv7m_common_t
*armv7m
= target
->arch_info
;
1111 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1113 if (target
->state
!= TARGET_HALTED
)
1115 LOG_WARNING("target not halted");
1116 return ERROR_TARGET_NOT_HALTED
;
1119 if (cortex_m3
->dwt_comp_available
< 1)
1121 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1124 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1126 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1129 cortex_m3
->dwt_comp_available
--;
1134 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1136 /* get pointers to arch-specific information */
1137 armv7m_common_t
*armv7m
= target
->arch_info
;
1138 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1140 if (target
->state
!= TARGET_HALTED
)
1142 LOG_WARNING("target not halted");
1143 return ERROR_TARGET_NOT_HALTED
;
1146 if (watchpoint
->set
)
1148 cortex_m3_unset_watchpoint(target
, watchpoint
);
1151 cortex_m3
->dwt_comp_available
++;
1156 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1158 watchpoint_t
*watchpoint
= target
->watchpoints
;
1160 /* set any pending watchpoints */
1163 if (watchpoint
->set
== 0)
1164 cortex_m3_set_watchpoint(target
, watchpoint
);
1165 watchpoint
= watchpoint
->next
;
1169 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1172 /* get pointers to arch-specific information */
1173 armv7m_common_t
*armv7m
= target
->arch_info
;
1174 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1175 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1177 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1179 /* read a normal core register */
1180 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1182 if (retval
!= ERROR_OK
)
1184 LOG_ERROR("JTAG failure %i",retval
);
1185 return ERROR_JTAG_DEVICE_ERROR
;
1187 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1189 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1191 /* read other registers */
1192 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1197 *value
= buf_get_u32((u8
*)value
, 0, 8);
1201 *value
= buf_get_u32((u8
*)value
, 8, 8);
1205 *value
= buf_get_u32((u8
*)value
, 16, 8);
1209 *value
= buf_get_u32((u8
*)value
, 24, 8);
1213 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1217 return ERROR_INVALID_ARGUMENTS
;
1223 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
1228 /* get pointers to arch-specific information */
1229 armv7m_common_t
*armv7m
= target
->arch_info
;
1230 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1231 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1233 #ifdef ARMV7_GDB_HACKS
1234 /* If the LR register is being modified, make sure it will put us
1235 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1236 * hack to deal with the fact that gdb will sometimes "forge"
1237 * return addresses, and doesn't set the LSB correctly (i.e., when
1238 * printing expressions containing function calls, it sets LR=0.) */
1244 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1246 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1247 if (retval
!= ERROR_OK
)
1249 LOG_ERROR("JTAG failure %i", retval
);
1250 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1251 return ERROR_JTAG_DEVICE_ERROR
;
1253 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1255 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1257 /* write other registers */
1259 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1264 buf_set_u32((u8
*)®
, 0, 8, value
);
1268 buf_set_u32((u8
*)®
, 8, 8, value
);
1272 buf_set_u32((u8
*)®
, 16, 8, value
);
1276 buf_set_u32((u8
*)®
, 24, 8, value
);
1280 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1282 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1286 return ERROR_INVALID_ARGUMENTS
;
1292 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1294 /* get pointers to arch-specific information */
1295 armv7m_common_t
*armv7m
= target
->arch_info
;
1296 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1297 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1300 /* sanitize arguments */
1301 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1302 return ERROR_INVALID_ARGUMENTS
;
1304 /* cortex_m3 handles unaligned memory access */
1309 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1312 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1315 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1318 LOG_ERROR("BUG: we shouldn't get here");
1325 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1327 /* get pointers to arch-specific information */
1328 armv7m_common_t
*armv7m
= target
->arch_info
;
1329 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1330 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1333 /* sanitize arguments */
1334 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1335 return ERROR_INVALID_ARGUMENTS
;
1340 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1343 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1346 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1349 LOG_ERROR("BUG: we shouldn't get here");
1356 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1358 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1361 void cortex_m3_build_reg_cache(target_t
*target
)
1363 armv7m_build_reg_cache(target
);
1366 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1368 cortex_m3_build_reg_cache(target
);
1372 int cortex_m3_examine(struct target_s
*target
)
1375 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1378 /* get pointers to arch-specific information */
1379 armv7m_common_t
*armv7m
= target
->arch_info
;
1380 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1381 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1383 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1386 if (!target
->type
->examined
)
1388 target
->type
->examined
= 1;
1390 /* Read from Device Identification Registers */
1391 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1394 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1395 LOG_DEBUG("CORTEX-M3 processor detected");
1396 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1398 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1399 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1400 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1401 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1403 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1404 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1408 target_read_u32(target
, FP_CTRL
, &fpcr
);
1409 cortex_m3
->auto_bp_type
= 1;
1410 cortex_m3
->fp_num_code
= (fpcr
>> 8) & 0x70 | (fpcr
>> 4) & 0xF; /* bits [14:12] and [7:4] */
1411 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1412 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1413 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1414 cortex_m3
->fpb_enabled
= fpcr
& 1;
1415 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1417 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1418 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1420 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1423 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1424 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1425 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1426 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1427 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1429 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1436 int cortex_m3_quit(void)
1442 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1446 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1448 *value
= (u8
)(dcrdr
>> 8);
1450 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1452 /* write ack back to software dcc register
1453 * signify we have read data */
1454 if (dcrdr
& (1 << 0))
1457 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1463 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1465 armv7m_common_t
*armv7m
= target
->arch_info
;
1466 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1467 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1472 for (i
= 0; i
< (size
* 4); i
++)
1474 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1481 int cortex_m3_handle_target_request(void *priv
)
1483 target_t
*target
= priv
;
1484 if (!target
->type
->examined
)
1486 armv7m_common_t
*armv7m
= target
->arch_info
;
1487 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1488 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1490 if (!target
->dbg_msg_enabled
)
1493 if (target
->state
== TARGET_RUNNING
)
1498 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1500 /* check if we have data */
1501 if (ctrl
& (1 << 0))
1505 /* we assume target is quick enough */
1507 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1508 request
|= (data
<< 8);
1509 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1510 request
|= (data
<< 16);
1511 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1512 request
|= (data
<< 24);
1513 target_request(target
, request
);
1520 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
, const char *variant
)
1522 armv7m_common_t
*armv7m
;
1523 armv7m
= &cortex_m3
->armv7m
;
1525 /* prepare JTAG information for the new target */
1526 cortex_m3
->jtag_info
.tap
= tap
;
1527 cortex_m3
->jtag_info
.scann_size
= 4;
1529 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1530 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1531 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1532 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1534 /* initialize arch-specific breakpoint handling */
1536 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1537 cortex_m3
->arch_info
= NULL
;
1539 /* register arch-specific functions */
1540 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1542 armv7m
->pre_debug_entry
= NULL
;
1543 armv7m
->post_debug_entry
= NULL
;
1545 armv7m
->pre_restore_context
= NULL
;
1546 armv7m
->post_restore_context
= NULL
;
1550 cortex_m3
->variant
= strdup(variant
);
1554 cortex_m3
->variant
= strdup("");
1557 armv7m_init_arch_info(target
, armv7m
);
1558 armv7m
->arch_info
= cortex_m3
;
1559 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1560 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1562 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1567 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1569 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1571 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
, target
->variant
);
1576 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1579 command_t
*cortex_m3_cmd
;
1581 retval
= armv7m_register_commands(cmd_ctx
);
1583 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3", NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1584 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr", handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
, "mask cortex_m3 interrupts ['on'|'off']");
1589 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1591 target_t
*target
= get_current_target(cmd_ctx
);
1592 armv7m_common_t
*armv7m
= target
->arch_info
;
1593 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1595 if (target
->state
!= TARGET_HALTED
)
1597 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1603 if (!strcmp(args
[0], "on"))
1605 cortex_m3_write_debug_halt_mask(target
, C_HALT
|C_MASKINTS
, 0);
1607 else if (!strcmp(args
[0], "off"))
1609 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1613 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1617 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1618 (cortex_m3
->dcb_dhcsr
& C_MASKINTS
) ? "on" : "off");
Linking to existing account procedure
If you already have an account and want to add another login method
you
MUST first sign in with your existing account and
then change URL to read
https://review.openocd.org/login/?link
to get to this page again but this time it'll work for linking. Thank you.
SSH host keys fingerprints
1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=.. |
|+o.. . |
|*.o . . |
|+B . . . |
|Bo. = o S |
|Oo.+ + = |
|oB=.* = . o |
| =+=.+ + E |
|. .=o . o |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)