Skip to content

Commit 342f294

Browse files
committed
target/riscv: restrict BSCAN-related commands to before-init
Logically, BSCAN tunneling is used to establish a connection, therefore it should be set up before the communication starts (i.e. before `init`). Moreover, current implementation does not support changing `bscan_tunnel_ir_width` after `init`. This is evident by RISC-V handler of the `init` itself. Link: https://github.com/riscv-collab/riscv-openocd/blob/9a23c9e67978f77d9166102cefc7b537b714b561/src/target/riscv/riscv.c#L467-L481 Change-Id: I817c6a996f7f7171b2286e181daf1092bd358f69 Signed-off-by: Evgeniy Naydanov <[email protected]>
1 parent 9a23c9e commit 342f294

File tree

3 files changed

+36
-32
lines changed

3 files changed

+36
-32
lines changed

doc/openocd.texi

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11354,10 +11354,15 @@ Display/set the current core displayed in GDB. This is needed only if
1135411354
@code{riscv smp} was used.
1135511355
@end deffn
1135611356

11357-
@deffn {Command} {riscv use_bscan_tunnel} value
11357+
@deffn {Command} {riscv use_bscan_tunnel} width [type]
1135811358
Enable or disable use of a BSCAN tunnel to reach the Debug Module. Supply the
11359-
width of the DM transport TAP's instruction register to enable. Supply a
11360-
value of 0 to disable.
11359+
@var{width} of the DM transport TAP's instruction register to enable. The
11360+
@var{width} should fit into 7 bits. Supply a value of 0 to disable.
11361+
Pass a second argument (optional) to indicate Bscan Tunnel Type:
11362+
@enumerate
11363+
@item 0:(default) NESTED_TAP
11364+
@item 1: DATA_REGISTER
11365+
@end enumerate
1136111366

1136211367
This BSCAN tunnel interface is specific to SiFive IP. Anybody may implement
1136311368
it, but currently there is no good documentation on it. In a nutshell, this

src/target/riscv/riscv.c

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ struct scan_field select_idcode = {
5454
};
5555

5656
static bscan_tunnel_type_t bscan_tunnel_type;
57-
int bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
57+
#define BSCAN_TUNNEL_IR_WIDTH_NBITS 7
58+
uint8_t bscan_tunnel_ir_width; /* if zero, then tunneling is not present/active */
5859
static int bscan_tunnel_ir_id; /* IR ID of the JTAG TAP to access the tunnel. Valid when not 0 */
5960

6061
static const uint8_t bscan_zero[4] = {0};
@@ -67,7 +68,6 @@ static struct scan_field select_user4 = {
6768
};
6869

6970

