1 /***************************************************************************
2 * Copyright (C) 2011 by Mathias Kuester *
3 * Mathias Kuester <kesmtp@freenet.de> *
5 * Copyright (C) 2011 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
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 ***************************************************************************/
28 #include "jtag/jtag.h"
29 #include "jtag/stlink/stlink_transport.h"
30 #include "jtag/stlink/stlink_interface.h"
31 #include "jtag/stlink/stlink_layout.h"
33 #include "algorithm.h"
35 #include "breakpoints.h"
36 #include "target_type.h"
39 #include "arm_semihosting.h"
41 #define ARMV7M_SCS_DCRSR 0xe000edf4
42 #define ARMV7M_SCS_DCRDR 0xe000edf8
44 static inline struct stlink_interface_s
*target_to_stlink(struct target
*target
)
46 return target
->tap
->priv
;
49 static int stm32_stlink_load_core_reg_u32(struct target
*target
,
50 enum armv7m_regtype type
,
51 uint32_t num
, uint32_t *value
)
54 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
56 LOG_DEBUG("%s", __func__
);
58 /* NOTE: we "know" here that the register identifiers used
59 * in the v7m header match the Cortex-M3 Debug Core Register
60 * Selector values for R0..R15, xPSR, MSP, and PSP.
64 /* read a normal core register */
65 retval
= stlink_if
->layout
->api
->read_reg(stlink_if
->fd
, num
, value
);
67 if (retval
!= ERROR_OK
) {
68 LOG_ERROR("JTAG failure %i", retval
);
69 return ERROR_JTAG_DEVICE_ERROR
;
71 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
80 /* Floating-point Status and Registers */
81 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, 33);
82 if (retval
!= ERROR_OK
)
84 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
85 if (retval
!= ERROR_OK
)
87 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
90 case ARMV7M_S0
... ARMV7M_S31
:
91 /* Floating-point Status and Registers */
92 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, num
-ARMV7M_S0
+64);
93 if (retval
!= ERROR_OK
)
95 retval
= target_read_u32(target
, ARMV7M_SCS_DCRDR
, value
);
96 if (retval
!= ERROR_OK
)
98 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"", (int)num
, *value
);
101 case ARMV7M_D0
... ARMV7M_D15
:
107 case ARMV7M_FAULTMASK
:
109 /* Cortex-M3 packages these four registers as bitfields
110 * in one Debug Core register. So say r0 and r2 docs;
111 * it was removed from r1 docs, but still works.
113 retval
= stlink_if
->layout
->api
->read_reg(stlink_if
->fd
, 20, value
);
117 *value
= buf_get_u32((uint8_t *) value
, 0, 1);
121 *value
= buf_get_u32((uint8_t *) value
, 8, 8);
124 case ARMV7M_FAULTMASK
:
125 *value
= buf_get_u32((uint8_t *) value
, 16, 1);
129 *value
= buf_get_u32((uint8_t *) value
, 24, 2);
133 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"",
138 return ERROR_COMMAND_SYNTAX_ERROR
;
144 static int stm32_stlink_store_core_reg_u32(struct target
*target
,
145 enum armv7m_regtype type
,
146 uint32_t num
, uint32_t value
)
150 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
151 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
153 LOG_DEBUG("%s", __func__
);
155 #ifdef ARMV7_GDB_HACKS
156 /* If the LR register is being modified, make sure it will put us
157 * in "thumb" mode, or an INVSTATE exception will occur. This is a
158 * hack to deal with the fact that gdb will sometimes "forge"
159 * return addresses, and doesn't set the LSB correctly (i.e., when
160 * printing expressions containing function calls, it sets LR = 0.)
161 * Valid exception return codes have bit 0 set too.
163 if (num
== ARMV7M_R14
)
167 /* NOTE: we "know" here that the register identifiers used
168 * in the v7m header match the Cortex-M3 Debug Core Register
169 * Selector values for R0..R15, xPSR, MSP, and PSP.
173 retval
= stlink_if
->layout
->api
->write_reg(stlink_if
->fd
, num
, value
);
175 if (retval
!= ERROR_OK
) {
178 LOG_ERROR("JTAG failure");
179 r
= armv7m
->core_cache
->reg_list
+ num
;
181 return ERROR_JTAG_DEVICE_ERROR
;
183 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
191 /* Floating-point Status and Registers */
192 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
193 if (retval
!= ERROR_OK
)
195 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, 33 | (1<<16));
196 if (retval
!= ERROR_OK
)
198 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
201 case ARMV7M_S0
... ARMV7M_S31
:
202 /* Floating-point Status and Registers */
203 retval
= target_write_u32(target
, ARMV7M_SCS_DCRDR
, value
);
204 if (retval
!= ERROR_OK
)
206 retval
= target_write_u32(target
, ARMV7M_SCS_DCRSR
, (num
-ARMV7M_S0
+64) | (1<<16));
207 if (retval
!= ERROR_OK
)
209 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
212 case ARMV7M_D0
... ARMV7M_D15
:
217 case ARMV7M_FAULTMASK
:
219 /* Cortex-M3 packages these four registers as bitfields
220 * in one Debug Core register. So say r0 and r2 docs;
221 * it was removed from r1 docs, but still works.
224 stlink_if
->layout
->api
->read_reg(stlink_if
->fd
, 20, ®
);
228 buf_set_u32((uint8_t *) ®
, 0, 1, value
);
232 buf_set_u32((uint8_t *) ®
, 8, 8, value
);
235 case ARMV7M_FAULTMASK
:
236 buf_set_u32((uint8_t *) ®
, 16, 1, value
);
240 buf_set_u32((uint8_t *) ®
, 24, 2, value
);
244 stlink_if
->layout
->api
->write_reg(stlink_if
->fd
, 20, reg
);
246 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
250 return ERROR_COMMAND_SYNTAX_ERROR
;
256 static int stm32_stlink_examine_debug_reason(struct target
*target
)
258 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
259 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
260 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
266 static int stm32_stlink_init_arch_info(struct target
*target
,
267 struct cortex_m3_common
*cortex_m3
,
268 struct jtag_tap
*tap
)
270 struct armv7m_common
*armv7m
;
272 LOG_DEBUG("%s", __func__
);
274 armv7m
= &cortex_m3
->armv7m
;
275 armv7m_init_arch_info(target
, armv7m
);
277 armv7m
->load_core_reg_u32
= stm32_stlink_load_core_reg_u32
;
278 armv7m
->store_core_reg_u32
= stm32_stlink_store_core_reg_u32
;
280 armv7m
->examine_debug_reason
= stm32_stlink_examine_debug_reason
;
281 armv7m
->stlink
= true;
286 static int stm32_stlink_init_target(struct command_context
*cmd_ctx
,
287 struct target
*target
)
289 LOG_DEBUG("%s", __func__
);
291 armv7m_build_reg_cache(target
);
296 static int stm32_stlink_target_create(struct target
*target
,
299 LOG_DEBUG("%s", __func__
);
301 struct cortex_m3_common
*cortex_m3
= calloc(1, sizeof(struct cortex_m3_common
));
304 return ERROR_COMMAND_SYNTAX_ERROR
;
306 stm32_stlink_init_arch_info(target
, cortex_m3
, target
->tap
);
311 static int stm32_stlink_load_context(struct target
*target
)
313 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
314 int num_regs
= armv7m
->core_cache
->num_regs
;
316 for (int i
= 0; i
< num_regs
; i
++) {
317 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
318 armv7m
->read_core_reg(target
, i
);
324 static int stlink_debug_entry(struct target
*target
)
326 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
327 struct arm
*arm
= &armv7m
->arm
;
332 retval
= armv7m
->examine_debug_reason(target
);
333 if (retval
!= ERROR_OK
)
336 stm32_stlink_load_context(target
);
338 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
339 xPSR
= buf_get_u32(r
->value
, 0, 32);
341 /* Are we in an exception handler */
343 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
344 armv7m
->exception_number
= (xPSR
& 0x1FF);
346 arm
->core_mode
= ARM_MODE_HANDLER
;
347 arm
->map
= armv7m_msp_reg_map
;
349 unsigned control
= buf_get_u32(armv7m
->core_cache
350 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
352 /* is this thread privileged? */
353 armv7m
->core_mode
= control
& 1;
354 arm
->core_mode
= armv7m
->core_mode
355 ? ARM_MODE_USER_THREAD
358 /* which stack is it using? */
360 arm
->map
= armv7m_psp_reg_map
;
362 arm
->map
= armv7m_msp_reg_map
;
364 armv7m
->exception_number
= 0;
367 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32
", target->state: %s",
368 armv7m_mode_strings
[armv7m
->core_mode
],
369 *(uint32_t *)(arm
->pc
->value
),
370 target_state_name(target
));
375 static int stm32_stlink_poll(struct target
*target
)
377 enum target_state state
;
378 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
379 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
381 state
= stlink_if
->layout
->api
->state(stlink_if
->fd
);
383 if (state
== TARGET_UNKNOWN
) {
384 LOG_ERROR("jtag status contains invalid mode value - communication failure");
385 return ERROR_TARGET_FAILURE
;
388 if (target
->state
== state
)
391 if (state
== TARGET_HALTED
) {
392 target
->state
= state
;
394 int retval
= stlink_debug_entry(target
);
395 if (retval
!= ERROR_OK
)
398 if (arm_semihosting(target
, &retval
) != 0)
401 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
402 LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
408 static int stm32_stlink_assert_reset(struct target
*target
)
411 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
412 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
413 bool use_srst_fallback
= true;
415 LOG_DEBUG("%s", __func__
);
417 enum reset_types jtag_reset_config
= jtag_get_reset_config();
419 bool srst_asserted
= false;
421 if (jtag_reset_config
& RESET_SRST_NO_GATING
) {
422 jtag_add_reset(0, 1);
423 res
= stlink_if
->layout
->api
->assert_srst(stlink_if
->fd
, 0);
424 srst_asserted
= true;
427 stlink_if
->layout
->api
->write_debug_reg(stlink_if
->fd
, DCB_DHCSR
, DBGKEY
|C_DEBUGEN
);
428 stlink_if
->layout
->api
->write_debug_reg(stlink_if
->fd
, DCB_DEMCR
, VC_CORERESET
);
430 if (jtag_reset_config
& RESET_HAS_SRST
) {
431 if (!srst_asserted
) {
432 jtag_add_reset(0, 1);
433 res
= stlink_if
->layout
->api
->assert_srst(stlink_if
->fd
, 0);
435 if (res
== ERROR_COMMAND_NOTFOUND
)
436 LOG_ERROR("Hardware srst not supported, falling back to software reset");
437 else if (res
== ERROR_OK
) {
438 /* hardware srst supported */
439 use_srst_fallback
= false;
443 if (use_srst_fallback
) {
444 /* stlink v1 api does support hardware srst, so we use a software reset fallback */
445 stlink_if
->layout
->api
->write_debug_reg(stlink_if
->fd
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
448 res
= stlink_if
->layout
->api
->reset(stlink_if
->fd
);
453 /* registers are now invalid */
454 register_cache_invalidate(armv7m
->core_cache
);
456 if (target
->reset_halt
) {
457 target
->state
= TARGET_RESET
;
458 target
->debug_reason
= DBG_REASON_DBGRQ
;
460 target
->state
= TARGET_HALTED
;
466 static int stm32_stlink_deassert_reset(struct target
*target
)
469 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
471 enum reset_types jtag_reset_config
= jtag_get_reset_config();
473 LOG_DEBUG("%s", __func__
);
475 if (jtag_reset_config
& RESET_HAS_SRST
)
476 stlink_if
->layout
->api
->assert_srst(stlink_if
->fd
, 1);
478 /* virtual deassert reset, we need it for the internal
481 jtag_add_reset(0, 0);
483 if (!target
->reset_halt
) {
484 res
= target_resume(target
, 1, 0, 0, 0);
493 static int stm32_stlink_soft_reset_halt(struct target
*target
)
495 LOG_DEBUG("%s", __func__
);
499 static int stm32_stlink_halt(struct target
*target
)
502 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
504 LOG_DEBUG("%s", __func__
);
506 if (target
->state
== TARGET_HALTED
) {
507 LOG_DEBUG("target was already halted");
511 if (target
->state
== TARGET_UNKNOWN
)
512 LOG_WARNING("target was in unknown state when halt was requested");
514 res
= stlink_if
->layout
->api
->halt(stlink_if
->fd
);
519 target
->debug_reason
= DBG_REASON_DBGRQ
;
524 static int stm32_stlink_resume(struct target
*target
, int current
,
525 uint32_t address
, int handle_breakpoints
,
529 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
530 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
532 struct breakpoint
*breakpoint
= NULL
;
535 LOG_DEBUG("%s %d 0x%08x %d %d", __func__
, current
, address
,
536 handle_breakpoints
, debug_execution
);
538 if (target
->state
!= TARGET_HALTED
) {
539 LOG_WARNING("target not halted");
540 return ERROR_TARGET_NOT_HALTED
;
545 buf_set_u32(pc
->value
, 0, 32, address
);
550 if (!breakpoint_find(target
, buf_get_u32(pc
->value
, 0, 32))
551 && !debug_execution
) {
552 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
555 resume_pc
= buf_get_u32(pc
->value
, 0, 32);
557 armv7m_restore_context(target
);
559 /* registers are now invalid */
560 register_cache_invalidate(armv7m
->core_cache
);
562 /* the front-end may request us not to handle breakpoints */
563 if (handle_breakpoints
) {
564 /* Single step past breakpoint at current address */
565 breakpoint
= breakpoint_find(target
, resume_pc
);
567 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
569 breakpoint
->unique_id
);
570 cortex_m3_unset_breakpoint(target
, breakpoint
);
572 res
= stlink_if
->layout
->api
->step(stlink_if
->fd
);
577 cortex_m3_set_breakpoint(target
, breakpoint
);
581 res
= stlink_if
->layout
->api
->run(stlink_if
->fd
);
586 target
->state
= TARGET_RUNNING
;
588 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
593 static int stm32_stlink_step(struct target
*target
, int current
,
594 uint32_t address
, int handle_breakpoints
)
597 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
598 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
599 struct breakpoint
*breakpoint
= NULL
;
600 struct reg
*pc
= armv7m
->arm
.pc
;
601 bool bkpt_inst_found
= false;
603 LOG_DEBUG("%s", __func__
);
605 if (target
->state
!= TARGET_HALTED
) {
606 LOG_WARNING("target not halted");
607 return ERROR_TARGET_NOT_HALTED
;
611 buf_set_u32(pc
->value
, 0, 32, address
);
616 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
618 /* the front-end may request us not to handle breakpoints */
619 if (handle_breakpoints
) {
620 breakpoint
= breakpoint_find(target
, pc_value
);
622 cortex_m3_unset_breakpoint(target
, breakpoint
);
625 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
627 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
629 armv7m_restore_context(target
);
631 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
633 res
= stlink_if
->layout
->api
->step(stlink_if
->fd
);
638 /* registers are now invalid */
639 register_cache_invalidate(armv7m
->core_cache
);
642 cortex_m3_set_breakpoint(target
, breakpoint
);
644 stlink_debug_entry(target
);
645 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
647 LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
652 static int stm32_stlink_read_memory(struct target
*target
, uint32_t address
,
653 uint32_t size
, uint32_t count
,
657 uint32_t buffer_threshold
= 128;
658 uint32_t addr_increment
= 4;
660 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
662 if (!count
|| !buffer
)
663 return ERROR_COMMAND_SYNTAX_ERROR
;
665 LOG_DEBUG("%s 0x%08x %d %d", __func__
, address
, size
, count
);
667 /* prepare byte count, buffer threshold
668 * and address increment for none 32bit access
672 buffer_threshold
= 64;
677 if (count
> buffer_threshold
)
678 c
= buffer_threshold
;
683 res
= stlink_if
->layout
->api
->read_mem8(stlink_if
->fd
,
686 res
= stlink_if
->layout
->api
->read_mem32(stlink_if
->fd
,
692 address
+= (c
* addr_increment
);
693 buffer
+= (c
* addr_increment
);
700 static int stm32_stlink_write_memory(struct target
*target
, uint32_t address
,
701 uint32_t size
, uint32_t count
,
702 const uint8_t *buffer
)
705 uint32_t buffer_threshold
= 128;
706 uint32_t addr_increment
= 4;
708 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
710 if (!count
|| !buffer
)
711 return ERROR_COMMAND_SYNTAX_ERROR
;
713 LOG_DEBUG("%s 0x%08x %d %d", __func__
, address
, size
, count
);
715 /* prepare byte count, buffer threshold
716 * and address increment for none 32bit access
720 buffer_threshold
= 64;
725 if (count
> buffer_threshold
)
726 c
= buffer_threshold
;
731 res
= stlink_if
->layout
->api
->write_mem8(stlink_if
->fd
,
734 res
= stlink_if
->layout
->api
->write_mem32(stlink_if
->fd
,
740 address
+= (c
* addr_increment
);
741 buffer
+= (c
* addr_increment
);
748 static int stm32_stlink_bulk_write_memory(struct target
*target
,
749 uint32_t address
, uint32_t count
,
750 const uint8_t *buffer
)
752 return stm32_stlink_write_memory(target
, address
, 4, count
, buffer
);
755 struct target_type stm32_stlink_target
= {
756 .name
= "stm32_stlink",
758 .init_target
= stm32_stlink_init_target
,
759 .target_create
= stm32_stlink_target_create
,
760 .examine
= cortex_m3_examine
,
762 .poll
= stm32_stlink_poll
,
763 .arch_state
= armv7m_arch_state
,
765 .assert_reset
= stm32_stlink_assert_reset
,
766 .deassert_reset
= stm32_stlink_deassert_reset
,
767 .soft_reset_halt
= stm32_stlink_soft_reset_halt
,
769 .halt
= stm32_stlink_halt
,
770 .resume
= stm32_stlink_resume
,
771 .step
= stm32_stlink_step
,
773 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
775 .read_memory
= stm32_stlink_read_memory
,
776 .write_memory
= stm32_stlink_write_memory
,
777 .bulk_write_memory
= stm32_stlink_bulk_write_memory
,
778 .checksum_memory
= armv7m_checksum_memory
,
779 .blank_check_memory
= armv7m_blank_check_memory
,
781 .run_algorithm
= armv7m_run_algorithm
,
782 .start_algorithm
= armv7m_start_algorithm
,
783 .wait_algorithm
= armv7m_wait_algorithm
,
785 .add_breakpoint
= cortex_m3_add_breakpoint
,
786 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
787 .add_watchpoint
= cortex_m3_add_watchpoint
,
788 .remove_watchpoint
= cortex_m3_remove_watchpoint
,
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)