target: are we running algorithm code?
[fw/openocd] / src / svf / svf.c
index 1c746f382c724042b9a1448d3223b94ef1cee67e..6e951e24f65ecb6368294a4754af4aa485ad191d 100644 (file)
@@ -216,8 +216,6 @@ static char *svf_command_buffer = NULL;
 static int svf_command_buffer_size = 0;
 static int svf_line_number = 1;
 
-static struct jtag_tap *tap = NULL;
-
 #define SVF_MAX_BUFFER_SIZE_TO_COMMIT  (4 * 1024)
 static uint8_t *svf_tdi_buffer = NULL, *svf_tdo_buffer = NULL, *svf_mask_buffer = NULL;
 static int svf_buffer_index = 0, svf_buffer_size = 0;
@@ -470,7 +468,8 @@ free_all:
 #define SVFP_CMD_INC_CNT                       1024
 static int svf_read_command_from_file(int fd)
 {
-       char ch, *tmp_buffer = NULL;
+       unsigned char ch;
+       char *tmp_buffer = NULL;
        int cmd_pos = 0, cmd_ok = 0, slash = 0, comment = 0;
 
        while (!cmd_ok && (read(fd, &ch, 1) > 0))
@@ -499,31 +498,55 @@ static int svf_read_command_from_file(int fd)
                case '\r':
                        slash = 0;
                        comment = 0;
-                       break;
+                       /* Don't save '\r' and '\n' if no data is parsed */
+                       if (!cmd_pos)
+                               break;
                default:
                        if (!comment)
                        {
-                               if (cmd_pos >= svf_command_buffer_size - 1)
+                               /* The parsing code currently expects a space
+                                * before parentheses -- "TDI (123)".  Also a
+                                * space afterwards -- "TDI (123) TDO(456)".
+                                * But such spaces are optional... instead of
+                                * parser updates, cope with that by adding the
+                                * spaces as needed.
+                                *
+                                * Ensure there are 3 bytes available, for:
+                                *  - current character
+                                *  - added space.
+                                *  - terminating NUL ('\0')
+                                */
+                               if ((cmd_pos + 2) >= svf_command_buffer_size)
                                {
-                                       tmp_buffer = (char*)malloc(svf_command_buffer_size + SVFP_CMD_INC_CNT);         // 1 more byte for '\0'
+                                       /* REVISIT use realloc(); simpler */
+                                       tmp_buffer = malloc(
+                                                       svf_command_buffer_size
+                                                       + SVFP_CMD_INC_CNT);
                                        if (NULL == tmp_buffer)
                                        {
                                                LOG_ERROR("not enough memory");
                                                return ERROR_FAIL;
                                        }
                                        if (svf_command_buffer_size > 0)
-                                       {
-                                               memcpy(tmp_buffer, svf_command_buffer, svf_command_buffer_size);
-                                       }
+                                               memcpy(tmp_buffer,
+                                                       svf_command_buffer,
+                                                       svf_command_buffer_size);
                                        if (svf_command_buffer != NULL)
-                                       {
                                                free(svf_command_buffer);
-                                       }
                                        svf_command_buffer = tmp_buffer;
                                        svf_command_buffer_size += SVFP_CMD_INC_CNT;
                                        tmp_buffer = NULL;
                                }
+
+                               /* insert a space before '(' */
+                               if ('(' == ch)
+                                       svf_command_buffer[cmd_pos++] = ' ';
+
                                svf_command_buffer[cmd_pos++] = (char)toupper(ch);
+
+                               /* insert a space after ')' */
+                               if (')' == ch)
+                                       svf_command_buffer[cmd_pos++] = ' ';
                        }
                        break;
                }
