Module Name:    src
Committed By:   simonb
Date:           Tue Nov 15 14:33:34 UTC 2022

Modified Files:
        src/sys/arch/riscv/include: sysreg.h
        src/sys/arch/riscv/riscv: pmap_machdep.c riscv_machdep.c vm_machdep.c

Log Message:
Use similar macro-magic to aarch64 armreg.h to add per-csr
read/write/set-bits/clear-bits inline functions.  Keep the
open-coded 32-bit version of riscvreg_cycle_read() than reads
a 64-bit cycle counter values.

Added benefit of fixing these so that the inline asm uses __volatile
and aren't opmtimised to nops by the compiler.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/riscv/include/sysreg.h
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/riscv/riscv/pmap_machdep.c
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/riscv/riscv/riscv_machdep.c
cvs rdiff -u -r1.5 -r1.6 src/sys/arch/riscv/riscv/vm_machdep.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/riscv/include/sysreg.h
diff -u src/sys/arch/riscv/include/sysreg.h:1.24 src/sys/arch/riscv/include/sysreg.h:1.25
--- src/sys/arch/riscv/include/sysreg.h:1.24	Sun Nov 13 08:13:55 2022
+++ src/sys/arch/riscv/include/sysreg.h	Tue Nov 15 14:33:33 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: sysreg.h,v 1.24 2022/11/13 08:13:55 skrll Exp $ */
+/* $NetBSD: sysreg.h,v 1.25 2022/11/15 14:33:33 simonb Exp $ */
 
 /*
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -104,7 +104,64 @@ riscvreg_fcsr_write_frm(uint32_t __new)
 	return __SHIFTOUT(__old, FCSR_FRM);
 }
 
+
+#define	RISCVREG_READ_INLINE(regname)					\
+static inline uintptr_t							\
+csr_##regname##_read(void)						\
+{									\
+	uintptr_t __rv;							\
+	asm volatile("csrr %0, " #regname : "=r"(__rv) :: "memory");	\
+	return __rv;							\
+}
+
+#define	RISCVREG_WRITE_INLINE(regname)					\
+static inline void							\
+csr_##regname##_write(uintptr_t __val)					\
+{									\
+	asm volatile("csrw " #regname ", %0" :: "r"(__val) : "memory");	\
+}
+
+#define	RISCVREG_SET_INLINE(regname)					\
+static inline void							\
+csr_##regname##_set(uintptr_t __mask)					\
+{									\
+	if (__builtin_constant_p(__mask) && __mask < 0x20) {		\
+		asm volatile("csrsi " #regname ", %0" :: "i"(__mask) :	\
+		    "memory");						\
+	} else {							\
+		asm volatile("csrs " #regname ", %0" :: "r"(__mask) :	\
+		    "memory");						\
+	}								\
+}
+
+#define	RISCVREG_CLEAR_INLINE(regname)					\
+static inline void							\
+csr_##regname##_clear(uintptr_t __mask)					\
+{									\
+	if (__builtin_constant_p(__mask) && __mask < 0x20) {		\
+		asm volatile("csrci " #regname ", %0" :: "i"(__mask) :	\
+		    "memory");						\
+	} else {							\
+		asm volatile("csrc " #regname ", %0" :: "r"(__mask) :	\
+		    "memory");						\
+	}								\
+}
+
+#define	RISCVREG_READ_WRITE_INLINE(regname)				\
+RISCVREG_READ_INLINE(regname)						\
+RISCVREG_WRITE_INLINE(regname)
+#define	RISCVREG_SET_CLEAR_INLINE(regname)				\
+RISCVREG_SET_INLINE(regname)						\
+RISCVREG_CLEAR_INLINE(regname)
+#define	RISCVREG_READ_SET_CLEAR_INLINE(regname)				\
+RISCVREG_READ_INLINE(regname)						\
+RISCVREG_SET_CLEAR_INLINE(regname)
+#define	RISCVREG_READ_WRITE_SET_CLEAR_INLINE(regname)			\
+RISCVREG_READ_WRITE_INLINE(regname)					\
+RISCVREG_SET_CLEAR_INLINE(regname)
+
 /* Supervisor Status Register */
+RISCVREG_READ_SET_CLEAR_INLINE(sstatus)		// supervisor status register
 #ifdef _LP64
 #define	SR_WPRI		__BITS(62, 34) | __BITS(31,20) | __BIT(17) | \
 			    __BITS(12,9) | __BITS(7,6) | __BITS(3,2)
@@ -144,6 +201,7 @@ riscvreg_fcsr_write_frm(uint32_t __new)
 
 /* Supervisor interrupt registers */
 /* ... interrupt pending register (sip) */
+RISCVREG_READ_SET_CLEAR_INLINE(sip)		// supervisor interrupt pending
 			/* Bit (XLEN-1) - 10 is WIRI */
 #define	SIP_SEIP	__BIT(9)
 #define	SIP_UEIP	__BIT(8)
