X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fsvf%2Fsvf.c;h=068a8730d0c94f9dc1243c87a4ce17b0daac5861;hb=cf04b595177b284484c3a9fafa03408237749f52;hp=1267755b9b2d8d024c4c72339b8386b1640990a0;hpb=204a360602b175e320be26a914209b13e0e53b60;p=openocd.git diff --git a/src/svf/svf.c b/src/svf/svf.c index 1267755b9b..068a8730d0 100644 --- a/src/svf/svf.c +++ b/src/svf/svf.c @@ -90,6 +90,38 @@ const char *svf_trst_mode_name[4] = "ABSENT" }; +typedef struct +{ + tap_state_t from; + tap_state_t to; + u32 num_of_moves; + tap_state_t paths[8]; +}svf_statemove_t; + +svf_statemove_t svf_statemoves[] = +{ + // from to num_of_moves, paths[8] +// {TAP_RESET, TAP_RESET, 1, {TAP_RESET}}, + {TAP_RESET, TAP_IDLE, 2, {TAP_RESET, TAP_IDLE}}, + {TAP_RESET, TAP_DRPAUSE, 6, {TAP_RESET, TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DREXIT1, TAP_DRPAUSE}}, + {TAP_RESET, TAP_IRPAUSE, 7, {TAP_RESET, TAP_IDLE, TAP_DRSELECT, TAP_IRSELECT, TAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE}}, + +// {TAP_IDLE, TAP_RESET, 4, {TAP_IDLE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, + {TAP_IDLE, TAP_IDLE, 1, {TAP_IDLE}}, + {TAP_IDLE, TAP_DRPAUSE, 5, {TAP_IDLE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DREXIT1, TAP_DRPAUSE}}, + {TAP_IDLE, TAP_IRPAUSE, 6, {TAP_IDLE, TAP_DRSELECT, TAP_IRSELECT, TAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE}}, + +// {TAP_DRPAUSE, TAP_RESET, 6, {TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, + {TAP_DRPAUSE, TAP_IDLE, 4, {TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE, TAP_IDLE}}, + {TAP_DRPAUSE, TAP_DRPAUSE, 7, {TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DREXIT1, TAP_DRPAUSE}}, + {TAP_DRPAUSE, TAP_IRPAUSE, 8, {TAP_DRPAUSE, TAP_DREXIT2, TAP_DRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_IRCAPTURE, TAP_IREXIT1, TAP_IRPAUSE}}, + +// {TAP_IRPAUSE, TAP_RESET, 6, {TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_IRSELECT, TAP_RESET}}, + {TAP_IRPAUSE, TAP_IDLE, 4, {TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE, TAP_IDLE}}, + {TAP_IRPAUSE, TAP_DRPAUSE, 7, {TAP_IRPAUSE, TAP_IREXIT2, TAP_IRUPDATE, TAP_DRSELECT, TAP_DRCAPTURE, TAP_DREXIT1, TAP_DRPAUSE}}, + {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) @@ -175,7 +207,6 @@ static int svf_command_buffer_size = 0; static int svf_line_number = 1; static jtag_tap_t *tap = NULL; -static tap_state_t last_state = TAP_RESET; #define SVF_MAX_BUFFER_SIZE_TO_COMMIT (4 * 1024) static u8 *svf_tdi_buffer = NULL, *svf_tdo_buffer = NULL, *svf_mask_buffer = NULL; @@ -218,6 +249,86 @@ void svf_free_xxd_para(svf_xxr_para_t *para) } } +unsigned svf_get_mask_u32(int bitlen) +{ + u32 bitmask; + + if (bitlen < 0) + { + bitmask = 0; + } + else if (bitlen >= 32) + { + bitmask = 0xFFFFFFFF; + } + else + { + bitmask = (1 << bitlen) - 1; + } + + 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) +{ + tap_state_t state_from = cmd_queue_cur_state; + u8 index; + + for (index = 0; index < dimof(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); + } + } + else + { + if (svf_statemoves[index].num_of_moves > 0) + { + 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)); + return ERROR_FAIL; +} + static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { #define SVF_NUM_OF_OPTIONS 1 @@ -305,8 +416,9 @@ static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char 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_name(i); + svf_tap_state_name[i] = (char *)tap_state_svf_name(i); } + // TAP_RESET jtag_add_tlr(); @@ -330,7 +442,7 @@ static int handle_svf_command(struct command_context_s *cmd_ctx, char *cmd, char } // print time - command_print(cmd_ctx, "%d ms used", timeval_ms() - time_ago); + command_print(cmd_ctx, "%lld ms used", timeval_ms() - time_ago); free_all: @@ -628,32 +740,29 @@ static int svf_copy_hexstring_to_binary(char *str, u8 **bin, int orig_bit_len, i static int svf_check_tdo(void) { - int i, j, byte_len, index; + int i, len, index; for (i = 0; i < svf_check_tdo_para_index; i++) { - if (svf_check_tdo_para[i].enabled) + index = svf_check_tdo_para[i].buffer_offset; + len = svf_check_tdo_para[i].bit_len; + if ((svf_check_tdo_para[i].enabled) + && buf_cmp_mask(&svf_tdi_buffer[index], &svf_tdo_buffer[index], &svf_mask_buffer[index], len)) { - byte_len = (svf_check_tdo_para[i].bit_len + 7) >> 3; - index = svf_check_tdo_para[i].buffer_offset; - for (j = 0; j < byte_len; j++) - { - if ((svf_tdi_buffer[index + j] & svf_mask_buffer[index + j]) != svf_tdo_buffer[index + j]) - { - unsigned bitmask = (1 << svf_check_tdo_para[i].bit_len) - 1; - unsigned received, expected, tapmask; - memcpy(&received, svf_tdi_buffer + index, sizeof(unsigned)); - memcpy(&expected, svf_tdo_buffer + index, sizeof(unsigned)); - memcpy(&tapmask, svf_mask_buffer + index, sizeof(unsigned)); - LOG_ERROR("tdo check error at line %d, " - "read = 0x%X, want = 0x%X, mask = 0x%X", - svf_check_tdo_para[i].line_num, - received & bitmask, - expected & bitmask, - tapmask & bitmask); - return ERROR_FAIL; - } - } + unsigned bitmask; + unsigned received, expected, tapmask; + bitmask = svf_get_mask_u32(svf_check_tdo_para[i].bit_len); + + memcpy(&received, svf_tdi_buffer + index, sizeof(unsigned)); + memcpy(&expected, svf_tdo_buffer + index, sizeof(unsigned)); + memcpy(&tapmask, svf_mask_buffer + index, sizeof(unsigned)); + LOG_ERROR("tdo check error at line %d", + svf_check_tdo_para[i].line_num); + LOG_ERROR("read = 0x%X, want = 0x%X, mask = 0x%X", + received & bitmask, + expected & bitmask, + tapmask & bitmask); + return ERROR_FAIL; } } svf_check_tdo_para_index = 0; @@ -694,10 +803,6 @@ static int svf_execute_tap(void) return ERROR_OK; } -// not good to use this -extern void* cmd_queue_alloc(size_t size); -extern void jtag_queue_command(jtag_command_t * cmd); - static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) { char *argus[256], command; @@ -859,7 +964,7 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) LOG_ERROR("fail to parse hex value"); return ERROR_FAIL; } - LOG_DEBUG("\t%s = 0x%X", argus[i], (**(int**)pbuffer_tmp) & ((1 << (xxr_para_tmp->len)) - 1)); + LOG_DEBUG("\t%s = 0x%X", argus[i], (**(int**)pbuffer_tmp) & svf_get_mask_u32(xxr_para_tmp->len)); } // If a command changes the length of the last scan of the same type and the MASK parameter is absent, // the mask pattern used is all cares @@ -873,6 +978,27 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) } buf_set_ones(xxr_para_tmp->mask, xxr_para_tmp->len); } + // If TDO is absent, no comparison is needed, set the mask to 0 + if (!(xxr_para_tmp->data_mask & XXR_TDO)) + { + if (NULL == xxr_para_tmp->tdo) + { + if (ERROR_OK != svf_adjust_array_length(&xxr_para_tmp->tdo, i_tmp, xxr_para_tmp->len)) + { + LOG_ERROR("fail to adjust length of array"); + return ERROR_FAIL; + } + } + if (NULL == xxr_para_tmp->mask) + { + if (ERROR_OK != svf_adjust_array_length(&xxr_para_tmp->mask, i_tmp, xxr_para_tmp->len)) + { + LOG_ERROR("fail to adjust length of array"); + return ERROR_FAIL; + } + } + memset(xxr_para_tmp->mask, 0, (xxr_para_tmp->len + 7) >> 3); + } // do scan if necessary if (SDR == command) { @@ -964,16 +1090,10 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) 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]; - - - - jtag_add_plain_dr_scan(1, &field, svf_para.dr_end_state); svf_buffer_index += (i + 7) >> 3; - last_state = svf_para.dr_end_state; } else if (SIR == command) { @@ -1065,16 +1185,10 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) 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]; - - - - jtag_add_plain_ir_scan(1, &field, svf_para.ir_end_state); svf_buffer_index += (i + 7) >> 3; - last_state = svf_para.ir_end_state; } break; case PIO: @@ -1174,35 +1288,19 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) // TODO: do runtest #if 1 // enter into run_state if necessary - if (last_state != svf_para.runtest_run_state) + if (cmd_queue_cur_state != svf_para.runtest_run_state) { - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_STATEMOVE; - cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); - cmd->cmd.statemove->end_state = svf_para.runtest_run_state; - - cmd_queue_end_state = cmd_queue_cur_state = cmd->cmd.statemove->end_state; + svf_add_statemove(svf_para.runtest_run_state); } // call jtag_add_clocks jtag_add_clocks(run_count); + // move to end_state if necessary if (svf_para.runtest_end_state != svf_para.runtest_run_state) { - // move to end_state - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - cmd->type = JTAG_STATEMOVE; - cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); - cmd->cmd.statemove->end_state = svf_para.runtest_end_state; - - cmd_queue_end_state = cmd_queue_cur_state = cmd->cmd.statemove->end_state; + svf_add_statemove(svf_para.runtest_end_state); } - last_state = svf_para.runtest_end_state; #else if (svf_para.runtest_run_state != TAP_IDLE) { @@ -1266,7 +1364,6 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) // last state MUST be stable state // TODO: call path_move jtag_add_pathmove(num_of_argu, path); - last_state = path[num_of_argu - 1]; LOG_DEBUG("\tmove to %s by path_move", svf_tap_state_name[path[num_of_argu - 1]]); } else @@ -1289,18 +1386,9 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) if (svf_tap_state_is_stable(state)) { // TODO: move to state - jtag_command_t * cmd = cmd_queue_alloc(sizeof(jtag_command_t)); - - jtag_queue_command(cmd); - - cmd->type = JTAG_STATEMOVE; - cmd->cmd.statemove = cmd_queue_alloc(sizeof(statemove_command_t)); - cmd->cmd.statemove->end_state = state; - - cmd_queue_end_state = cmd_queue_cur_state = cmd->cmd.statemove->end_state; - last_state = state; - - LOG_DEBUG("\tmove to %s by state_move", svf_tap_state_name[state]); + svf_add_statemove(state); + + LOG_DEBUG("\tmove to %s by svf_add_statemove", svf_tap_state_name[state]); } else { @@ -1326,7 +1414,6 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) switch (i_tmp) { case TRST_ON: - last_state = TAP_RESET; jtag_add_reset(1, 0); break; case TRST_Z: @@ -1372,7 +1459,7 @@ static int svf_run_command(struct command_context_s *cmd_ctx, char *cmd_str) int read_value; memcpy(&read_value, svf_tdi_buffer, sizeof(int)); // in debug mode, data is from index 0 - int read_mask = (1 << (svf_check_tdo_para[0].bit_len)) - 1; + int read_mask = svf_get_mask_u32(svf_check_tdo_para[0].bit_len); LOG_DEBUG("\tTDO read = 0x%X", read_value & read_mask); } }