* 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <arpa/inet.h>
#endif
+#ifndef _WIN32
+#include <netinet/tcp.h>
+#endif
+
#define NO_TAP_SHIFT 0
#define TAP_SHIFT 1
#define CMD_STOP_SIMU 4
int server_port = SERVER_PORT;
+char *server_address;
int sockfd;
struct sockaddr_in serv_addr;
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--;
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;
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)
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");
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");
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);
}
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[] = {
{
.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
};