1 #include "logfsos.h"
2 #include "nandecc.h"
3
4 static uchar ecctab[] = {
5 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
6 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
7 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
8 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
9 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
10 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
11 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
12 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
13 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,
14 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,
15 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,
16 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,
17 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,
18 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,
19 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,
20 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,
21 };
22
23 ulong
nandecc(uchar * buf)24 nandecc(uchar *buf)
25 {
26 int cp, zeros, ones, im;
27 int lp, om;
28 int i;
29
30 cp = 0xff;
31 zeros = 0xff;
32 ones = 0xff;
33 for (i = 0; i < 256; i++) {
34 int tabent = ecctab[buf[i]];
35 cp ^= tabent;
36 if (tabent & 1) {
37 zeros ^= ~i;
38 ones ^= i;
39 }
40 }
41 lp = 0;
42 for (im = 0x80, om = 0x8000; im; im >>= 1, om >>= 1) {
43 if (ones & im)
44 lp |= om;
45 om >>= 1;
46 if (zeros & im)
47 lp |= om;
48 }
49 return (((cp & 0xff) | 3) << 16) | lp;
50 }
51
52 #define CORRECTABLEMASK 0x545555
53
54 NandEccError
nandecccorrect(uchar * buf,ulong calcecc,ulong * storedecc,int reportbad)55 nandecccorrect(uchar *buf, ulong calcecc, ulong *storedecc, int reportbad)
56 {
57 ulong xorecc;
58 ulong mask;
59 int k;
60
61 if (calcecc == *storedecc)
62 return NandEccErrorGood;
63 if (reportbad)
64 print("nandecccorrect: calculated ecc %.8lux stored ecc %.8lux\n", calcecc, *storedecc);
65 xorecc = calcecc ^ *storedecc;
66 if (((xorecc ^ (xorecc >> 1)) & CORRECTABLEMASK) == CORRECTABLEMASK) {
67 ulong imask;
68 ushort out;
69 ushort omask;
70 int line, col;
71
72 for (imask = 0x800000, omask = 0x800, out = 0; imask; imask >>= 2, omask >>= 1) {
73 if (xorecc & imask)
74 out |= omask;
75 }
76 line = out & 0xff;
77 col = out >> 9;
78 if (reportbad)
79 print("nandecccorrect: single bit error line %d col %d\n", line, col);
80 buf[line] ^= (1 << col);
81 *storedecc = calcecc;
82 return NandEccErrorOneBit;
83 }
84 for (mask = 0x800000, k = 0; mask; mask >>= 1)
85 if (mask & xorecc)
86 k++;
87 if (k == 1) {
88 if (reportbad)
89 print("nandecccorrect: single bit error in ecc\n");
90 // assume the stored ecc was wrong
91 *storedecc = calcecc;
92 return NandEccErrorOneBitInEcc;
93 }
94 if (reportbad)
95 print("nandecccorrect: 2 bit error\n");
96 return NandEccErrorBad;
97 }
98
99