From cfbe9f1c9446e6551e0308f7da7dfff34fdb1557 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 8 May 2021 12:00:35 +0200 Subject: [PATCH 01/26] pc/gdb_if.c: More verbosity for Error messages #873 Thanks to "pshri" for dissecting and adding messages, as problems with Hpyer-V and port permissions happened on Win10 --- src/platforms/pc/gdb_if.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/platforms/pc/gdb_if.c b/src/platforms/pc/gdb_if.c index 2657d841..35c12615 100644 --- a/src/platforms/pc/gdb_if.c +++ b/src/platforms/pc/gdb_if.c @@ -51,8 +51,13 @@ static int gdb_if_serv, gdb_if_conn; int gdb_if_init(void) { #if defined(_WIN32) || defined(__CYGWIN__) + int iResult; WSADATA wsaData; - WSAStartup(MAKEWORD(2, 2), &wsaData); + iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); + if (iResult != NO_ERROR) { + DEBUG_WARN("WSAStartup failed with error: %ld\n", iResult); + exit(1); + } #endif struct sockaddr_in addr; int opt; @@ -67,23 +72,47 @@ int gdb_if_init(void) addr.sin_addr.s_addr = htonl(INADDR_ANY); gdb_if_serv = socket(PF_INET, SOCK_STREAM, 0); - if (gdb_if_serv == -1) + if (gdb_if_serv == -1) { + DEBUG_WARN("PF_INET %d\n",gdb_if_serv); continue; + } opt = 1; if (setsockopt(gdb_if_serv, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(opt)) == -1) { +#if defined(_WIN32) || defined(__CYGWIN__) + DEBUG_WARN("error setsockopt SOL_SOCKET : %d error: %d\n", gdb_if_serv, + WSAGetLastError()); +#else + DEBUG_WARN("error setsockopt SOL_SOCKET : %d error: %d\n", gdb_if_serv, + strerror(errno)); +#endif close(gdb_if_serv); continue; } if (setsockopt(gdb_if_serv, IPPROTO_TCP, TCP_NODELAY, (void*)&opt, sizeof(opt)) == -1) { +#if defined(_WIN32) || defined(__CYGWIN__) + DEBUG_WARN("error setsockopt IPPROTO_TCP : %d error: %d\n", gdb_if_serv, + WSAGetLastError()); +#else + DEBUG_WARN("error setsockopt IPPROTO_TCP : %d error: %d\n", gdb_if_serv, + strerror(errno)); +#endif close(gdb_if_serv); continue; } if (bind(gdb_if_serv, (void*)&addr, sizeof(addr)) == -1) { +#if defined(_WIN32) || defined(__CYGWIN__) + DEBUG_WARN("error when binding socket: %d error: %d\n", gdb_if_serv, + WSAGetLastError()); +#else + DEBUG_WARN("error when binding socket: %d error: %d\n", gdb_if_serv, + strerror(errno)); +#endif close(gdb_if_serv); continue; } if (listen(gdb_if_serv, 1) == -1) { + DEBUG_WARN("listen closed %d\n",gdb_if_serv); close(gdb_if_serv); continue; } @@ -100,6 +129,7 @@ unsigned char gdb_if_getchar(void) unsigned char ret; int i = 0; #if defined(_WIN32) || defined(__CYGWIN__) + int iResult; unsigned long opt; #else int flags; @@ -108,7 +138,10 @@ unsigned char gdb_if_getchar(void) if(gdb_if_conn <= 0) { #if defined(_WIN32) || defined(__CYGWIN__) opt = 1; - ioctlsocket(gdb_if_serv, FIONBIO, &opt); + iResult = ioctlsocket(gdb_if_serv, FIONBIO, &opt); + if (iResult != NO_ERROR) { + DEBUG_WARN("ioctlsocket failed with error: %ld\n", iResult); + } #else flags = fcntl(gdb_if_serv, F_GETFL); fcntl(gdb_if_serv, F_SETFL, flags | O_NONBLOCK); From 8e438b9e5f69a88e76da6ef087e77256e7119ec7 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 14 May 2021 18:51:53 +0200 Subject: [PATCH 02/26] Add missing headers and remove double typedef. --- src/command.c | 2 -- src/platforms/hosted/jlink_jtagtap.c | 2 +- src/platforms/pc/serial_unix.c | 1 + 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/command.c b/src/command.c index 3a26a292..12547f9d 100644 --- a/src/command.c +++ b/src/command.c @@ -38,8 +38,6 @@ # include "traceswo.h" #endif -typedef bool (*cmd_handler)(target *t, int argc, const char **argv); - static bool cmd_version(target *t, int argc, char **argv); static bool cmd_help(target *t, int argc, char **argv); diff --git a/src/platforms/hosted/jlink_jtagtap.c b/src/platforms/hosted/jlink_jtagtap.c index 4b20e146..3903fe52 100644 --- a/src/platforms/hosted/jlink_jtagtap.c +++ b/src/platforms/hosted/jlink_jtagtap.c @@ -24,7 +24,7 @@ #include #include #include - +#include #include #include "general.h" diff --git a/src/platforms/pc/serial_unix.c b/src/platforms/pc/serial_unix.c index 96e2da92..c4f4f748 100644 --- a/src/platforms/pc/serial_unix.c +++ b/src/platforms/pc/serial_unix.c @@ -19,6 +19,7 @@ */ #include #include +#include #include #include #include From e4421799baeba883584beba4bde4183b343ce5e3 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 14 May 2021 22:25:39 +0200 Subject: [PATCH 03/26] More header cleanup --- src/platforms/common/cdcacm.c | 1 - src/platforms/hosted/bmp_remote.c | 2 -- src/platforms/hosted/bmp_serial.c | 4 +--- src/platforms/hosted/cmsis_dap.h | 2 +- src/platforms/hosted/dap.c | 1 - src/platforms/hosted/ftdi_bmp.c | 1 - src/platforms/hosted/jlink_jtagtap.c | 5 +---- src/platforms/hosted/jtagtap.c | 0 src/platforms/hosted/libftdi_jtagtap.c | 5 +---- src/platforms/hosted/libftdi_swdptap.c | 4 +--- src/platforms/hosted/remote_jtagtap.c | 4 +--- src/platforms/hosted/swdptap.c | 0 src/platforms/pc/cl_utils.c | 2 -- src/platforms/pc/gdb_if.c | 4 +--- src/platforms/pc/hid.c | 4 +--- src/platforms/pc/serial_unix.c | 7 +++---- src/platforms/pc/serial_win.c | 1 - src/platforms/pc/utils.c | 9 ++++++++- src/remote.c | 1 - src/target/cortexm.c | 1 - src/target/target.c | 2 -- 21 files changed, 19 insertions(+), 41 deletions(-) delete mode 100644 src/platforms/hosted/jtagtap.c delete mode 100644 src/platforms/hosted/swdptap.c diff --git a/src/platforms/common/cdcacm.c b/src/platforms/common/cdcacm.c index b28f1970..b1a91264 100644 --- a/src/platforms/common/cdcacm.c +++ b/src/platforms/common/cdcacm.c @@ -41,7 +41,6 @@ #include #include #include -#include #define DFU_IF_NO 4 diff --git a/src/platforms/hosted/bmp_remote.c b/src/platforms/hosted/bmp_remote.c index b8dc1d2e..1ca68621 100644 --- a/src/platforms/hosted/bmp_remote.c +++ b/src/platforms/hosted/bmp_remote.c @@ -22,7 +22,6 @@ #include "general.h" #include "gdb_if.h" #include "version.h" -#include "platform.h" #include "remote.h" #include "target.h" #include "bmp_remote.h" @@ -33,7 +32,6 @@ #include #include #include -#include #include "adiv5.h" diff --git a/src/platforms/hosted/bmp_serial.c b/src/platforms/hosted/bmp_serial.c index a7baa77c..4f0333cc 100644 --- a/src/platforms/hosted/bmp_serial.c +++ b/src/platforms/hosted/bmp_serial.c @@ -19,11 +19,9 @@ /* Find all known serial connected debuggers */ +#include "general.h" #include #include -#include -#include "general.h" -#include "platform.h" #include "bmp_hosted.h" #include "version.h" diff --git a/src/platforms/hosted/cmsis_dap.h b/src/platforms/hosted/cmsis_dap.h index d23726db..9e8054f2 100644 --- a/src/platforms/hosted/cmsis_dap.h +++ b/src/platforms/hosted/cmsis_dap.h @@ -47,7 +47,7 @@ int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc) {return -1;} int dap_swdptap_init(swd_proc_t *swd_proc) {return -1;} int dap_jtag_dp_init(ADIv5_DP_t *dp) {return -1;} void dap_swd_configure(uint8_t cfg) {}; -## pragma GCC diagnostic pop +# pragma GCC diagnostic pop #endif diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c index 9d93ab7c..5acc03e5 100644 --- a/src/platforms/hosted/dap.c +++ b/src/platforms/hosted/dap.c @@ -32,7 +32,6 @@ /*- Includes ----------------------------------------------------------------*/ #include -#include #include "dap.h" #include "jtag_scan.h" diff --git a/src/platforms/hosted/ftdi_bmp.c b/src/platforms/hosted/ftdi_bmp.c index 77cb369a..53868157 100644 --- a/src/platforms/hosted/ftdi_bmp.c +++ b/src/platforms/hosted/ftdi_bmp.c @@ -20,7 +20,6 @@ */ #include "general.h" #include "gdb_if.h" -#include "platform.h" #include "target.h" #include diff --git a/src/platforms/hosted/jlink_jtagtap.c b/src/platforms/hosted/jlink_jtagtap.c index 3903fe52..17dd3a29 100644 --- a/src/platforms/hosted/jlink_jtagtap.c +++ b/src/platforms/hosted/jlink_jtagtap.c @@ -21,13 +21,10 @@ * */ -#include +#include "general.h" #include -#include -#include #include -#include "general.h" #include "exception.h" #include "jlink.h" diff --git a/src/platforms/hosted/jtagtap.c b/src/platforms/hosted/jtagtap.c deleted file mode 100644 index e69de29b..00000000 diff --git a/src/platforms/hosted/libftdi_jtagtap.c b/src/platforms/hosted/libftdi_jtagtap.c index 905faaf9..9443df53 100644 --- a/src/platforms/hosted/libftdi_jtagtap.c +++ b/src/platforms/hosted/libftdi_jtagtap.c @@ -22,15 +22,12 @@ * */ -#include +#include "general.h" #include -#include #include #include -#include "platform.h" #include "ftdi_bmp.h" -#include "general.h" extern cable_desc_t *active_cable; extern struct ftdi_context *ftdic; diff --git a/src/platforms/hosted/libftdi_swdptap.c b/src/platforms/hosted/libftdi_swdptap.c index 13a981bc..4878437f 100644 --- a/src/platforms/hosted/libftdi_swdptap.c +++ b/src/platforms/hosted/libftdi_swdptap.c @@ -21,12 +21,10 @@ * Speed is sensible. */ -#include +#include "general.h" #include -#include "general.h" #include -#include "platform.h" #include "ftdi_bmp.h" enum swdio_status{ diff --git a/src/platforms/hosted/remote_jtagtap.c b/src/platforms/hosted/remote_jtagtap.c index d98663b5..601a3e90 100644 --- a/src/platforms/hosted/remote_jtagtap.c +++ b/src/platforms/hosted/remote_jtagtap.c @@ -26,13 +26,11 @@ * Should share interface with swdptap.c or at least clean up... */ -#include +#include "general.h" #include -#include #include -#include "general.h" #include "remote.h" #include "jtagtap.h" #include "bmp_remote.h" diff --git a/src/platforms/hosted/swdptap.c b/src/platforms/hosted/swdptap.c deleted file mode 100644 index e69de29b..00000000 diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index b67bd9bd..a70074cf 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -24,12 +24,10 @@ #include "general.h" #include -#include #include #include #include #include "version.h" -#include "target.h" #include "target_internal.h" #include "cortexm.h" #include "command.h" diff --git a/src/platforms/pc/gdb_if.c b/src/platforms/pc/gdb_if.c index 35c12615..2734a7e2 100644 --- a/src/platforms/pc/gdb_if.c +++ b/src/platforms/pc/gdb_if.c @@ -36,13 +36,11 @@ # include #endif -#include +#include "general.h" #include #include -#include #include -#include "general.h" #include "gdb_if.h" static int gdb_if_serv, gdb_if_conn; diff --git a/src/platforms/pc/hid.c b/src/platforms/pc/hid.c index 3d0425c5..75fc3099 100755 --- a/src/platforms/pc/hid.c +++ b/src/platforms/pc/hid.c @@ -61,9 +61,7 @@ extern "C" { } /* extern "C" */ #endif -#include -#include - +#include #include "hidapi.h" diff --git a/src/platforms/pc/serial_unix.c b/src/platforms/pc/serial_unix.c index c4f4f748..08f01134 100644 --- a/src/platforms/pc/serial_unix.c +++ b/src/platforms/pc/serial_unix.c @@ -17,7 +17,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -#include +#include "general.h" #include #include #include @@ -25,9 +25,7 @@ #include #include #include -#include -#include "general.h" #include "remote.h" #include "cl_utils.h" #include "cortexm.h" @@ -61,8 +59,9 @@ static int set_interface_attribs(void) tty.c_cflag |= (CLOCAL | CREAD);// ignore modem controls, // enable reading tty.c_cflag &= ~CSTOPB; +#if defined(CRTSCTS) tty.c_cflag &= ~CRTSCTS; - +#endif if (tcsetattr (fd, TCSANOW, &tty) != 0) { DEBUG_WARN("error %d from tcsetattr", errno); return -1; diff --git a/src/platforms/pc/serial_win.c b/src/platforms/pc/serial_win.c index 57f78067..b08e87ea 100644 --- a/src/platforms/pc/serial_win.c +++ b/src/platforms/pc/serial_win.c @@ -17,7 +17,6 @@ * along with this program. If not, see . */ -#include #include "general.h" #include #include "remote.h" diff --git a/src/platforms/pc/utils.c b/src/platforms/pc/utils.c index b74c8ae3..e5de7148 100644 --- a/src/platforms/pc/utils.c +++ b/src/platforms/pc/utils.c @@ -44,7 +44,14 @@ int vasprintf(char **strp, const char *fmt, va_list ap) void platform_delay(uint32_t ms) { - usleep(ms * 1000); +#if defined(_WIN32) && !defined(__MINGW32__) + Sleep(ms); +#else +# if !defined(usleep) + int usleep(unsigned int); +# endif + usleep(ms); +#endif } uint32_t platform_time_ms(void) diff --git a/src/remote.c b/src/remote.c index 955c2f10..691f1e9e 100644 --- a/src/remote.c +++ b/src/remote.c @@ -24,7 +24,6 @@ #include "gdb_packet.h" #include "jtagtap.h" #include "gdb_if.h" -#include "platform.h" #include "version.h" #include "exception.h" #include diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 32c262da..36a472b4 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -33,7 +33,6 @@ #include "target.h" #include "target_internal.h" #include "cortexm.h" -#include "platform.h" #include "command.h" #include "gdb_packet.h" diff --git a/src/target/target.c b/src/target/target.c index c17e9158..4f4bcace 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -19,7 +19,6 @@ */ #include "general.h" -#include "target.h" #include "target_internal.h" #include @@ -342,7 +341,6 @@ void target_detach(target *t) t->detach(t); t->attached = false; #if PC_HOSTED == 1 -# include "platform.h" platform_buffer_flush(); #endif } From f880734050fa6339347158e2f2b0257304b28fdb Mon Sep 17 00:00:00 2001 From: James Turton Date: Tue, 11 May 2021 09:12:15 +0200 Subject: [PATCH 04/26] Fix compiling for native probe --- src/target/adiv5.c | 4 ++-- src/target/cortexm.c | 2 +- src/target/rp.c | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/target/adiv5.c b/src/target/adiv5.c index f8e6b58f..38c3c9f9 100644 --- a/src/target/adiv5.c +++ b/src/target/adiv5.c @@ -661,8 +661,8 @@ void adiv5_dp_init(ADIv5_DP_t *dp) return; } DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d)\n", dp->idcode, - (dp->idcode >> 12) & 0xf, - (dp->idcode & 0x10000) ? "MINDP " : "", dp->idcode >> 28); + (uint8_t)((dp->idcode >> 12) & 0xf), + (dp->idcode & 0x10000) ? "MINDP " : "", (uint16_t)(dp->idcode >> 28)); volatile uint32_t ctrlstat = 0; #if PC_HOSTED == 1 platform_adiv5_dp_defaults(dp); diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 36a472b4..727aaed6 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -327,7 +327,7 @@ bool cortexm_probe(ADIv5_AP_t *ap) break; default: if (ap->ap_designer != AP_DESIGNER_ATMEL) /* Protected Atmel device?*/{ - DEBUG_WARN("Unexpected CortexM CPUID partno %04x\n", cpuid_partno); + DEBUG_WARN("Unexpected CortexM CPUID partno %04" PRIx32 "\n", cpuid_partno); } } DEBUG_INFO("CPUID 0x%08" PRIx32 " (%s var %" PRIx32 " rev %" PRIx32 ")\n", diff --git a/src/target/rp.c b/src/target/rp.c index 5d95085c..ff29e71c 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -131,14 +131,14 @@ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd, target_halt_resume(t, false); if (!timeout) return false; - DEBUG_INFO("Call cmd %04x\n", cmd); + DEBUG_INFO("Call cmd %04" PRIx32 "\n", cmd); platform_timeout to; platform_timeout_set(&to, timeout); do { if (timeout > 400) tc_printf(t, "\b%c", spinner[spinindex++ % 4]); if (platform_timeout_is_expired(&to)) { - DEBUG_WARN("RP Run timout %d ms reached: ", timeout); + DEBUG_WARN("RP Run timout %d ms reached: ", (int)timeout); break; } } while (!target_halt_poll(t, NULL)); @@ -146,7 +146,7 @@ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd, target_regs_read(t, dbg_regs); bool ret = ((dbg_regs[REG_PC] &~1) != (ps->_debug_trampoline_end & ~1)); if (ret) { - DEBUG_WARN("rp_rom_call cmd %04x failed, PC %08" PRIx32 "\n", + DEBUG_WARN("rp_rom_call cmd %04" PRIx32 " failed, PC %08" PRIx32 "\n", cmd, dbg_regs[REG_PC]); } return ret; @@ -181,7 +181,7 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, DEBUG_WARN("Unaligned len\n"); len = (len + 0xfff) & ~0xfff; } - DEBUG_INFO("Erase addr %08" PRIx32 " len 0x%" PRIx32 "\n", addr, len); + DEBUG_INFO("Erase addr %08" PRIx32 " len 0x%" PRIx32 "\n", addr, (uint32_t)len); target *t = f->t; rp_flash_prepare(t); struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage; @@ -236,7 +236,7 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, int rp_flash_write(struct target_flash *f, target_addr dest, const void *src, size_t len) { - DEBUG_INFO("RP Write %08" PRIx32 " len 0x%" PRIx32 "\n", dest, len); + DEBUG_INFO("RP Write %08" PRIx32 " len 0x%" PRIx32 "\n", dest, (uint32_t)len); if ((dest & 0xff) || (len & 0xff)) { DEBUG_WARN("Unaligned erase\n"); return -1; From 67c900352221f9821a80681ae0a7cfa150a7f088 Mon Sep 17 00:00:00 2001 From: James Turton Date: Tue, 11 May 2021 09:17:09 +0200 Subject: [PATCH 05/26] rp: Flush cache after erase and write The RP2040 datasheet suggests that _flash_flush_cache and _flash_enter_cmd_xip should be called after erasing and writing to flash. --- src/target/rp.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/src/target/rp.c b/src/target/rp.c index ff29e71c..74ff07a6 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -164,6 +164,18 @@ static void rp_flash_prepare(target *t) } } +static void rp_flash_resume(target *t) +{ + struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage; + if (ps->is_prepared) { + /* flush */ + rp_rom_call(t, ps->regs, ps->_flash_flush_cache,100); + /* enter_cmd_xip */ + rp_rom_call(t, ps->regs, ps->_flash_enter_cmd_xip, 100); + ps->is_prepared = false; + } +} + /* FLASHCMD_SECTOR_ERASE 45/ 400 ms * 32k block erase 120/ 1600 ms * 64k block erase 150/ 2000 ms @@ -195,6 +207,7 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, addr -= XIP_FLASH_START; if (len > MAX_FLASH) len = MAX_FLASH; + bool ret = 0; while (len) { ps->regs[0] = addr; ps->regs[2] = -1; @@ -202,14 +215,14 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, ps->regs[1] = MAX_FLASH; ps->regs[3] = FLASHCMD_CHIP_ERASE; DEBUG_WARN("BULK_ERASE\n"); - rp_rom_call(t, ps->regs, ps->_flash_range_erase, 25100); + ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 25100); len = 0; } else if (len >= (64 * 1024)) { uint32_t chunk = len & ~((1 << 16) - 1); ps->regs[1] = chunk; ps->regs[3] = FLASHCMD_BLOCK64K_ERASE; DEBUG_WARN("64k_ERASE\n"); - rp_rom_call(t, ps->regs, ps->_flash_range_erase, 2100); + ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 2100); len -= chunk ; addr += chunk; } else if (len >= (32 * 1024)) { @@ -217,7 +230,7 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, ps->regs[1] = chunk; ps->regs[3] = FLASHCMD_BLOCK32K_ERASE; DEBUG_WARN("32k_ERASE\n"); - rp_rom_call(t, ps->regs, ps->_flash_range_erase, 1700); + ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 1700); len -= chunk; addr += chunk; } else { @@ -225,12 +238,15 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, ps->regs[2] = MAX_FLASH; ps->regs[3] = FLASHCMD_SECTOR_ERASE; DEBUG_WARN("Sector_ERASE\n"); - rp_rom_call(t, ps->regs, ps->_flash_range_erase, 410); + ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 410); len = 0; } + if (ret) + break; } + rp_flash_resume(t); DEBUG_INFO("\nErase done!\n"); - return 0; + return ret; } int rp_flash_write(struct target_flash *f, @@ -246,6 +262,7 @@ int rp_flash_write(struct target_flash *f, struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage; /* Write payload to target ram */ dest -= XIP_FLASH_START; + bool ret = 0; #define MAX_WRITE_CHUNK 0x1000 while (len) { uint32_t chunksize = (len <= MAX_WRITE_CHUNK) ? len : MAX_WRITE_CHUNK; @@ -254,13 +271,16 @@ int rp_flash_write(struct target_flash *f, ps->regs[0] = dest; ps->regs[1] = SRAM_START; ps->regs[2] = chunksize; - rp_rom_call(t, ps->regs, ps->flash_range_program, + ret = rp_rom_call(t, ps->regs, ps->flash_range_program, (3 * chunksize) >> 8); /* 3 ms per 256 byte page */ + if (ret) + break; len -= chunksize; src += chunksize; dest += chunksize; } - return 0; + rp_flash_resume(t); + return ret; } static bool rp_cmd_reset_usb_boot(target *t, int argc, const char *argv[]) From e453740aca019526e374f5588428c3c9d825a11b Mon Sep 17 00:00:00 2001 From: James Turton Date: Tue, 11 May 2021 12:17:59 +0200 Subject: [PATCH 06/26] rp: Increase spinner timeout to 500ms Increasing spinner timeout to 500 means `tc_printf` is not called during the `_flash_range_erase`. This is important as `_flash_range_erase` is used when loading. This fixes the issue: https://github.com/blacksphere/blackmagic/issues/875 Also adding spinner timeout counter to reduce bus traffic. --- src/target/rp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/target/rp.c b/src/target/rp.c index 74ff07a6..2f9caccf 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -112,7 +112,7 @@ static bool rp2040_fill_table(struct rp_priv_s *priv, uint16_t *table, int max) /* RP ROM functions calls * * timout == 0: Do not wait for poll, use for reset_usb_boot() - * timeout > 400 (ms) : display spinner + * timeout > 500 (ms) : display spinner */ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd, uint32_t timeout) @@ -134,9 +134,17 @@ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd, DEBUG_INFO("Call cmd %04" PRIx32 "\n", cmd); platform_timeout to; platform_timeout_set(&to, timeout); + platform_timeout to_spinner; + if (timeout > 500) + platform_timeout_set(&to_spinner, 500); + else + /* never trigger if timeout is short */ + platform_timeout_set(&to_spinner, timeout + 1); do { - if (timeout > 400) + if (platform_timeout_is_expired(&to_spinner)) { tc_printf(t, "\b%c", spinner[spinindex++ % 4]); + platform_timeout_set(&to_spinner, 500); + } if (platform_timeout_is_expired(&to)) { DEBUG_WARN("RP Run timout %d ms reached: ", (int)timeout); break; From ff302593543db081d418749e5d85b9c7c7d1c95c Mon Sep 17 00:00:00 2001 From: James Turton Date: Fri, 14 May 2021 18:11:40 +0200 Subject: [PATCH 07/26] rp: Add more debug logging during flash --- src/target/rp.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/target/rp.c b/src/target/rp.c index 2f9caccf..207e47fc 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -164,6 +164,7 @@ static void rp_flash_prepare(target *t) { struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage; if (!ps->is_prepared) { + DEBUG_INFO("rp_flash_prepare\n"); /* connect*/ rp_rom_call(t, ps->regs, ps->_connect_internal_flash,100); /* exit_xip */ @@ -176,6 +177,7 @@ static void rp_flash_resume(target *t) { struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage; if (ps->is_prepared) { + DEBUG_INFO("rp_flash_resume\n"); /* flush */ rp_rom_call(t, ps->regs, ps->_flash_flush_cache,100); /* enter_cmd_xip */ @@ -249,11 +251,13 @@ static int rp_flash_erase(struct target_flash *f, target_addr addr, ret = rp_rom_call(t, ps->regs, ps->_flash_range_erase, 410); len = 0; } - if (ret) + if (ret) { + DEBUG_WARN("Erase failed!\n"); break; + } } rp_flash_resume(t); - DEBUG_INFO("\nErase done!\n"); + DEBUG_INFO("Erase done!\n"); return ret; } @@ -279,15 +283,18 @@ int rp_flash_write(struct target_flash *f, ps->regs[0] = dest; ps->regs[1] = SRAM_START; ps->regs[2] = chunksize; - ret = rp_rom_call(t, ps->regs, ps->flash_range_program, + ret |= rp_rom_call(t, ps->regs, ps->flash_range_program, (3 * chunksize) >> 8); /* 3 ms per 256 byte page */ - if (ret) + if (ret) { + DEBUG_WARN("Write failed!\n"); break; + } len -= chunksize; src += chunksize; dest += chunksize; } rp_flash_resume(t); + DEBUG_INFO("Write done!\n"); return ret; } From 0ab10fee0b6afb94e7bdba2a13f7116145b9030a Mon Sep 17 00:00:00 2001 From: James Turton Date: Fri, 14 May 2021 18:12:36 +0200 Subject: [PATCH 08/26] rp: Increase timeout for flash_range_program If the RP2040 is using the ring oscilator (ROSC) rather than the crystal oscilator (XOSC) then flashing program will take much longer. As the XOSC is not enabled at boot we should not assume it will be enabled before the debugger is connected (or indeed at all), thus should use the longer timeout during load commands. --- src/target/rp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/target/rp.c b/src/target/rp.c index 207e47fc..b215803f 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -283,8 +283,12 @@ int rp_flash_write(struct target_flash *f, ps->regs[0] = dest; ps->regs[1] = SRAM_START; ps->regs[2] = chunksize; + /* Loading takes 3 ms per 256 byte page + * however it takes much longer if the XOSC is not enabled + * so lets give ourselves a little bit more time (x10) + */ ret |= rp_rom_call(t, ps->regs, ps->flash_range_program, - (3 * chunksize) >> 8); /* 3 ms per 256 byte page */ + (3 * chunksize * 10) >> 8); if (ret) { DEBUG_WARN("Write failed!\n"); break; From 517d5b5b316cdc23f0a4b5be93df649e77765f36 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Fri, 14 May 2021 12:44:07 +0200 Subject: [PATCH 09/26] rp: Show spinner only when called from monitor command. --- src/target/rp.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/target/rp.c b/src/target/rp.c index b215803f..c62bd0a0 100644 --- a/src/target/rp.c +++ b/src/target/rp.c @@ -59,6 +59,7 @@ struct rp_priv_s { uint16_t _flash_enter_cmd_xip; uint16_t reset_usb_boot; bool is_prepared; + bool is_monitor; uint32_t regs[0x20];/* Register playground*/ }; @@ -142,7 +143,8 @@ static bool rp_rom_call(target *t, uint32_t *regs, uint32_t cmd, platform_timeout_set(&to_spinner, timeout + 1); do { if (platform_timeout_is_expired(&to_spinner)) { - tc_printf(t, "\b%c", spinner[spinindex++ % 4]); + if (ps->is_monitor) + tc_printf(t, "\b%c", spinner[spinindex++ % 4]); platform_timeout_set(&to_spinner, 500); } if (platform_timeout_is_expired(&to)) { @@ -323,7 +325,11 @@ static bool rp_cmd_erase_mass(target *t, int argc, const char *argv[]) (void) argv; struct target_flash f; f.t = t; - return (rp_flash_erase(&f, XIP_FLASH_START, MAX_FLASH)) ? false: true; + struct rp_priv_s *ps = (struct rp_priv_s*)t->target_storage; + ps->is_monitor = true; + bool res = (rp_flash_erase(&f, XIP_FLASH_START, MAX_FLASH)) ? false: true; + ps->is_monitor = false; + return res; } const struct command_s rp_cmd_list[] = { From f0dd8c95173166d7f286a523c05f58c4ce716dff Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 26 Apr 2021 19:12:00 +0200 Subject: [PATCH 10/26] cl_utils: List -l option in the help. --- src/platforms/pc/cl_utils.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index a70074cf..145dccba 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -133,6 +133,7 @@ static void cl_help(char **argv) DEBUG_WARN("\t-h\t\t: This help.\n"); DEBUG_WARN("\t-v[bitmask]\t: Increasing verbosity. Bitmask:\n"); DEBUG_WARN("\t\t\t 1 = INFO, 2 = GDB, 4 = TARGET, 8 = PROBE, 16 = WIRE\n"); + DEBUG_WARN("\t-l\t\t: List available probes\n"); DEBUG_WARN("Probe selection arguments:\n"); DEBUG_WARN("\t-d \"path\"\t: Use serial BMP device at "); #if HOSTED_BMP_ONLY == 1 && defined(__APPLE__) From 36ad6efc6f4c63cf3e31e17202df3393c37cb619 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 16 May 2021 16:47:34 +0200 Subject: [PATCH 11/26] cmsis_dap.h: Fix wrong leftover argument. --- src/platforms/hosted/cmsis_dap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platforms/hosted/cmsis_dap.h b/src/platforms/hosted/cmsis_dap.h index 9e8054f2..a060d585 100644 --- a/src/platforms/hosted/cmsis_dap.h +++ b/src/platforms/hosted/cmsis_dap.h @@ -44,7 +44,7 @@ uint32_t dap_swj_clock(uint32_t clock) {return 0;} void dap_exit_function(void) {}; void dap_adiv5_dp_defaults(ADIv5_DP_t *dp) {}; int cmsis_dap_jtagtap_init(jtag_proc_t *jtag_proc) {return -1;} -int dap_swdptap_init(swd_proc_t *swd_proc) {return -1;} +int dap_swdptap_init(ADIv5_DP_t *dp) {return -1;} int dap_jtag_dp_init(ADIv5_DP_t *dp) {return -1;} void dap_swd_configure(uint8_t cfg) {}; # pragma GCC diagnostic pop From c3fd198f0d3ec6b53d6aa23d4cb90b047f3661d3 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 16 May 2021 22:58:37 +0200 Subject: [PATCH 12/26] bmp_libusb: Reject non-BMP devices with VID 1d50. --- src/platforms/hosted/bmp_libusb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/platforms/hosted/bmp_libusb.c b/src/platforms/hosted/bmp_libusb.c index 743f25b1..bef9e094 100644 --- a/src/platforms/hosted/bmp_libusb.c +++ b/src/platforms/hosted/bmp_libusb.c @@ -222,8 +222,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info) if (desc.idVendor == VENDOR_ID_BMP) { if (desc.idProduct == PRODUCT_ID_BMP) { type = BMP_TYPE_BMP; - } else if (desc.idProduct == PRODUCT_ID_BMP_BL) { - DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n"); + } else { + if (desc.idProduct == PRODUCT_ID_BMP_BL) + DEBUG_WARN("BMP in botloader mode found. Restart or reflash!\n"); continue; } } else if ((type = find_cmsis_dap_interface(dev, info)) != BMP_TYPE_NONE) { From cb4cff2c71e81853d4078a3407a594711d697e87 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 16 May 2021 23:06:04 +0200 Subject: [PATCH 13/26] hosted/ftdi: Compare only for length of the string given in the header Devices may have added version like "Tigard V1.1" vs "Tigard" --- src/platforms/hosted/bmp_libusb.c | 4 ++-- src/platforms/hosted/ftdi_bmp.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platforms/hosted/bmp_libusb.c b/src/platforms/hosted/bmp_libusb.c index bef9e094..63aad38e 100644 --- a/src/platforms/hosted/bmp_libusb.c +++ b/src/platforms/hosted/bmp_libusb.c @@ -253,13 +253,13 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info) if ((cable->vendor != desc.idVendor) || (cable->product != desc.idProduct)) continue; /* VID/PID do not match*/ if (cl_opts->opt_cable) { - if (strcmp(cable->name, cl_opts->opt_cable)) + if (strncmp(cable->name, cl_opts->opt_cable, strlen(cable->name))) continue; /* cable names do not match*/ else found = true; } if (cable->description) { - if (strcmp(cable->description, product)) + if (strncmp(cable->description, product, strlen(cable->description))) continue; /* discriptions do not match*/ else found = true; diff --git a/src/platforms/hosted/ftdi_bmp.c b/src/platforms/hosted/ftdi_bmp.c index 53868157..f05a86b7 100644 --- a/src/platforms/hosted/ftdi_bmp.c +++ b/src/platforms/hosted/ftdi_bmp.c @@ -269,7 +269,7 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) int err; cable_desc_t *cable = &cable_desc[0]; for(; cable->name; cable++) { - if (strcmp(cable->name, cl_opts->opt_cable) == 0) + if (strncmp(cable->name, cl_opts->opt_cable, strlen(cable->name)) == 0) break; } @@ -281,7 +281,7 @@ int ftdi_bmp_init(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) active_cable = cable; memcpy(&active_state, &active_cable->init, sizeof(data_desc_t)); /* If swd_(read|write) is not given for the selected cable and - the 'r' command line argument is give, assume resistor SWD + the 'e' command line argument is give, assume resistor SWD connection.*/ if (cl_opts->external_resistor_swd && (active_cable->mpsse_swd_read.set_data_low == 0) && From 87acd99fe4c3b75df1423279c6902d1709202a06 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 17 May 2021 16:07:37 +0200 Subject: [PATCH 14/26] cortexm: For Cortex-M0+ devices, probe also for lpc11 to detect LPC80 #884 --- src/target/cortexm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/target/cortexm.c b/src/target/cortexm.c index 727aaed6..82e22b66 100644 --- a/src/target/cortexm.c +++ b/src/target/cortexm.c @@ -440,6 +440,7 @@ bool cortexm_probe(ADIv5_AP_t *ap) if (ap->ap_partno == 0x4c0) { /* Cortex-M0+ ROM */ if ((ap->dp->targetid & 0xfff) == AP_DESIGNER_RASPBERRY) PROBE(rp_probe); + PROBE(lpc11xx_probe); /* LPC8 */ } else if (ap->ap_partno == 0x4c3) { /* Cortex-M3 ROM */ PROBE(stm32f1_probe); /* Care for STM32F1 clones */ PROBE(lpc15xx_probe); /* Thanks to JojoS for testing */ From 90534b3cf614fd78f43fc9aa393d0c51a74a928b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Mon, 10 May 2021 19:27:58 +0200 Subject: [PATCH 15/26] stm32: portability enhancements Needed for e.g. stlinkv3 --- src/platforms/stm32/gpio.h | 8 ++++++-- src/platforms/stm32/usbuart.c | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/platforms/stm32/gpio.h b/src/platforms/stm32/gpio.h index dad20bb2..5fb75e0e 100644 --- a/src/platforms/stm32/gpio.h +++ b/src/platforms/stm32/gpio.h @@ -39,6 +39,7 @@ static inline void _gpio_set(uint32_t gpioport, uint16_t gpios) { GPIO_BSRR(gpioport) = gpios; #ifdef STM32F4 + /* FIXME: Check if doubling is still needed */ GPIO_BSRR(gpioport) = gpios; #endif } @@ -46,11 +47,14 @@ static inline void _gpio_set(uint32_t gpioport, uint16_t gpios) static inline void _gpio_clear(uint32_t gpioport, uint16_t gpios) { -#ifndef STM32F4 +#if defined(STM32F4) + GPIO_BSRR(gpioport) = gpios<<16; + /* FIXME: Check if doubling is still needed */ + GPIO_BSRR(gpioport) = gpios<<16; +#elif defined(GPIO_BRR) GPIO_BRR(gpioport) = gpios; #else GPIO_BSRR(gpioport) = gpios<<16; - GPIO_BSRR(gpioport) = gpios<<16; #endif } #define gpio_clear _gpio_clear diff --git a/src/platforms/stm32/usbuart.c b/src/platforms/stm32/usbuart.c index 786bbc38..4775e1d3 100644 --- a/src/platforms/stm32/usbuart.c +++ b/src/platforms/stm32/usbuart.c @@ -118,8 +118,14 @@ void usbuart_init(void) USBUSART_CR1 |= USART_CR1_IDLEIE; /* Setup USART TX DMA */ +#if !defined(USBUSART_TDR) && defined(USBUSART_DR) +# define USBUSART_TDR USBUSART_DR +#endif +#if !defined(USBUSART_RDR) && defined(USBUSART_DR) +# define USBUSART_RDR USBUSART_DR +#endif dma_channel_reset(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN); - dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, (uint32_t)&USBUSART_DR); + dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, (uint32_t)&USBUSART_TDR); dma_enable_memory_increment_mode(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN); dma_set_peripheral_size(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, DMA_PSIZE_8BIT); dma_set_memory_size(USBUSART_DMA_BUS, USBUSART_DMA_TX_CHAN, DMA_MSIZE_8BIT); @@ -136,7 +142,7 @@ void usbuart_init(void) /* Setup USART RX DMA */ dma_channel_reset(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN); - dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, (uint32_t)&USBUSART_DR); + dma_set_peripheral_address(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, (uint32_t)&USBUSART_RDR); dma_set_memory_address(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, (uint32_t)buf_rx); dma_set_number_of_data(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN, RX_FIFO_SIZE); dma_enable_memory_increment_mode(USBUSART_DMA_BUS, USBUSART_DMA_RX_CHAN); From 7f1a560288a09ffc559f8571e3568b3cc10b28d2 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 11 May 2021 11:21:27 +0200 Subject: [PATCH 16/26] stm32/usbuart: Clear USART_ICR if provided. Otherwise endless interrupts happened. --- src/platforms/stm32/usbuart.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/platforms/stm32/usbuart.c b/src/platforms/stm32/usbuart.c index 4775e1d3..8c04db7b 100644 --- a/src/platforms/stm32/usbuart.c +++ b/src/platforms/stm32/usbuart.c @@ -399,8 +399,15 @@ void USBUSART_ISR(void) usart_recv(USBUSART); /* If line is now idle, then transmit a packet */ - if (isIdle) + if (isIdle) { +#if defined(USART_ICR) + USART_ICR(USBUSART) = USART_ICR_IDLECF; +#else + /* On the older uarts, the sequence "read flags", "read DR" + * as above cleared the flags */ +#endif usbuart_run(); + } nvic_enable_irq(USBUSART_DMA_RX_IRQ); } From df575eb0902a872d5906c281e87a1d07c57240f8 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 5 May 2021 12:50:45 +0200 Subject: [PATCH 17/26] stm32_mem.py: Wait longer for device to appear. --- scripts/stm32_mem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/stm32_mem.py b/scripts/stm32_mem.py index 690657e0..51a8537b 100755 --- a/scripts/stm32_mem.py +++ b/scripts/stm32_mem.py @@ -184,7 +184,7 @@ if __name__ == "__main__": print("Invoking DFU Device") timeout = 0 while True : - sleep(0.5) + sleep(1) timeout = timeout + 0.5 dfudev = stm32_scan(args, True) if dfudev: break From 6454d0bc96525d692817b52f382feb52dcde6f77 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Wed, 19 May 2021 17:41:54 +0200 Subject: [PATCH 18/26] bmp_libusb: Invalidate manufacturer and product in case libusb_get_string_descriptor_ascii fails. Prevent more false detections --- src/platforms/hosted/bmp_libusb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/platforms/hosted/bmp_libusb.c b/src/platforms/hosted/bmp_libusb.c index 63aad38e..8739710d 100644 --- a/src/platforms/hosted/bmp_libusb.c +++ b/src/platforms/hosted/bmp_libusb.c @@ -201,9 +201,11 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts,bmp_info_t *info) } if (res < 0) serial[0] = 0; + manufacturer[0] = 0; res = libusb_get_string_descriptor_ascii( handle, desc.iManufacturer, (uint8_t*)manufacturer, sizeof(manufacturer)); + product[0] = 0; res = libusb_get_string_descriptor_ascii( handle, desc.iProduct, (uint8_t*)product, sizeof(product)); From 21a702dc1e840abf42164dccf176b6b4e1ea6c72 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Thu, 20 May 2021 12:32:59 +0200 Subject: [PATCH 19/26] lpc: More verbosity and more definitions --- src/target/lpc_common.c | 48 ++++++++++++++++++++++++++++++++++++++--- src/target/lpc_common.h | 19 ++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/src/target/lpc_common.c b/src/target/lpc_common.c index b16c22c2..bfb5c8ee 100644 --- a/src/target/lpc_common.c +++ b/src/target/lpc_common.c @@ -33,6 +33,42 @@ struct flash_param { uint32_t result[4]; } __attribute__((aligned(4))); +char *iap_error[] = { + "CMD_SUCCESS", + "Invalid command", + "Unaligned src address", + "Dst address not on boundary", + "Src not mapped", + "Dst not mapped", + "Invalid byte count", + "Invalid sector", + "Sector not blank", + "Sector not prepared", + "Compare error", + "Flash interface busy", + "Invalid or missing parameter", + "Address not on boundary", + "Address not mapped", + "Checksum error", + "16", + "17", + "18", + "19", + "20", + "21", + "22", + "FRO not powered", + "Flash not powered", + "25", + "26", + "Flash clock disabled", + "Reinvoke error", + "Invalid image", + "30", + "31", + "Flash erase failed", + "Page is invalid", +}; struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length) { @@ -109,11 +145,17 @@ enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd if (result != NULL) memcpy(result, param.result, sizeof(param.result)); +#if defined(ENABLE_DEBUG) if (param.status != IAP_STATUS_CMD_SUCCESS) { - DEBUG_WARN("IAP failure code %d for cmd %d\n", - (enum iap_status)param.status, cmd); + if (param.status > (sizeof(iap_error) / sizeof(char*))) + DEBUG_WARN("IAP cmd %d : %d\n", cmd, param.status); + else + DEBUG_WARN("IAP cmd %d : %s\n", cmd, iap_error[param.status]); + DEBUG_WARN("return parameters: %08" PRIx32 " %08" PRIx32 " %08" PRIx32 + " %08" PRIx32 "\n", param.result[0], + param.result[1], param.result[2], param.result[3]); } - +#endif return param.status; } diff --git a/src/target/lpc_common.h b/src/target/lpc_common.h index 3130e96b..d5a4efc3 100644 --- a/src/target/lpc_common.h +++ b/src/target/lpc_common.h @@ -21,14 +21,23 @@ #define __LPC_COMMON_H enum iap_cmd { + IAP_CMD_READ_FACTORY_SETTINGS = 40, IAP_CMD_INIT = 49, IAP_CMD_PREPARE = 50, IAP_CMD_PROGRAM = 51, IAP_CMD_ERASE = 52, IAP_CMD_BLANKCHECK = 53, IAP_CMD_PARTID = 54, + IAP_CMD_READ_BOOTROM_VERSION = 55, + IAP_CMD_COMPARE = 56, + IAP_CMD_REINVOKE_ISP = 57, IAP_CMD_READUID = 58, + IAP_CMD_ERASE_PAGE = 59, IAP_CMD_SET_ACTIVE_BANK = 60, + IAP_CMD_READ_SIGNATURE = 70, + IAP_CMD_EXTENDED_READ_SIGNATURE = 73, + IAP_CMD_READ_EEPROM_PAGE = 80, + IAP_CMD_WRITE_EEPROM_PAGE = 81, }; enum iap_status { @@ -44,6 +53,16 @@ enum iap_status { IAP_STATUS_SECTOR_NOT_PREPARED = 9, IAP_STATUS_COMPARE_ERROR = 10, IAP_STATUS_BUSY = 11, + IAP_STATUS_MISSING_PARAMETERS = 12, + IAP_STATUS_UNALIGNED_ADDRESS = 13, + IAP_STATUS_ADDRESS_NOT_MAPPED = 14, + IAP_STATUS_FRO_NO_POWER = 23, + IAP_STATUS_FLASH_NO_POWER = 24, + IAP_STATUS_NO_CLOCK = 27, + IAP_STATUS_REINVOKE_CFG_ERR = 28, + IAP_STATUS_NO_VALID_IMAGE = 29, + IAP_STATUS_FLASH_ERASE = 32, + IAP_STATUS_INVALID_PAGE = 33, }; /* CPU Frequency */ From 42ebcac329c544ba6b88e7a6f649d684797ef90d Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sat, 29 May 2021 21:09:49 +0200 Subject: [PATCH 20/26] efm32_devices: Rearrange struct efm32_device_t to save flash space. --- src/target/efm32.c | 118 ++++++++++++++++++++++----------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/src/target/efm32.c b/src/target/efm32.c index 6ad4f32f..547eadc8 100644 --- a/src/target/efm32.c +++ b/src/target/efm32.c @@ -267,75 +267,75 @@ const struct command_s efm32_cmd_list[] = { /* -------------------------------------------------------------------------- */ typedef struct efm32_device_t { - uint16_t family_id; /* Family for device matching */ - char* name; /* Friendly device family name */ - uint32_t flash_page_size; /* Flash page size */ - uint32_t msc_addr; /* MSC Address */ + uint8_t family_id; /* Family for device matching */ bool has_radio; /* Indicates a device has attached radio */ - uint32_t user_data_size; /* User Data (UD) region size */ - uint32_t bootloader_size; /* Bootloader (BL) region size (may be 0 for no BL region) */ + uint16_t flash_page_size; /* Flash page size */ + char* name; /* Friendly device family name */ + uint32_t msc_addr; /* MSC Address */ + uint16_t user_data_size; /* User Data (UD) region size */ + uint16_t bootloader_size; /* Bootloader (BL) region size (may be 0 for no BL region) */ char* description; /* Human-readable description */ } efm32_device_t; efm32_device_t const efm32_devices[] = { /* First gen micros */ - {71, "EFM32G", 512, 0x400c0000, false, 512, 0, "Gecko"}, - {72, "EFM32GG", 2048, 0x400c0000, false, 4096, 0, "Giant Gecko"}, - {73, "EFM32TG", 512, 0x400c0000, false, 512, 0, "Tiny Gecko"}, - {74, "EFM32LG", 2048, 0x400c0000, false, 2048, 0, "Leopard Gecko"}, - {75, "EFM32WG", 2048, 0x400c0000, false, 2048, 0, "Wonder Gecko"}, - {76, "EFM32ZG", 1024, 0x400c0000, false, 1024, 0, "Zero Gecko"}, - {77, "EFM32HG", 1024, 0x400c0000, false, 1024, 0, "Happy Gecko"}, + { 71, false, 512, "EFM32G" , 0x400c0000, 512, 0, "Gecko"}, + { 72, false, 2048, "EFM32GG" , 0x400c0000, 4096, 0, "Giant Gecko"}, + { 73, false, 512, "EFM32TG" , 0x400c0000, 512, 0, "Tiny Gecko"}, + { 74, false, 2048, "EFM32LG" , 0x400c0000, 2048, 0, "Leopard Gecko"}, + { 75, false, 2048, "EFM32WG" , 0x400c0000, 2048, 0, "Wonder Gecko"}, + { 76, false, 1024, "EFM32ZG" , 0x400c0000, 1024, 0, "Zero Gecko"}, + { 77, false, 1024, "EFM32HG" , 0x400c0000, 1024, 0, "Happy Gecko"}, /* First (1.5) gen micro + radio */ - {120, "EZR32WG", 2048, 0x400c0000, true, 2048, 0, "EZR Wonder Gecko"}, - {121, "EZR32LG", 2048, 0x400c0000, true, 2048, 0, "EZR Leopard Gecko"}, - {122, "EZR32HG", 1024, 0x400c0000, true, 1024, 0, "EZR Happy Gecko"}, + {120, true , 2048, "EZR32WG" , 0x400c0000, 2048, 0, "EZR Wonder Gecko"}, + {121, true , 2048, "EZR32LG" , 0x400c0000, 2048, 0, "EZR Leopard Gecko"}, + {122, true , 1024, "EZR32HG" , 0x400c0000, 1024, 0, "EZR Happy Gecko"}, /* Second gen micros */ - {81, "EFM32PG1B", 2048, 0x400e0000, false, 2048, 10240, "Pearl Gecko"}, - {83, "EFM32JG1B", 2048, 0x400e0000, false, 2048, 10240, "Jade Gecko"}, - {85, "EFM32PG12B", 2048, 0x400e0000, false, 2048, 32768,"Pearl Gecko 12"}, - {87, "EFM32JG12B", 2048, 0x400e0000, false, 2048, 32768, "Jade Gecko 12"}, + { 81, false, 2048, "EFM32PG1B" , 0x400e0000, 2048, 10240, "Pearl Gecko"}, + { 83, false, 2048, "EFM32JG1B" , 0x400e0000, 2048, 10240, "Jade Gecko"}, + { 85, false, 2048, "EFM32PG12B", 0x400e0000, 2048, 32768,"Pearl Gecko 12"}, + { 87, false, 2048, "EFM32JG12B", 0x400e0000, 2048, 32768, "Jade Gecko 12"}, /* Second (2.5) gen micros, with re-located MSC */ - {100, "EFM32GG11B", 4096, 0x40000000, false, 4096, 32768, "Giant Gecko 11"}, - {103, "EFM32TG11B", 2048, 0x40000000, false, 2048, 18432, "Tiny Gecko 11"}, - {106, "EFM32GG12B", 2048, 0x40000000, false, 2048, 32768, "Giant Gecko 12"}, + {100, false, 4096, "EFM32GG11B", 0x40000000, 4096, 32768, "Giant Gecko 11"}, + {103, false, 2048, "EFM32TG11B", 0x40000000, 2048, 18432, "Tiny Gecko 11"}, + {106, false, 2048, "EFM32GG12B", 0x40000000, 2048, 32768, "Giant Gecko 12"}, /* Second gen devices micro + radio */ - {16, "EFR32MG1P", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"}, - {17, "EFR32MG1B", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"}, - {18, "EFR32MG1V", 2048, 0x400e0000, true, 2048, 10240, "Mighty Gecko"}, - {19, "EFR32BG1P", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"}, - {20, "EFR32BG1B", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"}, - {21, "EFR32BG1V", 2048, 0x400e0000, true, 2048, 10240, "Blue Gecko"}, - {25, "EFR32FG1P", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"}, - {26, "EFR32FG1B", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"}, - {27, "EFR32FG1V", 2048, 0x400e0000, true, 2048, 10240, "Flex Gecko"}, - {28, "EFR32MG12P", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"}, - {29, "EFR32MG12B", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"}, - {30, "EFR32MG12V", 2048, 0x400e0000, true, 2048, 32768, "Mighty Gecko"}, - {31, "EFR32BG12P", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"}, - {32, "EFR32BG12B", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"}, - {33, "EFR32BG12V", 2048, 0x400e0000, true, 2048, 32768, "Blue Gecko"}, - {37, "EFR32FG12P", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"}, - {38, "EFR32FG12B", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"}, - {39, "EFR32FG12V", 2048, 0x400e0000, true, 2048, 32768, "Flex Gecko"}, - {40, "EFR32MG13P", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {41, "EFR32MG13B", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {42, "EFR32MG13V", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {43, "EFR32BG13P", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {44, "EFR32BG13B", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {45, "EFR32BG13V", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {49, "EFR32FG13P", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {50, "EFR32FG13B", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {51, "EFR32FG13V", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {52, "EFR32MG14P", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {53, "EFR32MG14B", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {54, "EFR32MG14V", 2048, 0x400e0000, true, 2048, 16384, "Mighty Gecko"}, - {55, "EFR32BG14P", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {56, "EFR32BG14B", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {57, "EFR32BG14V", 2048, 0x400e0000, true, 2048, 16384, "Blue Gecko"}, - {61, "EFR32FG14P", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {62, "EFR32FG14B", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, - {63, "EFR32FG14V", 2048, 0x400e0000, true, 2048, 16384, "Flex Gecko"}, + { 16, true , 2048, "EFR32MG1P" , 0x400e0000, 2048, 10240, "Mighty Gecko"}, + { 17, true , 2048, "EFR32MG1B" , 0x400e0000, 2048, 10240, "Mighty Gecko"}, + { 18, true , 2048, "EFR32MG1V" , 0x400e0000, 2048, 10240, "Mighty Gecko"}, + { 19, true , 2048, "EFR32BG1P" , 0x400e0000, 2048, 10240, "Blue Gecko"}, + { 20, true , 2048, "EFR32BG1B" , 0x400e0000, 2048, 10240, "Blue Gecko"}, + { 21, true , 2048, "EFR32BG1V" , 0x400e0000, 2048, 10240, "Blue Gecko"}, + { 25, true , 2048, "EFR32FG1P" , 0x400e0000, 2048, 10240, "Flex Gecko"}, + { 26, true , 2048, "EFR32FG1B" , 0x400e0000, 2048, 10240, "Flex Gecko"}, + { 27, true , 2048, "EFR32FG1V" , 0x400e0000, 2048, 10240, "Flex Gecko"}, + { 28, true , 2048, "EFR32MG12P", 0x400e0000, 2048, 32768, "Mighty Gecko"}, + { 29, true , 2048, "EFR32MG12B", 0x400e0000, 2048, 32768, "Mighty Gecko"}, + { 30, true , 2048, "EFR32MG12V", 0x400e0000, 2048, 32768, "Mighty Gecko"}, + { 31, true , 2048, "EFR32BG12P", 0x400e0000, 2048, 32768, "Blue Gecko"}, + { 32, true , 2048, "EFR32BG12B", 0x400e0000, 2048, 32768, "Blue Gecko"}, + { 33, true , 2048, "EFR32BG12V", 0x400e0000, 2048, 32768, "Blue Gecko"}, + { 37, true , 2048, "EFR32FG12P", 0x400e0000, 2048, 32768, "Flex Gecko"}, + { 38, true , 2048, "EFR32FG12B", 0x400e0000, 2048, 32768, "Flex Gecko"}, + { 39, true , 2048, "EFR32FG12V", 0x400e0000, 2048, 32768, "Flex Gecko"}, + { 40, true , 2048, "EFR32MG13P", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 41, true , 2048, "EFR32MG13B", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 42, true , 2048, "EFR32MG13V", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 43, true , 2048, "EFR32BG13P", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 44, true , 2048, "EFR32BG13B", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 45, true , 2048, "EFR32BG13V", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 49, true , 2048, "EFR32FG13P", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 50, true , 2048, "EFR32FG13B", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 51, true , 2048, "EFR32FG13V", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 52, true , 2048, "EFR32MG14P", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 53, true , 2048, "EFR32MG14B", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 54, true , 2048, "EFR32MG14V", 0x400e0000, 2048, 16384, "Mighty Gecko"}, + { 55, true , 2048, "EFR32BG14P", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 56, true , 2048, "EFR32BG14B", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 57, true , 2048, "EFR32BG14V", 0x400e0000, 2048, 16384, "Blue Gecko"}, + { 61, true , 2048, "EFR32FG14P", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 62, true , 2048, "EFR32FG14B", 0x400e0000, 2048, 16384, "Flex Gecko"}, + { 63, true , 2048, "EFR32FG14V", 0x400e0000, 2048, 16384, "Flex Gecko"}, }; From f7b4697280e1dba3a0cda0c571e014daa541b3ed Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 30 May 2021 15:59:15 +0200 Subject: [PATCH 21/26] lpc11xx/lpc8c04: Do not expose two top system flash sectors. --- src/target/lpc11xx.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/target/lpc11xx.c b/src/target/lpc11xx.c index d487f337..9dc4b58f 100644 --- a/src/target/lpc11xx.c +++ b/src/target/lpc11xx.c @@ -36,6 +36,22 @@ #define LPC11XX_DEVICE_ID 0x400483F4 #define LPC8XX_DEVICE_ID 0x400483F8 +/* + * CHIP Ram Flash page sector Rsvd pages EEPROM + * LPX80x 2k 16k 64 1024 2 + * LPC804 4k 32k 64 1024 2 + * LPC8N04 8k 32k 64 1024 32 + * LPC810 1k 4k 64 1024 0 + * LPC811 2k 8k 64 1024 0 + * LPC812 4k 16k 64 1024 + * LPC822 4k 16k 64 1024 + * LPC822 8k 32k 64 1024 + * LPC832 4k 16k 64 1024 + * LPC834 4k 32k 64 1024 + * LPC844 8k 64k 64 1024 + * LPC845 16k 64k 64 1024 + */ + static bool lpc11xx_read_uid(target *t, int argc, const char *argv[]) { (void)argc; @@ -133,7 +149,10 @@ lpc11xx_probe(target *t) case 0x00008A04: /* LPC8N04 (see UM11074 Rev.1.3 section 4.5.19) */ t->driver = "LPC8N04"; target_add_ram(t, 0x10000000, 0x2000); - lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST); + /* UM11074/ Flash controller/15.2: The two topmost sectors + * contain the initialization code and IAP firmware. + * Do not touch the! */ + lpc11xx_add_flash(t, 0x00000000, 0x7800, 0x400, IAP_ENTRY_MOST); target_add_commands(t, lpc11xx_cmd_list, "LPC8N04"); return true; } From 891633322a87146735c6693b497eed2c8e2e8933 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 30 May 2021 17:42:39 +0200 Subject: [PATCH 22/26] lpc: Care for protected pages on LPC80x devices. --- src/target/lpc11xx.c | 33 +++++++++---------- src/target/lpc_common.c | 70 ++++++++++++++++++++++++++++++++--------- src/target/lpc_common.h | 3 +- 3 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/target/lpc11xx.c b/src/target/lpc11xx.c index 9dc4b58f..5b12e1c6 100644 --- a/src/target/lpc11xx.c +++ b/src/target/lpc11xx.c @@ -72,7 +72,7 @@ const struct command_s lpc11xx_cmd_list[] = { {NULL, NULL, NULL} }; -void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, uint32_t iap_entry) +void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, uint32_t iap_entry, uint8_t reserved_pages) { struct lpc_flash *lf = lpc_add_flash(t, addr, len); lf->f.blocksize = erasesize; @@ -81,6 +81,7 @@ void lpc11xx_add_flash(target *t, uint32_t addr, size_t len, size_t erasesize, u lf->iap_entry = iap_entry; lf->iap_ram = IAP_RAM_BASE; lf->iap_msp = IAP_RAM_BASE + MIN_RAM_SIZE - RAM_USAGE_FOR_IAP_ROUTINES; + lf->reserved_pages = reserved_pages; } bool @@ -125,7 +126,7 @@ lpc11xx_probe(target *t) case 0x2980002B: /* lpc11u24x/401 */ t->driver = "LPC11xx"; target_add_ram(t, 0x10000000, 0x2000); - lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC11xx"); return true; @@ -133,18 +134,18 @@ lpc11xx_probe(target *t) case 0x1A24902B: t->driver = "LPC1112"; target_add_ram(t, 0x10000000, 0x1000); - lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x1000, IAP_ENTRY_MOST, 0); return true; case 0x1000002b: // FX LPC11U6 32 kB SRAM/256 kB flash (max) t->driver = "LPC11U6"; target_add_ram(t, 0x10000000, 0x8000); - lpc11xx_add_flash(t, 0x00000000, 0x40000, 0x1000, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x40000, 0x1000, IAP_ENTRY_MOST, 0); return true; case 0x3000002B: case 0x3D00002B: t->driver = "LPC1343"; target_add_ram(t, 0x10000000, 0x2000); - lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x1000, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x1000, IAP_ENTRY_MOST, 0); return true; case 0x00008A04: /* LPC8N04 (see UM11074 Rev.1.3 section 4.5.19) */ t->driver = "LPC8N04"; @@ -152,7 +153,7 @@ lpc11xx_probe(target *t) /* UM11074/ Flash controller/15.2: The two topmost sectors * contain the initialization code and IAP firmware. * Do not touch the! */ - lpc11xx_add_flash(t, 0x00000000, 0x7800, 0x400, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x7800, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC8N04"); return true; } @@ -167,7 +168,7 @@ lpc11xx_probe(target *t) case 0x00008024: /* 802M001JHI33 */ t->driver = "LPC802"; target_add_ram(t, 0x10000000, 0x800); - lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x); + lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_84x, 2); target_add_commands(t, lpc11xx_cmd_list, "LPC802"); return true; case 0x00008040: /* 804M101JBD64 */ @@ -177,7 +178,7 @@ lpc11xx_probe(target *t) case 0x00008044: /* 804M101JHI33 */ t->driver = "LPC804"; target_add_ram(t, 0x10000000, 0x1000); - lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x); + lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_84x, 2); target_add_commands(t, lpc11xx_cmd_list, "LPC804"); return true; case 0x00008100: /* LPC810M021FN8 */ @@ -187,7 +188,7 @@ lpc11xx_probe(target *t) case 0x00008122: /* LPC812M101JDH20 / LPC812M101JTB16 */ t->driver = "LPC81x"; target_add_ram(t, 0x10000000, 0x1000); - lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC81x"); return true; case 0x00008221: /* LPC822M101JHI33 */ @@ -196,19 +197,19 @@ lpc11xx_probe(target *t) case 0x00008242: /* LPC824M201JDH20 */ t->driver = "LPC82x"; target_add_ram(t, 0x10000000, 0x2000); - lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC82x"); return true; case 0x00008322: /* LPC832M101FDH20 */ t->driver = "LPC832"; target_add_ram(t, 0x10000000, 0x1000); - lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x4000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC832"); return true; case 0x00008341: /* LPC8341201FHI33 */ t->driver = "LPC834"; target_add_ram(t, 0x10000000, 0x1000); - lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x8000, 0x400, IAP_ENTRY_MOST, 0); target_add_commands(t, lpc11xx_cmd_list, "LPC834"); return true; case 0x00008441: @@ -217,7 +218,7 @@ lpc11xx_probe(target *t) case 0x00008444: t->driver = "LPC844"; target_add_ram(t, 0x10000000, 0x2000); - lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x); + lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0); return true; case 0x00008451: case 0x00008452: @@ -225,7 +226,7 @@ lpc11xx_probe(target *t) case 0x00008454: t->driver = "LPC845"; target_add_ram(t, 0x10000000, 0x4000); - lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x); + lpc11xx_add_flash(t, 0x00000000, 0x10000, 0x400, IAP_ENTRY_84x, 0); return true; case 0x0003D440: /* LPC11U34/311 */ case 0x0001cc40: /* LPC11U34/421 */ @@ -237,13 +238,13 @@ lpc11xx_probe(target *t) case 0x00007C40: /* LPC11U37FBD64/501 */ t->driver = "LPC11U3x"; target_add_ram(t, 0x10000000, 0x2000); - lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); return true; case 0x00040070: /* LPC1114/333 */ case 0x00050080: /* lpc1115XL */ t->driver = "LPC1100XL"; target_add_ram(t, 0x10000000, 0x2000); - lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST); + lpc11xx_add_flash(t, 0x00000000, 0x20000, 0x1000, IAP_ENTRY_MOST, 0); return true; } if (idcode) { diff --git a/src/target/lpc_common.c b/src/target/lpc_common.c index bfb5c8ee..7b6b2efc 100644 --- a/src/target/lpc_common.c +++ b/src/target/lpc_common.c @@ -70,6 +70,9 @@ char *iap_error[] = { "Page is invalid", }; +static int lpc_flash_write(struct target_flash *tf, + target_addr dest, const void *src, size_t len); + struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length) { struct lpc_flash *lf = calloc(1, sizeof(*lf)); @@ -164,43 +167,80 @@ static uint8_t lpc_sector_for_addr(struct lpc_flash *f, uint32_t addr) return f->base_sector + (addr - f->f.start) / f->f.blocksize; } +#define LPX80X_SECTOR_SIZE 0x400 +#define LPX80X_PAGE_SIZE 0x40 + int lpc_flash_erase(struct target_flash *tf, target_addr addr, size_t len) { struct lpc_flash *f = (struct lpc_flash *)tf; uint32_t start = lpc_sector_for_addr(f, addr); uint32_t end = lpc_sector_for_addr(f, addr + len - 1); + uint32_t last_full_sector = end; if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, start, end, f->bank)) return -1; - /* and now erase them */ - if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, end, CPU_CLK_KHZ, f->bank)) - return -2; + /* Only LPC80x has reserved pages!*/ + if (f->reserved_pages && ((addr + len) >= tf->length - 0x400) ) { + last_full_sector -= 1; + } + if (start >= last_full_sector) { + /* Sector erase */ + if (lpc_iap_call(f, NULL, IAP_CMD_ERASE, start, last_full_sector, CPU_CLK_KHZ, f->bank)) + return -2; - /* check erase ok */ - if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, end, f->bank)) - return -3; + /* check erase ok */ + if (lpc_iap_call(f, NULL, IAP_CMD_BLANKCHECK, start, last_full_sector, f->bank)) + return -3; + } + if (last_full_sector != end) { + uint32_t page_start = (addr + len - LPX80X_SECTOR_SIZE) / LPX80X_PAGE_SIZE; + uint32_t page_end = page_start + LPX80X_SECTOR_SIZE/LPX80X_PAGE_SIZE - 1 - f->reserved_pages; + if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, end, end, f->bank)) + return -1; + if (lpc_iap_call(f, NULL, IAP_CMD_ERASE_PAGE, page_start, page_end, CPU_CLK_KHZ, f->bank)) + return -2; + /* Blank check omitted!*/ + } return 0; } -int lpc_flash_write(struct target_flash *tf, +static int lpc_flash_write(struct target_flash *tf, target_addr dest, const void *src, size_t len) { struct lpc_flash *f = (struct lpc_flash *)tf; /* prepare... */ uint32_t sector = lpc_sector_for_addr(f, dest); - if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, sector, sector, f->bank)) + if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, sector, sector, f->bank)) { + DEBUG_WARN("Prepare failed\n"); return -1; - - /* Write payload to target ram */ + } uint32_t bufaddr = ALIGN(f->iap_ram + sizeof(struct flash_param), 4); target_mem_write(f->f.t, bufaddr, src, len); - - /* set the destination address and program */ - if (lpc_iap_call(f, NULL, IAP_CMD_PROGRAM, dest, bufaddr, len, CPU_CLK_KHZ)) - return -2; - + /* Only LPC80x has reserved pages!*/ + if ((!f->reserved_pages) || ((dest + len) <= (tf->length - len))) { + /* Write payload to target ram */ + /* set the destination address and program */ + if (lpc_iap_call(f, NULL, IAP_CMD_PROGRAM, dest, bufaddr, len, CPU_CLK_KHZ)) + return -2; + } else { + /* On LPC80x, write top sector in pages. + * Silently ignore write to the 2 reserved pages at top!*/ + len -= 0x40 * f->reserved_pages; + while (len) { + if (lpc_iap_call(f, NULL, IAP_CMD_PREPARE, sector, sector, f->bank)) { + DEBUG_WARN("Prepare failed\n"); + return -1; + } + /* set the destination address and program */ + if (lpc_iap_call(f, NULL, IAP_CMD_PROGRAM, dest, bufaddr, LPX80X_PAGE_SIZE, CPU_CLK_KHZ)) + return -2; + dest += LPX80X_PAGE_SIZE; + bufaddr += LPX80X_PAGE_SIZE; + len -= LPX80X_PAGE_SIZE; + } + } return 0; } diff --git a/src/target/lpc_common.h b/src/target/lpc_common.h index d5a4efc3..5d17eef9 100644 --- a/src/target/lpc_common.h +++ b/src/target/lpc_common.h @@ -72,6 +72,7 @@ struct lpc_flash { struct target_flash f; uint8_t base_sector; uint8_t bank; + uint8_t reserved_pages; /* Info filled in by specific driver */ void (*wdt_kick)(target *t); uint32_t iap_entry; @@ -82,8 +83,6 @@ struct lpc_flash { struct lpc_flash *lpc_add_flash(target *t, target_addr addr, size_t length); enum iap_status lpc_iap_call(struct lpc_flash *f, void *result, enum iap_cmd cmd, ...); int lpc_flash_erase(struct target_flash *f, target_addr addr, size_t len); -int lpc_flash_write(struct target_flash *f, - target_addr dest, const void *src, size_t len); int lpc_flash_write_magic_vect(struct target_flash *f, target_addr dest, const void *src, size_t len); From c0437e7b25581800e0f8e0ccf1dd386de0004f60 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Sun, 30 May 2021 23:12:44 +0200 Subject: [PATCH 23/26] bmp_serial: Autodetect more BMP string variants. --- src/platforms/hosted/Makefile.inc | 2 +- src/platforms/hosted/bmp_serial.c | 86 +++++++++++++++++-------------- 2 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc index b73f6d75..20363583 100644 --- a/src/platforms/hosted/Makefile.inc +++ b/src/platforms/hosted/Makefile.inc @@ -8,7 +8,7 @@ CFLAGS +=-I ./target -I./platforms/pc # be useful to minimize external dependencies, and make building on # windows systems easier. HOSTED_BMP_ONLY ?= 0 -CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY) +CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY) -Wno-format-truncation ifneq (, $(findstring linux, $(SYS))) SRC += serial_unix.c diff --git a/src/platforms/hosted/bmp_serial.c b/src/platforms/hosted/bmp_serial.c index 4f0333cc..c04807b9 100644 --- a/src/platforms/hosted/bmp_serial.c +++ b/src/platforms/hosted/bmp_serial.c @@ -27,8 +27,10 @@ void bmp_ident(bmp_info_t *info) { - (void) info; + if (!info) + return; DEBUG_INFO("BMP hosted (BMP Only) %s\n", FIRMWARE_VERSION); + DEBUG_INFO("Using:\n %s %s %s\n", info->manufacturer, info->version, info->serial); } void libusb_exit_function(bmp_info_t *info) {(void)info;}; @@ -152,6 +154,10 @@ print_probes_info: } #else +/* Old ID: Black_Sphere_Technologies_Black_Magic_Probe_BFE4D6EC-if00 + * Recent: Black_Sphere_Technologies_Black_Magic_Probe_v1.7.1-212-g212292ab_7BAE7AB8-if00 + * usb-Black_Sphere_Technologies_Black_Magic_Probe__SWLINK__v1.7.1-155-gf55ad67b-dirty_DECB8811-if00 + */ #define BMP_IDSTRING "usb-Black_Sphere_Technologies_Black_Magic_Probe" #define DEVICE_BY_ID "/dev/serial/by-id/" @@ -170,41 +176,45 @@ static int scan_linux_id(char *name, char *type, char *version, char *serial) DEBUG_WARN("Unexpected end\n"); return -1; } - char *p = strchr(name, '_'); - if (!p) { - DEBUG_WARN("type not found\n"); - return -1; + char *p = name; + char *delims[4] = {0,0,0,0}; + int underscores = 0; + while (*p) { + if (*p == '_') { + while (p[1] == '_') + p++; /* remove multiple underscores */ + if (underscores > 2) + return -1; + delims[underscores] = p; + underscores ++; + } + p++; } - strncpy(type, name, p - name); - type[p - name] = 0; - name = p; - while (*name != 'v') - name++; - if (!*name) { - DEBUG_WARN("Unexpected end after type\n"); - return -1; + if (underscores == 0) { /* Old BMP native */ + int res; + res = sscanf(name, "%8s-if00", serial); + if (res != 1) + return -1; + strcpy(type, "Native"); + strcpy(version, "Unknown"); + } else if (underscores == 2) { + strncpy(type, name, delims[0] - name - 1); + strncpy(version, delims[0] + 1, delims[1] - delims[0] - 1); + int res = sscanf(delims[1] + 1, "%8s-if00", serial); + if (!res) + return -1; + } else { + int res = sscanf(delims[0] + 1, "%8s-if00", serial); + if (!res) + return -1; + if (name[0] == 'v') { + strcpy(type, "Unknown"); + strncpy(version, name, delims[0] - name - 1); + } else { + strncpy(type, name, delims[0] - name); + strcpy(type, "Unknown"); + } } - p = strchr(name, '_'); - if (!p) { - DEBUG_WARN("version not found\n"); - return -1; - } - strncpy(version, name, p - name); - version[p - name] = 0; - name = p; - while (*name == '_') - name++; - if (!*name) { - DEBUG_WARN("Unexpected end after version\n"); - return -1; - } - p = strchr(name, '-'); - if (!p) { - DEBUG_WARN("Serial not found\n"); - return -1; - } - strncpy(serial, name, p - name); - serial[p - name] = 0; return 0; } @@ -232,8 +242,9 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) (cl_opts->opt_position && cl_opts->opt_position == i)) { /* With serial number given and partial match, we are done!*/ strncpy(info->serial, serial, sizeof(info->serial)); - strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer)); - strncpy(info->product, type, sizeof(info->product)); + int res = snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type); + if (res) + DEBUG_WARN("Overflow\n"); strncpy(info->version, version, sizeof(info->version)); found_bmps = 1; break; @@ -263,8 +274,7 @@ int find_debuggers(BMP_CL_OPTIONS_t *cl_opts, bmp_info_t *info) strncpy(info->serial, serial, sizeof(info->serial)); found_bmps = 1; strncpy(info->serial, serial, sizeof(info->serial)); - strncpy(info->manufacturer, "BMP", sizeof(info->manufacturer)); - strncpy(info->product, type, sizeof(info->product)); + snprintf(info->manufacturer, sizeof(info->manufacturer), "Black Magic Probe (%s)", type); strncpy(info->version, version, sizeof(info->version)); break; } else if (found_bmps > 0) { From de83dbb7e2fccdc336ef56ba5f8ff3999336462b Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 1 Jun 2021 14:05:36 +0200 Subject: [PATCH 24/26] cl-utils: Fix bug introduced with 5288eef6171b9cff194fbeb087bc942bad08d9db Always use the file size for write and verify. --- src/platforms/pc/cl_utils.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c index 145dccba..fc34496f 100644 --- a/src/platforms/pc/cl_utils.c +++ b/src/platforms/pc/cl_utils.c @@ -418,7 +418,10 @@ int cl_execute(BMP_CL_OPTIONS_t *opt) } if (opt->opt_flash_start == 0xffffffff) opt->opt_flash_start = lowest_flash_start; - if (opt->opt_flash_size == 0xffffffff) + if ((opt->opt_flash_size == 0xffffffff) && + (opt->opt_mode != BMP_MODE_FLASH_WRITE) && + (opt->opt_mode != BMP_MODE_FLASH_VERIFY) && + (opt->opt_mode != BMP_MODE_FLASH_VERIFY)) opt->opt_flash_size = lowest_flash_size; if (opt->opt_mode == BMP_MODE_SWJ_TEST) { switch (t->core[0]) { From 1b49823f646919c80aa67057e37486fc69164268 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 1 Jun 2021 16:54:39 +0200 Subject: [PATCH 25/26] Fix hosted compile on MacOS. hidapi-libusb has a different name --- src/platforms/hosted/Makefile.inc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc index 20363583..4ac6ac25 100644 --- a/src/platforms/hosted/Makefile.inc +++ b/src/platforms/hosted/Makefile.inc @@ -12,6 +12,7 @@ CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY) -Wno-format-truncation ifneq (, $(findstring linux, $(SYS))) SRC += serial_unix.c +HIDAPILIB = hidapi-libusb ifeq ($(ASAN), 1) CFLAGS += -fsanitize=address LDFLAGS += -lasan @@ -36,6 +37,7 @@ SRC += serial_unix.c LDFLAGS += -lhidapi LDFLAGS += -framework CoreFoundation CFLAGS += -Ihidapi/hidapi +HIDAPILIB = hidapi endif ifneq ($(HOSTED_BMP_ONLY), 1) @@ -51,8 +53,8 @@ ifneq ($(HOSTED_BMP_ONLY), 1) ifneq (, $(findstring mingw, $(SYS))) SRC += hid.c else - CFLAGS += $(shell pkg-config --cflags hidapi-libusb) - LDFLAGS += $(shell pkg-config --libs hidapi-libusb) + CFLAGS += $(shell pkg-config --cflags $(HIDAPILIB)) + LDFLAGS += $(shell pkg-config --libs $(HIDAPILIB)) endif endif From 2a0d608b07487300a63908baa62e73a51a11e811 Mon Sep 17 00:00:00 2001 From: Uwe Bonnes Date: Tue, 1 Jun 2021 18:06:22 +0200 Subject: [PATCH 26/26] hosted: Fix last commit -Wno-format-truncation may not be understood by all systems --- src/platforms/hosted/Makefile.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc index 4ac6ac25..cd0ce561 100644 --- a/src/platforms/hosted/Makefile.inc +++ b/src/platforms/hosted/Makefile.inc @@ -8,13 +8,13 @@ CFLAGS +=-I ./target -I./platforms/pc # be useful to minimize external dependencies, and make building on # windows systems easier. HOSTED_BMP_ONLY ?= 0 -CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY) -Wno-format-truncation +CFLAGS += -DHOSTED_BMP_ONLY=$(HOSTED_BMP_ONLY) ifneq (, $(findstring linux, $(SYS))) SRC += serial_unix.c HIDAPILIB = hidapi-libusb ifeq ($(ASAN), 1) -CFLAGS += -fsanitize=address +CFLAGS += -fsanitize=address -Wno-format-truncation LDFLAGS += -lasan endif else ifneq (, $(findstring mingw, $(SYS)))