Signed-off-by: Ralf Ramsauer <[email protected]>
---
 hypervisor/arch/riscv/include/asm/bitops.h | 54 ++++++++++++++++++----
 1 file changed, 46 insertions(+), 8 deletions(-)

diff --git a/hypervisor/arch/riscv/include/asm/bitops.h 
b/hypervisor/arch/riscv/include/asm/bitops.h
index 4b7e31b1..f62f382a 100644
--- a/hypervisor/arch/riscv/include/asm/bitops.h
+++ b/hypervisor/arch/riscv/include/asm/bitops.h
@@ -2,9 +2,11 @@
  * Jailhouse, a Linux-based partitioning hypervisor
  *
  * Copyright (c) Siemens AG, 2020
+ * Copyright (c) OTH Regensburg, 2022
  *
  * Authors:
- *  Jan Kiszka <[email protected]>
+ *  Konrad Schwarz <[email protected]>
+ *  Ralf Ramsauer <[email protected]>
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
@@ -13,25 +15,61 @@
 #ifndef _JAILHOUSE_ASM_BITOPS_H
 #define _JAILHOUSE_ASM_BITOPS_H
 
+/*
+ * TBD: Introduce generic arch-independent bitops? This routine is shared with
+ * arm-common
+ */
 static inline __attribute__((always_inline)) int
 test_bit(unsigned int nr, const volatile unsigned long *addr)
 {
-       return 0;
+       return ((1UL << (nr % BITS_PER_LONG)) &
+               (addr[nr / BITS_PER_LONG])) != 0;
 }
 
-static inline int atomic_test_and_set_bit(int nr, volatile unsigned long *addr)
+static inline long unsigned atomic_test_and_set_bit(int nr, volatile unsigned 
long *addr)
 {
-       return 0;
+       unsigned long res, mask;
+
+       mask = 1UL << (nr % BITS_PER_LONG);
+       asm volatile("amoor.w.aqrl %0, %2, %1"
+                    : "=r"(res), "+A"(addr[nr / BITS_PER_LONG])
+                    : "r" (mask)
+                    : "memory");
+
+       return (res & mask) != 0;
 }
 
-static inline unsigned long ffzl(unsigned long word)
+/*
+ * note: the RISC-V Bit Manipulation standard extension will undoubtedly
+ * have more performant implementations of these routines
+ * Returns the position of the least significant 1, MSB=31, LSB=0
+ * CAUTION: in contrast to POSIX ffs(), LSB = 0
+ */
+static inline unsigned long ffsl(unsigned long word)
 {
-       return 0;
+       register int result;
+
+       if (!word)
+               return BITS_PER_LONG;
+       result = BITS_PER_LONG - 1;
+
+       word = (word - 1) ^ word;
+       /* word now contains 0s followed by n 1s, if
+       n - 1 was the least significant set bit */
+
+       while (0 <= (long) word) {
+               word <<= 1;
+               --result;
+       }
+       return result;
 }
 
-static inline unsigned long ffsl(unsigned long word)
+/* Returns the position of the least significant 0, MSB=31, LSB=0
+ * CAUTION: in contrast to the POSIX ffs(), LSB = 0
+ */
+static inline unsigned long ffzl (register unsigned long word)
 {
-       return 0;
+       return ffsl(~word);
 }
 
 #endif /* !_JAILHOUSE_ASM_BITOPS_H */
-- 
2.36.1

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jailhouse-dev/20220627132905.4338-6-ralf.ramsauer%40oth-regensburg.de.

Reply via email to