|
From: openocd-gerrit <ope...@us...> - 2023-07-08 18:01:53
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Main OpenOCD repository".
The branch, master has been updated
via 9cb09f8cfe4c041333f70be5a6b44a5d7c5be4e0 (commit)
from 5ae0264055b2d5e5cea024aba2dd291a4d1d4ada (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 9cb09f8cfe4c041333f70be5a6b44a5d7c5be4e0
Author: Daniel Anselmi <dan...@gm...>
Date: Sat Apr 15 01:13:12 2023 +0200
pld/xilinx: make instruction codes configurable
Change-Id: I4d2c1fbd4d6007ba8d5c8c687a7c13e25fb6a474
Signed-off-by: Daniel Anselmi <dan...@gm...>
Reviewed-on: https://review.openocd.org/c/openocd/+/7713
Tested-by: jenkins
Reviewed-by: Antonio Borneo <bor...@gm...>
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 7c579e30c..05951bbdf 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -8621,6 +8621,23 @@ openocd -f board/digilent_zedboard.cfg -c "init" \
Reads and displays the Virtex-II status register (STAT)
for FPGA @var{pld_name}.
@end deffn
+
+@deffn {Command} {virtex2 set_instr_codes} pld_name 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 and
+SSI devices are using different values.
+@var{pld_name} is the name of the pld device.
+@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.
+@end deffn
+
+@deffn {Command} {virtex2 set_user_codes} pld_name user1 [user2 [user3 [user4]]]
+Change values for boundary scan instructions selecting the registers USER1 to USER4.
+Description of the arguments can be found at command @command{virtex2 set_instr_codes}.
+@end deffn
@end deffn
diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c
index f044bdae9..dfcf4cf34 100644
--- a/src/pld/virtex2.c
+++ b/src/pld/virtex2.c
@@ -13,12 +13,23 @@
#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 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 +39,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 +71,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 +100,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 +148,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 +157,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 +172,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;
@@ -250,6 +261,62 @@ COMMAND_HANDLER(virtex2_handle_read_stat_command)
return ERROR_OK;
}
+COMMAND_HANDLER(virtex2_handle_set_instuction_codes_command)
+{
+ if (CMD_ARGC < 6 || CMD_ARGC > (6 + VIRTEX2_MAX_USER_INSTRUCTIONS))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct pld_device *device = get_pld_device_by_name(CMD_ARGV[0]);
+ if (!device) {
+ command_print(CMD, "pld device '#%s' is unknown", CMD_ARGV[0]);
+ return ERROR_FAIL;
+ }
+
+ struct virtex2_pld_device *virtex2_info = device->driver_priv;
+ if (!virtex2_info)
+ 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;
+
+ unsigned int num_user = CMD_ARGC - 6;
+ for (unsigned int i = 0; i < num_user; ++i)
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[6 + i], instr_codes.user[i]);
+ 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 || CMD_ARGC > (1 + VIRTEX2_MAX_USER_INSTRUCTIONS))
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct pld_device *device = get_pld_device_by_name(CMD_ARGV[0]);
+ if (!device) {
+ command_print(CMD, "pld device '#%s' is unknown", CMD_ARGV[0]);
+ return ERROR_FAIL;
+ }
+
+ struct virtex2_pld_device *virtex2_info = device->driver_priv;
+ if (!virtex2_info)
+ return ERROR_FAIL;
+
+ uint64_t user[VIRTEX2_MAX_USER_INSTRUCTIONS];
+ unsigned int num_user = CMD_ARGC - 1;
+ for (unsigned int i = 0; i < num_user; ++i)
+ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[1 + i], user[i]);
+ virtex2_info->command_set.num_user = num_user;
+ memcpy(virtex2_info->command_set.user, user, num_user * sizeof(uint64_t));
+ return ERROR_OK;
+}
+
PLD_CREATE_COMMAND_HANDLER(virtex2_pld_create_command)
{
if (CMD_ARGC < 4)
@@ -270,6 +337,7 @@ PLD_CREATE_COMMAND_HANDLER(virtex2_pld_create_command)
return ERROR_FAIL;
}
virtex2_info->tap = tap;
+ virtex2_info->command_set = virtex2_default_commands;
virtex2_info->no_jstart = 0;
if (CMD_ARGC >= 5 && strcmp(CMD_ARGV[4], "-no_jstart") == 0)
@@ -287,9 +355,23 @@ static const struct command_registration virtex2_exec_command_handlers[] = {
.handler = virtex2_handle_read_stat_command,
.help = "read status register",
.usage = "pld_name",
+ }, {
+ .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 = "pld_name 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 = "pld_name 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 05558f709..b69e3c97a 100644
--- a/src/pld/virtex2.h
+++ b/src/pld/virtex2.h
@@ -10,9 +10,23 @@
#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];
+ unsigned int num_user;
+};
+
struct virtex2_pld_device {
struct jtag_tap *tap;
int no_jstart;
+ struct virtex2_command_set command_set;
};
#endif /* OPENOCD_PLD_VIRTEX2_H */
-----------------------------------------------------------------------
Summary of changes:
doc/openocd.texi | 17 +++++++++
src/pld/virtex2.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++-------
src/pld/virtex2.h | 14 ++++++++
3 files changed, 125 insertions(+), 12 deletions(-)
hooks/post-receive
--
Main OpenOCD repository
|