From 347fc05851d7583156156048665c6c430e201172 Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 20:47:58 -0500
Subject: [PATCH 01/12] Revert "jtag_scan: Rework chain detection"

This reverts commit 2d4a50313596081a64bd1397017985641fd8cad0.
---
 src/Makefile                      |   1 +
 src/platforms/hosted/Makefile.inc |   2 +-
 src/target/adiv5.h                |   8 +-
 src/target/jtag_scan.c            | 276 +++++++++++++++---------------
 4 files changed, 141 insertions(+), 146 deletions(-)

diff --git a/src/Makefile b/src/Makefile
index 188ecfa4a75..de053656f15 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -31,6 +31,7 @@ SRC =			\
 	gdb_hostio.c	\
 	gdb_packet.c	\
 	hex_utils.c	\
+	jtag_devs.c	\
 	jtag_scan.c	\
 	lmi.c		\
 	lpc_common.c	\
diff --git a/src/platforms/hosted/Makefile.inc b/src/platforms/hosted/Makefile.inc
index f3e3248bcf5..6ba2d781ccd 100644
--- a/src/platforms/hosted/Makefile.inc
+++ b/src/platforms/hosted/Makefile.inc
@@ -73,7 +73,7 @@ ifneq ($(HOSTED_BMP_ONLY), 1)
 endif
 
 VPATH += platforms/pc
-SRC += timing.c cl_utils.c utils.c jtag_devs.c
+SRC += timing.c cl_utils.c utils.c
 SRC += bmp_remote.c remote_swdptap.c remote_jtagtap.c
 ifneq ($(HOSTED_BMP_ONLY), 1)
 SRC += bmp_libusb.c stlinkv2.c
diff --git a/src/target/adiv5.h b/src/target/adiv5.h
index 95c62f62a50..bd0985e49cf 100644
--- a/src/target/adiv5.h
+++ b/src/target/adiv5.h
@@ -89,23 +89,19 @@
 #define ADIV5_AP_BASE		ADIV5_AP_REG(0xF8)
 #define ADIV5_AP_IDR		ADIV5_AP_REG(0xFC)
 
-/* Known designers seen in SYSROM-PIDR and JTAG IDCode.
- * Ignore Bit 0 from the designer bits to get JEDEC Ids.
- * Should get it's one file as not only related to Adiv5!
- */
+/* Known designers seen in SYSROM-PIDR. Ignore Bit 0 from
+ * the designer bits to get JEDEC Ids with bit 7 ignored.*/
 #define AP_DESIGNER_FREESCALE    0x00e
 #define AP_DESIGNER_TEXAS        0x017
 #define AP_DESIGNER_ATMEL        0x01f
 #define AP_DESIGNER_STM          0x020
 #define AP_DESIGNER_CYPRESS      0x034
 #define AP_DESIGNER_INFINEON     0x041
-#define DESIGNER_XILINX          0x049
 #define AP_DESIGNER_NORDIC       0x244
 #define AP_DESIGNER_ARM          0x43b
 /*LPC845 with designer 501. Strange!? */
 #define AP_DESIGNER_SPECULAR     0x501
 #define AP_DESIGNER_CS           0x555
-#define DESIGNER_XAMBALA         0x61e
 #define AP_DESIGNER_ENERGY_MICRO 0x673
 #define AP_DESIGNER_GIGADEVICE   0x751
 #define AP_DESIGNER_RASPBERRY    0x927
diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c
index eb1efc80310..04a8cca4ab9 100644
--- a/src/target/jtag_scan.c
+++ b/src/target/jtag_scan.c
@@ -3,7 +3,6 @@
  *
  * Copyright (C) 2011  Black Sphere Technologies Ltd.
  * Written by Gareth McMullin <gareth@blacksphere.co.nz>
- * Copyright (C) 2021 Uwe Bonnes(bon@elektron.ikp.physik.tu-darmstadt.de)
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,14 +25,16 @@
 
 #include "general.h"
 #include "jtagtap.h"
+#include "jtag_scan.h"
 #include "target.h"
 #include "adiv5.h"
+#include "jtag_devs.h"
 
 jtag_dev_t jtag_devs[JTAG_MAX_DEVS+1];
 int jtag_dev_count;
 
 /* bucket of ones for don't care TDI */
-static const uint8_t ones[] = {0xff, 0xFF, 0xFF, 0xFF};
+static const uint8_t ones[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
 
 #if PC_HOSTED == 0
 void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev)
