#define CMD_SCAN_CHAIN_FLIP_TMS 3
#define CMD_STOP_SIMU 4
-int server_port = SERVER_PORT;
-char *server_address;
+/* jtag_vpi server port and address to connect to */
+static int server_port = SERVER_PORT;
+static char *server_address;
-int sockfd;
-struct sockaddr_in serv_addr;
+/* Send CMD_STOP_SIMU to server when OpenOCD exits? */
+static bool stop_sim_on_exit;
+
+static int sockfd;
+static struct sockaddr_in serv_addr;
/* One jtag_vpi "packet" as sent over a TCP channel. */
struct vpi_cmd {
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {
if (vpi->nb_bits > 0) {
/* command with a non-empty data payload */
- char *char_buf = buf_to_str(vpi->buffer_out,
+ char *char_buf = buf_to_hex_str(vpi->buffer_out,
(vpi->nb_bits > DEBUG_JTAG_IOZ)
? DEBUG_JTAG_IOZ
- : vpi->nb_bits,
- 16);
+ : vpi->nb_bits);
LOG_DEBUG_IO("sending JTAG VPI cmd: cmd=%s, "
"length=%" PRIu32 ", "
"nb_bits=%" PRIu32 ", "
* @bits: TMS bits to be written (bit0, bit1 .. bitN)
* @nb_bits: number of TMS bits (between 1 and 8)
*
- * Write a serie of TMS transitions, where each transition consists in :
+ * Write a series of TMS transitions, where each transition consists in :
* - writing out TCK=0, TMS=<new_state>, TDI=<???>
* - writing out TCK=1, TMS=<new_state>, TDI=<???> which triggers the transition
* The function ensures that at the end of the sequence, the clock (TCK) is put
* jtag_vpi_path_move - ask a TMS sequence transition to JTAG
* @cmd: path transition
*
- * Write a serie of TMS transitions, where each transition consists in :
+ * Write a series of TMS transitions, where each transition consists in :
* - writing out TCK=0, TMS=<new_state>, TDI=<???>
* - writing out TCK=1, TMS=<new_state>, TDI=<???> which triggers the transition
* The function ensures that at the end of the sequence, the clock (TCK) is put
/* Optional low-level JTAG debug */
if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) {
- char *char_buf = buf_to_str(vpi.buffer_in,
- (nb_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : nb_bits,
- 16);
+ char *char_buf = buf_to_hex_str(vpi.buffer_in,
+ (nb_bits > DEBUG_JTAG_IOZ) ? DEBUG_JTAG_IOZ : nb_bits);
LOG_DEBUG_IO("recvd JTAG VPI data: nb_bits=%d, buf_in=0x%s%s",
nb_bits, char_buf, (nb_bits > DEBUG_JTAG_IOZ) ? "(...)" : "");
free(char_buf);
*
* Launch a JTAG IR-scan or DR-scan
*
- * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occured.
+ * Returns ERROR_OK if OK, ERROR_xxx if a read/write error occurred.
*/
static int jtag_vpi_scan(struct scan_command *cmd)
{
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");
+ LOG_ERROR("inet_addr error occurred");
return ERROR_FAIL;
}
}
if (serv_addr.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) {
- /* This increases performance drematically for local
+ /* This increases performance dramatically for local
* connections, which is the most likely arrangement
* for a VPI connection. */
setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int));
return ERROR_OK;
}
+static int jtag_vpi_stop_simulation(void)
+{
+ struct vpi_cmd cmd;
+ memset(&cmd, 0, sizeof(struct vpi_cmd));
+ cmd.length = 0;
+ cmd.nb_bits = 0;
+ cmd.cmd = CMD_STOP_SIMU;
+ return jtag_vpi_send_cmd(&cmd);
+}
+
static int jtag_vpi_quit(void)
{
+ if (stop_sim_on_exit) {
+ if (jtag_vpi_stop_simulation() != ERROR_OK)
+ LOG_WARNING("jtag_vpi: failed to send \"stop simulation\" command");
+ }
+ if (close_socket(sockfd) != 0) {
+ LOG_WARNING("jtag_vpi: could not close jtag_vpi client socket");
+ log_socket_error("jtag_vpi");
+ }
free(server_address);
- return close_socket(sockfd);
+ return ERROR_OK;
}
COMMAND_HANDLER(jtag_vpi_set_port)
return ERROR_OK;
}
+COMMAND_HANDLER(jtag_vpi_stop_sim_on_exit_handler)
+{
+ if (CMD_ARGC != 1) {
+ LOG_ERROR("jtag_vpi_stop_sim_on_exit expects 1 argument (on|off)");
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ } else {
+ COMMAND_PARSE_ON_OFF(CMD_ARGV[0], stop_sim_on_exit);
+ }
+ return ERROR_OK;
+}
+
static const struct command_registration jtag_vpi_command_handlers[] = {
{
.name = "jtag_vpi_set_port",
.help = "set the address of the VPI server",
.usage = "ipv4_addr",
},
+ {
+ .name = "jtag_vpi_stop_sim_on_exit",
+ .handler = &jtag_vpi_stop_sim_on_exit_handler,
+ .mode = COMMAND_CONFIG,
+ .help = "Configure if simulation stop command shall be sent "
+ "before OpenOCD exits (default: off)",
+ .usage = "<on|off>",
+ },
COMMAND_REGISTRATION_DONE
};
-struct jtag_interface jtag_vpi_interface = {
- .name = "jtag_vpi",
+static struct jtag_interface jtag_vpi_interface = {
.supported = DEBUG_CAP_TMS_SEQ,
- .commands = jtag_vpi_command_handlers,
+ .execute_queue = jtag_vpi_execute_queue,
+};
+
+struct adapter_driver jtag_vpi_adapter_driver = {
+ .name = "jtag_vpi",
.transports = jtag_only,
+ .commands = jtag_vpi_command_handlers,
.init = jtag_vpi_init,
.quit = jtag_vpi_quit,
- .execute_queue = jtag_vpi_execute_queue,
+
+ .jtag_ops = &jtag_vpi_interface,
};