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
);
247 /* make sure we have latest dhcsr flags */
248 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
253 int cortex_m3_examine_debug_reason(target_t
*target
)
255 /* get pointers to arch-specific information */
256 armv7m_common_t
*armv7m
= target
->arch_info
;
257 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
259 /* THIS IS NOT GOOD, TODO - better logic for detection of debug state reason */
260 /* only check the debug reason if we don't know it already */
262 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
263 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
))
267 if (cortex_m3
->nvic_dfsr
& DFSR_BKPT
)
269 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
270 if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
271 target
->debug_reason
= DBG_REASON_WPTANDBKPT
;
273 else if (cortex_m3
->nvic_dfsr
& DFSR_DWTTRAP
)
274 target
->debug_reason
= DBG_REASON_WATCHPOINT
;
280 int cortex_m3_examine_exception_reason(target_t
*target
)
282 u32 shcsr
, except_sr
, cfsr
= -1, except_ar
= -1;
284 /* get pointers to arch-specific information */
285 armv7m_common_t
*armv7m
= target
->arch_info
;
286 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
287 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
289 ahbap_read_system_u32(swjdp
, NVIC_SHCSR
, &shcsr
);
290 switch (armv7m
->exception_number
)
294 case 3: /* Hard Fault */
295 ahbap_read_system_atomic_u32(swjdp
, NVIC_HFSR
, &except_sr
);
296 if (except_sr
& 0x40000000)
298 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &cfsr
);
301 case 4: /* Memory Management */
302 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
303 ahbap_read_system_u32(swjdp
, NVIC_MMFAR
, &except_ar
);
305 case 5: /* Bus Fault */
306 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
307 ahbap_read_system_u32(swjdp
, NVIC_BFAR
, &except_ar
);
309 case 6: /* Usage Fault */
310 ahbap_read_system_u32(swjdp
, NVIC_CFSR
, &except_sr
);
312 case 11: /* SVCall */
314 case 12: /* Debug Monitor */
315 ahbap_read_system_u32(swjdp
, NVIC_DFSR
, &except_sr
);
317 case 14: /* PendSV */
319 case 15: /* SysTick */
325 swjdp_transaction_endcheck(swjdp
);
326 LOG_DEBUG("%s SHCSR 0x%x, SR 0x%x, CFSR 0x%x, AR 0x%x", armv7m_exception_string(armv7m
->exception_number
), \
327 shcsr
, except_sr
, cfsr
, except_ar
);
331 int cortex_m3_debug_entry(target_t
*target
)
337 /* get pointers to arch-specific information */
338 armv7m_common_t
*armv7m
= target
->arch_info
;
339 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
340 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
343 if (armv7m
->pre_debug_entry
)
344 armv7m
->pre_debug_entry(target
);
346 cortex_m3_clear_halt(target
);
347 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
349 if ((retval
= armv7m
->examine_debug_reason(target
)) != ERROR_OK
)
352 /* Examine target state and mode */
353 /* First load register acessible through core debug port*/
354 for (i
= 0; i
< ARMV7M_PRIMASK
; i
++)
356 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
357 armv7m
->read_core_reg(target
, i
);
360 xPSR
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32);
362 #ifdef ARMV7_GDB_HACKS
363 /* copy real xpsr reg for gdb, setting thumb bit */
364 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 0, 32, xPSR
);
365 buf_set_u32(armv7m_gdb_dummy_cpsr_value
, 5, 1, 1);
366 armv7m_gdb_dummy_cpsr_reg
.valid
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
367 armv7m_gdb_dummy_cpsr_reg
.dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
;
370 /* For IT instructions xPSR must be reloaded on resume and clear on debug exec */
373 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
;
374 cortex_m3_store_core_reg_u32(target
, ARMV7M_REGISTER_CORE_GP
, 16, xPSR
&~ 0xff);
377 /* Now we can load SP core registers */
378 for (i
= ARMV7M_PRIMASK
; i
< ARMV7NUMCOREREGS
; i
++)
380 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
381 armv7m
->read_core_reg(target
, i
);
384 /* Are we in an exception handler */
387 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
388 armv7m
->exception_number
= (xPSR
& 0x1FF);
392 armv7m
->core_mode
= buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_CONTROL
].value
, 0, 1);
393 armv7m
->exception_number
= 0;
396 if (armv7m
->exception_number
)
398 cortex_m3_examine_exception_reason(target
);
401 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%x, target->state: %s",
402 armv7m_mode_strings
[armv7m
->core_mode
],
403 *(u32
*)(armv7m
->core_cache
->reg_list
[15].value
),
404 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
406 if (armv7m
->post_debug_entry
)
407 armv7m
->post_debug_entry(target
);
412 int cortex_m3_poll(target_t
*target
)
415 enum target_state prev_target_state
= target
->state
;
417 /* get pointers to arch-specific information */
418 armv7m_common_t
*armv7m
= target
->arch_info
;
419 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
420 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
422 /* Read from Debug Halting Control and Status Register */
423 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
424 if (retval
!= ERROR_OK
)
426 target
->state
= TARGET_UNKNOWN
;
430 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
432 /* check if still in reset */
433 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
435 if (cortex_m3
->dcb_dhcsr
& S_RESET_ST
)
437 target
->state
= TARGET_RESET
;
442 if (target
->state
== TARGET_RESET
)
444 /* Cannot switch context while running so endreset is called with target->state == TARGET_RESET */
445 LOG_DEBUG("Exit from reset with dcb_dhcsr 0x%x", cortex_m3
->dcb_dhcsr
);
446 cortex_m3_endreset_event(target
);
447 target
->state
= TARGET_RUNNING
;
448 prev_target_state
= TARGET_RUNNING
;
451 if (cortex_m3
->dcb_dhcsr
& S_HALT
)
453 target
->state
= TARGET_HALTED
;
455 if ((prev_target_state
== TARGET_RUNNING
) || (prev_target_state
== TARGET_RESET
))
457 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
460 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
462 if (prev_target_state
== TARGET_DEBUG_RUNNING
)
465 if ((retval
= cortex_m3_debug_entry(target
)) != ERROR_OK
)
468 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_HALTED
);
473 if (cortex_m3->dcb_dhcsr & S_SLEEP)
474 target->state = TARGET_SLEEP;
478 /* Read Debug Fault Status Register, added to figure out the lockup when running flashtest.script */
479 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
480 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
);
486 int cortex_m3_halt(target_t
*target
)
488 LOG_DEBUG("target->state: %s",
489 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
491 if (target
->state
== TARGET_HALTED
)
493 LOG_DEBUG("target was already halted");
497 if (target
->state
== TARGET_UNKNOWN
)
499 LOG_WARNING("target was in unknown state when halt was requested");
502 if (target
->state
== TARGET_RESET
)
504 if ((jtag_reset_config
& RESET_SRST_PULLS_TRST
) && jtag_srst
)
506 LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
507 return ERROR_TARGET_FAILURE
;
511 /* we came here in a reset_halt or reset_init sequence
512 * debug entry was already prepared in cortex_m3_prepare_reset_halt()
514 target
->debug_reason
= DBG_REASON_DBGRQ
;
520 /* Write to Debug Halting Control and Status Register */
521 cortex_m3_write_debug_halt_mask(target
, C_HALT
, 0);
523 target
->debug_reason
= DBG_REASON_DBGRQ
;
528 int cortex_m3_soft_reset_halt(struct target_s
*target
)
530 /* get pointers to arch-specific information */
531 armv7m_common_t
*armv7m
= target
->arch_info
;
532 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
533 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
535 int retval
, timeout
= 0;
537 /* Enter debug state on reset, cf. end_reset_event() */
538 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
540 /* Request a reset */
541 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_VECTRESET
);
542 target
->state
= TARGET_RESET
;
544 /* registers are now invalid */
545 armv7m_invalidate_core_regs(target
);
547 while (timeout
< 100)
549 retval
= ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &dcb_dhcsr
);
550 if (retval
== ERROR_OK
)
552 ahbap_read_system_atomic_u32(swjdp
, NVIC_DFSR
, &cortex_m3
->nvic_dfsr
);
553 if ((dcb_dhcsr
& S_HALT
) && (cortex_m3
->nvic_dfsr
& DFSR_VCATCH
))
555 LOG_DEBUG("system reset-halted, dcb_dhcsr 0x%x, nvic_dfsr 0x%x", dcb_dhcsr
, cortex_m3
->nvic_dfsr
);
556 cortex_m3_poll(target
);
560 LOG_DEBUG("waiting for system reset-halt, dcb_dhcsr 0x%x, %i ms", dcb_dhcsr
, timeout
);
569 int cortex_m3_resume(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
, int debug_execution
)
571 /* get pointers to arch-specific information */
572 armv7m_common_t
*armv7m
= target
->arch_info
;
573 breakpoint_t
*breakpoint
= NULL
;
576 if (target
->state
!= TARGET_HALTED
)
578 LOG_WARNING("target not halted");
579 return ERROR_TARGET_NOT_HALTED
;
582 if (!debug_execution
)
584 target_free_all_working_areas(target
);
585 cortex_m3_enable_breakpoints(target
);
586 cortex_m3_enable_watchpoints(target
);
591 /* Disable interrupts */
592 /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS,
593 * This is probably the same issue as Cortex-M3 Errata 377493:
594 * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */
595 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].value
, 0, 32, 1);
596 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].dirty
= 1;
597 armv7m
->core_cache
->reg_list
[ARMV7M_PRIMASK
].valid
= 1;
599 /* Make sure we are in Thumb mode */
600 buf_set_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32,
601 buf_get_u32(armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].value
, 0, 32) | (1<<24));
602 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].dirty
= 1;
603 armv7m
->core_cache
->reg_list
[ARMV7M_xPSR
].valid
= 1;
606 /* current = 1: continue on current pc, otherwise continue at <address> */
609 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
610 armv7m
->core_cache
->reg_list
[15].dirty
= 1;
611 armv7m
->core_cache
->reg_list
[15].valid
= 1;
614 resume_pc
= buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32);
616 armv7m_restore_context(target
);
618 /* the front-end may request us not to handle breakpoints */
619 if (handle_breakpoints
)
621 /* Single step past breakpoint at current address */
622 if ((breakpoint
= breakpoint_find(target
, resume_pc
)))
624 LOG_DEBUG("unset breakpoint at 0x%8.8x", breakpoint
->address
);
625 cortex_m3_unset_breakpoint(target
, breakpoint
);
626 cortex_m3_single_step_core(target
);
627 cortex_m3_set_breakpoint(target
, breakpoint
);
632 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
634 target
->debug_reason
= DBG_REASON_NOTHALTED
;
636 /* registers are now invalid */
637 armv7m_invalidate_core_regs(target
);
638 if (!debug_execution
)
640 target
->state
= TARGET_RUNNING
;
641 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
642 LOG_DEBUG("target resumed at 0x%x", resume_pc
);
646 target
->state
= TARGET_DEBUG_RUNNING
;
647 target_call_event_callbacks(target
, TARGET_EVENT_DEBUG_RESUMED
);
648 LOG_DEBUG("target debug resumed at 0x%x", resume_pc
);
654 /* int irqstepcount=0; */
655 int cortex_m3_step(struct target_s
*target
, int current
, u32 address
, int handle_breakpoints
)
657 /* get pointers to arch-specific information */
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
;
661 breakpoint_t
*breakpoint
= NULL
;
663 if (target
->state
!= TARGET_HALTED
)
665 LOG_WARNING("target not halted");
666 return ERROR_TARGET_NOT_HALTED
;
669 /* current = 1: continue on current pc, otherwise continue at <address> */
671 buf_set_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32, address
);
673 /* the front-end may request us not to handle breakpoints */
674 if (handle_breakpoints
)
675 if ((breakpoint
= breakpoint_find(target
, buf_get_u32(armv7m
->core_cache
->reg_list
[15].value
, 0, 32))))
676 cortex_m3_unset_breakpoint(target
, breakpoint
);
678 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
680 armv7m_restore_context(target
);
682 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
684 /* set step and clear halt */
685 cortex_m3_write_debug_halt_mask(target
, C_STEP
, C_HALT
);
686 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
688 /* registers are now invalid */
689 armv7m_invalidate_core_regs(target
);
692 cortex_m3_set_breakpoint(target
, breakpoint
);
694 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
696 cortex_m3_debug_entry(target
);
697 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
699 LOG_DEBUG("target stepped dcb_dhcsr = 0x%x nvic_icsr = 0x%x", cortex_m3
->dcb_dhcsr
, cortex_m3
->nvic_icsr
);
703 int cortex_m3_assert_reset(target_t
*target
)
705 armv7m_common_t
*armv7m
= target
->arch_info
;
706 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
707 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
710 LOG_DEBUG("target->state: %s",
711 Jim_Nvp_value2name_simple( nvp_target_state
, target
->state
)->name
);
713 if (!(jtag_reset_config
& RESET_HAS_SRST
))
715 LOG_ERROR("Can't assert SRST");
719 /* Enable debug requests */
720 ahbap_read_system_atomic_u32(swjdp
, DCB_DHCSR
, &cortex_m3
->dcb_dhcsr
);
721 if (!(cortex_m3
->dcb_dhcsr
& C_DEBUGEN
))
722 ahbap_write_system_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
);
724 ahbap_write_system_u32(swjdp
, DCB_DCRDR
, 0 );
726 if (!target
->reset_halt
)
728 /* Set/Clear C_MASKINTS in a separate operation */
729 if (cortex_m3
->dcb_dhcsr
& C_MASKINTS
)
730 ahbap_write_system_atomic_u32(swjdp
, DCB_DHCSR
, DBGKEY
| C_DEBUGEN
| C_HALT
);
732 /* clear any debug flags before resuming */
733 cortex_m3_clear_halt(target
);
735 /* clear C_HALT in dhcsr reg */
736 cortex_m3_write_debug_halt_mask(target
, 0, C_HALT
);
738 /* Enter debug state on reset, cf. end_reset_event() */
739 ahbap_write_system_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
);
743 /* Enter debug state on reset, cf. end_reset_event() */
744 ahbap_write_system_atomic_u32(swjdp
, DCB_DEMCR
, TRCENA
| VC_HARDERR
| VC_BUSERR
| VC_CORERESET
);
747 /* following hack is to handle luminary reset
748 * when srst is asserted the luminary device seesm to also clear the debug registers
749 * which does not match the armv7 debug TRM */
751 if (strcmp(target
->variant
, "lm3s") == 0)
753 /* get revision of lm3s target, only early silicon has this issue
754 * Fury Rev B, DustDevil Rev B, Tempest all ok */
758 if (target_read_u32(target
, 0x400fe000, &did0
) == ERROR_OK
)
760 switch ((did0
>> 16) & 0xff)
763 /* all Sandstorm suffer issue */
769 /* only Fury/DustDevil rev A suffer reset problems */
770 if (((did0
>> 8) & 0xff) == 0)
779 /* default to asserting srst */
780 if (jtag_reset_config
& RESET_SRST_PULLS_TRST
)
782 jtag_add_reset(1, 1);
786 jtag_add_reset(0, 1);
791 /* this causes the luminary device to reset using the watchdog */
792 ahbap_write_system_atomic_u32(swjdp
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
793 LOG_DEBUG("Using Luminary Reset: SYSRESETREQ");
796 /* I do not know why this is necessary, but it fixes strange effects
797 * (step/resume cause a NMI after reset) on LM3S6918 -- Michael Schwingen */
799 ahbap_read_system_atomic_u32(swjdp
, NVIC_AIRCR
, &tmp
);
803 target
->state
= TARGET_RESET
;
804 jtag_add_sleep(50000);
806 armv7m_invalidate_core_regs(target
);
808 if (target
->reset_halt
)
811 if ((retval
= target_halt(target
))!=ERROR_OK
)
818 int cortex_m3_deassert_reset(target_t
*target
)
820 LOG_DEBUG("target->state: %s",
821 Jim_Nvp_value2name_simple(nvp_target_state
, target
->state
)->name
);
823 /* deassert reset lines */
824 jtag_add_reset(0, 0);
829 void cortex_m3_enable_breakpoints(struct target_s
*target
)
831 breakpoint_t
*breakpoint
= target
->breakpoints
;
833 /* set any pending breakpoints */
836 if (breakpoint
->set
== 0)
837 cortex_m3_set_breakpoint(target
, breakpoint
);
838 breakpoint
= breakpoint
->next
;
842 int cortex_m3_set_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
848 /* get pointers to arch-specific information */
849 armv7m_common_t
*armv7m
= target
->arch_info
;
850 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
852 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
856 LOG_WARNING("breakpoint already set");
860 if (cortex_m3
->auto_bp_type
)
862 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
865 if (breakpoint
->type
== BKPT_HARD
)
867 while(comparator_list
[fp_num
].used
&& (fp_num
< cortex_m3
->fp_num_code
))
869 if (fp_num
>= cortex_m3
->fp_num_code
)
871 LOG_DEBUG("ERROR Can not find free FP Comparator");
872 LOG_WARNING("ERROR Can not find free FP Comparator");
875 breakpoint
->set
= fp_num
+ 1;
876 hilo
= (breakpoint
->address
& 0x2) ? FPCR_REPLACE_BKPT_HIGH
: FPCR_REPLACE_BKPT_LOW
;
877 comparator_list
[fp_num
].used
= 1;
878 comparator_list
[fp_num
].fpcr_value
= (breakpoint
->address
& 0x1FFFFFFC) | hilo
| 1;
879 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
880 LOG_DEBUG("fpc_num %i fpcr_value 0x%x", fp_num
, comparator_list
[fp_num
].fpcr_value
);
881 if (!cortex_m3
->fpb_enabled
)
883 LOG_DEBUG("FPB wasn't enabled, do it now");
884 target_write_u32(target
, FP_CTRL
, 3);
887 else if (breakpoint
->type
== BKPT_SOFT
)
890 buf_set_u32(code
, 0, 32, ARMV7M_T_BKPT(0x11));
891 if((retval
= target
->type
->read_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
895 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, breakpoint
->length
, 1, code
)) != ERROR_OK
)
899 breakpoint
->set
= 0x11; /* Any nice value but 0 */
905 int cortex_m3_unset_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
908 /* get pointers to arch-specific information */
909 armv7m_common_t
*armv7m
= target
->arch_info
;
910 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
911 cortex_m3_fp_comparator_t
* comparator_list
= cortex_m3
->fp_comparator_list
;
913 if (!breakpoint
->set
)
915 LOG_WARNING("breakpoint not set");
919 if (breakpoint
->type
== BKPT_HARD
)
921 int fp_num
= breakpoint
->set
- 1;
922 if ((fp_num
< 0) || (fp_num
>= cortex_m3
->fp_num_code
))
924 LOG_DEBUG("Invalid FP Comparator number in breakpoint");
927 comparator_list
[fp_num
].used
= 0;
928 comparator_list
[fp_num
].fpcr_value
= 0;
929 target_write_u32(target
, comparator_list
[fp_num
].fpcr_address
, comparator_list
[fp_num
].fpcr_value
);
933 /* restore original instruction (kept in target endianness) */
934 if (breakpoint
->length
== 4)
936 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 4, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
943 if((retval
= target
->type
->write_memory(target
, breakpoint
->address
& 0xFFFFFFFE, 2, 1, breakpoint
->orig_instr
)) != ERROR_OK
)
954 int cortex_m3_add_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
956 /* get pointers to arch-specific information */
957 armv7m_common_t
*armv7m
= target
->arch_info
;
958 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
960 if (cortex_m3
->auto_bp_type
)
962 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
963 #ifdef ARMV7_GDB_HACKS
964 if (breakpoint
->length
!= 2) {
965 /* XXX Hack: Replace all breakpoints with length != 2 with
966 * a hardware breakpoint. */
967 breakpoint
->type
= BKPT_HARD
;
968 breakpoint
->length
= 2;
973 if ((breakpoint
->type
== BKPT_HARD
) && (breakpoint
->address
>= 0x20000000))
975 LOG_INFO("flash patch comparator requested outside code memory region");
976 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
979 if ((breakpoint
->type
== BKPT_SOFT
) && (breakpoint
->address
< 0x20000000))
981 LOG_INFO("soft breakpoint requested in code (flash) memory region");
982 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
985 if ((breakpoint
->type
== BKPT_HARD
) && (cortex_m3
->fp_code_available
< 1))
987 LOG_INFO("no flash patch comparator unit available for hardware breakpoint");
988 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
991 if ((breakpoint
->length
!= 2))
993 LOG_INFO("only breakpoints of two bytes length supported");
994 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
997 if (breakpoint
->type
== BKPT_HARD
)
998 cortex_m3
->fp_code_available
--;
999 cortex_m3_set_breakpoint(target
, breakpoint
);
1004 int cortex_m3_remove_breakpoint(struct target_s
*target
, breakpoint_t
*breakpoint
)
1006 /* get pointers to arch-specific information */
1007 armv7m_common_t
*armv7m
= target
->arch_info
;
1008 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1010 if (target
->state
!= TARGET_HALTED
)
1012 LOG_WARNING("target not halted");
1013 return ERROR_TARGET_NOT_HALTED
;
1016 if (cortex_m3
->auto_bp_type
)
1018 breakpoint
->type
= (breakpoint
->address
< 0x20000000) ? BKPT_HARD
: BKPT_SOFT
;
1021 if (breakpoint
->set
)
1023 cortex_m3_unset_breakpoint(target
, breakpoint
);
1026 if (breakpoint
->type
== BKPT_HARD
)
1027 cortex_m3
->fp_code_available
++;
1032 int cortex_m3_set_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1037 /* get pointers to arch-specific information */
1038 armv7m_common_t
*armv7m
= target
->arch_info
;
1039 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1040 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1042 if (watchpoint
->set
)
1044 LOG_WARNING("watchpoint already set");
1048 if (watchpoint
->mask
== 0xffffffffu
)
1050 while(comparator_list
[dwt_num
].used
&& (dwt_num
< cortex_m3
->dwt_num_comp
))
1052 if (dwt_num
>= cortex_m3
->dwt_num_comp
)
1054 LOG_DEBUG("ERROR Can not find free DWT Comparator");
1055 LOG_WARNING("ERROR Can not find free DWT Comparator");
1058 watchpoint
->set
= dwt_num
+ 1;
1060 temp
= watchpoint
->length
;
1066 comparator_list
[dwt_num
].used
= 1;
1067 comparator_list
[dwt_num
].comp
= watchpoint
->address
;
1068 comparator_list
[dwt_num
].mask
= mask
;
1069 comparator_list
[dwt_num
].function
= watchpoint
->rw
+ 5;
1070 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
, comparator_list
[dwt_num
].comp
);
1071 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x4, comparator_list
[dwt_num
].mask
);
1072 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1073 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
);
1077 LOG_WARNING("Cannot watch data values"); /* Move this test to add_watchpoint */
1085 int cortex_m3_unset_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1087 /* get pointers to arch-specific information */
1088 armv7m_common_t
*armv7m
= target
->arch_info
;
1089 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1090 cortex_m3_dwt_comparator_t
* comparator_list
= cortex_m3
->dwt_comparator_list
;
1093 if (!watchpoint
->set
)
1095 LOG_WARNING("watchpoint not set");
1099 dwt_num
= watchpoint
->set
- 1;
1101 if ((dwt_num
< 0) || (dwt_num
>= cortex_m3
->dwt_num_comp
))
1103 LOG_DEBUG("Invalid DWT Comparator number in watchpoint");
1106 comparator_list
[dwt_num
].used
= 0;
1107 comparator_list
[dwt_num
].function
= 0;
1108 target_write_u32(target
, comparator_list
[dwt_num
].dwt_comparator_address
|0x8, comparator_list
[dwt_num
].function
);
1110 watchpoint
->set
= 0;
1115 int cortex_m3_add_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1117 /* get pointers to arch-specific information */
1118 armv7m_common_t
*armv7m
= target
->arch_info
;
1119 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1121 if (target
->state
!= TARGET_HALTED
)
1123 LOG_WARNING("target not halted");
1124 return ERROR_TARGET_NOT_HALTED
;
1127 if (cortex_m3
->dwt_comp_available
< 1)
1129 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1132 if ((watchpoint
->length
!= 1) && (watchpoint
->length
!= 2) && (watchpoint
->length
!= 4))
1134 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
1137 cortex_m3
->dwt_comp_available
--;
1142 int cortex_m3_remove_watchpoint(struct target_s
*target
, watchpoint_t
*watchpoint
)
1144 /* get pointers to arch-specific information */
1145 armv7m_common_t
*armv7m
= target
->arch_info
;
1146 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1148 if (target
->state
!= TARGET_HALTED
)
1150 LOG_WARNING("target not halted");
1151 return ERROR_TARGET_NOT_HALTED
;
1154 if (watchpoint
->set
)
1156 cortex_m3_unset_watchpoint(target
, watchpoint
);
1159 cortex_m3
->dwt_comp_available
++;
1164 void cortex_m3_enable_watchpoints(struct target_s
*target
)
1166 watchpoint_t
*watchpoint
= target
->watchpoints
;
1168 /* set any pending watchpoints */
1171 if (watchpoint
->set
== 0)
1172 cortex_m3_set_watchpoint(target
, watchpoint
);
1173 watchpoint
= watchpoint
->next
;
1177 int cortex_m3_load_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32
* value
)
1180 /* get pointers to arch-specific information */
1181 armv7m_common_t
*armv7m
= target
->arch_info
;
1182 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1183 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1185 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1187 /* read a normal core register */
1188 retval
= ahbap_read_coreregister_u32(swjdp
, value
, num
);
1190 if (retval
!= ERROR_OK
)
1192 LOG_ERROR("JTAG failure %i",retval
);
1193 return ERROR_JTAG_DEVICE_ERROR
;
1195 LOG_DEBUG("load from core reg %i value 0x%x",num
,*value
);
1197 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1199 /* read other registers */
1200 ahbap_read_coreregister_u32(swjdp
, value
, 20);
1205 *value
= buf_get_u32((u8
*)value
, 0, 8);
1209 *value
= buf_get_u32((u8
*)value
, 8, 8);
1213 *value
= buf_get_u32((u8
*)value
, 16, 8);
1217 *value
= buf_get_u32((u8
*)value
, 24, 8);
1221 LOG_DEBUG("load from special reg %i value 0x%x", num
, *value
);
1225 return ERROR_INVALID_ARGUMENTS
;
1231 int cortex_m3_store_core_reg_u32(struct target_s
*target
, enum armv7m_regtype type
, u32 num
, u32 value
)
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
;
1241 #ifdef ARMV7_GDB_HACKS
1242 /* If the LR register is being modified, make sure it will put us
1243 * in "thumb" mode, or an INVSTATE exception will occur. This is a
1244 * hack to deal with the fact that gdb will sometimes "forge"
1245 * return addresses, and doesn't set the LSB correctly (i.e., when
1246 * printing expressions containing function calls, it sets LR=0.) */
1252 if ((type
== ARMV7M_REGISTER_CORE_GP
) && (num
<= ARMV7M_PSP
))
1254 retval
= ahbap_write_coreregister_u32(swjdp
, value
, num
);
1255 if (retval
!= ERROR_OK
)
1257 LOG_ERROR("JTAG failure %i", retval
);
1258 armv7m
->core_cache
->reg_list
[num
].dirty
= armv7m
->core_cache
->reg_list
[num
].valid
;
1259 return ERROR_JTAG_DEVICE_ERROR
;
1261 LOG_DEBUG("write core reg %i value 0x%x", num
, value
);
1263 else if (type
== ARMV7M_REGISTER_CORE_SP
) /* Special purpose core register */
1265 /* write other registers */
1267 ahbap_read_coreregister_u32(swjdp
, ®
, 20);
1272 buf_set_u32((u8
*)®
, 0, 8, value
);
1276 buf_set_u32((u8
*)®
, 8, 8, value
);
1280 buf_set_u32((u8
*)®
, 16, 8, value
);
1284 buf_set_u32((u8
*)®
, 24, 8, value
);
1288 ahbap_write_coreregister_u32(swjdp
, reg
, 20);
1290 LOG_DEBUG("write special reg %i value 0x%x ", num
, value
);
1294 return ERROR_INVALID_ARGUMENTS
;
1300 int cortex_m3_read_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1302 /* get pointers to arch-specific information */
1303 armv7m_common_t
*armv7m
= target
->arch_info
;
1304 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1305 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1308 /* sanitize arguments */
1309 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1310 return ERROR_INVALID_ARGUMENTS
;
1312 /* cortex_m3 handles unaligned memory access */
1317 retval
= ahbap_read_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1320 retval
= ahbap_read_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1323 retval
= ahbap_read_buf_u8(swjdp
, buffer
, count
, address
);
1326 LOG_ERROR("BUG: we shouldn't get here");
1333 int cortex_m3_write_memory(struct target_s
*target
, u32 address
, u32 size
, u32 count
, u8
*buffer
)
1335 /* get pointers to arch-specific information */
1336 armv7m_common_t
*armv7m
= target
->arch_info
;
1337 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1338 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1341 /* sanitize arguments */
1342 if (((size
!= 4) && (size
!= 2) && (size
!= 1)) || (count
== 0) || !(buffer
))
1343 return ERROR_INVALID_ARGUMENTS
;
1348 retval
= ahbap_write_buf_u32(swjdp
, buffer
, 4 * count
, address
);
1351 retval
= ahbap_write_buf_u16(swjdp
, buffer
, 2 * count
, address
);
1354 retval
= ahbap_write_buf_u8(swjdp
, buffer
, count
, address
);
1357 LOG_ERROR("BUG: we shouldn't get here");
1364 int cortex_m3_bulk_write_memory(target_t
*target
, u32 address
, u32 count
, u8
*buffer
)
1366 return cortex_m3_write_memory(target
, address
, 4, count
, buffer
);
1369 void cortex_m3_build_reg_cache(target_t
*target
)
1371 armv7m_build_reg_cache(target
);
1374 int cortex_m3_init_target(struct command_context_s
*cmd_ctx
, struct target_s
*target
)
1376 cortex_m3_build_reg_cache(target
);
1380 int cortex_m3_examine(struct target_s
*target
)
1383 u32 cpuid
, fpcr
, dwtcr
, ictr
;
1386 /* get pointers to arch-specific information */
1387 armv7m_common_t
*armv7m
= target
->arch_info
;
1388 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1389 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1391 if ((retval
= ahbap_debugport_init(swjdp
)) != ERROR_OK
)
1394 if (!target
->type
->examined
)
1396 target
->type
->examined
= 1;
1398 /* Read from Device Identification Registers */
1399 if ((retval
= target_read_u32(target
, CPUID
, &cpuid
)) != ERROR_OK
)
1402 if (((cpuid
>> 4) & 0xc3f) == 0xc23)
1403 LOG_DEBUG("CORTEX-M3 processor detected");
1404 LOG_DEBUG("cpuid: 0x%8.8x", cpuid
);
1406 target_read_u32(target
, NVIC_ICTR
, &ictr
);
1407 cortex_m3
->intlinesnum
= (ictr
& 0x1F) + 1;
1408 cortex_m3
->intsetenable
= calloc(cortex_m3
->intlinesnum
, 4);
1409 for (i
= 0; i
< cortex_m3
->intlinesnum
; i
++)
1411 target_read_u32(target
, NVIC_ISE0
+ 4 * i
, cortex_m3
->intsetenable
+ i
);
1412 LOG_DEBUG("interrupt enable[%i] = 0x%8.8x", i
, cortex_m3
->intsetenable
[i
]);
1416 target_read_u32(target
, FP_CTRL
, &fpcr
);
1417 cortex_m3
->auto_bp_type
= 1;
1418 cortex_m3
->fp_num_code
= ((fpcr
>> 8) & 0x70) | ((fpcr
>> 4) & 0xF); /* bits [14:12] and [7:4] */
1419 cortex_m3
->fp_num_lit
= (fpcr
>> 8) & 0xF;
1420 cortex_m3
->fp_code_available
= cortex_m3
->fp_num_code
;
1421 cortex_m3
->fp_comparator_list
= calloc(cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
, sizeof(cortex_m3_fp_comparator_t
));
1422 cortex_m3
->fpb_enabled
= fpcr
& 1;
1423 for (i
= 0; i
< cortex_m3
->fp_num_code
+ cortex_m3
->fp_num_lit
; i
++)
1425 cortex_m3
->fp_comparator_list
[i
].type
= (i
< cortex_m3
->fp_num_code
) ? FPCR_CODE
: FPCR_LITERAL
;
1426 cortex_m3
->fp_comparator_list
[i
].fpcr_address
= FP_COMP0
+ 4 * i
;
1428 LOG_DEBUG("FPB fpcr 0x%x, numcode %i, numlit %i", fpcr
, cortex_m3
->fp_num_code
, cortex_m3
->fp_num_lit
);
1431 target_read_u32(target
, DWT_CTRL
, &dwtcr
);
1432 cortex_m3
->dwt_num_comp
= (dwtcr
>> 28) & 0xF;
1433 cortex_m3
->dwt_comp_available
= cortex_m3
->dwt_num_comp
;
1434 cortex_m3
->dwt_comparator_list
= calloc(cortex_m3
->dwt_num_comp
, sizeof(cortex_m3_dwt_comparator_t
));
1435 for (i
= 0; i
< cortex_m3
->dwt_num_comp
; i
++)
1437 cortex_m3
->dwt_comparator_list
[i
].dwt_comparator_address
= DWT_COMP0
+ 0x10 * i
;
1444 int cortex_m3_quit(void)
1450 int cortex_m3_dcc_read(swjdp_common_t
*swjdp
, u8
*value
, u8
*ctrl
)
1454 ahbap_read_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1456 *value
= (u8
)(dcrdr
>> 8);
1458 LOG_DEBUG("data 0x%x ctrl 0x%x", *value
, *ctrl
);
1460 /* write ack back to software dcc register
1461 * signify we have read data */
1462 if (dcrdr
& (1 << 0))
1465 ahbap_write_buf_u16( swjdp
, (u8
*)&dcrdr
, 1, DCB_DCRDR
);
1471 int cortex_m3_target_request_data(target_t
*target
, u32 size
, u8
*buffer
)
1473 armv7m_common_t
*armv7m
= target
->arch_info
;
1474 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1475 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1480 for (i
= 0; i
< (size
* 4); i
++)
1482 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1489 int cortex_m3_handle_target_request(void *priv
)
1491 target_t
*target
= priv
;
1492 if (!target
->type
->examined
)
1494 armv7m_common_t
*armv7m
= target
->arch_info
;
1495 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1496 swjdp_common_t
*swjdp
= &cortex_m3
->swjdp_info
;
1498 if (!target
->dbg_msg_enabled
)
1501 if (target
->state
== TARGET_RUNNING
)
1506 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1508 /* check if we have data */
1509 if (ctrl
& (1 << 0))
1513 /* we assume target is quick enough */
1515 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1516 request
|= (data
<< 8);
1517 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1518 request
|= (data
<< 16);
1519 cortex_m3_dcc_read(swjdp
, &data
, &ctrl
);
1520 request
|= (data
<< 24);
1521 target_request(target
, request
);
1528 int cortex_m3_init_arch_info(target_t
*target
, cortex_m3_common_t
*cortex_m3
, jtag_tap_t
*tap
)
1530 armv7m_common_t
*armv7m
;
1531 armv7m
= &cortex_m3
->armv7m
;
1533 /* prepare JTAG information for the new target */
1534 cortex_m3
->jtag_info
.tap
= tap
;
1535 cortex_m3
->jtag_info
.scann_size
= 4;
1537 cortex_m3
->swjdp_info
.dp_select_value
= -1;
1538 cortex_m3
->swjdp_info
.ap_csw_value
= -1;
1539 cortex_m3
->swjdp_info
.ap_tar_value
= -1;
1540 cortex_m3
->swjdp_info
.jtag_info
= &cortex_m3
->jtag_info
;
1542 /* initialize arch-specific breakpoint handling */
1544 cortex_m3
->common_magic
= CORTEX_M3_COMMON_MAGIC
;
1545 cortex_m3
->arch_info
= NULL
;
1547 /* register arch-specific functions */
1548 armv7m
->examine_debug_reason
= cortex_m3_examine_debug_reason
;
1550 armv7m
->pre_debug_entry
= NULL
;
1551 armv7m
->post_debug_entry
= NULL
;
1553 armv7m
->pre_restore_context
= NULL
;
1554 armv7m
->post_restore_context
= NULL
;
1556 armv7m_init_arch_info(target
, armv7m
);
1557 armv7m
->arch_info
= cortex_m3
;
1558 armv7m
->load_core_reg_u32
= cortex_m3_load_core_reg_u32
;
1559 armv7m
->store_core_reg_u32
= cortex_m3_store_core_reg_u32
;
1561 target_register_timer_callback(cortex_m3_handle_target_request
, 1, 1, target
);
1566 int cortex_m3_target_create(struct target_s
*target
, Jim_Interp
*interp
)
1568 cortex_m3_common_t
*cortex_m3
= calloc(1,sizeof(cortex_m3_common_t
));
1570 cortex_m3_init_arch_info(target
, cortex_m3
, target
->tap
);
1575 int cortex_m3_register_commands(struct command_context_s
*cmd_ctx
)
1578 command_t
*cortex_m3_cmd
;
1580 retval
= armv7m_register_commands(cmd_ctx
);
1582 cortex_m3_cmd
= register_command(cmd_ctx
, NULL
, "cortex_m3", NULL
, COMMAND_ANY
, "cortex_m3 specific commands");
1583 register_command(cmd_ctx
, cortex_m3_cmd
, "maskisr", handle_cortex_m3_mask_interrupts_command
, COMMAND_EXEC
, "mask cortex_m3 interrupts ['on'|'off']");
1588 int handle_cortex_m3_mask_interrupts_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1590 target_t
*target
= get_current_target(cmd_ctx
);
1591 armv7m_common_t
*armv7m
= target
->arch_info
;
1592 cortex_m3_common_t
*cortex_m3
= armv7m
->arch_info
;
1594 if (target
->state
!= TARGET_HALTED
)
1596 command_print(cmd_ctx
, "target must be stopped for \"%s\" command", cmd
);
1602 if (!strcmp(args
[0], "on"))
1604 cortex_m3_write_debug_halt_mask(target
, C_HALT
|C_MASKINTS
, 0);
1606 else if (!strcmp(args
[0], "off"))
1608 cortex_m3_write_debug_halt_mask(target
, C_HALT
, C_MASKINTS
);
1612 command_print(cmd_ctx
, "usage: cortex_m3 maskisr ['on'|'off']");
1616 command_print(cmd_ctx
, "cortex_m3 interrupt mask %s",
1617 (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)