@@ -46,32 +47,36 @@ void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev)
 #endif
 
 /* Scan JTAG chain for devices, store IR length and IDCODE (if present).
+ * Reset TAP state machine.
+ * Select Shift-IR state.
+ * Each device is assumed to shift out IR at 0x01. (this may not always be true)
+ * Shift in ones until we read two consecutive ones, then we have shifted out the
+ * 	IRs of all devices.
  *
- * https://www.fpga4fun.com/JTAG3.html
- * Count the number of devices in the JTAG chain
- *
- * shift enough ones in IR
- * shift enough zeros in DR
- * Now shift out ones and stop if first '1' is seen. This gets the number
- * of devices
- *
- * Assume max 32 devices with max IR len 16 = 512 bits = 16 loops * 32 bit
+ * After this process all the IRs are loaded with the BYPASS command.
+ * Select Shift-DR state.
+ * Shift in ones and count zeros shifted out. Should be one for each device.
+ * Check this against device count obtained by IR scan above.
  *
  * Reset the TAP state machine again. This should load all IRs with IDCODE.
- * Read 32 bit IDCODE for all devices.
-  */
-
+ * For each device, shift out one bit. If this is zero IDCODE isn't present,
+ *	continue to next device. If this is one shift out the remaining 31 bits
+ *	of the IDCODE register.
+ */
 int jtag_scan(const uint8_t *irlens)
 {
 	int i;
-	void (*jd_handlers[JTAG_MAX_DEVS])(jtag_dev_t *jd);
+	uint32_t j;
+
 	target_list_free();
 
-	memset(jd_handlers, 0, sizeof(jd_handlers));
+	jtag_dev_count = 0;
+	memset(&jtag_devs, 0, sizeof(jtag_devs));
 
-	/* Run throught the SWD to JTAG sequence for the case where an
-	 * attached SWJ-DP is in SW-DP mode.
+	/* Run throught the SWD to JTAG sequence for the case where an attached SWJ-DP is
+	 * in SW-DP mode.
 	 */
+	DEBUG_INFO("Resetting TAP\n");
 #if PC_HOSTED == 1
 	if (platform_jtagtap_init()) {
 		DEBUG_WARN("JTAG not available\n");
@@ -81,146 +86,139 @@ int jtag_scan(const uint8_t *irlens)
 	jtagtap_init();
 #endif
 	jtag_proc.jtagtap_reset();
-#define LOOPS 16
-	jtagtap_shift_ir();
-	i = LOOPS;
-	uint8_t ir_chain[64], *din = ir_chain;
-	while (i--) {
-		jtag_proc.jtagtap_tdi_tdo_seq(din, (i == 0) ? 1 : 0, ones,
-									  sizeof(ones) * 8);
-		din += sizeof(ones);
-	}
-	if (!(ir_chain[0] & 1)) {
-		DEBUG_WARN("Unexpected IR chain!\n");
-		return 0;
-	}
-	jtagtap_return_idle();
-	jtagtap_shift_dr();
-	i = LOOPS;
-	uint8_t zeros[] = {0, 0, 0, 0};
-	while(i--) {
-		jtag_proc.jtagtap_tdi_seq(0, zeros, sizeof(zeros) * 8);
-	}
-	int num_devices = 0;
-	while (!jtag_proc.jtagtap_next(0,1) && (i++ < 6))
-			num_devices++;
-	jtag_proc.jtagtap_reset();
-	jtagtap_shift_dr();
-	jtag_dev_count = num_devices;
-	if (!num_devices)
-		return 0;
-	DEBUG_TARGET("Found %d devices\n", num_devices);
-	int irbit = 1;
-	int j = 0;
-	for (i = 0; i < num_devices; i++) {
-		uint8_t id[4];
-		jtag_proc.jtagtap_tdi_tdo_seq(id, 0, ones, 32);
-		if (!(id[0] & 1)) {
-			DEBUG_WARN("Invalid IDCode!\n");
-			return 0;
-		}
-		uint32_t idcode = id[3] << 24 | id[2] << 16 |  id[1] << 8 | id[0];
-		unsigned int designer = ((id[1] & 0xf) << 8) | (id[0] >> 1);
-		unsigned int product = id[2] | ((id[3] & 0xf) << 8);
-		unsigned int expected_irlen = 0;
-		switch (designer) {
-		case AP_DESIGNER_ARM:
-			switch (product) {
-			case 0xba0:
-				jtag_devs[i].jd_descr = "ADIv5 JTAG-DP port";
-				jd_handlers[i] = adiv5_jtag_dp_handler;
-				expected_irlen = 4;
-				break;
-			default:
-				jtag_devs[i].jd_descr = "ARM";
-			}
-			break;
-		case AP_DESIGNER_STM:
-			expected_irlen = 5;
-			jtag_devs[i].jd_descr = "STM32 BSD";
-			break;
-		case AP_DESIGNER_ATMEL:
-			if ((product >= 0x940) & (product < 0x990)) {
-				jtag_devs[i].jd_descr = "ATMEL AVR8";
-				expected_irlen = 4;
+
+	if (irlens) {
+		DEBUG_WARN("Given list of IR lengths, skipping probe\n");
+		DEBUG_INFO("Change state to Shift-IR\n");
+		jtagtap_shift_ir();
+		j = 0;
+		while((jtag_dev_count <= JTAG_MAX_DEVS) &&
+		      (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) {
+			uint32_t irout;
+			if(*irlens == 0)
 				break;
+			jtag_proc.jtagtap_tdi_tdo_seq((uint8_t*)&irout, 0, ones, *irlens);
+			if (!(irout & 1)) {
+				DEBUG_WARN("check failed: IR[0] != 1\n");
+				return -1;
 			}
-			jtag_devs[i].jd_descr = "ATMEL";
-			break;
-		case DESIGNER_XILINX:
-			if (!irlens) {
-				/* Guessed irlen for XILINX devices is wrong.
-				 * IR data contains status bits!
-				 */
-				DEBUG_WARN("Please provide irlens as chain contains XILINX devices!\n");
-				return 0;
-			}
-			jtag_devs[i].jd_descr = "XILINX";
-			break;
-		case DESIGNER_XAMBALA:
-			expected_irlen = 5;
-			jtag_devs[i].jd_descr = "RVDBG013";
-			break;
-		case AP_DESIGNER_GIGADEVICE:
-			expected_irlen = 5;
-			jtag_devs[i].jd_descr = "GIGADEVICE BSD";
-			break;
+			jtag_devs[jtag_dev_count].ir_len = *irlens;
+			jtag_devs[jtag_dev_count].ir_prescan = j;
+			jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count;
+			j += *irlens;
+			irlens++;
+			jtag_dev_count++;
 		}
-		if (!jtag_devs[i].jd_descr) {
-			DEBUG_WARN("Unhandled designer %x\n", designer);
-			jtag_devs[i].jd_descr = "Unknow";
+	} else {
+		DEBUG_INFO("Change state to Shift-IR\n");
+		jtagtap_shift_ir();
+
+		DEBUG_INFO("Scanning out IRs\n");
+		if(!jtag_proc.jtagtap_next(0, 1)) {
+			DEBUG_WARN("jtag_scan: Sanity check failed: IR[0] shifted out "
+					   "as 0\n");
+			jtag_dev_count = -1;
+			return -1; /* must be 1 */
 		}
-		bool bit;
-		int guessed_irlen = 0;
-		int advance = irbit;
-		do {
-			/* Guess IR length from the IR scan after JTAG Reset
-			 * First bit should be '1', following bits are '0', if not used
-			 * for instruction capture, as for Xilinx parts.
-			 */
-			bit = (ir_chain[advance / 8] & (1 << (advance & 7)));
-			guessed_irlen++;
-			advance++;
-		} while (!bit && (advance < (JTAG_MAX_DEVS * 16)));
-		if (irlens) { /* Allow to overwrite from the command line!*/
-			if (*irlens != guessed_irlen) {
-				DEBUG_TARGET("Provides irlen %d vs guessed %d for device %d\n",
-							 *irlens, guessed_irlen, i + 1);
-			}
-			expected_irlen = *irlens++;
+		jtag_devs[0].ir_len = 1; j = 1;
+		while((jtag_dev_count <= JTAG_MAX_DEVS) &&
+		      (jtag_devs[jtag_dev_count].ir_len <= JTAG_MAX_IR_LEN)) {
+			if(jtag_proc.jtagtap_next(0, 1)) {
+				if(jtag_devs[jtag_dev_count].ir_len == 1) break;
+				jtag_devs[++jtag_dev_count].ir_len = 1;
+				jtag_devs[jtag_dev_count].ir_prescan = j;
+				jtag_devs[jtag_dev_count].jd_dev = jtag_dev_count;
+			} else jtag_devs[jtag_dev_count].ir_len++;
+			j++;
+		}
+		if(jtag_dev_count > JTAG_MAX_DEVS) {
+			DEBUG_WARN("jtag_scan: Maximum device count exceeded\n");
+			jtag_dev_count = -1;
+			return -1;
 		}
-		if (!expected_irlen) {
-			expected_irlen = guessed_irlen++;
+		if(jtag_devs[jtag_dev_count].ir_len > JTAG_MAX_IR_LEN) {
+			DEBUG_WARN("jtag_scan: Maximum IR length exceeded\n");
+			jtag_dev_count = -1;
+			return -1;
 		}
-		jtag_devs[i].ir_len = expected_irlen;
-		jtag_devs[i].ir_prescan = j;
-		jtag_devs[i].jd_dev = i;
-		jtag_devs[i].jd_idcode = idcode;
+	}
+
+	DEBUG_INFO("Return to Run-Test/Idle\n");
+	jtag_proc.jtagtap_next(1, 1);
+	jtagtap_return_idle();
+
+	/* All devices should be in BYPASS now */
+
+	/* Count device on chain */
+	DEBUG_INFO("Change state to Shift-DR\n");
+	jtagtap_shift_dr();
+	for(i = 0; (jtag_proc.jtagtap_next(0, 1) == 0) && (i <= jtag_dev_count); i++)
 		jtag_devs[i].dr_postscan = jtag_dev_count - i - 1;
-		jtag_devs[i].current_ir = -1;
-		j += expected_irlen;
-		irbit += expected_irlen;
-		DEBUG_INFO("%2d: IDCODE: 0x%08" PRIx32 ", IR len %d %s%s\n", i + 1,
-				   idcode,jtag_devs[i].ir_len, jtag_devs[i].jd_descr,
-				   (jd_handlers[i]) ? "" : " (Unhandled) ");
+
+	if(i != jtag_dev_count) {
+		DEBUG_WARN("jtag_scan: Sanity check failed: "
+			"BYPASS dev count doesn't match IR scan\n");
+		jtag_dev_count = -1;
+		return -1;
 	}
-	jtag_proc.jtagtap_reset();
+
+	DEBUG_INFO("Return to Run-Test/Idle\n");
+	jtag_proc.jtagtap_next(1, 1);
+	jtagtap_return_idle();
+	if(!jtag_dev_count) {
+		return 0;
+	}
+
 	/* Fill in the ir_postscan fields */
-	for(i = jtag_dev_count - 1; i; i--) {
+	for(i = jtag_dev_count - 1; i; i--)
 		jtag_devs[i-1].ir_postscan = jtag_devs[i].ir_postscan +
 					jtag_devs[i].ir_len;
+
+	/* Reset jtagtap: should take all devs to IDCODE */
+	jtag_proc.jtagtap_reset();
+	jtagtap_shift_dr();
+	for(i = 0; i < jtag_dev_count; i++) {
+		if(!jtag_proc.jtagtap_next(0, 1)) continue;
+		jtag_devs[i].jd_idcode = 1;
+		for(j = 2; j; j <<= 1)
+			if(jtag_proc.jtagtap_next(0, 1)) jtag_devs[i].jd_idcode |= j;
+
 	}
+	DEBUG_INFO("Return to Run-Test/Idle\n");
+	jtag_proc.jtagtap_next(1, 1);
+	jtagtap_return_idle();
 #if PC_HOSTED == 1
 	/*Transfer needed device information to firmware jtag_devs*/
-	for(i = 0; i < jtag_dev_count; i++) {
+	for(i = 0; i < jtag_dev_count; i++)
 		platform_add_jtag_dev(i, &jtag_devs[i]);
+	for(i = 0; i < jtag_dev_count; i++) {
+		DEBUG_INFO("Idcode 0x%08" PRIx32, jtag_devs[i].jd_idcode);
+		for(j = 0; dev_descr[j].idcode; j++) {
+			if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
+			   dev_descr[j].idcode) {
+				DEBUG_INFO(": %s",
+						  (dev_descr[j].descr) ? dev_descr[j].descr : "unknown");
+				break;
+			}
+		}
+		DEBUG_INFO("\n");
 	}
 #endif
+
 	/* Check for known devices and handle accordingly */
 	for(i = 0; i < jtag_dev_count; i++)
-		/* Call handler to initialise/probe device further */
-		if (jd_handlers[i])
-			jd_handlers[i](&jtag_devs[i]);
+		for(j = 0; dev_descr[j].idcode; j++)
+			if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
+			   dev_descr[j].idcode) {
+				jtag_devs[i].current_ir = -1;
+				/* Save description in table */
+				jtag_devs[i].jd_descr = dev_descr[j].descr;
+				/* Call handler to initialise/probe device further */
+				if(dev_descr[j].handler)
+					dev_descr[j].handler(i, jtag_devs[i].jd_idcode);
+				break;
+			}
+
 	return jtag_dev_count;
 }
 

From eb67659ebdedb4edd17887fa8e0be30667ca4514 Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 20:52:28 -0500
Subject: [PATCH 02/12] Revert "jtag_scan: Deliver full idcode to the handler."

This reverts commit 1845d71f00dda59849254bbddb3c4c00f556d35c.
---
 src/target/jtag_scan.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c
index 04a8cca4ab9..f35aa67cbd8 100644
--- a/src/target/jtag_scan.c
+++ b/src/target/jtag_scan.c
@@ -215,7 +215,7 @@ int jtag_scan(const uint8_t *irlens)
 				jtag_devs[i].jd_descr = dev_descr[j].descr;
 				/* Call handler to initialise/probe device further */
 				if(dev_descr[j].handler)
-					dev_descr[j].handler(i, jtag_devs[i].jd_idcode);
+					dev_descr[j].handler(i, dev_descr[i].idcode);
 				break;
 			}
 

From 8e6450dbbd8f8d0b612e70fba932628d2760490d Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 21:05:13 -0500
Subject: [PATCH 03/12] Revert "jtag: Make jtag_devs argument to jtag_handler."

This reverts commit 6308506276d09cde14be2985c0c5a59adc0addc6.
---
 src/platforms/hosted/stlinkv2.c | 2 +-
 src/target/adiv5.h              | 2 +-
 src/target/adiv5_jtagdp.c       | 6 +++---
 src/target/jtag_devs.h          | 2 +-
 src/target/jtag_scan.c          | 2 +-
 src/target/jtag_scan.h          | 2 +-
 6 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/platforms/hosted/stlinkv2.c b/src/platforms/hosted/stlinkv2.c
index 42e81dd9079..1ecae9f51df 100644
--- a/src/platforms/hosted/stlinkv2.c
+++ b/src/platforms/hosted/stlinkv2.c
@@ -1010,7 +1010,7 @@ int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens)
 			if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
 			   dev_descr[j].idcode) {
 				if(dev_descr[j].handler)
-					dev_descr[j].handler(&jtag_devs[i]);
+					dev_descr[j].handler(i, dev_descr[j].idcode);
 				break;
 			}
 
diff --git a/src/target/adiv5.h b/src/target/adiv5.h
index bd0985e49cf..bcaa1921b1c 100644
--- a/src/target/adiv5.h
+++ b/src/target/adiv5.h
@@ -285,7 +285,7 @@ void adiv5_ap_ref(ADIv5_AP_t *ap);
 void adiv5_ap_unref(ADIv5_AP_t *ap);
 void platform_add_jtag_dev(const int dev_index, const jtag_dev_t *jtag_dev);
 
-void adiv5_jtag_dp_handler(jtag_dev_t *jd);
+void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode);
 int platform_jtag_dp_init(ADIv5_DP_t *dp);
 int swdptap_init(ADIv5_DP_t *dp);
 
diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c
index 5273746136e..2c87dc7cc27 100644
--- a/src/target/adiv5_jtagdp.c
+++ b/src/target/adiv5_jtagdp.c
@@ -39,7 +39,7 @@
 
 static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp);
 
-void adiv5_jtag_dp_handler(jtag_dev_t *jd)
+void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode)
 {
 	ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
 	if (!dp) {			/* calloc failed: heap exhaustion */
@@ -47,8 +47,8 @@ void adiv5_jtag_dp_handler(jtag_dev_t *jd)
 		return;
 	}
 
-	dp->dp_jd_index = jd->jd_dev;
-	dp->idcode = jd->jd_idcode;
+	dp->dp_jd_index = jd_index;
+	dp->idcode = j_idcode;
 	if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) {
 		dp->dp_read = fw_adiv5_jtagdp_read;
 		dp->error = adiv5_jtagdp_error;
diff --git a/src/target/jtag_devs.h b/src/target/jtag_devs.h
index 8f8779851e1..8c2c0b5acd5 100644
--- a/src/target/jtag_devs.h
+++ b/src/target/jtag_devs.h
@@ -22,7 +22,7 @@ typedef const struct jtag_dev_descr_s {
 	const uint32_t idcode;
 	const uint32_t idmask;
 	const char * const descr;
-	void (*const handler)(jtag_dev_t *jd);
+	void (*const handler)(uint8_t jd_index, uint32_t j_idcode);
 } jtag_dev_descr_t;
 extern jtag_dev_descr_t dev_descr[];
 
diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c
index f35aa67cbd8..761f5ff0311 100644
--- a/src/target/jtag_scan.c
+++ b/src/target/jtag_scan.c
@@ -30,7 +30,7 @@
 #include "adiv5.h"
 #include "jtag_devs.h"
 
-jtag_dev_t jtag_devs[JTAG_MAX_DEVS+1];
+struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
 int jtag_dev_count;
 
 /* bucket of ones for don't care TDI */
diff --git a/src/target/jtag_scan.h b/src/target/jtag_scan.h
index bc76e0bc699..cc6d361a2c2 100644
--- a/src/target/jtag_scan.h
+++ b/src/target/jtag_scan.h
@@ -40,7 +40,7 @@ typedef struct jtag_dev_s {
 	uint32_t current_ir;
 } jtag_dev_t;
 
-extern jtag_dev_t jtag_devs[JTAG_MAX_DEVS+1];
+extern struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
 extern int jtag_dev_count;
 
 void jtag_dev_write_ir(jtag_proc_t *jp, uint8_t jd_index, uint32_t ir);

From 57e6c2fac39c747728c566c669d0d19618c121e0 Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 21:08:21 -0500
Subject: [PATCH 04/12] jtag_scan: Properly fixed the wrong IDCode getting to
 the handlers

---
 src/target/adiv5_jtagdp.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c
index 2c87dc7cc27..e4f30308be4 100644
--- a/src/target/adiv5_jtagdp.c
+++ b/src/target/adiv5_jtagdp.c
@@ -46,9 +46,10 @@ void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode)
 		DEBUG_WARN("calloc: failed in %s\n", __func__);
 		return;
 	}
+	(void)j_idcode;
 
 	dp->dp_jd_index = jd_index;
-	dp->idcode = j_idcode;
+	dp->idcode = jtag_devs[jd_index].jd_idcode;
 	if ((PC_HOSTED == 0 ) || (!platform_jtag_dp_init(dp))) {
 		dp->dp_read = fw_adiv5_jtagdp_read;
 		dp->error = adiv5_jtagdp_error;

From d3ed83ba94aa7cdc56d28e3c3c49d706025917ac Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 21:11:22 -0500
Subject: [PATCH 05/12] jtag_scan: Remove the now redundant IDCode parameter
 from the handlers

---
 src/platforms/hosted/stlinkv2.c | 2 +-
 src/target/adiv5.h              | 2 +-
 src/target/adiv5_jtagdp.c       | 3 +--
 src/target/jtag_devs.h          | 2 +-
 src/target/jtag_scan.c          | 2 +-
 5 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/src/platforms/hosted/stlinkv2.c b/src/platforms/hosted/stlinkv2.c
index 1ecae9f51df..f87ffc8c3eb 100644
--- a/src/platforms/hosted/stlinkv2.c
+++ b/src/platforms/hosted/stlinkv2.c
@@ -1010,7 +1010,7 @@ int jtag_scan_stlinkv2(bmp_info_t *info, const uint8_t *irlens)
 			if((jtag_devs[i].jd_idcode & dev_descr[j].idmask) ==
 			   dev_descr[j].idcode) {
 				if(dev_descr[j].handler)
-					dev_descr[j].handler(i, dev_descr[j].idcode);
+					dev_descr[j].handler(i);
 				break;
 			}
 
diff --git a/src/target/adiv5.h b/src/target/adiv5.h
index bcaa1921b1c..189869b0492 100644
--- a/src/target/adiv5.h
+++ b/src/target/adiv5.h
@@ -285,7 +285,7 @@ void adiv5_ap_ref(ADIv5_AP_t *ap);
 void adiv5_ap_unref(ADIv5_AP_t *ap);
 void platform_add_jtag_dev(const int dev_index, const jtag_dev_t *jtag_dev);
 
-void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode);
+void adiv5_jtag_dp_handler(uint8_t jd_index);
 int platform_jtag_dp_init(ADIv5_DP_t *dp);
 int swdptap_init(ADIv5_DP_t *dp);
 
diff --git a/src/target/adiv5_jtagdp.c b/src/target/adiv5_jtagdp.c
index e4f30308be4..cf8591b4800 100644
--- a/src/target/adiv5_jtagdp.c
+++ b/src/target/adiv5_jtagdp.c
@@ -39,14 +39,13 @@
 
 static uint32_t adiv5_jtagdp_error(ADIv5_DP_t *dp);
 
-void adiv5_jtag_dp_handler(uint8_t jd_index, uint32_t j_idcode)
+void adiv5_jtag_dp_handler(uint8_t jd_index)
 {
 	ADIv5_DP_t *dp = (void*)calloc(1, sizeof(*dp));
 	if (!dp) {			/* calloc failed: heap exhaustion */
 		DEBUG_WARN("calloc: failed in %s\n", __func__);
 		return;
 	}
-	(void)j_idcode;
 
 	dp->dp_jd_index = jd_index;
 	dp->idcode = jtag_devs[jd_index].jd_idcode;
diff --git a/src/target/jtag_devs.h b/src/target/jtag_devs.h
index 8c2c0b5acd5..08adf0474bb 100644
--- a/src/target/jtag_devs.h
+++ b/src/target/jtag_devs.h
@@ -22,7 +22,7 @@ typedef const struct jtag_dev_descr_s {
 	const uint32_t idcode;
 	const uint32_t idmask;
 	const char * const descr;
-	void (*const handler)(uint8_t jd_index, uint32_t j_idcode);
+	void (*const handler)(uint8_t jd_index);
 } jtag_dev_descr_t;
 extern jtag_dev_descr_t dev_descr[];
 
diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c
index 761f5ff0311..c547ef6b57f 100644
--- a/src/target/jtag_scan.c
+++ b/src/target/jtag_scan.c
@@ -215,7 +215,7 @@ int jtag_scan(const uint8_t *irlens)
 				jtag_devs[i].jd_descr = dev_descr[j].descr;
 				/* Call handler to initialise/probe device further */
 				if(dev_descr[j].handler)
-					dev_descr[j].handler(i, dev_descr[i].idcode);
+					dev_descr[j].handler(i);
 				break;
 			}
 

From fa3dca7c2790465cd3eed2d0054a13be91513e1b Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 21:31:59 -0500
Subject: [PATCH 06/12] hosted/dap: Partial revert of 5c8e277, taking into
 account that division may not be available on platforms 'hosted' might see
 itself built

---
 src/platforms/hosted/dap.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/platforms/hosted/dap.c b/src/platforms/hosted/dap.c
index 39318b3145e..3adc424be1c 100644
--- a/src/platforms/hosted/dap.c
+++ b/src/platforms/hosted/dap.c
@@ -721,9 +721,9 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS,
 			*p++ = transfers;
 			for (int i = 0; i < transfers; i++) {
 				*p++ = 1 | ((DO) ? DAP_JTAG_TDO_CAPTURE : 0) |
-					((TMS[i / 8] & (1 << (i & 7))) ? DAP_JTAG_TMS : 0);
+					((TMS[i >> 3] & (1 << (i & 7))) ? DAP_JTAG_TMS : 0);
 				if (DI)
-					*p++ = (DI[i / 8] & (1 << (i & 7))) ? 1 : 0;
+					*p++ = (DI[i >> 3] & (1 << (i & 7))) ? 1 : 0;
 				else
 					*p++ = 1;
 			}
@@ -733,9 +733,9 @@ void dap_jtagtap_tdi_tdo_seq(uint8_t *DO, bool final_tms, const uint8_t *TMS,
 			if (DO) {
 				for (int i = 0; i < transfers; i++) {
 					if (buf[i + 1])
-						DO[i / 8] |= (1 << (i & 7));
+						DO[i >> 3] |= (1 << (i & 7));
 					else
-						DO[i / 8] &= ~(1 << (i & 7));
+						DO[i >> 3] &= ~(1 << (i & 7));
 				}
 			}
 			ticks -= transfers;

From bfde3c71f0c1d1caee9f4dc21c4db12a20551d0c Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 21:32:27 -0500
Subject: [PATCH 07/12] Revert "adiv5_swdp_scan: If SWD scan fails, try a JTAG
 scan."

This reverts commit 3df692ecb247fdc7c62f3c3dc622030ad12817e6.
---
 src/platforms/pc/cl_utils.c | 2 +-
 src/target/adiv5_swdp.c     | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/platforms/pc/cl_utils.c b/src/platforms/pc/cl_utils.c
index 7a438da171a..6a203755d2c 100644
--- a/src/platforms/pc/cl_utils.c
+++ b/src/platforms/pc/cl_utils.c
@@ -378,7 +378,7 @@ int cl_execute(BMP_CL_OPTIONS_t *opt)
 	} else {
 		num_targets = platform_adiv5_swdp_scan(opt->opt_targetid);
 		if (!num_targets) {
-			DEBUG_WARN("Scan SWD failed, trying JTAG!\n");
+			DEBUG_INFO("Scan SWD failed, trying JTAG!\n");
 			num_targets = platform_jtag_scan(NULL);
 		}
 	}
diff --git a/src/target/adiv5_swdp.c b/src/target/adiv5_swdp.c
index d29d02ac13f..d6631c554ff 100644
--- a/src/target/adiv5_swdp.c
+++ b/src/target/adiv5_swdp.c
@@ -115,7 +115,7 @@ int adiv5_swdp_scan(uint32_t targetid)
 			}
 			if (e2.type || initial_dp->fault) {
 				DEBUG_WARN("No usable DP found\n");
-				return 0;
+				return -1;
 			}
 		}
 		if ((idcode & ADIV5_DP_VERSION_MASK) == ADIV5_DPv2) {

From 62fa3b6224eed87e94eef9b992467007837b454a Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 21:41:37 -0500
Subject: [PATCH 08/12] target: Cleanup in target_new() for the check_error
 callback

---
 src/target/target.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/target/target.c b/src/target/target.c
index c8a10a5306f..6e8ba24bd38 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -34,9 +34,9 @@ static bool nop_function(void)
 	return true;
 }
 
