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 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 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