Remove unused code, TAP_INVALID is never passed to drivers.
[openocd.git] / src / jtag / jlink.c
index 90fb42c4cfc7ca53e84bfc17ef8ceefcfed00e70..b677535ce1a903b250ea29a0f7fdacca129cc875 100644 (file)
@@ -25,6 +25,7 @@
 #include "config.h"
 #endif
 
+#define INCLUDE_JTAG_INTERFACE_H
 #include "jtag.h"
 
 #include <usb.h>
 #define JLINK_WRITE_ENDPOINT   0x02
 #define JLINK_READ_ENDPOINT            0x81
 
+static unsigned int jlink_write_ep = JLINK_WRITE_ENDPOINT;
+static unsigned int jlink_read_ep = JLINK_READ_ENDPOINT;
+static unsigned int jlink_hw_jtag_version = 2;
+
 #define JLINK_USB_TIMEOUT              1000
 
 // See Section 1.3.2 of the Segger JLink USB protocol manual
+/* 2048 is the max value we can use here */
+//#define JLINK_TAP_BUFFER_SIZE 2048
+#define JLINK_TAP_BUFFER_SIZE 256
+//#define JLINK_TAP_BUFFER_SIZE 384
+
 #define JLINK_IN_BUFFER_SIZE                   2048
 #define JLINK_OUT_BUFFER_SIZE                  2*2048+4
 #define JLINK_EMU_RESULT_BUFFER_SIZE   64
@@ -55,6 +65,7 @@ static u8 usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE];
 #define EMU_CMD_HW_CLOCK                       0xc8
 #define EMU_CMD_HW_TMS0                        0xc9
 #define EMU_CMD_HW_TMS1                        0xca
+#define EMU_CMD_HW_JTAG2               0xce
 #define EMU_CMD_HW_JTAG3               0xcf
 #define EMU_CMD_GET_MAX_MEM_BLOCK      0xd4
 #define EMU_CMD_HW_RESET0              0xdc
@@ -62,6 +73,11 @@ static u8 usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE];
 #define EMU_CMD_HW_TRST0               0xde
 #define EMU_CMD_HW_TRST1               0xdf
 #define EMU_CMD_GET_CAPS               0xe8
+#define EMU_CMD_GET_HW_VERSION         0xf0
+
+/* bits return from EMU_CMD_GET_CAPS */
+#define EMU_CAP_GET_HW_VERSION                 1
+#define EMU_CAP_GET_MAX_BLOCK_SIZE     11
 
 /* max speed 12MHz v5.0 jlink */
 #define JLINK_MAX_SPEED 12000
@@ -77,6 +93,7 @@ static int jlink_quit(void);
 
 /* CLI command handler functions */
 static int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int jlink_handle_jlink_hw_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
 
 /* Queue command functions */
 static void jlink_end_state(tap_state_t state);
@@ -134,22 +151,13 @@ jtag_interface_t jlink_interface =
        .quit = jlink_quit
 };
 
-static void jlink_execute_end_state(jtag_command_t *cmd)
-{
-       DEBUG_JTAG_IO("end_state: %i", cmd->cmd.end_state->end_state);
-
-       if (cmd->cmd.end_state->end_state != TAP_INVALID)
-               jlink_end_state(cmd->cmd.end_state->end_state);
-}
-
 static void jlink_execute_runtest(jtag_command_t *cmd)
 {
        DEBUG_JTAG_IO("runtest %i cycles, end in %i",
                        cmd->cmd.runtest->num_cycles,
                        cmd->cmd.runtest->end_state);
 
-       if (cmd->cmd.runtest->end_state != TAP_INVALID)
-               jlink_end_state(cmd->cmd.runtest->end_state);
+       jlink_end_state(cmd->cmd.runtest->end_state);
 
        jlink_runtest(cmd->cmd.runtest->num_cycles);
 }
@@ -158,10 +166,7 @@ static void jlink_execute_statemove(jtag_command_t *cmd)
 {
        DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state);
 
