summaryrefslogtreecommitdiff
path: root/include/sbi/sbi_bitops.h
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2019-01-21 10:23:28 +0300
committerAnup Patel <anup@brainfault.org>2019-01-22 07:33:49 +0300
commit312b6bf32f51e530dd22746fe2a36d6459e29588 (patch)
treef7f9270897139dce8886b1db11f02cc087559f9f /include/sbi/sbi_bitops.h
parent784a4657c0957e7f9561fd2d87930ba008643c1e (diff)
downloadopensbi-312b6bf32f51e530dd22746fe2a36d6459e29588.tar.xz
lib: Add atomic bit set/clear operations.
Add addtional functionlities for set/clear bits atomically. Signed-off-by: Atish Patra <atish.patra@wdc.com>
Diffstat (limited to 'include/sbi/sbi_bitops.h')
-rw-r--r--include/sbi/sbi_bitops.h98
1 files changed, 98 insertions, 0 deletions
diff --git a/include/sbi/sbi_bitops.h b/include/sbi/sbi_bitops.h
new file mode 100644
index 0000000..c7a6e88
--- /dev/null
+++ b/include/sbi/sbi_bitops.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2018 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Atish Patra<atish.patra@wdc.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef __SBI_BITOPS_H__
+#define __SBI_BITOPS_H__
+
+#include <sbi/sbi_bits.h>
+#include <sbi/riscv_asm.h>
+
+/**
+ * ffs - Find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+static inline int ffs(int x)
+{
+ int r = 1;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff)) {
+ x >>= 16;
+ r += 16;
+ }
+ if (!(x & 0xff)) {
+ x >>= 8;
+ r += 8;
+ }
+ if (!(x & 0xf)) {
+ x >>= 4;
+ r += 4;
+ }
+ if (!(x & 3)) {
+ x >>= 2;
+ r += 2;
+ }
+ if (!(x & 1)) {
+ x >>= 1;
+ r += 1;
+ }
+ return r;
+}
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static inline int __ffs(unsigned long word)
+{
+ int num = 0;
+
+#if BITS_PER_LONG == 64
+ if ((word & 0xffffffff) == 0) {
+ num += 32;
+ word >>= 32;
+ }
+#endif
+ if ((word & 0xffff) == 0) {
+ num += 16;
+ word >>= 16;
+ }
+ if ((word & 0xff) == 0) {
+ num += 8;
+ word >>= 8;
+ }
+ if ((word & 0xf) == 0) {
+ num += 4;
+ word >>= 4;
+ }
+ if ((word & 0x3) == 0) {
+ num += 2;
+ word >>= 2;
+ }
+ if ((word & 0x1) == 0)
+ num += 1;
+ return num;
+}
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#define ffz(x) __ffs(~(x))
+
+#endif