-static int null_function(void)
+static bool false_function(void)
 {
-	return 0;
+	return false;
 }
 
 target *target_new(void)
@@ -68,7 +68,7 @@ target *target_new(void)
 	t->halt_request = (void*)nop_function;
 	t->halt_poll = (void*)nop_function;
 	t->halt_resume = (void*)nop_function;
-	t->check_error = (void*)null_function;
+	t->check_error = (void*)false_function;
 
 	t->target_storage = NULL;
 

From 192db29a6b7a1b970b69fc14316f38a6529126aa Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 22:37:02 -0500
Subject: [PATCH 09/12] jtag_devs: Added a few more parts based on 0170aff and
 cleaned up the description wording for the existing ones

---
 src/target/jtag_devs.c | 43 ++++++++++++++++++++++++++----------------
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/src/target/jtag_devs.c b/src/target/jtag_devs.c
index af55a636ee5..f8f5ea25558 100644
--- a/src/target/jtag_devs.c
+++ b/src/target/jtag_devs.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2011  Black Sphere Technologies Ltd.
  * Written by Gareth McMullin <gareth@blacksphere.co.nz>
+ * Copyright (C) 2022  1bitsquared - Rachel Mant <git@dragonmux.network>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -25,35 +26,45 @@
 
 jtag_dev_descr_t dev_descr[] = {
 	{.idcode = 0x0BA00477, .idmask = 0x0FFF0FFF,
-		.descr = "ARM Limited: ADIv5 JTAG-DP port.",
+		.descr = "ADIv5 JTAG-DP port.",
 		.handler = adiv5_jtag_dp_handler},
+	{.idcode = 0x00000477, .idmask = 0x00000FFF,
+		.descr = "Unknown ARM."},
 	{.idcode = 0x06410041, .idmask = 0x0FFFFFFF,
-		.descr = "ST Microelectronics: STM32, Medium density."},
+		.descr = "STM32, Medium density."},
 	{.idcode = 0x06412041, .idmask = 0x0FFFFFFF,
-		.descr = "ST Microelectronics: STM32, Low density."},
+		.descr = "STM32, Low density."},
 	{.idcode = 0x06414041, .idmask = 0x0FFFFFFF,
-		.descr = "ST Microelectronics: STM32, High density."},
+		.descr = "STM32, High density."},
 	{.idcode = 0x06416041, .idmask = 0x0FFFFFFF,
-		.descr = "ST Microelectronics: STM32L."},
+		.descr = "STM32L."},
 	{.idcode = 0x06418041, .idmask = 0x0FFFFFFF,
-		.descr = "ST Microelectronics: STM32, Connectivity Line."},
+		.descr = "STM32, Connectivity Line."},
 	{.idcode = 0x06420041, .idmask = 0x0FFFFFFF,
-		.descr = "ST Microelectronics: STM32, Value Line."},
+		.descr = "STM32, Value Line."},
 	{.idcode = 0x06428041, .idmask = 0x0FFFFFFF,
-		.descr = "ST Microelectronics: STM32, Value Line, High density."},
+		.descr = "STM32, Value Line, High density."},
 	{.idcode = 0x06411041, .idmask = 0xFFFFFFFF,
-		.descr = "ST Microelectronics: STM32F2xx."},
+		.descr = "STM32F2xx."},
 	{.idcode = 0x06422041, .idmask = 0xFFFFFFFF,
-		.descr = "ST Microelectronics: STM32F3xx."},
-	{.idcode = 0x06413041 , .idmask = 0xFFFFFFFF,
-		.descr = "ST Microelectronics: STM32F4xx."},
-	{.idcode = 0x0BB11477 , .idmask = 0xFFFFFFFF,
+		.descr = "STM32F3xx."},
+	{.idcode = 0x06413041, .idmask = 0xFFFFFFFF,
+		.descr = "STM32F4xx."},
+	{.idcode = 0x00000041, .idmask = 0x00000FFF,
+		.descr = "STM32 BSD."},
+	{.idcode = 0x0BB11477, .idmask = 0xFFFFFFFF,
 		.descr = "NPX: LPC11C24."},
