--- adi_v5_jtag.c	2012-05-13 12:54:02 +0800
+++ adi_v5_swd.c	2012-05-14 08:08:35 +0800
@@ -28,7 +28,7 @@
 
 /**
  * @file
- * This file implements JTAG transport support for cores implementing
+ * This file implements SWD transport support for cores implementing
  the ARM Debug Interface version 5 (ADIv5).
  */
 
@@ -40,16 +40,6 @@
 #include "arm_adi_v5.h"
 #include <helper/time_support.h>
 
-/* JTAG instructions/registers for JTAG-DP and SWJ-DP */
-#define JTAG_DP_ABORT		0x8
-#define JTAG_DP_DPACC		0xA
-#define JTAG_DP_APACC		0xB
-#define JTAG_DP_IDCODE		0xE
-
-/* three-bit ACK values for DPACC and APACC reads */
-#define JTAG_ACK_OK_FAULT	0x2
-#define JTAG_ACK_WAIT		0x1
-
 /***************************************************************************
  *
  * DPACC and APACC scanchain access through JTAG-DP (or SWJ-DP)
@@ -66,72 +56,41 @@
  * the posted result of a preceding operation, not the current one.
  *
  * @param dap the DAP
- * @param instr JTAG_DP_APACC (AP access) or JTAG_DP_DPACC (DP access)
+ * @param instr SWD_DP_APACC (AP access) or SWD_DP_DPACC (DP access)
  * @param reg_addr two significant bits; A[3:2]; for APACC access, the
  *	SELECT register has more addressing bits.
  * @param RnW false iff outvalue will be written to the DP or AP
  * @param outvalue points to a 32-bit (little-endian) integer
  * @param invalue NULL, or points to a 32-bit (little-endian) integer
- * @param ack points to where the three bit JTAG_ACK_* code will be stored
+ * @param ack points to where the three bit SWD_ACK_* code will be stored
  */
 
 /* FIXME don't export ... this is a temporary workaround for the
  * mem_ap_read_buf_u32() mess, until it's no longer JTAG-specific.
  */
