change #include "jtag.h" to <jtag/jtag.h>
[fw/openocd] / src / svf / svf.c
index dfbbde4bec03fa648518395dd801db43ba21b241..e6d842b7a5edb2175837f3c5454b95a65b172d73 100644 (file)
@@ -31,9 +31,9 @@
 #include "config.h"
 #endif
 
-#include "jtag.h"
+#include <jtag/jtag.h>
 #include "svf.h"
-#include "time_support.h"
+#include <helper/time_support.h>
 
 
 // SVF command
@@ -55,7 +55,7 @@ typedef enum
        TRST,
 }svf_command_t;
 
-const char *svf_command_name[14] =
+static const char *svf_command_name[14] =
 {
        "ENDDR",
        "ENDIR",
@@ -81,7 +81,7 @@ typedef enum
        TRST_ABSENT
 }trst_mode_t;
 
-const char *svf_trst_mode_name[4] =
+static const char *svf_trst_mode_name[4] =
 {
        "ON",
        "OFF",
@@ -89,13 +89,13 @@ const char *svf_trst_mode_name[4] =
        "ABSENT"
 };
 
-typedef struct
+struct svf_statemove
 {
        tap_state_t from;
        tap_state_t to;
        uint32_t num_of_moves;
        tap_state_t paths[8];
-}svf_statemove_t;
+};
 
 /*
  * These paths are from the SVF specification for the STATE command, to be
@@ -112,7 +112,7 @@ typedef struct
  * and many SVF implementations, we don't want to risk missing that state.
  * To get to RESET, always we ignore the current state.
  */
-static const svf_statemove_t svf_statemoves[] =
+static const struct svf_statemove svf_statemoves[] =
 {
        // from                 to                              num_of_moves,   paths[8]
 //     {TAP_RESET,             TAP_RESET,              1,                              {TAP_RESET}},
@@ -136,13 +136,12 @@ static const svf_statemove_t svf_statemoves[] =
        {TAP_IRPAUSE,   TAP_IRPAUSE,    8,                              {TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE}}
 };
 
-char *svf_tap_state_name[TAP_NUM_STATES];
 
 #define XXR_TDI                                                (1 << 0)
 #define XXR_TDO                                                (1 << 1)
 #define XXR_MASK                                       (1 << 2)
 #define XXR_SMASK                                      (1 << 3)
-typedef struct
+struct svf_xxr_para
 {
        int len;
        int data_mask;
@@ -150,9 +149,9 @@ typedef struct
        uint8_t *tdo;
        uint8_t *mask;
        uint8_t *smask;
-}svf_xxr_para_t;
+};
 
-typedef struct
+struct svf_para
 {
        float frequency;
        tap_state_t ir_end_state;
@@ -161,16 +160,16 @@ typedef struct
        tap_state_t runtest_end_state;
        trst_mode_t trst_mode;
 
-       svf_xxr_para_t hir_para;
-       svf_xxr_para_t hdr_para;
-       svf_xxr_para_t tir_para;
-       svf_xxr_para_t tdr_para;
-       svf_xxr_para_t sir_para;
-       svf_xxr_para_t sdr_para;
-}svf_para_t;
+       struct svf_xxr_para hir_para;
+       struct svf_xxr_para hdr_para;
+       struct svf_xxr_para tir_para;
+       struct svf_xxr_para tdr_para;
+       struct svf_xxr_para sir_para;
+       struct svf_xxr_para sdr_para;
+};
 
-svf_para_t svf_para;
-const svf_para_t svf_para_init =
+static struct svf_para svf_para;
+static const struct svf_para svf_para_init =
 {
 //     frequency,      ir_end_state,   dr_end_state,   runtest_run_state,      runtest_end_state,      trst_mode
        0,                      TAP_IDLE,               TAP_IDLE,               TAP_IDLE,                       TAP_IDLE,                       TRST_Z,
@@ -194,33 +193,30 @@ const svf_para_t svf_para_init =
        {0,             0,                      NULL,   NULL,   NULL,   NULL},
 };
 
-typedef struct
+struct svf_check_tdo_para
 {
        int line_num;           // used to record line number of the check operation
                                                // so more information could be printed
        int enabled;            // check is enabled or not
        int buffer_offset;      // buffer_offset to buffers
        int bit_len;            // bit length to check
-}svf_check_tdo_para_t;
+};
 
 #define SVF_CHECK_TDO_PARA_SIZE        1024
-static svf_check_tdo_para_t *svf_check_tdo_para = NULL;
+static struct svf_check_tdo_para *svf_check_tdo_para = NULL;
 static int svf_check_tdo_para_index = 0;
 
