--- a/src/target/riscv/riscv.c +++ b/src/target/riscv/riscv.c @@ -127,6 +127,7 @@ static bscan_tunnel_type_t bscan_tunnel_type; int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */ +static int bscan_tunnel_ir_id; /* outer TAP IR used to access the tunnel */ static const uint8_t bscan_zero[4] = {0}; static const uint8_t bscan_one[4] = {1}; @@ -451,8 +452,12 @@ select_idcode.num_bits = target->tap->ir_length; if (bscan_tunnel_ir_width != 0) { - assert(target->tap->ir_length >= 6); - uint32_t ir_user4_raw = 0x23 << (target->tap->ir_length - 6); + uint32_t ir_user4_raw = bscan_tunnel_ir_id; + /* Preserve the legacy Xilinx USER4 default when no IR was supplied. */ + if (ir_user4_raw == 0) { + assert(target->tap->ir_length >= 6); + ir_user4_raw = 0x23 << (target->tap->ir_length - 6); + } h_u32_to_le(ir_user4, ir_user4_raw); select_user4.num_bits = target->tap->ir_length; bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width; @@ -2859,6 +2864,21 @@ return ERROR_OK; } +COMMAND_HANDLER(riscv_set_bscan_tunnel_ir) +{ + int ir_id = 0; + + if (CMD_ARGC > 1) + return ERROR_COMMAND_SYNTAX_ERROR; + + if (CMD_ARGC == 1) + COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], ir_id); + + LOG_INFO("Bscan tunnel IR 0x%x selected", ir_id); + bscan_tunnel_ir_id = ir_id; + return ERROR_OK; +} + COMMAND_HANDLER(riscv_set_enable_virt2phys) { if (CMD_ARGC != 1) { @@ -3072,6 +3092,14 @@ "1: DATA_REGISTER}" }, { + .name = "set_bscan_tunnel_ir", + .handler = riscv_set_bscan_tunnel_ir, + .mode = COMMAND_ANY, + .usage = "[value]", + .help = "Specify the outer JTAG TAP IR used to access the BSCAN tunnel. " + "The default remains the Xilinx FPGA USER4 instruction." + }, + { .name = "set_enable_virt2phys", .handler = riscv_set_enable_virt2phys, .mode = COMMAND_ANY,