This is an automated email from Gerrit.

Paul Fertser (fercer...@gmail.com) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/5975

-- gerrit

commit 30773d372cb86800f0b2f4aca93cf378686a3f81
Author: Paul Fertser <fercer...@gmail.com>
Date:   Mon Dec 14 12:23:58 2020 +0300

    [RFC] jtag: drivers: introduce q&d support for Linux kernel JTAG API
    
    This is a basic client to test patches from [1] (which can only work
    after some bugfixing, see the review comments).
    
    Only playing back an SVF for a Lattice CPLD run-time tested.
    
    [1] 
https://patchwork.kernel.org/project/linux-arm-kernel/cover/20200413222920.4722-1-ernesto.cor...@intel.com/
    
    Change-Id: I9ef81323a06cebc284fad067ae332c69780a126b
    Signed-off-by: Paul Fertser <fercer...@gmail.com>

diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am
index f7a54b0..190e1b8 100644
--- a/src/jtag/drivers/Makefile.am
+++ b/src/jtag/drivers/Makefile.am
@@ -190,6 +190,8 @@ if XDS110
 DRIVERFILES += %D%/xds110.c
 endif
 
+DRIVERFILES += %D%/kernel_jtag.c
+
 DRIVERHEADERS = \
        %D%/bitbang.h \
        %D%/bitq.h \
