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 static inline struct stlink_interface_s
*target_to_stlink(struct target
*target
)
43 return target
->tap
->priv
;
46 static int stm32_stlink_load_core_reg_u32(struct target
*target
,
47 enum armv7m_regtype type
,
48 uint32_t num
, uint32_t *value
)
51 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
53 LOG_DEBUG("%s", __func__
);
55 /* NOTE: we "know" here that the register identifiers used
56 * in the v7m header match the Cortex-M3 Debug Core Register
57 * Selector values for R0..R15, xPSR, MSP, and PSP.
61 /* read a normal core register */
62 retval
= stlink_if
->layout
->api
->read_reg(stlink_if
->fd
, num
, value
);
64 if (retval
!= ERROR_OK
) {
65 LOG_ERROR("JTAG failure %i", retval
);
66 return ERROR_JTAG_DEVICE_ERROR
;
68 LOG_DEBUG("load from core reg %i value 0x%" PRIx32
"",
74 case ARMV7M_FAULTMASK
:
76 /* Cortex-M3 packages these four registers as bitfields
77 * in one Debug Core register. So say r0 and r2 docs;
78 * it was removed from r1 docs, but still works.
80 retval
= stlink_if
->layout
->api
->read_reg(stlink_if
->fd
, 20, value
);
84 *value
= buf_get_u32((uint8_t *) value
, 0, 1);
88 *value
= buf_get_u32((uint8_t *) value
, 8, 8);
91 case ARMV7M_FAULTMASK
:
92 *value
= buf_get_u32((uint8_t *) value
, 16, 1);
96 *value
= buf_get_u32((uint8_t *) value
, 24, 2);
100 LOG_DEBUG("load from special reg %i value 0x%" PRIx32
"",
105 return ERROR_COMMAND_SYNTAX_ERROR
;
111 static int stm32_stlink_store_core_reg_u32(struct target
*target
,
112 enum armv7m_regtype type
,
113 uint32_t num
, uint32_t value
)
117 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
118 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
120 LOG_DEBUG("%s", __func__
);
122 #ifdef ARMV7_GDB_HACKS
123 /* If the LR register is being modified, make sure it will put us
124 * in "thumb" mode, or an INVSTATE exception will occur. This is a
125 * hack to deal with the fact that gdb will sometimes "forge"
126 * return addresses, and doesn't set the LSB correctly (i.e., when
127 * printing expressions containing function calls, it sets LR = 0.)
128 * Valid exception return codes have bit 0 set too.
130 if (num
== ARMV7M_R14
)
134 /* NOTE: we "know" here that the register identifiers used
135 * in the v7m header match the Cortex-M3 Debug Core Register
136 * Selector values for R0..R15, xPSR, MSP, and PSP.
140 retval
= stlink_if
->layout
->api
->write_reg(stlink_if
->fd
, num
, value
);
142 if (retval
!= ERROR_OK
) {
145 LOG_ERROR("JTAG failure");
146 r
= armv7m
->core_cache
->reg_list
+ num
;
148 return ERROR_JTAG_DEVICE_ERROR
;
150 LOG_DEBUG("write core reg %i value 0x%" PRIx32
"", (int)num
, value
);
155 case ARMV7M_FAULTMASK
:
157 /* Cortex-M3 packages these four registers as bitfields
158 * in one Debug Core register. So say r0 and r2 docs;
159 * it was removed from r1 docs, but still works.
162 stlink_if
->layout
->api
->read_reg(stlink_if
->fd
, 20, ®
);
166 buf_set_u32((uint8_t *) ®
, 0, 1, value
);
170 buf_set_u32((uint8_t *) ®
, 8, 8, value
);
173 case ARMV7M_FAULTMASK
:
174 buf_set_u32((uint8_t *) ®
, 16, 1, value
);
178 buf_set_u32((uint8_t *) ®
, 24, 2, value
);
182 stlink_if
->layout
->api
->write_reg(stlink_if
->fd
, 20, reg
);
184 LOG_DEBUG("write special reg %i value 0x%" PRIx32
" ", (int)num
, value
);
188 return ERROR_COMMAND_SYNTAX_ERROR
;
194 static int stm32_stlink_examine_debug_reason(struct target
*target
)
196 if ((target
->debug_reason
!= DBG_REASON_DBGRQ
)
197 && (target
->debug_reason
!= DBG_REASON_SINGLESTEP
)) {
198 target
->debug_reason
= DBG_REASON_BREAKPOINT
;
204 static int stm32_stlink_init_arch_info(struct target
*target
,
205 struct cortex_m3_common
*cortex_m3
,
206 struct jtag_tap
*tap
)
208 struct armv7m_common
*armv7m
;
210 LOG_DEBUG("%s", __func__
);
212 armv7m
= &cortex_m3
->armv7m
;
213 armv7m_init_arch_info(target
, armv7m
);
215 armv7m
->load_core_reg_u32
= stm32_stlink_load_core_reg_u32
;
216 armv7m
->store_core_reg_u32
= stm32_stlink_store_core_reg_u32
;
218 armv7m
->examine_debug_reason
= stm32_stlink_examine_debug_reason
;
223 static int stm32_stlink_init_target(struct command_context
*cmd_ctx
,
224 struct target
*target
)
226 LOG_DEBUG("%s", __func__
);
228 armv7m_build_reg_cache(target
);
233 static int stm32_stlink_target_create(struct target
*target
,
236 LOG_DEBUG("%s", __func__
);
238 struct cortex_m3_common
*cortex_m3
= calloc(1, sizeof(struct cortex_m3_common
));
241 return ERROR_COMMAND_SYNTAX_ERROR
;
243 stm32_stlink_init_arch_info(target
, cortex_m3
, target
->tap
);
248 static int stm32_stlink_load_context(struct target
*target
)
250 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
251 int num_regs
= armv7m
->core_cache
->num_regs
;
253 for (int i
= 0; i
< num_regs
; i
++) {
254 if (!armv7m
->core_cache
->reg_list
[i
].valid
)
255 armv7m
->read_core_reg(target
, i
);
261 static int stlink_debug_entry(struct target
*target
)
263 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
264 struct arm
*arm
= &armv7m
->arm
;
269 retval
= armv7m
->examine_debug_reason(target
);
270 if (retval
!= ERROR_OK
)
273 stm32_stlink_load_context(target
);
275 r
= armv7m
->core_cache
->reg_list
+ ARMV7M_xPSR
;
276 xPSR
= buf_get_u32(r
->value
, 0, 32);
278 /* Are we in an exception handler */
280 armv7m
->core_mode
= ARMV7M_MODE_HANDLER
;
281 armv7m
->exception_number
= (xPSR
& 0x1FF);
283 arm
->core_mode
= ARM_MODE_HANDLER
;
284 arm
->map
= armv7m_msp_reg_map
;
286 unsigned control
= buf_get_u32(armv7m
->core_cache
287 ->reg_list
[ARMV7M_CONTROL
].value
, 0, 2);
289 /* is this thread privileged? */
290 armv7m
->core_mode
= control
& 1;
291 arm
->core_mode
= armv7m
->core_mode
292 ? ARM_MODE_USER_THREAD
295 /* which stack is it using? */
297 arm
->map
= armv7m_psp_reg_map
;
299 arm
->map
= armv7m_msp_reg_map
;
301 armv7m
->exception_number
= 0;
304 LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32
", target->state: %s",
305 armv7m_mode_strings
[armv7m
->core_mode
],
306 *(uint32_t *)(arm
->pc
->value
),
307 target_state_name(target
));
312 static int stm32_stlink_poll(struct target
*target
)
314 enum target_state state
;
315 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
316 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
318 state
= stlink_if
->layout
->api
->state(stlink_if
->fd
);
320 if (state
== TARGET_UNKNOWN
) {
321 LOG_ERROR("jtag status contains invalid mode value - communication failure");
322 return ERROR_TARGET_FAILURE
;
325 if (target
->state
== state
)
328 if (state
== TARGET_HALTED
) {
329 target
->state
= state
;
331 int retval
= stlink_debug_entry(target
);
332 if (retval
!= ERROR_OK
)
335 if (arm_semihosting(target
, &retval
) != 0)
338 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
339 LOG_DEBUG("halted: PC: 0x%x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
345 static int stm32_stlink_assert_reset(struct target
*target
)
348 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
349 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
351 LOG_DEBUG("%s", __func__
);
353 res
= stlink_if
->layout
->api
->reset(stlink_if
->fd
);
358 /* virtual assert reset, we need it for the internal
361 jtag_add_reset(1, 1);
363 /* registers are now invalid */
364 register_cache_invalidate(armv7m
->core_cache
);
366 if (target
->reset_halt
) {
367 target
->state
= TARGET_RESET
;
368 target
->debug_reason
= DBG_REASON_DBGRQ
;
370 target
->state
= TARGET_HALTED
;
376 static int stm32_stlink_deassert_reset(struct target
*target
)
380 LOG_DEBUG("%s", __func__
);
382 /* virtual deassert reset, we need it for the internal
385 jtag_add_reset(0, 0);
387 if (!target
->reset_halt
) {
388 res
= target_resume(target
, 1, 0, 0, 0);
397 static int stm32_stlink_soft_reset_halt(struct target
*target
)
399 LOG_DEBUG("%s", __func__
);
403 static int stm32_stlink_halt(struct target
*target
)
406 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
408 LOG_DEBUG("%s", __func__
);
410 if (target
->state
== TARGET_HALTED
) {
411 LOG_DEBUG("target was already halted");
415 if (target
->state
== TARGET_UNKNOWN
)
416 LOG_WARNING("target was in unknown state when halt was requested");
418 res
= stlink_if
->layout
->api
->halt(stlink_if
->fd
);
423 target
->debug_reason
= DBG_REASON_DBGRQ
;
428 static int stm32_stlink_resume(struct target
*target
, int current
,
429 uint32_t address
, int handle_breakpoints
,
433 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
434 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
436 struct breakpoint
*breakpoint
= NULL
;
439 LOG_DEBUG("%s %d %x %d %d", __func__
, current
, address
,
440 handle_breakpoints
, debug_execution
);
442 if (target
->state
!= TARGET_HALTED
) {
443 LOG_WARNING("target not halted");
444 return ERROR_TARGET_NOT_HALTED
;
449 buf_set_u32(pc
->value
, 0, 32, address
);
454 if (!breakpoint_find(target
, buf_get_u32(pc
->value
, 0, 32))
455 && !debug_execution
) {
456 armv7m_maybe_skip_bkpt_inst(target
, NULL
);
459 resume_pc
= buf_get_u32(pc
->value
, 0, 32);
461 armv7m_restore_context(target
);
463 /* registers are now invalid */
464 register_cache_invalidate(armv7m
->core_cache
);
466 /* the front-end may request us not to handle breakpoints */
467 if (handle_breakpoints
) {
468 /* Single step past breakpoint at current address */
469 breakpoint
= breakpoint_find(target
, resume_pc
);
471 LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32
" (ID: %d)",
473 breakpoint
->unique_id
);
474 cortex_m3_unset_breakpoint(target
, breakpoint
);
476 res
= stlink_if
->layout
->api
->step(stlink_if
->fd
);
481 cortex_m3_set_breakpoint(target
, breakpoint
);
485 res
= stlink_if
->layout
->api
->run(stlink_if
->fd
);
490 target
->state
= TARGET_RUNNING
;
492 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
497 static int stm32_stlink_step(struct target
*target
, int current
,
498 uint32_t address
, int handle_breakpoints
)
501 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
502 struct armv7m_common
*armv7m
= target_to_armv7m(target
);
503 struct breakpoint
*breakpoint
= NULL
;
504 struct reg
*pc
= armv7m
->arm
.pc
;
505 bool bkpt_inst_found
= false;
507 LOG_DEBUG("%s", __func__
);
509 if (target
->state
!= TARGET_HALTED
) {
510 LOG_WARNING("target not halted");
511 return ERROR_TARGET_NOT_HALTED
;
515 buf_set_u32(pc
->value
, 0, 32, address
);
520 uint32_t pc_value
= buf_get_u32(pc
->value
, 0, 32);
522 /* the front-end may request us not to handle breakpoints */
523 if (handle_breakpoints
) {
524 breakpoint
= breakpoint_find(target
, pc_value
);
526 cortex_m3_unset_breakpoint(target
, breakpoint
);
529 armv7m_maybe_skip_bkpt_inst(target
, &bkpt_inst_found
);
531 target
->debug_reason
= DBG_REASON_SINGLESTEP
;
533 armv7m_restore_context(target
);
535 target_call_event_callbacks(target
, TARGET_EVENT_RESUMED
);
537 res
= stlink_if
->layout
->api
->step(stlink_if
->fd
);
542 /* registers are now invalid */
543 register_cache_invalidate(armv7m
->core_cache
);
546 cortex_m3_set_breakpoint(target
, breakpoint
);
548 stlink_debug_entry(target
);
549 target_call_event_callbacks(target
, TARGET_EVENT_HALTED
);
551 LOG_INFO("halted: PC: 0x%x", buf_get_u32(armv7m
->arm
.pc
->value
, 0, 32));
556 static int stm32_stlink_read_memory(struct target
*target
, uint32_t address
,
557 uint32_t size
, uint32_t count
,
561 uint32_t buffer_threshold
= 128;
562 uint32_t addr_increment
= 4;
563 uint8_t *dst
= buffer
;
565 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
567 if (!count
|| !buffer
)
568 return ERROR_COMMAND_SYNTAX_ERROR
;
570 LOG_DEBUG("%s %x %d %d", __func__
, address
, size
, count
);
572 /* prepare byte count, buffer threshold
573 * and address increment for none 32bit access
577 buffer_threshold
= 64;
582 if (count
> buffer_threshold
)
583 c
= buffer_threshold
;
588 res
= stlink_if
->layout
->api
->read_mem8(stlink_if
->fd
,
591 res
= stlink_if
->layout
->api
->read_mem32(stlink_if
->fd
,
592 address
, c
, (uint32_t *)dst
);
597 address
+= (c
* addr_increment
);
598 dst
+= (c
* addr_increment
);
605 static int stm32_stlink_write_memory(struct target
*target
, uint32_t address
,
606 uint32_t size
, uint32_t count
,
607 const uint8_t *buffer
)
610 uint32_t buffer_threshold
= 128;
611 uint32_t addr_increment
= 4;
612 const uint8_t *dst
= buffer
;
614 struct stlink_interface_s
*stlink_if
= target_to_stlink(target
);
616 if (!count
|| !buffer
)
617 return ERROR_COMMAND_SYNTAX_ERROR
;
619 LOG_DEBUG("%s %x %d %d", __func__
, address
, size
, count
);
621 /* prepare byte count, buffer threshold
622 * and address increment for none 32bit access
626 buffer_threshold
= 64;
631 if (count
> buffer_threshold
)
632 c
= buffer_threshold
;
637 res
= stlink_if
->layout
->api
->write_mem8(stlink_if
->fd
,
640 res
= stlink_if
->layout
->api
->write_mem32(stlink_if
->fd
,
641 address
, c
, (uint32_t *)dst
);
646 address
+= (c
* addr_increment
);
647 dst
+= (c
* addr_increment
);
654 static int stm32_stlink_bulk_write_memory(struct target
*target
,
655 uint32_t address
, uint32_t count
,
656 const uint8_t *buffer
)
658 return stm32_stlink_write_memory(target
, address
, 4, count
, buffer
);
661 struct target_type stm32_stlink_target
= {
662 .name
= "stm32_stlink",
664 .init_target
= stm32_stlink_init_target
,
665 .target_create
= stm32_stlink_target_create
,
666 .examine
= cortex_m3_examine
,
668 .poll
= stm32_stlink_poll
,
669 .arch_state
= armv7m_arch_state
,
671 .assert_reset
= stm32_stlink_assert_reset
,
672 .deassert_reset
= stm32_stlink_deassert_reset
,
673 .soft_reset_halt
= stm32_stlink_soft_reset_halt
,
675 .halt
= stm32_stlink_halt
,
676 .resume
= stm32_stlink_resume
,
677 .step
= stm32_stlink_step
,
679 .get_gdb_reg_list
= armv7m_get_gdb_reg_list
,
681 .read_memory
= stm32_stlink_read_memory
,
682 .write_memory
= stm32_stlink_write_memory
,
683 .bulk_write_memory
= stm32_stlink_bulk_write_memory
,
684 .checksum_memory
= armv7m_checksum_memory
,
685 .blank_check_memory
= armv7m_blank_check_memory
,
687 .run_algorithm
= armv7m_run_algorithm
,
688 .start_algorithm
= armv7m_start_algorithm
,
689 .wait_algorithm
= armv7m_wait_algorithm
,
691 .add_breakpoint
= cortex_m3_add_breakpoint
,
692 .remove_breakpoint
= cortex_m3_remove_breakpoint
,
693 .add_watchpoint
= cortex_m3_add_watchpoint
,
694 .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)