int print_sol(t_env *env, t_sol *sol) { t_grp *grp; int nb_pth; t_ant *ant; print_cmd(E_CMD); ant = NULL; S_TURN = S_GRP->P_LEN; if (E_ANTS) ft_putchar('\n'); while (E_ANTS > 0) { grp = S_GRP; nb_pth = 1; while (grp && E_ANTS >= (G_PTH->len - S_GRP->P_LEN + 1) / nb_pth++) { if (send_ant(env, &ant, grp) != EXIT_SUCCESS) return (EXIT_FAILURE); grp = G_NXT; } E_ANTS -= nb_pth - 1; print_turn(env); } while (print_turn(env)) (void)ant; return (EXIT_SUCCESS); }
/***************************************************************************** * int bsdl_emit_ports( jtag_ctrl_t *jc ) * * Adds the specified port name as a signal via shell command * signal <pin> * The port name is taken from the port_desc structure that was filled in * previously by rule Scalar_or_Vector. This way, the function can build * vectored ports as well. * Keep in mind that multiple names can be defined by one port specification * (there's a names_list in port_desc). * * Parameters * jc : jtag control structure * * Returns * 1 -> all ok * 0 -> error occured ****************************************************************************/ static int bsdl_emit_ports(jtag_ctrl_t *jc) { port_desc_t *pd = jc->port_desc; struct string_elem *name; size_t str_len, name_len; char *port_string; int idx; int result = 0; char *cmd[] = {"signal", NULL, NULL}; while (pd) { name = pd->names_list; while (name) { /* handle indexed port name: - names of scalar ports are simply copied from the port_desc structure to the final string that goes into ci - names of vectored ports are expanded with their decimal index as collected earlier in rule Scalar_or_Vector */ name_len = strlen( name->string ); str_len = name_len + 1 + 10 + 1 + 1; if ((port_string = (char *)malloc( str_len )) != NULL) { cmd[1] = port_string; for (idx = pd->low_idx; idx <= pd->high_idx; idx++) { if (pd->is_vector) snprintf( port_string, str_len-1, "%s(%d)", name->string, idx ); else strncpy( port_string, name->string, str_len-1 ); port_string[str_len-1] = '\0'; if (jc->proc_mode & BSDL_MODE_INSTR_EXEC) cmd_run( jc->chain, cmd ); if (jc->proc_mode & BSDL_MODE_INSTR_PRINT) print_cmd( cmd ); } free( port_string ); result = 1; } else bsdl_msg( jc->proc_mode, BSDL_MSG_FATAL, _("Out of memory, %s line %i\n"), __FILE__, __LINE__ ); name = name->next; } pd = pd->next; } return result; }
int send_command(usb_dev_handle *handle, cmdstruct command ) { if (command.numCmds == 0) { printf( "send_command: Empty command provided! Not sending anything...\n"); return 0; } int stat; stat = usb_detach_kernel_driver_np(handle, 0); if ((stat < 0 ) || verbose_flag) perror("Detach kernel driver"); stat = usb_claim_interface( handle, 0 ); if ( (stat < 0) || verbose_flag) perror("Claiming USB interface"); int transferred = 0; // send all command strings provided in command int cmdCount; for (cmdCount=0; cmdCount < command.numCmds; cmdCount++) { if (verbose_flag) { char raw_string[255]; print_cmd(raw_string, command.cmds[cmdCount]); printf("\tSending string: \"%s\"\n", raw_string); } stat = usb_interrupt_write( handle, 1, (const char*)command.cmds[cmdCount], sizeof( command.cmds[cmdCount] ), TRANSFER_WAIT_TIMEOUT_MS ); transferred = (stat>0)?stat:0; if ( (stat < 0) || verbose_flag) perror("Sending USB command"); } /* In case the command just sent caused the device to switch from restricted mode to native mode * the following two commands will fail due to invalid device handle (because the device changed * its pid on the USB bus). * So it is not possible anymore to release the interface and re-attach kernel driver. * I am not sure if this produces a memory leak within libusb, but i do not think there is another * solution possible... */ stat = usb_release_interface(handle, 0 ); /*FIXME: if (stat != usb_ERROR_NO_DEVICE) { // silently ignore "No such device" error due to reasons explained above. if ( (stat < 0) || verbose_flag) { perror("Releasing USB interface."); } } */ //FIXME: Not portable?! stat = usb_attach_kernel_driver_np( handle, 0); /*FIXME: if (stat != usb_ERROR_NO_DEVICE) { // silently ignore "No such device" error due to reasons explained above. if ( (stat < 0) || verbose_flag) { perror("Reattaching kernel driver"); } } */ return 0; }
/***************************************************************************** * int bsdl_set_instruction_length( jtag_ctrl_t *jc ) * * Sets the specified length of the instruction register via shell command * instruction length <len> * * Parameters * jc : jtag control structure * * Returns * 1 -> all ok * 0 -> error occured ****************************************************************************/ static int bsdl_set_instruction_length( jtag_ctrl_t *jc ) { char lenstring[6]; char *cmd[] = {"instruction", "length", lenstring, NULL}; snprintf( lenstring, 6, "%i", jc->instr_len ); lenstring[5] = '\0'; if (jc->proc_mode & BSDL_MODE_INSTR_EXEC) cmd_run( jc->chain, cmd ); if (jc->proc_mode & BSDL_MODE_INSTR_PRINT) print_cmd( cmd ); return 1; }
/***************************************************************************** * int create_register( jtag_ctrl_t *jc, char *reg_name, size_t len ) * * Generic function to create a jtag register via shell command * register <reg_name> <len> * * Parameters * jc : jtag control structure * reg_name : name of the new register * len : number of bits (= length) of new register * * Returns * 1 -> all ok * 0 -> error occured ****************************************************************************/ static int create_register( jtag_ctrl_t *jc, char *reg_name, size_t len) { const size_t str_len = 10; char len_str[str_len+1]; char *cmd[] = {"register", reg_name, len_str, NULL}; if (part_find_data_register( jc->part, reg_name )) return 1; /* convert length information to string */ snprintf( len_str, str_len, "%zu", len ); if (jc->proc_mode & BSDL_MODE_INSTR_EXEC) cmd_run( jc->chain, cmd ); if (jc->proc_mode & BSDL_MODE_INSTR_PRINT) print_cmd( cmd ); return 1; }
/***************************************************************************** * int bsdl_process_register_access( jtag_ctrl_t *jc ) * Register Access management function * * Runs through the main instruction list and builds the instruction/register * association for each instruction from the register access specifications * via shell command * instruction <instruction> <code> <register> * * Additional register are created on the fly: * - standard registers that haven't been created so far * - non-standard registers encountered in register access specs * * Mandatory instruction/register associations are generated also in * absence of a related register access specification (such specs are * optional in the BSDL standard). * * Parameters * jc : jtag control structure * * Returns * 1 -> all ok * 0 -> error occured ****************************************************************************/ static int bsdl_process_register_access( jtag_ctrl_t *jc ) { ainfo_elem_t *ai; instr_elem_t *cinst; /* ensure that all mandatory registers are created prior to handling the instruction/register associations + BOUNDARY/BSR has been generated during the parsing process + DEVICE_ID/DIR has been generated during the parsing process */ /* we need a BYPASS register */ create_register( jc, "BYPASS", 1 ); /* next scan through all register_access definitions and create the non-standard registers */ ai = jc->ainfo_list; while (ai) { int is_std = 0; if (strcasecmp( ai->reg, "BOUNDARY" ) == 0) is_std = 1; if (strcasecmp( ai->reg, "BYPASS" ) == 0) is_std = 1; if (strcasecmp( ai->reg, "DEVICE_ID" ) == 0) is_std = 1; if (strcasecmp( ai->reg, "USERCODE" ) == 0) is_std = 1; if (!is_std) create_register( jc, ai->reg, ai->reg_len ); ai = ai->next; } /* next scan through all instruction/opcode definitions and resolve the instruction/register associations for these */ cinst = jc->instr_list; while (cinst) { char *reg_name = NULL; char *instr_name = NULL; /* now see which of the register_access elements matches this instruction */ ai = jc->ainfo_list; while (ai && (reg_name == NULL)) { instr_elem_t *tinst = ai->instr_list; while (tinst && (reg_name == NULL)) { if (strcasecmp( tinst->instr, cinst->instr ) == 0) { /* found the instruction inside the current access info, now set the register name map some standard register names to different internal names*/ if (strcasecmp( ai->reg, "BOUNDARY" ) == 0) reg_name = "BSR"; else if (strcasecmp( ai->reg, "DEVICE_ID" ) == 0) reg_name = "DIR"; else reg_name = ai->reg; } tinst = tinst->next; } ai = ai->next; } if (reg_name == NULL) { /* BSDL file didn't specify an explicit register_access definition if we're looking at a standard mandatory instruction, we should build the association ourselves */ if (strcasecmp( cinst->instr, "BYPASS" ) == 0) reg_name = "BYPASS"; else if (strcasecmp( cinst->instr, "CLAMP" ) == 0) reg_name = "BYPASS"; else if (strcasecmp( cinst->instr, "EXTEST" ) == 0) reg_name = "BSR"; else if (strcasecmp( cinst->instr, "HIGHZ" ) == 0) reg_name = "BYPASS"; else if (strcasecmp( cinst->instr, "IDCODE" ) == 0) reg_name = "DIR"; else if (strcasecmp( cinst->instr, "INTEST" ) == 0) reg_name = "BSR"; else if (strcasecmp( cinst->instr, "PRELOAD" ) == 0) reg_name = "BSR"; else if (strcasecmp( cinst->instr, "SAMPLE" ) == 0) reg_name = "BSR"; else if (strcasecmp( cinst->instr, "USERCODE" ) == 0) reg_name = "USERCODE"; } if (strcasecmp( cinst->instr, "SAMPLE" ) == 0) instr_name = "SAMPLE/PRELOAD"; else instr_name = cinst->instr; if (reg_name) { char *cmd[] = {"instruction", instr_name, cinst->opcode, reg_name, NULL}; if (jc->proc_mode & BSDL_MODE_INSTR_EXEC) cmd_run( jc->chain, cmd ); if (jc->proc_mode & BSDL_MODE_INSTR_PRINT) print_cmd( cmd ); } cinst = cinst->next; } return 1; }
/***************************************************************************** * int bsdl_process_cell_info( jtag_ctrl_t *jc ) * Cell Info management function * * Creates a BSR cell from the temporary storage variables via shell command * bit <bit_num> <type> <default> <signal> [<cbit> <cval> Z] * * Parameters * jc : jtag control structure * * Returns * 1 -> all ok * 0 -> error occured ****************************************************************************/ static int bsdl_process_cell_info( jtag_ctrl_t *jc ) { cell_info_t *ci = jc->cell_info_first; const size_t str_len = 10; char bit_num_str[str_len+1]; char ctrl_bit_num_str[str_len+1]; char disable_safe_value_str[str_len+1]; char *cmd[] = {"bit", bit_num_str, NULL, NULL, NULL, NULL, disable_safe_value_str, "Z", NULL}; while (ci) { /* convert bit number to string */ snprintf( bit_num_str, str_len, "%i", ci->bit_num ); bit_num_str[str_len] = '\0'; /* convert cell function from BSDL token to jtag syntax */ switch (ci->cell_function) { case INTERNAL: /* fall through */ case OUTPUT2: /* fall through */ case OUTPUT3: cmd[2] = "O"; break; case OBSERVE_ONLY: /* fall through */ case INPUT: /* fall through */ case CLOCK: cmd[2] = "I"; break; case CONTROL: /* fall through */ case CONTROLR: cmd[2] = "C"; break; case BIDIR: cmd[2] = "B"; break; default: /* spoil command */ cmd[2] = "?"; break; } /* convert basic safe value */ cmd[3] = strcasecmp( ci->basic_safe_value, "x" ) == 0 ? "?" : ci->basic_safe_value; /* apply port name */ cmd[4] = ci->port_name; /* add disable spec if present */ if (ci->ctrl_bit_num >= 0) { /* convert bit number to string */ snprintf( ctrl_bit_num_str, str_len, "%i", ci->ctrl_bit_num ); ctrl_bit_num_str[str_len] = '\0'; /* convert disable safe value to string */ snprintf( disable_safe_value_str, str_len, "%i", ci->disable_safe_value ); disable_safe_value_str[str_len] = '\0'; cmd[5] = ctrl_bit_num_str; } else /* stop command procssing here */ cmd[5] = NULL; if (jc->proc_mode & BSDL_MODE_INSTR_EXEC) cmd_run( jc->chain, cmd ); if (jc->proc_mode & BSDL_MODE_INSTR_PRINT) print_cmd( cmd ); ci = ci->next; } return 1; }