Checking in for backup.

This commit is contained in:
Greg Savin 2019-04-04 15:50:11 -07:00
parent c089e6ae9a
commit 66e480d861
6 changed files with 180 additions and 0 deletions

View File

@ -111,6 +111,7 @@ m4_define([ADAPTER_OPT], [m4_translit(ADAPTER_ARG($1), [_], [-])])
m4_define([USB1_ADAPTERS], m4_define([USB1_ADAPTERS],
[[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]], [[[ftdi], [MPSSE mode of FTDI based devices], [FTDI]],
[[ftdi_oscan1], [cJTAG OSCAN1 tunneled thru MPSSE], [FTDI_OSCAN1]], [[ftdi_oscan1], [cJTAG OSCAN1 tunneled thru MPSSE], [FTDI_OSCAN1]],
[[riscv_arty_bscan], [Access to RISCV on Arty board via BSCAN], [RISCV_ARTY_BSCAN]],
[[stlink], [ST-Link JTAG Programmer], [HLADAPTER_STLINK]], [[stlink], [ST-Link JTAG Programmer], [HLADAPTER_STLINK]],
[[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]], [[ti_icdi], [TI ICDI JTAG Programmer], [HLADAPTER_ICDI]],
[[ulink], [Keil ULINK JTAG Programmer], [ULINK]], [[ulink], [Keil ULINK JTAG Programmer], [ULINK]],

View File

@ -404,8 +404,108 @@ static void dump_field(int idle, const struct scan_field *field)
/*** Utility functions. ***/ /*** Utility functions. ***/
#if BUILD_RISCV_ARTY_BSCAN == 1
static void select_dmi_via_bscan(struct target *target)
{
jtag_add_ir_scan(target->tap, &select_user4, TAP_IDLE);
jtag_add_dr_scan(target->tap, bscan_tunneled_select_dmi_num_fields, bscan_tunneled_select_dmi, TAP_IDLE);
}
static uint32_t dtmcontrol_scan_via_bscan(struct target *target, uint32_t out)
{
/* jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE); */
/* On BSCAN TAP: Select IR=USER4, issue tunneled IR scan via BSCAN TAP's DR */
uint8_t zero[4] = {0};
uint8_t one[4] = {1};
uint8_t tunneled_ir_width[4] = {target->bscan_tunnel_ir_width};
uint8_t tunneled_dr_width[4] = {32};
uint8_t out_0[4] = {out & 0x1};
uint8_t out_31_1[4];
uint8_t in_value[4];
buf_set_u32(out_31_1, 0, 32, (out >> 1));
struct scan_field tunneled_ir[] = {
{
.num_bits = 1,
.out_value = zero,
.in_value = NULL,
},
{
.num_bits = 7,
.out_value = tunneled_ir_width,
.in_value = NULL,
},
{
.num_bits = target->bscan_tunnel_ir_width,
.out_value = ir_dtmcontrol,
.in_value = NULL,
},
{
.num_bits = 3,
.out_value = zero,
.in_value = NULL,
}
};
struct scan_field tunneled_dr[] = {
{
.num_bits = 1,
.out_value = one,
.in_value = NULL,
},
{
.num_bits = 7,
.out_value = tunneled_dr_width,
.in_value = NULL,
},
/* for BSCAN tunnel. there is a one TCK skew between shift in and shift out, so splitting the DR payload into 2 fields */
{
.num_bits = 1,
.out_value = out_0,
.in_value = NULL,
},
{
.num_bits = 32,
.out_value = out_31_1,
.in_value = in_value,
},
{
.num_bits = 3,
.out_value = zero,
.in_value = NULL,
}
};
jtag_add_ir_scan(target->tap, &select_user4, TAP_IDLE);
jtag_add_dr_scan(target->tap, DIM(tunneled_ir), tunneled_ir, TAP_IDLE);
jtag_add_dr_scan(target->tap, DIM(tunneled_dr), tunneled_dr, TAP_IDLE);
select_dmi_via_bscan(target);
int retval = jtag_execute_queue();
if (retval != ERROR_OK) {
LOG_ERROR("failed jtag scan: %d", retval);
return retval;
}
uint32_t in = buf_get_u32(in_value, 0, 32);
LOG_DEBUG("DTMCS: 0x%x -> 0x%x", out, in);
return in;
}
#endif
static void select_dmi(struct target *target) static void select_dmi(struct target *target)
{ {
#if BUILD_RISCV_ARTY_BSCAN == 1
if (target->bscan_tunnel_ir_width != 0) {
select_dmi_via_bscan(target);
return;
}
#endif
jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE); jtag_add_ir_scan(target->tap, &select_dbus, TAP_IDLE);
} }
@ -415,6 +515,12 @@ static uint32_t dtmcontrol_scan(struct target *target, uint32_t out)
uint8_t in_value[4]; uint8_t in_value[4];
uint8_t out_value[4]; uint8_t out_value[4];
#if BUILD_RISCV_ARTY_BSCAN == 1
if (target->bscan_tunnel_ir_width != 0) {
return dtmcontrol_scan_via_bscan(target, out);
}
#endif
buf_set_u32(out_value, 0, 32, out); buf_set_u32(out_value, 0, 32, out);
jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE); jtag_add_ir_scan(target->tap, &select_dtmcontrol, TAP_IDLE);

View File

@ -170,6 +170,44 @@ struct scan_field select_idcode = {
.out_value = ir_idcode .out_value = ir_idcode
}; };
#if BUILD_RISCV_ARTY_BSCAN == 1
uint8_t ir_user4[4] = {0x23};
struct scan_field select_user4 = {
.in_value = NULL,
.out_value = ir_user4
};
uint8_t zero[4] = {0};
uint8_t one[4] = {1};
uint8_t tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */
struct scan_field _bscan_tunneled_select_dmi[] = {
{
.num_bits = 1,
.out_value = zero,
.in_value = NULL,
},
{
.num_bits = 7,
.out_value = tunneled_ir_width,
.in_value = NULL,
},
{
.num_bits = 0, /* initialized in riscv_init_target to ir width of DM */
.out_value = ir_dbus,
.in_value = NULL,
},
{
.num_bits = 3,
.out_value = zero,
.in_value = NULL,
}
};
struct scan_field *bscan_tunneled_select_dmi = _bscan_tunneled_select_dmi;
uint32_t bscan_tunneled_select_dmi_num_fields = sizeof(bscan_tunneled_select_dmi)/sizeof(bscan_tunneled_select_dmi[0]);
#endif
struct trigger { struct trigger {
uint64_t address; uint64_t address;
uint32_t length; uint32_t length;
@ -266,6 +304,15 @@ static int riscv_init_target(struct command_context *cmd_ctx,
select_dbus.num_bits = target->tap->ir_length; select_dbus.num_bits = target->tap->ir_length;
select_idcode.num_bits = target->tap->ir_length; select_idcode.num_bits = target->tap->ir_length;
#if BUILD_RISCV_ARTY_BSCAN == 1
if (target->bscan_tunnel_ir_width != 0) {
select_user4.num_bits = target->bscan_tunnel_ir_width;
tunneled_ir_width[0] = target->bscan_tunnel_ir_width;
bscan_tunneled_select_dmi[2].num_bits = target->bscan_tunnel_ir_width;
}
#endif
riscv_semihosting_init(target); riscv_semihosting_init(target);
target->debug_reason = DBG_REASON_DBGRQ; target->debug_reason = DBG_REASON_DBGRQ;

View File

@ -165,6 +165,11 @@ extern uint8_t ir_dbus[4];
extern struct scan_field select_dbus; extern struct scan_field select_dbus;
extern uint8_t ir_idcode[4]; extern uint8_t ir_idcode[4];
extern struct scan_field select_idcode; extern struct scan_field select_idcode;
#if BUILD_RISCV_ARTY_BSCAN == 1
extern struct scan_field select_user4;
extern struct scan_field *bscan_tunneled_select_dmi;
extern uint32_t bscan_tunneled_select_dmi_num_fields;
#endif
/*** OpenOCD Interface */ /*** OpenOCD Interface */
int riscv_openocd_poll(struct target *target); int riscv_openocd_poll(struct target *target);

View File

@ -4603,6 +4603,7 @@ enum target_cfg_param {
TCFG_RTOS, TCFG_RTOS,
TCFG_DEFER_EXAMINE, TCFG_DEFER_EXAMINE,
TCFG_GDB_PORT, TCFG_GDB_PORT,
TCFG_BSCAN_TUNNEL_IR_WIDTH,
}; };
static Jim_Nvp nvp_config_opts[] = { static Jim_Nvp nvp_config_opts[] = {
@ -4619,6 +4620,9 @@ static Jim_Nvp nvp_config_opts[] = {
{ .name = "-rtos", .value = TCFG_RTOS }, { .name = "-rtos", .value = TCFG_RTOS },
{ .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE }, { .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE },
{ .name = "-gdb-port", .value = TCFG_GDB_PORT }, { .name = "-gdb-port", .value = TCFG_GDB_PORT },
#if BUILD_RISCV_ARTY_BSCAN == 1
{ .name = "-bscan-tunnel-ir-width", .value = TCFG_BSCAN_TUNNEL_IR_WIDTH },
#endif
{ .name = NULL, .value = -1 } { .name = NULL, .value = -1 }
}; };
@ -4920,6 +4924,20 @@ no_params:
Jim_SetResultString(goi->interp, target->gdb_port_override ? : "undefined", -1); Jim_SetResultString(goi->interp, target->gdb_port_override ? : "undefined", -1);
/* loop for more */ /* loop for more */
break; break;
case TCFG_BSCAN_TUNNEL_IR_WIDTH:
if (goi->isconfigure) {
e = Jim_GetOpt_Wide(goi, &w);
if (e != JIM_OK)
return e;
target->bscan_tunnel_ir_width = (int32_t)w;
} else {
if (goi->argc != 0)
goto no_params;
}
Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->bscan_tunnel_ir_width));
/* loop for more */
break;
} }
} /* while (goi->argc) */ } /* while (goi->argc) */

View File

@ -210,6 +210,9 @@ struct target {
/* The semihosting information, extracted from the target. */ /* The semihosting information, extracted from the target. */
struct semihosting *semihosting; struct semihosting *semihosting;
#if BUILD_RISCV_ARTY_BSCAN == 1
int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
#endif
}; };
struct target_list { struct target_list {