xref: /isa-l/erasure_code/erasure_code_update_test.c (revision 300260a4d902423a8a69f0f7d74e6abaa33ded27)
100c1efc1SGreg Tucker /**********************************************************************
200c1efc1SGreg Tucker   Copyright(c) 2011-2015 Intel Corporation All rights reserved.
300c1efc1SGreg Tucker 
400c1efc1SGreg Tucker   Redistribution and use in source and binary forms, with or without
500c1efc1SGreg Tucker   modification, are permitted provided that the following conditions
600c1efc1SGreg Tucker   are met:
700c1efc1SGreg Tucker     * Redistributions of source code must retain the above copyright
800c1efc1SGreg Tucker       notice, this list of conditions and the following disclaimer.
900c1efc1SGreg Tucker     * Redistributions in binary form must reproduce the above copyright
1000c1efc1SGreg Tucker       notice, this list of conditions and the following disclaimer in
1100c1efc1SGreg Tucker       the documentation and/or other materials provided with the
1200c1efc1SGreg Tucker       distribution.
1300c1efc1SGreg Tucker     * Neither the name of Intel Corporation nor the names of its
1400c1efc1SGreg Tucker       contributors may be used to endorse or promote products derived
1500c1efc1SGreg Tucker       from this software without specific prior written permission.
1600c1efc1SGreg Tucker 
1700c1efc1SGreg Tucker   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1800c1efc1SGreg Tucker   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1900c1efc1SGreg Tucker   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2000c1efc1SGreg Tucker   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2100c1efc1SGreg Tucker   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2200c1efc1SGreg Tucker   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2300c1efc1SGreg Tucker   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2400c1efc1SGreg Tucker   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2500c1efc1SGreg Tucker   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2600c1efc1SGreg Tucker   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2700c1efc1SGreg Tucker   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2800c1efc1SGreg Tucker **********************************************************************/
2900c1efc1SGreg Tucker 
3000c1efc1SGreg Tucker #include <stdio.h>
3100c1efc1SGreg Tucker #include <stdlib.h>
3200c1efc1SGreg Tucker #include <string.h> // for memset, memcmp
33402bd4f7STomasz Kantecki #include <assert.h>
3400c1efc1SGreg Tucker #include "erasure_code.h"
35112dd72cSGreg Tucker #include "test.h"
3600c1efc1SGreg Tucker 
3700c1efc1SGreg Tucker #ifndef ALIGN_SIZE
3800c1efc1SGreg Tucker #define ALIGN_SIZE 16
3900c1efc1SGreg Tucker #endif
4000c1efc1SGreg Tucker 
4100c1efc1SGreg Tucker // By default, test multibinary version
4200c1efc1SGreg Tucker #ifndef FUNCTION_UNDER_TEST
4300c1efc1SGreg Tucker #define FUNCTION_UNDER_TEST ec_encode_data_update
4400c1efc1SGreg Tucker #define REF_FUNCTION        ec_encode_data
4500c1efc1SGreg Tucker #endif
4600c1efc1SGreg Tucker 
4700c1efc1SGreg Tucker #define TEST_LEN  8192
4800c1efc1SGreg Tucker #define TEST_SIZE (TEST_LEN / 2)
4900c1efc1SGreg Tucker 
5000c1efc1SGreg Tucker #ifndef TEST_SOURCES
5100c1efc1SGreg Tucker #define TEST_SOURCES 127
5200c1efc1SGreg Tucker #endif
5300c1efc1SGreg Tucker #ifndef RANDOMS
5400c1efc1SGreg Tucker #define RANDOMS 200
5500c1efc1SGreg Tucker #endif
5600c1efc1SGreg Tucker 
5700c1efc1SGreg Tucker #define MMAX TEST_SOURCES
5800c1efc1SGreg Tucker #define KMAX TEST_SOURCES
5900c1efc1SGreg Tucker 
604f2d148aSRoy Oursler #define EFENCE_TEST_MAX_SIZE 0x100
614f2d148aSRoy Oursler 
6200c1efc1SGreg Tucker #ifdef EC_ALIGNED_ADDR
6300c1efc1SGreg Tucker // Define power of 2 range to check ptr, len alignment
6400c1efc1SGreg Tucker #define PTR_ALIGN_CHK_B 0
6500c1efc1SGreg Tucker #define LEN_ALIGN_CHK_B 0 // 0 for aligned only
6600c1efc1SGreg Tucker #else
6700c1efc1SGreg Tucker // Define power of 2 range to check ptr, len alignment
6800c1efc1SGreg Tucker #define PTR_ALIGN_CHK_B ALIGN_SIZE
6900c1efc1SGreg Tucker #define LEN_ALIGN_CHK_B ALIGN_SIZE // 0 for aligned only
7000c1efc1SGreg Tucker #endif
7100c1efc1SGreg Tucker 
7200c1efc1SGreg Tucker #ifndef TEST_SEED
7300c1efc1SGreg Tucker #define TEST_SEED 11
7400c1efc1SGreg Tucker #endif
7500c1efc1SGreg Tucker 
7600c1efc1SGreg Tucker #define str(s)  #s
7700c1efc1SGreg Tucker #define xstr(s) str(s)
7800c1efc1SGreg Tucker 
7900c1efc1SGreg Tucker typedef unsigned char u8;
8000c1efc1SGreg Tucker 
81*300260a4SMarcel Cornu void
dump(unsigned char * buf,int len)82*300260a4SMarcel Cornu dump(unsigned char *buf, int len)
8300c1efc1SGreg Tucker {
8400c1efc1SGreg Tucker         int i;
8500c1efc1SGreg Tucker         for (i = 0; i < len;) {
8600c1efc1SGreg Tucker                 printf(" %2x", 0xff & buf[i++]);
8700c1efc1SGreg Tucker                 if (i % 32 == 0)
8800c1efc1SGreg Tucker                         printf("\n");
8900c1efc1SGreg Tucker         }
9000c1efc1SGreg Tucker         printf("\n");
9100c1efc1SGreg Tucker }
9200c1efc1SGreg Tucker 
93*300260a4SMarcel Cornu void
dump_matrix(unsigned char ** s,int k,int m)94*300260a4SMarcel Cornu dump_matrix(unsigned char **s, int k, int m)
9500c1efc1SGreg Tucker {
9600c1efc1SGreg Tucker         int i, j;
9700c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
9800c1efc1SGreg Tucker                 for (j = 0; j < m; j++) {
9900c1efc1SGreg Tucker                         printf(" %2x", s[i][j]);
10000c1efc1SGreg Tucker                 }
10100c1efc1SGreg Tucker                 printf("\n");
10200c1efc1SGreg Tucker         }
10300c1efc1SGreg Tucker         printf("\n");
10400c1efc1SGreg Tucker }
10500c1efc1SGreg Tucker 
106*300260a4SMarcel Cornu void
dump_u8xu8(unsigned char * s,int k,int m)107*300260a4SMarcel Cornu dump_u8xu8(unsigned char *s, int k, int m)
10800c1efc1SGreg Tucker {
10900c1efc1SGreg Tucker         int i, j;
11000c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
11100c1efc1SGreg Tucker                 for (j = 0; j < m; j++) {
11200c1efc1SGreg Tucker                         printf(" %2x", 0xff & s[j + (i * m)]);
11300c1efc1SGreg Tucker                 }
11400c1efc1SGreg Tucker                 printf("\n");
11500c1efc1SGreg Tucker         }
11600c1efc1SGreg Tucker         printf("\n");
11700c1efc1SGreg Tucker }
11800c1efc1SGreg Tucker 
11900c1efc1SGreg Tucker // Generate Random errors
120*300260a4SMarcel Cornu static void
gen_err_list(unsigned char * src_err_list,unsigned char * src_in_err,int * pnerrs,int * pnsrcerrs,int k,int m)121*300260a4SMarcel Cornu gen_err_list(unsigned char *src_err_list, unsigned char *src_in_err, int *pnerrs, int *pnsrcerrs,
122*300260a4SMarcel Cornu              int k, int m)
12300c1efc1SGreg Tucker {
12400c1efc1SGreg Tucker         int i, err;
12500c1efc1SGreg Tucker         int nerrs = 0, nsrcerrs = 0;
12600c1efc1SGreg Tucker 
12700c1efc1SGreg Tucker         for (i = 0, nerrs = 0, nsrcerrs = 0; i < m && nerrs < m - k; i++) {
12800c1efc1SGreg Tucker                 err = 1 & rand();
12900c1efc1SGreg Tucker                 src_in_err[i] = err;
13000c1efc1SGreg Tucker                 if (err) {
13100c1efc1SGreg Tucker                         src_err_list[nerrs++] = i;
13200c1efc1SGreg Tucker                         if (i < k) {
13300c1efc1SGreg Tucker                                 nsrcerrs++;
13400c1efc1SGreg Tucker                         }
13500c1efc1SGreg Tucker                 }
13600c1efc1SGreg Tucker         }
13700c1efc1SGreg Tucker         if (nerrs == 0) { // should have at least one error
138*300260a4SMarcel Cornu                 while ((err = (rand() % KMAX)) >= m)
139*300260a4SMarcel Cornu                         ;
14000c1efc1SGreg Tucker                 src_err_list[nerrs++] = err;
14100c1efc1SGreg Tucker                 src_in_err[err] = 1;
14200c1efc1SGreg Tucker                 if (err < k)
14300c1efc1SGreg Tucker                         nsrcerrs = 1;
14400c1efc1SGreg Tucker         }
14500c1efc1SGreg Tucker         *pnerrs = nerrs;
14600c1efc1SGreg Tucker         *pnsrcerrs = nsrcerrs;
14700c1efc1SGreg Tucker         return;
14800c1efc1SGreg Tucker }
14900c1efc1SGreg Tucker 
15000c1efc1SGreg Tucker #define NO_INVERT_MATRIX -2
15100c1efc1SGreg Tucker // Generate decode matrix from encode matrix
152*300260a4SMarcel Cornu static int
gf_gen_decode_matrix(unsigned char * encode_matrix,unsigned char * decode_matrix,unsigned char * invert_matrix,unsigned int * decode_index,unsigned char * src_err_list,unsigned char * src_in_err,int nerrs,int nsrcerrs,int k,int m)153*300260a4SMarcel Cornu gf_gen_decode_matrix(unsigned char *encode_matrix, unsigned char *decode_matrix,
154*300260a4SMarcel Cornu                      unsigned char *invert_matrix, unsigned int *decode_index,
155*300260a4SMarcel Cornu                      unsigned char *src_err_list, unsigned char *src_in_err, int nerrs,
156*300260a4SMarcel Cornu                      int nsrcerrs, int k, int m)
15700c1efc1SGreg Tucker {
15800c1efc1SGreg Tucker         int i, j, p;
15900c1efc1SGreg Tucker         int r;
16000c1efc1SGreg Tucker         unsigned char *backup, *b, s;
16100c1efc1SGreg Tucker         int incr = 0;
16200c1efc1SGreg Tucker 
16300c1efc1SGreg Tucker         b = malloc(MMAX * KMAX);
16400c1efc1SGreg Tucker         backup = malloc(MMAX * KMAX);
16500c1efc1SGreg Tucker 
16600c1efc1SGreg Tucker         if (b == NULL || backup == NULL) {
16700c1efc1SGreg Tucker                 printf("Test failure! Error with malloc\n");
16800c1efc1SGreg Tucker                 free(b);
16900c1efc1SGreg Tucker                 free(backup);
17000c1efc1SGreg Tucker                 return -1;
17100c1efc1SGreg Tucker         }
17200c1efc1SGreg Tucker         // Construct matrix b by removing error rows
17300c1efc1SGreg Tucker         for (i = 0, r = 0; i < k; i++, r++) {
17400c1efc1SGreg Tucker                 while (src_in_err[r])
17500c1efc1SGreg Tucker                         r++;
17600c1efc1SGreg Tucker                 for (j = 0; j < k; j++) {
17700c1efc1SGreg Tucker                         b[k * i + j] = encode_matrix[k * r + j];
17800c1efc1SGreg Tucker                         backup[k * i + j] = encode_matrix[k * r + j];
17900c1efc1SGreg Tucker                 }
18000c1efc1SGreg Tucker                 decode_index[i] = r;
18100c1efc1SGreg Tucker         }
18200c1efc1SGreg Tucker         incr = 0;
18300c1efc1SGreg Tucker         while (gf_invert_matrix(b, invert_matrix, k) < 0) {
18400c1efc1SGreg Tucker                 if (nerrs == (m - k)) {
18500c1efc1SGreg Tucker                         free(b);
18600c1efc1SGreg Tucker                         free(backup);
18700c1efc1SGreg Tucker                         printf("BAD MATRIX\n");
18800c1efc1SGreg Tucker                         return NO_INVERT_MATRIX;
18900c1efc1SGreg Tucker                 }
19000c1efc1SGreg Tucker                 incr++;
19100c1efc1SGreg Tucker                 memcpy(b, backup, MMAX * KMAX);
19200c1efc1SGreg Tucker                 for (i = nsrcerrs; i < nerrs - nsrcerrs; i++) {
19300c1efc1SGreg Tucker                         if (src_err_list[i] == (decode_index[k - 1] + incr)) {
19400c1efc1SGreg Tucker                                 // skip the erased parity line
19500c1efc1SGreg Tucker                                 incr++;
19600c1efc1SGreg Tucker                                 continue;
19700c1efc1SGreg Tucker                         }
19800c1efc1SGreg Tucker                 }
19900c1efc1SGreg Tucker                 if (decode_index[k - 1] + incr >= m) {
20000c1efc1SGreg Tucker                         free(b);
20100c1efc1SGreg Tucker                         free(backup);
20200c1efc1SGreg Tucker                         printf("BAD MATRIX\n");
20300c1efc1SGreg Tucker                         return NO_INVERT_MATRIX;
20400c1efc1SGreg Tucker                 }
20500c1efc1SGreg Tucker                 decode_index[k - 1] += incr;
20600c1efc1SGreg Tucker                 for (j = 0; j < k; j++)
20700c1efc1SGreg Tucker                         b[k * (k - 1) + j] = encode_matrix[k * decode_index[k - 1] + j];
20800c1efc1SGreg Tucker         };
20900c1efc1SGreg Tucker 
21000c1efc1SGreg Tucker         for (i = 0; i < nsrcerrs; i++) {
21100c1efc1SGreg Tucker                 for (j = 0; j < k; j++) {
21200c1efc1SGreg Tucker                         decode_matrix[k * i + j] = invert_matrix[k * src_err_list[i] + j];
21300c1efc1SGreg Tucker                 }
21400c1efc1SGreg Tucker         }
21500c1efc1SGreg Tucker         /* src_err_list from encode_matrix * invert of b for parity decoding */
21600c1efc1SGreg Tucker         for (p = nsrcerrs; p < nerrs; p++) {
21700c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
21800c1efc1SGreg Tucker                         s = 0;
21900c1efc1SGreg Tucker                         for (j = 0; j < k; j++)
22000c1efc1SGreg Tucker                                 s ^= gf_mul(invert_matrix[j * k + i],
22100c1efc1SGreg Tucker                                             encode_matrix[k * src_err_list[p] + j]);
22200c1efc1SGreg Tucker 
22300c1efc1SGreg Tucker                         decode_matrix[k * p + i] = s;
22400c1efc1SGreg Tucker                 }
22500c1efc1SGreg Tucker         }
22600c1efc1SGreg Tucker         free(b);
22700c1efc1SGreg Tucker         free(backup);
22800c1efc1SGreg Tucker         return 0;
22900c1efc1SGreg Tucker }
23000c1efc1SGreg Tucker 
231*300260a4SMarcel Cornu int
main(int argc,char * argv[])232*300260a4SMarcel Cornu main(int argc, char *argv[])
23300c1efc1SGreg Tucker {
234a3e26043SPablo de Lara         int re = -1;
23500c1efc1SGreg Tucker         int i, j, p, rtest, m, k;
23600c1efc1SGreg Tucker         int nerrs, nsrcerrs;
23700c1efc1SGreg Tucker         void *buf;
23800c1efc1SGreg Tucker         unsigned int decode_index[MMAX];
239a3e26043SPablo de Lara         unsigned char *temp_buffs[TEST_SOURCES] = { NULL }, *buffs[TEST_SOURCES] = { NULL };
240a3e26043SPablo de Lara         unsigned char *update_buffs[TEST_SOURCES] = { NULL };
241*300260a4SMarcel Cornu         unsigned char *encode_matrix = NULL, *decode_matrix = NULL, *invert_matrix = NULL,
242*300260a4SMarcel Cornu                       *g_tbls = NULL;
24300c1efc1SGreg Tucker         unsigned char src_in_err[TEST_SOURCES], src_err_list[TEST_SOURCES];
24400c1efc1SGreg Tucker         unsigned char *recov[TEST_SOURCES];
24500c1efc1SGreg Tucker 
24600c1efc1SGreg Tucker         int rows, align, size;
24700c1efc1SGreg Tucker         unsigned char *efence_buffs[TEST_SOURCES];
24800c1efc1SGreg Tucker         unsigned char *efence_update_buffs[TEST_SOURCES];
24900c1efc1SGreg Tucker         unsigned int offset;
25000c1efc1SGreg Tucker         u8 *ubuffs[TEST_SOURCES];
25100c1efc1SGreg Tucker         u8 *update_ubuffs[TEST_SOURCES];
25200c1efc1SGreg Tucker         u8 *temp_ubuffs[TEST_SOURCES];
25300c1efc1SGreg Tucker 
25400c1efc1SGreg Tucker         printf("test " xstr(FUNCTION_UNDER_TEST) ": %dx%d ", TEST_SOURCES, TEST_LEN);
25500c1efc1SGreg Tucker         srand(TEST_SEED);
25600c1efc1SGreg Tucker 
25700c1efc1SGreg Tucker         // Allocate the arrays
25800c1efc1SGreg Tucker         for (i = 0; i < TEST_SOURCES; i++) {
25900c1efc1SGreg Tucker                 if (posix_memalign(&buf, 64, TEST_LEN)) {
26000c1efc1SGreg Tucker                         printf("alloc error: Fail");
261a3e26043SPablo de Lara                         goto exit;
26200c1efc1SGreg Tucker                 }
26300c1efc1SGreg Tucker                 buffs[i] = buf;
26400c1efc1SGreg Tucker         }
26500c1efc1SGreg Tucker 
26600c1efc1SGreg Tucker         for (i = 0; i < TEST_SOURCES; i++) {
26700c1efc1SGreg Tucker                 if (posix_memalign(&buf, 64, TEST_LEN)) {
26800c1efc1SGreg Tucker                         printf("alloc error: Fail");
269a3e26043SPablo de Lara                         goto exit;
27000c1efc1SGreg Tucker                 }
27100c1efc1SGreg Tucker                 temp_buffs[i] = buf;
272*300260a4SMarcel Cornu                 memset(temp_buffs[i], 0, TEST_LEN); // initialize the destination buffer to be zero
273*300260a4SMarcel Cornu                                                     // for update function
27400c1efc1SGreg Tucker         }
27500c1efc1SGreg Tucker 
27600c1efc1SGreg Tucker         for (i = 0; i < TEST_SOURCES; i++) {
27700c1efc1SGreg Tucker                 if (posix_memalign(&buf, 64, TEST_LEN)) {
27800c1efc1SGreg Tucker                         printf("alloc error: Fail");
279a3e26043SPablo de Lara                         goto exit;
28000c1efc1SGreg Tucker                 }
28100c1efc1SGreg Tucker                 update_buffs[i] = buf;
282*300260a4SMarcel Cornu                 memset(update_buffs[i], 0, TEST_LEN); // initialize the destination buffer to be
283*300260a4SMarcel Cornu                                                       // zero for update function
28400c1efc1SGreg Tucker         }
28500c1efc1SGreg Tucker         // Test erasure code by encode and recovery
28600c1efc1SGreg Tucker 
28700c1efc1SGreg Tucker         encode_matrix = malloc(MMAX * KMAX);
28800c1efc1SGreg Tucker         decode_matrix = malloc(MMAX * KMAX);
28900c1efc1SGreg Tucker         invert_matrix = malloc(MMAX * KMAX);
29000c1efc1SGreg Tucker         g_tbls = malloc(KMAX * TEST_SOURCES * 32);
291*300260a4SMarcel Cornu         if (encode_matrix == NULL || decode_matrix == NULL || invert_matrix == NULL ||
292*300260a4SMarcel Cornu             g_tbls == NULL) {
29300c1efc1SGreg Tucker                 printf("Test failure! Error with malloc\n");
294a3e26043SPablo de Lara                 goto exit;
29500c1efc1SGreg Tucker         }
29600c1efc1SGreg Tucker         // Pick a first test
29782a6ac65SRoy Oursler         m = 14;
29800c1efc1SGreg Tucker         k = 10;
299402bd4f7STomasz Kantecki         assert(!(m > MMAX || k > KMAX));
30000c1efc1SGreg Tucker 
30100c1efc1SGreg Tucker         // Make random data
30200c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
30300c1efc1SGreg Tucker                 for (j = 0; j < TEST_LEN; j++) {
30400c1efc1SGreg Tucker                         buffs[i][j] = rand();
30500c1efc1SGreg Tucker                         update_buffs[i][j] = buffs[i][j];
30600c1efc1SGreg Tucker                 }
30700c1efc1SGreg Tucker         }
30800c1efc1SGreg Tucker 
30900c1efc1SGreg Tucker         // Generate encode matrix encode_matrix
31000c1efc1SGreg Tucker         // The matrix generated by gf_gen_rs_matrix
31100c1efc1SGreg Tucker         // is not always invertable.
31200c1efc1SGreg Tucker         gf_gen_rs_matrix(encode_matrix, m, k);
31300c1efc1SGreg Tucker 
31400c1efc1SGreg Tucker         // Generate g_tbls from encode matrix encode_matrix
31500c1efc1SGreg Tucker         ec_init_tables(k, m - k, &encode_matrix[k * k], g_tbls);
31600c1efc1SGreg Tucker 
31700c1efc1SGreg Tucker         // Perform matrix dot_prod for EC encoding
31800c1efc1SGreg Tucker         // using g_tbls from encode matrix encode_matrix
31900c1efc1SGreg Tucker         REF_FUNCTION(TEST_LEN, k, m - k, g_tbls, buffs, &buffs[k]);
32000c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
32100c1efc1SGreg Tucker                 FUNCTION_UNDER_TEST(TEST_LEN, k, m - k, i, g_tbls, update_buffs[i],
32200c1efc1SGreg Tucker                                     &update_buffs[k]);
32300c1efc1SGreg Tucker         }
32400c1efc1SGreg Tucker         for (i = 0; i < m - k; i++) {
32500c1efc1SGreg Tucker                 if (0 != memcmp(update_buffs[k + i], buffs[k + i], TEST_LEN)) {
32600c1efc1SGreg Tucker                         printf("\nupdate_buffs%d  :", i);
32700c1efc1SGreg Tucker                         dump(update_buffs[k + i], 25);
32800c1efc1SGreg Tucker                         printf("buffs%d         :", i);
32900c1efc1SGreg Tucker                         dump(buffs[k + i], 25);
330a3e26043SPablo de Lara                         goto exit;
33100c1efc1SGreg Tucker                 }
33200c1efc1SGreg Tucker         }
33300c1efc1SGreg Tucker 
33400c1efc1SGreg Tucker         // Choose random buffers to be in erasure
33500c1efc1SGreg Tucker         memset(src_in_err, 0, TEST_SOURCES);
33600c1efc1SGreg Tucker         gen_err_list(src_err_list, src_in_err, &nerrs, &nsrcerrs, k, m);
33700c1efc1SGreg Tucker 
33800c1efc1SGreg Tucker         // Generate decode matrix
339*300260a4SMarcel Cornu         re = gf_gen_decode_matrix(encode_matrix, decode_matrix, invert_matrix, decode_index,
340*300260a4SMarcel Cornu                                   src_err_list, src_in_err, nerrs, nsrcerrs, k, m);
34100c1efc1SGreg Tucker         if (re != 0) {
34200c1efc1SGreg Tucker                 printf("Fail to gf_gen_decode_matrix\n");
343a3e26043SPablo de Lara                 goto exit;
34400c1efc1SGreg Tucker         }
34500c1efc1SGreg Tucker         // Pack recovery array as list of valid sources
34600c1efc1SGreg Tucker         // Its order must be the same as the order
34700c1efc1SGreg Tucker         // to generate matrix b in gf_gen_decode_matrix
34800c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
34900c1efc1SGreg Tucker                 recov[i] = update_buffs[decode_index[i]];
35000c1efc1SGreg Tucker         }
35100c1efc1SGreg Tucker 
35200c1efc1SGreg Tucker         // Recover data
35300c1efc1SGreg Tucker         ec_init_tables(k, nerrs, decode_matrix, g_tbls);
35400c1efc1SGreg Tucker         REF_FUNCTION(TEST_LEN, k, nerrs, g_tbls, recov, &temp_buffs[k]);
35500c1efc1SGreg Tucker         for (i = 0; i < nerrs; i++) {
35600c1efc1SGreg Tucker 
35700c1efc1SGreg Tucker                 if (0 != memcmp(temp_buffs[k + i], update_buffs[src_err_list[i]], TEST_LEN)) {
35800c1efc1SGreg Tucker                         printf("Fail error recovery (%d, %d, %d)\n", m, k, nerrs);
35900c1efc1SGreg Tucker                         printf(" - erase list = ");
36000c1efc1SGreg Tucker                         for (j = 0; j < nerrs; j++)
36100c1efc1SGreg Tucker                                 printf(" %d", src_err_list[j]);
36200c1efc1SGreg Tucker                         printf(" - Index = ");
36300c1efc1SGreg Tucker                         for (p = 0; p < k; p++)
36400c1efc1SGreg Tucker                                 printf(" %d", decode_index[p]);
36500c1efc1SGreg Tucker                         printf("\nencode_matrix:\n");
36600c1efc1SGreg Tucker                         dump_u8xu8((u8 *) encode_matrix, m, k);
36700c1efc1SGreg Tucker                         printf("inv b:\n");
36800c1efc1SGreg Tucker                         dump_u8xu8((u8 *) invert_matrix, k, k);
36900c1efc1SGreg Tucker                         printf("\ndecode_matrix:\n");
37000c1efc1SGreg Tucker                         dump_u8xu8((u8 *) decode_matrix, m, k);
37100c1efc1SGreg Tucker                         printf("recov %d:", src_err_list[i]);
37200c1efc1SGreg Tucker                         dump(temp_buffs[k + i], 25);
37300c1efc1SGreg Tucker                         printf("orig   :");
37400c1efc1SGreg Tucker                         dump(update_buffs[src_err_list[i]], 25);
375a3e26043SPablo de Lara                         re = -1;
376a3e26043SPablo de Lara                         goto exit;
37700c1efc1SGreg Tucker                 }
37800c1efc1SGreg Tucker         }
3792ca781dfSPablo de Lara #ifdef TEST_VERBOSE
38000c1efc1SGreg Tucker         putchar('.');
3812ca781dfSPablo de Lara #endif
38200c1efc1SGreg Tucker 
38300c1efc1SGreg Tucker         // Pick a first test
38400c1efc1SGreg Tucker         m = 7;
38500c1efc1SGreg Tucker         k = 5;
386a3e26043SPablo de Lara         if (m > MMAX || k > KMAX) {
387a3e26043SPablo de Lara                 re = -1;
388a3e26043SPablo de Lara                 goto exit;
389a3e26043SPablo de Lara         }
39000c1efc1SGreg Tucker 
39100c1efc1SGreg Tucker         // Zero the destination buffer for update function
39200c1efc1SGreg Tucker         for (i = k; i < TEST_SOURCES; i++) {
39300c1efc1SGreg Tucker                 memset(buffs[i], 0, TEST_LEN);
39400c1efc1SGreg Tucker                 memset(update_buffs[i], 0, TEST_LEN);
39500c1efc1SGreg Tucker         }
39600c1efc1SGreg Tucker         // Make random data
39700c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
39800c1efc1SGreg Tucker                 for (j = 0; j < TEST_LEN; j++) {
39900c1efc1SGreg Tucker                         buffs[i][j] = rand();
40000c1efc1SGreg Tucker                         update_buffs[i][j] = buffs[i][j];
40100c1efc1SGreg Tucker                 }
40200c1efc1SGreg Tucker         }
40300c1efc1SGreg Tucker 
40400c1efc1SGreg Tucker         // The matrix generated by gf_gen_cauchy1_matrix
40500c1efc1SGreg Tucker         // is always invertable.
40600c1efc1SGreg Tucker         gf_gen_cauchy1_matrix(encode_matrix, m, k);
40700c1efc1SGreg Tucker 
40800c1efc1SGreg Tucker         // Generate g_tbls from encode matrix encode_matrix
40900c1efc1SGreg Tucker         ec_init_tables(k, m - k, &encode_matrix[k * k], g_tbls);
41000c1efc1SGreg Tucker 
41100c1efc1SGreg Tucker         // Perform matrix dot_prod for EC encoding
41200c1efc1SGreg Tucker         // using g_tbls from encode matrix encode_matrix
41300c1efc1SGreg Tucker         REF_FUNCTION(TEST_LEN, k, m - k, g_tbls, buffs, &buffs[k]);
41400c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
41500c1efc1SGreg Tucker                 FUNCTION_UNDER_TEST(TEST_LEN, k, m - k, i, g_tbls, update_buffs[i],
41600c1efc1SGreg Tucker                                     &update_buffs[k]);
41700c1efc1SGreg Tucker         }
41800c1efc1SGreg Tucker         for (i = 0; i < m - k; i++) {
41900c1efc1SGreg Tucker                 if (0 != memcmp(update_buffs[k + i], buffs[k + i], TEST_LEN)) {
42000c1efc1SGreg Tucker                         printf("\nupdate_buffs%d  :", i);
42100c1efc1SGreg Tucker                         dump(update_buffs[k + i], 25);
42200c1efc1SGreg Tucker                         printf("buffs%d         :", i);
42300c1efc1SGreg Tucker                         dump(buffs[k + i], 25);
424a3e26043SPablo de Lara                         re = -1;
425a3e26043SPablo de Lara                         goto exit;
42600c1efc1SGreg Tucker                 }
42700c1efc1SGreg Tucker         }
42800c1efc1SGreg Tucker 
42900c1efc1SGreg Tucker         // Choose random buffers to be in erasure
43000c1efc1SGreg Tucker         memset(src_in_err, 0, TEST_SOURCES);
43100c1efc1SGreg Tucker         gen_err_list(src_err_list, src_in_err, &nerrs, &nsrcerrs, k, m);
43200c1efc1SGreg Tucker 
43300c1efc1SGreg Tucker         // Generate decode matrix
434*300260a4SMarcel Cornu         re = gf_gen_decode_matrix(encode_matrix, decode_matrix, invert_matrix, decode_index,
435*300260a4SMarcel Cornu                                   src_err_list, src_in_err, nerrs, nsrcerrs, k, m);
43600c1efc1SGreg Tucker         if (re != 0) {
43700c1efc1SGreg Tucker                 printf("Fail to gf_gen_decode_matrix\n");
438a3e26043SPablo de Lara                 goto exit;
43900c1efc1SGreg Tucker         }
44000c1efc1SGreg Tucker         // Pack recovery array as list of valid sources
44100c1efc1SGreg Tucker         // Its order must be the same as the order
44200c1efc1SGreg Tucker         // to generate matrix b in gf_gen_decode_matrix
44300c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
44400c1efc1SGreg Tucker                 recov[i] = update_buffs[decode_index[i]];
44500c1efc1SGreg Tucker         }
44600c1efc1SGreg Tucker 
44700c1efc1SGreg Tucker         // Recover data
44800c1efc1SGreg Tucker         for (i = 0; i < TEST_SOURCES; i++) {
44900c1efc1SGreg Tucker                 memset(temp_buffs[i], 0, TEST_LEN);
45000c1efc1SGreg Tucker         }
45100c1efc1SGreg Tucker         ec_init_tables(k, nerrs, decode_matrix, g_tbls);
45200c1efc1SGreg Tucker         for (i = 0; i < k; i++) {
45300c1efc1SGreg Tucker                 FUNCTION_UNDER_TEST(TEST_LEN, k, nerrs, i, g_tbls, recov[i], &temp_buffs[k]);
45400c1efc1SGreg Tucker         }
45500c1efc1SGreg Tucker         for (i = 0; i < nerrs; i++) {
45600c1efc1SGreg Tucker 
45700c1efc1SGreg Tucker                 if (0 != memcmp(temp_buffs[k + i], update_buffs[src_err_list[i]], TEST_LEN)) {
45800c1efc1SGreg Tucker                         printf("Fail error recovery (%d, %d, %d)\n", m, k, nerrs);
45900c1efc1SGreg Tucker                         printf(" - erase list = ");
46000c1efc1SGreg Tucker                         for (j = 0; j < nerrs; j++)
46100c1efc1SGreg Tucker                                 printf(" %d", src_err_list[j]);
46200c1efc1SGreg Tucker                         printf(" - Index = ");
46300c1efc1SGreg Tucker                         for (p = 0; p < k; p++)
46400c1efc1SGreg Tucker                                 printf(" %d", decode_index[p]);
46500c1efc1SGreg Tucker                         printf("\nencode_matrix:\n");
46600c1efc1SGreg Tucker                         dump_u8xu8((u8 *) encode_matrix, m, k);
46700c1efc1SGreg Tucker                         printf("inv b:\n");
46800c1efc1SGreg Tucker                         dump_u8xu8((u8 *) invert_matrix, k, k);
46900c1efc1SGreg Tucker                         printf("\ndecode_matrix:\n");
47000c1efc1SGreg Tucker                         dump_u8xu8((u8 *) decode_matrix, m, k);
47100c1efc1SGreg Tucker                         printf("recov %d:", src_err_list[i]);
47200c1efc1SGreg Tucker                         dump(temp_buffs[k + i], 25);
47300c1efc1SGreg Tucker                         printf("orig   :");
47400c1efc1SGreg Tucker                         dump(update_buffs[src_err_list[i]], 25);
475a3e26043SPablo de Lara                         re = -1;
476a3e26043SPablo de Lara                         goto exit;
47700c1efc1SGreg Tucker                 }
47800c1efc1SGreg Tucker         }
4792ca781dfSPablo de Lara #ifdef TEST_VERBOSE
48000c1efc1SGreg Tucker         putchar('.');
4812ca781dfSPablo de Lara #endif
48200c1efc1SGreg Tucker 
48300c1efc1SGreg Tucker         // Do more random tests
48400c1efc1SGreg Tucker         for (rtest = 0; rtest < RANDOMS; rtest++) {
485*300260a4SMarcel Cornu                 while ((m = (rand() % MMAX)) < 2)
486*300260a4SMarcel Cornu                         ;
487*300260a4SMarcel Cornu                 while ((k = (rand() % KMAX)) >= m || k < 1)
488*300260a4SMarcel Cornu                         ;
48900c1efc1SGreg Tucker 
49000c1efc1SGreg Tucker                 if (m > MMAX || k > KMAX)
49100c1efc1SGreg Tucker                         continue;
49200c1efc1SGreg Tucker 
49300c1efc1SGreg Tucker                 // Zero the destination buffer for update function
49400c1efc1SGreg Tucker                 for (i = k; i < TEST_SOURCES; i++) {
49500c1efc1SGreg Tucker                         memset(buffs[i], 0, TEST_LEN);
49600c1efc1SGreg Tucker                         memset(update_buffs[i], 0, TEST_LEN);
49700c1efc1SGreg Tucker                 }
49800c1efc1SGreg Tucker                 // Make random data
49900c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
50000c1efc1SGreg Tucker                         for (j = 0; j < TEST_LEN; j++) {
50100c1efc1SGreg Tucker                                 buffs[i][j] = rand();
50200c1efc1SGreg Tucker                                 update_buffs[i][j] = buffs[i][j];
50300c1efc1SGreg Tucker                         }
50400c1efc1SGreg Tucker                 }
50500c1efc1SGreg Tucker 
50600c1efc1SGreg Tucker                 // The matrix generated by gf_gen_cauchy1_matrix
50700c1efc1SGreg Tucker                 // is always invertable.
50800c1efc1SGreg Tucker                 gf_gen_cauchy1_matrix(encode_matrix, m, k);
50900c1efc1SGreg Tucker 
51000c1efc1SGreg Tucker                 // Make parity vects
51100c1efc1SGreg Tucker                 // Generate g_tbls from encode matrix a
51200c1efc1SGreg Tucker                 ec_init_tables(k, m - k, &encode_matrix[k * k], g_tbls);
51300c1efc1SGreg Tucker                 // Perform matrix dot_prod for EC encoding
51400c1efc1SGreg Tucker                 // using g_tbls from encode matrix a
51500c1efc1SGreg Tucker                 REF_FUNCTION(TEST_LEN, k, m - k, g_tbls, buffs, &buffs[k]);
51600c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
51700c1efc1SGreg Tucker                         FUNCTION_UNDER_TEST(TEST_LEN, k, m - k, i, g_tbls, update_buffs[i],
51800c1efc1SGreg Tucker                                             &update_buffs[k]);
51900c1efc1SGreg Tucker                 }
52000c1efc1SGreg Tucker                 for (i = 0; i < m - k; i++) {
52100c1efc1SGreg Tucker                         if (0 != memcmp(update_buffs[k + i], buffs[k + i], TEST_LEN)) {
52200c1efc1SGreg Tucker                                 printf("\nupdate_buffs%d  :", i);
52300c1efc1SGreg Tucker                                 dump(update_buffs[k + i], 25);
52400c1efc1SGreg Tucker                                 printf("buffs%d         :", i);
52500c1efc1SGreg Tucker                                 dump(buffs[k + i], 25);
526a3e26043SPablo de Lara                                 re = -1;
527a3e26043SPablo de Lara                                 goto exit;
52800c1efc1SGreg Tucker                         }
52900c1efc1SGreg Tucker                 }
53000c1efc1SGreg Tucker 
53100c1efc1SGreg Tucker                 // Random errors
53200c1efc1SGreg Tucker                 memset(src_in_err, 0, TEST_SOURCES);
53300c1efc1SGreg Tucker                 gen_err_list(src_err_list, src_in_err, &nerrs, &nsrcerrs, k, m);
53400c1efc1SGreg Tucker 
53500c1efc1SGreg Tucker                 // Generate decode matrix
536*300260a4SMarcel Cornu                 re = gf_gen_decode_matrix(encode_matrix, decode_matrix, invert_matrix, decode_index,
537*300260a4SMarcel Cornu                                           src_err_list, src_in_err, nerrs, nsrcerrs, k, m);
53800c1efc1SGreg Tucker                 if (re != 0) {
53900c1efc1SGreg Tucker                         printf("Fail to gf_gen_decode_matrix\n");
540a3e26043SPablo de Lara                         goto exit;
54100c1efc1SGreg Tucker                 }
54200c1efc1SGreg Tucker                 // Pack recovery array as list of valid sources
54300c1efc1SGreg Tucker                 // Its order must be the same as the order
54400c1efc1SGreg Tucker                 // to generate matrix b in gf_gen_decode_matrix
54500c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
54600c1efc1SGreg Tucker                         recov[i] = update_buffs[decode_index[i]];
54700c1efc1SGreg Tucker                 }
54800c1efc1SGreg Tucker 
54900c1efc1SGreg Tucker                 // Recover data
55000c1efc1SGreg Tucker                 for (i = 0; i < TEST_SOURCES; i++) {
55100c1efc1SGreg Tucker                         memset(temp_buffs[i], 0, TEST_LEN);
55200c1efc1SGreg Tucker                 }
55300c1efc1SGreg Tucker                 ec_init_tables(k, nerrs, decode_matrix, g_tbls);
55400c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
55500c1efc1SGreg Tucker                         FUNCTION_UNDER_TEST(TEST_LEN, k, nerrs, i, g_tbls, recov[i],
55600c1efc1SGreg Tucker                                             &temp_buffs[k]);
55700c1efc1SGreg Tucker                 }
55800c1efc1SGreg Tucker 
55900c1efc1SGreg Tucker                 for (i = 0; i < nerrs; i++) {
56000c1efc1SGreg Tucker 
56100c1efc1SGreg Tucker                         if (0 !=
562*300260a4SMarcel Cornu                             memcmp(temp_buffs[k + i], update_buffs[src_err_list[i]], TEST_LEN)) {
56300c1efc1SGreg Tucker                                 printf("Fail error recovery (%d, %d, %d) - ", m, k, nerrs);
56400c1efc1SGreg Tucker                                 printf(" - erase list = ");
56500c1efc1SGreg Tucker                                 for (j = 0; j < nerrs; j++)
56600c1efc1SGreg Tucker                                         printf(" %d", src_err_list[j]);
56700c1efc1SGreg Tucker                                 printf(" - Index = ");
56800c1efc1SGreg Tucker                                 for (p = 0; p < k; p++)
56900c1efc1SGreg Tucker                                         printf(" %d", decode_index[p]);
57000c1efc1SGreg Tucker                                 printf("\nencode_matrix:\n");
57100c1efc1SGreg Tucker                                 dump_u8xu8((u8 *) encode_matrix, m, k);
57200c1efc1SGreg Tucker                                 printf("inv b:\n");
57300c1efc1SGreg Tucker                                 dump_u8xu8((u8 *) invert_matrix, k, k);
57400c1efc1SGreg Tucker                                 printf("\ndecode_matrix:\n");
57500c1efc1SGreg Tucker                                 dump_u8xu8((u8 *) decode_matrix, m, k);
57600c1efc1SGreg Tucker                                 printf("orig data:\n");
57700c1efc1SGreg Tucker                                 dump_matrix(update_buffs, m, 25);
57800c1efc1SGreg Tucker                                 printf("orig   :");
57900c1efc1SGreg Tucker                                 dump(update_buffs[src_err_list[i]], 25);
58000c1efc1SGreg Tucker                                 printf("recov %d:", src_err_list[i]);
58100c1efc1SGreg Tucker                                 dump(temp_buffs[k + i], 25);
582a3e26043SPablo de Lara                                 re = -1;
583a3e26043SPablo de Lara                                 goto exit;
58400c1efc1SGreg Tucker                         }
58500c1efc1SGreg Tucker                 }
5862ca781dfSPablo de Lara #ifdef TEST_VERBOSE
58700c1efc1SGreg Tucker                 putchar('.');
5882ca781dfSPablo de Lara #endif
58900c1efc1SGreg Tucker         }
59000c1efc1SGreg Tucker 
59100c1efc1SGreg Tucker         // Run tests at end of buffer for Electric Fence
59200c1efc1SGreg Tucker         k = 16;
59300c1efc1SGreg Tucker         align = (LEN_ALIGN_CHK_B != 0) ? 1 : ALIGN_SIZE;
594a3e26043SPablo de Lara         if (k > KMAX) {
595a3e26043SPablo de Lara                 re = -1;
596a3e26043SPablo de Lara                 goto exit;
597a3e26043SPablo de Lara         }
59800c1efc1SGreg Tucker 
59900c1efc1SGreg Tucker         for (rows = 1; rows <= 16; rows++) {
60000c1efc1SGreg Tucker                 m = k + rows;
601a3e26043SPablo de Lara                 if (m > MMAX) {
602a3e26043SPablo de Lara                         re = -1;
603a3e26043SPablo de Lara                         goto exit;
604a3e26043SPablo de Lara                 }
60500c1efc1SGreg Tucker 
60600c1efc1SGreg Tucker                 for (i = k; i < TEST_SOURCES; i++) {
60700c1efc1SGreg Tucker                         memset(buffs[i], 0, TEST_LEN);
60800c1efc1SGreg Tucker                         memset(update_buffs[i], 0, TEST_LEN);
60900c1efc1SGreg Tucker                 }
61000c1efc1SGreg Tucker                 // Make random data
61100c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
61200c1efc1SGreg Tucker                         for (j = 0; j < TEST_LEN; j++) {
61300c1efc1SGreg Tucker                                 buffs[i][j] = rand();
61400c1efc1SGreg Tucker                                 update_buffs[i][j] = buffs[i][j];
61500c1efc1SGreg Tucker                         }
61600c1efc1SGreg Tucker                 }
61700c1efc1SGreg Tucker 
6184f2d148aSRoy Oursler                 for (size = 0; size <= EFENCE_TEST_MAX_SIZE; size += align) {
61900c1efc1SGreg Tucker                         for (i = 0; i < m; i++) { // Line up TEST_SIZE from end
62000c1efc1SGreg Tucker                                 efence_buffs[i] = buffs[i] + TEST_LEN - size;
62100c1efc1SGreg Tucker                                 efence_update_buffs[i] = update_buffs[i] + TEST_LEN - size;
62200c1efc1SGreg Tucker                         }
62300c1efc1SGreg Tucker                         // Zero the destination buffer for update function
62400c1efc1SGreg Tucker                         for (i = k; i < m; i++) {
62500c1efc1SGreg Tucker                                 memset(efence_buffs[i], 0, size);
62600c1efc1SGreg Tucker                                 memset(efence_update_buffs[i], 0, size);
62700c1efc1SGreg Tucker                         }
62800c1efc1SGreg Tucker 
62900c1efc1SGreg Tucker                         // The matrix generated by gf_gen_cauchy1_matrix
63000c1efc1SGreg Tucker                         // is always invertable.
63100c1efc1SGreg Tucker                         gf_gen_cauchy1_matrix(encode_matrix, m, k);
63200c1efc1SGreg Tucker 
63300c1efc1SGreg Tucker                         // Make parity vects
63400c1efc1SGreg Tucker                         // Generate g_tbls from encode matrix a
63500c1efc1SGreg Tucker                         ec_init_tables(k, m - k, &encode_matrix[k * k], g_tbls);
63600c1efc1SGreg Tucker                         // Perform matrix dot_prod for EC encoding
63700c1efc1SGreg Tucker                         // using g_tbls from encode matrix a
63800c1efc1SGreg Tucker                         REF_FUNCTION(size, k, m - k, g_tbls, efence_buffs, &efence_buffs[k]);
63900c1efc1SGreg Tucker                         for (i = 0; i < k; i++) {
64000c1efc1SGreg Tucker                                 FUNCTION_UNDER_TEST(size, k, m - k, i, g_tbls,
64100c1efc1SGreg Tucker                                                     efence_update_buffs[i],
64200c1efc1SGreg Tucker                                                     &efence_update_buffs[k]);
64300c1efc1SGreg Tucker                         }
64400c1efc1SGreg Tucker                         for (i = 0; i < m - k; i++) {
64500c1efc1SGreg Tucker                                 if (0 !=
646*300260a4SMarcel Cornu                                     memcmp(efence_update_buffs[k + i], efence_buffs[k + i], size)) {
64700c1efc1SGreg Tucker                                         printf("\nefence_update_buffs%d  :", i);
64800c1efc1SGreg Tucker                                         dump(efence_update_buffs[k + i], 25);
64900c1efc1SGreg Tucker                                         printf("efence_buffs%d         :", i);
65000c1efc1SGreg Tucker                                         dump(efence_buffs[k + i], 25);
651a3e26043SPablo de Lara                                         re = -1;
652a3e26043SPablo de Lara                                         goto exit;
65300c1efc1SGreg Tucker                                 }
65400c1efc1SGreg Tucker                         }
65500c1efc1SGreg Tucker 
65600c1efc1SGreg Tucker                         // Random errors
65700c1efc1SGreg Tucker                         memset(src_in_err, 0, TEST_SOURCES);
65800c1efc1SGreg Tucker                         gen_err_list(src_err_list, src_in_err, &nerrs, &nsrcerrs, k, m);
65900c1efc1SGreg Tucker 
66000c1efc1SGreg Tucker                         // Generate decode matrix
661*300260a4SMarcel Cornu                         re = gf_gen_decode_matrix(encode_matrix, decode_matrix, invert_matrix,
662*300260a4SMarcel Cornu                                                   decode_index, src_err_list, src_in_err, nerrs,
663*300260a4SMarcel Cornu                                                   nsrcerrs, k, m);
66400c1efc1SGreg Tucker                         if (re != 0) {
66500c1efc1SGreg Tucker                                 printf("Fail to gf_gen_decode_matrix\n");
666a3e26043SPablo de Lara                                 goto exit;
66700c1efc1SGreg Tucker                         }
66800c1efc1SGreg Tucker                         // Pack recovery array as list of valid sources
66900c1efc1SGreg Tucker                         // Its order must be the same as the order
67000c1efc1SGreg Tucker                         // to generate matrix b in gf_gen_decode_matrix
67100c1efc1SGreg Tucker                         for (i = 0; i < k; i++) {
67200c1efc1SGreg Tucker                                 recov[i] = efence_update_buffs[decode_index[i]];
67300c1efc1SGreg Tucker                         }
67400c1efc1SGreg Tucker 
67500c1efc1SGreg Tucker                         // Recover data
67600c1efc1SGreg Tucker                         for (i = 0; i < TEST_SOURCES; i++) {
67700c1efc1SGreg Tucker                                 memset(temp_buffs[i], 0, TEST_LEN);
67800c1efc1SGreg Tucker                         }
67900c1efc1SGreg Tucker                         ec_init_tables(k, nerrs, decode_matrix, g_tbls);
68000c1efc1SGreg Tucker                         for (i = 0; i < k; i++) {
68100c1efc1SGreg Tucker                                 FUNCTION_UNDER_TEST(size, k, nerrs, i, g_tbls, recov[i],
68200c1efc1SGreg Tucker                                                     &temp_buffs[k]);
68300c1efc1SGreg Tucker                         }
68400c1efc1SGreg Tucker 
68500c1efc1SGreg Tucker                         for (i = 0; i < nerrs; i++) {
68600c1efc1SGreg Tucker 
687*300260a4SMarcel Cornu                                 if (0 != memcmp(temp_buffs[k + i],
68800c1efc1SGreg Tucker                                                 efence_update_buffs[src_err_list[i]], size)) {
689*300260a4SMarcel Cornu                                         printf("Efence: Fail error recovery (%d, %d, %d)\n", m, k,
690*300260a4SMarcel Cornu                                                nerrs);
69100c1efc1SGreg Tucker 
69200c1efc1SGreg Tucker                                         printf("size = %d\n", size);
69300c1efc1SGreg Tucker 
69400c1efc1SGreg Tucker                                         printf("Test erase list = ");
69500c1efc1SGreg Tucker                                         for (j = 0; j < nerrs; j++)
69600c1efc1SGreg Tucker                                                 printf(" %d", src_err_list[j]);
69700c1efc1SGreg Tucker                                         printf(" - Index = ");
69800c1efc1SGreg Tucker                                         for (p = 0; p < k; p++)
69900c1efc1SGreg Tucker                                                 printf(" %d", decode_index[p]);
70000c1efc1SGreg Tucker                                         printf("\nencode_matrix:\n");
70100c1efc1SGreg Tucker                                         dump_u8xu8((u8 *) encode_matrix, m, k);
70200c1efc1SGreg Tucker                                         printf("inv b:\n");
70300c1efc1SGreg Tucker                                         dump_u8xu8((u8 *) invert_matrix, k, k);
70400c1efc1SGreg Tucker                                         printf("\ndecode_matrix:\n");
70500c1efc1SGreg Tucker                                         dump_u8xu8((u8 *) decode_matrix, m, k);
70600c1efc1SGreg Tucker 
70700c1efc1SGreg Tucker                                         printf("recov %d:", src_err_list[i]);
70800c1efc1SGreg Tucker                                         dump(temp_buffs[k + i], align);
70900c1efc1SGreg Tucker                                         printf("orig   :");
71000c1efc1SGreg Tucker                                         dump(efence_update_buffs[src_err_list[i]], align);
711a3e26043SPablo de Lara                                         re = 1;
712a3e26043SPablo de Lara                                         goto exit;
71300c1efc1SGreg Tucker                                 }
71400c1efc1SGreg Tucker                         }
71500c1efc1SGreg Tucker                 }
7162ca781dfSPablo de Lara #ifdef TEST_VERBOSE
71700c1efc1SGreg Tucker                 putchar('.');
7182ca781dfSPablo de Lara #endif
71900c1efc1SGreg Tucker         }
72000c1efc1SGreg Tucker 
72100c1efc1SGreg Tucker         // Test rand ptr alignment if available
72200c1efc1SGreg Tucker 
72300c1efc1SGreg Tucker         for (rtest = 0; rtest < RANDOMS; rtest++) {
724*300260a4SMarcel Cornu                 while ((m = (rand() % MMAX)) < 2)
725*300260a4SMarcel Cornu                         ;
726*300260a4SMarcel Cornu                 while ((k = (rand() % KMAX)) >= m || k < 1)
727*300260a4SMarcel Cornu                         ;
72800c1efc1SGreg Tucker 
72900c1efc1SGreg Tucker                 if (m > MMAX || k > KMAX)
73000c1efc1SGreg Tucker                         continue;
73100c1efc1SGreg Tucker 
73200c1efc1SGreg Tucker                 size = (TEST_LEN - PTR_ALIGN_CHK_B) & ~15;
73300c1efc1SGreg Tucker 
73400c1efc1SGreg Tucker                 offset = (PTR_ALIGN_CHK_B != 0) ? 1 : PTR_ALIGN_CHK_B;
73500c1efc1SGreg Tucker                 // Add random offsets
73600c1efc1SGreg Tucker                 for (i = 0; i < m; i++) {
73700c1efc1SGreg Tucker                         memset(buffs[i], 0, TEST_LEN);        // zero pad to check write-over
73800c1efc1SGreg Tucker                         memset(update_buffs[i], 0, TEST_LEN); // zero pad to check write-over
73900c1efc1SGreg Tucker                         memset(temp_buffs[i], 0, TEST_LEN);   // zero pad to check write-over
74000c1efc1SGreg Tucker                         ubuffs[i] = buffs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
741*300260a4SMarcel Cornu                         update_ubuffs[i] = update_buffs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
74200c1efc1SGreg Tucker                         temp_ubuffs[i] = temp_buffs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
74300c1efc1SGreg Tucker                 }
74400c1efc1SGreg Tucker 
74500c1efc1SGreg Tucker                 // Zero the destination buffer for update function
74600c1efc1SGreg Tucker                 for (i = k; i < m; i++) {
74700c1efc1SGreg Tucker                         memset(ubuffs[i], 0, size);
74800c1efc1SGreg Tucker                         memset(update_ubuffs[i], 0, size);
74900c1efc1SGreg Tucker                 }
75000c1efc1SGreg Tucker                 // Make random data
75100c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
75200c1efc1SGreg Tucker                         for (j = 0; j < size; j++) {
75300c1efc1SGreg Tucker                                 ubuffs[i][j] = rand();
75400c1efc1SGreg Tucker                                 update_ubuffs[i][j] = ubuffs[i][j];
75500c1efc1SGreg Tucker                         }
75600c1efc1SGreg Tucker                 }
75700c1efc1SGreg Tucker 
75800c1efc1SGreg Tucker                 // The matrix generated by gf_gen_cauchy1_matrix
75900c1efc1SGreg Tucker                 // is always invertable.
76000c1efc1SGreg Tucker                 gf_gen_cauchy1_matrix(encode_matrix, m, k);
76100c1efc1SGreg Tucker 
76200c1efc1SGreg Tucker                 // Make parity vects
76300c1efc1SGreg Tucker                 // Generate g_tbls from encode matrix a
76400c1efc1SGreg Tucker                 ec_init_tables(k, m - k, &encode_matrix[k * k], g_tbls);
76500c1efc1SGreg Tucker                 // Perform matrix dot_prod for EC encoding
76600c1efc1SGreg Tucker                 // using g_tbls from encode matrix a
76700c1efc1SGreg Tucker                 REF_FUNCTION(size, k, m - k, g_tbls, ubuffs, &ubuffs[k]);
76800c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
76900c1efc1SGreg Tucker                         FUNCTION_UNDER_TEST(size, k, m - k, i, g_tbls, update_ubuffs[i],
77000c1efc1SGreg Tucker                                             &update_ubuffs[k]);
77100c1efc1SGreg Tucker                 }
77200c1efc1SGreg Tucker                 for (i = 0; i < m - k; i++) {
77300c1efc1SGreg Tucker                         if (0 != memcmp(update_ubuffs[k + i], ubuffs[k + i], size)) {
77400c1efc1SGreg Tucker                                 printf("\nupdate_ubuffs%d  :", i);
77500c1efc1SGreg Tucker                                 dump(update_ubuffs[k + i], 25);
77600c1efc1SGreg Tucker                                 printf("ubuffs%d         :", i);
77700c1efc1SGreg Tucker                                 dump(ubuffs[k + i], 25);
778a3e26043SPablo de Lara                                 re = -1;
779a3e26043SPablo de Lara                                 goto exit;
78000c1efc1SGreg Tucker                         }
78100c1efc1SGreg Tucker                 }
78200c1efc1SGreg Tucker 
78300c1efc1SGreg Tucker                 // Random errors
78400c1efc1SGreg Tucker                 memset(src_in_err, 0, TEST_SOURCES);
78500c1efc1SGreg Tucker                 gen_err_list(src_err_list, src_in_err, &nerrs, &nsrcerrs, k, m);
78600c1efc1SGreg Tucker 
78700c1efc1SGreg Tucker                 // Generate decode matrix
788*300260a4SMarcel Cornu                 re = gf_gen_decode_matrix(encode_matrix, decode_matrix, invert_matrix, decode_index,
789*300260a4SMarcel Cornu                                           src_err_list, src_in_err, nerrs, nsrcerrs, k, m);
79000c1efc1SGreg Tucker                 if (re != 0) {
79100c1efc1SGreg Tucker                         printf("Fail to gf_gen_decode_matrix\n");
792a3e26043SPablo de Lara                         goto exit;
79300c1efc1SGreg Tucker                 }
79400c1efc1SGreg Tucker                 // Pack recovery array as list of valid sources
79500c1efc1SGreg Tucker                 // Its order must be the same as the order
79600c1efc1SGreg Tucker                 // to generate matrix b in gf_gen_decode_matrix
79700c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
79800c1efc1SGreg Tucker                         recov[i] = update_ubuffs[decode_index[i]];
79900c1efc1SGreg Tucker                 }
80000c1efc1SGreg Tucker 
80100c1efc1SGreg Tucker                 // Recover data
80200c1efc1SGreg Tucker                 for (i = 0; i < m; i++) {
80300c1efc1SGreg Tucker                         memset(temp_ubuffs[i], 0, size);
80400c1efc1SGreg Tucker                 }
80500c1efc1SGreg Tucker                 ec_init_tables(k, nerrs, decode_matrix, g_tbls);
80600c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
807*300260a4SMarcel Cornu                         FUNCTION_UNDER_TEST(size, k, nerrs, i, g_tbls, recov[i], &temp_ubuffs[k]);
80800c1efc1SGreg Tucker                 }
80900c1efc1SGreg Tucker 
81000c1efc1SGreg Tucker                 for (i = 0; i < nerrs; i++) {
81100c1efc1SGreg Tucker 
812*300260a4SMarcel Cornu                         if (0 != memcmp(temp_ubuffs[k + i], update_ubuffs[src_err_list[i]], size)) {
81300c1efc1SGreg Tucker                                 printf("Fail error recovery (%d, %d, %d) - ", m, k, nerrs);
81400c1efc1SGreg Tucker                                 printf(" - erase list = ");
81500c1efc1SGreg Tucker                                 for (j = 0; j < nerrs; j++)
81600c1efc1SGreg Tucker                                         printf(" %d", src_err_list[j]);
81700c1efc1SGreg Tucker                                 printf(" - Index = ");
81800c1efc1SGreg Tucker                                 for (p = 0; p < k; p++)
81900c1efc1SGreg Tucker                                         printf(" %d", decode_index[p]);
82000c1efc1SGreg Tucker                                 printf("\nencode_matrix:\n");
82100c1efc1SGreg Tucker                                 dump_u8xu8((unsigned char *) encode_matrix, m, k);
82200c1efc1SGreg Tucker                                 printf("inv b:\n");
82300c1efc1SGreg Tucker                                 dump_u8xu8((unsigned char *) invert_matrix, k, k);
82400c1efc1SGreg Tucker                                 printf("\ndecode_matrix:\n");
82500c1efc1SGreg Tucker                                 dump_u8xu8((unsigned char *) decode_matrix, m, k);
82600c1efc1SGreg Tucker                                 printf("orig data:\n");
82700c1efc1SGreg Tucker                                 dump_matrix(update_ubuffs, m, 25);
82800c1efc1SGreg Tucker                                 printf("orig   :");
82900c1efc1SGreg Tucker                                 dump(update_ubuffs[src_err_list[i]], 25);
83000c1efc1SGreg Tucker                                 printf("recov %d:", src_err_list[i]);
83100c1efc1SGreg Tucker                                 dump(temp_ubuffs[k + i], 25);
832a3e26043SPablo de Lara                                 re = -1;
833a3e26043SPablo de Lara                                 goto exit;
83400c1efc1SGreg Tucker                         }
83500c1efc1SGreg Tucker                 }
83600c1efc1SGreg Tucker 
83700c1efc1SGreg Tucker                 // Confirm that padding around dests is unchanged
83800c1efc1SGreg Tucker                 memset(temp_buffs[0], 0, PTR_ALIGN_CHK_B); // Make reference zero buff
83900c1efc1SGreg Tucker 
84000c1efc1SGreg Tucker                 for (i = 0; i < m; i++) {
84100c1efc1SGreg Tucker 
84200c1efc1SGreg Tucker                         offset = update_ubuffs[i] - update_buffs[i];
84300c1efc1SGreg Tucker 
84400c1efc1SGreg Tucker                         if (memcmp(update_buffs[i], temp_buffs[0], offset)) {
84500c1efc1SGreg Tucker                                 printf("Fail rand ualign encode pad start\n");
846a3e26043SPablo de Lara                                 re = -1;
847a3e26043SPablo de Lara                                 goto exit;
84800c1efc1SGreg Tucker                         }
849*300260a4SMarcel Cornu                         if (memcmp(update_buffs[i] + offset + size, temp_buffs[0],
85000c1efc1SGreg Tucker                                    PTR_ALIGN_CHK_B - offset)) {
85100c1efc1SGreg Tucker                                 printf("Fail rand ualign encode pad end\n");
852a3e26043SPablo de Lara                                 re = -1;
853a3e26043SPablo de Lara                                 goto exit;
85400c1efc1SGreg Tucker                         }
85500c1efc1SGreg Tucker                 }
85600c1efc1SGreg Tucker 
85700c1efc1SGreg Tucker                 for (i = 0; i < nerrs; i++) {
85800c1efc1SGreg Tucker 
85900c1efc1SGreg Tucker                         offset = temp_ubuffs[k + i] - temp_buffs[k + i];
86000c1efc1SGreg Tucker                         if (memcmp(temp_buffs[k + i], temp_buffs[0], offset)) {
86100c1efc1SGreg Tucker                                 printf("Fail rand ualign decode pad start\n");
862a3e26043SPablo de Lara                                 re = -1;
863a3e26043SPablo de Lara                                 goto exit;
86400c1efc1SGreg Tucker                         }
865*300260a4SMarcel Cornu                         if (memcmp(temp_buffs[k + i] + offset + size, temp_buffs[0],
86600c1efc1SGreg Tucker                                    PTR_ALIGN_CHK_B - offset)) {
86700c1efc1SGreg Tucker                                 printf("Fail rand ualign decode pad end\n");
868a3e26043SPablo de Lara                                 re = -1;
869a3e26043SPablo de Lara                                 goto exit;
87000c1efc1SGreg Tucker                         }
87100c1efc1SGreg Tucker                 }
87200c1efc1SGreg Tucker 
8732ca781dfSPablo de Lara #ifdef TEST_VERBOSE
87400c1efc1SGreg Tucker                 putchar('.');
8752ca781dfSPablo de Lara #endif
87600c1efc1SGreg Tucker         }
87700c1efc1SGreg Tucker 
87800c1efc1SGreg Tucker         // Test size alignment
87900c1efc1SGreg Tucker 
88000c1efc1SGreg Tucker         align = (LEN_ALIGN_CHK_B != 0) ? 13 : ALIGN_SIZE;
88100c1efc1SGreg Tucker 
88200c1efc1SGreg Tucker         for (size = TEST_LEN; size >= 0; size -= align) {
883*300260a4SMarcel Cornu                 while ((m = (rand() % MMAX)) < 2)
884*300260a4SMarcel Cornu                         ;
885*300260a4SMarcel Cornu                 while ((k = (rand() % KMAX)) >= m || k < 1)
886*300260a4SMarcel Cornu                         ;
88700c1efc1SGreg Tucker 
88800c1efc1SGreg Tucker                 if (m > MMAX || k > KMAX)
88900c1efc1SGreg Tucker                         continue;
89000c1efc1SGreg Tucker 
89100c1efc1SGreg Tucker                 // Zero the destination buffer for update function
89200c1efc1SGreg Tucker                 for (i = k; i < TEST_SOURCES; i++) {
89300c1efc1SGreg Tucker                         memset(buffs[i], 0, size);
89400c1efc1SGreg Tucker                         memset(update_buffs[i], 0, size);
89500c1efc1SGreg Tucker                 }
89600c1efc1SGreg Tucker                 // Make random data
89700c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
89800c1efc1SGreg Tucker                         for (j = 0; j < size; j++) {
89900c1efc1SGreg Tucker                                 buffs[i][j] = rand();
90000c1efc1SGreg Tucker                                 update_buffs[i][j] = buffs[i][j];
90100c1efc1SGreg Tucker                         }
90200c1efc1SGreg Tucker                 }
90300c1efc1SGreg Tucker 
90400c1efc1SGreg Tucker                 // The matrix generated by gf_gen_cauchy1_matrix
90500c1efc1SGreg Tucker                 // is always invertable.
90600c1efc1SGreg Tucker                 gf_gen_cauchy1_matrix(encode_matrix, m, k);
90700c1efc1SGreg Tucker 
90800c1efc1SGreg Tucker                 // Make parity vects
90900c1efc1SGreg Tucker                 // Generate g_tbls from encode matrix a
91000c1efc1SGreg Tucker                 ec_init_tables(k, m - k, &encode_matrix[k * k], g_tbls);
91100c1efc1SGreg Tucker                 // Perform matrix dot_prod for EC encoding
91200c1efc1SGreg Tucker                 // using g_tbls from encode matrix a
91300c1efc1SGreg Tucker                 REF_FUNCTION(size, k, m - k, g_tbls, buffs, &buffs[k]);
91400c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
91500c1efc1SGreg Tucker                         FUNCTION_UNDER_TEST(size, k, m - k, i, g_tbls, update_buffs[i],
91600c1efc1SGreg Tucker                                             &update_buffs[k]);
91700c1efc1SGreg Tucker                 }
91800c1efc1SGreg Tucker                 for (i = 0; i < m - k; i++) {
91900c1efc1SGreg Tucker                         if (0 != memcmp(update_buffs[k + i], buffs[k + i], size)) {
92000c1efc1SGreg Tucker                                 printf("\nupdate_buffs%d (size=%d)  :", i, size);
92100c1efc1SGreg Tucker                                 dump(update_buffs[k + i], 25);
92200c1efc1SGreg Tucker                                 printf("buffs%d (size=%d)         :", i, size);
92300c1efc1SGreg Tucker                                 dump(buffs[k + i], 25);
924a3e26043SPablo de Lara                                 re = -1;
925a3e26043SPablo de Lara                                 goto exit;
92600c1efc1SGreg Tucker                         }
92700c1efc1SGreg Tucker                 }
92800c1efc1SGreg Tucker 
92900c1efc1SGreg Tucker                 // Random errors
93000c1efc1SGreg Tucker                 memset(src_in_err, 0, TEST_SOURCES);
93100c1efc1SGreg Tucker                 gen_err_list(src_err_list, src_in_err, &nerrs, &nsrcerrs, k, m);
93200c1efc1SGreg Tucker                 // Generate decode matrix
933*300260a4SMarcel Cornu                 re = gf_gen_decode_matrix(encode_matrix, decode_matrix, invert_matrix, decode_index,
934*300260a4SMarcel Cornu                                           src_err_list, src_in_err, nerrs, nsrcerrs, k, m);
93500c1efc1SGreg Tucker                 if (re != 0) {
93600c1efc1SGreg Tucker                         printf("Fail to gf_gen_decode_matrix\n");
937a3e26043SPablo de Lara                         goto exit;
93800c1efc1SGreg Tucker                 }
93900c1efc1SGreg Tucker                 // Pack recovery array as list of valid sources
94000c1efc1SGreg Tucker                 // Its order must be the same as the order
94100c1efc1SGreg Tucker                 // to generate matrix b in gf_gen_decode_matrix
94200c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
94300c1efc1SGreg Tucker                         recov[i] = update_buffs[decode_index[i]];
94400c1efc1SGreg Tucker                 }
94500c1efc1SGreg Tucker 
94600c1efc1SGreg Tucker                 // Recover data
94700c1efc1SGreg Tucker                 for (i = 0; i < TEST_SOURCES; i++) {
94800c1efc1SGreg Tucker                         memset(temp_buffs[i], 0, TEST_LEN);
94900c1efc1SGreg Tucker                 }
95000c1efc1SGreg Tucker                 ec_init_tables(k, nerrs, decode_matrix, g_tbls);
95100c1efc1SGreg Tucker                 for (i = 0; i < k; i++) {
952*300260a4SMarcel Cornu                         FUNCTION_UNDER_TEST(size, k, nerrs, i, g_tbls, recov[i], &temp_buffs[k]);
95300c1efc1SGreg Tucker                 }
95400c1efc1SGreg Tucker 
95500c1efc1SGreg Tucker                 for (i = 0; i < nerrs; i++) {
95600c1efc1SGreg Tucker 
957*300260a4SMarcel Cornu                         if (0 != memcmp(temp_buffs[k + i], update_buffs[src_err_list[i]], size)) {
95800c1efc1SGreg Tucker                                 printf("Fail error recovery (%d, %d, %d) - ", m, k, nerrs);
95900c1efc1SGreg Tucker                                 printf(" - erase list = ");
96000c1efc1SGreg Tucker                                 for (j = 0; j < nerrs; j++)
96100c1efc1SGreg Tucker                                         printf(" %d", src_err_list[j]);
96200c1efc1SGreg Tucker                                 printf(" - Index = ");
96300c1efc1SGreg Tucker                                 for (p = 0; p < k; p++)
96400c1efc1SGreg Tucker                                         printf(" %d", decode_index[p]);
96500c1efc1SGreg Tucker                                 printf("\nencode_matrix:\n");
96600c1efc1SGreg Tucker                                 dump_u8xu8((unsigned char *) encode_matrix, m, k);
96700c1efc1SGreg Tucker                                 printf("inv b:\n");
96800c1efc1SGreg Tucker                                 dump_u8xu8((unsigned char *) invert_matrix, k, k);
96900c1efc1SGreg Tucker                                 printf("\ndecode_matrix:\n");
97000c1efc1SGreg Tucker                                 dump_u8xu8((unsigned char *) decode_matrix, m, k);
97100c1efc1SGreg Tucker                                 printf("orig data:\n");
97200c1efc1SGreg Tucker                                 dump_matrix(update_buffs, m, 25);
97300c1efc1SGreg Tucker                                 printf("orig   :");
97400c1efc1SGreg Tucker                                 dump(update_buffs[src_err_list[i]], 25);
97500c1efc1SGreg Tucker                                 printf("recov %d:", src_err_list[i]);
97600c1efc1SGreg Tucker                                 dump(temp_buffs[k + i], 25);
977a3e26043SPablo de Lara                                 re = -1;
978a3e26043SPablo de Lara                                 goto exit;
97900c1efc1SGreg Tucker                         }
98000c1efc1SGreg Tucker                 }
9812ca781dfSPablo de Lara #ifdef TEST_VERBOSE
98200c1efc1SGreg Tucker                 putchar('.');
9832ca781dfSPablo de Lara #endif
98400c1efc1SGreg Tucker         }
98500c1efc1SGreg Tucker 
98600c1efc1SGreg Tucker         printf("done EC tests: Pass\n");
987a3e26043SPablo de Lara         re = 0;
988a3e26043SPablo de Lara 
989a3e26043SPablo de Lara exit:
990a3e26043SPablo de Lara         for (i = 0; i < TEST_SOURCES; i++) {
991a3e26043SPablo de Lara                 if (buffs[i])
992a3e26043SPablo de Lara                         aligned_free(buffs[i]);
993a3e26043SPablo de Lara                 if (temp_buffs[i])
994a3e26043SPablo de Lara                         aligned_free(temp_buffs[i]);
995a3e26043SPablo de Lara                 if (update_buffs[i])
996a3e26043SPablo de Lara                         aligned_free(update_buffs[i]);
997a3e26043SPablo de Lara         }
998a3e26043SPablo de Lara         free(encode_matrix);
999a3e26043SPablo de Lara         free(decode_matrix);
1000a3e26043SPablo de Lara         free(invert_matrix);
1001a3e26043SPablo de Lara         free(g_tbls);
100200c1efc1SGreg Tucker         return 0;
100300c1efc1SGreg Tucker }
1004