mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-25 07:41:42 +01:00
lib: sbi: Enhance CSR Handling in system_opcode_insn
- Completed TODO in `system_opcode_insn` to ensure CSR read/write instruction handling. - Refactored to use new macros `GET_RS1_NUM` and `GET_CSR_NUM`. - Updated `GET_RM` macro and replaced hardcoded funct3 values with constants (`CSRRW`, `CSRRS`, `CSRRC`, etc.). - Removed redundant `GET_RM` from `riscv_fp.h`. - Improved validation and error handling for CSR instructions. This patch enhances the clarity and correctness of CSR handling in `system_opcode_insn`. Signed-off-by: Dongdong Zhang <zhangdongdong@eswincomputing.com> Reviewed-by: Anup Patel <anup@brainfault.org>
This commit is contained in:

committed by
Anup Patel

parent
b9c091ed89
commit
d4322eebd0
@@ -947,7 +947,10 @@
|
|||||||
#define REG_PTR(insn, pos, regs) \
|
#define REG_PTR(insn, pos, regs) \
|
||||||
(ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
|
(ulong *)((ulong)(regs) + REG_OFFSET(insn, pos))
|
||||||
|
|
||||||
#define GET_RM(insn) (((insn) >> 12) & 7)
|
#define GET_RM(insn) ((insn & MASK_FUNCT3) >> SHIFT_FUNCT3)
|
||||||
|
|
||||||
|
#define GET_RS1_NUM(insn) ((insn & MASK_RS1) >> 15)
|
||||||
|
#define GET_CSR_NUM(insn) ((insn & MASK_CSR) >> SHIFT_CSR)
|
||||||
|
|
||||||
#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs))
|
#define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs))
|
||||||
#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs))
|
#define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs))
|
||||||
@@ -959,7 +962,20 @@
|
|||||||
#define IMM_I(insn) ((s32)(insn) >> 20)
|
#define IMM_I(insn) ((s32)(insn) >> 20)
|
||||||
#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
|
#define IMM_S(insn) (((s32)(insn) >> 25 << 5) | \
|
||||||
(s32)(((insn) >> 7) & 0x1f))
|
(s32)(((insn) >> 7) & 0x1f))
|
||||||
|
|
||||||
#define MASK_FUNCT3 0x7000
|
#define MASK_FUNCT3 0x7000
|
||||||
|
#define MASK_RS1 0xf8000
|
||||||
|
#define MASK_CSR 0xfff00000
|
||||||
|
|
||||||
|
#define SHIFT_FUNCT3 12
|
||||||
|
#define SHIFT_CSR 20
|
||||||
|
|
||||||
|
#define CSRRW 1
|
||||||
|
#define CSRRS 2
|
||||||
|
#define CSRRC 3
|
||||||
|
#define CSRRWI 5
|
||||||
|
#define CSRRSI 6
|
||||||
|
#define CSRRCI 7
|
||||||
|
|
||||||
/* clang-format on */
|
/* clang-format on */
|
||||||
|
|
||||||
|
@@ -15,7 +15,6 @@
|
|||||||
#include <sbi/sbi_types.h>
|
#include <sbi/sbi_types.h>
|
||||||
|
|
||||||
#define GET_PRECISION(insn) (((insn) >> 25) & 3)
|
#define GET_PRECISION(insn) (((insn) >> 25) & 3)
|
||||||
#define GET_RM(insn) (((insn) >> 12) & 7)
|
|
||||||
#define PRECISION_S 0
|
#define PRECISION_S 0
|
||||||
#define PRECISION_D 1
|
#define PRECISION_D 1
|
||||||
|
|
||||||
|
@@ -48,9 +48,10 @@ static int misc_mem_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
|
|||||||
|
|
||||||
static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
|
static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
|
||||||
{
|
{
|
||||||
int do_write, rs1_num = (insn >> 15) & 0x1f;
|
bool do_write = false;
|
||||||
ulong rs1_val = GET_RS1(insn, regs);
|
int rs1_num = GET_RS1_NUM(insn);
|
||||||
int csr_num = (u32)insn >> 20;
|
ulong rs1_val = GET_RS1(insn, regs);
|
||||||
|
int csr_num = GET_CSR_NUM((u32)insn);
|
||||||
ulong prev_mode = (regs->mstatus & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT;
|
ulong prev_mode = (regs->mstatus & MSTATUS_MPP) >> MSTATUS_MPP_SHIFT;
|
||||||
ulong csr_val, new_csr_val;
|
ulong csr_val, new_csr_val;
|
||||||
|
|
||||||
@@ -60,32 +61,41 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
|
|||||||
return SBI_EFAIL;
|
return SBI_EFAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Ensure that we got CSR read/write instruction */
|
/* Ensure that we got CSR read/write instruction */
|
||||||
|
int funct3 = GET_RM(insn);
|
||||||
|
if (funct3 == 0 || funct3 == 4) {
|
||||||
|
sbi_printf("%s: Invalid opcode for CSR read/write instruction",
|
||||||
|
__func__);
|
||||||
|
return truly_illegal_insn(insn, regs);
|
||||||
|
}
|
||||||
|
|
||||||
if (sbi_emulate_csr_read(csr_num, regs, &csr_val))
|
if (sbi_emulate_csr_read(csr_num, regs, &csr_val))
|
||||||
return truly_illegal_insn(insn, regs);
|
return truly_illegal_insn(insn, regs);
|
||||||
|
|
||||||
do_write = rs1_num;
|
switch (funct3) {
|
||||||
switch (GET_RM(insn)) {
|
case CSRRW:
|
||||||
case 1:
|
|
||||||
new_csr_val = rs1_val;
|
new_csr_val = rs1_val;
|
||||||
do_write = 1;
|
do_write = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case CSRRS:
|
||||||
new_csr_val = csr_val | rs1_val;
|
new_csr_val = csr_val | rs1_val;
|
||||||
|
do_write = (rs1_num != 0);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case CSRRC:
|
||||||
new_csr_val = csr_val & ~rs1_val;
|
new_csr_val = csr_val & ~rs1_val;
|
||||||
|
do_write = (rs1_num != 0);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case CSRRWI:
|
||||||
new_csr_val = rs1_num;
|
new_csr_val = rs1_num;
|
||||||
do_write = 1;
|
do_write = true;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case CSRRSI:
|
||||||
new_csr_val = csr_val | rs1_num;
|
new_csr_val = csr_val | rs1_num;
|
||||||
|
do_write = (rs1_num != 0);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case CSRRCI:
|
||||||
new_csr_val = csr_val & ~rs1_num;
|
new_csr_val = csr_val & ~rs1_num;
|
||||||
|
do_write = (rs1_num != 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return truly_illegal_insn(insn, regs);
|
return truly_illegal_insn(insn, regs);
|
||||||
|
Reference in New Issue
Block a user