aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Anselmi <danselmi@gmx.ch>2023-06-03 20:16:19 +0200
committerAntonio Borneo <borneo.antonio@gmail.com>2023-07-08 18:00:52 +0000
commit5ae0264055b2d5e5cea024aba2dd291a4d1d4ada (patch)
tree9304f785dfc51352ec1ec9948766d3d008b90d44
parent7335fbdbda6ff353ec878bf740721f2b13dde7ce (diff)
downloadriscv-openocd-5ae0264055b2d5e5cea024aba2dd291a4d1d4ada.zip
riscv-openocd-5ae0264055b2d5e5cea024aba2dd291a4d1d4ada.tar.gz
riscv-openocd-5ae0264055b2d5e5cea024aba2dd291a4d1d4ada.tar.bz2
pld: give devices a name for referencing in scripts
Change-Id: I05e8596ffacdb6cd8da4dd8a40bb460183f4930a Signed-off-by: Daniel Anselmi <danselmi@gmx.ch> Reviewed-on: https://review.openocd.org/c/openocd/+/7728 Tested-by: jenkins Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
-rw-r--r--doc/openocd.texi66
-rw-r--r--src/jtag/startup.tcl14
-rw-r--r--src/pld/efinix.c13
-rw-r--r--src/pld/gatemate.c17
-rw-r--r--src/pld/gowin.c44
-rw-r--r--src/pld/intel.c57
-rw-r--r--src/pld/lattice.c72
-rw-r--r--src/pld/pld.c166
-rw-r--r--src/pld/pld.h11
-rw-r--r--src/pld/virtex2.c29
-rw-r--r--tcl/cpld/xilinx-xc6s.cfg2
-rw-r--r--tcl/cpld/xilinx-xc7.cfg2
-rw-r--r--tcl/cpld/xilinx-xcu.cfg2
-rw-r--r--tcl/fpga/altera-arriaii.cfg2
-rw-r--r--tcl/fpga/altera-cycloneiii.cfg2
-rw-r--r--tcl/fpga/altera-cycloneiv.cfg2
-rw-r--r--tcl/fpga/altera-cyclonev.cfg2
-rw-r--r--tcl/fpga/efinix_titanium.cfg2
-rw-r--r--tcl/fpga/efinix_trion.cfg2
-rw-r--r--tcl/fpga/gatemate.cfg2
-rw-r--r--tcl/fpga/gowin_gw1n.cfg2
-rw-r--r--tcl/fpga/lattice_certus.cfg2
-rw-r--r--tcl/fpga/lattice_certuspro.cfg2
-rw-r--r--tcl/fpga/lattice_ecp2.cfg2
-rw-r--r--tcl/fpga/lattice_ecp3.cfg2
-rw-r--r--tcl/fpga/lattice_ecp5.cfg2
-rw-r--r--tcl/target/zynq_7000.cfg2
27 files changed, 285 insertions, 238 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 832047f..7c579e3 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -8575,22 +8575,24 @@ As it does for JTAG TAPs, debug targets, and flash chips (both NOR and NAND),
OpenOCD maintains a list of PLDs available for use in various commands.
Also, each such PLD requires a driver.
-They are referenced by the number shown by the @command{pld devices} command,
-and new PLDs are defined by @command{pld device driver_name}.
-
-@deffn {Config Command} {pld device} driver_name tap_name [driver_options]
-Defines a new PLD device, supported by driver @var{driver_name},
-using the TAP named @var{tap_name}.
-The driver may make use of any @var{driver_options} to configure its
-behavior.
+They are referenced by the name which was given when the pld was created or
+the number shown by the @command{pld devices} command.
+New PLDs are defined by @command{pld create pld_name driver_name -chain-position tap_name [driver_options]}.
+
+@deffn {Config Command} {pld create} pld_name driver_name -chain-position tap_name [driver_options]
+Creates a new PLD device, supported by driver @var{driver_name},
+assigning @var{pld_name} for further reference.
+@code{-chain-position} @var{tap_name} names the TAP
+used to access this target.
+The driver may make use of any @var{driver_options} to configure its behavior.
@end deffn
@deffn {Command} {pld devices}
-Lists the PLDs and their numbers.
+List the known PLDs with their name.
@end deffn
-@deffn {Command} {pld load} num filename
-Loads the file @file{filename} into the PLD identified by @var{num}.
+@deffn {Command} {pld load} pld_name filename
+Loads the file @file{filename} into the PLD identified by @var{pld_name}.
The file format must be inferred by the driver.
@end deffn
@@ -8600,12 +8602,12 @@ Drivers may support PLD-specific options to the @command{pld device}
definition command, and may also define commands usable only with
that particular type of PLD.
-@deffn {FPGA Driver} {virtex2} [no_jstart]
+@deffn {FPGA Driver} {virtex2} [@option{-no_jstart}]
Virtex-II is a family of FPGAs sold by Xilinx.
This driver can also be used to load Series3, Series6, Series7 and Zynq 7000 devices.
It supports the IEEE 1532 standard for In-System Configuration (ISC).
-If @var{no_jstart} is non-zero, the JSTART instruction is not used after
+If @var{-no_jstart} is given, the JSTART instruction is not used after
loading the bitstream. While required for Series2, Series3, and Series6, it
breaks bitstream loading on Series7.
@@ -8615,38 +8617,38 @@ openocd -f board/digilent_zedboard.cfg -c "init" \
@end example
-@deffn {Command} {virtex2 read_stat} num
+@deffn {Command} {virtex2 read_stat} pld_name
Reads and displays the Virtex-II status register (STAT)
-for FPGA @var{num}.
+for FPGA @var{pld_name}.
@end deffn
@end deffn
-@deffn {FPGA Driver} {lattice} [family]
+@deffn {FPGA Driver} {lattice} [@option{-family} <name>]
The FGPA families ECP2, ECP3, ECP5, Certus and CertusPro by Lattice are supported.
This driver can be used to load the bitstream into the FPGA or read the status register and read/write the usercode register.
-The option @option{family} is one of @var{ecp2 ecp3 ecp5 certus}. This is needed when the JTAG ID of the device is not known by openocd (newer NX devices).
+For the option @option{-family} @var{name} is one of @var{ecp2 ecp3 ecp5 certus}. This is needed when the JTAG ID of the device is not known by openocd (newer NX devices).
-@deffn {Command} {lattice read_status} num
+@deffn {Command} {lattice read_status} pld_name
Reads and displays the status register
-for FPGA @var{num}.
+for FPGA @var{pld_name}.
@end deffn
-@deffn {Command} {lattice read_user} num
+@deffn {Command} {lattice read_user} pld_name
Reads and displays the user register
-for FPGA @var{num}.
+for FPGA @var{pld_name}.
@end deffn
-@deffn {Command} {lattice write_user} num val
+@deffn {Command} {lattice write_user} pld_name val
Writes the user register.
-for FPGA @var{num} with value @var{val}.
+for FPGA @var{pld_name} with value @var{val}.
@end deffn
-@deffn {Command} {lattice set_preload} num length
+@deffn {Command} {lattice set_preload} pld_name length
Set the length of the register for the preload. This is needed when the JTAG ID of the device is not known by openocd (newer NX devices).
-The load command for the FPGA @var{num} will use a length for the preload of @var{length}.
+The load command for the FPGA @var{pld_name} will use a length for the preload of @var{length}.
@end deffn
@end deffn
@@ -8657,28 +8659,28 @@ This driver can be used to load the bitstream into the FPGA.
@end deffn
-@deffn {FPGA Driver} {intel} [@option{family}]
+@deffn {FPGA Driver} {intel} [@option{-family} <name>]
This driver can be used to load the bitstream into Intel (former Altera) FPGAs.
The families Cyclone III, Cyclone IV, Cyclone V, Cyclone 10, Arria II are supported.
@c Arria V and Arria 10, MAX II, MAX V, MAX10)
-The option @option{family} is one of @var{cycloneiii cycloneiv cyclonev cyclone10 arriaii}.
+For the option @option{-family} @var{name} is one of @var{cycloneiii cycloneiv cyclonev cyclone10 arriaii}.
This is needed when the JTAG ID of the device is ambiguous (same ID is used for chips in different families).
As input file format the driver supports a '.rbf' (raw bitstream file) file. The '.rbf' file can be generated
from a '.sof' file with @verb{|quartus_cpf -c blinker.sof blinker.rbf|}
-Defines a new PLD device, an FPGA of the Cyclone III family, using the TAP named @verb{|cycloneiii.tap|}:
+Creates a new PLD device, an FPGA of the Cyclone III family, using the TAP named @verb{|cycloneiii.tap|}:
@example
-pld device intel cycloneiii.tap cycloneiii
+pld create cycloneiii.pld intel -chain-position cycloneiii.tap -family cycloneiii
@end example
-@deffn {Command} {intel set_bscan} num len
-Set boundary scan register length of FPGA @var{num} to @var{len}. This is needed because the
+@deffn {Command} {intel set_bscan} pld_name len
+Set boundary scan register length of FPGA @var{pld_name} to @var{len}. This is needed because the
length can vary between chips with the same JTAG ID.
@end deffn
-@deffn {Command} {intel set_check_pos} num pos
+@deffn {Command} {intel set_check_pos} pld_name pos
Selects the position @var{pos} in the boundary-scan register. The bit at this
position is checked after loading the bitstream and must be '1', which is the case when no error occurred.
With a value of -1 for @var{pos} the check will be omitted.
diff --git a/src/jtag/startup.tcl b/src/jtag/startup.tcl
index b74775a..085c89b 100644
--- a/src/jtag/startup.tcl
+++ b/src/jtag/startup.tcl
@@ -1108,4 +1108,18 @@ proc "am335xgpio led_on_state" {state} {
}
}
+lappend _telnet_autocomplete_skip "pld device"
+proc "pld device" {driver tap_name {opt 0}} {
+ echo "DEPRECATED! use 'pld create ...', not 'pld device ...'"
+ if {[string is integer -strict $opt]} {
+ if {$opt == 0} {
+ eval pld create [lindex [split $tap_name .] 0].pld $driver -chain-position $tap_name
+ } else {
+ eval pld create [lindex [split $tap_name .] 0].pld $driver -chain-position $tap_name -no_jstart
+ }
+ } else {
+ eval pld create [lindex [split $tap_name .] 0].pld $driver -chain-position $tap_name -family $opt
+ }
+}
+
# END MIGRATION AIDS
diff --git a/src/pld/efinix.c b/src/pld/efinix.c
index f084394..370f184 100644
--- a/src/pld/efinix.c
+++ b/src/pld/efinix.c
@@ -188,14 +188,17 @@ static int efinix_load(struct pld_device *pld_device, const char *filename)
return retval;
}
-PLD_DEVICE_COMMAND_HANDLER(efinix_pld_device_command)
+PLD_CREATE_COMMAND_HANDLER(efinix_pld_create_command)
{
- if (CMD_ARGC != 2)
+ if (CMD_ARGC != 4)
return ERROR_COMMAND_SYNTAX_ERROR;
- struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[1]);
+ if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
if (!tap) {
- command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
+ command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
return ERROR_FAIL;
}
@@ -213,6 +216,6 @@ PLD_DEVICE_COMMAND_HANDLER(efinix_pld_device_command)
struct pld_driver efinix_pld = {
.name = "efinix",
- .pld_device_command = &efinix_pld_device_command,
+ .pld_create_command = &efinix_pld_create_command,
.load = &efinix_load,
};
diff --git a/src/pld/gatemate.c b/src/pld/gatemate.c
index 43b3f02..4ad2665 100644
--- a/src/pld/gatemate.c
+++ b/src/pld/gatemate.c
@@ -209,22 +209,21 @@ static int gatemate_load(struct pld_device *pld_device, const char *filename)
return retval;
}
-PLD_DEVICE_COMMAND_HANDLER(gatemate_pld_device_command)
+PLD_CREATE_COMMAND_HANDLER(gatemate_pld_create_command)
{
- struct jtag_tap *tap;
-
- struct gatemate_pld_device *gatemate_info;
+ if (CMD_ARGC != 4)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- if (CMD_ARGC != 2)
+ if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
- tap = jtag_tap_by_string(CMD_ARGV[1]);
+ struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
if (!tap) {
- command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
+ command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
return ERROR_FAIL;
}
- gatemate_info = malloc(sizeof(struct gatemate_pld_device));
+ struct gatemate_pld_device *gatemate_info = malloc(sizeof(struct gatemate_pld_device));
if (!gatemate_info) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
@@ -238,6 +237,6 @@ PLD_DEVICE_COMMAND_HANDLER(gatemate_pld_device_command)
struct pld_driver gatemate_pld = {
.name = "gatemate",
- .pld_device_command = &gatemate_pld_device_command,
+ .pld_create_command = &gatemate_pld_create_command,
.load = &gatemate_load,
};
diff --git a/src/pld/gowin.c b/src/pld/gowin.c
index 467b799..ab3582c 100644
--- a/src/pld/gowin.c
+++ b/src/pld/gowin.c
@@ -451,15 +451,12 @@ static int gowin_reload_command(struct pld_device *pld_device)
COMMAND_HANDLER(gowin_read_status_command_handler)
{
- int dev_id;
-
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *device = get_pld_device_by_num(dev_id);
+ struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -474,15 +471,12 @@ COMMAND_HANDLER(gowin_read_status_command_handler)
COMMAND_HANDLER(gowin_read_user_register_command_handler)
{
- int dev_id;
-
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *device = get_pld_device_by_num(dev_id);
+ struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -497,15 +491,12 @@ COMMAND_HANDLER(gowin_read_user_register_command_handler)
COMMAND_HANDLER(gowin_reload_command_handler)
{
- int dev_id;
-
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *device = get_pld_device_by_num(dev_id);
+ struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -518,19 +509,19 @@ static const struct command_registration gowin_exec_command_handlers[] = {
.mode = COMMAND_EXEC,
.handler = gowin_read_status_command_handler,
.help = "reading status register from FPGA",
- .usage = "num_pld",
+ .usage = "pld_name",
}, {
.name = "read_user",
.mode = COMMAND_EXEC,
.handler = gowin_read_user_register_command_handler,
.help = "reading user register from FPGA",
- .usage = "num_pld",
+ .usage = "pld_name",
}, {
.name = "reload",
.mode = COMMAND_EXEC,
.handler = gowin_reload_command_handler,
.help = "reloading bitstream from flash to SRAM",
- .usage = "num_pld",
+ .usage = "pld_name",
},
COMMAND_REGISTRATION_DONE
};
@@ -546,22 +537,21 @@ static const struct command_registration gowin_command_handler[] = {
COMMAND_REGISTRATION_DONE
};
-PLD_DEVICE_COMMAND_HANDLER(gowin_pld_device_command)
+PLD_CREATE_COMMAND_HANDLER(gowin_pld_create_command)
{
- struct jtag_tap *tap;
-
- struct gowin_pld_device *gowin_info;
+ if (CMD_ARGC != 4)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- if (CMD_ARGC != 2)
+ if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
- tap = jtag_tap_by_string(CMD_ARGV[1]);
+ struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
if (!tap) {
- command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
+ command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
return ERROR_FAIL;
}
- gowin_info = malloc(sizeof(struct gowin_pld_device));
+ struct gowin_pld_device *gowin_info = malloc(sizeof(struct gowin_pld_device));
if (!gowin_info) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
@@ -576,6 +566,6 @@ PLD_DEVICE_COMMAND_HANDLER(gowin_pld_device_command)
struct pld_driver gowin_pld = {
.name = "gowin",
.commands = gowin_command_handler,
- .pld_device_command = &gowin_pld_device_command,
+ .pld_create_command = &gowin_pld_create_command,
.load = &gowin_load_to_sram,
};
diff --git a/src/pld/intel.c b/src/pld/intel.c
index 119a569..92a790b 100644
--- a/src/pld/intel.c
+++ b/src/pld/intel.c
@@ -339,16 +339,14 @@ static int intel_load(struct pld_device *pld_device, const char *filename)
COMMAND_HANDLER(intel_set_bscan_command_handler)
{
- int dev_id;
unsigned int boundary_scan_length;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *pld_device = get_pld_device_by_num(dev_id);
+ struct pld_device *pld_device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!pld_device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -366,16 +364,14 @@ COMMAND_HANDLER(intel_set_bscan_command_handler)
COMMAND_HANDLER(intel_set_check_pos_command_handler)
{
- int dev_id;
int checkpos;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *pld_device = get_pld_device_by_num(dev_id);
+ struct pld_device *pld_device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!pld_device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -392,42 +388,47 @@ COMMAND_HANDLER(intel_set_check_pos_command_handler)
}
-PLD_DEVICE_COMMAND_HANDLER(intel_pld_device_command)
+PLD_CREATE_COMMAND_HANDLER(intel_pld_create_command)
{
- if (CMD_ARGC < 2 || CMD_ARGC > 3)
+ if (CMD_ARGC != 4 && CMD_ARGC != 6)
return ERROR_COMMAND_SYNTAX_ERROR;
- struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[1]);
- if (!tap) {
- command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
- return ERROR_FAIL;
- }
+ if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- struct intel_pld_device *intel_info = malloc(sizeof(struct intel_pld_device));
- if (!intel_info) {
- LOG_ERROR("Out of memory");
+ struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
+ if (!tap) {
+ command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
return ERROR_FAIL;
}
enum intel_family_e family = INTEL_UNKNOWN;
+ if (CMD_ARGC == 6) {
+ if (strcmp(CMD_ARGV[4], "-family") != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- if (CMD_ARGC == 3) {
- if (strcmp(CMD_ARGV[2], "cycloneiii") == 0) {
+ if (strcmp(CMD_ARGV[5], "cycloneiii") == 0) {
family = INTEL_CYCLONEIII;
- } else if (strcmp(CMD_ARGV[2], "cycloneiv") == 0) {
+ } else if (strcmp(CMD_ARGV[5], "cycloneiv") == 0) {
family = INTEL_CYCLONEIV;
- } else if (strcmp(CMD_ARGV[2], "cyclonev") == 0) {
+ } else if (strcmp(CMD_ARGV[5], "cyclonev") == 0) {
family = INTEL_CYCLONEV;
- } else if (strcmp(CMD_ARGV[2], "cyclone10") == 0) {
+ } else if (strcmp(CMD_ARGV[5], "cyclone10") == 0) {
family = INTEL_CYCLONE10;
- } else if (strcmp(CMD_ARGV[2], "arriaii") == 0) {
+ } else if (strcmp(CMD_ARGV[5], "arriaii") == 0) {
family = INTEL_ARRIAII;
} else {
command_print(CMD, "unknown family");
- free(intel_info);
return ERROR_FAIL;
}
}
+
+ struct intel_pld_device *intel_info = malloc(sizeof(struct intel_pld_device));
+ if (!intel_info) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
intel_info->tap = tap;
intel_info->boundary_scan_length = 0;
intel_info->checkpos = -1;
@@ -444,13 +445,13 @@ static const struct command_registration intel_exec_command_handlers[] = {
.mode = COMMAND_EXEC,
.handler = intel_set_bscan_command_handler,
.help = "set boundary scan register length of FPGA",
- .usage = "num_pld len",
+ .usage = "pld_name len",
}, {
.name = "set_check_pos",
.mode = COMMAND_EXEC,
.handler = intel_set_check_pos_command_handler,
.help = "set check_pos of FPGA",
- .usage = "num_pld pos",
+ .usage = "pld_name pos",
},
COMMAND_REGISTRATION_DONE
};
@@ -469,6 +470,6 @@ static const struct command_registration intel_command_handler[] = {
struct pld_driver intel_pld = {
.name = "intel",
.commands = intel_command_handler,
- .pld_device_command = &intel_pld_device_command,
+ .pld_create_command = &intel_pld_create_command,
.load = &intel_load,
};
diff --git a/src/pld/lattice.c b/src/pld/lattice.c
index 4ab5f63..63d7306 100644
--- a/src/pld/lattice.c
+++ b/src/pld/lattice.c
@@ -316,39 +316,46 @@ static int lattice_load_command(struct pld_device *pld_device, const char *filen
return retval;
}
-PLD_DEVICE_COMMAND_HANDLER(lattice_pld_device_command)
+PLD_CREATE_COMMAND_HANDLER(lattice_pld_create_command)
{
- if (CMD_ARGC < 2 || CMD_ARGC > 3)
+ if (CMD_ARGC != 4 && CMD_ARGC != 6)
return ERROR_COMMAND_SYNTAX_ERROR;
- struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[1]);
+ if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
if (!tap) {
- command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
+ command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
return ERROR_FAIL;
}
- struct lattice_pld_device *lattice_device = malloc(sizeof(struct lattice_pld_device));
- if (!lattice_device) {
- LOG_ERROR("Out of memory");
- return ERROR_FAIL;
- }
/* id is not known yet -> postpone lattice_check_device_family() */
enum lattice_family_e family = LATTICE_UNKNOWN;
- if (CMD_ARGC == 3) {
- if (strcasecmp(CMD_ARGV[2], "ecp2") == 0) {
+ if (CMD_ARGC == 6) {
+ if (strcmp(CMD_ARGV[4], "-family") != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ if (strcasecmp(CMD_ARGV[5], "ecp2") == 0) {
family = LATTICE_ECP2;
- } else if (strcasecmp(CMD_ARGV[2], "ecp3") == 0) {
+ } else if (strcasecmp(CMD_ARGV[5], "ecp3") == 0) {
family = LATTICE_ECP3;
- } else if (strcasecmp(CMD_ARGV[2], "ecp5") == 0) {
+ } else if (strcasecmp(CMD_ARGV[5], "ecp5") == 0) {
family = LATTICE_ECP5;
- } else if (strcasecmp(CMD_ARGV[2], "certus") == 0) {
+ } else if (strcasecmp(CMD_ARGV[5], "certus") == 0) {
family = LATTICE_CERTUS;
} else {
command_print(CMD, "unknown family");
- free(lattice_device);
return ERROR_FAIL;
}
}
+
+ struct lattice_pld_device *lattice_device = malloc(sizeof(struct lattice_pld_device));
+ if (!lattice_device) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
lattice_device->tap = tap;
lattice_device->family = family;
lattice_device->preload_length = 0;
@@ -360,16 +367,14 @@ PLD_DEVICE_COMMAND_HANDLER(lattice_pld_device_command)
COMMAND_HANDLER(lattice_read_usercode_register_command_handler)
{
- int dev_id;
uint32_t usercode;
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *device = get_pld_device_by_num(dev_id);
+ struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -390,16 +395,14 @@ COMMAND_HANDLER(lattice_read_usercode_register_command_handler)
COMMAND_HANDLER(lattice_set_preload_command_handler)
{
- int dev_id;
unsigned int preload_length;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *device = get_pld_device_by_num(dev_id);
+ struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -417,16 +420,14 @@ COMMAND_HANDLER(lattice_set_preload_command_handler)
COMMAND_HANDLER(lattice_write_usercode_register_command_handler)
{
- int dev_id;
uint32_t usercode;
if (CMD_ARGC != 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *device = get_pld_device_by_num(dev_id);
+ struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -445,15 +446,12 @@ COMMAND_HANDLER(lattice_write_usercode_register_command_handler)
COMMAND_HANDLER(lattice_read_status_command_handler)
{
- int dev_id;
-
if (CMD_ARGC != 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], dev_id);
- struct pld_device *device = get_pld_device_by_num(dev_id);
+ struct pld_device *device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -487,25 +485,25 @@ static const struct command_registration lattice_exec_command_handlers[] = {
.mode = COMMAND_EXEC,
.handler = lattice_read_status_command_handler,
.help = "reading status register from FPGA",
- .usage = "num_pld",
+ .usage = "pld_name",
}, {
.name = "read_user",
.mode = COMMAND_EXEC,
.handler = lattice_read_usercode_register_command_handler,
.help = "reading usercode register from FPGA",
- .usage = "num_pld",
+ .usage = "pld_name",
}, {
.name = "write_user",
.mode = COMMAND_EXEC,
.handler = lattice_write_usercode_register_command_handler,
.help = "writing usercode register to FPGA",
- .usage = "num_pld value",
+ .usage = "pld_name value",
}, {
.name = "set_preload",
.mode = COMMAND_EXEC,
.handler = lattice_set_preload_command_handler,
.help = "set length for preload (device specific)",
- .usage = "num_pld value",
+ .usage = "pld_name value",
},
COMMAND_REGISTRATION_DONE
};
@@ -524,6 +522,6 @@ static const struct command_registration lattice_command_handler[] = {
struct pld_driver lattice_pld = {
.name = "lattice",
.commands = lattice_command_handler,
- .pld_device_command = &lattice_pld_device_command,
+ .pld_create_command = &lattice_pld_create_command,
.load = &lattice_load_command,
};
diff --git a/src/pld/pld.c b/src/pld/pld.c
index 07b575f..c375418 100644
--- a/src/pld/pld.c
+++ b/src/pld/pld.c
@@ -34,68 +34,110 @@ struct pld_device *get_pld_device_by_num(int num)
int i = 0;
for (p = pld_devices; p; p = p->next) {
- if (i++ == num)
+ if (i++ == num) {
+ LOG_WARNING("DEPRECATED: use pld name \"%s\" instead of number %d", p->name, num);
return p;
+ }
}
return NULL;
}
-/* pld device <driver> [driver_options ...]
- */
-COMMAND_HANDLER(handle_pld_device_command)
+struct pld_device *get_pld_device_by_name(const char *name)
{
- int i;
- int found = 0;
+ for (struct pld_device *p = pld_devices; p; p = p->next) {
+ if (strcmp(p->name, name) == 0)
+ return p;
+ }
+
+ return NULL;
+}
- if (CMD_ARGC < 1)
+struct pld_device *get_pld_device_by_name_or_numstr(const char *str)
+{
+ struct pld_device *dev = get_pld_device_by_name(str);
+ if (dev)
+ return dev;
+
+ char *end;
+ unsigned long dev_num = strtoul(str, &end, 0);
+ if (*end || dev_num > INT_MAX) {
+ LOG_ERROR("Invalid argument");
+ return NULL;
+ }
+
+ return get_pld_device_by_num(dev_num);
+}
+
+/* @deffn {Config Command} {pld create} pld_name driver -chain-position tap_name [options]
+*/
+COMMAND_HANDLER(handle_pld_create_command)
+{
+ if (CMD_ARGC < 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- for (i = 0; pld_drivers[i]; i++) {
- if (strcmp(CMD_ARGV[0], pld_drivers[i]->name) == 0) {
- struct pld_device *p, *c;
-
- /* register pld specific commands */
- int retval;
- if (pld_drivers[i]->commands) {
- retval = register_commands(CMD_CTX, NULL, pld_drivers[i]->commands);
- if (retval != ERROR_OK) {
- LOG_ERROR("couldn't register '%s' commands", CMD_ARGV[0]);
- return ERROR_FAIL;
- }
- }
-
- c = malloc(sizeof(struct pld_device));
- c->driver = pld_drivers[i];
- c->next = NULL;
-
- retval = CALL_COMMAND_HANDLER(
- pld_drivers[i]->pld_device_command, c);
- if (retval != ERROR_OK) {
- LOG_ERROR("'%s' driver rejected pld device",
- CMD_ARGV[0]);
- free(c);
- return ERROR_OK;
- }
-
- /* put pld device in linked list */
- if (pld_devices) {
- /* find last pld device */
- for (p = pld_devices; p && p->next; p = p->next)
- ;
- if (p)
- p->next = c;
- } else
- pld_devices = c;
-
- found = 1;
+ struct pld_driver *pld_driver = NULL;
+
+ for (int i = 0; pld_drivers[i]; i++) {
+ if (strcmp(CMD_ARGV[1], pld_drivers[i]->name) == 0) {
+ pld_driver = pld_drivers[i];
+ break;
+ }
+ }
+
+ if (!pld_driver) {
+ LOG_ERROR("pld driver '%s' not found", CMD_ARGV[1]);
+ return ERROR_FAIL; /* exit(-1); */
+ }
+
+ if (get_pld_device_by_name(CMD_ARGV[0])) {
+ LOG_ERROR("pld device with name '%s' already exists", CMD_ARGV[0]);
+ return ERROR_FAIL;
+ }
+
+ struct pld_device *pld_device = malloc(sizeof(struct pld_device));
+ if (!pld_device) {
+ LOG_ERROR("Out of memory");
+ return ERROR_FAIL;
+ }
+
+ pld_device->driver = pld_driver;
+ pld_device->next = NULL;
+
+ int retval = CALL_COMMAND_HANDLER(pld_driver->pld_create_command, pld_device);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("'%s' driver rejected pld device",
+ CMD_ARGV[1]);
+ free(pld_device);
+ return ERROR_OK;
+ }
+ pld_device->name = strdup(CMD_ARGV[0]);
+ if (!pld_device->name) {
+ LOG_ERROR("Out of memory");
+ free(pld_device);
+ return ERROR_FAIL;
+ }
+
+ /* register pld specific commands */
+ if (pld_driver->commands) {
+ retval = register_commands(CMD_CTX, NULL, pld_driver->commands);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("couldn't register '%s' commands", CMD_ARGV[1]);
+ free(pld_device->name);
+ free(pld_device);
+ return ERROR_FAIL;
}
}
- /* no matching pld driver found */
- if (!found) {
- LOG_ERROR("pld driver '%s' not found", CMD_ARGV[0]);
- exit(-1);
+ if (pld_devices) {
+ /* find last pld device */
+ struct pld_device *p = pld_devices;
+ for (; p && p->next; p = p->next)
+ ;
+ if (p)
+ p->next = pld_device;
+ } else {
+ pld_devices = pld_device;
}
return ERROR_OK;
@@ -112,7 +154,7 @@ COMMAND_HANDLER(handle_pld_devices_command)
}
for (p = pld_devices; p; p = p->next)
- command_print(CMD, "#%i: %s", i++, p->driver->name);
+ command_print(CMD, "#%i: %s (driver: %s)", i++, p->name, p->driver->name);
return ERROR_OK;
}
@@ -128,11 +170,9 @@ COMMAND_HANDLER(handle_pld_load_command)
if (CMD_ARGC < 2)
return ERROR_COMMAND_SYNTAX_ERROR;
- unsigned dev_id;
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], dev_id);
- p = get_pld_device_by_num(dev_id);
+ p = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!p) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_OK;
}
@@ -154,15 +194,15 @@ COMMAND_HANDLER(handle_pld_load_command)
retval = p->driver->load(p, CMD_ARGV[1]);
if (retval != ERROR_OK) {
- command_print(CMD, "failed loading file %s to pld device %u",
- CMD_ARGV[1], dev_id);
+ command_print(CMD, "failed loading file %s to pld device %s",
+ CMD_ARGV[1], CMD_ARGV[0]);
return retval;
} else {
gettimeofday(&end, NULL);
timeval_subtract(&duration, &end, &start);
- command_print(CMD, "loaded file %s to pld device %u in %jis %jius",
- CMD_ARGV[1], dev_id,
+ command_print(CMD, "loaded file %s to pld device %s in %jis %jius",
+ CMD_ARGV[1], CMD_ARGV[0],
(intmax_t)duration.tv_sec, (intmax_t)duration.tv_usec);
}
@@ -182,7 +222,7 @@ static const struct command_registration pld_exec_command_handlers[] = {
.handler = handle_pld_load_command,
.mode = COMMAND_EXEC,
.help = "load configuration file into PLD",
- .usage = "pld_num filename",
+ .usage = "pld_name filename",
},
COMMAND_REGISTRATION_DONE
};
@@ -213,11 +253,11 @@ COMMAND_HANDLER(handle_pld_init_command)
static const struct command_registration pld_config_command_handlers[] = {
{
- .name = "device",
+ .name = "create",
.mode = COMMAND_CONFIG,
- .handler = handle_pld_device_command,
- .help = "configure a PLD device",
- .usage = "driver_name [driver_args ... ]",
+ .handler = handle_pld_create_command,
+ .help = "create a PLD device",
+ .usage = "name.pld driver_name [driver_args ... ]",
},
{
.name = "init",
diff --git a/src/pld/pld.h b/src/pld/pld.h
index 322b96e..8a2a118 100644
--- a/src/pld/pld.h
+++ b/src/pld/pld.h
@@ -12,28 +12,31 @@
struct pld_device;
-#define __PLD_DEVICE_COMMAND(name) \
+#define __PLD_CREATE_COMMAND(name) \
COMMAND_HELPER(name, struct pld_device *pld)
struct pld_driver {
const char *name;
- __PLD_DEVICE_COMMAND((*pld_device_command));
+ __PLD_CREATE_COMMAND((*pld_create_command));
const struct command_registration *commands;
int (*load)(struct pld_device *pld_device, const char *filename);
};
-#define PLD_DEVICE_COMMAND_HANDLER(name) \
- static __PLD_DEVICE_COMMAND(name)
+#define PLD_CREATE_COMMAND_HANDLER(name) \
+ static __PLD_CREATE_COMMAND(name)
struct pld_device {
struct pld_driver *driver;
void *driver_priv;
struct pld_device *next;
+ char *name;
};
int pld_register_commands(struct command_context *cmd_ctx);
struct pld_device *get_pld_device_by_num(int num);
+struct pld_device *get_pld_device_by_name(const char *name);
+struct pld_device *get_pld_device_by_name_or_numstr(const char *str);
#define ERROR_PLD_DEVICE_INVALID (-1000)
#define ERROR_PLD_FILE_LOAD_FAILED (-1001)
diff --git a/src/pld/virtex2.c b/src/pld/virtex2.c
index fd0725a..f044bda 100644
--- a/src/pld/virtex2.c
+++ b/src/pld/virtex2.c
@@ -233,11 +233,9 @@ COMMAND_HANDLER(virtex2_handle_read_stat_command)
if (CMD_ARGC < 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- unsigned dev_id;
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], dev_id);
- device = get_pld_device_by_num(dev_id);
+ device = get_pld_device_by_name_or_numstr(CMD_ARGV[0]);
if (!device) {
- command_print(CMD, "pld device '#%s' is out of bounds", CMD_ARGV[0]);
+ command_print(CMD, "pld device '#%s' is out of bounds or unknown", CMD_ARGV[0]);
return ERROR_FAIL;
}
@@ -252,22 +250,21 @@ COMMAND_HANDLER(virtex2_handle_read_stat_command)
return ERROR_OK;
}
-PLD_DEVICE_COMMAND_HANDLER(virtex2_pld_device_command)
+PLD_CREATE_COMMAND_HANDLER(virtex2_pld_create_command)
{
- struct jtag_tap *tap;
-
- struct virtex2_pld_device *virtex2_info;
+ if (CMD_ARGC < 4)
+ return ERROR_COMMAND_SYNTAX_ERROR;
- if (CMD_ARGC < 2)
+ if (strcmp(CMD_ARGV[2], "-chain-position") != 0)
return ERROR_COMMAND_SYNTAX_ERROR;
- tap = jtag_tap_by_string(CMD_ARGV[1]);
+ struct jtag_tap *tap = jtag_tap_by_string(CMD_ARGV[3]);
if (!tap) {
- command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
+ command_print(CMD, "Tap: %s does not exist", CMD_ARGV[3]);
return ERROR_FAIL;
}
- virtex2_info = malloc(sizeof(struct virtex2_pld_device));
+ struct virtex2_pld_device *virtex2_info = malloc(sizeof(struct virtex2_pld_device));
if (!virtex2_info) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
@@ -275,8 +272,8 @@ PLD_DEVICE_COMMAND_HANDLER(virtex2_pld_device_command)
virtex2_info->tap = tap;
virtex2_info->no_jstart = 0;
- if (CMD_ARGC >= 3)
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], virtex2_info->no_jstart);
+ if (CMD_ARGC >= 5 && strcmp(CMD_ARGV[4], "-no_jstart") == 0)
+ virtex2_info->no_jstart = 1;
pld->driver_priv = virtex2_info;
@@ -289,7 +286,7 @@ static const struct command_registration virtex2_exec_command_handlers[] = {
.mode = COMMAND_EXEC,
.handler = virtex2_handle_read_stat_command,
.help = "read status register",
- .usage = "pld_num",
+ .usage = "pld_name",
},
COMMAND_REGISTRATION_DONE
};
@@ -307,6 +304,6 @@ static const struct command_registration virtex2_command_handler[] = {
struct pld_driver virtex2_pld = {
.name = "virtex2",
.commands = virtex2_command_handler,
- .pld_device_command = &virtex2_pld_device_command,
+ .pld_create_command = &virtex2_pld_create_command,
.load = &virtex2_load,
};
diff --git a/tcl/cpld/xilinx-xc6s.cfg b/tcl/cpld/xilinx-xc6s.cfg
index 82b87fb..33b6d71 100644
--- a/tcl/cpld/xilinx-xc6s.cfg
+++ b/tcl/cpld/xilinx-xc6s.cfg
@@ -25,7 +25,7 @@ jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \
-expected-id 0x0401D093 \
-expected-id 0x0403D093
-pld device virtex2 $_CHIPNAME.tap
+pld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap
set XC6S_CFG_IN 0x05
set XC6S_JSHUTDOWN 0x0d
diff --git a/tcl/cpld/xilinx-xc7.cfg b/tcl/cpld/xilinx-xc7.cfg
index 91a07f9..1b1cb80 100644
--- a/tcl/cpld/xilinx-xc7.cfg
+++ b/tcl/cpld/xilinx-xc7.cfg
@@ -49,7 +49,7 @@ jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \
#jtag newtap $_CHIPNAME tap -irlen 38 -ignore-version -expected-id 0x036DB093
-pld device virtex2 $_CHIPNAME.tap 1
+pld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap -no_jstart
set XC7_JSHUTDOWN 0x0d
set XC7_JPROGRAM 0x0b
diff --git a/tcl/cpld/xilinx-xcu.cfg b/tcl/cpld/xilinx-xcu.cfg
index 9df696d..8518e96 100644
--- a/tcl/cpld/xilinx-xcu.cfg
+++ b/tcl/cpld/xilinx-xcu.cfg
@@ -54,7 +54,7 @@ set _IRLEN [lindex $_XCU_DATA($CHIP) 1]
# the 4 top bits (28:31) are the die stepping/revisions. ignore it.
jtag newtap $_CHIPNAME tap -irlen $_IRLEN -ignore-version -expected-id $_EXPID
-pld device virtex2 $_CHIPNAME.tap 1
+pld create $_CHIPNAME.pld virtex2 -chain-position $_CHIPNAME.tap -no_jstart
set XCU_JSHUTDOWN 0x0d
set XCU_JPROGRAM 0x0b
diff --git a/tcl/fpga/altera-arriaii.cfg b/tcl/fpga/altera-arriaii.cfg
index ae752df..d59c182 100644
--- a/tcl/fpga/altera-arriaii.cfg
+++ b/tcl/fpga/altera-arriaii.cfg
@@ -28,4 +28,4 @@ jtag newtap $_CHIPNAME tap -irlen 10 \
-expected-id 0x025030dd -expected-id 0x024820dd \
-expected-id 0x025140dd
-pld device intel $_CHIPNAME.tap arriaii
+pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family arriaii
diff --git a/tcl/fpga/altera-cycloneiii.cfg b/tcl/fpga/altera-cycloneiii.cfg
index e143572..d9be645 100644
--- a/tcl/fpga/altera-cycloneiii.cfg
+++ b/tcl/fpga/altera-cycloneiii.cfg
@@ -32,4 +32,4 @@ jtag newtap $_CHIPNAME tap -irlen 10 \
-expected-id 0x027000dd -expected-id 0x027030dd \
-expected-id 0x027020dd
-pld device intel $_CHIPNAME.tap cycloneiii
+pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cycloneiii
diff --git a/tcl/fpga/altera-cycloneiv.cfg b/tcl/fpga/altera-cycloneiv.cfg
index 59243cf..6a908e8 100644
--- a/tcl/fpga/altera-cycloneiv.cfg
+++ b/tcl/fpga/altera-cycloneiv.cfg
@@ -38,4 +38,4 @@ jtag newtap $_CHIPNAME tap -irlen 10 \
-expected-id 0x028030dd -expected-id 0x028140dd \
-expected-id 0x028040dd
-pld device intel $_CHIPNAME.tap cycloneiv
+pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cycloneiv
diff --git a/tcl/fpga/altera-cyclonev.cfg b/tcl/fpga/altera-cyclonev.cfg
index 1e9c9c4..46532a5 100644
--- a/tcl/fpga/altera-cyclonev.cfg
+++ b/tcl/fpga/altera-cyclonev.cfg
@@ -44,4 +44,4 @@ jtag newtap $_CHIPNAME tap -irlen 10 \
-expected-id 0x02d110dd -expected-id 0x02d010dd \
-expected-id 0x02d120dd -expected-id 0x02d020dd
-pld device intel $_CHIPNAME.tap cyclonev
+pld create $_CHIPNAME.pld intel -chain-position $_CHIPNAME.tap -family cyclonev
diff --git a/tcl/fpga/efinix_titanium.cfg b/tcl/fpga/efinix_titanium.cfg
index 681b58f..8b356cb 100644
--- a/tcl/fpga/efinix_titanium.cfg
+++ b/tcl/fpga/efinix_titanium.cfg
@@ -20,4 +20,4 @@ jtag newtap $_CHIPNAME tap -irlen 5 -ignore-version \
-expected-id 0x00680A79 \
-expected-id 0x00684A79
-pld device efinix $_CHIPNAME.tap
+pld create $_CHIPNAME.pld efinix -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/efinix_trion.cfg b/tcl/fpga/efinix_trion.cfg
index ecd2eda..2b50d8c 100644
--- a/tcl/fpga/efinix_trion.cfg
+++ b/tcl/fpga/efinix_trion.cfg
@@ -14,4 +14,4 @@ jtag newtap $_CHIPNAME tap -irlen 4 -ignore-version \
-expected-id 0x00240A79 \
-expected-id 0x00220A79
-pld device efinix $_CHIPNAME.tap
+pld create $_CHIPNAME.pld efinix -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/gatemate.cfg b/tcl/fpga/gatemate.cfg
index cc19fd4..e8f3382 100644
--- a/tcl/fpga/gatemate.cfg
+++ b/tcl/fpga/gatemate.cfg
@@ -13,4 +13,4 @@ if { [info exists CHIPNAME] } {
jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \
-expected-id 0x20000001
-pld device gatemate $_CHIPNAME.tap
+pld create $_CHIPNAME.pld gatemate -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/gowin_gw1n.cfg b/tcl/fpga/gowin_gw1n.cfg
index 43d66b7..5e85066 100644
--- a/tcl/fpga/gowin_gw1n.cfg
+++ b/tcl/fpga/gowin_gw1n.cfg
@@ -26,4 +26,4 @@ jtag newtap $_CHIPNAME tap -irlen 8 -ignore-version \
-expected-id 0x1100181B \
-expected-id 0x0100481B
-pld device gowin $_CHIPNAME.tap
+pld create $_CHIPNAME.pld gowin -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/lattice_certus.cfg b/tcl/fpga/lattice_certus.cfg
index 95b6e59..9ddb7d8 100644
--- a/tcl/fpga/lattice_certus.cfg
+++ b/tcl/fpga/lattice_certus.cfg
@@ -15,4 +15,4 @@ if { [info exists CHIPNAME] } {
jtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \
-expected-id 0x310F1043 -expected-id 0x310F0043
-pld device lattice $_CHIPNAME.tap
+pld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/lattice_certuspro.cfg b/tcl/fpga/lattice_certuspro.cfg
index c15a379..acaaa57 100644
--- a/tcl/fpga/lattice_certuspro.cfg
+++ b/tcl/fpga/lattice_certuspro.cfg
@@ -15,4 +15,4 @@ jtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \
-expected-id 0x010f4043
# -expected-id 0x01112043
-pld device lattice $_CHIPNAME.tap
+pld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/lattice_ecp2.cfg b/tcl/fpga/lattice_ecp2.cfg
index a1aa2ef..5b01787 100644
--- a/tcl/fpga/lattice_ecp2.cfg
+++ b/tcl/fpga/lattice_ecp2.cfg
@@ -28,4 +28,4 @@ jtag newtap $_CHIPNAME tap -irlen 8 \
-expected-id 0x01271043 -expected-id 0x01272043 -expected-id 0x01274043 \
-expected-id 0x01273043 -expected-id 0x01275043
-pld device lattice $_CHIPNAME.tap
+pld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/lattice_ecp3.cfg b/tcl/fpga/lattice_ecp3.cfg
index 7cd5706..21c8ffa 100644
--- a/tcl/fpga/lattice_ecp3.cfg
+++ b/tcl/fpga/lattice_ecp3.cfg
@@ -19,4 +19,4 @@ jtag newtap $_CHIPNAME tap -irlen 8 \
-expected-id 0x01010043 -expected-id 0x01012043 \
-expected-id 0x01014043 -expected-id 0x01015043
-pld device lattice $_CHIPNAME.tap
+pld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap
diff --git a/tcl/fpga/lattice_ecp5.cfg b/tcl/fpga/lattice_ecp5.cfg
index 4144249..cdc63f0 100644
--- a/tcl/fpga/lattice_ecp5.cfg
+++ b/tcl/fpga/lattice_ecp5.cfg
@@ -27,4 +27,4 @@ jtag newtap $_CHIPNAME tap -irlen 8 -irmask 0x83 -ircapture 0x1 \
-expected-id 0x41113043 -expected-id 0x81111043 -expected-id 0x81112043 \
-expected-id 0x81113043
-pld device lattice $_CHIPNAME.tap
+pld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap
diff --git a/tcl/target/zynq_7000.cfg b/tcl/target/zynq_7000.cfg
index a6f8995..014c428 100644
--- a/tcl/target/zynq_7000.cfg
+++ b/tcl/target/zynq_7000.cfg
@@ -46,7 +46,7 @@ adapter speed 1000
${_TARGETNAME}0 configure -event reset-assert-post "cortex_a dbginit"
${_TARGETNAME}1 configure -event reset-assert-post "cortex_a dbginit"
-pld device virtex2 zynq_pl.bs 1
+pld create zynq_pl.pld virtex2 -chain-position zynq_pl.bs -no_jstart
set XC7_JSHUTDOWN 0x0d
set XC7_JPROGRAM 0x0b