From 2c96555c732db8b73ce02bb1a235bb0ae0f99f5d Mon Sep 17 00:00:00 2001 From: Jan Matyas Date: Wed, 1 Feb 2023 14:42:57 +0100 Subject: Fix opcode for the "fence" instruction OpenOCD currently uses improper "fence" instruction: "FENCE" opcode with empty predecessor and successor sets. Such instruction has no effect and is reserved for future use as a HINT instruction (RISC-V Unprivileged ISA spec V20191213, section 2.9). This patch fixes it by using the proper "fence rw,rw" instruction. Change-Id: Ia2a66059009153efef27279410850ddfd73dae38 Signed-off-by: Jan Matyas --- src/target/riscv/opcodes.h | 7 ++++--- src/target/riscv/program.c | 4 ++-- src/target/riscv/program.h | 2 +- src/target/riscv/riscv-013.c | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/target/riscv/opcodes.h b/src/target/riscv/opcodes.h index 992196f..59c3413 100644 --- a/src/target/riscv/opcodes.h +++ b/src/target/riscv/opcodes.h @@ -294,10 +294,11 @@ static uint32_t srli(unsigned int dest, unsigned int src, uint8_t shamt) return inst_rs2(shamt) | inst_rs1(src) | inst_rd(dest) | MATCH_SRLI; } -static uint32_t fence(void) __attribute__((unused)); -static uint32_t fence(void) +static uint32_t fence_rw_rw(void) __attribute__((unused)); +static uint32_t fence_rw_rw(void) { - return MATCH_FENCE; + /* fence rw,rw */ + return MATCH_FENCE | 0x3300000; } static uint32_t auipc(unsigned int dest) __attribute__((unused)); diff --git a/src/target/riscv/program.c b/src/target/riscv/program.c index 8e2ce5d..f14923a 100644 --- a/src/target/riscv/program.c +++ b/src/target/riscv/program.c @@ -151,9 +151,9 @@ int riscv_program_fence_i(struct riscv_program *p) return riscv_program_insert(p, fence_i()); } -int riscv_program_fence(struct riscv_program *p) +int riscv_program_fence_rw_rw(struct riscv_program *p) { - return riscv_program_insert(p, fence()); + return riscv_program_insert(p, fence_rw_rw()); } int riscv_program_ebreak(struct riscv_program *p) diff --git a/src/target/riscv/program.h b/src/target/riscv/program.h index 62a04f0..6916500 100644 --- a/src/target/riscv/program.h +++ b/src/target/riscv/program.h @@ -63,7 +63,7 @@ int riscv_program_csrr(struct riscv_program *p, enum gdb_regno d, enum gdb_regno int riscv_program_csrw(struct riscv_program *p, enum gdb_regno s, enum gdb_regno csr); int riscv_program_fence_i(struct riscv_program *p); -int riscv_program_fence(struct riscv_program *p); +int riscv_program_fence_rw_rw(struct riscv_program *p); int riscv_program_ebreak(struct riscv_program *p); int riscv_program_addi(struct riscv_program *p, enum gdb_regno d, enum gdb_regno s, int16_t i); diff --git a/src/target/riscv/riscv-013.c b/src/target/riscv/riscv-013.c index 661197c..57f5530 100644 --- a/src/target/riscv/riscv-013.c +++ b/src/target/riscv/riscv-013.c @@ -2532,7 +2532,7 @@ static int execute_fence(struct target *target) struct riscv_program program; riscv_program_init(&program, target); riscv_program_fence_i(&program); - riscv_program_fence(&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"); -- cgit v1.1