drivers/bcm2835gpio: fix usage messages
[fw/openocd] / src / jtag / drivers / jtag_vpi.c
index 84cd947064860b20b560e560e106dca53b1f2df8..35c70312d6d507b13e352dbbd54d1526f59580f5 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_H
 #endif
 
 #include <jtag/interface.h>
+#ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
+#endif
+
+#ifndef _WIN32
+#include <netinet/tcp.h>
+#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;
 
@@ -100,7 +109,7 @@ static int jtag_vpi_tms_seq(const uint8_t *bits, int nb_bits)
        struct vpi_cmd vpi;
        int nb_bytes;
 
-       nb_bytes = (nb_bits / 8) + !!(nb_bits % 8);
+       nb_bytes = DIV_ROUND_UP(nb_bits, 8);
 
        vpi.cmd = CMD_TMS_SEQ;
        memcpy(vpi.buffer_out, bits, nb_bytes);
@@ -123,23 +132,17 @@ static int jtag_vpi_tms_seq(const uint8_t *bits, int nb_bits)
 
 static int jtag_vpi_path_move(struct pathmove_command *cmd)
 {
-       uint16_t trans = 0;
-       int retval;
-       int i;
+       uint8_t trans[DIV_ROUND_UP(cmd->num_states, 8)];
 
-       for (i = 0; i < cmd->num_states; i++) {
+       memset(trans, 0, DIV_ROUND_UP(cmd->num_states, 8));
+
+       for (int i = 0; i < cmd->num_states; i++) {
                if (tap_state_transition(tap_get_state(), true) == cmd->path[i])
-                       trans = trans | 1;
-               trans = trans << 1;
+                       buf_set_u32(trans, i, 1, 1);
+               tap_set_state(cmd->path[i]);
        }
 
-       retval = jtag_vpi_tms_seq((uint8_t *)&trans, 1);
-       if (retval != ERROR_OK)
-               return retval;
-
-       tap_set_state(cmd->path[i]);
-
-       return ERROR_OK;
+       return jtag_vpi_tms_seq(trans, cmd->num_states);
 }
 
 /**
@@ -171,7 +174,7 @@ static int jtag_vpi_state_move(tap_state_t state)
 static int jtag_vpi_queue_tdi_xfer(uint8_t *bits, int nb_bits, int tap_shift)
 {
        struct vpi_cmd vpi;
-       int nb_bytes = (nb_bits / 8) + !!(nb_bits % 8);
+       int nb_bytes = DIV_ROUND_UP(nb_bits, 8);
 
        vpi.cmd = tap_shift ? CMD_SCAN_CHAIN_FLIP_TMS : CMD_SCAN_CHAIN;
 
@@ -204,24 +207,21 @@ 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 = (nb_bits / (XFERT_MAX_SIZE * 8)) + !!(nb_bits % (XFERT_MAX_SIZE * 8));
-       uint8_t *xmit_buffer = bits;
-       int xmit_nb_bits = nb_bits;
-       int i = 0;
+       int nb_xfer = DIV_ROUND_UP(nb_bits, XFERT_MAX_SIZE * 8);
        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--;
@@ -372,6 +372,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");
@@ -383,24 +385,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);
 }
 
@@ -416,6 +431,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[] = {
        {
@@ -425,6 +454,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
 };