retire ERROR_INVALID_ARGUMENTS and replace with ERROR_COMMAND_SYNTAX_ERROR
[openocd.git] / src / jtag / zy1000 / zy1000.c
index c8bee2f506292c282f03e4cb1271ebb7712b76fe..22193abd2c74afe84890104e830f1eb27d860220 100644 (file)
@@ -45,6 +45,8 @@
 #include "config.h"
 #endif
 
+#include <pthread.h>
+
 #include <target/embeddedice.h>
 #include <jtag/minidriver.h>
 #include <jtag/interface.h>
@@ -170,6 +172,45 @@ static int zy1000_power_dropout(int *dropout)
        return ERROR_OK;
 }
 
+/* Wait for SRST to assert or deassert */
+static void waitSRST(bool asserted)
+{
+       bool first = true;
+       long long start = 0;
+       long total = 0;
+       const char *mode = asserted ? "assert" : "deassert";
+
+       for (;;)
+       {
+               bool srstAsserted = readSRST();
+               if ( (asserted && srstAsserted) || (!asserted && !srstAsserted) )
+               {
+                       if (total > 1)
+                       {
+                               LOG_USER("SRST took %dms to %s", (int)total, mode);
+                       }
+                       break;
+               }
+
+               if (first)
+               {
+                       first = false;
+                       start = timeval_ms();
+               }
+
+               total = timeval_ms() - start;
+
+               keep_alive();
+
+               if (total > 5000)
+               {
+                       LOG_ERROR("SRST took too long to %s: %dms", mode, (int)total);
+                       break;
+               }
+       }
+}
+
+
 void zy1000_reset(int trst, int srst)
 {
        LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
@@ -190,6 +231,8 @@ void zy1000_reset(int trst, int srst)
                 * idle in TAP_IDLE, reset halt on str912 will fail.
                 */
                ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000001);
+
+               waitSRST(true);
        }
 
        if (!trst)
@@ -216,40 +259,7 @@ void zy1000_reset(int trst, int srst)
        if ((!srst && ((jtag_get_reset_config() & RESET_TRST_PULLS_SRST) == 0))||
                (!srst && !trst && (jtag_get_reset_config() & RESET_TRST_PULLS_SRST)))
        {
-               bool first = true;
-               long long start = 0;
-               long total = 0;
-               for (;;)
-               {       
-                       // We don't want to sense our own reset, so we clear here.
-                       // There is of course a timing hole where we could loose
-                       // a "real" reset.
-                       if (!readSRST())
-                       {
-                               if (total > 1)
-                               {
-                                 LOG_USER("SRST took %dms to deassert", (int)total);
-                               }
-                               break;
-                       }
-
-                       if (first)
-                       {
-                           first = false;
-                           start = timeval_ms();
-                       }
-
-                       total = timeval_ms() - start;
-
-                       keep_alive();
-
-                       if (total > 5000)
-                       {
-                               LOG_ERROR("SRST took too long to deassert: %dms", (int)total);
-                           break;
-                       }
-               }
-
+               waitSRST(false);
        }
 }
 
@@ -273,7 +283,7 @@ int zy1000_speed(int speed)
                {
                        LOG_USER("valid ZY1000 jtag_speed=[8190,2]. With divisor is %dkHz / even values between 8190-2, i.e. min %dHz, max %dMHz",
                                        ZYLIN_KHZ, (ZYLIN_KHZ * 1000) / 8190, ZYLIN_KHZ / (2 * 1000));
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
                }
 
                int khz;
@@ -315,7 +325,7 @@ COMMAND_HANDLER(handle_power_command)
                LOG_INFO("Target power %s", savePower ? "on" : "off");
                break;
        default:
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        return ERROR_OK;
@@ -438,24 +448,10 @@ struct cyg_upgrade_info firmware_info =
                report_info,
 };
 
+// File written to /ram/firmware.phi before arriving at this fn
 static int jim_zy1000_writefirmware(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
-       if (argc != 2)
-               return JIM_ERR;
-
-       int length;
-       const char *str = Jim_GetString(argv[1], &length);
-
-       /* */
-       int tmpFile;
-       if ((tmpFile = open(firmware_info.file, O_RDWR | O_CREAT | O_TRUNC)) <= 0)
-       {
-               return JIM_ERR;
-       }
-       bool success;
-       success = write(tmpFile, str, length) == length;
-       close(tmpFile);
-       if (!success)
+       if (argc != 1)
                return JIM_ERR;
 
        if (!cyg_firmware_upgrade(NULL, firmware_info))
@@ -622,6 +618,11 @@ int interface_jtag_add_ir_scan(struct jtag_tap *active, const struct scan_field
                        assert(scan_size <= 32);
                        shiftValueInner(TAP_IRSHIFT, pause_state, scan_size, 0xffffffff);
 
+                       /* Optimization code will check what the cur_instr is set to, so
+                        * we must set it to bypass value.
+                        */
+                       buf_set_ones(tap->cur_instr, tap->ir_length);
+
                        tap->bypass = 1;
                }
        }
