X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fstm32_stlink.c;h=4044654cfe37c49b2d940d831889dd4234cde4b9;hp=64e83f534e6346d03b55befbef071fecc72e03d0;hb=d469c686d9c4aaef7dc0ff8376142b8fdd6d1dbd;hpb=e2073cc18ae1380a7f6d0f61f49aab42de01b732;ds=sidebyside diff --git a/src/target/stm32_stlink.c b/src/target/stm32_stlink.c index 64e83f534e..4044654cfe 100644 --- a/src/target/stm32_stlink.c +++ b/src/target/stm32_stlink.c @@ -38,6 +38,9 @@ #include "cortex_m.h" #include "arm_semihosting.h" +#define ARMV7M_SCS_DCRSR 0xe000edf4 +#define ARMV7M_SCS_DCRDR 0xe000edf8 + static inline struct stlink_interface_s *target_to_stlink(struct target *target) { return target->tap->priv; @@ -65,8 +68,38 @@ static int stm32_stlink_load_core_reg_u32(struct target *target, LOG_ERROR("JTAG failure %i", retval); return ERROR_JTAG_DEVICE_ERROR; } - LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", - (int)num, *value); + LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); + break; + + case ARMV7M_FPSID: + case ARMV7M_FPEXC: + *value = 0; + break; + + case ARMV7M_FPSCR: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33); + if (retval != ERROR_OK) + return retval; + retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); + break; + + case ARMV7M_S0 ... ARMV7M_S31: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, num-ARMV7M_S0+64); + if (retval != ERROR_OK) + return retval; + retval = target_read_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("load from core reg %i value 0x%" PRIx32 "", (int)num, *value); + break; + + case ARMV7M_D0 ... ARMV7M_D15: + value = 0; break; case ARMV7M_PRIMASK: @@ -150,6 +183,35 @@ static int stm32_stlink_store_core_reg_u32(struct target *target, LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); break; + case ARMV7M_FPSID: + case ARMV7M_FPEXC: + break; + + case ARMV7M_FPSCR: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, 33 | (1<<16)); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); + break; + + case ARMV7M_S0 ... ARMV7M_S31: + /* Floating-point Status and Registers */ + retval = target_write_u32(target, ARMV7M_SCS_DCRDR, value); + if (retval != ERROR_OK) + return retval; + retval = target_write_u32(target, ARMV7M_SCS_DCRSR, (num-ARMV7M_S0+64) | (1<<16)); + if (retval != ERROR_OK) + return retval; + LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", (int)num, value); + break; + + case ARMV7M_D0 ... ARMV7M_D15: + break; + case ARMV7M_PRIMASK: case ARMV7M_BASEPRI: case ARMV7M_FAULTMASK: @@ -301,7 +363,7 @@ static int stlink_debug_entry(struct target *target) armv7m->exception_number = 0; } - LOG_DEBUG("entered debug state in core mode: %s at PC 0x%" PRIx32 ", target->state: %s", + LOG_DEBUG("entered debug state in core mode: %s at PC 0x%08" PRIx32 ", target->state: %s", armv7m_mode_strings[armv7m->core_mode], *(uint32_t *)(arm->pc->value), target_state_name(target)); @@ -336,7 +398,7 @@ static int stm32_stlink_poll(struct target *target) return retval; target_call_event_callbacks(target, TARGET_EVENT_HALTED); - LOG_DEBUG("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); + LOG_DEBUG("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); } return ERROR_OK; @@ -344,22 +406,49 @@ static int stm32_stlink_poll(struct target *target) static int stm32_stlink_assert_reset(struct target *target) { - int res; + int res = ERROR_OK; struct stlink_interface_s *stlink_if = target_to_stlink(target); struct armv7m_common *armv7m = target_to_armv7m(target); + bool use_srst_fallback = true; LOG_DEBUG("%s", __func__); + enum reset_types jtag_reset_config = jtag_get_reset_config(); + + bool srst_asserted = false; + + if (jtag_reset_config & RESET_SRST_NO_GATING) { + jtag_add_reset(0, 1); + res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0); + srst_asserted = true; + } + + stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DHCSR, DBGKEY|C_DEBUGEN); + stlink_if->layout->api->write_debug_reg(stlink_if->fd, DCB_DEMCR, VC_CORERESET); + + if (jtag_reset_config & RESET_HAS_SRST) { + if (!srst_asserted) { + jtag_add_reset(0, 1); + res = stlink_if->layout->api->assert_srst(stlink_if->fd, 0); + } + if (res == ERROR_COMMAND_NOTFOUND) + LOG_ERROR("Hardware srst not supported, falling back to software reset"); + else if (res == ERROR_OK) { + /* hardware srst supported */ + use_srst_fallback = false; + } + } + + if (use_srst_fallback) { + /* stlink v1 api does support hardware srst, so we use a software reset fallback */ + stlink_if->layout->api->write_debug_reg(stlink_if->fd, NVIC_AIRCR, AIRCR_VECTKEY | AIRCR_SYSRESETREQ); + } + res = stlink_if->layout->api->reset(stlink_if->fd); if (res != ERROR_OK) return res; - /* virtual assert reset, we need it for the internal - * jtag state machine - */ - jtag_add_reset(1, 1); - /* registers are now invalid */ register_cache_invalidate(armv7m->core_cache); @@ -376,9 +465,15 @@ static int stm32_stlink_assert_reset(struct target *target) static int stm32_stlink_deassert_reset(struct target *target) { int res; + struct stlink_interface_s *stlink_if = target_to_stlink(target); + + enum reset_types jtag_reset_config = jtag_get_reset_config(); LOG_DEBUG("%s", __func__); + if (jtag_reset_config & RESET_HAS_SRST) + stlink_if->layout->api->assert_srst(stlink_if->fd, 1); + /* virtual deassert reset, we need it for the internal * jtag state machine */ @@ -436,7 +531,7 @@ static int stm32_stlink_resume(struct target *target, int current, struct breakpoint *breakpoint = NULL; struct reg *pc; - LOG_DEBUG("%s %d %x %d %d", __func__, current, address, + LOG_DEBUG("%s %d 0x%08x %d %d", __func__, current, address, handle_breakpoints, debug_execution); if (target->state != TARGET_HALTED) { @@ -548,7 +643,7 @@ static int stm32_stlink_step(struct target *target, int current, stlink_debug_entry(target); target_call_event_callbacks(target, TARGET_EVENT_HALTED); - LOG_INFO("halted: PC: 0x%x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); + LOG_INFO("halted: PC: 0x%08x", buf_get_u32(armv7m->arm.pc->value, 0, 32)); return ERROR_OK; } @@ -560,14 +655,13 @@ static int stm32_stlink_read_memory(struct target *target, uint32_t address, int res; uint32_t buffer_threshold = 128; uint32_t addr_increment = 4; - uint8_t *dst = buffer; uint32_t c; struct stlink_interface_s *stlink_if = target_to_stlink(target); if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; - LOG_DEBUG("%s %x %d %d", __func__, address, size, count); + LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count); /* prepare byte count, buffer threshold * and address increment for none 32bit access @@ -586,16 +680,16 @@ static int stm32_stlink_read_memory(struct target *target, uint32_t address, if (size != 4) res = stlink_if->layout->api->read_mem8(stlink_if->fd, - address, c, dst); + address, c, buffer); else res = stlink_if->layout->api->read_mem32(stlink_if->fd, - address, c, (uint32_t *)dst); + address, c, buffer); if (res != ERROR_OK) return res; address += (c * addr_increment); - dst += (c * addr_increment); + buffer += (c * addr_increment); count -= c; } @@ -609,14 +703,13 @@ static int stm32_stlink_write_memory(struct target *target, uint32_t address, int res; uint32_t buffer_threshold = 128; uint32_t addr_increment = 4; - const uint8_t *dst = buffer; uint32_t c; struct stlink_interface_s *stlink_if = target_to_stlink(target); if (!count || !buffer) return ERROR_COMMAND_SYNTAX_ERROR; - LOG_DEBUG("%s %x %d %d", __func__, address, size, count); + LOG_DEBUG("%s 0x%08x %d %d", __func__, address, size, count); /* prepare byte count, buffer threshold * and address increment for none 32bit access @@ -635,16 +728,16 @@ static int stm32_stlink_write_memory(struct target *target, uint32_t address, if (size != 4) res = stlink_if->layout->api->write_mem8(stlink_if->fd, - address, c, dst); + address, c, buffer); else res = stlink_if->layout->api->write_mem32(stlink_if->fd, - address, c, (uint32_t *)dst); + address, c, buffer); if (res != ERROR_OK) return res; address += (c * addr_increment); - dst += (c * addr_increment); + buffer += (c * addr_increment); count -= c; }