crc32be-vx.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Hardware-accelerated CRC-32 variants for Linux on z Systems
  4. *
  5. * Use the z/Architecture Vector Extension Facility to accelerate the
  6. * computing of CRC-32 checksums.
  7. *
  8. * This CRC-32 implementation algorithm processes the most-significant
  9. * bit first (BE).
  10. *
  11. * Copyright IBM Corp. 2015
  12. * Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
  13. */
  14. #include <linux/types.h>
  15. #include <asm/fpu.h>
  16. #include "crc32-vx.h"
  17. /* Vector register range containing CRC-32 constants */
  18. #define CONST_R1R2 9
  19. #define CONST_R3R4 10
  20. #define CONST_R5 11
  21. #define CONST_R6 12
  22. #define CONST_RU_POLY 13
  23. #define CONST_CRC_POLY 14
  24. /*
  25. * The CRC-32 constant block contains reduction constants to fold and
  26. * process particular chunks of the input data stream in parallel.
  27. *
  28. * For the CRC-32 variants, the constants are precomputed according to
  29. * these definitions:
  30. *
  31. * R1 = x4*128+64 mod P(x)
  32. * R2 = x4*128 mod P(x)
  33. * R3 = x128+64 mod P(x)
  34. * R4 = x128 mod P(x)
  35. * R5 = x96 mod P(x)
  36. * R6 = x64 mod P(x)
  37. *
  38. * Barret reduction constant, u, is defined as floor(x**64 / P(x)).
  39. *
  40. * where P(x) is the polynomial in the normal domain and the P'(x) is the
  41. * polynomial in the reversed (bitreflected) domain.
  42. *
  43. * Note that the constant definitions below are extended in order to compute
  44. * intermediate results with a single VECTOR GALOIS FIELD MULTIPLY instruction.
  45. * The rightmost doubleword can be 0 to prevent contribution to the result or
  46. * can be multiplied by 1 to perform an XOR without the need for a separate
  47. * VECTOR EXCLUSIVE OR instruction.
  48. *
  49. * CRC-32 (IEEE 802.3 Ethernet, ...) polynomials:
  50. *
  51. * P(x) = 0x04C11DB7
  52. * P'(x) = 0xEDB88320
  53. */
  54. static unsigned long constants_CRC_32_BE[] = {
  55. 0x08833794c, 0x0e6228b11, /* R1, R2 */
  56. 0x0c5b9cd4c, 0x0e8a45605, /* R3, R4 */
  57. 0x0f200aa66, 1UL << 32, /* R5, x32 */
  58. 0x0490d678d, 1, /* R6, 1 */
  59. 0x104d101df, 0, /* u */
  60. 0x104C11DB7, 0, /* P(x) */
  61. };
  62. /**
  63. * crc32_be_vgfm_16 - Compute CRC-32 (BE variant) with vector registers
  64. * @crc: Initial CRC value, typically ~0.
  65. * @buf: Input buffer pointer, performance might be improved if the
  66. * buffer is on a doubleword boundary.
  67. * @size: Size of the buffer, must be 64 bytes or greater.
  68. *
  69. * Register usage:
  70. * V0: Initial CRC value and intermediate constants and results.
  71. * V1..V4: Data for CRC computation.
  72. * V5..V8: Next data chunks that are fetched from the input buffer.
  73. * V9..V14: CRC-32 constants.
  74. */
  75. u32 crc32_be_vgfm_16(u32 crc, unsigned char const *buf, size_t size)
  76. {
  77. /* Load CRC-32 constants */
  78. fpu_vlm(CONST_R1R2, CONST_CRC_POLY, &constants_CRC_32_BE);
  79. fpu_vzero(0);
  80. /* Load the initial CRC value into the leftmost word of V0. */
  81. fpu_vlvgf(0, crc, 0);
  82. /* Load a 64-byte data chunk and XOR with CRC */
  83. fpu_vlm(1, 4, buf);
  84. fpu_vx(1, 0, 1);
  85. buf += 64;
  86. size -= 64;
  87. while (size >= 64) {
  88. /* Load the next 64-byte data chunk into V5 to V8 */
  89. fpu_vlm(5, 8, buf);
  90. /*
  91. * Perform a GF(2) multiplication of the doublewords in V1 with
  92. * the reduction constants in V0. The intermediate result is
  93. * then folded (accumulated) with the next data chunk in V5 and
  94. * stored in V1. Repeat this step for the register contents
  95. * in V2, V3, and V4 respectively.
  96. */
  97. fpu_vgfmag(1, CONST_R1R2, 1, 5);
  98. fpu_vgfmag(2, CONST_R1R2, 2, 6);
  99. fpu_vgfmag(3, CONST_R1R2, 3, 7);
  100. fpu_vgfmag(4, CONST_R1R2, 4, 8);
  101. buf += 64;
  102. size -= 64;
  103. }
  104. /* Fold V1 to V4 into a single 128-bit value in V1 */
  105. fpu_vgfmag(1, CONST_R3R4, 1, 2);
  106. fpu_vgfmag(1, CONST_R3R4, 1, 3);
  107. fpu_vgfmag(1, CONST_R3R4, 1, 4);
  108. while (size >= 16) {
  109. fpu_vl(2, buf);
  110. fpu_vgfmag(1, CONST_R3R4, 1, 2);
  111. buf += 16;
  112. size -= 16;
  113. }
  114. /*
  115. * The R5 constant is used to fold a 128-bit value into an 96-bit value
  116. * that is XORed with the next 96-bit input data chunk. To use a single
  117. * VGFMG instruction, multiply the rightmost 64-bit with x^32 (1<<32) to
  118. * form an intermediate 96-bit value (with appended zeros) which is then
  119. * XORed with the intermediate reduction result.
  120. */
  121. fpu_vgfmg(1, CONST_R5, 1);
  122. /*
  123. * Further reduce the remaining 96-bit value to a 64-bit value using a
  124. * single VGFMG, the rightmost doubleword is multiplied with 0x1. The
  125. * intermediate result is then XORed with the product of the leftmost
  126. * doubleword with R6. The result is a 64-bit value and is subject to
  127. * the Barret reduction.
  128. */
  129. fpu_vgfmg(1, CONST_R6, 1);
  130. /*
  131. * The input values to the Barret reduction are the degree-63 polynomial
  132. * in V1 (R(x)), degree-32 generator polynomial, and the reduction
  133. * constant u. The Barret reduction result is the CRC value of R(x) mod
  134. * P(x).
  135. *
  136. * The Barret reduction algorithm is defined as:
  137. *
  138. * 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u
  139. * 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x)
  140. * 3. C(x) = R(x) XOR T2(x) mod x^32
  141. *
  142. * Note: To compensate the division by x^32, use the vector unpack
  143. * instruction to move the leftmost word into the leftmost doubleword
  144. * of the vector register. The rightmost doubleword is multiplied
  145. * with zero to not contribute to the intermediate results.
  146. */
  147. /* T1(x) = floor( R(x) / x^32 ) GF2MUL u */
  148. fpu_vupllf(2, 1);
  149. fpu_vgfmg(2, CONST_RU_POLY, 2);
  150. /*
  151. * Compute the GF(2) product of the CRC polynomial in VO with T1(x) in
  152. * V2 and XOR the intermediate result, T2(x), with the value in V1.
  153. * The final result is in the rightmost word of V2.
  154. */
  155. fpu_vupllf(2, 2);
  156. fpu_vgfmag(2, CONST_CRC_POLY, 2, 1);
  157. return fpu_vlgvf(2, 3);
  158. }