@@ -155,6 +213,7 @@ riscvreg_fcsr_write_frm(uint32_t __new)
 #define	SIP_USIP	__BIT(0)
 
 /* ... interrupt-enable register (sie) */
+RISCVREG_READ_SET_CLEAR_INLINE(sie)		// supervisor interrupt enable
 			/* Bit (XLEN-1) - 10 is WIRI */
 #define	SIE_SEIE	__BIT(9)
 #define	SIE_UEIE	__BIT(8)
@@ -177,38 +236,6 @@ riscvreg_fcsr_write_frm(uint32_t __new)
 #define	SR_KERNEL	(SR_SIE | SR_UIE)
 #endif
 
-static inline uintptr_t
-riscvreg_status_read(void)
-{
-	uintptr_t __sr;
-	__asm("csrr\t%0, sstatus" : "=r"(__sr));
-	return __sr;
-}
-
-static inline uintptr_t
-riscvreg_status_clear(uintptr_t __mask)
-{
-	uintptr_t __sr;
-	if (__builtin_constant_p(__mask) && __mask < 0x20) {
-		__asm("csrrci\t%0, sstatus, %1" : "=r"(__sr) : "i"(__mask));
-	} else {
-		__asm("csrrc\t%0, sstatus, %1" : "=r"(__sr) : "r"(__mask));
-	}
-	return __sr;
-}
-
-static inline uintptr_t
-riscvreg_status_set(uintptr_t __mask)
-{
-	uintptr_t __sr;
-	if (__builtin_constant_p(__mask) && __mask < 0x20) {
-		__asm("csrrsi\t%0, sstatus, %1" : "=r"(__sr) : "i"(__mask));
-	} else {
-		__asm("csrrs\t%0, sstatus, %1" : "=r"(__sr) : "r"(__mask));
-	}
-	return __sr;
-}
-
 // Cause register
 #define	CAUSE_INTERRUPT_P(cause)	((cause) & __BIT(XLEN-1))
 #define	CAUSE_CODE(cause)		((cause) & __BITS(XLEN-2, 0))
@@ -241,14 +268,13 @@ riscvreg_status_set(uintptr_t __mask)
 #define	IRQ_SUPERVISOR_EXTERNAL	9
 #define	IRQ_MACHINE_EXTERNAL	11
 
+RISCVREG_READ_INLINE(time)
+#ifdef _LP64
+RISCVREG_READ_INLINE(cycle)
+#else /* !_LP64 */
 static inline uint64_t
-riscvreg_cycle_read(void)
+csr_cycle_read(void)
 {
-#ifdef _LP64
-	uint64_t __lo;
-	__asm __volatile("csrr\t%0, cycle" : "=r"(__lo));
-	return __lo;
-#else
 	uint32_t __hi0, __hi1, __lo0;
 	do {
 		__asm __volatile(
@@ -260,8 +286,8 @@ riscvreg_cycle_read(void)
 			[__hi1] "=r"(__hi1));
 	} while (__hi0 != __hi1);
 	return ((uint64_t)__hi0 << 32) | (uint64_t)__lo0;
-#endif
 }
+#endif /* !_LP64 */
 
 #ifdef _LP64
 #define	SATP_MODE		__BITS(63,60)
@@ -280,36 +306,25 @@ riscvreg_cycle_read(void)
 #define	SATP_PPN		__BITS(21,0)
 #endif
 
-static inline uintptr_t
-riscvreg_satp_read(void)
-{
-	uintptr_t satp;
-	__asm __volatile("csrr	%0, satp" : "=r" (satp));
-	return satp;
-}
-
-static inline void
-riscvreg_satp_write(uintptr_t satp)
-{
-	__asm __volatile("csrw	satp, %0" :: "r" (satp));
-}
+RISCVREG_READ_WRITE_INLINE(satp)
 
+/* Fake "ASID" CSR (a field of SATP register) functions */
 static inline uint32_t
-riscvreg_asid_read(void)
+csr_asid_read(void)
 {
-	uintptr_t satp;
-	__asm __volatile("csrr	%0, satp" : "=r" (satp));
+	uintptr_t satp = csr_satp_read();
 	return __SHIFTOUT(satp, SATP_ASID);
 }
 
 static inline void
-riscvreg_asid_write(uint32_t asid)
+csr_asid_write(uint32_t asid)
 {
 	uintptr_t satp;
-	__asm __volatile("csrr	%0, satp" : "=r" (satp));
+
+	satp = csr_satp_read();
 	satp &= ~SATP_ASID;
 	satp |= __SHIFTIN(asid, SATP_ASID);
-	__asm __volatile("csrw	satp, %0" :: "r" (satp));
+	csr_satp_write(satp);
 }
 
 #endif /* _RISCV_SYSREG_H_ */

