ecc.c 3.2 KB

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