20 #define WIN32_LEAN_AND_MEAN
26 #ifdef HAVE_SYS_SOCKET_H
27 #include <sys/socket.h>
29 #ifdef HAVE_ARPA_INET_H
30 #include <arpa/inet.h>
57 #define VD_BUFFER_LEN 4024
58 #define VD_CHEADER_LEN 24
59 #define VD_SHEADER_LEN 16
61 #define VD_MAX_MEMORIES 20
62 #define VD_POLL_INTERVAL 500
63 #define VD_SCALE_PSTOMS 1000000000
238 return WSAGetLastError();
248 uint32_t buflen =
sizeof(
struct vd_shm);
249 struct addrinfo *ainfo =
NULL;
250 struct addrinfo ahint = { 0, AF_INET, SOCK_STREAM, 0, 0,
NULL,
NULL,
NULL };
253 hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
254 if (hsock == INVALID_SOCKET)
258 hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
261 else if (setsockopt(hsock, SOL_SOCKET, SO_RCVLOWAT, &rcvwat,
sizeof(rcvwat)) < 0)
264 else if (setsockopt(hsock, SOL_SOCKET, SO_SNDBUF, (
const char *)&buflen,
sizeof(buflen)) < 0)
266 else if (setsockopt(hsock, SOL_SOCKET, SO_RCVBUF, (
const char *)&buflen,
sizeof(buflen)) < 0)
270 LOG_ERROR(
"socket_open: cannot set socket option, error %d", rc);
271 }
else if (getaddrinfo(server_addr,
NULL, &ahint, &ainfo) != 0) {
275 buf_set_u32((uint8_t *)ainfo->ai_addr->sa_data, 0, 16, htons(port));
276 if (connect(hsock, ainfo->ai_addr,
sizeof(
struct sockaddr)) < 0) {
299 char *pb = (
char *)pmem;
302 rc = recv(hsock, pb +
offset, to_receive, 0);
309 LOG_DEBUG_IO(
"socket_receive: received %d, to receive %d", rc, to_receive);
311 }
while (to_receive);
341 LOG_DEBUG_IO(
"wait_server: cmd %02" PRIx8
" done, sent %d, rcvd %d, status %d",
342 pmem->
cmd, st, rd, rc);
349 uint8_t num_pre, num_post, tdi, tms;
350 unsigned int num, anum, bytes, hwords, words;
365 while (!rc && (req <
count)) {
368 hwords = (jhdr >> 32) & 0xffff;
369 anum = jhdr & 0xffffff;
370 num_pre = (jhdr >> 27) & 0x7;
371 num_post = (jhdr >> 24) & 0x7;
373 num = anum - num_pre - num_post + 1;
375 num = anum - num_pre;
376 bytes = (num + 7) / 8;
379 if (((jhdr >> 30) & 0x3) == 3) {
389 for (
unsigned int j = 0; j < bytes; j++) {
390 tdo[j] = (pm->
rd8[
rwords * 8 + j] >> num_pre) | (pm->
rd8[
rwords * 8 + j + 1] << (8 - num_pre));
397 waddr +=
sizeof(uint64_t) / 4;
398 tdi = (pm->
wd8[
waddr * 4] >> num_pre) | (pm->
wd8[
waddr * 4 + 1] << (8 - num_pre));
399 tms = (pm->
wd8[
waddr * 4 + 4] >> num_pre) | (pm->
wd8[
waddr * 4 + 4 + 1] << (8 - num_pre));
400 LOG_DEBUG_IO(
"%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x",
402 waddr - 2, tdi, tms, (tdo ? tdo[0] : 0xdd));
408 LOG_ERROR(
"0x%x executing transaction", rc);
425 unsigned int num, awidth, wwidth;
442 while (!rc && (req <
count)) {
445 num = (rhdr >> 16) & 0x7ff;
447 awidth = (1 << ((rhdr >> 27) & 0x7));
451 if (((rhdr >> 30) & 0x3) == 2) {
462 for (
unsigned int j = 0; j < num; j++)
463 memcpy(&data[j * awidth], &pm->
rd8[(
rwords + j) * awidth], awidth);
469 waddr +=
sizeof(uint64_t) / 4;
474 waddr +=
sizeof(uint64_t) / 4 + (num * wwidth * awidth + 3) / 4;
480 LOG_ERROR(
"0x%x executing transaction", rc);
496 uint8_t
type, uint32_t period_ps, uint32_t sig_mask)
508 LOG_ERROR(
"0x%x connecting to server", rc);
533 LOG_ERROR(
"0x%x connecting to BFM %s", rc, path);
538 LOG_DEBUG(
"%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x",
575 LOG_ERROR(
"0x%x waiting %" PRIx32
" cycles", rc, cycles);
592 LOG_ERROR(
"0x%x setting signals %04" PRIx32, rc, write_mask);
596 LOG_DEBUG(
"setting signals %04" PRIx32
" to %04" PRIx32, write_mask, value);
609 LOG_ERROR(
"0x%x setting jtag_clock", rc);
613 LOG_DEBUG(
"setting jtag clock divider to %" PRIx32, value);
619 const uint8_t tms_pre, uint32_t num,
const uint8_t *tdi,
620 uint8_t num_post,
const uint8_t tms_post, uint8_t *tdo,
623 const uint32_t tobits = 8;
624 uint16_t bytes, hwords, anum, words,
waddr;
634 anum = num + num_pre + num_post - 1;
636 anum = num + num_pre;
638 words = (hwords + 1) / 2;
639 bytes = (num + 7) / 8;
645 LOG_ERROR(
"%04x L:%02d O:%05x @%04x too many bits to shift",
652 uint64_t jhdr = (tdo ? ((uint64_t)(words) << 48) : 0) + ((uint64_t)(hwords) << 32) +
653 ((tdo ? 3UL : 1UL) << 30) + (num_pre << 27) + (num_post << 24) + anum;
659 pm->
wd8[4 *
waddr] = (tdi ? (tdi[0] << num_pre) : 0);
661 if (num + num_pre <= 8)
662 pm->
wd8[4 *
waddr + 4] |= (tms_post << (num + num_pre - 1));
663 for (i = 1, j = 4 *
waddr; i < bytes; i++) {
664 if (i == bytes - 1 && num + num_pre <= bytes * tobits)
665 pm->
wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);
667 pm->
wd8[j + i + 4] = 0x0;
669 pm->
wd8[j + i] = 0x0;
671 pm->
wd8[j + i] = (tdi[i] << num_pre) | (tdi[i - 1] >> (8 - num_pre));
677 if (num + num_pre > bytes * tobits)
678 pm->
wd8[j + i] = (tdi[i - 1] >> (8 - num_pre));
680 if (num + num_pre <= bytes * tobits) {
681 pm->
wd8[j + i + 4] = tms_post >> (8 - (num + num_pre - 1) % 8);
683 }
else if (num + num_pre > bytes * tobits && anum <= (bytes + 1) * tobits) {
684 pm->
wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);
686 pm->
wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);
688 pm->
wd8[j + i + 4 + 5] = tms_post >> (8 - (num + num_pre - 1) % 8);
690 pm->
wd8[j + i + 4 + 1] = tms_post >> (8 - (num + num_pre - 1) % 8);
698 rd = calloc(1,
sizeof(
struct vd_rdata));
722 const uint32_t data, uint8_t aspace, uint8_t f_last)
737 uint64_t rhdr = ((uint64_t)
reg << 32) + (1UL << 30) + (2UL << 27) + (1UL << 16) + aspace;
753 uint32_t *data, uint8_t aspace, uint8_t f_last)
768 uint64_t rhdr = ((uint64_t)
reg << 32) + (2UL << 30) + (2UL << 27) + ((data ? 1UL : 0UL) << 16) + aspace;
776 rd = calloc(1,
sizeof(
struct vd_rdata));
781 rd->
rdata = (uint8_t *)data;
810 LOG_ERROR(
"0x%x opening memory %s", rc, path);
811 }
else if (ndx != pm->
rd8[2]) {
812 LOG_WARNING(
"Invalid memory index %" PRIu16
" returned. Direct memory access disabled", pm->
rd8[2]);
816 LOG_DEBUG(
"%" PRIx8
": %s memory %" PRIu32
"x%" PRIu32
"B, buffer %" PRIu32
"x%" PRIu32
"B", ndx, path,
849 LOG_ERROR(
"cannot connect to vdebug server %s:%" PRIu16,
873 LOG_INFO(
"vdebug %d connected to %s through %s:%" PRIu16,
898 uint16_t sig_val = 0xffff;
899 uint16_t sig_mask = 0;
910 LOG_INFO(
"rst trst:%d srst:%d mask:%" PRIx16
" val:%" PRIx16, trst, srst, sig_mask, sig_val);
920 LOG_INFO(
"tms len:%d tms:%x", num, *tms);
932 for (uint8_t i = 0; i <
cmd->num_states; i++) {
968 LOG_DEBUG(
"scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x",
969 num_bits,
cmd->num_fields,
cmd->ir_scan, cur,
cmd->end_state);
970 for (
int i = 0; i <
cmd->num_fields; i++) {
971 uint8_t cur_num_pre = i == 0 ? num_pre : 0;
972 uint8_t cur_tms_pre = i == 0 ? tms_pre : 0;
973 uint8_t cur_num_post = i ==
cmd->num_fields - 1 ? num_post : 0;
974 uint8_t cur_tms_post = i ==
cmd->num_fields - 1 ? tms_post : 0;
975 uint8_t cur_flush = i ==
cmd->num_fields - 1 ? f_flush : 0;
977 cmd->fields[i].num_bits,
cmd->fields[i].out_value, cur_num_post, cur_tms_post,
978 cmd->fields[i].in_value, cur_flush);
983 if (cur !=
cmd->end_state)
1019 unsigned int divval = clkmax / speed;
1020 LOG_INFO(
"jclk speed:%d kHz set, BFM divider %u", speed, divval);
1028 unsigned int divval = khz ? clkmax / khz : 1;
1029 *jtag_speed = clkmax / divval;
1030 LOG_DEBUG(
"khz speed:%d from khz:%d", *jtag_speed, khz);
1038 LOG_DEBUG(
"div khz:%d from speed:%d", *khz, speed);
1048 switch (
cmd->type) {
1071 LOG_ERROR(
"Unknown JTAG command type 0x%x encountered",
cmd->type);
1139 char *pchar = strchr(
CMD_ARGV[0],
':');
1142 int port = atoi(++pchar);
1143 if (port < 0 || port > UINT16_MAX) {
1144 LOG_ERROR(
"invalid port number %d specified", port);
1206 if (isdigit((
unsigned char)
CMD_ARGV[0][0]))
1234 .handler = &vdebug_set_server,
1236 .help =
"set the vdebug server name or address",
1237 .usage =
"<host:port>",
1241 .handler = &vdebug_set_bfm,
1243 .help =
"set the vdebug BFM hierarchical path",
1244 .usage =
"<path> <clk_period[p|n|u]s>",
1248 .handler = &vdebug_set_mem,
1250 .help =
"set the design memory for the code load",
1251 .usage =
"<path> <base_address> <size>",
1255 .handler = &vdebug_set_batching,
1257 .help =
"set the transaction batching no|wr|rd [0|1|2]",
1262 .handler = &vdebug_set_polling,
1264 .help =
"set the polling pause, executing hardware cycles between min and max",
1265 .usage =
"<min cycles> <max cycles>",
1275 .help =
"vdebug command group",
bool transport_is_dapdirect_swd(void)
Returns true if the current debug session is using SWD as its transport.
int dap_dp_init(struct adiv5_dap *dap)
Initialize a DAP.
This defines formats and data structures used to talk to ADIv5 entities.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned 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_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
struct jtag_command * jtag_command_queue
The current queue of jtag_command_s structures.
int jtag_scan_size(const struct scan_command *cmd)
tap_state_t tap_state_transition(tap_state_t cur_state, bool tms)
Function tap_state_transition takes a current TAP state and returns the next state according to the t...
int tap_get_tms_path(tap_state_t from, tap_state_t to)
This function provides a "bit sequence" indicating what has to be done with TMS during a sequence of ...
int tap_get_tms_path_len(tap_state_t from, tap_state_t to)
Function int tap_get_tms_path_len returns the total number of bits that represents a TMS path transit...
tap_state_t tap_get_state(void)
This function gets the state of the "state follower" which tracks the state of the TAPs connected to ...
#define DEBUG_CAP_TMS_SEQ
#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...
bool transport_is_jtag(void)
Returns true if the current debug session is using JTAG as its transport.
enum tap_state tap_state_t
Defines JTAG Test Access Port states.
#define list_first_entry(ptr, type, member)
list_first_entry - get the first element from a list
static void list_add_tail(struct list_head *new, struct list_head *head)
list_add_tail - add a new entry
static int list_empty(const struct list_head *head)
list_empty - tests whether a list is empty
static void list_del(struct list_head *entry)
list_del - deletes entry from list.
static void INIT_LIST_HEAD(struct list_head *list)
INIT_LIST_HEAD - Initialize a list_head structure.
#define LOG_DEBUG_IO(expr ...)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
static uint32_t lh(unsigned int rd, unsigned int base, uint16_t offset) __attribute__((unused))
static int close_socket(int sock)
Represents a driver for a debugging interface.
const char *const name
The name of the interface driver.
This represents an ARM Debug Interface (v5) Access Port (AP).
struct adiv5_dap * dap
DAP this AP belongs to.
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
uint64_t select
Cache for DP_SELECT register.
Transport-neutral representation of queued DAP transactions, supporting both JTAG and SWD transports.
int(* connect)(struct adiv5_dap *dap)
connect operation for SWD
Represents a driver for a debugging interface.
unsigned supported
Bit vector listing capabilities exposed by this driver.
The scan_command provide a means of encapsulating a set of scan_field_s structures that should be sca...
uint32_t mem_width[VD_MAX_MEMORIES]
uint32_t mem_base[VD_MAX_MEMORIES]
char mem_path[VD_MAX_MEMORIES][128]
uint32_t mem_depth[VD_MAX_MEMORIES]
uint32_t mem_size[VD_MAX_MEMORIES]
uint8_t rd8[VD_BUFFER_LEN]
uint8_t wd8[VD_BUFFER_LEN]
static uint64_t le_to_h_u64(const uint8_t *buf)
static uint16_t le_to_h_u16(const uint8_t *buf)
static void h_u32_to_le(uint8_t *buf, uint32_t val)
#define DIV_ROUND_UP(m, n)
Rounds m up to the nearest multiple of n using division.
static void h_u16_to_le(uint8_t *buf, uint16_t val)
static uint32_t le_to_h_u32(const uint8_t *buf)
static void h_u64_to_le(uint8_t *buf, uint64_t val)
static uint32_t vdebug_wait_server(int hsock, struct vd_shm *pmem)
static int vdebug_close(int hsock, struct vd_shm *pm, uint8_t type)
static int vdebug_dap_send_sequence(struct adiv5_dap *dap, enum swd_special_seq seq)
static int vdebug_dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
static int vdebug_jtag_div(int speed, int *khz)
static const char *const vdebug_transports[]
static int vdebug_dap_queue_ap_abort(struct adiv5_dap *dap, uint8_t *ack)
static int vdebug_reg_read(int hsock, struct vd_shm *pm, const uint32_t reg, uint32_t *data, uint8_t aspace, uint8_t f_last)
static int vdebug_open(int hsock, struct vd_shm *pm, const char *path, uint8_t type, uint32_t period_ps, uint32_t sig_mask)
static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
static int vdebug_jtag_stableclocks(int num, uint8_t f_flush)
static int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush)
COMMAND_HANDLER(vdebug_set_server)
static struct jtag_interface vdebug_jtag_ops
struct adapter_driver vdebug_adapter_driver
static int vdebug_jtag_shift_tap(int hsock, struct vd_shm *pm, uint8_t num_pre, const uint8_t tms_pre, uint32_t num, const uint8_t *tdi, uint8_t num_post, const uint8_t tms_post, uint8_t *tdo, uint8_t f_last)
static int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
static int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush)
static int vdebug_socket_open(char *server_addr, uint32_t port)
static struct vd_client vdc
static int vdebug_quit(void)
static int vdebug_jtag_speed(int speed)
static const struct dap_ops vdebug_dap_ops
static int vdebug_reset(int trst, int srst)
static int vdebug_jtag_scan(struct scan_command *cmd, uint8_t f_flush)
static int vdebug_init(void)
static int vdebug_jtag_clock(int hsock, struct vd_shm *pm, uint32_t value)
struct vd_rdata __attribute__
static int vdebug_dap_connect(struct adiv5_dap *dap)
static int vdebug_reg_write(int hsock, struct vd_shm *pm, const uint32_t reg, const uint32_t data, uint8_t aspace, uint8_t f_last)
static int vdebug_dap_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush)
static int vdebug_mem_open(int hsock, struct vd_shm *pm, const char *path, uint8_t ndx)
static int vdebug_wait(int hsock, struct vd_shm *pm, uint32_t cycles)
static int vdebug_dap_run(struct adiv5_dap *dap)
static int vdebug_jtag_tlr(tap_state_t state, uint8_t f_flush)
static void vdebug_mem_close(int hsock, struct vd_shm *pm, uint8_t ndx)
static int vdebug_sig_set(int hsock, struct vd_shm *pm, uint32_t write_mask, uint32_t value)
static int vdebug_jtag_khz(int khz, int *jtag_speed)
static int vdebug_socket_error(void)
static int vdebug_socket_send(int hsock, struct vd_shm *pmem)
static int vdebug_socket_receive(int hsock, struct vd_shm *pmem)
static const struct command_registration vdebug_command[]
static struct vd_shm * pbuf
static int vdebug_jtag_execute_queue(void)
static int vdebug_sleep(int us)
static const struct command_registration vdebug_command_handlers[]
int vdebug_run_reg_queue(int hsock, struct vd_shm *pm, unsigned int count)
int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)