-#define dimof(a)                                       (sizeof(a) / sizeof((a)[0]))
-
 static int svf_read_command_from_file(int fd);
 static int svf_check_tdo(void);
 static int svf_add_check_para(uint8_t enabled, int buffer_offset, int bit_len);
-static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str);
-static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
+static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str);
 
 static int svf_fd = 0;
 static char *svf_command_buffer = NULL;
 static int svf_command_buffer_size = 0;
 static int svf_line_number = 1;
 
-static jtag_tap_t *tap = NULL;
+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;
@@ -228,15 +224,7 @@ static int svf_buffer_index = 0, svf_buffer_size = 0;
 static int svf_quiet = 0;
 
 
-int svf_register_commands(struct command_context_s *cmd_ctx)
-{
-       register_command(cmd_ctx, NULL, "svf", handle_svf_command,
-               COMMAND_EXEC, "run svf <file>");
-
-       return ERROR_OK;
-}
-
-void svf_free_xxd_para(svf_xxr_para_t *para)
+static void svf_free_xxd_para(struct svf_xxr_para *para)
 {
        if (NULL != para)
        {
@@ -263,7 +251,7 @@ void svf_free_xxd_para(svf_xxr_para_t *para)
        }
 }
 
-unsigned svf_get_mask_u32(int bitlen)
+static unsigned svf_get_mask_u32(int bitlen)
 {
        uint32_t bitmask;
 
@@ -283,34 +271,6 @@ unsigned svf_get_mask_u32(int bitlen)
        return bitmask;
 }
 
-static const char* tap_state_svf_name(tap_state_t state)
-{
-       const char* ret;
-
-       switch (state)
-       {
-       case TAP_RESET:         ret = "RESET";          break;
-       case TAP_IDLE:          ret = "IDLE";           break;
-       case TAP_DRSELECT:      ret = "DRSELECT";       break;
-       case TAP_DRCAPTURE: ret = "DRCAPTURE";  break;
-       case TAP_DRSHIFT:       ret = "DRSHIFT";        break;
-       case TAP_DREXIT1:       ret = "DREXIT1";        break;
-       case TAP_DRPAUSE:       ret = "DRPAUSE";        break;
-       case TAP_DREXIT2:       ret = "DREXIT2";        break;
-       case TAP_DRUPDATE:      ret = "DRUPDATE";       break;
-       case TAP_IRSELECT:      ret = "IRSELECT";       break;
-       case TAP_IRCAPTURE: ret = "IRCAPTURE";  break;
-       case TAP_IRSHIFT:       ret = "IRSHIFT";        break;
-       case TAP_IREXIT1:       ret = "IREXIT1";        break;
-       case TAP_IRPAUSE:       ret = "IRPAUSE";        break;
-       case TAP_IREXIT2:       ret = "IREXIT2";        break;
-       case TAP_IRUPDATE:      ret = "IRUPDATE";       break;
-       default:                        ret = "???";            break;
-       }
-
-       return ret;
-}
-
 int svf_add_statemove(tap_state_t state_to)
 {
        tap_state_t state_from = cmd_queue_cur_state;
@@ -322,7 +282,7 @@ int svf_add_statemove(tap_state_t state_to)
                return ERROR_OK;
        }
 
-       for (index = 0; index < dimof(svf_statemoves); index++)
+       for (index = 0; index < ARRAY_SIZE(svf_statemoves); index++)
        {
                if ((svf_statemoves[index].from == state_from)
                        && (svf_statemoves[index].to == state_to))
@@ -337,49 +297,49 @@ int svf_add_statemove(tap_state_t state_to)
                        return ERROR_OK;
                }
        }
-       LOG_ERROR("SVF: can not move to %s", tap_state_svf_name(state_to));
+       LOG_ERROR("SVF: can not move to %s", tap_state_name(state_to));
        return ERROR_FAIL;
 }
 
