This is an automated email from Gerrit.

"Daniel Anselmi <danse...@gmx.ch>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/7713

-- gerrit

commit 2e39cf4dfcf3d76ab6a698ef6294257c0e83fd34
Author: Daniel Anselmi <danse...@gmx.ch>
Date:   Sat Apr 15 01:13:12 2023 +0200

    pld/xilinx: make instruction codes configurable
    
    Change-Id: I4d2c1fbd4d6007ba8d5c8c687a7c13e25fb6a474
    Signed-off-by: Daniel Anselmi <danse...@gmx.ch>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index d0bc3f9f50..18a7793c61 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -8509,6 +8509,22 @@ openocd -f board/digilent_zedboard.cfg -c "init" \
 Reads and displays the Virtex-II status register (STAT)
 for FPGA @var{num}.
 @end deffn
+
+@deffn {Command} {virtex2 set_instr_codes} device.tap cfg_out cfg_in jprogb 
jstart jshutdown [user1 [user2 [user3 [user4]]]]
+Change values for boundary scan instructions. Default are values for Virtex 2 
devices Virtex 4/5/6 are using different values.
+@end deffn
+@var{device.tap} is the name of the tap.
+@var{cfg_out} is the value used to select CFG_OUT instruction.
+@var{cfg_in} is the value used to select CFG_IN instruction.
+@var{jprogb} is the value used to select JPROGRAM instruction.
+@var{jstart} is the value used to select JSTART instruction.
+@var{jshutdown} is the value used to select JSHUTDOWN instruction.
+@var{user1} to @var{user4} are the intruction used to select the user 
registers USER1 to USER4.
+
+@deffn {Command} {virtex2 set_user_codes} device.tap user1 [user2 [user3 
[user4]]]
+Change values for boundary scan instructions selecting the registers USER1 to 
USER4.
+@end deffn
+Description of the arguments can be found at command @command{virtex2 
set_instr_codes}.
 @end deffn
 
 
diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c
index fd0725a63a..58cc2df3c7 100644
--- a/src/pld/virtex2.c
+++ b/src/pld/virtex2.c
@@ -13,12 +13,25 @@
 #include "xilinx_bit.h"
 #include "pld.h"
 
-static int virtex2_set_instr(struct jtag_tap *tap, uint32_t new_instr)
+static const struct virtex2_command_set virtex2_default_commands = {
+       .cfg_out   = 0x04,
+       .cfg_in    = 0x05,
+       .jprog_b   = 0x0b,
+       .jstart    = 0x0c,
+       .jshutdown = 0x0d,
+       .bypass    = 0x3f,
+       .user      = {0x02, 0x03},
+       .num_user  = 2, /* virtex II has only 2 user instructions */
+};
+
+static struct virtex2_pld_device *virtex2_pld_devices;
+
+static int virtex2_set_instr(struct jtag_tap *tap, uint64_t new_instr)
 {
        if (!tap)
                return ERROR_FAIL;
 
-       if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
+       if (buf_get_u64(tap->cur_instr, 0, tap->ir_length) != new_instr) {
                struct scan_field field;
 
                field.num_bits = tap->ir_length;
@@ -28,7 +41,7 @@ static int virtex2_set_instr(struct jtag_tap *tap, uint32_t 
new_instr)
                        return ERROR_FAIL;
                }
                field.out_value = t;
-               buf_set_u32(t, 0, field.num_bits, new_instr);
+               buf_set_u64(t, 0, field.num_bits, new_instr);
                field.in_value = NULL;
 
                jtag_add_ir_scan(tap, &field, TAP_IDLE);
@@ -60,7 +73,7 @@ static int virtex2_send_32(struct pld_device *pld_device,
        for (i = 0; i < num_words; i++)
                buf_set_u32(values + 4 * i, 0, 32, flip_u32(*words++, 32));
 
-       int retval = virtex2_set_instr(virtex2_info->tap, 0x5); /* CFG_IN */
+       int retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.cfg_in);
        if (retval != ERROR_OK) {
                free(values);
                return retval;
@@ -89,7 +102,7 @@ static int virtex2_receive_32(struct pld_device *pld_device,
        scan_field.out_value = NULL;
        scan_field.in_value = NULL;
 
-       int retval = virtex2_set_instr(virtex2_info->tap, 0x4); /* CFG_OUT */
+       int retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.cfg_out);
        if (retval != ERROR_OK)
                return retval;
 
@@ -137,7 +150,7 @@ static int virtex2_load_prepare(struct pld_device 
*pld_device)
        struct virtex2_pld_device *virtex2_info = pld_device->driver_priv;
        int retval;
 
-       retval = virtex2_set_instr(virtex2_info->tap, 0xb);     /* JPROG_B */
+       retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.jprog_b);
        if (retval != ERROR_OK)
                return retval;
 
@@ -146,7 +159,7 @@ static int virtex2_load_prepare(struct pld_device 
*pld_device)
                return retval;
        jtag_add_sleep(1000);
 
-       retval = virtex2_set_instr(virtex2_info->tap, 0x5);     /* CFG_IN */
+       retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.cfg_in);
        if (retval != ERROR_OK)
                return retval;
 