-	{.idcode = 0x4BA00477 , .idmask = 0xFFFFFFFF,
+	{.idcode = 0x4BA00477, .idmask = 0xFFFFFFFF,
 		.descr = "NXP: LPC17xx family."},
+	{.idcode = 0x00000093, .idmask = 0x00000FFF,
+		.descr = "Xilinx."},
+	{.idcode = 0x0000063D, .idmask = 0x00000FFF,
+		.descr = "Xambala: RVDBG013."},
+	{.idcode = 0x000007A3, .idmask = 0x00000FFF,
+		.descr = "Gigadevice BSD."},
 /* Just for fun, unsupported */
-	{.idcode = 0x8940303F, .idmask = 0xFFFFFFFF, .descr = "ATMEL: ATMega16."},
-	{.idcode = 0x0792603F, .idmask = 0xFFFFFFFF, .descr = "ATMEL: AT91SAM9261."},
+	{.idcode = 0x8940303F, .idmask = 0xFFFFFFFF, .descr = "Atmel: ATMega16."},
+	{.idcode = 0x0792603F, .idmask = 0xFFFFFFFF, .descr = "Atmel: AT91SAM9261."},
 	{.idcode = 0x20270013, .idmask = 0xFFFFFFFF, .descr = "Intel: i80386ex."},
 	{.idcode = 0x07B7617F, .idmask = 0xFFFFFFFF, .descr = "Broadcom: BCM2835."},
 	{.idcode = 0x4BA00477, .idmask = 0xFFFFFFFF, .descr = "Broadcom: BCM2836."},

From e9d616cf54fca3f6cb789e7461a3620f0117625d Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 22:37:54 -0500
Subject: [PATCH 10/12] jtag_scan: Cleaned up the ones array to use a more
 correct syntax

---
 src/target/jtag_scan.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/target/jtag_scan.c b/src/target/jtag_scan.c
index c547ef6b57f..4addc4921e3 100644
--- a/src/target/jtag_scan.c
+++ b/src/target/jtag_scan.c
@@ -3,6 +3,7 @@
  *
  * Copyright (C) 2011  Black Sphere Technologies Ltd.
  * Written by Gareth McMullin <gareth@blacksphere.co.nz>
+ * Copyright (C) 2022  1bitsquared - Rachel Mant <git@dragonmux.network>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -34,7 +35,7 @@ struct jtag_dev_s jtag_devs[JTAG_MAX_DEVS+1];
 int jtag_dev_count;
 
 /* bucket of ones for don't care TDI */
-static const uint8_t ones[] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF";
+static const uint8_t ones[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 
 #if PC_HOSTED == 0
 void jtag_add_device(const int dev_index, const jtag_dev_t *jtag_dev)

From 48049624997c837b9bb9815fdb165145e2c60835 Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Fri, 21 Jan 2022 22:55:56 -0500
Subject: [PATCH 11/12] crc32: Fix the launchpad-icdi build as that was broken

---
 src/crc32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/crc32.c b/src/crc32.c
index 8ce25dff903..80e16f3a18f 100644
--- a/src/crc32.c
+++ b/src/crc32.c
@@ -132,7 +132,7 @@ int generic_crc32(target *t, uint32_t *crc_res, uint32_t base, size_t len)
 		base += read_len;
 		len -= read_len;
 	}
-	DEBUG_WARN("%d ms\n", platform_time_ms() - start_time);
+	DEBUG_WARN("%" PRIu32 " ms\n", platform_time_ms() - start_time);
 	*crc_res = crc;
 	return 0;
 }

