OpenSBI Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn
@ 2024-07-01  2:45 zhangdongdong
  2024-07-01  9:20 ` Andrew Jones
  0 siblings, 1 reply; 5+ messages in thread
From: zhangdongdong @ 2024-07-01  2:45 UTC (permalink / raw)
  To: opensbi

From: Dongdong Zhang <zhangdongdong@eswincomputing.com>

- 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>
---
 include/sbi/riscv_encoding.h | 19 +++++++++++++++++-
 include/sbi/riscv_fp.h       |  1 -
 lib/sbi/sbi_illegal_insn.c   | 37 +++++++++++++++++++++++-------------
 3 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
index 477fa3a..5146654 100644
--- a/include/sbi/riscv_encoding.h
+++ b/include/sbi/riscv_encoding.h
@@ -947,7 +947,10 @@
 #define REG_PTR(insn, pos, regs)	\
 	(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_RS2(insn, regs)		(*REG_PTR(insn, SH_RS2, regs))
@@ -959,7 +962,21 @@
 #define IMM_I(insn)			((s32)(insn) >> 20)
 #define IMM_S(insn)			(((s32)(insn) >> 25 << 5) | \
 					 (s32)(((insn) >> 7) & 0x1f))
+
 #define MASK_FUNCT3			0x7000
+#define MASK_RS1			0xf8000
+#define MASK_CSR            0xfff
+
+#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 */
 
diff --git a/include/sbi/riscv_fp.h b/include/sbi/riscv_fp.h
index 3141c1c..f523c56 100644
--- a/include/sbi/riscv_fp.h
+++ b/include/sbi/riscv_fp.h
@@ -15,7 +15,6 @@
 #include <sbi/sbi_types.h>
 
 #define GET_PRECISION(insn) (((insn) >> 25) & 3)
-#define GET_RM(insn) (((insn) >> 12) & 7)
 #define PRECISION_S 0
 #define PRECISION_D 1
 
diff --git a/lib/sbi/sbi_illegal_insn.c b/lib/sbi/sbi_illegal_insn.c
index ed6f111..7086a5e 100644
--- a/lib/sbi/sbi_illegal_insn.c
+++ b/lib/sbi/sbi_illegal_insn.c
@@ -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)
 {
-	int do_write, rs1_num = (insn >> 15) & 0x1f;
-	ulong rs1_val = GET_RS1(insn, regs);
-	int csr_num   = (u32)insn >> 20;
+	bool do_write	= false;
+	int rs1_num	= GET_RS1_NUM(insn);
+	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 csr_val, new_csr_val;
 
@@ -60,32 +61,42 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
 		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 < 1 || funct3 > 3) && (funct3 < 5 || funct3 > 7)) {
+		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))
 		return truly_illegal_insn(insn, regs);
 
 	do_write = rs1_num;
-	switch (GET_RM(insn)) {
-	case 1:
+	switch (funct3) {
+	case CSRRW:
 		new_csr_val = rs1_val;
-		do_write    = 1;
+		do_write    = true;
 		break;
-	case 2:
+	case CSRRS:
 		new_csr_val = csr_val | rs1_val;
+		do_write    = (rs1_num != 0);
 		break;
-	case 3:
+	case CSRRC:
 		new_csr_val = csr_val & ~rs1_val;
+		do_write    = (rs1_num != 0);
 		break;
-	case 5:
+	case CSRRWI:
 		new_csr_val = rs1_num;
-		do_write    = 1;
+		do_write    = true;
 		break;
-	case 6:
+	case CSRRSI:
 		new_csr_val = csr_val | rs1_num;
+		do_write    = (rs1_num != 0);
 		break;
-	case 7:
+	case CSRRCI:
 		new_csr_val = csr_val & ~rs1_num;
+		do_write    = (rs1_num != 0);
 		break;
 	default:
 		return truly_illegal_insn(insn, regs);
-- 
2.17.1



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn
  2024-07-01  2:45 [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn zhangdongdong
@ 2024-07-01  9:20 ` Andrew Jones
  2024-07-03  1:45   ` DongdongZhang
  2024-07-03 11:00   ` Vivian Wang
  0 siblings, 2 replies; 5+ messages in thread
