21 #include <linux/pci.h>
32 #ifndef PCI_CFG_SPACE_EXP_SIZE
33 #define PCI_CFG_SPACE_EXP_SIZE 4096
36 #define PCIE_EXT_CAP_LST 0x100
38 #define XLNX_PCIE_XVC_EXT_CAP 0x00
39 #define XLNX_PCIE_XVC_VSEC_HDR 0x04
40 #define XLNX_PCIE_XVC_LEN_REG 0x0C
41 #define XLNX_PCIE_XVC_TMS_REG 0x10
42 #define XLNX_PCIE_XVC_TDX_REG 0x14
44 #define XLNX_PCIE_XVC_CAP_SIZE 0x20
45 #define XLNX_PCIE_XVC_VSEC_ID 0x8
47 #define XLNX_AXI_XVC_LEN_REG 0x00
48 #define XLNX_AXI_XVC_TMS_REG 0x04
49 #define XLNX_AXI_XVC_TDI_REG 0x08
50 #define XLNX_AXI_XVC_TDO_REG 0x0c
51 #define XLNX_AXI_XVC_CTRL_REG 0x10
52 #define XLNX_AXI_XVC_MAX_REG 0x18
54 #define XLNX_AXI_XVC_CTRL_REG_ENABLE_MASK 0x01
56 #define XLNX_XVC_MAX_BITS 0x20
58 #define MASK_ACK(x) (((x) >> 9) & 0x7)
59 #define MASK_PAR(x) ((int)((x) & 0x1))
96 if (err !=
sizeof(res)) {
110 volatile uint32_t *w = (uint32_t *)b;
113 __atomic_thread_fence(__ATOMIC_SEQ_CST);
130 if (err !=
sizeof(val)) {
131 LOG_ERROR(
"Failed to write offset: 0x%x with value: %" PRIx32,
142 volatile uint32_t *w = (uint32_t *)b;
145 __atomic_thread_fence(__ATOMIC_SEQ_CST);
172 LOG_DEBUG_IO(
"Transact num_bits: %zu, tms: %" PRIx32
", tdi: %" PRIx32
", tdo: %" PRIx32,
173 num_bits, tms, tdi, *tdo);
175 LOG_DEBUG_IO(
"Transact num_bits: %zu, tms: %" PRIx32
", tdi: %" PRIx32
", tdo: <null>",
232 LOG_DEBUG_IO(
"Transact num_bits: %zu, tms: 0x%x, tdi: 0x%x, tdo: 0x%x",
233 num_bits, tms, tdi, *tdo);
235 LOG_DEBUG_IO(
"Transact num_bits: %zu, tms: 0x%x, tdi: 0x%x, tdo: <null>",
243 if (xvc_type ==
PCIE)
245 assert(xvc_type ==
AXI);
252 size_t left =
cmd->cmd.stableclocks->num_cycles;
256 LOG_DEBUG(
"stableclocks %u cycles",
cmd->cmd.runtest->num_cycles);
277 LOG_DEBUG(
"statemove starting at (skip: %zu) %s end in %s", skip,
296 LOG_DEBUG(
"runtest %u cycles, end in %i",
297 cmd->cmd.runtest->num_cycles,
298 cmd->cmd.runtest->end_state);
309 size_t left =
cmd->cmd.runtest->num_cycles;
330 unsigned int num_states =
cmd->cmd.pathmove->num_states;
334 LOG_DEBUG(
"pathmove: %u states, end in %i",
335 cmd->cmd.pathmove->num_states,
336 cmd->cmd.pathmove->path[
cmd->cmd.pathmove->num_states - 1]);
338 for (
unsigned int i = 0; i < num_states; i++) {
344 LOG_ERROR(
"BUG: %s -> %s isn't a valid TAP transition.",
363 enum tap_state saved_end_state =
cmd->cmd.scan->end_state;
364 bool ir_scan =
cmd->cmd.scan->ir_scan;
365 uint32_t tdi, tms, tdo;
366 uint8_t *buf, *rd_ptr;
373 LOG_DEBUG(
"%s scan type %d %d bits; starts in %s end in %s",
374 (
cmd->cmd.scan->ir_scan) ?
"IR" :
"DR",
type, scan_size,
403 &tdo :
NULL, xvc_type);
409 rd_ptr +=
sizeof(uint32_t);
428 usleep(
cmd->cmd.sleep->us);
434 const size_t num_bits =
cmd->cmd.tms->num_bits;
435 const uint8_t *
bits =
cmd->cmd.tms->bits;
473 LOG_INFO(
"WARN: XVC driver has no reset.");
481 LOG_ERROR(
"BUG: Unknown JTAG command type encountered.");
518 char filename[PATH_MAX];
522 snprintf(filename, PATH_MAX,
"/sys/bus/pci/devices/%s/config",
526 LOG_ERROR(
"Failed to open device: %s", filename);
530 LOG_INFO(
"Scanning PCIe device %s's for Xilinx XVC/PCIe ...",
540 LOG_DEBUG(
"Checking capability at 0x%x; id=0x%04" PRIx32
" version=0x%" PRIx32
" next=0x%" PRIx32,
543 PCI_EXT_CAP_VER(cap),
544 PCI_EXT_CAP_NEXT(cap));
545 if (PCI_EXT_CAP_ID(cap) == PCI_EXT_CAP_ID_VNDR) {
549 LOG_DEBUG(
"Checking possible match at 0x%x; id: 0x%" PRIx32
"; rev: 0x%" PRIx32
"; length: 0x%" PRIx32,
551 PCI_VNDR_HEADER_ID(vh),
552 PCI_VNDR_HEADER_REV(vh),
553 PCI_VNDR_HEADER_LEN(vh));
586 LOG_INFO(
"Opening /dev/mem for AXI communication");
591 LOG_ERROR(
"Failed to open device file, check permissions.");
598 LOG_ERROR(
"mmap() failed, check permissions.");
603 LOG_INFO(
"Mapped Xilinx XVC/AXI vaddr %p paddr 0x%" PRIx64,
672 .handler = xlnx_pcie_xvc_handle_config_command,
674 .help =
"Configure XVC/PCIe JTAG adapter",
682 .
name =
"xlnx_pcie_xvc",
684 .help =
"perform xlnx_pcie_xvc management",
694 .handler = xlnx_axi_xvc_handle_dev_addr_command,
696 .help =
"Configure XVC/AXI JTAG device memory address",
701 .handler = xlnx_axi_xvc_handle_dev_file_command,
703 .help =
"Configure XVC/AXI JTAG device file location",
711 .
name =
"xlnx_axi_xvc",
713 .help =
"perform xlnx_axi_xvc management",
743 seq +=
sizeof(uint32_t);
766 LOG_ERROR(
"Sequence %d not supported", seq);
786 uint32_t ap_delay_clk,
796 uint32_t ap_delay_clk,
799 uint32_t res, ack, rpar;
822 LOG_DEBUG(
"%s %s %s reg %X = %08" PRIx32,
851 LOG_DEBUG_IO(
"No valid acknowledge: ack=%02" PRIx32, ack);
860 uint32_t ap_delay_clk)
866 uint32_t ap_delay_clk)
872 uint32_t ap_delay_clk,
898 LOG_DEBUG(
"%s %s %s reg %X = %08" PRIx32,
921 LOG_DEBUG_IO(
"No valid acknowledge: ack=%02" PRIx32, ack);
931 uint32_t ap_delay_clk)
937 uint32_t ap_delay_clk)
953 LOG_DEBUG(
"SWD queue return value: %02x", err);
990 .
name =
"xlnx_pcie_xvc",
1003 .
name =
"xlnx_axi_xvc",
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
int jtag_build_buffer(const struct scan_command *cmd, uint8_t **buffer)
enum scan_type jtag_scan_type(const struct scan_command *cmd)
int jtag_read_buffer(uint8_t *buffer, const struct scan_command *cmd)
scan_type
The inferred type of a scan_command structure, indicating whether the command has the host scan in fr...
@ SCAN_IN
From device to host,.
@ SCAN_OUT
From host to device,.
enum tap_state tap_get_end_state(void)
For more information,.
enum tap_state tap_state_transition(enum tap_state cur_state, bool tms)
Function tap_state_transition takes a current TAP state and returns the next state according to the t...
const char * tap_state_name(enum tap_state state)
Function tap_state_name Returns a string suitable for display representing the JTAG tap_state.
int tap_get_tms_path_len(enum tap_state from, enum tap_state to)
Function int tap_get_tms_path_len returns the total number of bits that represents a TMS path transit...
void tap_set_end_state(enum tap_state new_end_state)
This function sets the state of an "end state follower" which tracks the state that any cable driver ...
enum tap_state tap_get_state(void)
This function gets the state of the "state follower" which tracks the state of the TAPs connected to ...
int tap_get_tms_path(enum tap_state from, enum tap_state to)
This function provides a "bit sequence" indicating what has to be done with TMS during a sequence of ...
#define tap_set_state(new_state)
This function sets the state of a "state follower" which tracks the state of the TAPs connected to th...
#define ERROR_JTAG_DEVICE_ERROR
tap_state
Defines JTAG Test Access Port states.
#define ERROR_JTAG_QUEUE_FAILED
#define ERROR_JTAG_INIT_FAILED
#define LOG_DEBUG_IO(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
uint8_t bits[QN908X_FLASH_MAX_BLOCKS *QN908X_FLASH_PAGES_PER_BLOCK/8]
struct rtt_control ctrl
Control block.
Represents a driver for a debugging interface.
const char *const name
The name of the interface driver.
const char * usage
a string listing the options and arguments, required or optional
Represents a driver for a debugging interface.
int(* execute_queue)(struct jtag_command *cmd_queue)
Execute commands in the supplied queue.
int(* init)(void)
Initialize the debug link so it can perform SWD operations.
static uint8_t swd_cmd(bool is_read, bool is_ap, uint8_t regnum)
Construct a "cmd" byte, in lSB bit order, which swd_driver.read_reg() and swd_driver....
static const unsigned int swd_seq_jtag_to_swd_len
static const unsigned int swd_seq_line_reset_len
static const uint8_t swd_seq_line_reset[]
SWD Line reset.
static const uint8_t swd_seq_jtag_to_swd[]
JTAG-to-SWD sequence.
static const uint8_t swd_seq_swd_to_jtag[]
SWD-to-JTAG sequence.
static const unsigned int swd_seq_swd_to_jtag_len
static int parity_u32(uint32_t x)
Calculate the (even) parity of a 32-bit datum.
#define XLNX_AXI_XVC_TMS_REG
static int xlnx_xvc_swd_run_queue(enum xlnx_xvc_type_t xvc_type)
#define XLNX_AXI_XVC_CTRL_REG
static struct jtag_interface xlnx_pcie_xvc_jtag_ops
static int xlnx_pcie_xvc_write_reg(const int offset, const uint32_t val)
#define XLNX_PCIE_XVC_VSEC_HDR
static void xlnx_pcie_xvc_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
#define XLNX_PCIE_XVC_EXT_CAP
static const struct swd_driver xlnx_axi_xvc_swd_ops
#define XLNX_PCIE_XVC_TDX_REG
static int xlnx_xvc_execute_stableclocks(struct jtag_command *cmd, enum xlnx_xvc_type_t xvc_type)
static void xlnx_xvc_execute_sleep(struct jtag_command *cmd)
static void xlnx_axi_xvc_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
static int xlnx_xvc_swd_switch_seq(enum swd_special_seq seq, enum xlnx_xvc_type_t xvc_type)
static int xlnx_pcie_xvc_transact(size_t num_bits, uint32_t tms, uint32_t tdi, uint32_t *tdo)
static int xlnx_xvc_swd_init(void)
#define XLNX_AXI_XVC_CTRL_REG_ENABLE_MASK
COMMAND_HANDLER(xlnx_pcie_xvc_handle_config_command)
struct adapter_driver xlnx_axi_xvc_adapter_driver
static int xlnx_xvc_execute_scan(struct jtag_command *cmd, enum xlnx_xvc_type_t xvc_type)
static int xlnx_axi_xvc_execute_queue(struct jtag_command *cmd_queue)
struct adapter_driver xlnx_pcie_xvc_adapter_driver
static int xlnx_xvc_execute_tms(struct jtag_command *cmd, enum xlnx_xvc_type_t xvc_type)
static struct jtag_interface xlnx_axi_xvc_jtag_ops
static int xlnx_pcie_xvc_quit(void)
static int xlnx_axi_xvc_swd_run_queue(void)
static int xlnx_xvc_transact(size_t num_bits, uint32_t tms, uint32_t tdi, uint32_t *tdo, enum xlnx_xvc_type_t xvc_type)
static const struct command_registration xlnx_pcie_xvc_command_handlers[]
#define XLNX_PCIE_XVC_VSEC_ID
static void xlnx_xvc_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk, enum xlnx_xvc_type_t xvc_type)
static int xlnx_axi_xvc_quit(void)
static const struct swd_driver xlnx_pcie_xvc_swd_ops
static struct xlnx_axi_xvc xlnx_axi_xvc_state
#define XLNX_AXI_XVC_TDO_REG
static int xlnx_axi_xvc_init(void)
static int xlnx_xvc_swd_sequence(const uint8_t *seq, size_t length, enum xlnx_xvc_type_t xvc_type)
#define XLNX_AXI_XVC_TDI_REG
static int xlnx_axi_xvc_read_reg(const int offset, uint32_t *val)
static int xlnx_xvc_execute_pathmove(struct jtag_command *cmd, enum xlnx_xvc_type_t xvc_type)
static int xlnx_pcie_xvc_read_reg(const int offset, uint32_t *val)
static int xlnx_pcie_xvc_swd_switch_seq(enum swd_special_seq seq)
static void xlnx_xvc_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk, enum xlnx_xvc_type_t xvc_type)
static void swd_clear_sticky_errors(enum xlnx_xvc_type_t xvc_type)
static int xlnx_xvc_execute_command(struct jtag_command *cmd, enum xlnx_xvc_type_t xvc_type)
static int xlnx_pcie_xvc_init(void)
static int xlnx_xvc_execute_runtest(struct jtag_command *cmd, enum xlnx_xvc_type_t xvc_type)
#define XLNX_AXI_XVC_LEN_REG
static int xlnx_axi_xvc_write_reg(const int offset, const uint32_t val)
static const struct command_registration xlnx_axi_xvc_command_handlers[]
static int xlnx_pcie_xvc_execute_queue(struct jtag_command *cmd_queue)
static const struct command_registration xlnx_axi_xvc_subcommand_handlers[]
#define XLNX_PCIE_XVC_CAP_SIZE
static void xlnx_axi_xvc_swd_write_reg(uint8_t cmd, uint32_t value, uint32_t ap_delay_clk)
static int xlnx_xvc_execute_queue(struct jtag_command *cmd_queue, enum xlnx_xvc_type_t xvc_type)
static void xlnx_pcie_xvc_swd_read_reg(uint8_t cmd, uint32_t *value, uint32_t ap_delay_clk)
static int xlnx_axi_xvc_swd_switch_seq(enum swd_special_seq seq)
#define XLNX_XVC_MAX_BITS
#define XLNX_AXI_XVC_MAX_REG
static int xlnx_axi_xvc_transact(size_t num_bits, uint32_t tms, uint32_t tdi, uint32_t *tdo)
static struct xlnx_pcie_xvc xlnx_pcie_xvc_state
#define XLNX_PCIE_XVC_TMS_REG
static int xlnx_pcie_xvc_swd_run_queue(void)
static int xlnx_xvc_execute_statemove(size_t skip, enum xlnx_xvc_type_t xvc_type)
#define PCI_CFG_SPACE_EXP_SIZE
static const struct command_registration xlnx_pcie_xvc_subcommand_handlers[]
#define XLNX_PCIE_XVC_LEN_REG