adapter: add command "adapter [de]assert srst|trst [[de]assert srst|trst]"
[fw/openocd] / src / jtag / core.c
index eb01abc7147aeec1ed74f7182b1f463829c4a983..871b4d2bd07b83fe6010c3d63d5a787747ee945c 100644 (file)
@@ -23,9 +23,7 @@
  *   GNU General Public License for more details.                          *
  *                                                                         *
  *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
+ *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -36,6 +34,9 @@
 #include "swd.h"
 #include "interface.h"
 #include <transport/transport.h>
+#include <helper/jep106.h>
+#include <jtag/hla/hla_transport.h>
+#include <jtag/hla/hla_interface.h>
 
 #ifdef HAVE_STRINGS_H
 #include <strings.h>
@@ -649,6 +650,12 @@ void swd_add_reset(int req_srst)
                        if (adapter_nsrst_delay)
                                jtag_add_sleep(adapter_nsrst_delay * 1000);
                }
+
+               retval = jtag_execute_queue();
+               if (retval != ERROR_OK) {
+                       LOG_ERROR("SRST timings error");
+                       return;
+               }
        }
 }
 
@@ -831,7 +838,75 @@ int default_interface_jtag_execute_queue(void)
                return ERROR_FAIL;
        }
 
-       return jtag->execute_queue();
+       int result = jtag->execute_queue();
+
+#if !BUILD_ZY1000
+       /* Only build this if we use a regular driver with a command queue.
+        * Otherwise jtag_command_queue won't be found at compile/link time. Its
+        * definition is in jtag/commands.c, which is only built/linked by
+        * jtag/Makefile.am if MINIDRIVER_DUMMY || !MINIDRIVER, but those variables
+        * aren't accessible here. */
+       struct jtag_command *cmd = jtag_command_queue;
+       while (debug_level >= LOG_LVL_DEBUG && cmd) {
+               switch (cmd->type) {
+                       case JTAG_SCAN:
+                               LOG_DEBUG_IO("JTAG %s SCAN to %s",
+                                               cmd->cmd.scan->ir_scan ? "IR" : "DR",
+                                               tap_state_name(cmd->cmd.scan->end_state));
+                               for (int i = 0; i < cmd->cmd.scan->num_fields; i++) {
+                                       struct scan_field *field = cmd->cmd.scan->fields + i;
+                                       if (field->out_value) {
+                                               char *str = buf_to_str(field->out_value, field->num_bits, 16);
+                                               LOG_DEBUG_IO("  %db out: %s", field->num_bits, str);
+                                               free(str);
+                                       }
+                                       if (field->in_value) {
+                                               char *str = buf_to_str(field->in_value, field->num_bits, 16);
+                                               LOG_DEBUG_IO("  %db  in: %s", field->num_bits, str);
+                                               free(str);
+                                       }
+                               }
+                               break;
+                       case JTAG_TLR_RESET:
+                               LOG_DEBUG_IO("JTAG TLR RESET to %s",
+                                               tap_state_name(cmd->cmd.statemove->end_state));
+                               break;
+                       case JTAG_RUNTEST:
+                               LOG_DEBUG_IO("JTAG RUNTEST %d cycles to %s",
+                                               cmd->cmd.runtest->num_cycles,
+                                               tap_state_name(cmd->cmd.runtest->end_state));
+                               break;
+                       case JTAG_RESET:
+                               {
+                                       const char *reset_str[3] = {
+                                               "leave", "deassert", "assert"
+                                       };
+                                       LOG_DEBUG_IO("JTAG RESET %s TRST, %s SRST",
+                                                       reset_str[cmd->cmd.reset->trst + 1],
+                                                       reset_str[cmd->cmd.reset->srst + 1]);
+                               }
+                               break;
+                       case JTAG_PATHMOVE:
+                               LOG_DEBUG_IO("JTAG PATHMOVE (TODO)");
+                               break;
+                       case JTAG_SLEEP:
+                               LOG_DEBUG_IO("JTAG SLEEP (TODO)");
+                               break;
+                       case JTAG_STABLECLOCKS:
+                               LOG_DEBUG_IO("JTAG STABLECLOCKS (TODO)");
+                               break;
+                       case JTAG_TMS:
+                               LOG_DEBUG_IO("JTAG TMS (TODO)");
+                               break;
+                       default:
+                               LOG_ERROR("Unknown JTAG command: %d", cmd->type);
+                               break;
+               }
+               cmd = cmd->next;
+       }
+#endif
+
+       return result;
 }
 
 void jtag_execute_queue_noclear(void)