From a15e378b93188f5854eed192fe32e3ee7f89f4c1 Mon Sep 17 00:00:00 2001
From: dragonmux <git@dragonmux.network>
Date: Mon, 14 Mar 2022 06:27:46 -0400
Subject: [PATCH 12/12] Removal of MFR descriptions as requested in #978

---
 src/target/jtag_devs.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/target/jtag_devs.c b/src/target/jtag_devs.c
index f8f5ea25558..f0ddea43df6 100644
--- a/src/target/jtag_devs.c
+++ b/src/target/jtag_devs.c
@@ -63,10 +63,10 @@ jtag_dev_descr_t dev_descr[] = {
 	{.idcode = 0x000007A3, .idmask = 0x00000FFF,
 		.descr = "Gigadevice BSD."},
 /* Just for fun, unsupported */
-	{.idcode = 0x8940303F, .idmask = 0xFFFFFFFF, .descr = "Atmel: ATMega16."},
-	{.idcode = 0x0792603F, .idmask = 0xFFFFFFFF, .descr = "Atmel: AT91SAM9261."},
-	{.idcode = 0x20270013, .idmask = 0xFFFFFFFF, .descr = "Intel: i80386ex."},
-	{.idcode = 0x07B7617F, .idmask = 0xFFFFFFFF, .descr = "Broadcom: BCM2835."},
-	{.idcode = 0x4BA00477, .idmask = 0xFFFFFFFF, .descr = "Broadcom: BCM2836."},
+	{.idcode = 0x8940303F, .idmask = 0xFFFFFFFF, .descr = "ATMega16."},
+	{.idcode = 0x0792603F, .idmask = 0xFFFFFFFF, .descr = "AT91SAM9261."},
+	{.idcode = 0x20270013, .idmask = 0xFFFFFFFF, .descr = "i80386ex."},
+	{.idcode = 0x07B7617F, .idmask = 0xFFFFFFFF, .descr = "BCM2835."},
+	{.idcode = 0x4BA00477, .idmask = 0xFFFFFFFF, .descr = "BCM2836."},
 	{.idcode = 0, .idmask = 0, .descr = "Unknown"},
 };