-/* SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) */
+// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
/* Copyright 2020-2022 Cadence Design Systems, Inc. */
#include "helper/log.h"
#include "helper/list.h"
-#define VD_VERSION 44
+#define VD_VERSION 48
#define VD_BUFFER_LEN 4024
#define VD_CHEADER_LEN 24
#define VD_SHEADER_LEN 16
* @brief List of transactor types
*/
enum {
- VD_BFM_JTDP = 0x0001, /* transactor DAP JTAG DP */
+ VD_BFM_TPIU = 0x0000, /* transactor trace TPIU */
+ VD_BFM_DAP6 = 0x0001, /* transactor DAP ADI V6 */
VD_BFM_SWDP = 0x0002, /* transactor DAP SWD DP */
VD_BFM_AHB = 0x0003, /* transactor AMBA AHB */
VD_BFM_APB = 0x0004, /* transactor AMBA APB */
hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if (hsock == INVALID_SOCKET)
rc = vdebug_socket_error();
+#elif defined __CYGWIN__
+ /* SO_RCVLOWAT unsupported on CYGWIN */
+ hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
+ if (hsock < 0)
+ rc = errno;
#else
uint32_t rcvwat = VD_SHEADER_LEN; /* size of the rcv header, as rcv min watermark */
hsock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
LOG_ERROR("socket_open: cannot resolve address %s, error %d", server_addr, vdebug_socket_error());
rc = VD_ERR_SOC_ADDR;
} else {
- buf_set_u32((uint8_t *)ainfo->ai_addr->sa_data, 0, 16, htons(port));
+ h_u16_to_be((uint8_t *)ainfo->ai_addr->sa_data, port);
if (connect(hsock, ainfo->ai_addr, sizeof(struct sockaddr)) < 0) {
LOG_ERROR("socket_open: cannot connect to %s:%d, error %d", server_addr, port, vdebug_socket_error());
rc = VD_ERR_SOC_CONN;
return rc;
}
-int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)
+static int vdebug_run_jtag_queue(int hsock, struct vd_shm *pm, unsigned int count)
{
uint8_t num_pre, num_post, tdi, tms;
unsigned int num, anum, bytes, hwords, words;
return rc;
}
-int vdebug_run_reg_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)
{
unsigned int num, awidth, wwidth;
unsigned int req, waddr, rwords;
for (unsigned int j = 0; j < num; j++)
memcpy(&data[j * awidth], &pm->rd8[(rwords + j) * awidth], awidth);
}
- LOG_DEBUG_IO("read %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req,
- aspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,
+ LOG_DEBUG("read %04x AS:%1x RG:%1x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req,
+ aspace, addr << 2, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,
(num ? le_to_h_u32(&pm->rd8[rwords * 4]) : 0xdead));
rwords += num * wwidth;
waddr += sizeof(uint64_t) / 4; /* waddr past header */
} else {
- LOG_DEBUG_IO("write %04x AS:%02x RG:%02x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req,
- aspace, addr, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,
+ LOG_DEBUG("write %04x AS:%1x RG:%1x O:%05x @%03x D:%08x", le_to_h_u16(pm->wid) - count + req,
+ aspace, addr << 2, (vdc.trans_first << 14) | (vdc.trans_last << 15), waddr,
le_to_h_u32(&pm->wd8[(waddr + num + 1) * 4]));
waddr += sizeof(uint64_t) / 4 + (num * wwidth * awidth + 3) / 4;
}
rc = VD_ERR_VERSION;
} else {
pm->cmd = VD_CMD_CONNECT;
- pm->type = type; /* BFM type to connect to, here JTAG */
+ pm->type = type; /* BFM type to connect to */
h_u32_to_le(pm->rwdata, sig_mask | VD_SIG_BUF | (VD_SIG_BUF << 16));
h_u16_to_le(pm->wbytes, strlen(path) + 1);
h_u16_to_le(pm->rbytes, 12);
static int vdebug_jtag_tms_seq(const uint8_t *tms, int num, uint8_t f_flush)
{
- LOG_INFO("tms len:%d tms:%x", num, *tms);
+ LOG_DEBUG_IO("tms len:%d tms:%x", num, *tms);
return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num, *tms, 0, NULL, 0, 0, NULL, f_flush);
}
static int vdebug_jtag_path_move(struct pathmove_command *cmd, uint8_t f_flush)
{
uint8_t tms[DIV_ROUND_UP(cmd->num_states, 8)];
- LOG_INFO("path num states %d", cmd->num_states);
+ LOG_DEBUG_IO("path num states %d", cmd->num_states);
memset(tms, 0, DIV_ROUND_UP(cmd->num_states, 8));
{
int rc = ERROR_OK;
- uint8_t cur = tap_get_state();
+ tap_state_t cur = tap_get_state();
uint8_t tms_pre = tap_get_tms_path(cur, state);
uint8_t num_pre = tap_get_tms_path_len(cur, state);
- LOG_INFO("tlr from %" PRIx8 " to %" PRIx8, cur, state);
+ LOG_DEBUG_IO("tlr from %x to %x", cur, state);
if (cur != state) {
rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, 0, NULL, 0, 0, NULL, f_flush);
tap_set_state(state);
{
int rc = ERROR_OK;
- uint8_t cur = tap_get_state();
+ tap_state_t cur = tap_get_state();
uint8_t state = cmd->ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT;
uint8_t tms_pre = tap_get_tms_path(cur, state);
uint8_t num_pre = tap_get_tms_path_len(cur, state);
uint8_t tms_post = tap_get_tms_path(state, cmd->end_state);
uint8_t num_post = tap_get_tms_path_len(state, cmd->end_state);
int num_bits = jtag_scan_size(cmd);
- LOG_DEBUG("scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x",
+ LOG_DEBUG_IO("scan len:%d fields:%d ir/!dr:%d state cur:%x end:%x",
num_bits, cmd->num_fields, cmd->ir_scan, cur, cmd->end_state);
for (int i = 0; i < cmd->num_fields; i++) {
uint8_t cur_num_pre = i == 0 ? num_pre : 0;
static int vdebug_jtag_runtest(int cycles, tap_state_t state, uint8_t f_flush)
{
- uint8_t cur = tap_get_state();
+ tap_state_t cur = tap_get_state();
uint8_t tms_pre = tap_get_tms_path(cur, state);
uint8_t num_pre = tap_get_tms_path_len(cur, state);
- LOG_DEBUG("idle len:%d state cur:%x end:%x", cycles, cur, state);
+ LOG_DEBUG_IO("idle len:%d state cur:%x end:%x", cycles, cur, state);
int rc = vdebug_jtag_shift_tap(vdc.hsocket, pbuf, num_pre, tms_pre, cycles, NULL, 0, 0, NULL, f_flush);
if (cur != state)
tap_set_state(state);
static int vdebug_jtag_stableclocks(int num, uint8_t f_flush)
{
- LOG_INFO("stab len:%d state cur:%x", num, tap_get_state());
+ LOG_DEBUG("stab len:%d state cur:%x", num, tap_get_state());
return vdebug_jtag_shift_tap(vdc.hsocket, pbuf, 0, 0, num, NULL, 0, 0, NULL, f_flush);
}
return rc;
}
+static int vdebug_dap_bankselect(struct adiv5_ap *ap, unsigned int reg)
+{
+ int rc = ERROR_OK;
+ uint64_t sel;
+
+ if (is_adiv6(ap->dap)) {
+ sel = ap->ap_num | (reg & 0x00000FF0);
+ if (sel != (ap->dap->select & ~0xfull)) {
+ sel |= ap->dap->select & DP_SELECT_DPBANK;
+ if (ap->dap->asize > 32)
+ sel |= (DP_SELECT1 >> 4) & DP_SELECT_DPBANK;
+ ap->dap->select = sel;
+ ap->dap->select_valid = true;
+ rc = vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, (uint32_t)sel, VD_ASPACE_DP, 0);
+ if (rc == ERROR_OK) {
+ ap->dap->select_valid = true;
+ if (ap->dap->asize > 32)
+ rc = vdebug_reg_write(vdc.hsocket, pbuf, (DP_SELECT1 & DP_SELECT_DPBANK) >> 2,
+ (uint32_t)(sel >> 32), VD_ASPACE_DP, 0);
+ if (rc == ERROR_OK)
+ ap->dap->select1_valid = true;
+ }
+ }
+ } else { /* ADIv5 */
+ sel = (ap->ap_num << 24) | (reg & ADIV5_DP_SELECT_APBANK);
+ if (sel != ap->dap->select) {
+ ap->dap->select = sel;
+ rc = vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, (uint32_t)sel, VD_ASPACE_DP, 0);
+ if (rc == ERROR_OK)
+ ap->dap->select_valid = true;
+ }
+ }
+ return rc;
+}
+
static int vdebug_dap_connect(struct adiv5_dap *dap)
{
return dap_dp_init(dap);
static int vdebug_dap_queue_dp_read(struct adiv5_dap *dap, unsigned int reg, uint32_t *data)
{
+ if (reg != DP_SELECT && reg != DP_RDBUFF
+ && (!dap->select_valid || ((reg >> 4) & DP_SELECT_DPBANK) != (dap->select & DP_SELECT_DPBANK))) {
+ dap->select = (dap->select & ~DP_SELECT_DPBANK) | ((reg >> 4) & DP_SELECT_DPBANK);
+ vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, dap->select, VD_ASPACE_DP, 0);
+ dap->select_valid = true;
+ }
return vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);
}
static int vdebug_dap_queue_dp_write(struct adiv5_dap *dap, unsigned int reg, uint32_t data)
{
+ if (reg != DP_SELECT && reg != DP_RDBUFF
+ && (!dap->select_valid || ((reg >> 4) & DP_SELECT_DPBANK) != (dap->select & DP_SELECT_DPBANK))) {
+ dap->select = (dap->select & ~DP_SELECT_DPBANK) | ((reg >> 4) & DP_SELECT_DPBANK);
+ vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, dap->select, VD_ASPACE_DP, 0);
+ dap->select_valid = true;
+ }
return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_DP, 0);
}
static int vdebug_dap_queue_ap_read(struct adiv5_ap *ap, unsigned int reg, uint32_t *data)
{
- if ((reg & DP_SELECT_APBANK) != ap->dap->select) {
- vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);
- ap->dap->select = reg & DP_SELECT_APBANK;
- }
+ vdebug_dap_bankselect(ap, reg);
vdebug_reg_read(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, NULL, VD_ASPACE_AP, 0);
static int vdebug_dap_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, uint32_t data)
{
- if ((reg & DP_SELECT_APBANK) != ap->dap->select) {
- vdebug_reg_write(vdc.hsocket, pbuf, DP_SELECT >> 2, reg & DP_SELECT_APBANK, VD_ASPACE_DP, 0);
- ap->dap->select = reg & DP_SELECT_APBANK;
- }
-
+ vdebug_dap_bankselect(ap, reg);
return vdebug_reg_write(vdc.hsocket, pbuf, (reg & DP_SELECT_DPBANK) >> 2, data, VD_ASPACE_AP, 0);
}
static int vdebug_dap_run(struct adiv5_dap *dap)
{
- if (pbuf->waddr)
+ if (le_to_h_u16(pbuf->waddr))
return vdebug_run_reg_queue(vdc.hsocket, pbuf, le_to_h_u16(pbuf->waddr));
return ERROR_OK;
break;
}
if (transport_is_dapdirect_swd())
- vdc.bfm_type = VD_BFM_SWDP;
+ vdc.bfm_type = strstr(vdc.bfm_path, "dap6") ? VD_BFM_DAP6 : VD_BFM_SWDP;
else
vdc.bfm_type = VD_BFM_JTAG;
LOG_DEBUG("bfm_path: %s clk_period %ups", vdc.bfm_path, vdc.bfm_period);
{
.name = "mem_path",
.handler = &vdebug_set_mem,
- .mode = COMMAND_ANY,
+ .mode = COMMAND_CONFIG,
.help = "set the design memory for the code load",
.usage = "<path> <base_address> <size>",
},