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:
committed by
Antonio Borneo
parent
30375c6439
commit
fe5ed48f40
@@ -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)
|
||||
|
||||
@@ -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) \
|
||||
|
||||
Reference in New Issue
Block a user