@@ -161,24 +174,24 @@ static int virtex2_load_cleanup(struct pld_device 
*pld_device)
        jtag_add_tlr();
 
        if (!(virtex2_info->no_jstart)) {
-               retval = virtex2_set_instr(virtex2_info->tap, 0xc);     /* 
JSTART */
+               retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.jstart);
                if (retval != ERROR_OK)
                        return retval;
        }
        jtag_add_runtest(13, TAP_IDLE);
-       retval = virtex2_set_instr(virtex2_info->tap, 0x3f);            /* 
BYPASS */
+       retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.bypass);
        if (retval != ERROR_OK)
                return retval;
-       retval = virtex2_set_instr(virtex2_info->tap, 0x3f);            /* 
BYPASS */
+       retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.bypass);
        if (retval != ERROR_OK)
                return retval;
        if (!(virtex2_info->no_jstart)) {
-               retval = virtex2_set_instr(virtex2_info->tap, 0xc);     /* 
JSTART */
+               retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.jstart);
                if (retval != ERROR_OK)
                        return retval;
        }
        jtag_add_runtest(13, TAP_IDLE);
-       retval = virtex2_set_instr(virtex2_info->tap, 0x3f);            /* 
BYPASS */
+       retval = virtex2_set_instr(virtex2_info->tap, 
virtex2_info->command_set.bypass);
        if (retval != ERROR_OK)
                return retval;
 
@@ -252,6 +265,91 @@ COMMAND_HANDLER(virtex2_handle_read_stat_command)
        return ERROR_OK;
 }
 
+static int virtex2_get_pld_device_for_tap(struct jtag_tap *tap, struct 
virtex2_pld_device **virtex2_info)
+{
+       if (!tap)
+               return ERROR_FAIL;
+
+       struct virtex2_pld_device *info = virtex2_pld_devices;
+       while (info) {
+               if (info->tap == tap)
+                       break;
+               info = info->next;
+       }
+       if (!info)
+               return ERROR_FAIL;
+
+       *virtex2_info = info;
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command)
+{
+       if (CMD_ARGC < 6)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[0]);
+       if (!tap) {
+               command_print(CMD, "Tap %s unknown", CMD_ARGV[0]);
+               return ERROR_FAIL;
+       }
+
+       struct virtex2_pld_device *virtex2_info;
+       int retval = virtex2_get_pld_device_for_tap(tap, &virtex2_info);
+       if (retval != ERROR_OK) {
+               command_print(CMD, "No virtex2 pld driver initialized for tap 
%s", CMD_ARGV[0]);
+               return ERROR_FAIL;
+       }
+
+       struct virtex2_command_set instr_codes;
+       COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1], instr_codes.cfg_out);
+       COMMAND_PARSE_NUMBER(u64, CMD_ARGV[2], instr_codes.cfg_in);
+       COMMAND_PARSE_NUMBER(u64, CMD_ARGV[3], instr_codes.jprog_b);
+       COMMAND_PARSE_NUMBER(u64, CMD_ARGV[4], instr_codes.jstart);
+       COMMAND_PARSE_NUMBER(u64, CMD_ARGV[5], instr_codes.jshutdown);
+       instr_codes.bypass = 0xffffffffffffffff;
+
+       uint8_t num_user = 0;
+       for (size_t i = 0; i < VIRTEX2_MAX_USER_INSTRUCTIONS && CMD_ARGC > 6 + 
i; ++i) {
+               COMMAND_PARSE_NUMBER(u64, CMD_ARGV[6 + i], instr_codes.user[i]);
+               num_user++;
+       }
+       instr_codes.num_user = num_user;
+
+       virtex2_info->command_set = instr_codes;
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(virtex2_handle_set_user_codes_command)
+{
+       if (CMD_ARGC < 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[0]);
+       if (!tap) {
+               command_print(CMD, "Tap %s unknown", CMD_ARGV[0]);
+               return ERROR_FAIL;
+       }
+
+       struct virtex2_pld_device *virtex2_info;
+       int retval = virtex2_get_pld_device_for_tap(tap, &virtex2_info);
+       if (retval != ERROR_OK) {
+               command_print(CMD, "No virtex2 pld driver initialized for tap 
%s", CMD_ARGV[0]);
+               return ERROR_FAIL;
+       }
+
+       uint64_t user[VIRTEX2_MAX_USER_INSTRUCTIONS];
+       uint8_t num_user = 0;
+       for (size_t i = 0; i < VIRTEX2_MAX_USER_INSTRUCTIONS && CMD_ARGC > 1 + 
i; ++i) {
+               COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1 + i], user[i]);
+               num_user++;
+       }
+       virtex2_info->command_set.num_user = num_user;
+       memcpy(virtex2_info->command_set.user, user, num_user * 
sizeof(uint64_t));
+       return ERROR_OK;
+}
+
 PLD_DEVICE_COMMAND_HANDLER(virtex2_pld_device_command)
 {
        struct jtag_tap *tap;
@@ -273,13 +371,24 @@ PLD_DEVICE_COMMAND_HANDLER(virtex2_pld_device_command)
                return ERROR_FAIL;
        }
        virtex2_info->tap = tap;