From: Andrew Jones @ 2024-07-01  9:20 UTC (permalink / raw)
  To: opensbi

On Mon, Jul 01, 2024 at 10:45:16AM GMT, zhangdongdong at eswincomputing.com wrote:
> From: Dongdong Zhang <zhangdongdong@eswincomputing.com>
> 
> - 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>
> ---
>  include/sbi/riscv_encoding.h | 19 +++++++++++++++++-
>  include/sbi/riscv_fp.h       |  1 -
>  lib/sbi/sbi_illegal_insn.c   | 37 +++++++++++++++++++++++-------------
>  3 files changed, 42 insertions(+), 15 deletions(-)
> 
> diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
> index 477fa3a..5146654 100644
> --- a/include/sbi/riscv_encoding.h
> +++ b/include/sbi/riscv_encoding.h
> @@ -947,7 +947,10 @@
>  #define REG_PTR(insn, pos, regs)	\
>  	(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_RS2(insn, regs)		(*REG_PTR(insn, SH_RS2, regs))
> @@ -959,7 +962,21 @@
>  #define IMM_I(insn)			((s32)(insn) >> 20)
>  #define IMM_S(insn)			(((s32)(insn) >> 25 << 5) | \
>  					 (s32)(((insn) >> 7) & 0x1f))
> +
>  #define MASK_FUNCT3			0x7000
> +#define MASK_RS1			0xf8000
> +#define MASK_CSR            0xfff
> +
> +#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 */
>  
> diff --git a/include/sbi/riscv_fp.h b/include/sbi/riscv_fp.h
> index 3141c1c..f523c56 100644
> --- a/include/sbi/riscv_fp.h
> +++ b/include/sbi/riscv_fp.h
> @@ -15,7 +15,6 @@
>  #include <sbi/sbi_types.h>
>  
>  #define GET_PRECISION(insn) (((insn) >> 25) & 3)
> -#define GET_RM(insn) (((insn) >> 12) & 7)
>  #define PRECISION_S 0
>  #define PRECISION_D 1
>  
> diff --git a/lib/sbi/sbi_illegal_insn.c b/lib/sbi/sbi_illegal_insn.c
> index ed6f111..7086a5e 100644
> --- a/lib/sbi/sbi_illegal_insn.c
> +++ b/lib/sbi/sbi_illegal_insn.c
> @@ -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)
>  {
> -	int do_write, rs1_num = (insn >> 15) & 0x1f;
> -	ulong rs1_val = GET_RS1(insn, regs);
> -	int csr_num   = (u32)insn >> 20;
> +	bool do_write	= false;
> +	int rs1_num	= GET_RS1_NUM(insn);
> +	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 csr_val, new_csr_val;
>  
> @@ -60,32 +61,42 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
>  		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 < 1 || funct3 > 3) && (funct3 < 5 || funct3 > 7)) {

This looks complicated. Isn't it just

 (func3 < 1 || func3 > 7 || func3 == 4)

Thanks,
drew

> +		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))
>  		return truly_illegal_insn(insn, regs);
>  
>  	do_write = rs1_num;
> -	switch (GET_RM(insn)) {
> -	case 1:
> +	switch (funct3) {
> +	case CSRRW:
>  		new_csr_val = rs1_val;
> -		do_write    = 1;
> +		do_write    = true;
>  		break;
> -	case 2:
> +	case CSRRS:
>  		new_csr_val = csr_val | rs1_val;
> +		do_write    = (rs1_num != 0);
>  		break;
> -	case 3:
> +	case CSRRC:
>  		new_csr_val = csr_val & ~rs1_val;
> +		do_write    = (rs1_num != 0);
>  		break;
> -	case 5:
> +	case CSRRWI:
>  		new_csr_val = rs1_num;
> -		do_write    = 1;
> +		do_write    = true;
>  		break;
> -	case 6:
> +	case CSRRSI:
>  		new_csr_val = csr_val | rs1_num;
> +		do_write    = (rs1_num != 0);
>  		break;
> -	case 7:
> +	case CSRRCI:
>  		new_csr_val = csr_val & ~rs1_num;
> +		do_write    = (rs1_num != 0);
>  		break;
>  	default:
>  		return truly_illegal_insn(insn, regs);
> -- 
> 2.17.1
> 
> 
> -- 
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn
  2024-07-01  9:20 ` Andrew Jones
@ 2024-07-03  1:45   ` DongdongZhang
  2024-07-03 11:00   ` Vivian Wang
  1 sibling, 0 replies; 5+ messages in thread
From: DongdongZhang @ 2024-07-03  1:45 UTC (permalink / raw)
  To: opensbi




> -----????-----???:"Andrew Jones" <ajones@ventanamicro.com>????:2024-07-01 17:20:37 (???)???:zhangdongdong at eswincomputing.com??:opensbi at lists.infradead.org??:Re: [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn
> 
> On Mon, Jul 01, 2024 at 10:45:16AM GMT, zhangdongdong at eswincomputing.com wrote:
> > From: Dongdong Zhang <zhangdongdong@eswincomputing.com>
> > 
> > - 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>
> > ---
> >  include/sbi/riscv_encoding.h | 19 +++++++++++++++++-
> >  include/sbi/riscv_fp.h       |  1 -
> >  lib/sbi/sbi_illegal_insn.c   | 37 +++++++++++++++++++++++-------------
> >  3 files changed, 42 insertions(+), 15 deletions(-)
> > 
> > diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
> > index 477fa3a..5146654 100644
> > --- a/include/sbi/riscv_encoding.h
> > +++ b/include/sbi/riscv_encoding.h
> > @@ -947,7 +947,10 @@
> >  #define REG_PTR(insn, pos, regs)	\
> >  	(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_RS2(insn, regs)		(*REG_PTR(insn, SH_RS2, regs))
> > @@ -959,7 +962,21 @@
> >  #define IMM_I(insn)			((s32)(insn) >> 20)
> >  #define IMM_S(insn)			(((s32)(insn) >> 25 << 5) | \
> >  					 (s32)(((insn) >> 7) & 0x1f))
> > +
> >  #define MASK_FUNCT3			0x7000
> > +#define MASK_RS1			0xf8000
> > +#define MASK_CSR            0xfff
> > +
> > +#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 */
> >  
> > diff --git a/include/sbi/riscv_fp.h b/include/sbi/riscv_fp.h
> > index 3141c1c..f523c56 100644
> > --- a/include/sbi/riscv_fp.h
> > +++ b/include/sbi/riscv_fp.h
> > @@ -15,7 +15,6 @@
> >  #include <sbi/sbi_types.h>
> >  
> >  #define GET_PRECISION(insn) (((insn) >> 25) & 3)
> > -#define GET_RM(insn) (((insn) >> 12) & 7)
> >  #define PRECISION_S 0
> >  #define PRECISION_D 1
> >  
> > diff --git a/lib/sbi/sbi_illegal_insn.c b/lib/sbi/sbi_illegal_insn.c
> > index ed6f111..7086a5e 100644
> > --- a/lib/sbi/sbi_illegal_insn.c
> > +++ b/lib/sbi/sbi_illegal_insn.c
> > @@ -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)
> >  {
> > -	int do_write, rs1_num = (insn >> 15) & 0x1f;
> > -	ulong rs1_val = GET_RS1(insn, regs);
> > -	int csr_num   = (u32)insn >> 20;
> > +	bool do_write	= false;
> > +	int rs1_num	= GET_RS1_NUM(insn);
> > +	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 csr_val, new_csr_val;
> >  
> > @@ -60,32 +61,42 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
> >  		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 < 1 || funct3 > 3) && (funct3 < 5 || funct3 > 7)) {
> 
> This looks complicated. Isn't it just
> 
>  (func3 < 1 || func3 > 7 || func3 == 4)
> 
> Thanks,
> drew
> 
Hi Drew,

Thank you for your feedback. You are right. I will update the patch as suggested.

Best regards,
Dongdong
> > +		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))
> >  		return truly_illegal_insn(insn, regs);
> >  
> >  	do_write = rs1_num;
> > -	switch (GET_RM(insn)) {
> > -	case 1:
> > +	switch (funct3) {
> > +	case CSRRW:
> >  		new_csr_val = rs1_val;
> > -		do_write    = 1;
> > +		do_write    = true;
> >  		break;
> > -	case 2:
> > +	case CSRRS:
> >  		new_csr_val = csr_val | rs1_val;
> > +		do_write    = (rs1_num != 0);
> >  		break;
> > -	case 3:
> > +	case CSRRC:
> >  		new_csr_val = csr_val & ~rs1_val;
> > +		do_write    = (rs1_num != 0);
> >  		break;
> > -	case 5:
> > +	case CSRRWI:
> >  		new_csr_val = rs1_num;
> > -		do_write    = 1;
> > +		do_write    = true;
> >  		break;
> > -	case 6:
> > +	case CSRRSI:
> >  		new_csr_val = csr_val | rs1_num;
> > +		do_write    = (rs1_num != 0);
> >  		break;
> > -	case 7:
> > +	case CSRRCI:
> >  		new_csr_val = csr_val & ~rs1_num;
> > +		do_write    = (rs1_num != 0);
> >  		break;
> >  	default:
> >  		return truly_illegal_insn(insn, regs);
> > -- 
> > 2.17.1
> > 
> > 
> > -- 
> > opensbi mailing list
> > opensbi at lists.infradead.org
> > http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn
  2024-07-01  9:20 ` Andrew Jones
  2024-07-03  1:45   ` DongdongZhang
@ 2024-07-03 11:00   ` Vivian Wang
  2024-07-04  7:33     ` DongdongZhang
  1 sibling, 1 reply; 5+ messages in thread
From: Vivian Wang @ 2024-07-03 11:00 UTC (permalink / raw)
  To: opensbi

(Resend, forgot to CC mailing list last time, sorry.)

On 7/1/24 17:20, Andrew Jones wrote:

> On Mon, Jul 01, 2024 at 10:45:16AM GMT, zhangdongdong at eswincomputing.com wrote:
>> From: Dongdong Zhang <zhangdongdong@eswincomputing.com>
>>
>> - 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>
>> ---
>>  include/sbi/riscv_encoding.h | 19 +++++++++++++++++-
>>  include/sbi/riscv_fp.h       |  1 -
>>  lib/sbi/sbi_illegal_insn.c   | 37 +++++++++++++++++++++++-------------
>>  3 files changed, 42 insertions(+), 15 deletions(-)
>>
>> diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
>> index 477fa3a..5146654 100644
>> --- a/include/sbi/riscv_encoding.h
>> +++ b/include/sbi/riscv_encoding.h
>> @@ -947,7 +947,10 @@
>>  #define REG_PTR(insn, pos, regs)	\
>>  	(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_RS2(insn, regs)		(*REG_PTR(insn, SH_RS2, regs))
>> @@ -959,7 +962,21 @@
>>  #define IMM_I(insn)			((s32)(insn) >> 20)
>>  #define IMM_S(insn)			(((s32)(insn) >> 25 << 5) | \
>>  					 (s32)(((insn) >> 7) & 0x1f))
>> +
>>  #define MASK_FUNCT3			0x7000
>> +#define MASK_RS1			0xf8000
>> +#define MASK_CSR            0xfff
>> +
>> +#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 */
>>  
>> diff --git a/include/sbi/riscv_fp.h b/include/sbi/riscv_fp.h
>> index 3141c1c..f523c56 100644
>> --- a/include/sbi/riscv_fp.h
>> +++ b/include/sbi/riscv_fp.h
>> @@ -15,7 +15,6 @@
>>  #include <sbi/sbi_types.h>
>>  
>>  #define GET_PRECISION(insn) (((insn) >> 25) & 3)
>> -#define GET_RM(insn) (((insn) >> 12) & 7)
>>  #define PRECISION_S 0
>>  #define PRECISION_D 1
>>  
>> diff --git a/lib/sbi/sbi_illegal_insn.c b/lib/sbi/sbi_illegal_insn.c
>> index ed6f111..7086a5e 100644
>> --- a/lib/sbi/sbi_illegal_insn.c
>> +++ b/lib/sbi/sbi_illegal_insn.c
>> @@ -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)
>>  {
>> -	int do_write, rs1_num = (insn >> 15) & 0x1f;
>> -	ulong rs1_val = GET_RS1(insn, regs);
>> -	int csr_num   = (u32)insn >> 20;
>> +	bool do_write	= false;
>> +	int rs1_num	= GET_RS1_NUM(insn);
>> +	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 csr_val, new_csr_val;
>>  
>> @@ -60,32 +61,42 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
>>  		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 < 1 || funct3 > 3) && (funct3 < 5 || funct3 > 7)) {
> This looks complicated. Isn't it just
>
>  (func3 < 1 || func3 > 7 || func3 == 4)
>
> Thanks,
> drew

Getting warmer but funct3 is just 3 bits, so it can't be > 7, right?
IIUC this is just (funct3 == 0 || funct3 == 4).

Vivian "dram" Wang

>> +		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))
>>  		return truly_illegal_insn(insn, regs);
>>  
>>  	do_write = rs1_num;
>> -	switch (GET_RM(insn)) {
>> -	case 1:
>> +	switch (funct3) {
>> +	case CSRRW:
>>  		new_csr_val = rs1_val;
>> -		do_write    = 1;
>> +		do_write    = true;
>>  		break;
>> -	case 2:
>> +	case CSRRS:
>>  		new_csr_val = csr_val | rs1_val;
>> +		do_write    = (rs1_num != 0);
>>  		break;
>> -	case 3:
>> +	case CSRRC:
>>  		new_csr_val = csr_val & ~rs1_val;
>> +		do_write    = (rs1_num != 0);
>>  		break;
>> -	case 5:
>> +	case CSRRWI:
>>  		new_csr_val = rs1_num;
>> -		do_write    = 1;
>> +		do_write    = true;
>>  		break;
>> -	case 6:
>> +	case CSRRSI:
>>  		new_csr_val = csr_val | rs1_num;
>> +		do_write    = (rs1_num != 0);
>>  		break;
>> -	case 7:
>> +	case CSRRCI:
>>  		new_csr_val = csr_val & ~rs1_num;
>> +		do_write    = (rs1_num != 0);
>>  		break;
>>  	default:
>>  		return truly_illegal_insn(insn, regs);
>> -- 
>> 2.17.1
>>
>>
>> -- 
>> opensbi mailing list
>> opensbi at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/opensbi



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn
  2024-07-03 11:00   ` Vivian Wang
@ 2024-07-04  7:33     ` DongdongZhang
  0 siblings, 0 replies; 5+ messages in thread
From: DongdongZhang @ 2024-07-04  7:33 UTC (permalink / raw)
  To: opensbi




> -----????-----???:"Vivian Wang" <uwu@dram.page>????:2024-07-03 19:00:27 (???)???:"Andrew Jones" <ajones@ventanamicro.com>, zhangdongdong at eswincomputing.com??:opensbi at lists.infradead.org??:Re: [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn
> 
> (Resend, forgot to CC mailing list last time, sorry.)
> 
> On 7/1/24 17:20, Andrew Jones wrote:
> 
> > On Mon, Jul 01, 2024 at 10:45:16AM GMT, zhangdongdong at eswincomputing.com wrote:
> >> From: Dongdong Zhang <zhangdongdong@eswincomputing.com>
> >>
> >> - 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>
> >> ---
> >>  include/sbi/riscv_encoding.h | 19 +++++++++++++++++-
> >>  include/sbi/riscv_fp.h       |  1 -
> >>  lib/sbi/sbi_illegal_insn.c   | 37 +++++++++++++++++++++++-------------
> >>  3 files changed, 42 insertions(+), 15 deletions(-)
> >>
> >> diff --git a/include/sbi/riscv_encoding.h b/include/sbi/riscv_encoding.h
> >> index 477fa3a..5146654 100644
> >> --- a/include/sbi/riscv_encoding.h
> >> +++ b/include/sbi/riscv_encoding.h
> >> @@ -947,7 +947,10 @@
> >>  #define REG_PTR(insn, pos, regs)	\
> >>  	(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_RS2(insn, regs)		(*REG_PTR(insn, SH_RS2, regs))
> >> @@ -959,7 +962,21 @@
> >>  #define IMM_I(insn)			((s32)(insn) >> 20)
> >>  #define IMM_S(insn)			(((s32)(insn) >> 25 << 5) | \
> >>  					 (s32)(((insn) >> 7) & 0x1f))
> >> +
> >>  #define MASK_FUNCT3			0x7000
> >> +#define MASK_RS1			0xf8000
> >> +#define MASK_CSR            0xfff
> >> +
> >> +#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 */
> >>  
> >> diff --git a/include/sbi/riscv_fp.h b/include/sbi/riscv_fp.h
> >> index 3141c1c..f523c56 100644
> >> --- a/include/sbi/riscv_fp.h
> >> +++ b/include/sbi/riscv_fp.h
> >> @@ -15,7 +15,6 @@
> >>  #include <sbi/sbi_types.h>
> >>  
> >>  #define GET_PRECISION(insn) (((insn) >> 25) & 3)
> >> -#define GET_RM(insn) (((insn) >> 12) & 7)
> >>  #define PRECISION_S 0
> >>  #define PRECISION_D 1
> >>  
> >> diff --git a/lib/sbi/sbi_illegal_insn.c b/lib/sbi/sbi_illegal_insn.c
> >> index ed6f111..7086a5e 100644
> >> --- a/lib/sbi/sbi_illegal_insn.c
> >> +++ b/lib/sbi/sbi_illegal_insn.c
> >> @@ -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)
> >>  {
> >> -	int do_write, rs1_num = (insn >> 15) & 0x1f;
> >> -	ulong rs1_val = GET_RS1(insn, regs);
> >> -	int csr_num   = (u32)insn >> 20;
> >> +	bool do_write	= false;
> >> +	int rs1_num	= GET_RS1_NUM(insn);
> >> +	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 csr_val, new_csr_val;
> >>  
> >> @@ -60,32 +61,42 @@ static int system_opcode_insn(ulong insn, struct sbi_trap_regs *regs)
> >>  		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 < 1 || funct3 > 3) && (funct3 < 5 || funct3 > 7)) {
> > This looks complicated. Isn't it just
> >
> >  (func3 < 1 || func3 > 7 || func3 == 4)
> >
> > Thanks,
> > drew
> 
> Getting warmer but funct3 is just 3 bits, so it can't be > 7, right?
> IIUC this is just (funct3 == 0 || funct3 == 4).
> 
> Vivian "dram" Wang

You are right. Your code is more concise and clear.

Thanks,
Dongdong
> 
> >> +		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))
> >>  		return truly_illegal_insn(insn, regs);
> >>  
> >>  	do_write = rs1_num;
> >> -	switch (GET_RM(insn)) {
> >> -	case 1:
> >> +	switch (funct3) {
> >> +	case CSRRW:
> >>  		new_csr_val = rs1_val;
> >> -		do_write    = 1;
> >> +		do_write    = true;
> >>  		break;
> >> -	case 2:
> >> +	case CSRRS:
> >>  		new_csr_val = csr_val | rs1_val;
> >> +		do_write    = (rs1_num != 0);
> >>  		break;
> >> -	case 3:
> >> +	case CSRRC:
> >>  		new_csr_val = csr_val & ~rs1_val;
> >> +		do_write    = (rs1_num != 0);
> >>  		break;
> >> -	case 5:
> >> +	case CSRRWI:
> >>  		new_csr_val = rs1_num;
> >> -		do_write    = 1;
> >> +		do_write    = true;
> >>  		break;
> >> -	case 6:
> >> +	case CSRRSI:
> >>  		new_csr_val = csr_val | rs1_num;
> >> +		do_write    = (rs1_num != 0);
> >>  		break;
> >> -	case 7:
> >> +	case CSRRCI:
> >>  		new_csr_val = csr_val & ~rs1_num;
> >> +		do_write    = (rs1_num != 0);
> >>  		break;
> >>  	default:
> >>  		return truly_illegal_insn(insn, regs);
> >> -- 
> >> 2.17.1
> >>
> >>
> >> -- 
> >> opensbi mailing list
> >> opensbi at lists.infradead.org
> >> http://lists.infradead.org/mailman/listinfo/opensbi

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-07-04  7:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-01  2:45 [PATCH] lib:sbi: Enhance CSR Handling in system_opcode_insn zhangdongdong
2024-07-01  9:20 ` Andrew Jones
2024-07-03  1:45   ` DongdongZhang
2024-07-03 11:00   ` Vivian Wang
2024-07-04  7:33     ` DongdongZhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox