xdebug

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit de60c86b2ae817590c82b62847e3f23054794eb2
parent fc068d707ecc405ed27cc3d5044b270ec43147e3
Author: Brian Swetland <swetland@frotz.net>
Date:   Fri,  3 Mar 2023 16:28:04 -0800

speed up block memory transfers

With the clock set at 4MHz (measures at ~3.3MHz on the scope)
on an LPC MCU-LINK with 512byte packets, we see about 74KB/s
for the simple bulk reads.  Using auto increment in the CSW
and removing almost all MAP.TAR writes, we get up to 202KB/s.

It may be possible to get somewhat better efficiency by using
DAP_TransferBlock instead of DAP_Transfer, but I suspect that's
not going to have much impact on high speed USB devices like
this one.  On full speed devices, could be significant.

Diffstat:
Msrc/transport-arm-debug.c | 52+++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/src/transport-arm-debug.c b/src/transport-arm-debug.c @@ -55,6 +55,7 @@ int dc_mem_wr32(DC* dc, uint32_t addr, uint32_t val) { +#if 0 int dc_mem_rd_words(dctx_t* dc, uint32_t addr, uint32_t num, uint32_t* ptr) { while (num > 0) { dc_q_mem_rd32(dc, addr, ptr); @@ -74,6 +75,55 @@ int dc_mem_wr_words(dctx_t* dc, uint32_t addr, uint32_t num, const uint32_t* ptr } return dc_q_exec(dc); } +#else +// some implementations support >10 bits, but 10 is the minimum required +// by spec (and some targets like rp2040 are limited to this) +#define WRAPSIZE 0x400 +#define WRAPMASK (WRAPSIZE - 1) +int dc_mem_rd_words(dctx_t* dc, uint32_t addr, uint32_t num, uint32_t* ptr) { + while (num > 0) { + uint32_t xfer = (WRAPSIZE - (addr & WRAPMASK)) / 4; + if (xfer > num) { + xfer = num; + } + dc_q_init(dc); + dc_q_map_csw_wr(dc, MAP_CSW_SZ_32 | MAP_CSW_INC_SINGLE | MAP_CSW_DEVICE_EN); + dc_q_map_tar_wr(dc, addr); + num -= xfer; + addr += xfer * 4; + while (xfer > 0) { + dc_q_ap_rd(dc, MAP_DRW, ptr++); + xfer--; + } + int r = dc_q_exec(dc); + if (r != DC_OK) { + return r; + } + } + return DC_OK; +} - +int dc_mem_wr_words(dctx_t* dc, uint32_t addr, uint32_t num, const uint32_t* ptr) { + while (num > 0) { + uint32_t xfer = (WRAPSIZE - (addr & WRAPMASK)) / 4; + if (xfer > num) { + xfer = num; + } + dc_q_init(dc); + dc_q_map_csw_wr(dc, MAP_CSW_SZ_32 | MAP_CSW_INC_SINGLE | MAP_CSW_DEVICE_EN); + dc_q_map_tar_wr(dc, addr); + num -= xfer; + addr += xfer * 4; + while (xfer > 0) { + dc_q_ap_wr(dc, MAP_DRW, *ptr++); + xfer--; + } + int r = dc_q_exec(dc); + if (r != DC_OK) { + return r; + } + } + return DC_OK; +} +#endif