@@ -886,12 +961,10 @@ void jtag_sleep(uint32_t us)
                alive_sleep((us+999)/1000);
 }
 
-/* Maximum number of enabled JTAG devices we expect in the scan chain,
- * plus one (to detect garbage at the end).  Devices that don't support
- * IDCODE take up fewer bits, possibly allowing a few more devices.
- */
-#define JTAG_MAX_CHAIN_SIZE 20
+#define JTAG_MAX_AUTO_TAPS 20
 
+#define EXTRACT_JEP106_BANK(X) (((X) & 0xf00) >> 8)
+#define EXTRACT_JEP106_ID(X)   (((X) & 0xfe) >> 1)
 #define EXTRACT_MFG(X)  (((X) & 0xffe) >> 1)
 #define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)
 #define EXTRACT_VER(X)  (((X) & 0xf0000000) >> 28)
@@ -913,7 +986,7 @@ static int jtag_examine_chain_execute(uint8_t *idcode_buffer, unsigned num_idcod
        };
 
        /* initialize to the end of chain ID value */
-       for (unsigned i = 0; i < JTAG_MAX_CHAIN_SIZE; i++)
+       for (unsigned i = 0; i < num_idcode; i++)
                buf_set_u32(idcode_buffer, i * 32, 32, END_OF_CHAIN_FLAG);
 
        jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, TAP_DRPAUSE);
