X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fsvf%2Fsvf.c;h=348145d98e2fe51549d7b71cf4279de8f112d4ed;hp=5b96971c1fd7fd597332d5796335d66c13a9c3ec;hb=d0809ac060b35a04e7f0bceb96e1868663bd18df;hpb=3cc147efd95502bd4d873596b60c3c6d8e92ab71 diff --git a/src/svf/svf.c b/src/svf/svf.c index 5b96971c1f..348145d98e 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -31,8 +31,8 @@ #include "config.h" #endif -#include "svf.h" #include "jtag.h" +#include "svf.h" #include "time_support.h" @@ -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", @@ -136,7 +136,6 @@ 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) @@ -169,8 +168,8 @@ typedef struct svf_xxr_para_t sdr_para; }svf_para_t; -svf_para_t svf_para; -const svf_para_t svf_para_init = +static svf_para_t svf_para; +static const svf_para_t 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, @@ -207,20 +206,17 @@ typedef struct static svf_check_tdo_para_t *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_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 "); - - return ERROR_OK; -} - -void svf_free_xxd_para(svf_xxr_para_t *para) +static void svf_free_xxd_para(svf_xxr_para_t *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,70 +271,40 @@ 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; -} - -static int svf_add_statemove(tap_state_t state_to) +int svf_add_statemove(tap_state_t state_to) { tap_state_t state_from = cmd_queue_cur_state; uint8_t index; - for (index = 0; index < dimof(svf_statemoves); index++) + /* when resetting, be paranoid and ignore current state */ + if (state_to == TAP_RESET) { + jtag_add_tlr(); + return ERROR_OK; + } + + for (index = 0; index < DIM(svf_statemoves); index++) { if ((svf_statemoves[index].from == state_from) && (svf_statemoves[index].to == state_to)) { - if (TAP_RESET == state_from) - { - jtag_add_tlr(); - if (svf_statemoves[index].num_of_moves > 1) - { - jtag_add_pathmove(svf_statemoves[index].num_of_moves - 1, svf_statemoves[index].paths + 1); - } - } + /* recorded path includes current state ... avoid extra TCKs! */ + if (svf_statemoves[index].num_of_moves > 1) + jtag_add_pathmove(svf_statemoves[index].num_of_moves - 1, + svf_statemoves[index].paths + 1); else - { - if (svf_statemoves[index].num_of_moves > 0) - { - jtag_add_pathmove(svf_statemoves[index].num_of_moves, svf_statemoves[index].paths); - } - } + jtag_add_pathmove(svf_statemoves[index].num_of_moves, + svf_statemoves[index].paths); return ERROR_OK; } } - LOG_ERROR("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; @@ -358,7 +316,7 @@ static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char // parse variant svf_quiet = 0; - for (i = 1; i < argc; i++) + for (unsigned i = 1; i < argc; i++) { if (!strcmp(args[i], "quiet")) { @@ -428,10 +386,6 @@ 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(); @@ -621,14 +575,10 @@ static int svf_parse_cmd_string(char *str, int len, char **argus, int *num_of_ar return ERROR_OK; } -static int svf_tap_state_is_stable(tap_state_t state) +bool svf_tap_state_is_stable(tap_state_t state) { - return ((TAP_RESET == state) || (TAP_IDLE == 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; + return (TAP_RESET == state) || (TAP_IDLE == state) + || (TAP_DRPAUSE == state) || (TAP_IRPAUSE == state); } static int svf_find_string_in_array(char *str, char **strs, int num_of_element) @@ -721,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; } @@ -810,7 +764,7 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) // for XXR svf_xxr_para_t *xxr_para_tmp; uint8_t **pbuffer_tmp; - scan_field_t field; + struct scan_field field; // for STATE tap_state_t *path = NULL, state; @@ -824,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, DIM(svf_command_name)); switch (command) { case ENDDR: @@ -834,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; @@ -1084,6 +1048,7 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) 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); svf_buffer_index += (i + 7) >> 3; @@ -1179,6 +1144,7 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) 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); svf_buffer_index += (i + 7) >> 3; @@ -1202,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")) { @@ -1254,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; @@ -1280,10 +1255,13 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) // run_state and end_state is checked to be stable state // TODO: do runtest #if 1 + /* FIXME handle statemove failures */ + int retval; + // enter into run_state if necessary if (cmd_queue_cur_state != svf_para.runtest_run_state) { - svf_add_statemove(svf_para.runtest_run_state); + retval = svf_add_statemove(svf_para.runtest_run_state); } // call jtag_add_clocks @@ -1292,13 +1270,13 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) // move to end_state if necessary if (svf_para.runtest_end_state != svf_para.runtest_run_state) { - svf_add_statemove(svf_para.runtest_end_state); + retval = svf_add_statemove(svf_para.runtest_end_state); } #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; } @@ -1329,18 +1307,21 @@ 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; } + /* OpenOCD refuses paths containing TAP_RESET */ if (TAP_RESET == path[i]) { + /* FIXME last state MUST be stable! */ if (i > 0) { jtag_add_pathmove(i, path); @@ -1356,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; } @@ -1377,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)) { - // TODO: move to state + LOG_DEBUG("\tmove to %s by svf_add_statemove", + tap_state_name(state)); + /* FIXME handle statemove failures */ svf_add_statemove(state); - - LOG_DEBUG("\tmove to %s by svf_add_statemove", svf_tap_state_name[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; } } @@ -1405,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, + DIM(svf_trst_mode_name)); switch (i_tmp) { case TRST_ON: @@ -1473,3 +1459,12 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) return ERROR_OK; } + +int svf_register_commands(struct command_context_s *cmd_ctx) +{ + register_command(cmd_ctx, NULL, "svf", + &handle_svf_command, COMMAND_EXEC, + "run svf "); + + return ERROR_OK; +}