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>
58 #define VD_BUFFER_LEN 4024
59 #define VD_CHEADER_LEN 24
60 #define VD_SHEADER_LEN 16
62 #define VD_MAX_MEMORIES 20
63 #define VD_POLL_INTERVAL 1000
64 #define VD_SCALE_PSTOMS 1000000000
241 return WSAGetLastError();
251 uint32_t buflen =
sizeof(
struct vd_shm);
252 struct addrinfo *ainfo =
NULL;
253 struct addrinfo ahint = { 0, AF_INET, SOCK_STREAM, 0, 0,
NULL,
NULL,
NULL };
256 hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
259 #elif defined __CYGWIN__
261 hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
266 hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
269 else if (setsockopt(hsock, SOL_SOCKET, SO_RCVLOWAT, &rcvwat,
sizeof(rcvwat)) < 0)
272 else if (setsockopt(hsock, SOL_SOCKET, SO_SNDBUF, (
const char *)&buflen,
sizeof(buflen)) < 0)
274 else if (setsockopt(hsock, SOL_SOCKET, SO_RCVBUF, (
const char *)&buflen,
sizeof(buflen)) < 0)
278 LOG_ERROR(
"socket_open: cannot set socket option, error %d", rc);
279 }
else if (getaddrinfo(server_addr,
NULL, &ahint, &ainfo) != 0) {
283 h_u16_to_be((uint8_t *)ainfo->ai_addr->sa_data, port);
284 if (connect(hsock, ainfo->ai_addr,
sizeof(
struct sockaddr)) < 0) {
307 char *pb = (
char *)pmem;
310 rc = recv(hsock, pb +
offset, to_receive, 0);
317 LOG_DEBUG_IO(
"socket_receive: received %d, to receive %d", rc, to_receive);
319 }
while (to_receive);
349 LOG_DEBUG_IO(
"wait_server: cmd %02" PRIx8
" done, sent %d, rcvd %d, status %d",
350 pmem->
cmd, st, rd, rc);
357 uint8_t num_pre, num_post, tdi, tms;
358 unsigned int num, anum, bytes, hwords, words;
373 while (!rc && (req <
count)) {
376 hwords = (jhdr >> 32) & 0xffff;
377 anum = jhdr & 0xffffff;
378 num_pre = (jhdr >> 27) & 0x7;
379 num_post = (jhdr >> 24) & 0x7;
381 num = anum - num_pre - num_post + 1;
383 num = anum - num_pre;
384 bytes = (num + 7) / 8;
387 if (((jhdr >> 30) & 0x3) == 3) {
397 for (
unsigned int j = 0; j < bytes; j++) {
398 tdo[j] = (pm->
rd8[
rwords * 8 + j] >> num_pre) | (pm->
rd8[
rwords * 8 + j + 1] << (8 - num_pre));
405 waddr +=
sizeof(uint64_t) / 4;
406 tdi = (pm->
wd8[
waddr * 4] >> num_pre) | (pm->
wd8[
waddr * 4 + 1] << (8 - num_pre));
407 tms = (pm->
wd8[
waddr * 4 + 4] >> num_pre) | (pm->
wd8[
waddr * 4 + 4 + 1] << (8 - num_pre));
408 LOG_DEBUG_IO(
"%04x L:%02d O:%05x @%03x DI:%02x MS:%02x DO:%02x",
410 waddr - 2, tdi, tms, (tdo ? tdo[0] : 0xdd));
416 LOG_ERROR(
"0x%x executing transaction", rc);
433 unsigned int num, awidth, wwidth;
450 while (!rc && (req <
count)) {
453 num = (rhdr >> 16) & 0x7ff;
455 awidth = (1 << ((rhdr >> 27) & 0x7));
459 if (((rhdr >> 30) & 0x3) == 2) {
470 for (
unsigned int j = 0; j < num; j++)
471 memcpy(&data[j * awidth], &pm->
rd8[(
rwords + j) * awidth], awidth);
477 waddr +=
sizeof(uint64_t) / 4;
482 waddr +=
sizeof(uint64_t) / 4 + (num * wwidth * awidth + 3) / 4;
488 LOG_ERROR(
"0x%x executing transaction", rc);
504 uint8_t
type, uint32_t period_ps, uint32_t sig_mask)
516 LOG_ERROR(
"0x%x connecting to server", rc);
541 LOG_ERROR(
"0x%x connecting to BFM %s", rc, path);
546 LOG_DEBUG(
"%s type %0x, period %dps, buffer %dx%dB signals r%04xw%04x",
583 LOG_ERROR(
"0x%x waiting %" PRIx32
" cycles", rc, cycles);
600 LOG_ERROR(
"0x%x setting signals %04" PRIx32, rc, write_mask);
604 LOG_DEBUG(
"setting signals %04" PRIx32
" to %04" PRIx32, write_mask, value);
617 LOG_ERROR(
"0x%x setting jtag_clock", rc);
621 LOG_DEBUG(
"setting jtag clock divider to %" PRIx32, value);
627 const uint8_t tms_pre, uint32_t num,
const uint8_t *tdi,
628 uint8_t num_post,
const uint8_t tms_post, uint8_t *tdo,
631 const uint32_t tobits = 8;
632 uint16_t bytes, hwords, anum, words,
waddr;
642 anum = num + num_pre + num_post - 1;
644 anum = num + num_pre;
646 words = (hwords + 1) / 2;
647 bytes = (num + 7) / 8;
653 LOG_ERROR(
"%04x L:%02d O:%05x @%04x too many bits to shift",
660 uint64_t jhdr = (tdo ? ((uint64_t)(words) << 48) : 0) + ((uint64_t)(hwords) << 32) +
661 ((tdo ? 3UL : 1UL) << 30) + (num_pre << 27) + (num_post << 24) + anum;
667 pm->
wd8[4 *
waddr] = (tdi ? (tdi[0] << num_pre) : 0);
669 if (num + num_pre <= 8)
670 pm->
wd8[4 *
waddr + 4] |= (tms_post << (num + num_pre - 1));
671 for (i = 1, j = 4 *
waddr; i < bytes; i++) {
672 if (i == bytes - 1 && num + num_pre <= bytes * tobits)
673 pm->
wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);
675 pm->
wd8[j + i + 4] = 0x0;
677 pm->
wd8[j + i] = 0x0;
679 pm->
wd8[j + i] = (tdi[i] << num_pre) | (tdi[i - 1] >> (8 - num_pre));
685 if (num + num_pre > bytes * tobits)
686 pm->
wd8[j + i] = (tdi[i - 1] >> (8 - num_pre));
688 if (num + num_pre <= bytes * tobits) {
689 pm->
wd8[j + i + 4] = tms_post >> (8 - (num + num_pre - 1) % 8);
691 }
else if (num + num_pre > bytes * tobits && anum <= (bytes + 1) * tobits) {
692 pm->
wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);
694 pm->
wd8[j + i + 4] = tms_post << ((num + num_pre - 1) % 8);
696 pm->
wd8[j + i + 4 + 5] = tms_post >> (8 - (num + num_pre - 1) % 8);
698 pm->
wd8[j + i + 4 + 1] = tms_post >> (8 - (num + num_pre - 1) % 8);
706 rd = calloc(1,
sizeof(
struct vd_rdata));
730 const uint32_t data, uint8_t aspace, uint8_t f_last)
745 uint64_t rhdr = ((uint64_t)
reg << 32) + (1UL << 30) + (2UL << 27) + (1UL << 16) + aspace;
761 uint32_t *data, uint8_t aspace, uint8_t f_last)
776 uint64_t rhdr = ((uint64_t)
reg << 32) + (2UL << 30) + (2UL << 27) + ((data ? 1UL : 0UL) << 16) + aspace;
784 rd = calloc(1,
sizeof(
struct vd_rdata));
789 rd->
rdata = (uint8_t *)data;
818 LOG_ERROR(
"0x%x opening memory %s", rc, path);
819 }
else if (ndx != pm->
rd8[2]) {
820 LOG_WARNING(
"Invalid memory index %" PRIu16
" returned. Direct memory access disabled", pm->
rd8[2]);
824 LOG_DEBUG(
"%" PRIx8
": %s memory %" PRIu32
"x%" PRIu32
"B, buffer %" PRIu32
"x%" PRIu32
"B", ndx, path,
857 LOG_DEBUG(
"poll after %" PRId64
"ms, busy %" PRIu32
"ms; wait %" PRIu32
" %" PRId64
"ms",
886 LOG_ERROR(
"cannot connect to vdebug server %s:%" PRIu16,
913 LOG_INFO(
"vdebug %d connected to %s through %s:%" PRIu16,
940 uint16_t sig_val = 0xffff;
941 uint16_t sig_mask = 0;
952 LOG_INFO(
"rst trst:%d srst:%d mask:%" PRIx16
" val:%" PRIx16, trst, srst, sig_mask, sig_val);
974 for (
unsigned int i = 0; i <
cmd->num_states; i++) {
1010 LOG_DEBUG_IO(
"scan len:%u fields:%u ir/!dr:%d state cur:%x end:%x",
1011 num_bits,
cmd->num_fields,
cmd->ir_scan, cur,
cmd->end_state);
1012 for (
unsigned int i = 0; i <
cmd->num_fields; i++) {
1013 uint8_t cur_num_pre = i == 0 ? num_pre : 0;
1014 uint8_t cur_tms_pre = i == 0 ? tms_pre : 0;
1015 uint8_t cur_num_post = i ==
cmd->num_fields - 1 ? num_post : 0;
1016 uint8_t cur_tms_post = i ==
cmd->num_fields - 1 ? tms_post : 0;
1017 uint8_t cur_flush = i ==
cmd->num_fields - 1 ? f_flush : 0;
1019 cmd->fields[i].num_bits,
cmd->fields[i].out_value, cur_num_post, cur_tms_post,
1020 cmd->fields[i].in_value, cur_flush);
1025 if (cur !=
cmd->end_state)
1061 unsigned int divval = clkmax / speed;
1062 LOG_INFO(
"jclk speed:%d kHz set, BFM divider %u", speed, divval);
1070 unsigned int divval = khz ? clkmax / khz : 1;
1071 *jtag_speed = clkmax / divval;
1072 LOG_DEBUG(
"khz speed:%d from khz:%d", *jtag_speed, khz);
1080 LOG_DEBUG(
"div khz:%d from speed:%d", *khz, speed);
1090 switch (
cmd->type) {
1113 LOG_ERROR(
"Unknown JTAG command type 0x%x encountered",
cmd->type);
1128 if (sel != (ap->
dap->
select & ~0xfull)) {
1221 char *pchar = strchr(
CMD_ARGV[0],
':');
1224 int port = atoi(++pchar);
1225 if (port < 0 || port > UINT16_MAX) {
1226 LOG_ERROR(
"invalid port number %d specified", port);
1288 if (isdigit((
unsigned char)
CMD_ARGV[0][0]))
1316 .handler = &vdebug_set_server,
1318 .help =
"set the vdebug server name or address",
1319 .usage =
"<host:port>",
1323 .handler = &vdebug_set_bfm,
1325 .help =
"set the vdebug BFM hierarchical path",
1326 .usage =
"<path> <clk_period[p|n|u]s>",
1330 .handler = &vdebug_set_mem,
1332 .help =
"set the design memory for the code load",
1333 .usage =
"<path> <base_address> <size>",
1337 .handler = &vdebug_set_batching,
1339 .help =
"set the transaction batching no|wr|rd [0|1|2]",
1344 .handler = &vdebug_set_polling,
1346 .help =
"set the min idle time and max wait time in ms",
1347 .usage =
"<min_idle> <max_wait>",
1357 .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 bool is_adiv6(const struct adiv5_dap *dap)
Check if DAP is ADIv6.
#define ADIV5_DP_SELECT_APBANK
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_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.
unsigned int jtag_scan_size(const struct scan_command *cmd)
static struct esp_usb_jtag * priv
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...
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...
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 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.
tap_state
Defines JTAG Test Access Port states.
#define list_first_entry(ptr, type, member)
static void list_add_tail(struct list_head *new, struct list_head *head)
static int list_empty(const struct list_head *head)
static void list_del(struct list_head *entry)
static void INIT_LIST_HEAD(struct list_head *list)
#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)
target_addr_t addr
Start address to search for the control block.
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).
uint64_t ap_num
ADIv5: Number of this AP (0~255) ADIv6: Base address of this AP (4k aligned) TODO: to be more coheren...
struct adiv5_dap * dap
DAP this AP belongs to.
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
bool select_valid
Validity of DP SELECT cache.
uint64_t select
Cache for DP SELECT and SELECT1 (ADIv6) 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 int supported
Bit vector listing capabilities exposed by this driver.
The scan_command provide a means of encapsulating a set of scan_field structures that should be scann...
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]
int target_unregister_timer_callback(int(*callback)(void *priv), void *priv)
int target_register_timer_callback(int(*callback)(void *priv), unsigned int time_ms, enum target_timer_type type, void *priv)
The period is very approximate, the callback can happen much more often or much more rarely than spec...
@ TARGET_TIMER_TYPE_PERIODIC
#define TRANSPORT_DAPDIRECT_SWD
static uint64_t le_to_h_u64(const uint8_t *buf)
static void h_u16_to_be(uint8_t *buf, uint16_t val)
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_bankselect(struct adiv5_ap *ap, unsigned int reg)
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 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_path_move(struct pathmove_command *cmd, uint8_t f_flush)
static int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)
static int vdebug_run_reg_queue(int hsock, struct vd_shm *pm, unsigned int count)
COMMAND_HANDLER(vdebug_set_server)
static struct jtag_interface vdebug_jtag_ops
static int vdebug_poll(void *priv)
static int vdebug_jtag_runtest(unsigned int num_cycles, enum tap_state state, uint8_t f_flush)
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_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 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_execute_queue(struct jtag_command *cmd_queue)
static int vdebug_jtag_khz(int khz, int *jtag_speed)
static int vdebug_socket_error(void)
static int vdebug_jtag_stableclocks(unsigned int num_cycles, uint8_t f_flush)
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_sleep(int us)
static const struct command_registration vdebug_command_handlers[]
static int vdebug_jtag_tlr(enum tap_state state, uint8_t f_flush)