1 /* error correcting code for nand flash */
3 #include "../port/lib.h"
8 #include "../port/error.h"
11 #define CORRECTABLEMASK 0x545555
13 static uchar ecctab[] = {
14 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
15 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
16 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
17 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
18 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
19 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
20 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
21 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
22 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
23 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
24 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
25 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
26 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
27 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
28 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
29 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
30 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0,
31 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
32 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55,
33 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
34 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59,
35 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
36 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc,
37 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
38 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65,
39 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
40 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0,
41 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
42 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc,
43 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
44 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69,
45 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
51 int cp, zeros, ones, im, lp, om, i;
56 for (i = 0; i < 256; i++) {
57 int tabent = ecctab[buf[i]];
66 for (im = 0x80, om = 0x8000; im; im >>= 1, om >>= 1) {
73 return (((cp & 0xff) | 3) << 16) | lp;
77 nandecccorrect(uchar *buf, ulong calcecc, ulong *storedecc, int reportbad)
82 if (calcecc == *storedecc)
83 return NandEccErrorGood;
85 print("nandecccorrect: calculated ecc %.8lux stored ecc %.8lux\n",
87 xorecc = calcecc ^ *storedecc;
88 if (((xorecc ^ (xorecc >> 1)) & CORRECTABLEMASK) == CORRECTABLEMASK) {
93 for (imask = 0x800000, omask = 0x800, out = 0; imask;
94 imask >>= 2, omask >>= 1)
100 print("nandecccorrect: single bit error line %d col %d\n",
102 buf[line] ^= (1 << col);
103 *storedecc = calcecc;
104 return NandEccErrorOneBit;
106 for (mask = 0x800000, k = 0; mask; mask >>= 1)
111 print("nandecccorrect: single bit error in ecc\n");
112 /* assume the stored ecc was wrong */
113 *storedecc = calcecc;
114 return NandEccErrorOneBitInEcc;
117 print("nandecccorrect: 2 bit error\n");
118 return NandEccErrorBad;