+       memcpy(&virtex2_info->command_set, &virtex2_default_commands, 
sizeof(struct virtex2_command_set));
 
        virtex2_info->no_jstart = 0;
        if (CMD_ARGC >= 3)
                COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], virtex2_info->no_jstart);
+       virtex2_info->next = NULL;
 
        pld->driver_priv = virtex2_info;
 
+       if (!virtex2_pld_devices) {
+               virtex2_pld_devices = virtex2_info;
+       } else {
+               struct virtex2_pld_device *devs = virtex2_pld_devices;
+               while (devs->next)
+                       devs = devs->next;
+               devs->next = virtex2_info;
+       }
+
        return ERROR_OK;
 }
 
@@ -290,9 +399,23 @@ static const struct command_registration 
virtex2_exec_command_handlers[] = {
                .handler = virtex2_handle_read_stat_command,
                .help = "read status register",
                .usage = "pld_num",
+       }, {
+               .name = "set_instr_codes",
+               .mode = COMMAND_EXEC,
+               .handler = virtex2_handle_set_instuction_codes_command,
+               .help = "set instructions codes used for loading the 
bitstream/refreshing/jtag-hub",
+               .usage = "device.tap cfg_out cfg_in jprogb jstart jshutdown"
+                                " [user1 [user2 [user3 [user4]]]]",
+       }, {
+               .name = "set_user_codes",
+               .mode = COMMAND_EXEC,
+               .handler = virtex2_handle_set_user_codes_command,
+               .help = "set instructions codes used for jtag-hub",
+               .usage = "device.tap user1 [user2 [user3 [user4]]]",
        },
        COMMAND_REGISTRATION_DONE
 };
+
 static const struct command_registration virtex2_command_handler[] = {
        {
                .name = "virtex2",
diff --git a/src/pld/virtex2.h b/src/pld/virtex2.h
index 05558f709d..32dc44b391 100644
--- a/src/pld/virtex2.h
+++ b/src/pld/virtex2.h
@@ -10,9 +10,24 @@
 
 #include <jtag/jtag.h>
 
+#define VIRTEX2_MAX_USER_INSTRUCTIONS 4
+
+struct virtex2_command_set {
+       uint64_t cfg_out;
+       uint64_t cfg_in;
+       uint64_t jprog_b;
+       uint64_t jstart;
+       uint64_t jshutdown;
+       uint64_t bypass;
+       uint64_t user[VIRTEX2_MAX_USER_INSTRUCTIONS];
+       uint8_t num_user;
+};
+
 struct virtex2_pld_device {
        struct jtag_tap *tap;
        int no_jstart;
+       struct virtex2_command_set command_set;
+       struct virtex2_pld_device *next;
 };
 
 #endif /* OPENOCD_PLD_VIRTEX2_H */

-- 

Reply via email to