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 <jan.matyas@codasip.com>
This commit is contained in:
Jan Matyas 2023-02-01 14:42:57 +01:00
parent 9c3a4b458c
commit 2c96555c73
4 changed files with 8 additions and 7 deletions

View File

@ -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));

View File

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

View File

@ -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);

View File

@ -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");