void jtag_reset( chain_t *chain ) { chain_set_trst( chain, 0 ); chain_set_trst( chain, 1 ); tap_reset( chain ); }
// Resets JTAG, and sets up DEBUG scan chain static void configure_chain ( void ) { printf( "Resetting the JTAG interface...\n" ); tap_reset(); printf( "Enumerating the JTAG chain...\n" ); jtag_enumerate_chain( &discovered_id_codes ); printf("\nDevices discovered on the JTAG chain:\n"); printf("Index\tName\t\tID Code\t\tIR Length\n"); printf("----------------------------------------------------------------\n"); for( unsigned i = 0; i < discovered_id_codes.size(); i++ ) { const char * name; int irlen; if ( discovered_id_codes[i] != IDCODE_INVALID ) { name = bsdl_get_name ( discovered_id_codes[i] ); irlen = bsdl_get_IR_size( discovered_id_codes[i] ); if ( name == NULL ) name = name_not_found; } else { name = name_not_found; irlen = -1; } printf("%d: \t%s \t0x%08X \t%d\n", i, name, discovered_id_codes[i], irlen); } printf("\n"); if ( discovered_id_codes.size() > 1 ) { throw std::runtime_error( "TODO: Support for JTAG chains with more than one device must be tested again." ); } if ( target_dev_pos >= int( discovered_id_codes.size() ) ) { printf("ERROR: Requested target device (%i) beyond highest device index (%u).\n", target_dev_pos, unsigned( discovered_id_codes.size() - 1 )) ; exit(1); } const unsigned int manuf_id = (discovered_id_codes[target_dev_pos] >> 1) & IDCODE_MANUFACTURER_ID_MASK; // Use BSDL files to determine prefix bits, postfix bits, debug command, IR length const int ir_size = get_IR_size(target_dev_pos); printf( "The target device is at JTAG chain position %d and has an IDCODE of 0x%08X.\nThe IR register has a length of %d bits.\n", target_dev_pos, discovered_id_codes[target_dev_pos], ir_size ); config_set_IR_size( ir_size ); // Set the IR prefix / postfix bits int total = 0; for ( int i = 0; i < int( discovered_id_codes.size() ); i++ ) { if(i == target_dev_pos) { config_set_IR_postfix_bits(total); //debug("Postfix bits: %d\n", total); total = 0; continue; } total += get_IR_size(i); debug("Adding %i to total for devidx %i\n", get_IR_size(i), i); } config_set_IR_prefix_bits(total); debug("Prefix bits: %d\n", total); // Note that there's a little translation here, since device index 0 is actually closest to the cable data input config_set_DR_prefix_bits(int(discovered_id_codes.size()) - target_dev_pos - 1); // number of devices between cable data out and target device config_set_DR_postfix_bits(target_dev_pos); // number of devices between target device and cable data in // Set the DEBUG command for the IR of the target device. // If this is a Xilinx device, use USER1 instead of DEBUG // If we Altera Virtual JTAG mode, we don't care. if((force_alt_vjtag == -1) || ((force_alt_vjtag == 0) && (manuf_id != ALTERA_MANUFACTURER_ID))) { const uint32_t cmd = get_debug_cmd(target_dev_pos); if(cmd == TAP_CMD_INVALID) { printf("Unable to find DEBUG command, aborting.\n"); exit(1); } config_set_debug_cmd(cmd); // This may have to be USER1 if this is a Xilinx device } // Enable the kludge for Xilinx BSCAN, if necessary. // Safe, but slower, for non-BSCAN TAPs. if ( manuf_id == XILINX_MANUFACTURER_ID ) { config_set_xilinx_bscan_internal_jtag( true ); } // Set Altera Virtual JTAG mode on or off. If not forced, then enable // if the target device has an Altera manufacturer IDCODE if(force_alt_vjtag == 1) { config_set_alt_vjtag(1); } else if(force_alt_vjtag == -1) { config_set_alt_vjtag(0); } else { if(manuf_id == ALTERA_MANUFACTURER_ID) { config_set_alt_vjtag(1); } else { config_set_alt_vjtag(0); } } printf( "Performing a TAP sanity check (explicitly write the IDCODE instruction code and read back the IDCODE value)...\n" ); const uint32_t cmd = bsdl_get_idcode_cmd( discovered_id_codes[target_dev_pos] ); if ( cmd == TAP_CMD_INVALID ) throw std::runtime_error( "Error: The BSDL file does not contain the IDCODE instruction opcode, which is needed for a basic sanity check." ); uint32_t id_read; jtag_get_idcode( cmd, &id_read ); if ( id_read != discovered_id_codes[target_dev_pos] ) { throw std::runtime_error( format_msg( "The IDCODE sanity test has failed, the IDCODE value read was 0x%08X, but the expected code was 0x%08X.\n", id_read, discovered_id_codes[target_dev_pos] ) ); } printf("IDCODE sanity test passed, the JTAG chain looks OK.\n"); printf("Switching to the debug module of the OR10 TAP...\n"); set_ir_to_cpu_debug_module(); }
static int cmd_cable_run( chain_t *chain, char *params[] ) { cable_t *cable; int i; int paramc = cmd_params( params ); /* we need at least one parameter for 'cable' command */ if (paramc < 2) return -1; /* maybe old syntax was used? search connection type driver */ for (i = 0; parport_drivers[i]; i++) if (strcasecmp( params[1], parport_drivers[i]->type ) == 0) break; if (parport_drivers[i] != 0) { /* Old syntax was used. Swap params. */ printf( _("Note: the 'cable' command syntax changed, please read the help text\n") ); if (paramc >= 4) { char *tmparam; tmparam = params[3]; params[3] = params[2]; params[2] = params[1]; params[1] = tmparam; } else return -1; } /* search cable driver list */ for (i = 0; cable_drivers[i]; i++) if (strcasecmp( params[1], cable_drivers[i]->name ) == 0) break; if (!cable_drivers[i]) { printf( _("Unknown cable type: %s\n"), params[1] ); return 1; } if (paramc >= 3) { if (strcasecmp( params[2], "help" ) == 0) { cable_drivers[i]->help(cable_drivers[i]->name); return 1; } } if (bus) { bus_free( bus ); bus = NULL; } chain_disconnect( chain ); cable = calloc(1, sizeof(cable_t) ); if (!cable) { printf( _("%s(%d) malloc failed!\n"), __FILE__, __LINE__); return 1; } cable->driver = cable_drivers[i]; if ( cable->driver->connect( ++params, cable ) ) { printf( _("Error: Cable connection failed!\n") ); free( cable ); return 1; } chain->cable = cable; if (cable_init( chain->cable )) { printf( _("Error: Cable initialization failed!\n") ); chain_disconnect( chain ); return 1; } chain_set_trst( chain, 0 ); chain_set_trst( chain, 1 ); tap_reset( chain ); return 1; }