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
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.
@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
@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.
}
}
+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
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;
}
struct pld_driver efinix_pld = {
.name = "efinix",
- .pld_device_command = &efinix_pld_device_command,
+ .pld_create_command = &efinix_pld_create_command,
.load = &efinix_load,
};
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;
struct pld_driver gatemate_pld = {
.name = "gatemate",
- .pld_device_command = &gatemate_pld_device_command,
+ .pld_create_command = &gatemate_pld_create_command,
.load = &gatemate_load,
};
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;
}
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;
}
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;
}
.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
};
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;
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,
};
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;
}
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;
}
}
-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;
.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
};
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,
};
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;
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;
}
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;
}
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;
}
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;
}
.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
};
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,
};
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;
}
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;
}
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;
}
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);
}
.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
};
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",
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)
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;
}
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;
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;
.mode = COMMAND_EXEC,
.handler = virtex2_handle_read_stat_command,
.help = "read status register",
- .usage = "pld_num",
+ .usage = "pld_name",
},
COMMAND_REGISTRATION_DONE
};
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,
};
-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
#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
# 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
-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
-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
-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
-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
-expected-id 0x00680A79 \
-expected-id 0x00684A79
-pld device efinix $_CHIPNAME.tap
+pld create $_CHIPNAME.pld efinix -chain-position $_CHIPNAME.tap
-expected-id 0x00240A79 \
-expected-id 0x00220A79
-pld device efinix $_CHIPNAME.tap
+pld create $_CHIPNAME.pld efinix -chain-position $_CHIPNAME.tap
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
-expected-id 0x1100181B \
-expected-id 0x0100481B
-pld device gowin $_CHIPNAME.tap
+pld create $_CHIPNAME.pld gowin -chain-position $_CHIPNAME.tap
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
-expected-id 0x010f4043
# -expected-id 0x01112043
-pld device lattice $_CHIPNAME.tap
+pld create $_CHIPNAME.pld lattice -chain-position $_CHIPNAME.tap
-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
-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
-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
${_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