diff mbox series

[v2,1/8] lib: sbi: add 64 bit csr macros

Message ID 20250429142549.3673976-3-rkrcmar@ventanamicro.com
State New
Headers show
Series Reset more security-related CSRs | expand

Commit Message

Radim Krčmář April 29, 2025, 2:25 p.m. UTC
Most CSRs are XLEN bits wide, but some are 64 bit, so rv32 needs two
accesses, plaguing the code with ifdefs.

Add new helpers that split 64 bit operation into two operations on rv32.

The helpers don't use "csr + 0x10", but append "H" at the end of the csr
name to get a compile-time error when accessing a non 64 bit register.
This has the downside that you have to use the name when accessing them.
e.g. csr_read64(0x1234) or csr_read64(CSR_SATP) won't compile and the
error messages you get for these bugs are not straightforward.

Reviewed-by: Anup Patel <anup@brainfault.org>
Signed-off-by: Radim Krčmář <rkrcmar@ventanamicro.com>
---
v2:
* Remove redundant newline. [Anup]
* Add Reviewed-by [Anup]
---
 include/sbi/riscv_asm.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
diff mbox series

Patch

diff --git a/include/sbi/riscv_asm.h b/include/sbi/riscv_asm.h
index 4605db20bd7a..ef48dc89adf1 100644
--- a/include/sbi/riscv_asm.h
+++ b/include/sbi/riscv_asm.h
@@ -156,6 +156,26 @@ 
 				     : "memory");                  \
 	})
 
+#if __riscv_xlen == 64
+#define __csrrw64(op, csr, csrh, val) (true ? op(csr, val) : (uint64_t)csrh)
+#define __csrr64( op, csr, csrh)      (true ? op(csr)      : (uint64_t)csrh)
+#define __csrw64( op, csr, csrh, val) (true ? op(csr, val) : (uint64_t)csrh)
+#elif __riscv_xlen == 32
+#define __csrrw64(op, csr, csrh, val) (  op(csr, val) | (uint64_t)op(csrh, val >> 32) << 32)
+#define __csrr64( op, csr, csrh)      (  op(csr)      | (uint64_t)op(csrh)            << 32)
+#define __csrw64( op, csr, csrh, val) ({ op(csr, val);            op(csrh, val >> 32);    })
+#endif
+
+#define csr_swap64(        csr, val) __csrrw64(csr_swap,         csr, csr ## H, val)
+#define csr_read64(        csr)      __csrr64 (csr_read,         csr, csr ## H)
+#define csr_read_relaxed64(csr)      __csrr64 (csr_read_relaxed, csr, csr ## H)
+#define csr_write64(       csr, val) __csrw64 (csr_write,        csr, csr ## H, val)
+#define csr_read_set64(    csr, val) __csrrw64(csr_read_set,     csr, csr ## H, val)
+#define csr_set64(         csr, val) __csrw64 (csr_set,          csr, csr ## H, val)
+#define csr_clear64(       csr, val) __csrw64 (csr_clear,        csr, csr ## H, val)
+#define csr_read_clear64(  csr, val) __csrrw64(csr_read_clear,   csr, csr ## H, val)
+#define csr_clear64(       csr, val) __csrw64 (csr_clear,        csr, csr ## H, val)
+
 unsigned long csr_read_num(int csr_num);
 
 void csr_write_num(int csr_num, unsigned long val);