This is an automated email from Gerrit. "Tomas Vanek <van...@fbl.cz>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8119
-- gerrit commit 5fd1d8dd0b8551412d50aef55038c10ccb268855 Author: Tomas Vanek <van...@fbl.cz> Date: Fri Jan 26 11:53:49 2024 +0100 target/adi_v5_swd: introduce swd_check_dpidr() Add two checks on DP IDR value when connecting: - bit 0 should read-as-one - DP version should comply with ADI version Signed-off-by: Tomas Vanek <van...@fbl.cz> Change-Id: I6fa53f28094007ae568de02e8a853f3dffced375 diff --git a/src/target/adi_v5_swd.c b/src/target/adi_v5_swd.c index 6d6f287b05..f748e3120f 100644 --- a/src/target/adi_v5_swd.c +++ b/src/target/adi_v5_swd.c @@ -297,6 +297,37 @@ static int swd_multidrop_select(struct adiv5_dap *dap) return retval; } +static int swd_check_dpidr(struct adiv5_dap *dap, uint32_t dpidr) +{ + unsigned int dp_ver = (dpidr & DP_DPIDR_VERSION_MASK) >> DP_DPIDR_VERSION_SHIFT; + + LOG_INFO("SWD DPIDR 0x%08" PRIx32 " DPv%u", dpidr, dp_ver); + + if ((dpidr & BIT(0)) == 0) { + /* Without this check and with SWDIO pulled down a false DP detection + * is possible on an unconnected SWD or when target does not respond: + * The gradual drop of voltage at not driven SWDIO signal imposed + * by discharging pins and wiring capacity can be misinterpreted + * by the adapter as a valid read result: + * ACK 100, RDATA 00000000000000000000000000000000, PARITY 0 */ + LOG_ERROR("Error connecting DP: bad IDR value, bit 0 should read-as-one"); + return ERROR_FAIL; + } + + if (is_adiv6(dap)) { + if (dp_ver < 3) { + LOG_ERROR("Error connecting DP: ADIv6 requires DPv3"); + return ERROR_FAIL; + } + } else { + if (dp_ver > 2) { + LOG_ERROR("Error connecting DP: DPv3 requires dap create -adiv6 option"); + return ERROR_FAIL; + } + } + return ERROR_OK; +} + static int swd_connect_multidrop(struct adiv5_dap *dap) { int retval; @@ -330,8 +361,9 @@ static int swd_connect_multidrop(struct adiv5_dap *dap) } swd_multidrop_in_swd_state = true; - LOG_INFO("SWD DPIDR 0x%08" PRIx32 ", DLPIDR 0x%08" PRIx32, - dpidr, dlpidr); + + retval = swd_check_dpidr(dap, dpidr); + LOG_INFO("multidrop DLPIDR 0x%08" PRIx32, dlpidr); return retval; } @@ -387,7 +419,10 @@ static int swd_connect_single(struct adiv5_dap *dap) return retval; } - LOG_INFO("SWD DPIDR 0x%08" PRIx32, dpidr); + retval = swd_check_dpidr(dap, dpidr); + if (retval != ERROR_OK) { + return retval; + } do { dap->do_reconnect = false; --