diff options
author | Xiang W <wxjstz@126.com> | 2023-08-08 14:31:52 +0800 |
---|---|---|
committer | Xiang W <wxjstz@126.com> | 2023-08-17 09:05:36 +0800 |
commit | 373b8f1a899402828d84190da57af4e27f118909 (patch) | |
tree | 3c9ebb287a754589b6fead6d92a625a2267a1c31 | |
parent | ee5c5c292fd04f62f88fc0ae3a8d69c403aa2803 (diff) | |
download | riscv-openocd-373b8f1a899402828d84190da57af4e27f118909.zip riscv-openocd-373b8f1a899402828d84190da57af4e27f118909.tar.gz riscv-openocd-373b8f1a899402828d84190da57af4e27f118909.tar.bz2 |
target/riscv: fix execute_fence
This patch improves the following issues:
1. Makes it compatible with targets with progbufsize == 1.
2. Although exceptions don’t update any registers, but do end execution
of the progbuf. This will make fence rw, rw impossible to execute.
Change-Id: I2208fd31ec6a7dae6e61c5952f90901568caada6
Signed-off-by: Xiang W <wxjstz@126.com>
-rw-r--r-- | src/target/riscv/riscv-013.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 8021375..0acb39d 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2845,15 +2845,35 @@ static int execute_fence(struct target *target) /* FIXME: For non-coherent systems we need to flush the caches right * here, but there's no ISA-defined way of doing that. */ + int result; struct riscv_program program; - riscv_program_init(&program, target); - riscv_program_fence_i(&program); - riscv_program_fence_rw_rw(&program); - int result = riscv_program_exec(&program, target); - if (result != ERROR_OK) - LOG_TARGET_DEBUG(target, "Unable to execute pre-fence"); - return ERROR_OK; + if (has_sufficient_progbuf(target, 3)) { + riscv_program_init(&program, target); + riscv_program_fence_rw_rw(&program); + riscv_program_fence_i(&program); + result = riscv_program_exec(&program, target); + if (result != ERROR_OK) + LOG_TARGET_DEBUG(target, "Unable to execute pre-fence"); + return ERROR_OK; + } + + if (has_sufficient_progbuf(target, 2)) { + riscv_program_init(&program, target); + riscv_program_fence_i(&program); + result = riscv_program_exec(&program, target); + if (result != ERROR_OK) + LOG_TARGET_DEBUG(target, "Unable to execute fence.i"); + + riscv_program_init(&program, target); + riscv_program_fence_rw_rw(&program); + result = riscv_program_exec(&program, target); + if (result != ERROR_OK) + LOG_TARGET_DEBUG(target, "Unable to execute fence rw, rw"); + return ERROR_OK; + } + + return ERROR_FAIL; } static void log_memory_access128(target_addr_t address, uint64_t value_h, @@ -4995,7 +5015,7 @@ void riscv013_fill_dm_nop_u64(struct target *target, char *buf) static int maybe_execute_fence_i(struct target *target) { - if (has_sufficient_progbuf(target, 3)) + if (has_sufficient_progbuf(target, 2)) return execute_fence(target); return ERROR_OK; } |