@@ -542,25 +565,30 @@ static int svf_read_command_from_file(int fd)
 
 static int svf_parse_cmd_string(char *str, int len, char **argus, int *num_of_argu)
 {
-       int pos = 0, num = 0, space_found = 1;
+       int pos = 0, num = 0, space_found = 1, in_bracket = 0;
 
        while (pos < len)
        {
                switch (str[pos])
                {
-               case '\n':
-               case '\r':
                case '!':
                case '/':
                        LOG_ERROR("fail to parse svf command");
                        return ERROR_FAIL;
-                       break;
-               case ' ':
-                       space_found = 1;
-                       str[pos] = '\0';
-                       break;
+               case '(':
+                       in_bracket = 1;
+                       goto parse_char;
+               case ')':
+                       in_bracket = 0;
+                       goto parse_char;
                default:
-                       if (space_found)
+parse_char:
+                       if (!in_bracket && isspace((int) str[pos]))
+                       {
+                               space_found = 1;
+                               str[pos] = '\0';
+                       }
+                       else if (space_found)
                        {
                                argus[num++] = &str[pos];
                                space_found = 0;
@@ -628,6 +656,7 @@ static int svf_copy_hexstring_to_binary(char *str, uint8_t **bin, int orig_bit_l
                return ERROR_FAIL;
        }
 
+       /* fill from LSB (end of str) to MSB (beginning of str) */
        for (i = 0; i < str_hbyte_len; i++)
        {
                ch = 0;
@@ -635,7 +664,13 @@ static int svf_copy_hexstring_to_binary(char *str, uint8_t **bin, int orig_bit_l
                {
                        ch = str[--str_len];
 
-                       if (!isblank(ch))
+                       /* Skip whitespace.  The SVF specification (rev E) is
+                        * deficient in terms of basic lexical issues like
+                        * where whitespace is allowed.  Long bitstrings may
+                        * require line ends for correctness, since there is
+                        * a hard limit on line length.
+                        */
+                       if (!isspace(ch))
                        {
                                if ((ch >= '0') && (ch <= '9'))
                                {
@@ -671,11 +706,12 @@ static int svf_copy_hexstring_to_binary(char *str, uint8_t **bin, int orig_bit_l
                }
        }
 
-       // consume optional leading '0' characters
-       while (str_len > 0 && str[str_len - 1] == '0')
+       /* consume optional leading '0' MSBs or whitespace */
+       while (str_len > 0 && ((str[str_len - 1] == '0')
+                               || isspace((int) str[str_len - 1])))
                str_len--;
 
-       // check valid
+       /* check validity: we must have consumed everything */
        if (str_len > 0 || (ch & ~((2 << ((bit_len - 1) % 4)) - 1)) != 0)
        {
                LOG_ERROR("value execeeds length");
@@ -844,7 +880,7 @@ static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str)
                        // TODO: set jtag speed to
                        if (svf_para.frequency > 0)
                        {
-                               command_run_linef(cmd_ctx, "jtag_khz %d", (int)svf_para.frequency / 1000);
+                               command_run_linef(cmd_ctx, "adapter_khz %d", (int)svf_para.frequency / 1000);
                                LOG_DEBUG("\tfrequency = %f", svf_para.frequency);
                        }
                }
@@ -1044,12 +1080,11 @@ static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str)
                        {
                                svf_add_check_para(0, svf_buffer_index, i);
                        }
-                       field.tap = tap;
                        field.num_bits = i;
                        field.out_value = &svf_tdi_buffer[svf_buffer_index];
                        field.in_value = &svf_tdi_buffer[svf_buffer_index];
                        /* NOTE:  doesn't use SVF-specified state paths */
-                       jtag_add_plain_dr_scan(1, &field, svf_para.dr_end_state);
+                       jtag_add_plain_dr_scan(field.num_bits, field.out_value, field.in_value, svf_para.dr_end_state);
 
                        svf_buffer_index += (i + 7) >> 3;
                }
@@ -1140,12 +1175,12 @@ static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str)
                        {
                                svf_add_check_para(0, svf_buffer_index, i);
                        }
-                       field.tap = tap;
                        field.num_bits = i;
                        field.out_value = &svf_tdi_buffer[svf_buffer_index];
                        field.in_value = &svf_tdi_buffer[svf_buffer_index];
                        /* NOTE:  doesn't use SVF-specified state paths */
-                       jtag_add_plain_ir_scan(1, &field, svf_para.ir_end_state);
+                       jtag_add_plain_ir_scan(field.num_bits, field.out_value, field.in_value,
+                                       svf_para.ir_end_state);
 
                        svf_buffer_index += (i + 7) >> 3;
                }
@@ -1460,10 +1495,10 @@ static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str)
 static const struct command_registration svf_command_handlers[] = {
        {
                .name = "svf",
-               .handler = &handle_svf_command,
+               .handler = handle_svf_command,
                .mode = COMMAND_EXEC,
                .help = "Runs a SVF file.",
-               .usage = "<file>",
+               .usage = "filename ['quiet']",
        },
        COMMAND_REGISTRATION_DONE
 };