From 48b49d3e2797310a7884c02676e49e12d905dee0 Mon Sep 17 00:00:00 2001 From: Christophe Priouzeau Date: Mon, 6 Jun 2022 15:17:50 +0200 Subject: [PATCH] OPENOCD: 0.11.0 Signed-off-by: Christophe Priouzeau Change-Id: Ia1f287c846227ddad1bd023637f57a05d1d4e6d6 --- recipes-devtools/openocd/openocd-stm32mp.inc | 12 +- .../0001-rebase-on-v0.11.0-rc2.patch | 989 ------------------ .../openocd/openocd-stm32mp_0.11.0.bb | 20 +- 3 files changed, 18 insertions(+), 1003 deletions(-) delete mode 100644 recipes-devtools/openocd/openocd-stm32mp/0001-rebase-on-v0.11.0-rc2.patch diff --git a/recipes-devtools/openocd/openocd-stm32mp.inc b/recipes-devtools/openocd/openocd-stm32mp.inc index 044fb2d..20da7cd 100644 --- a/recipes-devtools/openocd/openocd-stm32mp.inc +++ b/recipes-devtools/openocd/openocd-stm32mp.inc @@ -4,21 +4,20 @@ RDEPENDS:${PN} += "libusb1 hidapi-stm32mp" inherit pkgconfig autotools-brokensep gettext -SRC_URI = " \ - git://repo.or.cz/git2cl.git;destsuffix=git/tools/git2cl;name=git2cl;branch=master \ - git://github.com/msteveb/jimtcl;protocol=https;destsuffix=git/jimtcl;name=jimtcl;branch=master \ - git://repo.or.cz/libjaylink.git;destsuffix=git/src/jtag/drivers/libjaylink;name=libjaylink;branch=master \ +SRC_URI:append = " \ + git://git.savannah.nongnu.org/git/git2cl.git;protocol=https;;destsuffix=git/tools/git2cl;nobranch=1;name=git2cl \ + git://github.com/msteveb/jimtcl.git;protocol=https;destsuffix=git/jimtcl;nobranch=1;name=jimtcl \ + git://gitlab.zapb.de/libjaylink/libjaylink.git;protocol=https;destsuffix=git/src/jtag/drivers/libjaylink;nobranch=1;name=libjaylink \ " SRCREV_git2cl = "8373c9f74993e218a08819cbcdbab3f3564bbeba" -SRCREV_jimtcl = "0aa0fb4e3a38d38a49de9eb585d93d63a370dcf6" +SRCREV_jimtcl = "3920cedd1cdd4702720773f0637b780f79be6158" SRCREV_libjaylink = "9aa7a5957c07bb6e862fc1a6d3153d109c7407e4" S = "${WORKDIR}/git" BBCLASSEXTEND += "native nativesdk" -DEPENDS += "hidapi-stm32mp" DEPENDS:class-native = "hidapi-stm32mp-native" DEPENDS:class-nativesdk = "nativesdk-hidapi-stm32mp" @@ -39,7 +38,6 @@ EXTRA_OECONF = " \ CCACHE_DISABLE = "1" do_configure() { - export RANLIB="ranlib" ./bootstrap nosubmodule oe_runconf ${EXTRA_OECONF} } diff --git a/recipes-devtools/openocd/openocd-stm32mp/0001-rebase-on-v0.11.0-rc2.patch b/recipes-devtools/openocd/openocd-stm32mp/0001-rebase-on-v0.11.0-rc2.patch deleted file mode 100644 index e54fea8..0000000 --- a/recipes-devtools/openocd/openocd-stm32mp/0001-rebase-on-v0.11.0-rc2.patch +++ /dev/null @@ -1,989 +0,0 @@ -From 4b8f01fdcbbb47fe912a01ff33308d59adaae7cd Mon Sep 17 00:00:00 2001 -From: Antonio Borneo -Date: Mon, 11 Jan 2021 14:36:24 +0100 -Subject: [PATCH] rebase on v0.11.0-rc2 ---- - src/helper/log.h | 1 + - src/jtag/drivers/stlink_usb.c | 567 +++++++++++++++++++---- - src/target/arm_adi_v5.c | 28 ++ - src/target/arm_adi_v5.h | 22 + - tcl/board/stm32mp15x_ev1_jlink_jtag.cfg | 9 + - tcl/board/stm32mp15x_ev1_jlink_swd.cfg | 9 + - tcl/board/stm32mp15x_ev1_stlink_jtag.cfg | 9 + - tcl/board/stm32mp15x_ev1_stlink_swd.cfg | 9 + - tcl/board/stm32mp15x_ev1_ulink2_jtag.cfg | 9 + - tcl/board/stm32mp15x_ev1_ulink2_swd.cfg | 9 + - 10 files changed, 577 insertions(+), 95 deletions(-) - -diff --git a/src/helper/log.h b/src/helper/log.h -index f2ba0daa6..f91925919 100644 ---- a/src/helper/log.h -+++ b/src/helper/log.h -@@ -155,6 +155,7 @@ extern int debug_level; - /* ERROR_TIMEOUT is already taken by winerror.h. */ - #define ERROR_TIMEOUT_REACHED (-6) - #define ERROR_NOT_IMPLEMENTED (-7) -+#define ERROR_OP_NOT_SUPPORTED (-8) - - - #endif /* OPENOCD_HELPER_LOG_H */ -diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c -index 4545bcba0..b04611144 100644 ---- a/src/jtag/drivers/stlink_usb.c -+++ b/src/jtag/drivers/stlink_usb.c -@@ -85,11 +85,22 @@ - #define STLINK_MAX_RW8 (64) - #define STLINKV3_MAX_RW8 (512) - -+/* -+ * FIXME: this definition + comment should be moved in a generic header file -+ * ARM IHI 0031E: TAR Automatic address increment is only guaranteed to -+ * operate on the 10 least significant bits of the address -+ */ -+#define TAR_AUTOINCR_BLOCK (1 << 10) -+ - /* "WAIT" responses will be retried (with exponential backoff) at - * most this many times before failing to caller. - */ - #define MAX_WAIT_RETRIES 8 - -+/* HLA is currently limited at AP#0 and no control on CSW */ -+#define STLINK_HLA_AP_NUM 0 -+#define STLINK_HLA_CSW 0 -+ - enum stlink_jtag_api_version { - STLINK_JTAG_API_V1 = 1, - STLINK_JTAG_API_V2, -@@ -286,6 +297,10 @@ struct stlink_usb_handle_s { - #define STLINK_DEBUG_APIV2_INIT_AP 0x4B - #define STLINK_DEBUG_APIV2_CLOSE_AP_DBG 0x4C - -+#define STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC 0x50 -+ -+#define STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC 0x54 -+ - #define STLINK_APIV3_SET_COM_FREQ 0x61 - #define STLINK_APIV3_GET_COM_FREQ 0x62 - -@@ -325,6 +340,9 @@ struct stlink_usb_handle_s { - /* aliases */ - #define STLINK_F_HAS_TARGET_VOLT STLINK_F_HAS_TRACE - #define STLINK_F_HAS_FPU_REG STLINK_F_HAS_GETLASTRWSTATUS2 -+#define STLINK_F_HAS_MEM_WR_NO_INC STLINK_F_HAS_MEM_16BIT -+#define STLINK_F_HAS_MEM_RD_NO_INC STLINK_F_HAS_DPBANKSEL -+#define STLINK_F_HAS_CSW STLINK_F_HAS_DPBANKSEL - - #define STLINK_REGSEL_IS_FPU(x) ((x) > 0x1F) - -@@ -1029,6 +1047,7 @@ static int stlink_usb_version(void *handle) - flags |= STLINK_F_QUIRK_JTAG_DP_READ; - - /* API to read/write memory at 16 bit from J26 */ -+ /* API to write memory without address increment from J26 */ - if (h->version.jtag >= 26) - flags |= STLINK_F_HAS_MEM_16BIT; - -@@ -1041,6 +1060,8 @@ static int stlink_usb_version(void *handle) - flags |= STLINK_F_FIX_CLOSE_AP; - - /* Banked regs (DPv1 & DPv2) support from V2J32 */ -+ /* API to read memory without address increment from V2J32 */ -+ /* Memory R/W supports CSW from V2J32 */ - if (h->version.jtag >= 32) - flags |= STLINK_F_HAS_DPBANKSEL; - -@@ -1062,6 +1083,7 @@ static int stlink_usb_version(void *handle) - flags |= STLINK_F_HAS_DAP_REG; - - /* API to read/write memory at 16 bit */ -+ /* API to write memory without address increment */ - flags |= STLINK_F_HAS_MEM_16BIT; - - /* API required to init AP before any AP access */ -@@ -1071,6 +1093,8 @@ static int stlink_usb_version(void *handle) - flags |= STLINK_F_FIX_CLOSE_AP; - - /* Banked regs (DPv1 & DPv2) support from V3J2 */ -+ /* API to read memory without address increment from V3J2 */ -+ /* Memory R/W supports CSW from V3J2 */ - if (h->version.jtag >= 2) - flags |= STLINK_F_HAS_DPBANKSEL; - -@@ -2111,8 +2135,8 @@ static int stlink_usb_get_rw_status(void *handle) - } - - /** */ --static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, -- uint8_t *buffer) -+static int stlink_usb_read_mem8(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, uint8_t *buffer) - { - int res; - uint16_t read_len = len; -@@ -2134,6 +2158,9 @@ static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; - - /* we need to fix read length for single bytes */ - if (read_len == 1) -@@ -2150,8 +2177,8 @@ static int stlink_usb_read_mem8(void *handle, uint32_t addr, uint16_t len, - } - - /** */ --static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, -- const uint8_t *buffer) -+static int stlink_usb_write_mem8(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, const uint8_t *buffer) - { - int res; - struct stlink_usb_handle_s *h = handle; -@@ -2172,6 +2199,9 @@ static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; - - res = stlink_usb_xfer_noerrcheck(handle, buffer, len); - -@@ -2182,8 +2212,8 @@ static int stlink_usb_write_mem8(void *handle, uint32_t addr, uint16_t len, - } - - /** */ --static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, -- uint8_t *buffer) -+static int stlink_usb_read_mem16(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, uint8_t *buffer) - { - int res; - struct stlink_usb_handle_s *h = handle; -@@ -2207,6 +2237,9 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; - - res = stlink_usb_xfer_noerrcheck(handle, h->databuf, len); - -@@ -2219,8 +2252,8 @@ static int stlink_usb_read_mem16(void *handle, uint32_t addr, uint16_t len, - } - - /** */ --static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, -- const uint8_t *buffer) -+static int stlink_usb_write_mem16(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, const uint8_t *buffer) - { - int res; - struct stlink_usb_handle_s *h = handle; -@@ -2244,6 +2277,9 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; - - res = stlink_usb_xfer_noerrcheck(handle, buffer, len); - -@@ -2254,8 +2290,8 @@ static int stlink_usb_write_mem16(void *handle, uint32_t addr, uint16_t len, - } - - /** */ --static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, -- uint8_t *buffer) -+static int stlink_usb_read_mem32(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, uint8_t *buffer) - { - int res; - struct stlink_usb_handle_s *h = handle; -@@ -2276,6 +2312,9 @@ static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; - - res = stlink_usb_xfer_noerrcheck(handle, h->databuf, len); - -@@ -2288,8 +2327,8 @@ static int stlink_usb_read_mem32(void *handle, uint32_t addr, uint16_t len, - } - - /** */ --static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, -- const uint8_t *buffer) -+static int stlink_usb_write_mem32(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, const uint8_t *buffer) - { - int res; - struct stlink_usb_handle_s *h = handle; -@@ -2310,6 +2349,9 @@ static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, - h->cmdidx += 4; - h_u16_to_le(h->cmdbuf+h->cmdidx, len); - h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; - - res = stlink_usb_xfer_noerrcheck(handle, buffer, len); - -@@ -2319,6 +2361,80 @@ static int stlink_usb_write_mem32(void *handle, uint32_t addr, uint16_t len, - return stlink_usb_get_rw_status(handle); - } - -+static int stlink_usb_read_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, uint8_t *buffer) -+{ -+ int res; -+ struct stlink_usb_handle_s *h = handle; -+ -+ assert(handle != NULL); -+ -+ if (!(h->version.flags & STLINK_F_HAS_MEM_RD_NO_INC)) -+ return ERROR_COMMAND_NOTFOUND; -+ -+ /* data must be a multiple of 4 and word aligned */ -+ if (len % 4 || addr % 4) { -+ LOG_DEBUG("Invalid data alignment"); -+ return ERROR_TARGET_UNALIGNED_ACCESS; -+ } -+ -+ stlink_usb_init_buffer(handle, h->rx_ep, len); -+ -+ h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; -+ h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_READMEM_32BIT_NO_ADDR_INC; -+ h_u32_to_le(h->cmdbuf+h->cmdidx, addr); -+ h->cmdidx += 4; -+ h_u16_to_le(h->cmdbuf+h->cmdidx, len); -+ h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; -+ -+ res = stlink_usb_xfer_noerrcheck(handle, h->databuf, len); -+ if (res != ERROR_OK) -+ return res; -+ -+ memcpy(buffer, h->databuf, len); -+ -+ return stlink_usb_get_rw_status(handle); -+} -+ -+static int stlink_usb_write_mem32_noaddrinc(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint16_t len, const uint8_t *buffer) -+{ -+ int res; -+ struct stlink_usb_handle_s *h = handle; -+ -+ assert(handle != NULL); -+ -+ if (!(h->version.flags & STLINK_F_HAS_MEM_WR_NO_INC)) -+ return ERROR_COMMAND_NOTFOUND; -+ -+ /* data must be a multiple of 4 and word aligned */ -+ if (len % 4 || addr % 4) { -+ LOG_DEBUG("Invalid data alignment"); -+ return ERROR_TARGET_UNALIGNED_ACCESS; -+ } -+ -+ stlink_usb_init_buffer(handle, h->tx_ep, len); -+ -+ h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND; -+ h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_WRITEMEM_32BIT_NO_ADDR_INC; -+ h_u32_to_le(h->cmdbuf+h->cmdidx, addr); -+ h->cmdidx += 4; -+ h_u16_to_le(h->cmdbuf+h->cmdidx, len); -+ h->cmdidx += 2; -+ h->cmdbuf[h->cmdidx++] = ap_num; -+ h_u24_to_le(h->cmdbuf+h->cmdidx, csw >> 8); -+ h->cmdidx += 3; -+ -+ res = stlink_usb_xfer_noerrcheck(handle, buffer, len); -+ if (res != ERROR_OK) -+ return res; -+ -+ return stlink_usb_get_rw_status(handle); -+} -+ - static uint32_t stlink_max_block_size(uint32_t tar_autoincr_block, uint32_t address) - { - uint32_t max_tar_block = (tar_autoincr_block - ((tar_autoincr_block - 1) & address)); -@@ -2327,8 +2443,95 @@ static uint32_t stlink_max_block_size(uint32_t tar_autoincr_block, uint32_t addr - return max_tar_block; - } - -+static int stlink_usb_read_ap_mem(void *handle, uint8_t ap_num, uint32_t csw, -+ uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) -+{ -+ int retval = ERROR_OK; -+ uint32_t bytes_remaining; -+ int retries = 0; -+ struct stlink_usb_handle_s *h = handle; -+ -+ /* calculate byte count */ -+ count *= size; -+ -+ /* switch to 8 bit if stlink does not support 16 bit memory read */ -+ if (size == 2 && !(h->version.flags & STLINK_F_HAS_MEM_16BIT)) -+ size = 1; -+ -+ while (count) { -+ -+ bytes_remaining = (size != 1) ? -+ stlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h); -+ -+ if (count < bytes_remaining) -+ bytes_remaining = count; -+ -+ /* -+ * all stlink support 8/32bit memory read/writes and only from -+ * stlink V2J26 there is support for 16 bit memory read/write. -+ * Honour 32 bit and, if possible, 16 bit too. Otherwise, handle -+ * as 8bit access. -+ */ -+ if (size != 1) { -+ -+ /* When in jtag mode the stlink uses the auto-increment functionality. -+ * However it expects us to pass the data correctly, this includes -+ * alignment and any page boundaries. We already do this as part of the -+ * adi_v5 implementation, but the stlink is a hla adapter and so this -+ * needs implementing manually. -+ * currently this only affects jtag mode, according to ST they do single -+ * access in SWD mode - but this may change and so we do it for both modes */ -+ -+ /* we first need to check for any unaligned bytes */ -+ if (addr & (size - 1)) { -+ -+ uint32_t head_bytes = size - (addr & (size - 1)); -+ retval = stlink_usb_read_mem8(handle, ap_num, csw, addr, head_bytes, buffer); -+ if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { -+ usleep((1<version.flags & STLINK_F_HAS_MEM_16BIT)) -- size = 1; -- -- while (count) { -- -- bytes_remaining = (size != 1) ? -- stlink_max_block_size(h->max_mem_packet, addr) : stlink_usb_block(h); -- -- if (count < bytes_remaining) -- bytes_remaining = count; -- -- /* -- * all stlink support 8/32bit memory read/writes and only from -- * stlink V2J26 there is support for 16 bit memory read/write. -- * Honour 32 bit and, if possible, 16 bit too. Otherwise, handle -- * as 8bit access. -- */ -- if (size != 1) { -- -- /* When in jtag mode the stlink uses the auto-increment functionality. -- * However it expects us to pass the data correctly, this includes -- * alignment and any page boundaries. We already do this as part of the -- * adi_v5 implementation, but the stlink is a hla adapter and so this -- * needs implementing manually. -- * currently this only affects jtag mode, according to ST they do single -- * access in SWD mode - but this may change and so we do it for both modes */ -- -- /* we first need to check for any unaligned bytes */ -- if (addr & (size - 1)) { -- -- uint32_t head_bytes = size - (addr & (size - 1)); -- retval = stlink_usb_write_mem8(handle, addr, head_bytes, buffer); -- if (retval == ERROR_WAIT && retries < MAX_WAIT_RETRIES) { -- usleep((1<max_mem_packet = (1 << 10); - - uint8_t buffer[4]; -- stlink_usb_open_ap(h, 0); -- err = stlink_usb_read_mem32(h, CPUID, 4, buffer); -+ stlink_usb_open_ap(h, STLINK_HLA_AP_NUM); -+ err = stlink_usb_read_mem32(h, STLINK_HLA_AP_NUM, STLINK_HLA_CSW, CPUID, 4, buffer); - if (err == ERROR_OK) { - uint32_t cpuid = le_to_h_u32(buffer); - int i = (cpuid >> 4) & 0xf; -@@ -3539,6 +3669,249 @@ static int stlink_dap_op_run(struct adiv5_dap *dap) - return saved_retval; - } - -+/* -+ * Explanation on CSW hack used for firmware V2J24~V2J31 and V3J1 -+ * -+ * The API of these firmware versions don't provide a way to specify directly -+ * the value of CSW used for mem_ap accesses. The CSW value used by the -+ * firmware is not under user control. The lack of specific API would force -+ * the use of inefficient memory access through low-level AP register API. -+ * -+ * The CSW value internally computed by the firmware is cached by the firmware -+ * itself to minimize the writes to register MEM_AP_REG_CSW, writing it only -+ * to updated a new CSW value. The update is only triggered by a change in the -+ * CSW fields "size" and "addrinc" (note: with these firmware versions we only -+ * use "addrinc = true"). -+ * -+ * With the command STLINK_DEBUG_APIV2_WRITE_DAP_REG we can write the register -+ * MEM_AP_REG_CSW; the firmware does not intercept this write and its internal -+ * cached CSW value get out-of-sync wrt the value in register MEM_AP_REG_CSW. -+ * The hack rely on this mismatch between firmware cache and MEM_AP_REG_CSW. -+ * Given the "size" of data we plan to use for memory access, we execute: -+ * 1) a dummy memory read of "size" to let the firmware compute a CSW value -+ * coherent with "size". This will update the internal CSW cache and -+ * (eventually) the register MEM_AP_REG_CSW; -+ * 2) a write of the desired "user" CSW value in MEM_AP_REG_CSW, including the -+ * field "addrinc" ("size" has not to be changed wrt point 1); -+ * 3) a set of memory read/write commands of the same "size". -+ * While executing 3), the firmware will not modify the content of register -+ * MEM_AP_REG_CSW because accordingly to its cached value there is no need to -+ * update it! -+ * The memory accesses in 3) would then be executed with the desired CSW value -+ * programmed in 2). -+ * -+ * To simplify the code and only use one "size", the case of unaligned access -+ * is converted to a 8 bit access. -+ * -+ * Because of the available API, in step 3) we will use the normal access (with -+ * address auto-increment) also for addrinc==false, and this triggers another -+ * problem. The auto-increment of register MEM_AP_REG_TAR is guaranteed only -+ * on the 10 least significant bits. The firmware will update MEM_AP_REG_TAR -+ * every time the 10 bit increment is crossed, to avoid any potential -+ * wrap-around. This disrupts the address in MEM_AP_REG_TAR, that should -+ * instead be constant during the whole memory access. To prevent this, we -+ * split the memory access in chunks whose length cannot cause the 10 bits -+ * wrap-around so the firmware will not touch MEM_AP_REG_TAR. -+ * -+ * For write case only, the firmware operates per USB blocks, so it re-programs -+ * MEM_AP_REG_TAR every 64 bytes (on stlink/v1) or 512 bytes (on stlik/v3) and -+ * this limits the maximum size of each write chunk when addrinc==false. -+ */ -+static int stlink_dap_hack_csw(struct adiv5_ap *ap, uint32_t size, bool addrinc) -+{ -+ uint32_t csw; -+ uint8_t dummy[4]; -+ -+ switch (size) { -+ case 1: -+ csw = CSW_8BIT; -+ break; -+ case 2: -+ csw = CSW_16BIT; -+ break; -+ case 4: -+ /* -+ * ST-Link sets autoinc only in 32 bits mode -+ * -+ * ARM IHI 0031D: Note: -+ * It is IMPLEMENTATION DEFINED whether a MEM-AP supports transfer sizes other than Word. If a -+ * MEM-AP only supports word transfers and Increment single is selected, the TAR always -+ * increments by four after a successful DRW transaction. -+ */ -+ csw = addrinc ? (CSW_32BIT | CSW_ADDRINC_SINGLE) : CSW_32BIT; -+ break; -+ default: -+ return ERROR_FAIL; -+ } -+ csw |= ap->csw_default; -+ -+ /* This mem read will change CSW. Ignore errors */ -+ stlink_usb_read_ap_mem(stlink_dap_handle, ap->ap_num, STLINK_HLA_CSW, 0x00000000, size, 1, dummy); -+ -+ return dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw); -+} -+ -+static int stlink_dap_hack_csw_mem_read(struct adiv5_ap *ap, uint8_t *buffer, -+ uint32_t size, uint32_t count, uint32_t address, bool addrinc) -+{ -+ int retval; -+ uint32_t bytes_remaining, max_count; -+ -+ /* unaligned access could be split in mix 32/16/8 bits. Force 8-bis only */ -+ if ((size == 4 && address & 3) || -+ (size == 2 && address & 1) || -+ (size == 2 && !(stlink_dap_handle->version.flags & STLINK_F_HAS_MEM_16BIT))) { -+ count *= size; -+ size = 1; -+ } -+ -+ retval = stlink_dap_hack_csw(ap, size, addrinc); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ if (addrinc) -+ return stlink_usb_read_ap_mem(stlink_dap_handle, ap->ap_num, -+ STLINK_HLA_CSW, address, size, count, buffer); -+ -+ count *= size; -+ max_count = TAR_AUTOINCR_BLOCK - (address & (TAR_AUTOINCR_BLOCK - 1)); -+ while (count) { -+ bytes_remaining = (count < max_count) ? count : max_count; -+ -+ retval = stlink_usb_read_mem32(stlink_dap_handle, ap->ap_num, -+ STLINK_HLA_CSW, address, bytes_remaining, buffer); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ buffer += bytes_remaining; -+ count -= bytes_remaining; -+ } -+ return ERROR_OK; -+} -+ -+static int stlink_dap_op_ap_mem_read(struct adiv5_ap *ap, uint8_t *buffer, -+ uint32_t size, uint32_t count, uint32_t address, bool addrinc) -+{ -+ int retval; -+ uint32_t bytes_remaining; -+ -+ if (!addrinc && size != 4) -+ return ERROR_OP_NOT_SUPPORTED; -+ -+ retval = stlink_dap_op_run(ap->dap); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ retval = stlink_dap_open_ap(ap->ap_num); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ dap_invalidate_cache(ap->dap); -+ -+ if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_CSW)) -+ return stlink_dap_hack_csw_mem_read(ap, buffer, size, count, address, addrinc); -+ -+ if (addrinc) -+ return stlink_usb_read_ap_mem(stlink_dap_handle, ap->ap_num, -+ ap->csw_default, address, size, count, buffer); -+ -+ count *= size; -+ while (count) { -+ bytes_remaining = (count < STLINK_DATA_SIZE) ? count : STLINK_DATA_SIZE; -+ -+ retval = stlink_usb_read_mem32_noaddrinc(stlink_dap_handle, ap->ap_num, -+ ap->csw_default, address, bytes_remaining, buffer); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ buffer += bytes_remaining; -+ count -= bytes_remaining; -+ } -+ return ERROR_OK; -+} -+ -+static int stlink_dap_hack_csw_mem_write(struct adiv5_ap *ap, const uint8_t *buffer, -+ uint32_t size, uint32_t count, uint32_t address, bool addrinc) -+{ -+ int retval; -+ uint32_t bytes_remaining, max_count; -+ -+ /* unaligned access could be split in mix 32/16/8 bits. Force 8-bis only */ -+ if ((size == 4 && address & 3) || -+ (size == 2 && address & 1) || -+ (size == 2 && !(stlink_dap_handle->version.flags & STLINK_F_HAS_MEM_16BIT))) { -+ count *= size; -+ size = 1; -+ } -+ -+ retval = stlink_dap_hack_csw(ap, size, addrinc); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ if (addrinc) -+ return stlink_usb_write_ap_mem(stlink_dap_handle, ap->ap_num, -+ STLINK_HLA_CSW, address, size, count, buffer); -+ -+ count *= size; -+ max_count = TAR_AUTOINCR_BLOCK - (address & (TAR_AUTOINCR_BLOCK - 1)); -+ if (max_count > stlink_usb_block(&stlink_dap_handle)) -+ max_count = stlink_usb_block(&stlink_dap_handle); -+ -+ while (count) { -+ bytes_remaining = (count < max_count) ? count : max_count; -+ -+ retval = stlink_usb_write_mem32(stlink_dap_handle, ap->ap_num, -+ STLINK_HLA_CSW, address, bytes_remaining, buffer); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ buffer += bytes_remaining; -+ count -= bytes_remaining; -+ } -+ return ERROR_OK; -+} -+ -+static int stlink_dap_op_ap_mem_write(struct adiv5_ap *ap, const uint8_t *buffer, -+ uint32_t size, uint32_t count, uint32_t address, bool addrinc) -+{ -+ int retval; -+ uint32_t bytes_remaining; -+ -+ if (!addrinc && size != 4) -+ return ERROR_OP_NOT_SUPPORTED; -+ -+ retval = stlink_dap_op_run(ap->dap); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ retval = stlink_dap_open_ap(ap->ap_num); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ dap_invalidate_cache(ap->dap); -+ -+ if (!(stlink_dap_handle->version.flags & STLINK_F_HAS_CSW)) -+ return stlink_dap_hack_csw_mem_write(ap, buffer, size, count, address, addrinc); -+ -+ if (addrinc) -+ return stlink_usb_write_ap_mem(stlink_dap_handle, ap->ap_num, -+ ap->csw_default, address, size, count, buffer); -+ -+ count *= size; -+ while (count) { -+ bytes_remaining = (count < STLINK_DATA_SIZE) ? count : STLINK_DATA_SIZE; -+ -+ retval = stlink_usb_write_mem32_noaddrinc(stlink_dap_handle, ap->ap_num, -+ ap->csw_default, address, bytes_remaining, buffer); -+ if (retval != ERROR_OK) -+ return retval; -+ -+ buffer += bytes_remaining; -+ count -= bytes_remaining; -+ } -+ return ERROR_OK; -+} -+ - /** */ - static void stlink_dap_op_quit(struct adiv5_dap *dap) - { -@@ -3803,6 +4176,10 @@ static const struct dap_ops stlink_dap_ops = { - .run = stlink_dap_op_run, - .sync = NULL, /* optional */ - .quit = stlink_dap_op_quit, /* optional */ -+ .ap_ops = { -+ .ap_mem_read = stlink_dap_op_ap_mem_read, -+ .ap_mem_write = stlink_dap_op_ap_mem_write, -+ }, - }; - - static const struct swim_driver stlink_swim_ops = { -diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c -index 8f5ad59c3..d7c920e91 100644 ---- a/src/target/arm_adi_v5.c -+++ b/src/target/arm_adi_v5.c -@@ -596,24 +596,52 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint - int mem_ap_read_buf(struct adiv5_ap *ap, - uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) - { -+ int retval; -+ -+ if (ap->dap->ops->ap_ops.ap_mem_read) { -+ retval = ap->dap->ops->ap_ops.ap_mem_read(ap, buffer, size, count, address, true); -+ if (retval != ERROR_OP_NOT_SUPPORTED) -+ return retval; -+ } - return mem_ap_read(ap, buffer, size, count, address, true); - } - - int mem_ap_write_buf(struct adiv5_ap *ap, - const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) - { -+ int retval; -+ -+ if (ap->dap->ops->ap_ops.ap_mem_write) { -+ retval = ap->dap->ops->ap_ops.ap_mem_write(ap, buffer, size, count, address, true); -+ if (retval != ERROR_OP_NOT_SUPPORTED) -+ return retval; -+ } - return mem_ap_write(ap, buffer, size, count, address, true); - } - - int mem_ap_read_buf_noincr(struct adiv5_ap *ap, - uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) - { -+ int retval; -+ -+ if (ap->dap->ops->ap_ops.ap_mem_read) { -+ retval = ap->dap->ops->ap_ops.ap_mem_read(ap, buffer, size, count, address, false); -+ if (retval != ERROR_OP_NOT_SUPPORTED) -+ return retval; -+ } - return mem_ap_read(ap, buffer, size, count, address, false); - } - - int mem_ap_write_buf_noincr(struct adiv5_ap *ap, - const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address) - { -+ int retval; -+ -+ if (ap->dap->ops->ap_ops.ap_mem_write) { -+ retval = ap->dap->ops->ap_ops.ap_mem_write(ap, buffer, size, count, address, false); -+ if (retval != ERROR_OP_NOT_SUPPORTED) -+ return retval; -+ } - return mem_ap_write(ap, buffer, size, count, address, false); - } - -diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h -index 8edfaa816..587bb3dd9 100644 ---- a/src/target/arm_adi_v5.h -+++ b/src/target/arm_adi_v5.h -@@ -296,6 +296,26 @@ struct adiv5_dap { - bool ignore_syspwrupack; - }; - -+/** -+ * Optional optimized implementation of AP access. -+ * Use of low-level primitives in struct dap_ops already allows implementing -+ * any type of AP access. Some adapter offer faster API at higher level for -+ * specific AP types or mode. -+ * Specific request not available or not implemented should return error -+ * ERROR_OP_NOT_SUPPORTED. -+ */ -+struct ap_ops { -+ /** Optional interface-specific optimized AP memory read */ -+ int (*ap_mem_read)(struct adiv5_ap *ap, uint8_t *buffer, -+ uint32_t size, uint32_t count, uint32_t address, -+ bool addrinc); -+ -+ /** Optional interface-specific optimized AP memory write */ -+ int (*ap_mem_write)(struct adiv5_ap *ap, const uint8_t *buffer, -+ uint32_t size, uint32_t count, uint32_t address, -+ bool addrinc); -+}; -+ - /** - * Transport-neutral representation of queued DAP transactions, supporting - * both JTAG and SWD transports. All submitted transactions are logically -@@ -336,6 +356,8 @@ struct dap_ops { - - /** Optional; called at OpenOCD exit */ - void (*quit)(struct adiv5_dap *dap); -+ -+ struct ap_ops ap_ops; - }; - - /* -diff --git a/tcl/board/stm32mp15x_ev1_jlink_jtag.cfg b/tcl/board/stm32mp15x_ev1_jlink_jtag.cfg -new file mode 100644 -index 000000000..ce0c56cdb ---- /dev/null -+++ b/tcl/board/stm32mp15x_ev1_jlink_jtag.cfg -@@ -0,0 +1,9 @@ -+# This is a STM32MP15x board set MB1262C + MB1263B. -+ -+source [find interface/jlink.cfg] -+ -+transport select jtag -+ -+source [find target/stm32mp15x.cfg] -+ -+reset_config trst_and_srst separate -diff --git a/tcl/board/stm32mp15x_ev1_jlink_swd.cfg b/tcl/board/stm32mp15x_ev1_jlink_swd.cfg -new file mode 100644 -index 000000000..58286d3f8 ---- /dev/null -+++ b/tcl/board/stm32mp15x_ev1_jlink_swd.cfg -@@ -0,0 +1,9 @@ -+# This is a STM32MP15x board set MB1262C + MB1263B. -+ -+source [find interface/jlink.cfg] -+ -+transport select swd -+ -+source [find target/stm32mp15x.cfg] -+ -+reset_config srst_only -diff --git a/tcl/board/stm32mp15x_ev1_stlink_jtag.cfg b/tcl/board/stm32mp15x_ev1_stlink_jtag.cfg -new file mode 100644 -index 000000000..b0cba47c3 ---- /dev/null -+++ b/tcl/board/stm32mp15x_ev1_stlink_jtag.cfg -@@ -0,0 +1,9 @@ -+# This is a STM32MP15x board set MB1262C + MB1263B. -+ -+source [find interface/stlink-dap.cfg] -+ -+transport select dapdirect_jtag -+ -+source [find target/stm32mp15x.cfg] -+ -+reset_config srst_only -diff --git a/tcl/board/stm32mp15x_ev1_stlink_swd.cfg b/tcl/board/stm32mp15x_ev1_stlink_swd.cfg -new file mode 100644 -index 000000000..793b2c771 ---- /dev/null -+++ b/tcl/board/stm32mp15x_ev1_stlink_swd.cfg -@@ -0,0 +1,9 @@ -+# This is a STM32MP15x board set MB1262C + MB1263B. -+ -+source [find interface/stlink-dap.cfg] -+ -+transport select dapdirect_swd -+ -+source [find target/stm32mp15x.cfg] -+ -+reset_config srst_only -diff --git a/tcl/board/stm32mp15x_ev1_ulink2_jtag.cfg b/tcl/board/stm32mp15x_ev1_ulink2_jtag.cfg -new file mode 100644 -index 000000000..fcf62d4f3 ---- /dev/null -+++ b/tcl/board/stm32mp15x_ev1_ulink2_jtag.cfg -@@ -0,0 +1,9 @@ -+# This is a STM32MP15x board set MB1262C + MB1263B. -+ -+source [find interface/cmsis-dap.cfg] -+ -+transport select jtag -+ -+source [find target/stm32mp15x.cfg] -+ -+reset_config trst_and_srst separate -diff --git a/tcl/board/stm32mp15x_ev1_ulink2_swd.cfg b/tcl/board/stm32mp15x_ev1_ulink2_swd.cfg -new file mode 100644 -index 000000000..2c0528bf1 ---- /dev/null -+++ b/tcl/board/stm32mp15x_ev1_ulink2_swd.cfg -@@ -0,0 +1,9 @@ -+# This is a STM32MP15x board set MB1262C + MB1263B. -+ -+source [find interface/cmsis-dap.cfg] -+ -+transport select swd -+ -+source [find target/stm32mp15x.cfg] -+ -+reset_config srst_only --- -2.30.0 - diff --git a/recipes-devtools/openocd/openocd-stm32mp_0.11.0.bb b/recipes-devtools/openocd/openocd-stm32mp_0.11.0.bb index 0ce44d5..b8556ca 100644 --- a/recipes-devtools/openocd/openocd-stm32mp_0.11.0.bb +++ b/recipes-devtools/openocd/openocd-stm32mp_0.11.0.bb @@ -1,17 +1,23 @@ SUMMARY = "Free and Open On-Chip Debugging, In-System Programming and Boundary-Scan Testing" HOMEPAGE = "http://openocd.org" LICENSE = "GPL-2.0-only" -LIC_FILES_CHKSUM = "file://COPYING;md5=b234ee4d69f5fce4486a80fdaf4a4263" +LIC_FILES_CHKSUM = "file://COPYING;md5=599d2d1ee7fc84c0467b3d19801db870" require openocd-stm32mp.inc -SRC_URI:prepend = "git://repo.or.cz/openocd.git;name=openocd;branch=master " +SRC_URI = "git://github.com/openocd-org/openocd.git;protocol=https;branch=master;name=openocd " SRCREV_FORMAT = "openocd" -SRCREV_openocd = "a5e526d8575cf63fe11babec85c0798ac3f4ad74" +SRCREV_openocd = "fdf17dba569ac8aca0771c28b661e3722d776541" -PV = "0.11.0-rc2.${SRCPV}" +PV = "0.11.0+dev.${SRCPV}" -SRC_URI += " \ - file://0001-rebase-on-v0.11.0-rc2.patch \ -" +SRC_URI += "" + +# Use jimtcl master branch to fix RANLIB issue in kirkstone and commit it +# to prevent "-dirty" suffix to openocd version. +# To be removed after a new jimtcl release get used by openocd. +do_configure:prepend() { + git add jimtcl + git commit -m "Update jimtcl" +}