Index: src/sys/arch/riscv/riscv/pmap_machdep.c
diff -u src/sys/arch/riscv/riscv/pmap_machdep.c:1.13 src/sys/arch/riscv/riscv/pmap_machdep.c:1.14
--- src/sys/arch/riscv/riscv/pmap_machdep.c:1.13	Sun Oct 16 08:43:44 2022
+++ src/sys/arch/riscv/riscv/pmap_machdep.c	Tue Nov 15 14:33:33 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: pmap_machdep.c,v 1.13 2022/10/16 08:43:44 skrll Exp $ */
+/* $NetBSD: pmap_machdep.c,v 1.14 2022/11/15 14:33:33 simonb Exp $ */
 
 /*
  * Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
 #define	__PMAP_PRIVATE
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pmap_machdep.c,v 1.13 2022/10/16 08:43:44 skrll Exp $");
+__RCSID("$NetBSD: pmap_machdep.c,v 1.14 2022/11/15 14:33:33 simonb Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -168,14 +168,14 @@ pmap_md_xtab_activate(struct pmap *pmap,
 	    __SHIFTIN(pai->pai_asid, SATP_ASID) |
 	    __SHIFTIN(pmap->pm_md.md_ppn, SATP_PPN);
 
-	riscvreg_satp_write(satp);
+	csr_satp_write(satp);
 }
 
 void
 pmap_md_xtab_deactivate(struct pmap *pmap)
 {
 
-	riscvreg_satp_write(0);
+	csr_satp_write(0);
 }
 
 void
@@ -276,13 +276,13 @@ pmap_bootstrap(vaddr_t vstart, vaddr_t v
 tlb_asid_t
 tlb_get_asid(void)
 {
-	return riscvreg_asid_read();
+	return csr_asid_read();
 }
 
 void
 tlb_set_asid(tlb_asid_t asid, struct pmap *pm)
 {
-	riscvreg_asid_write(asid);
+	csr_asid_write(asid);
 }
 
 #if 0

Index: src/sys/arch/riscv/riscv/riscv_machdep.c
diff -u src/sys/arch/riscv/riscv/riscv_machdep.c:1.23 src/sys/arch/riscv/riscv/riscv_machdep.c:1.24
--- src/sys/arch/riscv/riscv/riscv_machdep.c:1.23	Tue Oct 18 04:24:54 2022
+++ src/sys/arch/riscv/riscv/riscv_machdep.c	Tue Nov 15 14:33:33 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: riscv_machdep.c,v 1.23 2022/10/18 04:24:54 skrll Exp $	*/
+/*	$NetBSD: riscv_machdep.c,v 1.24 2022/11/15 14:33:33 simonb Exp $	*/
 
 /*-
  * Copyright (c) 2014, 2019, 2022 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #include "opt_riscv_debug.h"
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: riscv_machdep.c,v 1.23 2022/10/18 04:24:54 skrll Exp $");
+__RCSID("$NetBSD: riscv_machdep.c,v 1.24 2022/11/15 14:33:33 simonb Exp $");
 
 #include <sys/param.h>
 
@@ -122,9 +122,9 @@ delay(unsigned long us)
 {
 	const uint32_t cycles_per_us = curcpu()->ci_data.cpu_cc_freq / 1000000;
 	const uint64_t cycles = (uint64_t)us * cycles_per_us;
-	const uint64_t finish = riscvreg_cycle_read() + cycles;
+	const uint64_t finish = csr_cycle_read() + cycles;
 
-	while (riscvreg_cycle_read() < finish) {
+	while (csr_cycle_read() < finish) {
 		/* spin, baby spin */
 	}
 }

Index: src/sys/arch/riscv/riscv/vm_machdep.c
diff -u src/sys/arch/riscv/riscv/vm_machdep.c:1.5 src/sys/arch/riscv/riscv/vm_machdep.c:1.6
--- src/sys/arch/riscv/riscv/vm_machdep.c:1.5	Thu Sep 29 06:51:17 2022
+++ src/sys/arch/riscv/riscv/vm_machdep.c	Tue Nov 15 14:33:33 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vm_machdep.c,v 1.5 2022/09/29 06:51:17 skrll Exp $	*/
+/*	$NetBSD: vm_machdep.c,v 1.6 2022/11/15 14:33:33 simonb Exp $	*/
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.5 2022/09/29 06:51:17 skrll Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.6 2022/11/15 14:33:33 simonb Exp $");
 
 #define _PMAP_PRIVATE
 
@@ -111,7 +111,7 @@ cpu_lwp_fork(struct lwp *l1, struct lwp 
 	 */
 	--tf;	/* cpu_switchto uses trapframes */
 
-	tf->tf_sr = riscvreg_status_read();
+	tf->tf_sr = csr_sstatus_read();
 	tf->tf_s0 = (intptr_t)func;			/* S0 */
 	tf->tf_s1 = (intptr_t)arg;			/* S1 */
 	tf->tf_ra = (intptr_t)cpu_lwp_trampoline;	/* RA */

Reply via email to