diff options
author | Atish Patra <atish.patra@wdc.com> | 2019-11-25 10:33:47 +0300 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2019-12-23 06:42:13 +0300 |
commit | 9777aeef41a613b3c27056a695d4d6007760b3a8 (patch) | |
tree | a50c68b24fa6caf5932f0b96aafaf2509cc6be62 /include/sbi/sbi_bitops.h | |
parent | 109266397a6d8a37f4450c5ff80ea3737a6acd3e (diff) | |
download | opensbi-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.h | 74 |
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 |