-       if (cmd->cmd.statemove->end_state != TAP_INVALID)
-       {
-               jlink_end_state(cmd->cmd.statemove->end_state);
-       }
+       jlink_end_state(cmd->cmd.statemove->end_state);
        jlink_state_move();
 }
 
@@ -183,8 +188,7 @@ static void jlink_execute_scan(jtag_command_t *cmd)
 
        DEBUG_JTAG_IO("scan end in %s", tap_state_name(cmd->cmd.scan->end_state));
 
-       if (cmd->cmd.scan->end_state != TAP_INVALID)
-               jlink_end_state(cmd->cmd.scan->end_state);
+       jlink_end_state(cmd->cmd.scan->end_state);
 
        scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
        DEBUG_JTAG_IO("scan input, length = %d", scan_size);
@@ -203,12 +207,6 @@ static void jlink_execute_reset(jtag_command_t *cmd)
                        cmd->cmd.reset->trst, cmd->cmd.reset->srst);
 
        jlink_tap_execute();
-
-       if ( (cmd->cmd.reset->trst == 1) || ( cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST) ) )
-       {
-               tap_set_state(TAP_RESET);
-       }
-
        jlink_reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
        jlink_tap_execute();
 }
@@ -224,7 +222,6 @@ static void jlink_execute_command(jtag_command_t *cmd)
 {
        switch (cmd->type)
        {
-       case JTAG_END_STATE: jlink_execute_end_state(cmd); break;
        case JTAG_RUNTEST:   jlink_execute_runtest(cmd); break;
        case JTAG_STATEMOVE: jlink_execute_statemove(cmd); break;
        case JTAG_PATHMOVE:  jlink_execute_pathmove(cmd); break;
@@ -296,8 +293,13 @@ static int jlink_khz(int khz, int *jtag_speed)
 
 static int jlink_register_commands(struct command_context_s *cmd_ctx)
 {
-       register_command(cmd_ctx, NULL, "jlink_info", jlink_handle_jlink_info_command, COMMAND_EXEC,
+
+       register_command(cmd_ctx, NULL, "jlink_info", 
+               &jlink_handle_jlink_info_command, COMMAND_EXEC,
                "query jlink info");
+       register_command(cmd_ctx, NULL, "jlink_hw_jtag",
+               &jlink_handle_jlink_hw_jtag_command, COMMAND_EXEC,
+               "set/get jlink hw jtag command version [2|3]");
        return ERROR_OK;
 }
 
@@ -313,6 +315,7 @@ static int jlink_init(void)
                return ERROR_JTAG_INIT_FAILED;
        }
 
+       jlink_hw_jtag_version = 2;
        check_cnt = 0;
        while (check_cnt < 3)
        {
@@ -412,6 +415,8 @@ static void jlink_runtest(int num_cycles)
 
        tap_state_t saved_end_state = tap_get_end_state();
 
+       jlink_tap_ensure_space(1,num_cycles + 16);
+
        /* only do a state_move when we're not already in IDLE */
        if (tap_get_state() != TAP_IDLE)
        {
@@ -438,7 +443,7 @@ static void jlink_scan(bool ir_scan, enum scan_type type, u8 *buffer, int scan_s
 {
        tap_state_t saved_end_state;
 
-       jlink_tap_ensure_space(1, scan_size + 8);
+       jlink_tap_ensure_space(1, scan_size + 16);
 
        saved_end_state = tap_get_end_state();
 
@@ -549,6 +554,12 @@ static int jlink_get_version_info(void)
        }
 
        len = buf_get_u32(usb_in_buffer, 0, 16);
+       if (len > JLINK_IN_BUFFER_SIZE)
+       {
+               LOG_ERROR("J-Link command EMU_CMD_VERSION impossible return length 0x%0x", len);
+               len = JLINK_IN_BUFFER_SIZE;
+       }
+       
        result = jlink_usb_read(jlink_jtag_handle, len);
        if (result != len)
        {
@@ -572,20 +583,41 @@ static int jlink_get_version_info(void)
        jlink_caps = buf_get_u32(usb_in_buffer, 0, 32);
        LOG_INFO("JLink caps 0x%x", jlink_caps);
 
+       if (jlink_caps & (1 << EMU_CAP_GET_HW_VERSION))
+       {
+               /* query hardware version */
+               jlink_simple_command(EMU_CMD_GET_HW_VERSION);
 
-       /* query hardware maximum memory block */
-       jlink_simple_command(EMU_CMD_GET_MAX_MEM_BLOCK);
+               result = jlink_usb_read(jlink_jtag_handle, 4);
+               if (4 != result)
+               {
+                       LOG_ERROR("J-Link command EMU_CMD_GET_HW_VERSION failed (%d)\n", result);
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
 
-       result = jlink_usb_read(jlink_jtag_handle, 4);
-       if (4 != result)
-       {
-               LOG_ERROR("J-Link command EMU_CMD_GET_MAX_MEM_BLOCK failed (%d)\n", result);
-               return ERROR_JTAG_DEVICE_ERROR;
+               u32 jlink_hw_version = buf_get_u32(usb_in_buffer, 0, 32);
+               u32 major_revision = (jlink_hw_version / 10000) % 100;
+               if (major_revision >= 5)
+                       jlink_hw_jtag_version = 3;
+
+               LOG_INFO("JLink hw version %i", jlink_hw_version);
        }
 
-       jlink_max_size = buf_get_u32(usb_in_buffer, 0, 32);
-       LOG_INFO("JLink max mem block %i", jlink_max_size);
+       if (jlink_caps & (1 << EMU_CAP_GET_MAX_BLOCK_SIZE))
+       {
+               /* query hardware maximum memory block */
+               jlink_simple_command(EMU_CMD_GET_MAX_MEM_BLOCK);
 
+               result = jlink_usb_read(jlink_jtag_handle, 4);
+               if (4 != result)
+               {
+                       LOG_ERROR("J-Link command EMU_CMD_GET_MAX_MEM_BLOCK failed (%d)\n", result);
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
+
+               jlink_max_size = buf_get_u32(usb_in_buffer, 0, 32);
+               LOG_INFO("JLink max mem block %i", jlink_max_size);
+       }
 
        return ERROR_OK;
 }
@@ -601,11 +633,33 @@ static int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, ch
        return ERROR_OK;
 }
 
+static int jlink_handle_jlink_hw_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+{
+       switch (argc) {
+       case 0:
+               command_print(cmd_ctx, "jlink hw jtag  %i", jlink_hw_jtag_version);
+               break;
+       case 1: {
+               int request_version = atoi(args[0]);
+               switch (request_version) {
+               case 2: case 3:
+                       jlink_hw_jtag_version = request_version;
+                       break;
+               default:
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               }
+               break;
+       }
+       default:
+               return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       return ERROR_OK;
+}
+
 /***************************************************************************/
 /* J-Link tap functions */
 
-/* 2048 is the max value we can use here */
-#define JLINK_TAP_BUFFER_SIZE 1024
 
 static unsigned tap_length=0;
 static u8 tms_buffer[JLINK_TAP_BUFFER_SIZE];
@@ -634,7 +688,7 @@ static void jlink_tap_init(void)
 static void jlink_tap_ensure_space(int scans, int bits)
 {
        int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length;
-       int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length - 64;
+       int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length - 32;
 
        if (scans > available_scans || bits > available_bits)
        {
@@ -649,6 +703,7 @@ static void jlink_tap_append_step(int tms, int tdi)
        if (index >= JLINK_TAP_BUFFER_SIZE)
        {
                LOG_ERROR("jlink_tap_append_step: overflow");
+               *(u32 *)0xFFFFFFFF = 0;
                exit(-1);
        }
 
@@ -715,7 +770,8 @@ static int jlink_tap_execute(void)
        // number of full bytes (plus one if some would be left over)
        byte_length = TAP_SCAN_BYTES(tap_length);
 
-       usb_out_buffer[0] = EMU_CMD_HW_JTAG3;
+       bool use_jtag3 = jlink_hw_jtag_version >= 3;
+       usb_out_buffer[0] = use_jtag3 ? EMU_CMD_HW_JTAG3 : EMU_CMD_HW_JTAG2;
        usb_out_buffer[1] = 0;
        usb_out_buffer[2] = (tap_length >> 0) & 0xff;
        usb_out_buffer[3] = (tap_length >> 8) & 0xff;
@@ -749,7 +805,7 @@ static int jlink_tap_execute(void)
                DEBUG_JTAG_IO("pending scan result, length = %d", length);
 
 #ifdef _DEBUG_USB_COMMS_
-               jlink_debug_buffer(buffer, byte_length);
+               jlink_debug_buffer(buffer, TAP_SCAN_BYTES(length));
 #endif
 
                if (jtag_read_buffer(buffer, command) != ERROR_OK)
@@ -808,6 +864,19 @@ static jlink_jtag_t* jlink_usb_open()
                                 */
                                usb_set_altinterface(result->usb_handle, 0);
 #endif
+                               struct usb_interface *iface = dev->config->interface;
+                               struct usb_interface_descriptor *desc = iface->altsetting;
+                               for (int i = 0; i < desc->bNumEndpoints; i++)
+                               {
+                                       u8 epnum = desc->endpoint[i].bEndpointAddress;
+                                       bool is_input = epnum & 0x80;
+                                       LOG_DEBUG("usb ep %s %02x", is_input ? "in" : "out", epnum);
+                                       if (is_input)
+                                               jlink_read_ep = epnum;
+                                       else
+                                               jlink_write_ep = epnum;
+                               }
+
                                return result;
                        }
                }
@@ -827,7 +896,6 @@ static void jlink_usb_close(jlink_jtag_t *jlink_jtag)
 static int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length)
 {
        int result;
-       int result2;
 
        result = jlink_usb_write(jlink_jtag, out_length);
        if (result != out_length)
@@ -845,6 +913,10 @@ static int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_le
                return ERROR_JTAG_DEVICE_ERROR;
        }
 
+       if (jlink_hw_jtag_version < 3)
+               return result;
+
+       int result2 = ERROR_OK;
        if (result == in_length)
        {
                /* Must read the result from the EMU too */
@@ -931,7 +1003,7 @@ static int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length)
                return -1;
        }
 
-       result = usb_bulk_write_ex(jlink_jtag->usb_handle, JLINK_WRITE_ENDPOINT,
+       result = usb_bulk_write_ex(jlink_jtag->usb_handle, jlink_write_ep,
                (char *)usb_out_buffer, out_length, JLINK_USB_TIMEOUT);
 
        DEBUG_JTAG_IO("jlink_usb_write, out_length = %d, result = %d", out_length, result);
@@ -945,7 +1017,7 @@ static int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length)
 /* Read data from USB into in_buffer. */
 static int jlink_usb_read(jlink_jtag_t *jlink_jtag, int expected_size)
 {
-       int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT,
+       int result = usb_bulk_read_ex(jlink_jtag->usb_handle, jlink_read_ep,
                (char *)usb_in_buffer, expected_size, JLINK_USB_TIMEOUT);
 
        DEBUG_JTAG_IO("jlink_usb_read, result = %d", result);
@@ -959,7 +1031,7 @@ static int jlink_usb_read(jlink_jtag_t *jlink_jtag, int expected_size)
 /* Read the result from the previous EMU cmd into result_buffer. */
 static int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag)
 {
-       int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT,
+       int result = usb_bulk_read_ex(jlink_jtag->usb_handle, jlink_read_ep,
                (char *)usb_emu_result_buffer, 1 /* JLINK_EMU_RESULT_BUFFER_SIZE */,
                JLINK_USB_TIMEOUT);
 

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)