aboutsummaryrefslogtreecommitdiff
path: root/src/target
diff options
context:
space:
mode:
authorXiang W <wxjstz@126.com>2023-08-08 14:31:52 +0800
committerXiang W <wxjstz@126.com>2023-08-17 09:05:36 +0800
commit373b8f1a899402828d84190da57af4e27f118909 (patch)
tree3c9ebb287a754589b6fead6d92a625a2267a1c31 /src/target
parentee5c5c292fd04f62f88fc0ae3a8d69c403aa2803 (diff)
downloadriscv-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>
Diffstat (limited to 'src/target')
-rw-r--r--src/target/riscv/riscv-013.c36
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;
}