neon.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * linux/lib/raid6/neon.c - RAID6 syndrome calculation using ARM NEON intrinsics
  4. *
  5. * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
  6. */
  7. #include <linux/raid/pq.h>
  8. #ifdef __KERNEL__
  9. #include <asm/neon.h>
  10. #else
  11. #define kernel_neon_begin()
  12. #define kernel_neon_end()
  13. #define cpu_has_neon() (1)
  14. #endif
  15. /*
  16. * There are 2 reasons these wrappers are kept in a separate compilation unit
  17. * from the actual implementations in neonN.c (generated from neon.uc by
  18. * unroll.awk):
  19. * - the actual implementations use NEON intrinsics, and the GCC support header
  20. * (arm_neon.h) is not fully compatible (type wise) with the kernel;
  21. * - the neonN.c files are compiled with -mfpu=neon and optimization enabled,
  22. * and we have to make sure that we never use *any* NEON/VFP instructions
  23. * outside a kernel_neon_begin()/kernel_neon_end() pair.
  24. */
  25. #define RAID6_NEON_WRAPPER(_n) \
  26. static void raid6_neon ## _n ## _gen_syndrome(int disks, \
  27. size_t bytes, void **ptrs) \
  28. { \
  29. void raid6_neon ## _n ## _gen_syndrome_real(int, \
  30. unsigned long, void**); \
  31. kernel_neon_begin(); \
  32. raid6_neon ## _n ## _gen_syndrome_real(disks, \
  33. (unsigned long)bytes, ptrs); \
  34. kernel_neon_end(); \
  35. } \
  36. static void raid6_neon ## _n ## _xor_syndrome(int disks, \
  37. int start, int stop, \
  38. size_t bytes, void **ptrs) \
  39. { \
  40. void raid6_neon ## _n ## _xor_syndrome_real(int, \
  41. int, int, unsigned long, void**); \
  42. kernel_neon_begin(); \
  43. raid6_neon ## _n ## _xor_syndrome_real(disks, \
  44. start, stop, (unsigned long)bytes, ptrs); \
  45. kernel_neon_end(); \
  46. } \
  47. struct raid6_calls const raid6_neonx ## _n = { \
  48. raid6_neon ## _n ## _gen_syndrome, \
  49. raid6_neon ## _n ## _xor_syndrome, \
  50. raid6_have_neon, \
  51. "neonx" #_n, \
  52. 0 \
  53. }
  54. static int raid6_have_neon(void)
  55. {
  56. return cpu_has_neon();
  57. }
  58. RAID6_NEON_WRAPPER(1);
  59. RAID6_NEON_WRAPPER(2);
  60. RAID6_NEON_WRAPPER(4);
  61. RAID6_NEON_WRAPPER(8);