70-
static uint8_t bscan_tunneled_ir_width[4] = {5}; /* overridden by assignment in riscv_init_target */
7171
static struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
7272
{
7373
.num_bits = 3,
@@ -80,8 +80,8 @@ static struct scan_field _bscan_tunnel_data_register_select_dmi[] = {
8080
.in_value = NULL,
8181
},
8282
{
83-
.num_bits = 7,
84-
.out_value = bscan_tunneled_ir_width,
83+
.num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS,
84+
.out_value = &bscan_tunnel_ir_width,
8585
.in_value = NULL,
8686
},
8787
{
@@ -98,8 +98,8 @@ static struct scan_field _bscan_tunnel_nested_tap_select_dmi[] = {
9898
.in_value = NULL,
9999
},
100100
{
101-
.num_bits = 7,
102-
.out_value = bscan_tunneled_ir_width,
101+
.num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS,
102+
.out_value = &bscan_tunnel_ir_width,
103103
.in_value = NULL,
104104
},
105105
{
@@ -300,7 +300,6 @@ void select_dmi_via_bscan(struct target *target)
300300
int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_ptr)
301301
{
302302
/* On BSCAN TAP: Select IR=USER4, issue tunneled IR scan via BSCAN TAP's DR */
303-
uint8_t tunneled_ir_width[4] = {bscan_tunnel_ir_width};
304303
uint8_t tunneled_dr_width[4] = {32};
305304
uint8_t out_value[5] = {0};
306305
uint8_t in_value[5] = {0};
@@ -316,8 +315,8 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
316315
tunneled_ir[1].num_bits = bscan_tunnel_ir_width;
317316
tunneled_ir[1].out_value = ir_dtmcontrol;
318317
tunneled_ir[1].in_value = NULL;
319-
tunneled_ir[2].num_bits = 7;
320-
tunneled_ir[2].out_value = tunneled_ir_width;
318+
tunneled_ir[2].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
319+
tunneled_ir[2].out_value = &bscan_tunnel_ir_width;
321320
tunneled_ir[2].in_value = NULL;
322321
tunneled_ir[3].num_bits = 1;
323322
tunneled_ir[3].out_value = bscan_zero;
@@ -329,7 +328,7 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
329328
tunneled_dr[1].num_bits = 32 + 1;
330329
tunneled_dr[1].out_value = out_value;
331330
tunneled_dr[1].in_value = in_value;
332-
tunneled_dr[2].num_bits = 7;
331+
tunneled_dr[2].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
333332
tunneled_dr[2].out_value = tunneled_dr_width;
334333
tunneled_dr[2].in_value = NULL;
335334
tunneled_dr[3].num_bits = 1;
@@ -343,8 +342,8 @@ int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_
343342
tunneled_ir[2].num_bits = bscan_tunnel_ir_width;
344343
tunneled_ir[2].out_value = ir_dtmcontrol;
345344
tunneled_ir[1].in_value = NULL;
346-
tunneled_ir[1].num_bits = 7;
347-
tunneled_ir[1].out_value = tunneled_ir_width;
345+
tunneled_ir[1].num_bits = BSCAN_TUNNEL_IR_WIDTH_NBITS;
346+
tunneled_ir[1].out_value = &bscan_tunnel_ir_width;
348347
tunneled_ir[2].in_value = NULL;
349348
tunneled_ir[0].num_bits = 1;
350349
tunneled_ir[0].out_value = bscan_zero;
@@ -473,7 +472,6 @@ static int riscv_init_target(struct command_context *cmd_ctx,
473472
}
474473
h_u32_to_le(ir_user4, ir_user4_raw);
475474
select_user4.num_bits = target->tap->ir_length;
476-
bscan_tunneled_ir_width[0] = bscan_tunnel_ir_width;
477475
if (bscan_tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)
478476
bscan_tunnel_data_register_select_dmi[1].num_bits = bscan_tunnel_ir_width;
479477
else /* BSCAN_TUNNEL_NESTED_TAP */
@@ -4382,18 +4380,23 @@ COMMAND_HANDLER(riscv_resume_order)
43824380

43834381
COMMAND_HANDLER(riscv_use_bscan_tunnel)
43844382
{
4385-
int irwidth = 0;
4383+
uint8_t irwidth = 0;
43864384
int tunnel_type = BSCAN_TUNNEL_NESTED_TAP;
43874385

4388-
if (CMD_ARGC > 2) {
4389-
LOG_ERROR("Command takes at most two arguments");
4386+
if (CMD_ARGC < 1 || CMD_ARGC > 2)
43904387
return ERROR_COMMAND_SYNTAX_ERROR;
4391-
} else if (CMD_ARGC == 1) {
4392-
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);
4393-
} else if (CMD_ARGC == 2) {
4394-
COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], irwidth);
4395-
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tunnel_type);
4388+
4389+
if (CMD_ARGC >= 1) {
4390+
COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], irwidth);
4391+
assert(BSCAN_TUNNEL_IR_WIDTH_NBITS < 8);
4392+
if (irwidth >= (uint8_t)1 << BSCAN_TUNNEL_IR_WIDTH_NBITS) {
4393+
command_print(CMD, "'value' does not fit into %d bits.",
4394+
BSCAN_TUNNEL_IR_WIDTH_NBITS);
4395+
return ERROR_COMMAND_ARGUMENT_OVERFLOW;
4396+
}
43964397
}
4398+
if (CMD_ARGC == 2)
4399+
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], tunnel_type);
43974400
if (tunnel_type == BSCAN_TUNNEL_NESTED_TAP)
43984401
LOG_INFO("Nested Tap based Bscan Tunnel Selected");
43994402
else if (tunnel_type == BSCAN_TUNNEL_DATA_REGISTER)
@@ -5195,18 +5198,14 @@ static const struct command_registration riscv_exec_command_handlers[] = {
51955198
{
51965199
.name = "use_bscan_tunnel",
51975200
.handler = riscv_use_bscan_tunnel,
5198-
.mode = COMMAND_ANY,
5201+
.mode = COMMAND_CONFIG,
51995202
.usage = "value [type]",
5200-
.help = "Enable or disable use of a BSCAN tunnel to reach DM. Supply "
5201-
"the width of the DM transport TAP's instruction register to "
5202-
"enable. Supply a value of 0 to disable. Pass A second argument "
5203-
"(optional) to indicate Bscan Tunnel Type {0:(default) NESTED_TAP , "
5204-
"1: DATA_REGISTER}"
5203+
.help = "Enable or disable use of a BSCAN tunnel to reach DM."
52055204
},
52065205
{
52075206
.name = "set_bscan_tunnel_ir",
52085207
.handler = riscv_set_bscan_tunnel_ir,
5209-
.mode = COMMAND_ANY,
5208+
.mode = COMMAND_CONFIG,
52105209
.usage = "value",
52115210
.help = "Specify the JTAG TAP IR used to access the bscan tunnel. "
52125211
"By default it is 0x23 << (ir_length - 6), which map some "

src/target/riscv/riscv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ extern struct scan_field select_idcode;
365365
extern struct scan_field *bscan_tunneled_select_dmi;
366366
extern uint32_t bscan_tunneled_select_dmi_num_fields;
367367
typedef enum { BSCAN_TUNNEL_NESTED_TAP, BSCAN_TUNNEL_DATA_REGISTER } bscan_tunnel_type_t;
368-
extern int bscan_tunnel_ir_width;
368+
extern uint8_t bscan_tunnel_ir_width;
369369

370370
int dtmcontrol_scan_via_bscan(struct target *target, uint32_t out, uint32_t *in_ptr);
371371
void select_dmi_via_bscan(struct target *target);

0 commit comments

Comments
 (0)