-int adi_jtag_dp_scan(struct adiv5_dap *dap,
+int adi_swd_dp_scan(struct adiv5_dap *dap,
 		uint8_t instr, uint8_t reg_addr, uint8_t RnW,
 		uint8_t *outvalue, uint8_t *invalue, uint8_t *ack)
 {
-	struct arm_jtag *jtag_info = dap->jtag_info;
-	struct scan_field fields[2];
-	uint8_t out_addr_buf;
-	int retval;
-
-	retval = arm_jtag_set_instr(jtag_info, instr, NULL, TAP_IDLE);
-	if (retval != ERROR_OK)
-		return retval;
-
-	/* Scan out a read or write operation using some DP or AP register.
-	 * For APACC access with any sticky error flag set, this is discarded.
-	 */
-	fields[0].num_bits = 3;
-	buf_set_u32(&out_addr_buf, 0, 3, ((reg_addr >> 1) & 0x6) | (RnW & 0x1));
-	fields[0].out_value = &out_addr_buf;
-	fields[0].in_value = ack;
-
-	/* NOTE: if we receive JTAG_ACK_WAIT, the previous operation did not
-	 * complete; data we write is discarded, data we read is unpredictable.
-	 * When overrun detect is active, STICKYORUN is set.
-	 */
-
-	fields[1].num_bits = 32;
-	fields[1].out_value = outvalue;
-	fields[1].in_value = invalue;
-
-	jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
-
-	/* Add specified number of tck clocks after starting memory bus
-	 * access, giving the hardware time to complete the access.
-	 * They provide more time for the (MEM) AP to complete the read ...
-	 * See "Minimum Response Time" for JTAG-DP, in the ADIv5 spec.
-	 */
-	if ((instr == JTAG_DP_APACC)
-			&& ((reg_addr == AP_REG_DRW)
-				|| ((reg_addr & 0xF0) == AP_REG_BD0))
-			&& (dap->memaccess_tck != 0))
-		jtag_add_runtest(dap->memaccess_tck,
-				TAP_IDLE);
+	if (RnW == DPAP_READ)
+	{
+		swd_add_transact_in(instr, 1, reg_addr, (uint32_t *)invalue, ack);
+	}
+	else
+	{
+		swd_add_transact_out(instr, 0, reg_addr, *(uint32_t *)outvalue, ack);
+	}
 
 	return ERROR_OK;
 }
 
 /**
  * Scan DPACC or APACC out and in from host ordered uint32_t buffers.
- * This is exactly like adi_jtag_dp_scan(), except that endianness
+ * This is exactly like adi_swd_dp_scan(), except that endianness
  * conversions are performed (so the types of invalue and outvalue
  * must be different).
  */
-static int adi_jtag_dp_scan_u32(struct adiv5_dap *dap,
+static int adi_swd_dp_scan_u32(struct adiv5_dap *dap,
 		uint8_t instr, uint8_t reg_addr, uint8_t RnW,
 		uint32_t outvalue, uint32_t *invalue, uint8_t *ack)
 {
@@ -140,7 +99,7 @@
 
 	buf_set_u32(out_value_buf, 0, 32, outvalue);
 
-	retval = adi_jtag_dp_scan(dap, instr, reg_addr, RnW,
+	retval = adi_swd_dp_scan(dap, instr, reg_addr, RnW,
 			out_value_buf, (uint8_t *)invalue, ack);
 	if (retval != ERROR_OK)
 		return retval;
@@ -155,35 +114,37 @@
 /**
  * Utility to write AP registers.
  */
-static inline int adi_jtag_ap_write_check(struct adiv5_dap *dap,
+static inline int adi_swd_ap_write_check(struct adiv5_dap *dap,
 		uint8_t reg_addr, uint8_t *outvalue)
 {
-	return adi_jtag_dp_scan(dap, JTAG_DP_APACC, reg_addr, DPAP_WRITE,
+	return adi_swd_dp_scan(dap, SWD_DP_APACC, reg_addr, DPAP_WRITE,
 			outvalue, NULL, NULL);
 }
 
-static int adi_jtag_scan_inout_check_u32(struct adiv5_dap *dap,
+static int adi_swd_scan_inout_check_u32(struct adiv5_dap *dap,
 		uint8_t instr, uint8_t reg_addr, uint8_t RnW,
 		uint32_t outvalue, uint32_t *invalue)
 {
 	int retval;
 
 	/* Issue the read or write */
-	retval = adi_jtag_dp_scan_u32(dap, instr, reg_addr,
-			RnW, outvalue, NULL, NULL);
+	// DIFF
+	retval = adi_swd_dp_scan_u32(dap, instr, reg_addr,
+			RnW, outvalue, invalue, NULL);
 	if (retval != ERROR_OK)
 		return retval;
 
 	/* For reads,  collect posted value; RDBUFF has no other effect.
 	 * Assumes read gets acked with OK/FAULT, and CTRL_STAT says "OK".
 	 */
-	if ((RnW == DPAP_READ) && (invalue != NULL))
-		retval = adi_jtag_dp_scan_u32(dap, JTAG_DP_DPACC,
+	// DIFF
+	if ((RnW == DPAP_READ) && (invalue != NULL) && (instr == SWD_DP_APACC))
+		retval = adi_swd_dp_scan_u32(dap, SWD_DP_DPACC,
 				DP_RDBUFF, DPAP_READ, 0, invalue, &dap->ack);
 	return retval;
 }
 
-static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
+static int swddp_transaction_endcheck(struct adiv5_dap *dap)
 {
 	int retval;
 	uint32_t ctrlstat;
@@ -218,7 +179,7 @@
 	/* Post CTRL/STAT read; discard any previous posted read value
 	 * but collect its ACK status.
 	 */
-	retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+	retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
 			DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
 	if (retval != ERROR_OK)
 		return retval;
@@ -229,28 +190,28 @@
 	dap->ack = dap->ack & 0x7;
 
 	/* common code path avoids calling timeval_ms() */
-	if (dap->ack != JTAG_ACK_OK_FAULT) {
+	if (dap->ack != SWD_ACK_OK) {
 		long long then = timeval_ms();
 
-		while (dap->ack != JTAG_ACK_OK_FAULT) {
-			if (dap->ack == JTAG_ACK_WAIT) {
+		while (dap->ack != SWD_ACK_OK) {
+			if (dap->ack == SWD_ACK_WAIT) {
 				if ((timeval_ms()-then) > 1000) {
 					/* NOTE:  this would be a good spot
 					 * to use JTAG_DP_ABORT.
 					 */
 					LOG_WARNING("Timeout (1000ms) waiting "
 						"for ACK=OK/FAULT "
-						"in JTAG-DP transaction");
+						"in swd-DP transaction");
 					return ERROR_JTAG_DEVICE_ERROR;
 				}
 			} else {
 				LOG_WARNING("Invalid ACK %#x "
-						"in JTAG-DP transaction",
+						"in swd-DP transaction",
 						dap->ack);
 				return ERROR_JTAG_DEVICE_ERROR;
 			}
 
-			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
 					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
 			if (retval != ERROR_OK)
 				return retval;
@@ -265,7 +226,7 @@
 
 	/* Check for STICKYERR and STICKYORUN */
 	if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) {
-		LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
+		LOG_DEBUG("swd-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
 		/* Check power to debug regions */
 		if ((ctrlstat & 0xf0000000) != 0xf0000000) {
 			retval = ahbap_debugport_init(dap);
@@ -288,20 +249,21 @@
 					dap->ap_tar_value);
 
 			if (ctrlstat & SSTICKYORUN)
-				LOG_ERROR("JTAG-DP OVERRUN - check clock, "
-					"memaccess, or reduce jtag speed");
+				LOG_ERROR("SWD-DP OVERRUN - check clock, "
+					"memaccess, or reduce swd speed");
 
 			if (ctrlstat & SSTICKYERR)
-				LOG_ERROR("JTAG-DP STICKY ERROR");
+				LOG_ERROR("SWD-DP STICKY ERROR");
 
 			/* Clear Sticky Error Bits */
-			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
-					DP_CTRL_STAT, DPAP_WRITE,
-					dap->dp_ctrl_stat | SSTICKYORUN
-						| SSTICKYERR, NULL);
+			// DIFF
+			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+					DP_ABORT, DPAP_WRITE,
+					dap->dp_ctrl_stat | ORUNERRCLR
+						| STKERRCLR, NULL);
 			if (retval != ERROR_OK)
 				return retval;
-			retval = adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+			retval = adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
 					DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
 			if (retval != ERROR_OK)
 				return retval;
@@ -309,7 +271,7 @@
 			if (retval != ERROR_OK)
 				return retval;
 
-			LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
+			LOG_DEBUG("swd-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
 
 			retval = dap_queue_ap_read(dap,
 					AP_REG_CSW, &mem_ap_csw);
@@ -339,46 +301,29 @@
 
 /*--------------------------------------------------------------------------*/
 
-static int jtag_idcode_q_read(struct adiv5_dap *dap,
+static int swd_idcode_q_read(struct adiv5_dap *dap,
 		uint8_t *ack, uint32_t *data)
 {
-	struct arm_jtag *jtag_info = dap->jtag_info;
-	int retval;
-	struct scan_field fields[1];
-
-	/* This is a standard JTAG operation -- no DAP tweakage */
-	retval = arm_jtag_set_instr(jtag_info, JTAG_DP_IDCODE, NULL, TAP_IDLE);
-	if (retval != ERROR_OK)
-		return retval;
-
-	fields[0].num_bits = 32;
-	fields[0].out_value = NULL;
-	fields[0].in_value = (void *) data;
-
-	jtag_add_dr_scan(jtag_info->tap, 1, fields, TAP_IDLE);
-
-	jtag_add_callback(arm_le_to_h_u32,
-			(jtag_callback_data_t) data);
-
-	return ERROR_OK;
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
+			DP_IDCODE, DPAP_READ, 0, data);
 }
 
-static int jtag_dp_q_read(struct adiv5_dap *dap, unsigned reg,
+static int swd_dp_q_read(struct adiv5_dap *dap, unsigned reg,
 		uint32_t *data)
 {
-	return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
 			reg, DPAP_READ, 0, data);
 }
 
-static int jtag_dp_q_write(struct adiv5_dap *dap, unsigned reg,
+static int swd_dp_q_write(struct adiv5_dap *dap, unsigned reg,
 		uint32_t data)
 {
-	return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_DPACC,
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_DPACC,
 			reg, DPAP_WRITE, data, NULL);
 }
 
 /** Select the AP register bank matching bits 7:4 of reg. */
-static int jtag_ap_q_bankselect(struct adiv5_dap *dap, unsigned reg)
+static int swd_ap_q_bankselect(struct adiv5_dap *dap, unsigned reg)
 {
 	uint32_t select_ap_bank = reg & 0x000000F0;
 
@@ -388,106 +333,293 @@
 
 	select_ap_bank |= dap->ap_current;
 
-	return jtag_dp_q_write(dap, DP_SELECT, select_ap_bank);
+	return swd_dp_q_write(dap, DP_SELECT, select_ap_bank);
 }
 
-static int jtag_ap_q_read(struct adiv5_dap *dap, unsigned reg,
+static int swd_ap_q_read(struct adiv5_dap *dap, unsigned reg,
 		uint32_t *data)
 {
-	int retval = jtag_ap_q_bankselect(dap, reg);
+	int retval = swd_ap_q_bankselect(dap, reg);
 
 	if (retval != ERROR_OK)
 		return retval;
 
-	return adi_jtag_scan_inout_check_u32(dap, JTAG_DP_APACC, reg,
+	return adi_swd_scan_inout_check_u32(dap, SWD_DP_APACC, reg,
 			DPAP_READ, 0, data);
 }
 
-static int jtag_ap_q_write(struct adiv5_dap *dap, unsigned reg,
+static int swd_ap_q_write(struct adiv5_dap *dap, unsigned reg,
 		uint32_t data)
 {
 	uint8_t out_value_buf[4];
 
-	int retval = jtag_ap_q_bankselect(dap, reg);
+	int retval = swd_ap_q_bankselect(dap, reg);
 	if (retval != ERROR_OK)
 		return retval;
 
 	buf_set_u32(out_value_buf, 0, 32, data);
 
-	return adi_jtag_ap_write_check(dap, reg, out_value_buf);
+	return adi_swd_ap_write_check(dap, reg, out_value_buf);
 }
 
-static int jtag_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)
+static int swd_ap_q_abort(struct adiv5_dap *dap, uint8_t *ack)
 {
-	/* for JTAG, this is the only valid ABORT register operation */
-	return adi_jtag_dp_scan_u32(dap, JTAG_DP_ABORT,
-			0, DPAP_WRITE, 1, NULL, ack);
+	return ERROR_OK;
 }
 
-static int jtag_dp_run(struct adiv5_dap *dap)
+static int swd_dp_run(struct adiv5_dap *dap)
 {
-	return jtagdp_transaction_endcheck(dap);
+	dap->ack = SWD_ACK_OK;
+	return swddp_transaction_endcheck(dap);
 }
 
 /* FIXME don't export ... just initialize as
  * part of DAP setup
 */
-const struct dap_ops jtag_dp_ops = {
-	.queue_idcode_read =	jtag_idcode_q_read,
-	.queue_dp_read =	jtag_dp_q_read,
-	.queue_dp_write =	jtag_dp_q_write,
-	.queue_ap_read =	jtag_ap_q_read,
-	.queue_ap_write =	jtag_ap_q_write,
-	.queue_ap_abort =	jtag_ap_q_abort,
-	.queue_dp_scan =	adi_jtag_dp_scan,
-	.run =			jtag_dp_run,
+const struct dap_ops swd_dp_ops = {
+	.queue_idcode_read =	swd_idcode_q_read,
+	.queue_dp_read =	swd_dp_q_read,
+	.queue_dp_write =	swd_dp_q_write,
+	.queue_ap_read =	swd_ap_q_read,
+	.queue_ap_write =	swd_ap_q_write,
+	.queue_ap_abort =	swd_ap_q_abort,
+	.queue_dp_scan =	adi_swd_dp_scan,
+	.run =			swd_dp_run,
 };
 
-
-static const uint8_t swd2jtag_bitseq[] = {
+static const uint8_t jtag2swd_bitseq[] = {
 	/* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
 	 * putting both JTAG and SWD logic into reset state.
 	 */
 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-	/* Switching equence disables SWD and enables JTAG
-	 * NOTE: bits in the DP's IDCODE can expose the need for
-	 * the old/deprecated sequence (0xae 0xde).
+	/* Switching sequence enables SWD and disables JTAG
+	 * NOTE: bits in the DP's IDCODE may expose the need for
+	 * an old/obsolete/deprecated sequence (0xb6 0xed).
 	 */
-	0x3c, 0xe7,
-	/* At least 50 TCK/SWCLK cycles with TMS/SWDIO high,
+	0x9e, 0xe7,
+	/* More than 50 TCK/SWCLK cycles with TMS/SWDIO high,
 	 * putting both JTAG and SWD logic into reset state.
-	 * NOTE:  some docs say "at least 5".
 	 */
-	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
 };
 
-/** Put the debug link into JTAG mode, if the target supports it.
- * The link's initial mode may be either SWD or JTAG.
+/** Put the debug link into SWD mode, if the target supports it.
+ * The link's initial mode may be either JTAG (for example,
+ * with SWJ-DP after reset) or SWD.
  *
- * @param target Enters JTAG mode (if possible).
+ * @param target Enters SWD mode (if possible).
  *
- * Note that targets implemented with SW-DP do not support JTAG, and
- * that some targets which could otherwise support it may have been
- * configured to disable JTAG signaling
+ * Note that targets using the JTAG-DP do not support SWD, and that
+ * some targets which could otherwise support it may have have been
+ * configured to disable SWD signaling
  *
  * @return ERROR_OK or else a fault code.
  */
-int dap_to_jtag(struct target *target)
+int dap_to_swd(struct target *target)
 {
+//	struct arm *arm = target_to_arm(target);
 	int retval;
 
-	LOG_DEBUG("Enter JTAG mode");
+	LOG_DEBUG("Enter SWD mode");
 
 	/* REVISIT it's nasty to need to make calls to a "jtag"
 	 * subsystem if the link isn't in JTAG mode...
 	 */
 
-	retval = jtag_add_tms_seq(8 * sizeof(swd2jtag_bitseq),
-			swd2jtag_bitseq, TAP_RESET);
-	if (retval == ERROR_OK)
-		retval = jtag_execute_queue();
+	swd_add_sequence((uint8_t*)jtag2swd_bitseq, sizeof(jtag2swd_bitseq) * 8);
+	retval = jtag_execute_queue();
+
+	/* set up the DAP's ops vector for SWD mode. */
+//	arm->dap->ops = &swd_dap_ops;
+
+	return retval;
+}
+
+
+
+
+#include <transport/transport.h>
+#include <jtag/interface.h>
+
+#include <jtag/swd.h>
+
+COMMAND_HANDLER(handle_swd_wcr)
+{
+	int retval;
+	struct target *target = get_current_target(CMD_CTX);
+	struct arm *arm = target_to_arm(target);
+	struct adiv5_dap *dap = arm->dap;
+	uint32_t wcr;
+	unsigned trn, scale = 0;
+
+	switch (CMD_ARGC) {
+	/* no-args: just dump state */
+	case 0:
+		/*retval = swd_queue_dp_read(dap, DP_WCR, &wcr); */
+		retval = dap_queue_dp_read(dap, DP_WCR, &wcr);
+		if (retval == ERROR_OK)
+			dap->ops->run(dap);
+		if (retval != ERROR_OK) {
+			LOG_ERROR("can't read WCR?");
+			return retval;
+		}
+
+		command_print(CMD_CTX,
+			"turnaround=%d, prescale=%d",
+			WCR_TO_TRN(wcr),
+			WCR_TO_PRESCALE(wcr));
+	return ERROR_OK;
+
+	case 2:		/* TRN and prescale */
+		COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], scale);
+		if (scale > 7) {
+			LOG_ERROR("prescale %d is too big", scale);
+			return ERROR_FAIL;
+		}
+		/* FALL THROUGH */
+
+	case 1:		/* TRN only */
+		COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], trn);
+		if (trn < 1 || trn > 4) {
+			LOG_ERROR("turnaround %d is invalid", trn);
+			return ERROR_FAIL;
+		}
+
+		wcr = ((trn - 1) << 8) | scale;
+		/* FIXME
+		 * write WCR ...
+		 * then, re-init adapter with new TRN
+		 */
+		LOG_ERROR("can't yet modify WCR");
+		return ERROR_FAIL;
 
-	/* REVISIT set up the DAP's ops vector for JTAG mode. */
+	default:	/* too many arguments */
+		return ERROR_COMMAND_SYNTAX_ERROR;
+	}
+}
+
+static const struct command_registration swd_commands[] = {
+	{
+		/*
+		 * Set up SWD and JTAG targets identically, unless/until
+		 * infrastructure improves ...  meanwhile, ignore all
+		 * JTAG-specific stuff like IR length for SWD.
+		 *
+		 * REVISIT can we verify "just one SWD DAP" here/early?
+		 */
+		.name = "newdap",
+		.jim_handler = jim_jtag_newtap,
+		.mode = COMMAND_CONFIG,
+		.help = "declare a new SWD DAP"
+	},
+	{
+		.name = "wcr",
+		.handler = handle_swd_wcr,
+		.mode = COMMAND_ANY,
+		.help = "display or update DAP's WCR register",
+		.usage = "turnaround (1..4), prescale (0..7)",
+	},
+
+	/* REVISIT -- add a command for SWV trace on/off */
+	COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration swd_handlers[] = {
+	{
+		.name = "swd",
+		.mode = COMMAND_ANY,
+		.help = "SWD command group",
+		.chain = swd_commands,
+	},
+	COMMAND_REGISTRATION_DONE
+};
+
+static int swd_select(struct command_context *ctx)
+{
+//	struct target *target = get_current_target(ctx);
+	int retval;
+
+	retval = register_commands(ctx, NULL, swd_handlers);
+
+	if (retval != ERROR_OK)
+		return retval;
+
+	retval = jtag_register_commands(ctx);
+
+	if (retval != ERROR_OK)
+		return retval;
+#if 0
+	 /* be sure driver is in SWD mode; start
+	  * with hardware default TRN (1), it can be changed later
+	  */
+	if (!swd || !swd->read_reg || !swd->write_reg || !swd->init) {
+		LOG_DEBUG("no SWD driver?");
+		return ERROR_FAIL;
+	}
+
+	 retval = swd->init(1);
+	if (retval != ERROR_OK) {
+		LOG_DEBUG("can't init SWD driver");
+		return retval;
+	}
 
+	/* force DAP into SWD mode (not JTAG) */
+	retval = dap_to_swd(target);
+#endif
 	return retval;
 }
+
+static int swd_init(struct command_context *ctx)
+{
+#if 0
+	struct target *target = get_current_target(ctx);
+	struct arm *arm = target_to_arm(target);
+	struct adiv5_dap *dap = arm->dap;
+	uint32_t idcode;
+	int status;
+
+	/* FIXME validate transport config ... is the
+	 * configured DAP present (check IDCODE)?
+	 * Is *only* one DAP configured?
+	 *
+	 * MUST READ IDCODE
+	 */
+
+ /* Note, debugport_init() does setup too */
+
+	uint8_t ack;
+
+	status = swd_queue_idcode_read(dap, &ack, &idcode);
+
+	if (status == ERROR_OK)
+		LOG_INFO("SWD IDCODE %#8.8x", idcode);
+
+	return status;
+
+#endif
+	int retval;
+	jtag_add_reset(0, 0);
+	if ((retval = jtag_execute_queue()) != ERROR_OK)
+		return retval;
+	return ERROR_OK;
+}
+
+static struct transport swd_transport = {
+	.name = "swd",
+	.select = swd_select,
+	.init = swd_init,
+};
+
+static void swd_constructor(void) __attribute__((constructor));
+static void swd_constructor(void)
+{
+	transport_register(&swd_transport);
+}
+
+/** Returns true if the current debug session
+ * is using SWD as its transport.
+ */
+bool transport_is_swd(void)
+{
+	return get_current_transport() == &swd_transport;
+}
