From 6bf4fd3598d3126e0bc5518187ad2f3c6e5d48d3 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 19 Aug 2019 16:26:21 +0200 Subject: [PATCH 1/6] pc-stlinkv2: CPU register read and write must be done with the AP set. FIXME: Writing CPU registers on M4 of STM32H745 seems not to work. --- src/platforms/pc-stlinkv2/stlinkv2.c | 23 +++++++++++++---------- src/platforms/pc-stlinkv2/stlinkv2.h | 6 +++--- src/target/cortexm.c | 18 +++++++++--------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index 4474f73..4d8d699 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -1197,37 +1197,40 @@ void stlink_writemem32(ADIv5_AP_t *ap, uint32_t addr, size_t len, write_retry(cmd, 16, (void*)buffer, len); } -void stlink_regs_read(void *data) +void stlink_regs_read(ADIv5_AP_t *ap, void *data) { - uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READALLREGS}; + uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READALLREGS, + ap->apsel}; uint8_t res[88]; - DEBUG_STLINK("Read all core registers\n"); + DEBUG_STLINK("AP %d: Read all core registers\n", ap->apsel); send_recv(cmd, 16, res, 88); stlink_usb_error_check(res, true); memcpy(data, res + 4, 84); } -uint32_t stlink_reg_read(int num) +uint32_t stlink_reg_read(ADIv5_AP_t *ap, int num) { - uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READREG, num}; + uint8_t cmd[16] = {STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_READREG, num, + ap->apsel}; uint8_t res[8]; send_recv(cmd, 16, res, 8); stlink_usb_error_check(res, true); uint32_t ret = res[0] | res[1] << 8 | res[2] << 16 | res[3] << 24; - DEBUG_STLINK("Read reg %02" PRId32 " val 0x%08" PRIx32 "\n", num, ret); + DEBUG_STLINK("AP %d: Read reg %02" PRId32 " val 0x%08" PRIx32 "\n", + ap->apsel, num, ret); return ret; } -void stlink_reg_write(int num, uint32_t val) +void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val) { uint8_t cmd[16] = { STLINK_DEBUG_COMMAND, STLINK_DEBUG_APIV2_WRITEREG, num, val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, - (val >> 24) & 0xff - }; + (val >> 24) & 0xff, ap->apsel}; uint8_t res[2]; send_recv(cmd, 16, res, 2); - DEBUG_STLINK("Write reg %02" PRId32 " val 0x%08" PRIx32 "\n", num, val); + DEBUG_STLINK("AP %d: Write reg %02" PRId32 " val 0x%08" PRIx32 "\n", + ap->apsel, num, val); stlink_usb_error_check(res, true); } diff --git a/src/platforms/pc-stlinkv2/stlinkv2.h b/src/platforms/pc-stlinkv2/stlinkv2.h index 1653741..04b8fd7 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.h +++ b/src/platforms/pc-stlinkv2/stlinkv2.h @@ -44,9 +44,9 @@ void stlink_dp_abort(ADIv5_DP_t *dp, uint32_t abort); int stlink_open_ap(uint8_t ap); void stlink_close_ap(uint8_t ap); int stlink_usb_get_rw_status(void); -void stlink_regs_read(void *data); -uint32_t stlink_reg_read(int idx); -void stlink_reg_write(int num, uint32_t val); +void stlink_regs_read(ADIv5_AP_t *ap, void *data); +uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx); +void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val); extern int debug_level; # define DEBUG_STLINK if (debug_level > 0) printf # define DEBUG_USB if (debug_level > 1) printf diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 7def372..882022d 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -450,16 +450,16 @@ enum { DB_DHCSR, DB_DCRSR, DB_DCRDR, DB_DEMCR }; static void cortexm_regs_read(target *t, void *data) { uint32_t *regs = data; + ADIv5_AP_t *ap = cortexm_ap(t); #if defined(STLINKV2) - extern void stlink_regs_read(void *data); - extern uint32_t stlink_reg_read(int idx); - stlink_regs_read(data); + extern void stlink_regs_read(ADIv5_AP_t *ap, void *data); + extern uint32_t stlink_reg_read(ADIv5_AP_t *ap, int idx); + stlink_regs_read(ap, data); regs += sizeof(regnum_cortex_m); if (t->target_options & TOPT_FLAVOUR_V7MF) for(size_t t = 0; t < sizeof(regnum_cortex_mf) / 4; t++) - *regs++ = stlink_reg_read(regnum_cortex_mf[t]); + *regs++ = stlink_reg_read(ap, regnum_cortex_mf[t]); #else - ADIv5_AP_t *ap = cortexm_ap(t); unsigned i; /* FIXME: Describe what's really going on here */ @@ -491,19 +491,19 @@ static void cortexm_regs_read(target *t, void *data) static void cortexm_regs_write(target *t, const void *data) { const uint32_t *regs = data; + ADIv5_AP_t *ap = cortexm_ap(t); #if defined(STLINKV2) - extern void stlink_reg_write(int num, uint32_t val); + extern void stlink_reg_write(ADIv5_AP_t *ap, int num, uint32_t val); for(size_t z = 1; z < sizeof(regnum_cortex_m) / 4; z++) { - stlink_reg_write(regnum_cortex_m[z], *regs); + stlink_reg_write(ap, regnum_cortex_m[z], *regs); regs++; if (t->target_options & TOPT_FLAVOUR_V7MF) for(size_t z = 0; z < sizeof(regnum_cortex_mf) / 4; z++) { - stlink_reg_write(regnum_cortex_mf[z], *regs); + stlink_reg_write(ap, regnum_cortex_mf[z], *regs); regs++; } } #else - ADIv5_AP_t *ap = cortexm_ap(t); unsigned i; /* FIXME: Describe what's really going on here */ From fa27649f874827f2b564a66b3b2f729bc71a1868 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 20 Aug 2019 12:28:36 +0200 Subject: [PATCH 2/6] Remove debug_bmp command on PC hosted platforms. --- src/command.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/command.c b/src/command.c index ff7bce9..f5d385c 100644 --- a/src/command.c +++ b/src/command.c @@ -59,7 +59,7 @@ static bool cmd_target_power(target *t, int argc, const char **argv); #ifdef PLATFORM_HAS_TRACESWO static bool cmd_traceswo(target *t, int argc, const char **argv); #endif -#ifdef PLATFORM_HAS_DEBUG +#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED) static bool cmd_debug_bmp(target *t, int argc, const char **argv); #endif @@ -79,7 +79,7 @@ const struct command_s cmd_list[] = { #ifdef PLATFORM_HAS_TRACESWO {"traceswo", (cmd_handler)cmd_traceswo, "Start trace capture [(baudrate) for async swo]" }, #endif -#ifdef PLATFORM_HAS_DEBUG +#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED) {"debug_bmp", (cmd_handler)cmd_debug_bmp, "Output BMP \"debug\" strings to the second vcom: (enable|disable)"}, #endif {NULL, NULL, NULL} @@ -344,7 +344,7 @@ static bool cmd_traceswo(target *t, int argc, const char **argv) } #endif -#ifdef PLATFORM_HAS_DEBUG +#if defined(PLATFORM_HAS_DEBUG) && !defined(PC_HOSTED) static bool cmd_debug_bmp(target *t, int argc, const char **argv) { (void)t; From 5fbb3a44fdabd626bf8b371ec43aa18cf944f2e1 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 20 Aug 2019 17:56:25 +0200 Subject: [PATCH 3/6] PC-STLINKV2/Libftdi: Better version string. --- src/command.c | 5 +++++ src/platforms/libftdi/platform.h | 1 + src/platforms/pc-stlinkv2/platform.h | 1 + 3 files changed, 7 insertions(+) diff --git a/src/command.c b/src/command.c index f5d385c..c0c4e03 100644 --- a/src/command.c +++ b/src/command.c @@ -124,7 +124,12 @@ int command_process(target *t, char *cmd) bool cmd_version(void) { +#if defined PC_HOSTED + gdb_outf("Black Magic Probe, PC-Hosted for " PLATFORM_IDENT + ", Version " FIRMWARE_VERSION "\n"); +#else gdb_outf("Black Magic Probe (Firmware " FIRMWARE_VERSION ") (Hardware Version %d)\n", platform_hwversion()); +#endif gdb_out("Copyright (C) 2015 Black Sphere Technologies Ltd.\n"); gdb_out("License GPLv3+: GNU GPL version 3 or later " "\n\n"); diff --git a/src/platforms/libftdi/platform.h b/src/platforms/libftdi/platform.h index 5452c51..122cdce 100644 --- a/src/platforms/libftdi/platform.h +++ b/src/platforms/libftdi/platform.h @@ -38,6 +38,7 @@ #define PLATFORM_HAS_DEBUG +#define PLATFORM_IDENT "FTDI/MPSSE" #define SET_RUN_STATE(state) #define SET_IDLE_STATE(state) #define SET_ERROR_STATE(state) diff --git a/src/platforms/pc-stlinkv2/platform.h b/src/platforms/pc-stlinkv2/platform.h index 5ecba6b..a100a06 100644 --- a/src/platforms/pc-stlinkv2/platform.h +++ b/src/platforms/pc-stlinkv2/platform.h @@ -35,6 +35,7 @@ #define PLATFORM_HAS_DEBUG +#define PLATFORM_IDENT "StlinkV2/3" #define SET_RUN_STATE(state) #define SET_IDLE_STATE(state) //#define SET_ERROR_STATE(state) From 82be49f05212d36733ab99c6f83ef93a7ff444d1 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 20 Aug 2019 18:45:30 +0200 Subject: [PATCH 4/6] Stlink: Add a README.md, mostly deprecating reflashing Stlinkv2/1. --- src/platforms/stlink/README.md | 47 ++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/platforms/stlink/README.md diff --git a/src/platforms/stlink/README.md b/src/platforms/stlink/README.md new file mode 100644 index 0000000..a22cf08 --- /dev/null +++ b/src/platforms/stlink/README.md @@ -0,0 +1,47 @@ +# Blackmagic for ST -Link Adapters + +For STlinkV3 and StlinkV2/1, as found on all Nucleo and recent Discovery +boards, use the pc-stlinkv2 branch, running on the PC and with original, +recent ST firmware. + +Only if you have a Stlinkv2 with STM32F103C8 versus the STM32F103CB on V2/1 +and you want to rewire and use the UART, consider reflashing the the Stlink +firmware. + +## Versions + +### [Standalone ST-LINKV2 +](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/st-link-v2.html) +Accessible connectors for JTAG/SWD (20-pin) and SWIM. +ST-LINKV2/ISOL). +### ST-LINKV2 clones aka "baite" +JTAG/SWD/SWIM are on a 10-pin connector. CPU SWD pins are accessible on the +board. +### SWIM-only ST-LINK adapters on STM8 Discovery boards +JTAG and target SWIM pins are accessible on connector (footprints). They are handled in the swlink branch. +### SWIM-only ST-LINK adapters on STM8 Nucleo-Stm8 boards +As only a SWIM connector is accessible, they are not usefull as BMP target. +### [SWD only ST-LINK adapter +](https://www.st.com/content/ccc/resource/technical/document/technical_note/group0/30/c8/1d/0f/15/62/46/ef/DM00290229/files/DM00290229.pdf/jcr:content/translations/en.DM00290229.pdf) + SWD, SWO and Reset are accessible on a 6-pin connector row. + Jumper allow to route SWD to on-board target or off-board. + Newer variants have UART TX/RX accessible on a connector + According to on-board target variant, some signals have open (resistor) jumper between debugger and target. + Newer variants have transistor for USB reenumeration + Newer variants may switch onboard target power. + Newer Variants may have level shifters for some signals to onboard target. +#### ST-Link/V1 +CDCACM USART pins are not accessible. MCO output is used for LED. +#### ST-Link/V2 and ST-Link/V2-A +CDCACM USART pins are not accessible. MCO is connected to on board target. +#### ST-Link/V2-1 and ST-Link/V2-B +### [STLINK-V3SET +](https://www.st.com/content/st_com/en/products/development-tools/hardware-development-tools/development-tool-hardware-for-mcus/debug-hardware-for-mcus/debug-hardware-for-stm32-mcus/stlink-v3set.html) + +## BMP version detection and handling +All stlink variants +PC13/14 open -> Standalone ST-LINKV2 or baite, some STM32 Disco w/o accessible +UART RX/TX + +PC13 low -> SWIM internal connection + From 44f471db531350deeacbf0d42fb760e780b29f27 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 20 Aug 2019 22:01:20 +0200 Subject: [PATCH 5/6] pc-stlinkv2: READMEM_8BIT needs to read 2 bytes for 1 byte requested. Fix as seen in openocd. SYSROM_PIDR2 has only 3 bits for the JEP106 identity code field, bits [6:4]. --- src/platforms/pc-stlinkv2/stlinkv2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index 4d8d699..7cc6ddd 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -1095,6 +1095,7 @@ void stlink_readmem(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len) { if (len == 0) return; + size_t read_len = len; uint8_t type; char *CMD; if (src & 1 || len & 1) { @@ -1104,6 +1105,8 @@ void stlink_readmem(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len) DEBUG(" Too large!\n"); return; } + if (len == 1) + read_len ++; /* Fix read length as in openocd*/ } else if (src & 3 || len & 3) { CMD = "READMEM_16BIT"; type = STLINK_DEBUG_APIV2_READMEM_16BIT; @@ -1120,7 +1123,7 @@ void stlink_readmem(ADIv5_AP_t *ap, void *dest, uint32_t src, size_t len) src & 0xff, (src >> 8) & 0xff, (src >> 16) & 0xff, (src >> 24) & 0xff, len & 0xff, len >> 8, ap->apsel}; - int res = read_retry(cmd, 16, dest, len); + int res = read_retry(cmd, 16, dest, read_len); if (res == STLINK_ERROR_OK) { uint8_t *p = (uint8_t*)dest; for (size_t i = 0; i < len ; i++) { From 5d59338de5f396300e46f52c264d6a050b8ae247 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 21 Aug 2019 12:50:29 +0200 Subject: [PATCH 6/6] pc-stlinkv2: Try first to reset device if we read a strange version number. --- src/platforms/pc-stlinkv2/stlinkv2.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/platforms/pc-stlinkv2/stlinkv2.c b/src/platforms/pc-stlinkv2/stlinkv2.c index 7cc6ddd..f3de39e 100644 --- a/src/platforms/pc-stlinkv2/stlinkv2.c +++ b/src/platforms/pc-stlinkv2/stlinkv2.c @@ -800,10 +800,23 @@ void stlink_init(int argc, char **argv) Stlink.req_trans = libusb_alloc_transfer(0); Stlink.rep_trans = libusb_alloc_transfer(0); stlink_version(); - if (Stlink.ver_stlink < 3 && Stlink.ver_jtag < 32) { - DEBUG("Please update Firmware\n"); - goto error_1; - } else if (Stlink.ver_stlink == 3 && Stlink.ver_jtag < 3) { + if ((Stlink.ver_stlink < 3 && Stlink.ver_jtag < 32) || + (Stlink.ver_stlink == 3 && Stlink.ver_jtag < 3)) { + /* Maybe the adapter is in some strange state. Try to reset */ + int result = libusb_reset_device(Stlink.handle); + DEBUG("Trying reset\n"); + if (result == LIBUSB_ERROR_BUSY) { /* Try again */ + platform_delay(50); + result = libusb_reset_device(Stlink.handle); + } + if (result != LIBUSB_SUCCESS) { + DEBUG("libusb_reset_device failed\n"); + goto error_1; + } + stlink_version(); + } + if ((Stlink.ver_stlink < 3 && Stlink.ver_jtag < 32) || + (Stlink.ver_stlink == 3 && Stlink.ver_jtag < 3)) { DEBUG("Please update Firmware\n"); goto error_1; }