diff --git a/src/jtag/drivers/kernel_jtag.c b/src/jtag/drivers/kernel_jtag.c
new file mode 100644
index 0000000..2b77dc2
--- /dev/null
+++ b/src/jtag/drivers/kernel_jtag.c
@@ -0,0 +1,436 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020  Gagar.IN LLC
+ * by Paul Fertser <fercer...@gmail.com>
+ *
+ * Copyright (C) 2012 by Andreas Fritiofson
+ * andreas.fritiof...@gmail.com
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/* project specific includes */
+#include <jtag/drivers/jtag_usb_common.h>
+#include <jtag/interface.h>
+#include <transport/transport.h>
+#include <helper/time_support.h>
+
+#include <assert.h>
+
+#include "kernel_jtag.h"
+#include <sys/ioctl.h>
+
+static int jtag_fd;
+
+static uint8_t tap_state_to_kernel(tap_state_t state)
+{
+       switch (state) {
+       case TAP_DREXIT2:
+               return JTAG_STATE_EXIT2DR;
+       case TAP_DREXIT1:
+               return JTAG_STATE_EXIT1DR;
+       case TAP_DRSHIFT:
+               return JTAG_STATE_SHIFTDR;
+       case TAP_DRPAUSE:
+               return JTAG_STATE_PAUSEDR;
+       case TAP_IRSELECT:
+               return JTAG_STATE_SELECTIR;
+       case TAP_DRUPDATE:
+               return JTAG_STATE_UPDATEDR;
+       case TAP_DRCAPTURE:
+               return JTAG_STATE_CAPTUREDR;
+       case TAP_DRSELECT:
+               return JTAG_STATE_SELECTDR;
+       case TAP_IREXIT2:
+               return JTAG_STATE_EXIT2IR;
+       case TAP_IREXIT1:
+               return JTAG_STATE_EXIT1IR;
+       case TAP_IRSHIFT:
+               return JTAG_STATE_SHIFTIR;
+       case TAP_IRPAUSE:
+               return JTAG_STATE_PAUSEIR;
+       case TAP_IDLE:
+               return JTAG_STATE_IDLE;
+       case TAP_IRUPDATE:
+               return JTAG_STATE_UPDATEIR;
+       case TAP_IRCAPTURE:
+               return JTAG_STATE_CAPTUREIR;
+       case TAP_RESET:
+               return JTAG_STATE_TLRESET;
+       case TAP_INVALID:
+       default:
+               return JTAG_STATE_UPDATEIR + 1;
+       }
+}
+
+/**
+ * Function move_to_state
+ * moves the TAP controller from the current state to a
+ * \a goal_state through a path given by tap_get_tms_path().  State transition
+ * logging is performed by delegation to clock_tms().
+ *
+ * @param goal_state is the destination state for the move.
+ */
+static int move_to_state(tap_state_t goal_state)
+{
+       tap_state_t start_state = tap_get_state();
+
+       /*      goal_state is 1/2 of a tuple/pair of states which allow 
convenient
+               lookup of the required TMS pattern to move to this state from 
the
+               start state.
+       */
+
+       /* do the 2 lookups */
+       uint8_t tms_bits  = tap_get_tms_path(start_state, goal_state);
+       int tms_count = tap_get_tms_path_len(start_state, goal_state);
+       assert(tms_count <= 8);
+
+       LOG_DEBUG_IO("start=%s goal=%s", tap_state_name(start_state), 
tap_state_name(goal_state));
+
+       /* Track state transitions step by step */
+       for (int i = 0; i < tms_count; i++)
+               tap_set_state(tap_state_transition(tap_get_state(), (tms_bits 
>> i) & 1));
+
+       struct jtag_end_tap_state endstate;
+       endstate.endstate = tap_state_to_kernel(goal_state);
+       endstate.reset = JTAG_NO_RESET;
+       endstate.tck = 0;
+       int retval = ioctl(jtag_fd, JTAG_SIOCSTATE, &endstate);
+       if (retval < 0) {
+               LOG_ERROR("couldn't set move to state");
+               return ERROR_FAIL;
+       }
+       return ERROR_OK;
+}
+
+static int kernel_jtag_speed(int speed)
+{
+       int retval;
+       uint32_t freq = speed;
+
+       retval = ioctl(jtag_fd, JTAG_SIOCFREQ, &freq);
+
+       if (retval < 0) {
+               LOG_ERROR("couldn't set JTAG TCK speed");
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
+
+static int kernel_jtag_speed_div(int speed, int *khz)
+{
+       *khz = speed / 1000;
+       return ERROR_OK;
+}
+
+static int kernel_jtag_khz(int khz, int *jtag_speed)
+{
+       if (khz == 0) {
+               /* TODO */
+               LOG_DEBUG("RCLK not supported");
+               return ERROR_FAIL;
+       }
+
+       *jtag_speed = khz * 1000;
+       return ERROR_OK;
+}
+
+static void kernel_jtag_end_state(tap_state_t state)
+{
+       if (tap_is_state_stable(state))
+               tap_set_end_state(state);
+       else {
+               LOG_ERROR("BUG: %s is not a stable end state", 
tap_state_name(state));
+               exit(-1);
+       }
+}
+
+static void kernel_jtag_execute_runtest(struct jtag_command *cmd)
+{
+       LOG_DEBUG_IO("runtest %i cycles, end in %s",
+               cmd->cmd.runtest->num_cycles,
+               tap_state_name(cmd->cmd.runtest->end_state));
+
+       if (tap_get_state() != TAP_IDLE)
+               move_to_state(TAP_IDLE);
+
+       /* TODO: Reuse kernel_jtag_execute_stableclocks */
+
+       move_to_state(TAP_IDLE);
+
+       struct tck_bitbang bitbang;
+       bitbang.tms = 0;
+       bitbang.tdi = 0;
+
+       for (int i = 0; i < cmd->cmd.runtest->num_cycles; i++) {
+               int retval = ioctl(jtag_fd, JTAG_IOCBITBANG, &bitbang);
+               if (retval < 0) {
+                       LOG_ERROR("CBITBANG error");
+                       return;
+               }
+       }
+
+       kernel_jtag_end_state(cmd->cmd.runtest->end_state);
+
+       if (tap_get_state() != tap_get_end_state())
+               move_to_state(tap_get_end_state());
+
+       LOG_DEBUG_IO("runtest: %i, end in %s",
+               cmd->cmd.runtest->num_cycles,
+               tap_state_name(tap_get_end_state()));
+}
+
+static void kernel_jtag_execute_statemove(struct jtag_command *cmd)
+{
+       LOG_DEBUG_IO("statemove end in %s",
+               tap_state_name(cmd->cmd.statemove->end_state));
+
+       kernel_jtag_end_state(cmd->cmd.statemove->end_state);
+
+       /* shortest-path move to desired end state */
+       if (tap_get_state() != tap_get_end_state() || tap_get_end_state() == 
TAP_RESET)
+               move_to_state(tap_get_end_state());
+}
+
+static void kernel_jtag_execute_pathmove(struct jtag_command *cmd)
+{
+       tap_state_t *path = cmd->cmd.pathmove->path;
+       int num_states  = cmd->cmd.pathmove->num_states;
+
+       LOG_DEBUG_IO("pathmove: %i states, current: %s  end: %s", num_states,
+               tap_state_name(tap_get_state()),
+               tap_state_name(path[num_states-1]));
+
+       int state_count = 0;
+       unsigned bit_count = 0;
+       uint8_t tms_byte = 0;
+
+       LOG_DEBUG_IO("-");
+
+       /* this loop verifies that the path is legal and logs each state in the 
path */
+       while (num_states--) {
+
+               /* either TMS=0 or TMS=1 must work ... */
+               if (tap_state_transition(tap_get_state(), false)
+                   == path[state_count])
+                       buf_set_u32(&tms_byte, bit_count++, 1, 0x0);
+               else if (tap_state_transition(tap_get_state(), true)
+                        == path[state_count]) {
+                       buf_set_u32(&tms_byte, bit_count++, 1, 0x1);
+
+                       /* ... or else the caller goofed BADLY */
+               } else {
+                       LOG_ERROR("BUG: %s -> %s isn't a valid "
+                               "TAP state transition",
+                               tap_state_name(tap_get_state()),
+                               tap_state_name(path[state_count]));
+                       exit(-1);
+               }
+
+               tap_set_state(path[state_count]);
+               state_count++;
+
+               if (bit_count == 7 || num_states == 0) {
+                       /* TODO mpsse_clock_tms_cs_out(mpsse_ctx,
+                                       &tms_byte,
+                                       0,
+                                       bit_count,
+                                       false,
+                                       ftdi_jtag_mode); */
+                       bit_count = 0;
+               }
+       }
+       tap_set_end_state(tap_get_state());
+       move_to_state(tap_get_state());
+}
+
+static void kernel_jtag_execute_scan(struct jtag_command *cmd)
+{
+       LOG_DEBUG_IO("%s type:%d", cmd->cmd.scan->ir_scan ? "IRSCAN" : "DRSCAN",
+               jtag_scan_type(cmd->cmd.scan));
+
+       /* Make sure there are no trailing fields with num_bits == 0, or the 
logic below will fail. */
+       while (cmd->cmd.scan->num_fields > 0
+                       && cmd->cmd.scan->fields[cmd->cmd.scan->num_fields - 
1].num_bits == 0) {
+               cmd->cmd.scan->num_fields--;
+               LOG_DEBUG_IO("discarding trailing empty field");
+       }
+
+       if (cmd->cmd.scan->num_fields == 0) {
+               LOG_DEBUG_IO("empty scan, doing nothing");
+               return;
+       }
+
+       kernel_jtag_end_state(cmd->cmd.scan->end_state);
+
+       struct scan_field *field = cmd->cmd.scan->fields;
+       unsigned scan_size = 0;
+       struct jtag_xfer xfer;
+       xfer.type = cmd->cmd.scan->ir_scan ? JTAG_SIR_XFER : JTAG_SDR_XFER;
+       /* TODO why doesn't this work ...
+        * xfer.endstate = cmd->cmd.scan->ir_scan ? JTAG_STATE_PAUSEIR : 
JTAG_STATE_PAUSEDR;
+       */
+       xfer.endstate = JTAG_STATE_IDLE;
+       xfer.padding = 0;
+
+       for (int i = 0; i < cmd->cmd.scan->num_fields; i++, field++) {
+               scan_size += field->num_bits;
+               LOG_DEBUG_IO("%s%s field %d/%d %d bits",
+                       field->in_value ? "in" : "",
+                       field->out_value ? "out" : "",
+                       i,
+                       cmd->cmd.scan->num_fields,
+                       field->num_bits);
+
+               xfer.length = field->num_bits;
+
+               /*if (i == cmd->cmd.scan->num_fields - 1)
+                 xfer.endstate = tap_state_to_kernel(tap_get_end_state());*/
+
+               if (field->in_value && field->out_value)
+                       xfer.direction = JTAG_READ_WRITE_XFER;
+               else if (field->in_value)
+                       xfer.direction = JTAG_READ_XFER;
+               else
+                       xfer.direction = JTAG_WRITE_XFER;
+
+               if (field->out_value)
+                       xfer.tdio = (uint64_t)(uintptr_t)field->out_value;
+               else
+                       xfer.tdio = (uint64_t)(uintptr_t)field->in_value;
+
+               int retval = ioctl(jtag_fd, JTAG_IOCXFER, &xfer);
+               if (retval < 0) {
+                       LOG_ERROR("Error doing JTAG_IOCXFER");
+                       return;
+               }
+
+               if (field->in_value && field->out_value)
+                       bit_copy(field->in_value, 0, field->out_value, 0, 
field->num_bits);
+       }
+
+       tap_set_state(tap_get_end_state());
+
+       LOG_DEBUG_IO("%s scan, %i bits, end in %s",
+               (cmd->cmd.scan->ir_scan) ? "IR" : "DR", scan_size,
+               tap_state_name(tap_get_end_state()));
+}
+
+static void kernel_jtag_execute_sleep(struct jtag_command *cmd)
+{
+       LOG_DEBUG_IO("sleep %" PRIi32, cmd->cmd.sleep->us);
+
+       jtag_sleep(cmd->cmd.sleep->us);
+       LOG_DEBUG_IO("sleep %" PRIi32 " usec while in %s",
+               cmd->cmd.sleep->us,
+               tap_state_name(tap_get_state()));
+}
+
+static void kernel_jtag_execute_stableclocks(struct jtag_command *cmd)
+{
+       /* this is only allowed while in a stable state.  A check for a stable
+        * state was done in jtag_add_clocks()
+        */
+       struct tck_bitbang bitbang;
+       bitbang.tms = 0;
+       bitbang.tdi = 0;
+
+       for (int i = 0; i < cmd->cmd.runtest->num_cycles; i++) {
+               int retval = ioctl(jtag_fd, JTAG_IOCBITBANG, &bitbang);
+               if (retval < 0) {
+                       LOG_ERROR("CBITBANG error");
+                       return;
+               }
+       }
+
+       LOG_DEBUG_IO("clocks %i while in %s",
+               cmd->cmd.stableclocks->num_cycles,
+               tap_state_name(tap_get_state()));
+}
+
+static void kernel_jtag_execute_command(struct jtag_command *cmd)
+{
+       switch (cmd->type) {
+               case JTAG_RESET:
+                       /* TODO kernel_jtag_execute_reset(cmd); */
+                       break;
+               case JTAG_RUNTEST:
+                       kernel_jtag_execute_runtest(cmd);
+                       break;
+               case JTAG_TLR_RESET:
+                       kernel_jtag_execute_statemove(cmd);
+                       break;
+               case JTAG_PATHMOVE:
+                       kernel_jtag_execute_pathmove(cmd);
+                       break;
+               case JTAG_SCAN:
+                       kernel_jtag_execute_scan(cmd);
+                       break;
+               case JTAG_SLEEP:
+                       kernel_jtag_execute_sleep(cmd);
+                       break;
+               case JTAG_STABLECLOCKS:
+                       kernel_jtag_execute_stableclocks(cmd);
+                       break;
+               case JTAG_TMS:
+                       /* TODO kernel_jtag_execute_tms(cmd); */
+                       break;
+               default:
+                       LOG_ERROR("BUG: unknown JTAG command type encountered: 
%d", cmd->type);
+                       break;
+       }
+}
+
+static int kernel_jtag_initialize(void)
+{
+       jtag_fd = open("/dev/jtag0", O_RDWR);
+       if (jtag_fd == -1) {
+               LOG_ERROR("Can't open JTAG device node");
+               return ERROR_FAIL;
+       }
+
+       kernel_jtag_speed(jtag_get_speed_khz() * 1000);
+
+       /* TODO HW mode doesn't work */
+       struct jtag_mode mode = { .feature = JTAG_XFER_MODE,
+                                 .mode = JTAG_XFER_SW_MODE };
+       ioctl(jtag_fd, JTAG_SIOCMODE, &mode);
+
+       return ERROR_OK;
+}
+
+static int kernel_jtag_quit(void)
+{
+       close(jtag_fd);
+       return ERROR_OK;
+}
+
+static int kernel_jtag_execute_queue(void)
+{
+       for (struct jtag_command *cmd = jtag_command_queue; cmd; cmd = 
cmd->next)
+               kernel_jtag_execute_command(cmd);
+
+       return ERROR_OK;
+}
+
+static const char * const kernel_jtag_transports[] = { "jtag", NULL };
+
+static struct jtag_interface kernel_jtag_interface = {
+       /* TODO .supported = DEBUG_CAP_TMS_SEQ, */
+       .execute_queue = kernel_jtag_execute_queue,
+};
+
+struct adapter_driver kernel_jtag_adapter_driver = {
+       .name = "kernel_jtag",
+       .transports = kernel_jtag_transports,
+
+       .init = kernel_jtag_initialize,
+       .quit = kernel_jtag_quit,
+       .speed = kernel_jtag_speed,
+       .speed_div = kernel_jtag_speed_div,
+       .khz = kernel_jtag_khz,
+       .jtag_ops = &kernel_jtag_interface,
+};
diff --git a/src/jtag/drivers/kernel_jtag.h b/src/jtag/drivers/kernel_jtag.h
new file mode 100644
index 0000000..97517ce
--- /dev/null
+++ b/src/jtag/drivers/kernel_jtag.h
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* include/uapi/linux/jtag.h - JTAG class driver uapi
+ *
+ * Copyright (c) 2018 Mellanox Technologies. All rights reserved.
+ * Copyright (c) 2018 Oleksandr Shamray <oleksan...@mellanox.com>
+ */
+
+#ifndef __UAPI_LINUX_JTAG_H
+#define __UAPI_LINUX_JTAG_H
+
+#include <linux/types.h>
+
+/*
+ * JTAG_XFER_MODE: JTAG transfer mode. Used to set JTAG controller transfer 
mode
+ * This is bitmask for feature param in jtag_mode for ioctl JTAG_SIOCMODE
+ */
+#define  JTAG_XFER_MODE 0
+/*
+ * JTAG_CONTROL_MODE: JTAG controller mode. Used to set JTAG controller mode
+ * This is bitmask for feature param in jtag_mode for ioctl JTAG_SIOCMODE
+ */
+#define  JTAG_CONTROL_MODE 1
+/*
+ * JTAG_SLAVE_MODE: JTAG slave mode. Used to set JTAG controller slave mode
+ * This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
+ */
+#define  JTAG_SLAVE_MODE 0
+/*
+ * JTAG_MASTER_MODE: JTAG master mode. Used to set JTAG controller master mode
+ * This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
+ */
+#define  JTAG_MASTER_MODE 1
+/*
+ * JTAG_XFER_HW_MODE: JTAG hardware mode. Used to set HW drived or bitbang
+ * mode. This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
+ */
+#define  JTAG_XFER_HW_MODE 1
+/*
+ * JTAG_XFER_SW_MODE: JTAG software mode. Used to set SW drived or bitbang
+ * mode. This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE
+ */
+#define  JTAG_XFER_SW_MODE 0
+
+/**
+ * enum jtag_endstate:
+ *
+ * @JTAG_STATE_TLRESET: JTAG state machine Test Logic Reset state
+ * @JTAG_STATE_IDLE: JTAG state machine IDLE state
+ * @JTAG_STATE_SELECTDR: JTAG state machine SELECT_DR state
+ * @JTAG_STATE_CAPTUREDR: JTAG state machine CAPTURE_DR state
+ * @JTAG_STATE_SHIFTDR: JTAG state machine SHIFT_DR state
+ * @JTAG_STATE_EXIT1DR: JTAG state machine EXIT-1 DR state
+ * @JTAG_STATE_PAUSEDR: JTAG state machine PAUSE_DR state
+ * @JTAG_STATE_EXIT2DR: JTAG state machine EXIT-2 DR state
+ * @JTAG_STATE_UPDATEDR: JTAG state machine UPDATE DR state
+ * @JTAG_STATE_SELECTIR: JTAG state machine SELECT_IR state
+ * @JTAG_STATE_CAPTUREIR: JTAG state machine CAPTURE_IR state
+ * @JTAG_STATE_SHIFTIR: JTAG state machine SHIFT_IR state
+ * @JTAG_STATE_EXIT1IR: JTAG state machine EXIT-1 IR state
+ * @JTAG_STATE_PAUSEIR: JTAG state machine PAUSE_IR state
+ * @JTAG_STATE_EXIT2IR: JTAG state machine EXIT-2 IR state
+ * @JTAG_STATE_UPDATEIR: JTAG state machine UPDATE IR state
+ */
+enum jtag_endstate {
+       JTAG_STATE_TLRESET,
+       JTAG_STATE_IDLE,
+       JTAG_STATE_SELECTDR,
+       JTAG_STATE_CAPTUREDR,
+       JTAG_STATE_SHIFTDR,
+       JTAG_STATE_EXIT1DR,
+       JTAG_STATE_PAUSEDR,
+       JTAG_STATE_EXIT2DR,
+       JTAG_STATE_UPDATEDR,
+       JTAG_STATE_SELECTIR,
+       JTAG_STATE_CAPTUREIR,
+       JTAG_STATE_SHIFTIR,
+       JTAG_STATE_EXIT1IR,
+       JTAG_STATE_PAUSEIR,
+       JTAG_STATE_EXIT2IR,
+       JTAG_STATE_UPDATEIR
+};
+
+/**
+ * enum jtag_reset:
+ *
+ * @JTAG_NO_RESET: JTAG run TAP from current state
+ * @JTAG_FORCE_RESET: JTAG force TAP to reset state
+ */
+enum jtag_reset {
+       JTAG_NO_RESET = 0,
+       JTAG_FORCE_RESET = 1,
+};
+
+/**
+ * enum jtag_xfer_type:
+ *
+ * @JTAG_SIR_XFER: SIR transfer
+ * @JTAG_SDR_XFER: SDR transfer
+ */
+enum jtag_xfer_type {
+       JTAG_SIR_XFER = 0,
+       JTAG_SDR_XFER = 1,
+};
+
+/**
+ * enum jtag_xfer_direction:
+ *
+ * @JTAG_READ_XFER: read transfer
+ * @JTAG_WRITE_XFER: write transfer
+ * @JTAG_READ_WRITE_XFER: read & write transfer
+ */
+enum jtag_xfer_direction {
+       JTAG_READ_XFER = 1,
+       JTAG_WRITE_XFER = 2,
+       JTAG_READ_WRITE_XFER = 3,
+};
+
+/**
+ * struct jtag_end_tap_state - forces JTAG state machine to go into a TAPC
+ * state
+ *
+ * @reset: 0 - run IDLE/PAUSE from current state
+ *         1 - go through TEST_LOGIC/RESET state before  IDLE/PAUSE
+ * @end: completion flag
+ * @tck: clock counter
+ *
+ * Structure provide interface to JTAG device for JTAG set state execution.
+ */
+struct jtag_end_tap_state {
+       __u8    reset;
+       __u8    endstate;
+       __u8    tck;
+};
+
+/**
+ * struct jtag_xfer - jtag xfer:
+ *
+ * @type: transfer type
+ * @direction: xfer direction
+ * @length: xfer bits len
+ * @tdio : xfer data array
+ * @endir: xfer end state
+ *
+ * Structure provide interface to JTAG device for JTAG SDR/SIR xfer execution.
+ */
+struct jtag_xfer {
+       __u8    type;
+       __u8    direction;
+       __u8    endstate;
+       __u8    padding;
+       __u32   length;
+       __u64   tdio;
+};
+
+/**
+ * struct jtag_bitbang - jtag bitbang:
+ *
+ * @tms: JTAG TMS
+ * @tdi: JTAG TDI (input)
+ * @tdo: JTAG TDO (output)
+ *
+ * Structure provide interface to JTAG device for JTAG bitbang execution.
+ */
+struct tck_bitbang {
+       __u8    tms;
+       __u8    tdi;
+       __u8    tdo;
+} __attribute__((__packed__));
+
+/**
+ * struct jtag_mode - jtag mode:
+ *
+ * @feature: 0 - JTAG feature setting selector for JTAG controller HW/SW
+ *           1 - JTAG feature setting selector for controller
+ *               bus(master/slave) mode.
+ * @mode:    (0 - SW / 1 - HW) for JTAG_XFER_MODE feature(0)
+ *           (0 - Slave / 1 - Master) for JTAG_CONTROL_MODE feature(1)
+ *
+ * Structure provide configuration modes to JTAG device.
+ */
+struct jtag_mode {
+       __u32   feature;
+       __u32   mode;
+};
+
+/* ioctl interface */
+#define __JTAG_IOCTL_MAGIC     0xb2
+
+#define JTAG_SIOCSTATE _IOW(__JTAG_IOCTL_MAGIC, 0, struct jtag_end_tap_state)
+#define JTAG_SIOCFREQ  _IOW(__JTAG_IOCTL_MAGIC, 1, unsigned int)
+#define JTAG_GIOCFREQ  _IOR(__JTAG_IOCTL_MAGIC, 2, unsigned int)
+#define JTAG_IOCXFER   _IOWR(__JTAG_IOCTL_MAGIC, 3, struct jtag_xfer)
+#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtag_endstate)
+#define JTAG_SIOCMODE  _IOW(__JTAG_IOCTL_MAGIC, 5, unsigned int)
+#define JTAG_IOCBITBANG        _IOW(__JTAG_IOCTL_MAGIC, 6, unsigned int)
+
+#endif /* __UAPI_LINUX_JTAG_H */
diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c
index 061a78f..f88de35 100644
--- a/src/jtag/interfaces.c
+++ b/src/jtag/interfaces.c
@@ -152,6 +152,7 @@ extern struct adapter_driver stlink_dap_adapter_driver;
 #if BUILD_RSHIM == 1
 extern struct adapter_driver rshim_dap_adapter_driver;
 #endif
+extern struct adapter_driver kernel_jtag_adapter_driver;
 #endif /* standard drivers */
 
 /**
@@ -272,6 +273,7 @@ struct adapter_driver *adapter_drivers[] = {
 #if BUILD_RSHIM == 1
                &rshim_dap_adapter_driver,
 #endif
+               &kernel_jtag_adapter_driver,
 #endif /* standard drivers */
                NULL,
        };

-- 


_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to