Skip to content

Commit 463d1b0

Browse files
authored
Merge pull request riscv-collab#1157 from zqb-all/support-disable-auto-fence
target/riscv: support disable auto fence
2 parents c53f931 + 340e38a commit 463d1b0

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

doc/openocd.texi

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11625,6 +11625,19 @@ riscv exec_progbuf 0x0330000f 0x0000100f
1162511625
riscv exec_progbuf 0x94a20405
1162611626
@end example
1162711627

11628+
@deffn {Command} {riscv autofence} [on|off]
11629+
When on (default), OpenOCD will automatically execute RISC-V fence instructions
11630+
(@var{fence.i} and @var{fence rw, rw}) in these cases:
11631+
@itemize @bullet
11632+
@item before step or resume,
11633+
@item before memory read via the Program Buffer,
11634+
@item after memory write via the Program Buffer.
11635+
@end itemize
11636+
When off, users need to take care of memory coherency themselves, for example
11637+
using the @var{riscv exec_progbuf} command to execute fences or CMO instructions
11638+
(RISC-V Cache Management Operations).
11639+
@end deffn
11640+
1162811641
@section ARC Architecture
1162911642
@cindex ARC
1163011643

src/target/riscv/riscv-013.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2925,11 +2925,15 @@ static int deassert_reset(struct target *target)
29252925
return ERROR_OK;
29262926
}
29272927

2928-
static int execute_fence(struct target *target)
2928+
static int execute_autofence(struct target *target)
29292929
{
29302930
if (dm013_select_target(target) != ERROR_OK)
29312931
return ERROR_FAIL;
29322932

2933+
RISCV_INFO(r);
2934+
if (!r->autofence)
2935+
return ERROR_OK;
2936+
29332937
/* FIXME: For non-coherent systems we need to flush the caches right
29342938
* here, but there's no ISA-defined way of doing that. */
29352939
struct riscv_program program;
@@ -2951,8 +2955,9 @@ static int execute_fence(struct target *target)
29512955
LOG_TARGET_ERROR(target, "Unexpected error during fence execution");
29522956
return ERROR_FAIL;
29532957
}
2954-
LOG_TARGET_DEBUG(target, "Unable to execute fence");
2958+
LOG_TARGET_DEBUG(target, "Unable to execute fence.i and fence rw, rw");
29552959
}
2960+
LOG_TARGET_DEBUG(target, "Successfully executed fence.i and fence rw, rw");
29562961
return ERROR_OK;
29572962
}
29582963

@@ -2966,6 +2971,7 @@ static int execute_fence(struct target *target)
29662971
}
29672972
LOG_TARGET_DEBUG(target, "Unable to execute fence.i");
29682973
}
2974+
LOG_TARGET_DEBUG(target, "Successfully executed fence.i");
29692975

29702976
riscv_program_init(&program, target);
29712977
riscv_program_fence_rw_rw(&program);
@@ -2976,6 +2982,7 @@ static int execute_fence(struct target *target)
29762982
}
29772983
LOG_TARGET_DEBUG(target, "Unable to execute fence rw, rw");
29782984
}
2985+
LOG_TARGET_DEBUG(target, "Successfully executed fence rw, rw");
29792986
return ERROR_OK;
29802987
}
29812988

@@ -4285,7 +4292,7 @@ read_memory_progbuf(struct target *target, target_addr_t address,
42854292

42864293
memset(buffer, 0, count*size);
42874294

4288-
if (execute_fence(target) != ERROR_OK)
4295+
if (execute_autofence(target) != ERROR_OK)
42894296
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED;
42904297

42914298
uint64_t mstatus = 0;
@@ -4876,7 +4883,7 @@ write_memory_progbuf(struct target *target, target_addr_t address,
48764883
if (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old))
48774884
return MEM_ACCESS_FAILED;
48784885

4879-
if (execute_fence(target) != ERROR_OK)
4886+
if (execute_autofence(target) != ERROR_OK)
48804887
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED;
48814888

48824889
return result == ERROR_OK ? MEM_ACCESS_OK : MEM_ACCESS_FAILED;
@@ -5363,18 +5370,12 @@ static int riscv013_get_dmi_scan_length(struct target *target)
53635370
return info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH;
53645371
}
53655372

5366-
static int maybe_execute_fence_i(struct target *target)
5367-
{
5368-
if (has_sufficient_progbuf(target, 2))
5369-
return execute_fence(target);
5370-
return ERROR_OK;
5371-
}
5372-
53735373
/* Helper Functions. */
53745374
static int riscv013_on_step_or_resume(struct target *target, bool step)
53755375
{
5376-
if (maybe_execute_fence_i(target) != ERROR_OK)
5377-
return ERROR_FAIL;
5376+
if (has_sufficient_progbuf(target, 2))
5377+
if (execute_autofence(target) != ERROR_OK)
5378+
return ERROR_FAIL;
53785379

53795380
if (set_dcsr_ebreak(target, step) != ERROR_OK)
53805381
return ERROR_FAIL;

src/target/riscv/riscv.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4504,6 +4504,22 @@ COMMAND_HANDLER(riscv_set_maskisr)
45044504
return ERROR_OK;
45054505
}
45064506

4507+
COMMAND_HANDLER(riscv_set_autofence)
4508+
{
4509+
struct target *target = get_current_target(CMD_CTX);
4510+
RISCV_INFO(r);
4511+
4512+
if (CMD_ARGC == 0) {
4513+
command_print(CMD, "autofence: %s", r->autofence ? "on" : "off");
4514+
return ERROR_OK;
4515+
} else if (CMD_ARGC == 1) {
4516+
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->autofence);
4517+
return ERROR_OK;
4518+
}
4519+
4520+
return ERROR_COMMAND_SYNTAX_ERROR;
4521+
}
4522+
45074523
COMMAND_HANDLER(riscv_set_ebreakm)
45084524
{
45094525
struct target *target = get_current_target(CMD_CTX);
@@ -5390,6 +5406,15 @@ static const struct command_registration riscv_exec_command_handlers[] = {
53905406
"hw - translate vaddr to paddr by hardware, "
53915407
"off - no address translation."
53925408
},
5409+
{
5410+
.name = "autofence",
5411+
.handler = riscv_set_autofence,
5412+
.mode = COMMAND_ANY,
5413+
.usage = "[on|off]",
5414+
.help = "When on (default), OpenOCD will automatically execute fence instructions in some situations. "
5415+
"When off, users need to take care of memory coherency themselves, for example by using "
5416+
"`riscv exec_progbuf` to execute fence or CMO instructions."
5417+
},
53935418
COMMAND_REGISTRATION_DONE
53945419
};
53955420

@@ -5531,6 +5556,8 @@ static void riscv_info_init(struct target *target, struct riscv_info *r)
55315556
r->wp_allow_equality_match_trigger = true;
55325557
r->wp_allow_ge_lt_trigger = true;
55335558
r->wp_allow_napot_trigger = true;
5559+
5560+
r->autofence = true;
55345561
}
55355562

55365563
static int riscv_resume_go_all_harts(struct target *target)

src/target/riscv/riscv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,8 @@ struct riscv_info {
321321
bool wp_allow_equality_match_trigger;
322322
bool wp_allow_napot_trigger;
323323
bool wp_allow_ge_lt_trigger;
324+
325+
bool autofence;
324326
};
325327

326328
COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,

0 commit comments

Comments
 (0)