X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fjtag_vpi.c;h=1033cedb28c95a18a38483afee01b2ebd9100a46;hb=refs%2Fchanges%2F51%2F5151%2F3;hp=29dbd4821eeeba3234798aff0b16f0cdd4fc1256;hpb=0da3f66ed48d29be02af5e18496d383a7f8c66ba;p=openocd.git diff --git a/src/jtag/drivers/jtag_vpi.c b/src/jtag/drivers/jtag_vpi.c index 29dbd4821e..1033cedb28 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 @@ -27,6 +29,10 @@ #include #endif +#ifndef _WIN32 +#include +#endif + #define NO_TAP_SHIFT 0 #define TAP_SHIFT 1 @@ -42,6 +48,7 @@ #define CMD_STOP_SIMU 4 int server_port = SERVER_PORT; +char *server_address; int sockfd; struct sockaddr_in serv_addr; @@ -201,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--; @@ -315,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; @@ -324,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) @@ -368,6 +392,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"); @@ -379,7 +405,10 @@ static int jtag_vpi_init(void) serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(server_port); - serv_addr.sin_addr.s_addr = inet_addr(SERVER_ADDRESS); + 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"); @@ -388,17 +417,25 @@ static int jtag_vpi_init(void) 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); } @@ -414,6 +451,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[] = { { @@ -423,6 +474,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 };