0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/hardirq.h>
0010 #include <asm-generic/xor.h>
0011 #include <asm/hwcap.h>
0012 #include <asm/neon.h>
0013
0014 #ifdef CONFIG_KERNEL_MODE_NEON
0015
0016 extern struct xor_block_template const xor_block_inner_neon;
0017
0018 static void
0019 xor_neon_2(unsigned long bytes, unsigned long * __restrict p1,
0020 const unsigned long * __restrict p2)
0021 {
0022 kernel_neon_begin();
0023 xor_block_inner_neon.do_2(bytes, p1, p2);
0024 kernel_neon_end();
0025 }
0026
0027 static void
0028 xor_neon_3(unsigned long bytes, unsigned long * __restrict p1,
0029 const unsigned long * __restrict p2,
0030 const unsigned long * __restrict p3)
0031 {
0032 kernel_neon_begin();
0033 xor_block_inner_neon.do_3(bytes, p1, p2, p3);
0034 kernel_neon_end();
0035 }
0036
0037 static void
0038 xor_neon_4(unsigned long bytes, unsigned long * __restrict p1,
0039 const unsigned long * __restrict p2,
0040 const unsigned long * __restrict p3,
0041 const unsigned long * __restrict p4)
0042 {
0043 kernel_neon_begin();
0044 xor_block_inner_neon.do_4(bytes, p1, p2, p3, p4);
0045 kernel_neon_end();
0046 }
0047
0048 static void
0049 xor_neon_5(unsigned long bytes, unsigned long * __restrict p1,
0050 const unsigned long * __restrict p2,
0051 const unsigned long * __restrict p3,
0052 const unsigned long * __restrict p4,
0053 const unsigned long * __restrict p5)
0054 {
0055 kernel_neon_begin();
0056 xor_block_inner_neon.do_5(bytes, p1, p2, p3, p4, p5);
0057 kernel_neon_end();
0058 }
0059
0060 static struct xor_block_template xor_block_arm64 = {
0061 .name = "arm64_neon",
0062 .do_2 = xor_neon_2,
0063 .do_3 = xor_neon_3,
0064 .do_4 = xor_neon_4,
0065 .do_5 = xor_neon_5
0066 };
0067 #undef XOR_TRY_TEMPLATES
0068 #define XOR_TRY_TEMPLATES \
0069 do { \
0070 xor_speed(&xor_block_8regs); \
0071 xor_speed(&xor_block_32regs); \
0072 if (cpu_has_neon()) { \
0073 xor_speed(&xor_block_arm64);\
0074 } \
0075 } while (0)
0076
0077 #endif