jtagspi/pld: add interface to get support from pld drivers

Jtagspi is using a proxy bitstream to "connect" JTAG to the
SPI pins. This is not possible with all FPGA vendors/families.
In this cases a dedicated procedure is needed to establish such
a connection.

This patch adds a jtagspi-mode for these cases. It also adds the
needed interfaces to jtagspi and the pld-driver so the driver
can select the mode and provide the necessary procedures.

For the cases where a proxy bitstream is needed, the pld driver
will select the mode and provide instruction code needed in this
case.

Change-Id: I9563f26739589157b39a3664a73d91152cd13f77
Signed-off-by: Daniel Anselmi <danselmi@gmx.ch>
Reviewed-on: https://review.openocd.org/c/openocd/+/7822
Tested-by: jenkins
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
Daniel Anselmi
2023-02-24 15:57:30 +01:00
committed by Antonio Borneo
parent 30375c6439
commit fe5ed48f40
5 changed files with 245 additions and 47 deletions

View File

@@ -69,8 +69,95 @@ struct pld_device *get_pld_device_by_name_or_numstr(const char *str)
return get_pld_device_by_num(dev_num);
}
/* @deffn {Config Command} {pld create} pld_name driver -chain-position tap_name [options]
*/
int pld_has_jtagspi_instruction(struct pld_device *pld_device, bool *has_instruction)
{
*has_instruction = false; /* default is using a proxy bitstream */
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->has_jtagspi_instruction)
return pld_driver->has_jtagspi_instruction(pld_device, has_instruction);
/* else, take the default (proxy bitstream) */
return ERROR_OK;
}
int pld_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->get_jtagspi_userircode)
return pld_driver->get_jtagspi_userircode(pld_device, ir);
return ERROR_FAIL;
}
int pld_get_jtagspi_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->get_stuff_bits)
return pld_driver->get_stuff_bits(pld_device, facing_read_bits, trailing_write_bits);
return ERROR_OK;
}
int pld_connect_spi_to_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->connect_spi_to_jtag)
return pld_driver->connect_spi_to_jtag(pld_device);
return ERROR_FAIL;
}
int pld_disconnect_spi_from_jtag(struct pld_device *pld_device)
{
if (!pld_device)
return ERROR_FAIL;
struct pld_driver *pld_driver = pld_device->driver;
if (!pld_driver) {
LOG_ERROR("pld device has no associated driver");
return ERROR_FAIL;
}
if (pld_driver->disconnect_spi_from_jtag)
return pld_driver->disconnect_spi_from_jtag(pld_device);
return ERROR_FAIL;
}
COMMAND_HANDLER(handle_pld_create_command)
{
if (CMD_ARGC < 2)

View File

@@ -20,12 +20,26 @@ struct pld_ipdbg_hub {
unsigned int user_ir_code;
};
int pld_has_jtagspi_instruction(struct pld_device *device, bool *has_instruction);
int pld_get_jtagspi_userircode(struct pld_device *pld_device, unsigned int *ir);
int pld_get_jtagspi_stuff_bits(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits);
int pld_connect_spi_to_jtag(struct pld_device *pld_device);
int pld_disconnect_spi_from_jtag(struct pld_device *pld_device);
struct pld_driver {
const char *name;
__PLD_CREATE_COMMAND((*pld_create_command));
const struct command_registration *commands;
int (*load)(struct pld_device *pld_device, const char *filename);
int (*get_ipdbg_hub)(int user_num, struct pld_device *pld_device, struct pld_ipdbg_hub *hub);
int (*has_jtagspi_instruction)(struct pld_device *device, bool *has_instruction);
int (*get_jtagspi_userircode)(struct pld_device *pld_device, unsigned int *ir);
int (*connect_spi_to_jtag)(struct pld_device *pld_device);
int (*disconnect_spi_from_jtag)(struct pld_device *pld_device);
int (*get_stuff_bits)(struct pld_device *pld_device, unsigned int *facing_read_bits,
unsigned int *trailing_write_bits);
};
#define PLD_CREATE_COMMAND_HANDLER(name) \