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
;
285 static int stm32_stlink_init_target(struct command_context
*cmd_ctx
,
286 struct target
*target
)
288 LOG_DEBUG("%s", __func__
);
290 armv7m_build_reg_cache(target
);
295 static int stm32_stlink_target_create(struct target
*target
,
298 LOG_DEBUG("%s", __func__
);
300 struct cortex_m3_common
*cortex_m3
= calloc(1, sizeof(struct cortex_m3_common
));
303 return ERROR_COMMAND_SYNTAX_ERROR
;
305 stm32_stlink_init_arch_info(target
, cortex_m3
, target
->tap
);
310 static int stm32_stlink_load_context(struct target
*target
)
312 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
313 int num_regs
= armv7m
->core_cache
->num_regs
;
315 for (int i
= 0; i
< num_regs
; i
++) {
316 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
317 armv7m
->read_core_reg(target
, i
);
323 static int stlink_debug_entry(struct target
*target
)
325 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
326 struct arm
*arm
= &armv7m
->arm
;
331 retval
= armv7m
->examine_debug_reason(target
);
332 if (retval
!= ERROR_OK
)
335 stm32_stlink_load_context(target
);
337 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
338 xPSR
= buf_get_u32(r
->value
, 0, 32);
340 /* Are we in an exception handler */
342 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
343 armv7m
->exception_number
= (xPSR
& 0x1FF);
345 arm
->core_mode
= ARM_MODE_HANDLER
;
346 arm
->map
= armv7m_msp_reg_map
;
348 unsigned control
= buf_get_u32(armv7m
->core_cache
349 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
351 /* is this thread privileged? */
352 armv7m
->core_mode
= control
& 1;
353 arm
->core_mode
= armv7m
->core_mode
354 ? ARM_MODE_USER_THREAD
357 /* which stack is it using? */
359 arm
->map
= armv7m_psp_reg_map
;
361 arm
->map
= armv7m_msp_reg_map
;
363 armv7m
->exception_number
= 0;
366 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32
", target->state: %s",
367 armv7m_mode_strings
[armv7m
->core_mode
],
368 *(uint32_t *)(arm
->pc
->value
),
369 target_state_name(target
));
374 static int stm32_stlink_poll(struct target
*target
)
376 enum target_state state
;
377 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
378 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
380 state
= stlink_if
->layout
->api
->state(stlink_if
->fd
);
382 if (state
== TARGET_UNKNOWN
) {
383 LOG_ERROR("jtag status contains invalid mode value - communication failure");
384 return ERROR_TARGET_FAILURE
;
387 if (target
->state
== state
)
390 if (state
== TARGET_HALTED
) {
391 target
->state
= state
;
393 int retval
= stlink_debug_entry(target
);
394 if (retval
!= ERROR_OK
)
397 if (arm_semihosting(target
, &retval
) != 0)
400 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
401 LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
407 static int stm32_stlink_assert_reset(struct target
*target
)
410 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
411 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
412 bool use_srst_fallback
= true;
414 LOG_DEBUG("%s", __func__
);
416 enum reset_types jtag_reset_config
= jtag_get_reset_config();
418 stlink_if
->layout
->api
->write_debug_reg(stlink_if
->fd
, DCB_DHCSR
, DBGKEY
|C_DEBUGEN
);
419 stlink_if
->layout
->api
->write_debug_reg(stlink_if
->fd
, DCB_DEMCR
, VC_CORERESET
);
421 if (jtag_reset_config
& RESET_HAS_SRST
) {
422 jtag_add_reset(0, 1);
423 res
= stlink_if
->layout
->api
->assert_srst(stlink_if
->fd
, 0);
424 if (res
== ERROR_COMMAND_NOTFOUND
)
425 LOG_ERROR("Hardware srst not supported, falling back to software reset");
426 else if (res
== ERROR_OK
) {
427 /* hardware srst supported */
428 use_srst_fallback
= false;
432 if (use_srst_fallback
) {
433 /* stlink v1 api does support hardware srst, so we use a software reset fallback */
434 stlink_if
->layout
->api
->write_debug_reg(stlink_if
->fd
, NVIC_AIRCR
, AIRCR_VECTKEY
| AIRCR_SYSRESETREQ
);
437 res
= stlink_if
->layout
->api
->reset(stlink_if
->fd
);
442 /* registers are now invalid */
443 register_cache_invalidate(armv7m
->core_cache
);
445 if (target
->reset_halt
) {
446 target
->state
= TARGET_RESET
;
447 target
->debug_reason
= DBG_REASON_DBGRQ
;
449 target
->state
= TARGET_HALTED
;
455 static int stm32_stlink_deassert_reset(struct target
*target
)
458 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
460 enum reset_types jtag_reset_config
= jtag_get_reset_config();
462 LOG_DEBUG("%s", __func__
);
464 if (jtag_reset_config
& RESET_HAS_SRST
)
465 stlink_if
->layout
->api
->assert_srst(stlink_if
->fd
, 1);
467 /* virtual deassert reset, we need it for the internal
470 jtag_add_reset(0, 0);
472 if (!target
->reset_halt
) {
473 res
= target_resume(target
, 1, 0, 0, 0);
482 static int stm32_stlink_soft_reset_halt(struct target
*target
)
484 LOG_DEBUG("%s", __func__
);
488 static int stm32_stlink_halt(struct target
*target
)
491 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
493 LOG_DEBUG("%s", __func__
);
495 if (target
->state
== TARGET_HALTED
) {
496 LOG_DEBUG("target was already halted");
500 if (target
->state
== TARGET_UNKNOWN
)
501 LOG_WARNING("target was in unknown state when halt was requested");
503 res
= stlink_if
->layout
->api
->halt(stlink_if
->fd
);
508 target
->debug_reason
= DBG_REASON_DBGRQ
;
513 static int stm32_stlink_resume(struct target
*target
, int current
,
514 uint32_t address
, int handle_breakpoints
,
518 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
519 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
521 struct breakpoint
*breakpoint
= NULL
;
524 LOG_DEBUG("%s %d 0x%08x %d %d", __func__
, current
, address
,
525 handle_breakpoints
, debug_execution
);
527 if (target
->state
!= TARGET_HALTED
) {
528 LOG_WARNING("target not halted");
529 return ERROR_TARGET_NOT_HALTED
;
534 buf_set_u32(pc
->value
, 0, 32, address
);
539 if (!breakpoint_find(target
, buf_get_u32(pc
->value
, 0, 32))
540 && !debug_execution
) {
541 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
544 resume_pc
= buf_get_u32(pc
->value
, 0, 32);
546 armv7m_restore_context(target
);
548 /* registers are now invalid */
549 register_cache_invalidate(armv7m
->core_cache
);
551 /* the front-end may request us not to handle breakpoints */
552 if (handle_breakpoints
) {
553 /* Single step past breakpoint at current address */
554 breakpoint
= breakpoint_find(target
, resume_pc
);
556 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
558 breakpoint
->unique_id
);
559 cortex_m3_unset_breakpoint(target
, breakpoint
);
561 res
= stlink_if
->layout
->api
->step(stlink_if
->fd
);
566 cortex_m3_set_breakpoint(target
, breakpoint
);
570 res
= stlink_if
->layout
->api
->run(stlink_if
->fd
);
575 target
->state
= TARGET_RUNNING
;
577 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
582 static int stm32_stlink_step(struct target
*target
, int current
,
583 uint32_t address
, int handle_breakpoints
)
586 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
587 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
588 struct breakpoint
*breakpoint
= NULL
;
589 struct reg
*pc
= armv7m
->arm
.pc
;
590 bool bkpt_inst_found
= false;
592 LOG_DEBUG("%s", __func__
);
594 if (target
->state
!= TARGET_HALTED
) {
595 LOG_WARNING("target not halted");
596 return ERROR_TARGET_NOT_HALTED
;
600 buf_set_u32(pc
->value
, 0, 32, address
);
605 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
607 /* the front-end may request us not to handle breakpoints */
608 if (handle_breakpoints
) {
609 breakpoint
= breakpoint_find(target
, pc_value
);
611 cortex_m3_unset_breakpoint(target
, breakpoint
);
614 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
616 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
618 armv7m_restore_context(target
);
620 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
622 res
= stlink_if
->layout
->api
->step(stlink_if
->fd
);
627 /* registers are now invalid */
628 register_cache_invalidate(armv7m
->core_cache
);
631 cortex_m3_set_breakpoint(target
, breakpoint
);
633 stlink_debug_entry(target
);
634 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
636 LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
641 static int stm32_stlink_read_memory(struct target
*target
, uint32_t address
,
642 uint32_t size
, uint32_t count
,
646 uint32_t buffer_threshold
= 128;
647 uint32_t addr_increment
= 4;
649 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
651 if (!count
|| !buffer
)
652 return ERROR_COMMAND_SYNTAX_ERROR
;
654 LOG_DEBUG("%s 0x%08x %d %d", __func__
, address
, size
, count
);
656 /* prepare byte count, buffer threshold
657 * and address increment for none 32bit access
661 buffer_threshold
= 64;
666 if (count
> buffer_threshold
)
667 c
= buffer_threshold
;
672 res
= stlink_if
->layout
->api
->read_mem8(stlink_if
->fd
,
675 res
= stlink_if
->layout
->api
->read_mem32(stlink_if
->fd
,
681 address
+= (c
* addr_increment
);
682 buffer
+= (c
* addr_increment
);
689 static int stm32_stlink_write_memory(struct target
*target
, uint32_t address
,
690 uint32_t size
, uint32_t count
,
691 const uint8_t *buffer
)
694 uint32_t buffer_threshold
= 128;
695 uint32_t addr_increment
= 4;
697 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
699 if (!count
|| !buffer
)
700 return ERROR_COMMAND_SYNTAX_ERROR
;
702 LOG_DEBUG("%s 0x%08x %d %d", __func__
, address
, size
, count
);
704 /* prepare byte count, buffer threshold
705 * and address increment for none 32bit access
709 buffer_threshold
= 64;
714 if (count
> buffer_threshold
)
715 c
= buffer_threshold
;
720 res
= stlink_if
->layout
->api
->write_mem8(stlink_if
->fd
,
723 res
= stlink_if
->layout
->api
->write_mem32(stlink_if
->fd
,
729 address
+= (c
* addr_increment
);
730 buffer
+= (c
* addr_increment
);
737 static int stm32_stlink_bulk_write_memory(struct target
*target
,
738 uint32_t address
, uint32_t count
,
739 const uint8_t *buffer
)
741 return stm32_stlink_write_memory(target
, address
, 4, count
, buffer
);
744 struct target_type stm32_stlink_target
= {
745 .name
= "stm32_stlink",
747 .init_target
= stm32_stlink_init_target
,
748 .target_create
= stm32_stlink_target_create
,
749 .examine
= cortex_m3_examine
,
751 .poll
= stm32_stlink_poll
,
752 .arch_state
= armv7m_arch_state
,
754 .assert_reset
= stm32_stlink_assert_reset
,
755 .deassert_reset
= stm32_stlink_deassert_reset
,
756 .soft_reset_halt
= stm32_stlink_soft_reset_halt
,
758 .halt
= stm32_stlink_halt
,
759 .resume
= stm32_stlink_resume
,
760 .step
= stm32_stlink_step
,
762 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
764 .read_memory
= stm32_stlink_read_memory
,
765 .write_memory
= stm32_stlink_write_memory
,
766 .bulk_write_memory
= stm32_stlink_bulk_write_memory
,
767 .checksum_memory
= armv7m_checksum_memory
,
768 .blank_check_memory
= armv7m_blank_check_memory
,
770 .run_algorithm
= armv7m_run_algorithm
,
771 .start_algorithm
= armv7m_start_algorithm
,
772 .wait_algorithm
= armv7m_wait_algorithm
,
774 .add_breakpoint
= cortex_m3_add_breakpoint
,
775 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
776 .add_watchpoint
= cortex_m3_add_watchpoint
,
777 .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)