Merge pull request #1157 from zqb-all/support-disable-auto-fence

target/riscv: support disable auto fence
This commit is contained in:
Evgeniy Naydanov 2024-11-18 13:16:54 +03:00 committed by GitHub
commit 463d1b0866
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 56 additions and 13 deletions

View File

@ -11625,6 +11625,19 @@ riscv exec_progbuf 0x0330000f 0x0000100f
riscv exec_progbuf 0x94a20405 riscv exec_progbuf 0x94a20405
@end example @end example
@deffn {Command} {riscv autofence} [on|off]
When on (default), OpenOCD will automatically execute RISC-V fence instructions
(@var{fence.i} and @var{fence rw, rw}) in these cases:
@itemize @bullet
@item before step or resume,
@item before memory read via the Program Buffer,
@item after memory write via the Program Buffer.
@end itemize
When off, users need to take care of memory coherency themselves, for example
using the @var{riscv exec_progbuf} command to execute fences or CMO instructions
(RISC-V Cache Management Operations).
@end deffn
@section ARC Architecture @section ARC Architecture
@cindex ARC @cindex ARC

View File

@ -2925,11 +2925,15 @@ static int deassert_reset(struct target *target)
return ERROR_OK; return ERROR_OK;
} }
static int execute_fence(struct target *target) static int execute_autofence(struct target *target)
{ {
if (dm013_select_target(target) != ERROR_OK) if (dm013_select_target(target) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;
RISCV_INFO(r);
if (!r->autofence)
return ERROR_OK;
/* FIXME: For non-coherent systems we need to flush the caches right /* FIXME: For non-coherent systems we need to flush the caches right
* here, but there's no ISA-defined way of doing that. */ * here, but there's no ISA-defined way of doing that. */
struct riscv_program program; struct riscv_program program;
@ -2951,8 +2955,9 @@ static int execute_fence(struct target *target)
LOG_TARGET_ERROR(target, "Unexpected error during fence execution"); LOG_TARGET_ERROR(target, "Unexpected error during fence execution");
return ERROR_FAIL; return ERROR_FAIL;
} }
LOG_TARGET_DEBUG(target, "Unable to execute fence"); LOG_TARGET_DEBUG(target, "Unable to execute fence.i and fence rw, rw");
} }
LOG_TARGET_DEBUG(target, "Successfully executed fence.i and fence rw, rw");
return ERROR_OK; return ERROR_OK;
} }
@ -2966,6 +2971,7 @@ static int execute_fence(struct target *target)
} }
LOG_TARGET_DEBUG(target, "Unable to execute fence.i"); LOG_TARGET_DEBUG(target, "Unable to execute fence.i");
} }
LOG_TARGET_DEBUG(target, "Successfully executed fence.i");
riscv_program_init(&program, target); riscv_program_init(&program, target);
riscv_program_fence_rw_rw(&program); riscv_program_fence_rw_rw(&program);
@ -2976,6 +2982,7 @@ static int execute_fence(struct target *target)
} }
LOG_TARGET_DEBUG(target, "Unable to execute fence rw, rw"); LOG_TARGET_DEBUG(target, "Unable to execute fence rw, rw");
} }
LOG_TARGET_DEBUG(target, "Successfully executed fence rw, rw");
return ERROR_OK; return ERROR_OK;
} }
@ -4285,7 +4292,7 @@ read_memory_progbuf(struct target *target, target_addr_t address,
memset(buffer, 0, count*size); memset(buffer, 0, count*size);
if (execute_fence(target) != ERROR_OK) if (execute_autofence(target) != ERROR_OK)
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED; return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED;
uint64_t mstatus = 0; uint64_t mstatus = 0;
@ -4876,7 +4883,7 @@ write_memory_progbuf(struct target *target, target_addr_t address,
if (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old)) if (register_write_direct(target, GDB_REGNO_MSTATUS, mstatus_old))
return MEM_ACCESS_FAILED; return MEM_ACCESS_FAILED;
if (execute_fence(target) != ERROR_OK) if (execute_autofence(target) != ERROR_OK)
return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED; return MEM_ACCESS_SKIPPED_FENCE_EXEC_FAILED;
return result == ERROR_OK ? MEM_ACCESS_OK : MEM_ACCESS_FAILED; return result == ERROR_OK ? MEM_ACCESS_OK : MEM_ACCESS_FAILED;
@ -5363,18 +5370,12 @@ static int riscv013_get_dmi_scan_length(struct target *target)
return info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH; return info->abits + DTM_DMI_DATA_LENGTH + DTM_DMI_OP_LENGTH;
} }
static int maybe_execute_fence_i(struct target *target)
{
if (has_sufficient_progbuf(target, 2))
return execute_fence(target);
return ERROR_OK;
}
/* Helper Functions. */ /* Helper Functions. */
static int riscv013_on_step_or_resume(struct target *target, bool step) static int riscv013_on_step_or_resume(struct target *target, bool step)
{ {
if (maybe_execute_fence_i(target) != ERROR_OK) if (has_sufficient_progbuf(target, 2))
return ERROR_FAIL; if (execute_autofence(target) != ERROR_OK)
return ERROR_FAIL;
if (set_dcsr_ebreak(target, step) != ERROR_OK) if (set_dcsr_ebreak(target, step) != ERROR_OK)
return ERROR_FAIL; return ERROR_FAIL;

View File

@ -4504,6 +4504,22 @@ COMMAND_HANDLER(riscv_set_maskisr)
return ERROR_OK; return ERROR_OK;
} }
COMMAND_HANDLER(riscv_set_autofence)
{
struct target *target = get_current_target(CMD_CTX);
RISCV_INFO(r);
if (CMD_ARGC == 0) {
command_print(CMD, "autofence: %s", r->autofence ? "on" : "off");
return ERROR_OK;
} else if (CMD_ARGC == 1) {
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], r->autofence);
return ERROR_OK;
}
return ERROR_COMMAND_SYNTAX_ERROR;
}
COMMAND_HANDLER(riscv_set_ebreakm) COMMAND_HANDLER(riscv_set_ebreakm)
{ {
struct target *target = get_current_target(CMD_CTX); struct target *target = get_current_target(CMD_CTX);
@ -5390,6 +5406,15 @@ static const struct command_registration riscv_exec_command_handlers[] = {
"hw - translate vaddr to paddr by hardware, " "hw - translate vaddr to paddr by hardware, "
"off - no address translation." "off - no address translation."
}, },
{
.name = "autofence",
.handler = riscv_set_autofence,
.mode = COMMAND_ANY,
.usage = "[on|off]",
.help = "When on (default), OpenOCD will automatically execute fence instructions in some situations. "
"When off, users need to take care of memory coherency themselves, for example by using "
"`riscv exec_progbuf` to execute fence or CMO instructions."
},
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };
@ -5531,6 +5556,8 @@ static void riscv_info_init(struct target *target, struct riscv_info *r)
r->wp_allow_equality_match_trigger = true; r->wp_allow_equality_match_trigger = true;
r->wp_allow_ge_lt_trigger = true; r->wp_allow_ge_lt_trigger = true;
r->wp_allow_napot_trigger = true; r->wp_allow_napot_trigger = true;
r->autofence = true;
} }
static int riscv_resume_go_all_harts(struct target *target) static int riscv_resume_go_all_harts(struct target *target)

View File

@ -321,6 +321,8 @@ struct riscv_info {
bool wp_allow_equality_match_trigger; bool wp_allow_equality_match_trigger;
bool wp_allow_napot_trigger; bool wp_allow_napot_trigger;
bool wp_allow_ge_lt_trigger; bool wp_allow_ge_lt_trigger;
bool autofence;
}; };
COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key, COMMAND_HELPER(riscv_print_info_line, const char *section, const char *key,