X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fjtag_vpi.c;h=3e39420fb39b80bebb8e1cdc924c49222b50fe69;hb=4f779a88db4c03c3cf280275c383fd3f24f9fea3;hp=d962ecfc7bf770aa1c1d2fc65722ec14f450b854;hpb=1211b8ea481b9185b04563a741ac0c41da274bc9;p=openocd.git
diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c
index d962ecfc7b..3e39420fb3 100644
--- a/src/jtag/drivers/jtag_vpi.c
+++ b/src/jtag/drivers/jtag_vpi.c
@@ -16,6 +16,8 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
*/
#ifdef HAVE_CONFIG_H
@@ -23,7 +25,13 @@
#endif
#include
+#ifdef HAVE_ARPA_INET_H
#include
+#endif
+
+#ifndef _WIN32
+#include
+#endif
#define NO_TAP_SHIFT 0
#define TAP_SHIFT 1
@@ -40,6 +48,7 @@
#define CMD_STOP_SIMU 4
int server_port = SERVER_PORT;
+char *server_address;
int sockfd;
struct sockaddr_in serv_addr;
@@ -54,7 +63,7 @@ struct vpi_cmd {
static int jtag_vpi_send_cmd(struct vpi_cmd *vpi)
{
- int retval = write(sockfd, vpi, sizeof(struct vpi_cmd));
+ int retval = write_socket(sockfd, vpi, sizeof(struct vpi_cmd));
if (retval <= 0)
return ERROR_FAIL;
@@ -63,7 +72,7 @@ static int jtag_vpi_send_cmd(struct vpi_cmd *vpi)
static int jtag_vpi_receive_cmd(struct vpi_cmd *vpi)
{
- int retval = read(sockfd, vpi, sizeof(struct vpi_cmd));
+ int retval = read_socket(sockfd, vpi, sizeof(struct vpi_cmd));
if (retval < (int)sizeof(struct vpi_cmd))
return ERROR_FAIL;
@@ -199,23 +208,20 @@ static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift)
static int jtag_vpi_queue_tdi(uint8_t *bits, int nb_bits, int tap_shift)
{
int nb_xfer = DIV_ROUND_UP(nb_bits, XFERT_MAX_SIZE * 8);
- uint8_t *xmit_buffer = bits;
- int xmit_nb_bits = nb_bits;
- int i = 0;
int retval;
while (nb_xfer) {
-
if (nb_xfer == 1) {
- retval = jtag_vpi_queue_tdi_xfer(&xmit_buffer[i], xmit_nb_bits, tap_shift);
+ retval = jtag_vpi_queue_tdi_xfer(bits, nb_bits, tap_shift);
if (retval != ERROR_OK)
return retval;
} else {
- retval = jtag_vpi_queue_tdi_xfer(&xmit_buffer[i], XFERT_MAX_SIZE * 8, NO_TAP_SHIFT);
+ retval = jtag_vpi_queue_tdi_xfer(bits, XFERT_MAX_SIZE * 8, NO_TAP_SHIFT);
if (retval != ERROR_OK)
return retval;
- xmit_nb_bits -= XFERT_MAX_SIZE * 8;
- i += XFERT_MAX_SIZE;
+ nb_bits -= XFERT_MAX_SIZE * 8;
+ if (bits)
+ bits += XFERT_MAX_SIZE;
}
nb_xfer--;
@@ -313,7 +319,7 @@ static int jtag_vpi_runtest(int cycles, tap_state_t state)
if (retval != ERROR_OK)
return retval;
- retval = jtag_vpi_queue_tdi(NULL, cycles, TAP_SHIFT);
+ retval = jtag_vpi_queue_tdi(NULL, cycles, NO_TAP_SHIFT);
if (retval != ERROR_OK)
return retval;
@@ -322,7 +328,27 @@ static int jtag_vpi_runtest(int cycles, tap_state_t state)
static int jtag_vpi_stableclocks(int cycles)
{
- return jtag_vpi_queue_tdi(NULL, cycles, TAP_SHIFT);
+ uint8_t tms_bits[4];
+ int cycles_remain = cycles;
+ int nb_bits;
+ int retval;
+ const int CYCLES_ONE_BATCH = sizeof(tms_bits) * 8;
+
+ assert(cycles >= 0);
+
+ /* use TMS=1 in TAP RESET state, TMS=0 in all other stable states */
+ memset(&tms_bits, (tap_get_state() == TAP_RESET) ? 0xff : 0x00, sizeof(tms_bits));
+
+ /* send the TMS bits */
+ while (cycles_remain > 0) {
+ nb_bits = (cycles_remain < CYCLES_ONE_BATCH) ? cycles_remain : CYCLES_ONE_BATCH;
+ retval = jtag_vpi_tms_seq(tms_bits, nb_bits);
+ if (retval != ERROR_OK)
+ return retval;
+ cycles_remain -= nb_bits;
+ }
+
+ return ERROR_OK;
}
static int jtag_vpi_execute_queue(void)
@@ -358,6 +384,11 @@ static int jtag_vpi_execute_queue(void)
case JTAG_SCAN:
retval = jtag_vpi_scan(cmd->cmd.scan);
break;
+ default:
+ LOG_ERROR("BUG: unknown JTAG command type 0x%X",
+ cmd->type);
+ retval = ERROR_FAIL;
+ break;
}
}
@@ -366,6 +397,8 @@ static int jtag_vpi_execute_queue(void)
static int jtag_vpi_init(void)
{
+ int flag = 1;
+
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
LOG_ERROR("Could not create socket");
@@ -377,24 +410,37 @@ static int jtag_vpi_init(void)
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(server_port);
- if (inet_pton(AF_INET, SERVER_ADDRESS, &serv_addr.sin_addr) <= 0) {
- LOG_ERROR("inet_pton error occured");
+ if (!server_address)
+ server_address = strdup(SERVER_ADDRESS);
+
+ serv_addr.sin_addr.s_addr = inet_addr(server_address);
+
+ if (serv_addr.sin_addr.s_addr == INADDR_NONE) {
+ LOG_ERROR("inet_addr error occured");
return ERROR_FAIL;
}
if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
close(sockfd);
- LOG_ERROR("Can't connect to %s : %u", SERVER_ADDRESS, server_port);
+ LOG_ERROR("Can't connect to %s : %u", server_address, server_port);
return ERROR_COMMAND_CLOSE_CONNECTION;
}
- LOG_INFO("Connection to %s : %u succeed", SERVER_ADDRESS, server_port);
+ if (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
+ /* This increases performance drematically for local
+ * connections, which is the most likely arrangement
+ * for a VPI connection. */
+ setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
+ }
+
+ LOG_INFO("Connection to %s : %u succeed", server_address, server_port);
return ERROR_OK;
}
static int jtag_vpi_quit(void)
{
+ free(server_address);
return close(sockfd);
}
@@ -410,6 +456,20 @@ COMMAND_HANDLER(jtag_vpi_set_port)
return ERROR_OK;
}
+COMMAND_HANDLER(jtag_vpi_set_address)
+{
+ free(server_address);
+
+ if (CMD_ARGC == 0) {
+ LOG_WARNING("You need to set an address");
+ server_address = strdup(SERVER_ADDRESS);
+ } else
+ server_address = strdup(CMD_ARGV[0]);
+
+ LOG_INFO("Set server address to %s", server_address);
+
+ return ERROR_OK;
+}
static const struct command_registration jtag_vpi_command_handlers[] = {
{
@@ -419,6 +479,13 @@ static const struct command_registration jtag_vpi_command_handlers[] = {
.help = "set the port of the VPI server",
.usage = "description_string",
},
+ {
+ .name = "jtag_vpi_set_address",
+ .handler = &jtag_vpi_set_address,
+ .mode = COMMAND_CONFIG,
+ .help = "set the address of the VPI server",
+ .usage = "description_string",
+ },
COMMAND_REGISTRATION_DONE
};