-static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(handle_svf_command)
 {
 #define SVF_NUM_OF_OPTIONS                     1
-       int command_num = 0, i;
+       int command_num = 0;
        int ret = ERROR_OK;
        long long time_ago;
 
-       if ((argc < 1) || (argc > (1 + SVF_NUM_OF_OPTIONS)))
+       if ((CMD_ARGC < 1) || (CMD_ARGC > (1 + SVF_NUM_OF_OPTIONS)))
        {
-               command_print(cmd_ctx, "usage: svf <file> [quiet]");
+               command_print(CMD_CTX, "usage: svf <file> [quiet]");
                return ERROR_FAIL;
        }
 
        // parse variant
        svf_quiet = 0;
-       for (i = 1; i < argc; i++)
+       for (unsigned i = 1; i < CMD_ARGC; i++)
        {
-               if (!strcmp(args[i], "quiet"))
+               if (!strcmp(CMD_ARGV[i], "quiet"))
                {
                        svf_quiet = 1;
                }
                else
                {
-                       LOG_ERROR("unknown variant for svf: %s", args[i]);
+                       LOG_ERROR("unknown variant for svf: %s", CMD_ARGV[i]);
 
                        // no need to free anything now
                        return ERROR_FAIL;
                }
        }
 
-       if ((svf_fd = open(args[0], O_RDONLY)) < 0)
+       if ((svf_fd = open(CMD_ARGV[0], O_RDONLY)) < 0)
        {
-               command_print(cmd_ctx, "file \"%s\" not found", args[0]);
+               command_print(CMD_CTX, "file \"%s\" not found", CMD_ARGV[0]);
 
                // no need to free anything now
                return ERROR_FAIL;
        }
 
-       LOG_USER("svf processing file: \"%s\"", args[0]);
+       LOG_USER("svf processing file: \"%s\"", CMD_ARGV[0]);
 
        // get time
        time_ago = timeval_ms();
@@ -389,7 +349,7 @@ static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char
        svf_command_buffer_size = 0;
 
        svf_check_tdo_para_index = 0;
-       svf_check_tdo_para = malloc(sizeof(svf_check_tdo_para_t) * SVF_CHECK_TDO_PARA_SIZE);
+       svf_check_tdo_para = malloc(sizeof(struct svf_check_tdo_para) * SVF_CHECK_TDO_PARA_SIZE);
        if (NULL == svf_check_tdo_para)
        {
                LOG_ERROR("not enough memory");
@@ -426,17 +386,13 @@ static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char
        svf_buffer_size = 2 * SVF_MAX_BUFFER_SIZE_TO_COMMIT;
 
        memcpy(&svf_para, &svf_para_init, sizeof(svf_para));
-       for (i = 0; i < (int)dimof(svf_tap_state_name); i++)
-       {
-               svf_tap_state_name[i] = (char *)tap_state_svf_name(i);
-       }
 
        // TAP_RESET
        jtag_add_tlr();
 
        while (ERROR_OK == svf_read_command_from_file(svf_fd))
        {
-               if (ERROR_OK != svf_run_command(cmd_ctx, svf_command_buffer))
+               if (ERROR_OK != svf_run_command(CMD_CTX, svf_command_buffer))
                {
                        LOG_ERROR("fail to run command at line %d", svf_line_number);
                        ret = ERROR_FAIL;
@@ -454,7 +410,7 @@ static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char
        }
 
        // print time
-       command_print(cmd_ctx, "%lld ms used", timeval_ms() - time_ago);
+       command_print(CMD_CTX, "%lld ms used", timeval_ms() - time_ago);
 
 free_all:
 
@@ -501,11 +457,11 @@ free_all:
 
        if (ERROR_OK == ret)
        {
-               command_print(cmd_ctx, "svf file programmed successfully for %d commands", command_num);
+               command_print(CMD_CTX, "svf file programmed successfully for %d commands", command_num);
        }
        else
        {
-               command_print(cmd_ctx, "svf file programmed failed");
+               command_print(CMD_CTX, "svf file programmed failed");
        }
 
        return ret;
@@ -625,11 +581,6 @@ bool svf_tap_state_is_stable(tap_state_t state)
                        || (TAP_DRPAUSE == state) || (TAP_IRPAUSE == state);
 }
 
-static int svf_tap_state_is_valid(tap_state_t state)
-{
-       return state >= 0 && state < TAP_NUM_STATES;
-}
-
 static int svf_find_string_in_array(char *str, char **strs, int num_of_element)
 {
        int i;
@@ -720,10 +671,14 @@ 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')
+               str_len--;
+
        // check valid
-       if (str_len > 0 || (ch & ~((1 << (4 - (bit_len % 4))) - 1)) != 0)
+       if (str_len > 0 || (ch & ~((2 << ((bit_len - 1) % 4)) - 1)) != 0)
        {
-               LOG_ERROR("value execede length");
+               LOG_ERROR("value execeeds length");
                return ERROR_FAIL;
        }
 
@@ -795,7 +750,7 @@ static int svf_execute_tap(void)
        return ERROR_OK;
 }
 
-static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
+static int svf_run_command(struct command_context *cmd_ctx, char *cmd_str)
 {
        char *argus[256], command;
        int num_of_argu = 0, i;
@@ -807,9 +762,9 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
        int run_count;
        float min_time, max_time;
        // for XXR
-       svf_xxr_para_t *xxr_para_tmp;
+       struct svf_xxr_para *xxr_para_tmp;
        uint8_t **pbuffer_tmp;
-       scan_field_t field;
+       struct scan_field field;
        // for STATE
        tap_state_t *path = NULL, state;
 
@@ -823,7 +778,12 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                return ERROR_FAIL;
        }
 
-       command = svf_find_string_in_array(argus[0], (char **)svf_command_name, dimof(svf_command_name));
+       /* NOTE: we're a bit loose here, because we ignore case in
+        * TAP state names (instead of insisting on uppercase).
+        */
+
+       command = svf_find_string_in_array(argus[0],
+                       (char **)svf_command_name, ARRAY_SIZE(svf_command_name));
        switch (command)
        {
        case ENDDR:
@@ -833,23 +793,28 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                        LOG_ERROR("invalid parameter of %s", argus[0]);
                        return ERROR_FAIL;
                }
-               i_tmp = svf_find_string_in_array(argus[1], (char **)svf_tap_state_name, dimof(svf_tap_state_name));
+
+               i_tmp = tap_state_by_name(argus[1]);
+
                if (svf_tap_state_is_stable(i_tmp))
                {
                        if (command == ENDIR)
                        {
                                svf_para.ir_end_state = i_tmp;
-                               LOG_DEBUG("\tir_end_state = %s", svf_tap_state_name[svf_para.ir_end_state]);
+                               LOG_DEBUG("\tIR end_state = %s",
+                                               tap_state_name(i_tmp));
                        }
                        else
                        {
                                svf_para.dr_end_state = i_tmp;
-                               LOG_DEBUG("\tdr_end_state = %s", svf_tap_state_name[svf_para.dr_end_state]);
+                               LOG_DEBUG("\tDR end_state = %s",
+                                               tap_state_name(i_tmp));
                        }
                }
                else
                {
-                       LOG_ERROR("%s is not valid state", argus[1]);
+                       LOG_ERROR("%s: %s is not a stable state",
+                                       argus[0], argus[1]);
                        return ERROR_FAIL;
                }
                break;
@@ -1203,25 +1168,31 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                min_time = 0;
                max_time = 0;
                i = 1;
+
                // run_state
-               i_tmp = svf_find_string_in_array(argus[i], (char **)svf_tap_state_name, dimof(svf_tap_state_name));
-               if (svf_tap_state_is_valid(i_tmp))
+               i_tmp = tap_state_by_name(argus[i]);
+               if (i_tmp != TAP_INVALID)
                {
                        if (svf_tap_state_is_stable(i_tmp))
                        {
                                svf_para.runtest_run_state = i_tmp;
 
-                               // When a run_state is specified, the new  run_state becomes the default end_state
+                               /* When a run_state is specified, the new
+                                * run_state becomes the default end_state.
+                                */
                                svf_para.runtest_end_state = i_tmp;
-                               LOG_DEBUG("\trun_state = %s", svf_tap_state_name[svf_para.runtest_run_state]);
+                               LOG_DEBUG("\trun_state = %s",
+                                               tap_state_name(i_tmp));
                                i++;
                        }
                        else
                        {
-                               LOG_ERROR("%s is not valid state", svf_tap_state_name[i_tmp]);
+                               LOG_ERROR("%s: %s is not a stable state",
+                                       argus[0], tap_state_name(i_tmp));
                                return ERROR_FAIL;
                        }
                }
+
                // run_count run_clk
                if (((i + 2) <= num_of_argu) && strcmp(argus[i + 1], "SEC"))
                {
@@ -1255,15 +1226,18 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                // ENDSTATE end_state
                if (((i + 2) <= num_of_argu) && !strcmp(argus[i], "ENDSTATE"))
                {
-                       i_tmp = svf_find_string_in_array(argus[i + 1], (char **)svf_tap_state_name, dimof(svf_tap_state_name));
+                       i_tmp = tap_state_by_name(argus[i + 1]);
+
                        if (svf_tap_state_is_stable(i_tmp))
                        {
                                svf_para.runtest_end_state = i_tmp;
-                               LOG_DEBUG("\tend_state = %s", svf_tap_state_name[svf_para.runtest_end_state]);
+                               LOG_DEBUG("\tend_state = %s",
+                                       tap_state_name(i_tmp));
                        }
                        else
                        {
-                               LOG_ERROR("%s is not valid state", svf_tap_state_name[i_tmp]);
+                               LOG_ERROR("%s: %s is not a stable state",
+                                       argus[0], tap_state_name(i_tmp));
                                return ERROR_FAIL;
                        }
                        i += 2;
@@ -1301,8 +1275,8 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
 #else
                                if (svf_para.runtest_run_state != TAP_IDLE)
                                {
-                                       // RUNTEST can only executed in TAP_IDLE
-                                       LOG_ERROR("cannot runtest in %s state", svf_tap_state_name[svf_para.runtest_run_state]);
+                                       LOG_ERROR("cannot runtest in %s state",
+                                               tap_state_name(svf_para.runtest_run_state));
                                        return ERROR_FAIL;
                                }
 
@@ -1333,13 +1307,14 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                                return ERROR_FAIL;
                        }
                        num_of_argu--;          // num of path
-                       i_tmp = 1;                      // path is from patameter 1
-                       for (i = 0; i < num_of_argu; i++)
+                       i_tmp = 1;              /* path is from parameter 1 */
+                       for (i = 0; i < num_of_argu; i++, i_tmp++)
                        {
-                               path[i] = svf_find_string_in_array(argus[i_tmp++], (char **)svf_tap_state_name, dimof(svf_tap_state_name));
-                               if (!svf_tap_state_is_valid(path[i]))
+                               path[i] = tap_state_by_name(argus[i_tmp]);
+                               if (path[i] == TAP_INVALID)
                                {
-                                       LOG_ERROR("%s is not valid state", svf_tap_state_name[path[i]]);
+                                       LOG_ERROR("%s: %s is not a valid state",
+                                               argus[0], argus[i_tmp]);
                                        free(path);
                                        return ERROR_FAIL;
                                }
@@ -1362,13 +1337,15 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                                if (svf_tap_state_is_stable(path[num_of_argu - 1]))
                                {
                                        // last state MUST be stable state
-                                       // TODO: call path_move
                                        jtag_add_pathmove(num_of_argu, path);
-                                       LOG_DEBUG("\tmove to %s by path_move", svf_tap_state_name[path[num_of_argu - 1]]);
+                                       LOG_DEBUG("\tmove to %s by path_move",
+                                               tap_state_name(path[num_of_argu - 1]));
                                }
                                else
                                {
-                                       LOG_ERROR("%s is not valid state", svf_tap_state_name[path[num_of_argu - 1]]);
+                                       LOG_ERROR("%s: %s is not a stable state",
+                                               argus[0],
+                                               tap_state_name(path[num_of_argu - 1]));
                                        free(path);
                                        return ERROR_FAIL;
                                }
@@ -1383,17 +1360,18 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                else
                {
                        // STATE stable_state
-                       state = svf_find_string_in_array(argus[1], (char **)svf_tap_state_name, dimof(svf_tap_state_name));
+                       state = tap_state_by_name(argus[1]);
                        if (svf_tap_state_is_stable(state))
                        {
                                LOG_DEBUG("\tmove to %s by svf_add_statemove",
-                                               svf_tap_state_name[state]);
+                                               tap_state_name(state));
                                /* FIXME handle statemove failures */
                                svf_add_statemove(state);
                        }
                        else
                        {
-                               LOG_ERROR("%s is not valid state", svf_tap_state_name[state]);
+                               LOG_ERROR("%s: %s is not a stable state",
+                                       argus[0], tap_state_name(state));
                                return ERROR_FAIL;
                        }
                }
@@ -1411,7 +1389,9 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
                        {
                                return ERROR_FAIL;
                        }
-                       i_tmp = svf_find_string_in_array(argus[1], (char **)svf_trst_mode_name, dimof(svf_trst_mode_name));
+                       i_tmp = svf_find_string_in_array(argus[1],
+                                       (char **)svf_trst_mode_name,
+                                       ARRAY_SIZE(svf_trst_mode_name));
                        switch (i_tmp)
                        {
                        case TRST_ON:
@@ -1479,3 +1459,19 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str)
 
        return ERROR_OK;
 }
+
+static const struct command_registration svf_command_handlers[] = {
+       {
+               .name = "svf",
+               .handler = &handle_svf_command,
+               .mode = COMMAND_EXEC,
+               .help = "Runs a SVF file.",
+               .usage = "<file>",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+int svf_register_commands(struct command_context *cmd_ctx)
+{
+       return register_commands(cmd_ctx, NULL, svf_command_handlers);
+}