neon.c 2.1 KB

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