Skip to content

Commit 340e38a

Browse files
committed
target/riscv: support disable auto fence
Support disable automatic fence, it's useful for debug some cache related issue.
1 parent 9ff272e commit 340e38a

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
@@ -11631,6 +11631,19 @@ riscv exec_progbuf 0x0330000f 0x0000100f
1163111631
riscv exec_progbuf 0x94a20405
1163211632
@end example
1163311633

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

src/target/riscv/riscv-013.c

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2913,11 +2913,15 @@ static int deassert_reset(struct target *target)
29132913
return dm_write(target, DM_DMCONTROL, control);
29142914
}
29152915

2916-
static int execute_fence(struct target *target)
2916+
static int execute_autofence(struct target *target)
29172917
{
29182918
if (dm013_select_target(target) != ERROR_OK)
29192919
return ERROR_FAIL;
29202920

2921+
RISCV_INFO(r);
2922+
if (!r->autofence)
2923+
return ERROR_OK;
2924+
29212925
/* FIXME: For non-coherent systems we need to flush the caches right
29222926
* here, but there's no ISA-defined way of doing that. */
29232927
struct riscv_program program;
@@ -2939,8 +2943,9 @@ static int execute_fence(struct target *target)
29392943
LOG_TARGET_ERROR(target, "Unexpected error during fence execution");
29402944
return ERROR_FAIL;
29412945
}
2942-
LOG_TARGET_DEBUG(target, "Unable to execute fence");
2946+
LOG_TARGET_DEBUG(target, "Unable to execute fence.i and fence rw, rw");
29432947
}
2948+
LOG_TARGET_DEBUG(target, "Successfully executed fence.i and fence rw, rw");
29442949
return ERROR_OK;
29452950
}
29462951

@@ -2954,6 +2959,7 @@ static int execute_fence(struct target *target)
29542959
}
29552960
LOG_TARGET_DEBUG(target, "Unable to execute fence.i");
29562961
}
2962+
LOG_TARGET_DEBUG(target, "Successfully executed fence.i");
29572963

29582964
riscv_program_init(&program, target);
29592965
riscv_program_fence_rw_rw(&program);
@@ -2964,6 +2970,7 @@ static int execute_fence(struct target *target)
29642970
}
29652971
LOG_TARGET_DEBUG(target, "Unable to execute fence rw, rw");
29662972
}
2973+
LOG_TARGET_DEBUG(target, "Successfully executed fence rw, rw");
29672974
return ERROR_OK;
29682975
}
29692976

@@ -4273,7 +4280,7 @@ read_memory_progbuf(struct target *target, target_addr_t address,
42734280

42744281
memset(buffer, 0, count*size);
42754282

4276-
if (execute_fence(target) != ERROR_OK)
4283+
if (execute_autofence(target) != ERROR_OK)
42774284
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED;
42784285

42794286
uint64_t mstatus = 0;
@@ -4864,7 +4871,7 @@ write_memory_progbuf(struct target *target, target_addr_t address,
48644871
if (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old))
48654872
return MEM_ACCESS_FAILED;
48664873

4867-
if (execute_fence(target) != ERROR_OK)
4874+
if (execute_autofence(target) != ERROR_OK)
48684875
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED;
48694876

48704877
return result == ERROR_OK ? MEM_ACCESS_OK : MEM_ACCESS_FAILED;
@@ -5351,18 +5358,12 @@ static int riscv013_get_dmi_scan_length(struct target *target)
53515358
return info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH;
53525359
}
53535360

5354-
static int maybe_execute_fence_i(struct target *target)
5355-
{
5356-
if (has_sufficient_progbuf(target, 2))
5357-
return execute_fence(target);
5358-
return ERROR_OK;
5359-
}
5360-
53615361
/* Helper Functions. */
53625362
static int riscv013_on_step_or_resume(struct target *target, bool step)
53635363
{
5364-
if (maybe_execute_fence_i(target) != ERROR_OK)
5365-
return ERROR_FAIL;
5364+
if (has_sufficient_progbuf(target, 2))
5365+
if (execute_autofence(target) != ERROR_OK)
5366+
return ERROR_FAIL;
53665367

53675368
if (set_dcsr_ebreak(target, step) != ERROR_OK)
53685369
return ERROR_FAIL;

src/target/riscv/riscv.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4521,6 +4521,22 @@ COMMAND_HANDLER(riscv_set_maskisr)
45214521
return ERROR_OK;
45224522
}
45234523

4524+
COMMAND_HANDLER(riscv_set_autofence)
4525+
{
4526+
struct target *target = get_current_target(CMD_CTX);
4527+
RISCV_INFO(r);
4528+
4529+
if (CMD_ARGC == 0) {
4530+
command_print(CMD, "autofence: %s", r->autofence ? "on" : "off");
4531+
return ERROR_OK;
4532+
} else if (CMD_ARGC == 1) {
4533+
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->autofence);
4534+
return ERROR_OK;
4535+
}
4536+
4537+
return ERROR_COMMAND_SYNTAX_ERROR;
4538+
}
4539+
45244540
COMMAND_HANDLER(riscv_set_ebreakm)
45254541
{
45264542
struct target *target = get_current_target(CMD_CTX);
@@ -5428,6 +5444,15 @@ static const struct command_registration riscv_exec_command_handlers[] = {
54285444
"hw - translate vaddr to paddr by hardware, "
54295445
"off - no address translation."
54305446
},
5447+
{
5448+
.name = "autofence",
5449+
.handler = riscv_set_autofence,
5450+
.mode = COMMAND_ANY,
5451+
.usage = "[on|off]",
5452+
.help = "When on (default), OpenOCD will automatically execute fence instructions in some situations. "
5453+
"When off, users need to take care of memory coherency themselves, for example by using "
5454+
"`riscv exec_progbuf` to execute fence or CMO instructions."
5455+
},
54315456
COMMAND_REGISTRATION_DONE
54325457
};
54335458

@@ -5569,6 +5594,8 @@ static void riscv_info_init(struct target *target, struct riscv_info *r)
55695594
r->wp_allow_equality_match_trigger = true;
55705595
r->wp_allow_ge_lt_trigger = true;
55715596
r->wp_allow_napot_trigger = true;
5597+
5598+
r->autofence = true;
55725599
}
55735600

55745601
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)