@@ -955,10 +1028,11 @@ static void jtag_examine_chain_display(enum log_levels level, const char *msg,
 {
        log_printf_lf(level, __FILE__, __LINE__, __func__,
                "JTAG tap: %s %16.16s: 0x%08x "
-               "(mfg: 0x%3.3x, part: 0x%4.4x, ver: 0x%1.1x)",
+               "(mfg: 0x%3.3x (%s), part: 0x%4.4x, ver: 0x%1.1x)",
                name, msg,
                (unsigned int)idcode,
                (unsigned int)EXTRACT_MFG(idcode),
+               jep106_manufacturer(EXTRACT_JEP106_BANK(idcode), EXTRACT_JEP106_ID(idcode)),
                (unsigned int)EXTRACT_PART(idcode),
                (unsigned int)EXTRACT_VER(idcode));
 }
@@ -998,21 +1072,16 @@ static bool jtag_examine_chain_end(uint8_t *idcodes, unsigned count, unsigned ma
 
 static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
 {
-       uint32_t idcode = tap->idcode;
 
-       /* ignore expected BYPASS codes; warn otherwise */
-       if (0 == tap->expected_ids_cnt && !idcode)
+       if (tap->expected_ids_cnt == 0 || !tap->hasidcode)
                return true;
 
        /* optionally ignore the JTAG version field - bits 28-31 of IDCODE */
-       uint32_t mask = tap->ignore_version ? ~(0xf << 28) : ~0;
-
-       idcode &= mask;
+       uint32_t mask = tap->ignore_version ? ~(0xfU << 28) : ~0U;
+       uint32_t idcode = tap->idcode & mask;
 
        /* Loop over the expected identification codes and test for a match */
-       unsigned ii, limit = tap->expected_ids_cnt;
-
-       for (ii = 0; ii < limit; ii++) {
+       for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
                uint32_t expected = tap->expected_ids[ii] & mask;
 
                if (idcode == expected)
@@ -1026,10 +1095,10 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
        /* If none of the expected ids matched, warn */
        jtag_examine_chain_display(LOG_LVL_WARNING, "UNEXPECTED",
                tap->dotted_name, tap->idcode);
-       for (ii = 0; ii < limit; ii++) {
+       for (unsigned ii = 0; ii < tap->expected_ids_cnt; ii++) {
                char msg[32];
 
-               snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, limit);
+               snprintf(msg, sizeof(msg), "expected %u of %u", ii + 1, tap->expected_ids_cnt);
                jtag_examine_chain_display(LOG_LVL_ERROR, msg,
                        tap->dotted_name, tap->expected_ids[ii]);
        }
@@ -1041,130 +1110,109 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
  */
 static int jtag_examine_chain(void)
 {
-       uint8_t idcode_buffer[JTAG_MAX_CHAIN_SIZE * 4];
-       unsigned bit_count;
        int retval;
-       int tapcount = 0;
-       bool autoprobe = false;
+       unsigned max_taps = jtag_tap_count();
+
+       /* Autoprobe up to this many. */
+       if (max_taps < JTAG_MAX_AUTO_TAPS)
+               max_taps = JTAG_MAX_AUTO_TAPS;
+
+       /* Add room for end-of-chain marker. */
+       max_taps++;
+
+       uint8_t *idcode_buffer = malloc(max_taps * 4);
+       if (idcode_buffer == NULL)
+               return ERROR_JTAG_INIT_FAILED;
 
        /* DR scan to collect BYPASS or IDCODE register contents.
         * Then make sure the scan data has both ones and zeroes.
         */
        LOG_DEBUG("DR scan interrogation for IDCODE/BYPASS");
-       retval = jtag_examine_chain_execute(idcode_buffer, JTAG_MAX_CHAIN_SIZE);
+       retval = jtag_examine_chain_execute(idcode_buffer, max_taps);
        if (retval != ERROR_OK)
-               return retval;
-       if (!jtag_examine_chain_check(idcode_buffer, JTAG_MAX_CHAIN_SIZE))
-               return ERROR_JTAG_INIT_FAILED;
+               goto out;
+       if (!jtag_examine_chain_check(idcode_buffer, max_taps)) {
+               retval = ERROR_JTAG_INIT_FAILED;
+               goto out;
+       }
 
-       /* point at the 1st tap */
+       /* Point at the 1st predefined tap, if any */
        struct jtag_tap *tap = jtag_tap_next_enabled(NULL);
 
-       if (!tap)
-               autoprobe = true;
-
-       for (bit_count = 0;
-            tap && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;
-            tap = jtag_tap_next_enabled(tap)) {
+       unsigned bit_count = 0;
+       unsigned autocount = 0;
+       for (unsigned i = 0; i < max_taps; i++) {
+               assert(bit_count < max_taps * 32);
                uint32_t idcode = buf_get_u32(idcode_buffer, bit_count, 32);
 
+               /* No predefined TAP? Auto-probe. */
+               if (tap == NULL) {
+                       /* Is there another TAP? */
+                       if (jtag_idcode_is_final(idcode))
+                               break;
+
+                       /* Default everything in this TAP except IR length.
+                        *
+                        * REVISIT create a jtag_alloc(chip, tap) routine, and
+                        * share it with jim_newtap_cmd().
+                        */
+                       tap = calloc(1, sizeof *tap);
+                       if (!tap) {
+                               retval = ERROR_FAIL;
+                               goto out;
+                       }
+
+                       tap->chip = alloc_printf("auto%u", autocount++);
+                       tap->tapname = strdup("tap");
+                       tap->dotted_name = alloc_printf("%s.%s", tap->chip, tap->tapname);
+
+                       tap->ir_length = 0; /* ... signifying irlen autoprobe */
+                       tap->ir_capture_mask = 0x03;
+                       tap->ir_capture_value = 0x01;
+
+                       tap->enabled = true;
+
+                       jtag_tap_init(tap);
+               }
+
                if ((idcode & 1) == 0) {
                        /* Zero for LSB indicates a device in bypass */
-                       LOG_INFO("TAP %s does not have IDCODE",
-                               tap->dotted_name);
-                       idcode = 0;
+                       LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%x)",
+                                       tap->dotted_name, idcode);
                        tap->hasidcode = false;
+                       tap->idcode = 0;
 
                        bit_count += 1;
                } else {
                        /* Friendly devices support IDCODE */
                        tap->hasidcode = true;
-                       jtag_examine_chain_display(LOG_LVL_INFO,
-                               "tap/device found",
-                               tap->dotted_name, idcode);
+                       tap->idcode = idcode;
+                       jtag_examine_chain_display(LOG_LVL_INFO, "tap/device found", tap->dotted_name, idcode);
 
                        bit_count += 32;
                }
-               tap->idcode = idcode;
 
                /* ensure the TAP ID matches what was expected */
                if (!jtag_examine_chain_match_tap(tap))
                        retval = ERROR_JTAG_INIT_SOFT_FAIL;
-       }
-
-       /* Fail if too many TAPs were enabled for us to verify them all. */
-       if (tap) {
-               LOG_ERROR("Too many TAPs enabled; '%s' ignored.",
-                       tap->dotted_name);
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       /* if autoprobing, the tap list is still empty ... populate it! */
-       while (autoprobe && bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31) {
-               uint32_t idcode;
-               char buf[12];
-
-               /* Is there another TAP? */
-               idcode = buf_get_u32(idcode_buffer, bit_count, 32);
-               if (jtag_idcode_is_final(idcode))
-                       break;
-
-               /* Default everything in this TAP except IR length.
-                *
-                * REVISIT create a jtag_alloc(chip, tap) routine, and
-                * share it with jim_newtap_cmd().
-                */
-               tap = calloc(1, sizeof *tap);
-               if (!tap)
-                       return ERROR_FAIL;
-
-               sprintf(buf, "auto%d", tapcount++);
-               tap->chip = strdup(buf);
-               tap->tapname = strdup("tap");
-
-               sprintf(buf, "%s.%s", tap->chip, tap->tapname);
-               tap->dotted_name = strdup(buf);
-
-               /* tap->ir_length == 0 ... signifying irlen autoprobe */
-               tap->ir_capture_mask = 0x03;
-               tap->ir_capture_value = 0x01;
 
-               tap->enabled = true;
-
-               if ((idcode & 1) == 0) {
-                       bit_count += 1;
-                       tap->hasidcode = false;
-               } else {
-                       bit_count += 32;
-                       tap->hasidcode = true;
-                       tap->idcode = idcode;
-
-                       tap->expected_ids_cnt = 1;
-                       tap->expected_ids = malloc(sizeof(uint32_t));
-                       tap->expected_ids[0] = idcode;
-               }
-
-               LOG_WARNING("AUTO %s - use \"jtag newtap "
-                       "%s %s -expected-id 0x%8.8" PRIx32 " ...\"",
-                       tap->dotted_name, tap->chip, tap->tapname,
-                       tap->idcode);
-
-               jtag_tap_init(tap);
+               tap = jtag_tap_next_enabled(tap);
        }
 
        /* After those IDCODE or BYPASS register values should be
         * only the data we fed into the scan chain.
         */
-       if (jtag_examine_chain_end(idcode_buffer, bit_count,
-                   8 * sizeof(idcode_buffer))) {
-               LOG_ERROR("double-check your JTAG setup (interface, "
-                       "speed, missing TAPs, ...)");
-               return ERROR_JTAG_INIT_FAILED;
+       if (jtag_examine_chain_end(idcode_buffer, bit_count, max_taps * 32)) {
+               LOG_ERROR("double-check your JTAG setup (interface, speed, ...)");
+               retval = ERROR_JTAG_INIT_FAILED;
+               goto out;
        }
 
        /* Return success or, for backwards compatibility if only
         * some IDCODE values mismatched, a soft/continuable fault.
         */
+out:
+       free(idcode_buffer);
        return retval;
 }
 
@@ -1227,7 +1275,7 @@ static int jtag_validate_ircapture(void)
                 * least two bits.  Guessing will fail if (a) any TAP does
                 * not conform to the JTAG spec; or (b) when the upper bits
                 * captured from some conforming TAP are nonzero.  Or if
-                * (c) an IR length is longer than 32 bits -- which is only
+                * (c) an IR length is longer than JTAG_IRLEN_MAX bits,
                 * an implementation limit, which could someday be raised.
                 *
                 * REVISIT optimization:  if there's a *single* TAP we can
@@ -1242,11 +1290,12 @@ static int jtag_validate_ircapture(void)
                if (tap->ir_length == 0) {
                        tap->ir_length = 2;
                        while ((val = buf_get_u64(ir_test, chain_pos, tap->ir_length + 1)) == 1
-                                       && tap->ir_length <= 64) {
+                                       && tap->ir_length < JTAG_IRLEN_MAX) {
                                tap->ir_length++;
                        }
-                       LOG_WARNING("AUTO %s - use \"... -irlen %d\"",
-                               jtag_tap_name(tap), tap->ir_length);
+                       LOG_WARNING("AUTO %s - use \"jtag newtap " "%s %s -irlen %d "
+                                       "-expected-id 0x%08" PRIx32 "\"",
+                                       tap->dotted_name, tap->chip, tap->tapname, tap->ir_length, tap->idcode);
                }
 
                /* Validate the two LSBs, which must be 01 per JTAG spec.
@@ -1330,6 +1379,14 @@ void jtag_tap_free(struct jtag_tap *tap)
 {
        jtag_unregister_event_callback(&jtag_reset_callback, tap);
 
+       struct jtag_tap_event_action *jteap = tap->event_action;
+       while (jteap) {
+               struct jtag_tap_event_action *next = jteap->next;
+               Jim_DecrRefCount(jteap->interp, jteap->body);
+               free(jteap);
+               jteap = next;
+       }
+
        free(tap->expected);
        free(tap->expected_mask);
        free(tap->expected_ids);
@@ -1362,19 +1419,6 @@ int adapter_init(struct command_context *cmd_ctx)
                return retval;
        jtag = jtag_interface;
 
-       /* LEGACY SUPPORT ... adapter drivers  must declare what
-        * transports they allow.  Until they all do so, assume
-        * the legacy drivers are JTAG-only
-        */
-       if (!transports_are_declared()) {
-               LOG_ERROR("Adapter driver '%s' did not declare "
-                       "which transports it allows; assuming "
-                       "JTAG-only", jtag->name);
-               retval = allow_transports(cmd_ctx, jtag_only);
-               if (retval != ERROR_OK)
-                       return retval;
-       }
-
        if (jtag->speed == NULL) {
                LOG_INFO("This adapter doesn't support configurable speed");
                return ERROR_OK;
@@ -1494,13 +1538,19 @@ int jtag_init_inner(struct command_context *cmd_ctx)
 
 int adapter_quit(void)
 {
-       if (!jtag || !jtag->quit)
-               return ERROR_OK;
+       if (jtag && jtag->quit) {
+               /* close the JTAG interface */
+               int result = jtag->quit();
+               if (ERROR_OK != result)
+                       LOG_ERROR("failed: %d", result);
+       }
 
-       /* close the JTAG interface */
-       int result = jtag->quit();
-       if (ERROR_OK != result)
-               LOG_ERROR("failed: %d", result);
+       struct jtag_tap *t = jtag_all_taps();
+       while (t) {
+               struct jtag_tap *n = t->next_tap;
+               jtag_tap_free(t);
+               t = n;
+       }
 
        return ERROR_OK;
 }
@@ -1619,14 +1669,18 @@ static int adapter_khz_to_speed(unsigned khz, int *speed)
 {
        LOG_DEBUG("convert khz to interface specific speed value");
        speed_khz = khz;
-       if (jtag != NULL) {
-               LOG_DEBUG("have interface set up");
-               int speed_div1;
-               int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
-               if (ERROR_OK != retval)
-                       return retval;
-               *speed = speed_div1;
+       if (!jtag)
+               return ERROR_OK;
+       LOG_DEBUG("have interface set up");
+       if (!jtag->khz) {
+               LOG_ERROR("Translation from khz to jtag_speed not implemented");
+               return ERROR_FAIL;
        }
+       int speed_div1;
+       int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
+       if (ERROR_OK != retval)
+               return retval;
+       *speed = speed_div1;
        return ERROR_OK;
 }
 
@@ -1689,7 +1743,13 @@ int jtag_get_speed_readable(int *khz)
        int retval = jtag_get_speed(&jtag_speed_var);
        if (retval != ERROR_OK)
                return retval;
-       return jtag ? jtag->speed_div(jtag_speed_var, khz) : ERROR_OK;
+       if (!jtag)
+               return ERROR_OK;
+       if (!jtag->speed_div) {
+               LOG_ERROR("Translation from jtag_speed to khz not implemented");
+               return ERROR_FAIL;
+       }
+       return jtag->speed_div(jtag_speed_var, khz);
 }
 
 void jtag_set_verify(bool enable)
@@ -1720,12 +1780,20 @@ int jtag_power_dropout(int *dropout)
                LOG_ERROR("No Valid JTAG Interface Configured.");
                exit(-1);
        }
-       return jtag->power_dropout(dropout);
+       if (jtag->power_dropout)
+               return jtag->power_dropout(dropout);
+
+       *dropout = 0; /* by default we can't detect power dropout */
+       return ERROR_OK;
 }
 
 int jtag_srst_asserted(int *srst_asserted)
 {
-       return jtag->srst_asserted(srst_asserted);
+       if (jtag->srst_asserted)
+               return jtag->srst_asserted(srst_asserted);
+
+       *srst_asserted = 0; /* by default we can't detect srst asserted */
+       return ERROR_OK;
 }
 
 enum reset_types jtag_get_reset_config(void)
@@ -1739,11 +1807,11 @@ void jtag_set_reset_config(enum reset_types type)
 
 int jtag_get_trst(void)
 {
-       return jtag_trst;
+       return jtag_trst == 1;
 }
 int jtag_get_srst(void)
 {
-       return jtag_srst;
+       return jtag_srst == 1;
 }
 
 void jtag_set_nsrst_delay(unsigned delay)
@@ -1822,6 +1890,57 @@ bool transport_is_jtag(void)
        return get_current_transport() == &jtag_transport;
 }
 
+int adapter_resets(int trst, int srst)
+{
+       if (get_current_transport() == NULL) {
+               LOG_ERROR("transport is not selected");
+               return ERROR_FAIL;
+       }
+
+       if (transport_is_jtag()) {
+               if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
+                       LOG_ERROR("adapter has no srst signal");
+                       return ERROR_FAIL;
+               }
+
+               /* adapters without trst signal will eventually use tlr sequence */
+               jtag_add_reset(trst, srst);
+               return ERROR_OK;
+       } else if (transport_is_swd()) {
+               if (trst == TRST_ASSERT) {
+                       LOG_ERROR("transport swd has no trst signal");
+                       return ERROR_FAIL;
+               }
+
+               if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
+                       LOG_ERROR("adapter has no srst signal");
+                       return ERROR_FAIL;
+               }
+               swd_add_reset(srst);
+               return ERROR_OK;
+       } else if (transport_is_hla()) {
+               if (trst == TRST_ASSERT) {
+                       LOG_ERROR("transport %s has no trst signal",
+                               get_current_transport()->name);
+                       return ERROR_FAIL;
+               }
+
+               if (srst == SRST_ASSERT && !(jtag_reset_config & RESET_HAS_SRST)) {
+                       LOG_ERROR("adapter has no srst signal");
+                       return ERROR_FAIL;
+               }
+               return hl_interface_reset(srst);
+       }
+
+       if (trst == TRST_DEASSERT && srst == SRST_DEASSERT)
+               return ERROR_OK;
+
+       LOG_ERROR("reset is not supported on transport %s",
+               get_current_transport()->name);
+
+       return ERROR_FAIL;
+}
+
 void adapter_assert_reset(void)
 {
        if (transport_is_jtag()) {
@@ -1831,8 +1950,6 @@ void adapter_assert_reset(void)
                        jtag_add_reset(0, 1);
        } else if (transport_is_swd())
                swd_add_reset(1);
-       else if (transport_is_cmsis_dap())
-               swd_add_reset(1);  /* FIXME */
        else if (get_current_transport() != NULL)
                LOG_ERROR("reset is not supported on %s",
                        get_current_transport()->name);
@@ -1846,11 +1963,32 @@ void adapter_deassert_reset(void)
                jtag_add_reset(0, 0);
        else if (transport_is_swd())
                swd_add_reset(0);
-       else if (transport_is_cmsis_dap())
-               swd_add_reset(0);  /* FIXME */
        else if (get_current_transport() != NULL)
                LOG_ERROR("reset is not supported on %s",
                        get_current_transport()->name);
        else
                LOG_ERROR("transport is not selected");
 }
+
+int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
+               uint32_t port_size, unsigned int *trace_freq,
+               unsigned int traceclkin_freq, uint16_t *prescaler)
+{
+       if (jtag->config_trace) {
+               return jtag->config_trace(enabled, pin_protocol, port_size, trace_freq,
+                       traceclkin_freq, prescaler);
+       } else if (enabled) {
+               LOG_ERROR("The selected interface does not support tracing");
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
+
+int adapter_poll_trace(uint8_t *buf, size_t *size)
+{
+       if (jtag->poll_trace)
+               return jtag->poll_trace(buf, size);
+
+       return ERROR_FAIL;
+}