Charles.Forsyth20060303a828770d19 years agoHistory
98 lines · 3.2 KB · C
RawDownload
#include "lib9.h"#include "nandecc.h" static uchar ecctab[] = {	0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,	0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,	0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,	0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,	0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,	0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,	0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,	0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,	0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9,	0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c,	0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30,	0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5,	0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c,	0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99,	0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95,	0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00,}; ulongnandecc(uchar *buf){	int cp, zeros, ones, im;	int lp, om;	int i; 	cp = 0xff;	zeros = 0xff;	ones = 0xff;	for (i = 0; i < 256; i++) {		int tabent = ecctab[buf[i]];		cp ^= tabent;		if (tabent & 1) {			zeros ^= ~i;			ones ^= i;		}	}	lp = 0;	for (im = 0x80, om = 0x8000; im; im >>= 1, om >>= 1) {		if (ones & im)			lp |= om;		om >>= 1;		if (zeros & im)			lp |= om;	}	return (((cp & 0xff) | 3) << 16) | lp;} #define CORRECTABLEMASK 0x545555 NandEccErrornandecccorrect(uchar *buf, ulong calcecc, ulong *storedecc, int reportbad){	ulong xorecc;	ulong mask;	int k; 	if (calcecc == *storedecc)		return NandEccErrorGood;	if (reportbad)		print("nandecccorrect: calculated ecc %.8lux stored ecc %.8lux\n", calcecc, *storedecc);	xorecc = calcecc ^ *storedecc;	if (((xorecc ^ (xorecc >> 1)) & CORRECTABLEMASK) == CORRECTABLEMASK) {		ulong imask;		ushort out;		ushort omask;		int line, col; 		for (imask = 0x800000, omask = 0x800, out = 0; imask; imask >>= 2, omask >>= 1) {			if (xorecc & imask)				out |= omask;		}		line = out & 0xff;		col = out >> 9;		if (reportbad)			print("nandecccorrect: single bit error line %d col %d\n", line, col);		buf[line] ^= (1 << col);		*storedecc = calcecc;		return NandEccErrorOneBit;	}	for (mask = 0x800000, k = 0; mask; mask >>= 1)		if (mask & xorecc)			k++;	if (k == 1) {		if (reportbad)			print("nandecccorrect: single bit error in ecc\n");		// assume the stored ecc was wrong		*storedecc = calcecc;		return NandEccErrorOneBitInEcc;	}	if (reportbad)		print("nandecccorrect: 2 bit error\n");	return NandEccErrorBad;}