summaryrefslogtreecommitdiff
path: root/include/sbi/sbi_bitops.h
diff options
context:
space:
mode:
authorAtish Patra <atish.patra@wdc.com>2019-11-25 10:33:47 +0300
committerAnup Patel <anup@brainfault.org>2019-12-23 06:42:13 +0300
commit9777aeef41a613b3c27056a695d4d6007760b3a8 (patch)
treea50c68b24fa6caf5932f0b96aafaf2509cc6be62 /include/sbi/sbi_bitops.h
parent109266397a6d8a37f4450c5ff80ea3737a6acd3e (diff)
downloadopensbi-9777aeef41a613b3c27056a695d4d6007760b3a8.tar.xz
lib: Add IPI extension in SBI
This patch adds new IPI extension which replaces ipi related v0.1 extensions. This also adds a new API for ipi sending as trap handling is not necessary in v0.2 SBI IPI related extensions. It also modifies the IPI sending code which now accepts hart mask as a value instead of S-mode virtual address. Thus, the caller should set it to exact hart mask value everytime. Signed-off-by: Atish Patra <atish.patra@wdc.com> Reviewed-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'include/sbi/sbi_bitops.h')
-rw-r--r--include/sbi/sbi_bitops.h74
1 files changed, 74 insertions, 0 deletions
diff --git a/include/sbi/sbi_bitops.h b/include/sbi/sbi_bitops.h
index ece6ec4..9d99299 100644
--- a/include/sbi/sbi_bitops.h
+++ b/include/sbi/sbi_bitops.h
@@ -95,4 +95,78 @@ static inline int __ffs(unsigned long word)
*/
#define ffz(x) __ffs(~(x))
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+
+static inline int fls(int x)
+{
+ int r = 32;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xffff0000u)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xff000000u)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xf0000000u)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xc0000000u)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000u)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
+
+/**
+ * __fls - find last (most-significant) set bit in a long word
+ * @word: the word to search
+ *
+ * Undefined if no set bit exists, so code should check against 0 first.
+ */
+static inline unsigned long __fls(unsigned long word)
+{
+ int num = BITS_PER_LONG - 1;
+
+#if BITS_PER_LONG == 64
+ if (!(word & (~0ul << 32))) {
+ num -= 32;
+ word <<= 32;
+ }
+#endif
+ if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
+ num -= 16;
+ word <<= 16;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
+ num -= 8;
+ word <<= 8;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
+ num -= 4;
+ word <<= 4;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
+ num -= 2;
+ word <<= 2;
+ }
+ if (!(word & (~0ul << (BITS_PER_LONG-1))))
+ num -= 1;
+ return num;
+}
+
#endif