diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 90c531e6abf5cf..465545200379d4 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -128,6 +128,7 @@ config RISCV select HAS_IOPORT if MMU select HAVE_ALIGNED_STRUCT_PAGE select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_BITREVERSE if RISCV_ISA_ZBKB select HAVE_ARCH_HUGE_VMALLOC if HAVE_ARCH_HUGE_VMAP select HAVE_ARCH_HUGE_VMAP if MMU && 64BIT select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL @@ -207,6 +208,7 @@ config RISCV select LOCK_MM_AND_FIND_VMA select MMU_GATHER_RCU_TABLE_FREE if SMP && MMU select MODULES_USE_ELF_RELA if MODULES + select NEED_BYTE_REVERSE_TABLE select OF select OF_EARLY_FLATTREE select OF_IRQ diff --git a/arch/riscv/include/asm/bitrev.h b/arch/riscv/include/asm/bitrev.h new file mode 100644 index 00000000000000..4b9b8d34cc3b2e --- /dev/null +++ b/arch/riscv/include/asm/bitrev.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __ASM_BITREV_H +#define __ASM_BITREV_H + +#include +#include +#include +#include + +static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x) +{ + unsigned long result; + + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) + return generic___bitrev32(x); + + asm volatile( + ".option push\n" + ".option arch,+zbkb\n" + "rev8 %0, %1\n" + "brev8 %0, %0\n" + ".option pop" + : "=r" (result) : "r" ((long)x) + ); + + return result >> (__riscv_xlen - 32); +} + +static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x) +{ + return __arch_bitrev32(x) >> 16; +} + +static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x) +{ + unsigned long result; + + if (!riscv_has_extension_likely(RISCV_ISA_EXT_ZBKB)) + return generic___bitrev8(x); + + asm volatile( + ".option push\n" + ".option arch,+zbkb\n" + "brev8 %0, %1\n" + ".option pop" + : "=r" (result) : "r" ((long)x) + ); + + return result; +} +#endif diff --git a/include/asm-generic/bitops/__bitrev.h b/include/asm-generic/bitops/__bitrev.h new file mode 100644 index 00000000000000..9d7d3d3693646e --- /dev/null +++ b/include/asm-generic/bitops/__bitrev.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_GENERIC_BITOPS___BITREV_H_ +#define _ASM_GENERIC_BITOPS___BITREV_H_ + +#ifdef CONFIG_NEED_BYTE_REVERSE_TABLE +#include + +extern u8 const byte_rev_table[256]; +static __always_inline __attribute_const__ u8 generic___bitrev8(u8 byte) +{ + return byte_rev_table[byte]; +} + +static __always_inline __attribute_const__ u16 generic___bitrev16(u16 x) +{ + return (generic___bitrev8(x & 0xff) << 8) | generic___bitrev8(x >> 8); +} + +static __always_inline __attribute_const__ u32 generic___bitrev32(u32 x) +{ + return (generic___bitrev16(x & 0xffff) << 16) | generic___bitrev16(x >> 16); +} +#endif /* CONFIG_NEED_BYTE_REVERSE_TABLE */ + +#endif /* _ASM_GENERIC_BITOPS___BITREV_H_ */ diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h index d35b8ec1c485cb..11620a70e77626 100644 --- a/include/linux/bitrev.h +++ b/include/linux/bitrev.h @@ -12,22 +12,10 @@ #define __bitrev8 __arch_bitrev8 #else -extern u8 const byte_rev_table[256]; -static inline u8 __bitrev8(u8 byte) -{ - return byte_rev_table[byte]; -} - -static inline u16 __bitrev16(u16 x) -{ - return (__bitrev8(x & 0xff) << 8) | __bitrev8(x >> 8); -} - -static inline u32 __bitrev32(u32 x) -{ - return (__bitrev16(x & 0xffff) << 16) | __bitrev16(x >> 16); -} - +#include +#define __bitrev32 generic___bitrev32 +#define __bitrev16 generic___bitrev16 +#define __bitrev8 generic___bitrev8 #endif /* CONFIG_HAVE_ARCH_BITREVERSE */ #define __bitrev8x4(x) (__bitrev32(swab32(x))) diff --git a/lib/Kconfig b/lib/Kconfig index 0f2fb96106476c..75cbb647b1da79 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -62,6 +62,10 @@ config HAVE_ARCH_BITREVERSE This option enables the use of hardware bit-reversal instructions on architectures which support such operations. +config NEED_BYTE_REVERSE_TABLE + bool + default y if !HAVE_ARCH_BITREVERSE + config ARCH_HAS_STRNCPY_FROM_USER bool diff --git a/lib/bitrev.c b/lib/bitrev.c index 81b56e0a7f325b..d9d5ee00229c9b 100644 --- a/lib/bitrev.c +++ b/lib/bitrev.c @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only -#ifndef CONFIG_HAVE_ARCH_BITREVERSE +#ifdef CONFIG_NEED_BYTE_REVERSE_TABLE #include #include #include @@ -44,4 +44,4 @@ const u8 byte_rev_table[256] = { }; EXPORT_SYMBOL_GPL(byte_rev_table); -#endif /* CONFIG_HAVE_ARCH_BITREVERSE */ +#endif /* CONFIG_NEED_BYTE_REVERSE_TABLE */