From 9acf539c70e35643be2dc63b0789ff86d878615a Mon Sep 17 00:00:00 2001 From: anton Date: Wed, 26 May 2021 23:04:39 +0500 Subject: [PATCH] Optimizing the half page write fallback --- src/common.c | 23 ++++++++++++----------- src/stlink-lib/flash_loader.c | 10 +++++++--- src/stlink-lib/usb.c | 32 +++++++++++++++++++------------- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/src/common.c b/src/common.c index d2387d08b..6d81bf743 100644 --- a/src/common.c +++ b/src/common.c @@ -2636,20 +2636,21 @@ int stlink_fread(stlink_t *sl, const char *path, bool is_ihex, int write_buffer_to_sram(stlink_t *sl, flash_loader_t *fl, const uint8_t *buf, size_t size) { // write the buffer right after the loader + int ret = 0; size_t chunk = size & ~0x3; size_t rem = size & 0x3; if (chunk) { memcpy(sl->q_buf, buf, chunk); - stlink_write_mem32(sl, fl->buf_addr, chunk); + ret = stlink_write_mem32(sl, fl->buf_addr, chunk); } - if (rem) { + if (rem && !ret) { memcpy(sl->q_buf, buf + chunk, rem); - stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); + ret = stlink_write_mem8(sl, (fl->buf_addr) + (uint32_t)chunk, rem); } - return (0); + return (ret); } uint32_t calculate_F4_sectornum(uint32_t flashaddr) { @@ -3075,7 +3076,7 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, uint32_t len, uint32_t pagesize) { unsigned int count, off; unsigned int num_half_pages = len / pagesize; - uint32_t val, data; + uint32_t val; uint32_t flash_regs_base = get_stm32l0_flash_base(sl); flash_loader_t fl; bool use_loader = true; @@ -3102,10 +3103,10 @@ int stm32l1_write_half_pages(stlink_t *sl, stm32_addr_t addr, uint8_t *base, } if (!use_loader) { ret = 0; - for (off = 0; off < pagesize && !ret; off += 4) - { - write_uint32((unsigned char *)&data, *(uint32_t *)(base + count * pagesize + off)); - ret = stlink_write_debug32(sl, addr + count * pagesize + off, data); + for (off = 0; off < pagesize && !ret; off += 64) { + size_t chunk = (pagesize - off > 64) ? 64 : pagesize - off; + memcpy(sl->q_buf, base + count * pagesize + off, chunk); + ret = stlink_write_mem32(sl, addr + count * pagesize + off, chunk); } } @@ -3237,8 +3238,8 @@ int stlink_flashloader_start(stlink_t *sl, flash_loader_t *fl) { /* Flash loader initialisation */ if (stlink_flash_loader_init(sl, fl) == -1) { - ELOG("stlink_flash_loader_init() == -1\n"); - return (-1); + // L0/L1 have fallback to soft write + WLOG("stlink_flash_loader_init() == -1\n"); } } else if ((sl->flash_type == STLINK_FLASH_TYPE_F0) || (sl->flash_type == STLINK_FLASH_TYPE_F1_XL)) { diff --git a/src/stlink-lib/flash_loader.c b/src/stlink-lib/flash_loader.c index d492716db..355223146 100644 --- a/src/stlink-lib/flash_loader.c +++ b/src/stlink-lib/flash_loader.c @@ -14,7 +14,13 @@ #define STM32F0_WDG_KR_KEY_RELOAD 0xAAAA -/* DO NOT MODIFY SOURCECODE DIRECTLY, EDIT ASSEMBLY FILES INSTEAD */ +/* !!! + * !!! DO NOT MODIFY FLASH LOADERS DIRECTLY! + * !!! + * + * Edit assembly files in the '/flashloaders' instead. The sizes of binary + * flash loaders must be aligned by 4 (it's written by stlink_write_mem32) + */ /* flashloaders/stm32f0.s -- compiled with thumb2 */ static const uint8_t loader_code_stm32vl[] = { @@ -322,9 +328,7 @@ int stlink_flash_loader_run(stlink_t *sl, flash_loader_t* fl, stm32_addr_t targe DLOG("Running flash loader, write address:%#x, size: %u\n", target, (unsigned int)size); - // TODO: This can never return -1 if (write_buffer_to_sram(sl, fl, buf, size) == -1) { - // IMPOSSIBLE! ELOG("write_buffer_to_sram() == -1\n"); return(-1); } diff --git a/src/stlink-lib/usb.c b/src/stlink-lib/usb.c index 1d50bb202..5e5f042d5 100644 --- a/src/stlink-lib/usb.c +++ b/src/stlink-lib/usb.c @@ -122,16 +122,16 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, retry++; continue; } - WLOG("%s wait error (0x%02X)\n", cmd, rxbuf[0]); + DLOG("%s wait error (0x%02X)\n", cmd, rxbuf[0]); break; - case STLINK_DEBUG_ERR_FAULT: WLOG("%s response fault\n", cmd); break; - case STLINK_DEBUG_ERR_AP_FAULT: WLOG("%s access port fault\n", cmd); break; - case STLINK_DEBUG_ERR_DP_FAULT: WLOG("%s debug port fault\n", cmd); break; - case STLINK_DEBUG_ERR_AP_ERROR: WLOG("%s access port error\n", cmd); break; - case STLINK_DEBUG_ERR_DP_ERROR: WLOG("%s debug port error\n", cmd); break; - case STLINK_DEBUG_ERR_WRITE_VERIFY: WLOG("%s verification error\n", cmd); break; - case STLINK_DEBUG_ERR_WRITE: WLOG("%s write error\n", cmd); break; - default: WLOG("%s error (0x%02X)\n", cmd, rxbuf[0]); break; + case STLINK_DEBUG_ERR_FAULT: DLOG("%s response fault\n", cmd); break; + case STLINK_DEBUG_ERR_AP_FAULT: DLOG("%s access port fault\n", cmd); break; + case STLINK_DEBUG_ERR_DP_FAULT: DLOG("%s debug port fault\n", cmd); break; + case STLINK_DEBUG_ERR_AP_ERROR: DLOG("%s access port error\n", cmd); break; + case STLINK_DEBUG_ERR_DP_ERROR: DLOG("%s debug port error\n", cmd); break; + case STLINK_DEBUG_ERR_WRITE_VERIFY: DLOG("%s verification error\n", cmd); break; + case STLINK_DEBUG_ERR_WRITE: DLOG("%s write error\n", cmd); break; + default: DLOG("%s error (0x%02X)\n", cmd, rxbuf[0]); break; } return(-1); @@ -149,7 +149,7 @@ ssize_t send_recv(struct stlink_libusb* handle, int terminate, t = libusb_bulk_transfer(handle->usb_handle, handle->ep_rep, sg_buf, 13, &res, 3000); if (t) { - ELOG("stlink: %s read storage failed: %s\n", cmd, libusb_error_name(t)); + ELOG("%s read storage failed: %s\n", cmd, libusb_error_name(t)); return(-1); } @@ -306,6 +306,12 @@ int _stlink_usb_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) { unsigned char* const cmd = sl->c_buf; int i, ret; + if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || + (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { + ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len); + return (-1); + } + i = fill_command(sl, SG_DXFER_TO_DEV, len); cmd[i++] = STLINK_DEBUG_COMMAND; cmd[i++] = STLINK_DEBUG_WRITEMEM_32BIT; @@ -330,7 +336,7 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { if ((sl->version.jtag_api < STLINK_JTAG_API_V3 && len > 64) || (sl->version.jtag_api >= STLINK_JTAG_API_V3 && len > 512)) { - ELOG("WRITEMEM_32BIT: bulk packet limits exceeded (data len %d byte)\n", len); + ELOG("WRITEMEM_8BIT: bulk packet limits exceeded (data len %d byte)\n", len); return (-1); } @@ -339,11 +345,11 @@ int _stlink_usb_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) { cmd[i++] = STLINK_DEBUG_WRITEMEM_8BIT; write_uint32(&cmd[i], addr); write_uint16(&cmd[i + 4], len); - ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_32BIT"); + ret = send_only(slu, 0, cmd, slu->cmd_len, "WRITEMEM_8BIT"); if (ret == -1) { return(ret); } - ret = send_only(slu, 1, data, len, "WRITEMEM_32BIT"); + ret = send_only(slu, 1, data, len, "WRITEMEM_8BIT"); if (ret == -1) { return(ret); }