⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 error.c

📁 开源代码
💻 C
字号:
/* error.c - MemTest-86  Version 3.4 * * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com * ---------------------------------------------------- * MemTest86+ V2.01 Specific code (GPL V2.0) * By Samuel DEMEULEMEESTER, sdemeule@memtest.org * http://www.canardpc.com - http://www.memtest.org */ #include "test.h"#include "config.h"#include <sys/io.h>#include "dmi.h"extern int test_ticks, nticks, beepmode;extern struct tseq tseq[];extern int dmi_err_cnts[MAX_DMI_MEMDEVS];extern short dmi_initialized;void poll_errors();static void update_err_counts(void);static void print_err_counts(void);static int syn, chan, len=1;/* * Print an individual error */void common_err( ulong *adr, ulong good, ulong bad, ulong xor, int type) {	int i, n, x, j, flag=0;	ulong page, offset;	int patnchg;	ulong mb;	update_err_counts();	add_dmi_err((ulong)adr);	switch(v->printmode) {	case PRINTMODE_SUMMARY:		/* Don't do anything for a parity error. */		if (type == 3) {			return;		}		/* Address error */		if (type == 1) {			xor = good ^ bad;		}		/* Ecc correctable errors */		if (type == 2) {			/* the bad value is the corrected flag */			if (bad) {				v->erri.cor_err++;			}			page = (ulong)adr;			offset = good;		} else {			page = page_of(adr);			offset = (ulong)adr & 0xFFF;		}					/* Calc upper and lower error addresses */		if (v->erri.low_addr.page > page) {			v->erri.low_addr.page = page;			v->erri.low_addr.offset = offset;			flag++;		} else if (v->erri.low_addr.page == page &&				v->erri.low_addr.offset > offset) {			v->erri.low_addr.offset = offset;			v->erri.high_addr.offset = offset;			flag++;		} else if (v->erri.high_addr.page < page) {			v->erri.high_addr.page = page;			flag++;		}		if (v->erri.high_addr.page == page &&				v->erri.high_addr.offset < offset) {			v->erri.high_addr.offset = offset;			flag++;		}		/* Calc bits in error */		for (i=0, n=0; i<32; i++) {			if (xor>>i & 1) {				n++;			}		}		v->erri.tbits += n;		if (n > v->erri.max_bits) {			v->erri.max_bits = n;			flag++;		}		if (n < v->erri.min_bits) {			v->erri.min_bits = n;			flag++;		}		if (v->erri.ebits ^ xor) {			flag++;		}		v->erri.ebits |= xor;	 	/* Calc max contig errors */		len = 1;		if ((ulong)adr == (ulong)v->erri.eadr+4 ||				(ulong)adr == (ulong)v->erri.eadr-4 ) {			len++;		}		if (len > v->erri.maxl) {			v->erri.maxl = len;			flag++;		}		v->erri.eadr = (ulong)adr;		if (v->erri.hdr_flag == 0) {			clear_scroll();			cprint(LINE_HEADER+0, 1,  "Error Confidence Value:");			cprint(LINE_HEADER+1, 1,  "  Lowest Error Address:");			cprint(LINE_HEADER+2, 1,  " Highest Error Address:");			cprint(LINE_HEADER+3, 1,  "    Bits in Error Mask:");			cprint(LINE_HEADER+4, 1,  " Bits in Error - Total:");			cprint(LINE_HEADER+4, 29,  "Min:    Max:    Avg:");			cprint(LINE_HEADER+5, 1,  " Max Contiguous Errors:");			cprint(LINE_HEADER+6, 1,  "ECC Correctable Errors:");			cprint(LINE_HEADER+7, 1,  "Errors per Memory Slot:");			x = 24;			if (dmi_initialized) {			  for ( i=0; i < MAX_DMI_MEMDEVS;){			    n = LINE_HEADER+7;			    for (j=0; j<4; j++) {				if (dmi_err_cnts[i] >= 0) {					dprint(n, x, i, 2, 0);					cprint(n, x+2, ": 0");				}				i++;				n++;			    }			    x += 10;			  }			}			cprint(LINE_HEADER+0, 64,   "Test  Errors");			v->erri.hdr_flag++;		}		if (flag) {		  /* Calc bits in error */		  for (i=0, n=0; i<32; i++) {			if (v->erri.ebits>>i & 1) {				n++;			}		  }		  page = v->erri.low_addr.page;		  offset = v->erri.low_addr.offset;		  mb = page >> 8;		  hprint(LINE_HEADER+1, 25, page);		  hprint2(LINE_HEADER+1, 33, offset, 3);		  cprint(LINE_HEADER+1, 36, " -      . MB");		  dprint(LINE_HEADER+1, 39, mb, 5, 0);		  dprint(LINE_HEADER+1, 45, ((page & 0xF)*10)/16, 1, 0);		  page = v->erri.high_addr.page;		  offset = v->erri.high_addr.offset;		  mb = page >> 8;		  hprint(LINE_HEADER+2, 25, page);		  hprint2(LINE_HEADER+2, 33, offset, 3);		  cprint(LINE_HEADER+2, 36, " -      . MB");		  dprint(LINE_HEADER+2, 39, mb, 5, 0);		  dprint(LINE_HEADER+2, 45, ((page & 0xF)*10)/16, 1, 0);		  hprint(LINE_HEADER+3, 25, v->erri.ebits);		  dprint(LINE_HEADER+4, 25, n, 2, 1);		  dprint(LINE_HEADER+4, 34, v->erri.min_bits, 2, 1);		  dprint(LINE_HEADER+4, 42, v->erri.max_bits, 2, 1);		  dprint(LINE_HEADER+4, 50, v->erri.tbits/v->ecount, 2, 1);		  dprint(LINE_HEADER+5, 25, v->erri.maxl, 7, 1);		  x = 28;		  for ( i=0; i < MAX_DMI_MEMDEVS;){		  	n = LINE_HEADER+7;			for (j=0; j<4; j++) {				if (dmi_err_cnts[i] > 0) {					dprint (n, x, dmi_err_cnts[i], 7, 1);				}				i++;				n++;			}			x += 10;		  }					  for (i=0; tseq[i].msg != NULL; i++) {			dprint(LINE_HEADER+1+i, 66, i, 2, 0);			dprint(LINE_HEADER+1+i, 68, tseq[i].errors, 8, 0);	  	  }		}		if (v->erri.cor_err) {		  dprint(LINE_HEADER+6, 25, v->erri.cor_err, 8, 1);		}		break;	case PRINTMODE_ADDRESSES:		/* Don't display duplicate errors */		if ((ulong)adr == (ulong)v->erri.eadr &&				 xor == v->erri.exor) {			return;		}		if (v->erri.hdr_flag == 0) {			clear_scroll();			cprint(LINE_HEADER, 0,"Tst  Pass   Failing Address          Good       Bad     Err-Bits  Count Chan");			cprint(LINE_HEADER+1, 0,"---  ----  -----------------------  --------  --------  --------  ----- ----");			v->erri.hdr_flag++;		}		/* Check for keyboard input */		check_input();		scroll();			if ( type == 2 || type == 3) {			page = (ulong)adr;			offset = good;		} else {			page = page_of(adr);			offset = ((unsigned long)adr) & 0xFFF;		}		mb = page >> 8;		dprint(v->msg_line, 0, v->test, 3, 0);		dprint(v->msg_line, 4, v->pass, 5, 0);		hprint(v->msg_line, 11, page);		hprint2(v->msg_line, 19, offset, 3);		cprint(v->msg_line, 22, " -      . MB");		dprint(v->msg_line, 25, mb, 5, 0);		dprint(v->msg_line, 31, ((page & 0xF)*10)/16, 1, 0);		if (type == 3) {			/* ECC error */			cprint(v->msg_line, 36, 			  bad?"corrected           ": "uncorrected         ");			hprint2(v->msg_line, 60, syn, 4);			cprint(v->msg_line, 68, "ECC"); 			dprint(v->msg_line, 74, chan, 2, 0);		} else if (type == 2) {			cprint(v->msg_line, 36, "Parity error detected                ");		} else {			hprint(v->msg_line, 36, good);			hprint(v->msg_line, 46, bad);			hprint(v->msg_line, 56, xor);			dprint(v->msg_line, 66, v->ecount, 5, 0);			v->erri.exor = xor;		}		v->erri.eadr = (ulong)adr;		print_err_counts();		break;	case PRINTMODE_PATTERNS:		if (v->erri.hdr_flag == 0) {			clear_scroll();			v->erri.hdr_flag++;		}		/* Do not do badram patterns from test 0 or 5 */		if (v->test == 0 || v->test == 5) {			return;		}		/* Only do patterns for data errors */		if ( type != 0) {			return;		}		/* Process the address in the pattern administration */		patnchg=insertaddress ((ulong) adr);		if (patnchg) { 			printpatn();		}		break;	case PRINTMODE_NONE:		if (v->erri.hdr_flag == 0) {			clear_scroll();			v->erri.hdr_flag++;		}		break;	}}/* * Display data error message. Don't display duplicate errors. */void error(ulong *adr, ulong good, ulong bad){	ulong xor;	xor = good ^ bad;#ifdef USB_WAR	/* Skip any errrors that appear to be due to the BIOS using location	 * 0x4e0 for USB keyboard support.  This often happens with Intel         * 810, 815 and 820 chipsets.  It is possible that we will skip	 * a real error but the odds are very low.	 */	if ((ulong)adr == 0x4e0 || (ulong)adr == 0x410) {		return;	}#endif	common_err(adr, good, bad, xor, 0);}/* * Display address error message. * Since this is strictly an address test, trying to create BadRAM * patterns does not make sense.  Just report the error. */void ad_err1(ulong *adr1, ulong *mask, ulong bad, ulong good){	common_err(adr1, good, bad, (ulong)mask, 1);}/* * Display address error message. * Since this type of address error can also report data errors go * ahead and generate BadRAM patterns. */void ad_err2(ulong *adr, ulong bad){	common_err(adr, (ulong)adr, bad, ((ulong)adr) ^ bad, 0);}static void update_err_counts(void){	if (beepmode){		beep(600);		beep(1000);	}		if (v->pass && v->ecount == 0) {		cprint(LINE_MSG, COL_MSG,			"                                            ");	}	++(v->ecount);	tseq[v->test].errors++;		}static void print_err_counts(void){	int i;	char *pp;	if ((v->ecount > 4096) && (v->ecount % 256 != 0)) return;	dprint(LINE_INFO, COL_ERR, v->ecount, 6, 0);	dprint(LINE_INFO, COL_ECC_ERR, v->ecc_ecount, 6, 0);	/* Paint the error messages on the screen red to provide a vivid */	/* indicator that an error has occured */ 	if ((v->printmode == PRINTMODE_ADDRESSES ||			v->printmode == PRINTMODE_PATTERNS) &&			v->msg_line < 24) {		for(i=0, pp=(char *)((SCREEN_ADR+v->msg_line*160+1));				 i<76; i++, pp+=2) {			*pp = 0x47;		}	}}/* * Print an ecc error */void print_ecc_err(unsigned long page, unsigned long offset, 	int corrected, unsigned short syndrome, int channel){	++(v->ecc_ecount);	syn = syndrome;	chan = channel;	common_err((ulong *)page, offset, corrected, 0, 2);}#ifdef PARITY_MEM/* * Print a parity error message */void parity_err( unsigned long edi, unsigned long esi) {	unsigned long addr;	if (v->test == 5) {		addr = esi;	} else {		addr = edi;	}	common_err((ulong *)addr, addr & 0xFFF, 0, 0, 3);}#endif/* * Print the pattern array as a LILO boot option addressing BadRAM support. */void printpatn (void){       int idx=0;       int x;	/* Check for keyboard input */	check_input();       if (v->numpatn == 0)               return;       scroll();       cprint (v->msg_line, 0, "badram=");       x=7;       for (idx = 0; idx < v->numpatn; idx++) {               if (x > 80-22) {                       scroll();                       x=7;               }               cprint (v->msg_line, x, "0x");               hprint (v->msg_line, x+2,  v->patn[idx].adr );               cprint (v->msg_line, x+10, ",0x");               hprint (v->msg_line, x+13, v->patn[idx].mask);               if (idx+1 < v->numpatn)                       cprint (v->msg_line, x+21, ",");               x+=22;       }}	/* * Show progress by displaying elapsed time and update bar graphs */void do_tick(void){	int i, n, pct;	ulong h, l, t;	/* FIXME only print serial error messages from the tick handler */	if (v->ecount) {		print_err_counts();	}		nticks++;	v->total_ticks++;	pct = 100*nticks/test_ticks;	dprint(1, COL_MID+4, pct, 3, 0);	i = (BAR_SIZE * pct) / 100;	while (i > v->tptr) {		if (v->tptr >= BAR_SIZE) {			break;		}		cprint(1, COL_MID+9+v->tptr, "#");		v->tptr++;	}		pct = 100*v->total_ticks/v->pass_ticks;	dprint(0, COL_MID+4, pct, 3, 0);	i = (BAR_SIZE * pct) / 100;	while (i > v->pptr) {		if (v->pptr >= BAR_SIZE) {			break;		}		cprint(0, COL_MID+9+v->pptr, "#");		v->pptr++;	}	if (v->ecount && v->printmode == PRINTMODE_SUMMARY) {		/* Compute confidence score */		pct = 0;		/* If there are no errors within 1mb of start - end addresses */		h = v->pmap[v->msegs - 1].end - 0x100;		if (v->erri.low_addr.page >  0x100 &&				 v->erri.high_addr.page < h) {			pct += 8;		}		/* Errors for only some tests */		if (v->pass) {			for (i=0, n=0; tseq[i].msg != NULL; i++) {				if (tseq[i].errors == 0) {					n++;				}			}			pct += n*3;		} else {			for (i=0, n=0; i<v->test; i++) {				if (tseq[i].errors == 0) {					n++;				}			}			pct += n*2;					}		/* Only some bits in error */		n = 0;		if (v->erri.ebits & 0xf) n++;		if (v->erri.ebits & 0xf0) n++;		if (v->erri.ebits & 0xf00) n++;		if (v->erri.ebits & 0xf000) n++;		if (v->erri.ebits & 0xf0000) n++;		if (v->erri.ebits & 0xf00000) n++;		if (v->erri.ebits & 0xf000000) n++;		if (v->erri.ebits & 0xf0000000) n++;		pct += (8-n)*2;		/* Adjust the score */		pct = pct*100/22;/*		if (pct > 100) {			pct = 100;		}*/		dprint(LINE_HEADER+0, 25, pct, 3, 1);	}			/* We can't do the elapsed time unless the rdtsc instruction	 * is supported	 */	if (v->rdtsc) {		asm __volatile__(			"rdtsc":"=a" (l),"=d" (h));		asm __volatile__ (			"subl %2,%0\n\t"			"sbbl %3,%1"			:"=a" (l), "=d" (h)			:"g" (v->startl), "g" (v->starth),			"0" (l), "1" (h));		t = h * ((unsigned)0xffffffff / v->clks_msec) / 1000;		t += (l / v->clks_msec) / 1000;		i = t % 60;		dprint(LINE_TIME, COL_TIME+9, i%10, 1, 0);		dprint(LINE_TIME, COL_TIME+8, i/10, 1, 0);		t /= 60;		i = t % 60;		dprint(LINE_TIME, COL_TIME+6, i % 10, 1, 0);		dprint(LINE_TIME, COL_TIME+5, i / 10, 1, 0);		t /= 60;		dprint(LINE_TIME, COL_TIME, t, 4, 0);	}	/* Check for keyboard input */	check_input();	/* Poll for ECC errors */	poll_errors();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -