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