@@ -852,7 +853,7 @@ static void jtag_pre_post_bits(struct jtag_tap *tap, int *pre, int *post)
                        TAP_IDLE);
 */
 
-void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer, int little, int count)
+void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer, int little, int count)
 {
 #if 0
        int i;
@@ -894,7 +895,7 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer,
 
 
 
-int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, uint32_t * data, size_t count)
+int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opcode, const uint32_t * data, size_t count)
 {
        /* bypass bits before and after */
        int pre_bits;
@@ -904,7 +905,7 @@ int arm11_run_instr_data_to_core_noack_inner(struct jtag_tap * tap, uint32_t opc
 
        if ((pre_bits > 32) || (post_bits > 32))
        {
-               int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *, uint32_t, uint32_t *, size_t);
+               int arm11_run_instr_data_to_core_noack_inner_default(struct jtag_tap *, uint32_t, const uint32_t *, size_t);
                return arm11_run_instr_data_to_core_noack_inner_default(tap, opcode, data, count);
        } else
        {
@@ -1040,7 +1041,8 @@ static const struct command_registration zy1000_commands[] = {
 };
 
 
-#if !BUILD_ZY1000_MASTER || BUILD_ECOSBOARD
+#if !BUILD_ZY1000_MASTER
+
 static int tcp_ip = -1;
 
 /* Write large packets if we can */
@@ -1077,14 +1079,6 @@ static bool writeLong(uint32_t l)
 
 static bool readLong(uint32_t *out_data)
 {
-       if (out_pos > 0)
-       {
-               if (!flush_writes())
-               {
-                       return false;
-               }
-       }
-
        uint32_t data = 0;
        int i;
        for (i = 0; i < 4; i++)
@@ -1092,6 +1086,17 @@ static bool readLong(uint32_t *out_data)
                uint8_t c;
                if (in_pos == in_write)
                {
+                       /* If we have some data that we can send, send them before
+                        * we wait for more data
+                        */
+                       if (out_pos > 0)
+                       {
+                               if (!flush_writes())
+                               {
+                                       return false;
+                               }
+                       }
+
                        /* read more */
                        int t;
                        t = read(tcp_ip, in_buffer, sizeof(in_buffer));
@@ -1109,7 +1114,6 @@ static bool readLong(uint32_t *out_data)
        *out_data = data;
        return true;
 }
-#endif
 
 enum ZY1000_CMD
 {
@@ -1119,9 +1123,6 @@ enum ZY1000_CMD
        ZY1000_CMD_WAITIDLE = 2
 };
 
-
-#if !BUILD_ZY1000_MASTER
-
 #include <sys/socket.h> /* for socket(), connect(), send(), and recv() */
 #include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */
 
@@ -1295,6 +1296,15 @@ void zy1000_jtag_add_callback4(jtag_callback_t callback, jtag_callback_data_t da
        callbackqueue[callbackqueue_pos].data2 = data2;
        callbackqueue[callbackqueue_pos].data3 = data3;
        callbackqueue_pos++;
+
+       /* KLUDGE!
+        * make callbacks synchronous for now as minidriver requires callback
+        * to be synchronous.
+        *
+        * We can get away with making read and writes asynchronous so we
+        * don't completely kill performance.
+        */
+       zy1000_flush_callbackqueue();
 }
 
 static int zy1000_jtag_convert_to_callback4(jtag_callback_data_t data0, jtag_callback_data_t data1, jtag_callback_data_t data2, jtag_callback_data_t data3)
@@ -1341,6 +1351,9 @@ static void writeShiftValue(uint8_t *data, int bits)
        readqueue[readqueue_pos].dest = data;
        readqueue[readqueue_pos].bits = bits;
        readqueue_pos++;
+
+       /* KLUDGE!!! minidriver requires readqueue to be synchronous */
+       zy1000_flush_readqueue();
 }
 
 #else
@@ -1364,129 +1377,13 @@ static void writeShiftValue(uint8_t *data, int bits)
 
 #endif
 
-#if BUILD_ECOSBOARD
-static char tcpip_stack[2048];
-static cyg_thread tcpip_thread_object;
-static cyg_handle_t tcpip_thread_handle;
+#if BUILD_ZY1000_MASTER
 
+#if BUILD_ECOSBOARD
 static char watchdog_stack[2048];
 static cyg_thread watchdog_thread_object;
 static cyg_handle_t watchdog_thread_handle;
-
-/* Infinite loop peeking & poking */
-static void tcpipserver(void)
-{
-       for (;;)
-       {
-               uint32_t address;
-               if (!readLong(&address))
-                       return;
-               enum ZY1000_CMD c = (address >> 24) & 0xff;
-               address &= 0xffffff;
-               switch (c)
-               {
-                       case ZY1000_CMD_POKE:
-                       {
-                               uint32_t data;
-                               if (!readLong(&data))
-                                       return;
-                               address &= ~0x80000000;
-                               ZY1000_POKE(address + ZY1000_JTAG_BASE, data);
-                               break;
-                       }
-                       case ZY1000_CMD_PEEK:
-                       {
-                               uint32_t data;
-                               ZY1000_PEEK(address + ZY1000_JTAG_BASE, data);
-                               if (!writeLong(data))
-                                       return;
-                               break;
-                       }
-                       case ZY1000_CMD_SLEEP:
-                       {
-                               uint32_t data;
-                               if (!readLong(&data))
-                                       return;
-                               jtag_sleep(data);
-                               break;
-                       }
-                       case ZY1000_CMD_WAITIDLE:
-                       {
-                               waitIdle();
-                               break;
-                       }
-                       default:
-                               return;
-               }
-       }
-}
-
-
-static void tcpip_server(cyg_addrword_t data)
-{
-       int so_reuseaddr_option = 1;
-
-       int fd;
-       if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
-       {
-               LOG_ERROR("error creating socket: %s", strerror(errno));
-               exit(-1);
-       }
-
-       setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void*) &so_reuseaddr_option,
-                       sizeof(int));
-
-       struct sockaddr_in sin;
-       unsigned int address_size;
-       address_size = sizeof(sin);
-       memset(&sin, 0, sizeof(sin));
-       sin.sin_family = AF_INET;
-       sin.sin_addr.s_addr = INADDR_ANY;
-       sin.sin_port = htons(7777);
-
-       if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) == -1)
-       {
-               LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
-               exit(-1);
-       }
-
-       if (listen(fd, 1) == -1)
-       {
-               LOG_ERROR("couldn't listen on socket: %s", strerror(errno));
-               exit(-1);
-       }
-
-
-       for (;;)
-       {
-               tcp_ip = accept(fd, (struct sockaddr *) &sin, &address_size);
-               if (tcp_ip < 0)
-               {
-                       continue;
-               }
-
-               int flag = 1;
-               setsockopt(tcp_ip,      /* socket affected */
-                               IPPROTO_TCP,            /* set option at TCP level */
-                               TCP_NODELAY,            /* name of option */
-                               (char *)&flag,          /* the cast is historical cruft */
-                               sizeof(int));           /* length of option value */
-
-               bool save_poll = jtag_poll_get_enabled();
-
-               /* polling will screw up the "connection" */
-               jtag_poll_set_enabled(false);
-
-               tcpipserver();
-
-               jtag_poll_set_enabled(save_poll);
-
-               close(tcp_ip);
-
-       }
-       close(fd);
-
-}
+#endif
 
 #ifdef WATCHDOG_BASE
 /* If we connect to port 8888 we must send a char every 10s or the board resets itself */
@@ -1620,20 +1517,16 @@ int zy1000_init(void)
 
         /* deassert resets. Important to avoid infinite loop waiting for SRST to deassert */
        zy1000_reset(0, 0);
-       zy1000_speed(jtag_get_speed());
-
 
+#if BUILD_ZY1000_MASTER
 #if BUILD_ECOSBOARD
-       cyg_thread_create(1, tcpip_server, (cyg_addrword_t) 0, "tcip/ip server",
-                       (void *) tcpip_stack, sizeof(tcpip_stack),
-                       &tcpip_thread_handle, &tcpip_thread_object);
-       cyg_thread_resume(tcpip_thread_handle);
 #ifdef WATCHDOG_BASE
        cyg_thread_create(1, watchdog_server, (cyg_addrword_t) 0, "watchdog tcip/ip server",
                        (void *) watchdog_stack, sizeof(watchdog_stack),
                        &watchdog_thread_handle, &watchdog_thread_object);
        cyg_thread_resume(watchdog_thread_handle);
 #endif
+#endif
 #endif
 
        return ERROR_OK;

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)