^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* -*- linux-c -*- ------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright 2002-2007 H. Peter Anvin - All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * ----------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * mktables.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Make RAID-6 tables. This is a host user space program to be run at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * compile time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static uint8_t gfmul(uint8_t a, uint8_t b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) uint8_t v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) while (b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (b & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) v ^= a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) a = (a << 1) ^ (a & 0x80 ? 0x1d : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) b >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static uint8_t gfpow(uint8_t a, int b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) uint8_t v = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) b %= 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if (b < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) b += 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) while (b) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (b & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) v = gfmul(v, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) a = gfmul(a, a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) b >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) int main(int argc, char *argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int i, j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) uint8_t v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) uint8_t exptbl[256], invtbl[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) printf("#include <linux/export.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) printf("#include <linux/raid/pq.h>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) /* Compute multiplication table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) printf("\nconst u8 __attribute__((aligned(256)))\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "raid6_gfmul[256][256] =\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) printf("\t{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) for (j = 0; j < 256; j += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) printf("\t\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) for (k = 0; k < 8; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) printf("0x%02x,%c", gfmul(i, j + k),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) (k == 7) ? '\n' : ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) printf("\t},\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) printf("};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) printf("#ifdef __KERNEL__\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) printf("EXPORT_SYMBOL(raid6_gfmul);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) printf("#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Compute vector multiplication table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) printf("\nconst u8 __attribute__((aligned(256)))\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "raid6_vgfmul[256][32] =\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) "{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) for (i = 0; i < 256; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) printf("\t{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) for (j = 0; j < 16; j += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) printf("\t\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) for (k = 0; k < 8; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) printf("0x%02x,%c", gfmul(i, j + k),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) (k == 7) ? '\n' : ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) for (j = 0; j < 16; j += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) printf("\t\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) for (k = 0; k < 8; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) printf("0x%02x,%c", gfmul(i, (j + k) << 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) (k == 7) ? '\n' : ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) printf("\t},\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) printf("};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) printf("#ifdef __KERNEL__\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) printf("EXPORT_SYMBOL(raid6_vgfmul);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) printf("#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Compute power-of-2 table (exponent) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) v = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) printf("\nconst u8 __attribute__((aligned(256)))\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) "raid6_gfexp[256] =\n" "{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) for (i = 0; i < 256; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) printf("\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) for (j = 0; j < 8; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) exptbl[i + j] = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) printf("0x%02x,%c", v, (j == 7) ? '\n' : ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) v = gfmul(v, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (v == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) v = 0; /* For entry 255, not a real entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) printf("};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) printf("#ifdef __KERNEL__\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) printf("EXPORT_SYMBOL(raid6_gfexp);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) printf("#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* Compute log-of-2 table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) printf("\nconst u8 __attribute__((aligned(256)))\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) "raid6_gflog[256] =\n" "{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) for (i = 0; i < 256; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) printf("\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) for (j = 0; j < 8; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) v = 255;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) for (k = 0; k < 256; k++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (exptbl[k] == (i + j)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) v = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) printf("0x%02x,%c", v, (j == 7) ? '\n' : ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) printf("};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) printf("#ifdef __KERNEL__\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) printf("EXPORT_SYMBOL(raid6_gflog);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) printf("#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Compute inverse table x^-1 == x^254 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) printf("\nconst u8 __attribute__((aligned(256)))\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) "raid6_gfinv[256] =\n" "{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) for (i = 0; i < 256; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) printf("\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) for (j = 0; j < 8; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) invtbl[i + j] = v = gfpow(i + j, 254);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) printf("0x%02x,%c", v, (j == 7) ? '\n' : ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) printf("};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) printf("#ifdef __KERNEL__\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) printf("EXPORT_SYMBOL(raid6_gfinv);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) printf("#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* Compute inv(2^x + 1) (exponent-xor-inverse) table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) printf("\nconst u8 __attribute__((aligned(256)))\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) "raid6_gfexi[256] =\n" "{\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (i = 0; i < 256; i += 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) printf("\t");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) for (j = 0; j < 8; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) printf("0x%02x,%c", invtbl[exptbl[i + j] ^ 1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) (j == 7) ? '\n' : ' ');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) printf("};\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) printf("#ifdef __KERNEL__\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) printf("EXPORT_SYMBOL(raid6_gfexi);\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) printf("#endif\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }