tgt_machdep.c

来自「国产CPU-龙芯(loongson)BIOS源代码」· C语言 代码 · 共 2,203 行 · 第 1/4 页

C
2,203
字号
				"cmpl %%edx,%%edi\n\t"				"jb L20\n\t"				: "=b" (k), "=D" (p)				: "D" (p),"d" (pe),"b" (k),"c" (pat),					"a" (sval), "S" (lb)			);			do_tick();			BAILR		} while (!done);	}	/* Do moving inversions test. Check for initial pattern and then	 * write the complement for each memory location. Test from bottom	 * up and then from the top down.  */	for (i=0; i<iter; i++) {		for (j=0; j<segs; j++) {			start = v->map[j].start;			end = v->map[j].end;			pe = start;			p = start;			done = 0;			k = off;			pat = p1;			do {				/* Check for overflow */				if (pe + SPINSZ > pe) {					pe += SPINSZ;				} else {					pe = end;				}				if (pe >= end) {					pe = end;					done++;				}				if (p == pe ) {					break;				}/* Original C code replaced with hand tuned assembly code *				while (p < pe) { *					if ((bad=*p) != pat) { *						error((unsigned long*)p, pat, bad); *					} *					*p = ~pat; *					if (++k >= 32) { *						pat = lb; *						k = 0; *					} else { *						pat = pat << 1; *						pat |= sval; *					} *					p++; *				} */				asm __volatile__ (					"pushl %%ebp\n\t"					"jmp L30\n\t"					".p2align 4,,7\n\t"					"L30:\n\t"					"movl (%%edi),%%ebp\n\t"					"cmpl %%ecx,%%ebp\n\t"					"jne L34\n\t"					"L35:\n\t"					"notl %%ecx\n\t"					"movl %%ecx,(%%edi)\n\t"					"notl %%ecx\n\t"					"incl %%ebx\n\t"					"cmpl $32,%%ebx\n\t"					"jne L31\n\t"					"movl %%esi,%%ecx\n\t"					"xorl %%ebx,%%ebx\n\t"					"jmp L32\n"					"L31:\n\t"					"shll $1,%%ecx\n\t"					"orl %%eax,%%ecx\n\t"					"L32:\n\t"					"addl $4,%%edi\n\t"					"cmpl %%edx,%%edi\n\t"					"jb L30\n\t"					"jmp L33\n\t"					"L34:\n\t" \					"pushl %%esi\n\t"					"pushl %%eax\n\t"					"pushl %%ebx\n\t"					"pushl %%edx\n\t"					"pushl %%ebp\n\t"					"pushl %%ecx\n\t"					"pushl %%edi\n\t"					"call error\n\t"					"popl %%edi\n\t"					"popl %%ecx\n\t"					"popl %%ebp\n\t"					"popl %%edx\n\t"					"popl %%ebx\n\t"					"popl %%eax\n\t"					"popl %%esi\n\t"					"jmp L35\n"					"L33:\n\t"					"popl %%ebp\n\t"					: "=b" (k), "=D" (p)					: "D" (p),"d" (pe),"b" (k),"c" (pat),						"a" (sval), "S" (lb)				);				do_tick();				BAILR			} while (!done);		}		/* Since we already adjusted k and the pattern this		 * code backs both up one step		 */		if (--k < 0) {			k = 31;		}		for (pat = lb, n = 0; n < k; n++) {			pat = pat << 1;			pat |= sval;		}		k++;		for (j=segs-1; j>=0; j--) {			start = v->map[j].start;			end = v->map[j].end;			p = end -1;			pe = end -1;			done = 0;			do {				/* Check for underflow */				if (pe - SPINSZ < pe) {					pe -= SPINSZ;				} else {					pe = start;				}				if (pe <= start) {					pe = start;					done++;				}				if (p == pe ) {					break;				}/* Original C code replaced with hand tuned assembly code *				do { *					if ((bad=*p) != ~pat) { *						error((unsigned long*)p, ~pat, bad); *					} *					*p = pat; *					if (--k <= 0) { *						pat = hb; *						k = 32; *					} else { *						pat = pat >> 1; *						pat |= p3; *					} *				} while (p-- > pe); */				asm __volatile__ (					"pushl %%ebp\n\t"					"addl $4,%%edi\n\t"					"jmp L40\n\t"						".p2align 4,,7\n\t"					"L40:\n\t"					"subl $4,%%edi\n\t"					"movl (%%edi),%%ebp\n\t"					"notl %%ecx\n\t"					"cmpl %%ecx,%%ebp\n\t"					"jne L44\n\t"					"L45:\n\t"					"notl %%ecx\n\t"					"movl %%ecx,(%%edi)\n\t"					"decl %%ebx\n\t"					"cmpl $0,%%ebx\n\t"					"jg L41\n\t"					"movl %%esi,%%ecx\n\t"					"movl $32,%%ebx\n\t"					"jmp L42\n"					"L41:\n\t"					"shrl $1,%%ecx\n\t"					"orl %%eax,%%ecx\n\t"					"L42:\n\t"					"cmpl %%edx,%%edi\n\t"					"ja L40\n\t"					"jmp L43\n\t"					"L44:\n\t" \					"pushl %%esi\n\t"					"pushl %%eax\n\t"					"pushl %%ebx\n\t"					"pushl %%edx\n\t"					"pushl %%ebp\n\t"					"pushl %%ecx\n\t"					"pushl %%edi\n\t"					"call error\n\t"					"popl %%edi\n\t"					"popl %%ecx\n\t"					"popl %%ebp\n\t"					"popl %%edx\n\t"					"popl %%ebx\n\t"					"popl %%eax\n\t"					"popl %%esi\n\t"					"jmp L45\n"					"L43:\n\t"					"subl $4,%%edi\n\t"					"popl %%ebp\n\t"					: "=b" (k), "=D" (p), "=c" (pat)					: "D" (p),"d" (pe),"b" (k),"c" (pat),						"a" (p3), "S" (hb)				);				do_tick();				BAILR			} while (!done);		}	}}#endif/* * Test all of memory using modulo X access pattern. */void modtst(int offset, int iter, unsigned long p1, unsigned long p2){	int j, k, l, done;	volatile unsigned long *pe;	volatile unsigned long *start, *end;	/* Display the current pattern */	/*        hprint(LINE_PAT, COL_PAT-2, p1);	cprint(LINE_PAT, COL_PAT+6, "-");        dprint(LINE_PAT, COL_PAT+7, offset, 2, 1);	*/	printf("modtst offset=%x,p1=%x,p2=%x\n",offset,p1,p2);	/* Write every nth location with pattern */	for (j=0; j<segs; j++) {		start = map[j].start;		end = map[j].end;		pe = (unsigned long *)start;		p = start+offset;		done = 0;		do {			/* Check for overflow */			if (pe + SPINSZ > pe) {				pe += SPINSZ;			} else {				pe = end;			}			if (pe >= end) {				pe = end;				done++;			}			if (p == pe ) {				break;			} 			for (; p < pe; p += MOD_SZ) { 				*p = p1; 			}			do_tick();			BAILR		} while (!done);	}	/* Write the rest of memory "iter" times with the pattern complement */	for (l=0; l<iter; l++) {		for (j=0; j<segs; j++) {			start = map[j].start;			end = map[j].end;			pe = (unsigned long *)start;			p = start;			done = 0;			k = 0;			do {				/* Check for overflow */				if (pe + SPINSZ > pe) {					pe += SPINSZ;				} else {					pe = end;				}				if (pe >= end) {					pe = end;					done++;				}				if (p == pe ) {					break;				} 				for (; p < pe; p++) { 					if (k != offset) { 						*p = p2; 					} 					if (++k > MOD_SZ-1) { 						k = 0; 					} 				}				do_tick();				BAILR			} while (!done);		}	}	/* Now check every nth location */	for (j=0; j<segs; j++) {		start = map[j].start;		end = map[j].end;		pe = (unsigned long *)start;		p = start+offset;		done = 0;		do {			/* Check for overflow */			if (pe + SPINSZ > pe) {				pe += SPINSZ;			} else {				pe = end;			}			if (pe >= end) {				pe = end;				done++;			}			if (p == pe ) {				break;			} 			for (; p < pe; p += MOD_SZ) { 				if ((bad=*p) != p1) { 					error((unsigned long*)p, p1, bad); 				}			}			do_tick();			BAILR		} while (!done);	}}#if 0/* * Test memory using block moves  * Adapted from Robert Redelmeier's burnBX test */void block_move(int iter){	int i, j, done;	unsigned long len;	volatile unsigned long p, pe, pp;	volatile unsigned long start, end;        //cprint(LINE_PAT, COL_PAT-2, "          ");	printf("block move test...\n");	/* Initialize memory with the initial pattern.  */	for (j=0; j<segs; j++) {		start = (unsigned long)map[j].start;		end = (unsigned long)map[j].end;		pe = start;		p = start;		done = 0;		do {			/* Check for overflow */			if (pe + SPINSZ*4 > pe) {				pe += SPINSZ*4;			} else {				pe = end;			}			if (pe >= end) {				pe = end;				done++;			}			if (p == pe ) {				break;			}			len  = ((unsigned long)pe - (unsigned long)p) / 64;			asm __volatile__ (				".set noreorder\n\t"                                "b   1f\n\n"				"nop\n\t"				".algin 4\n\t"				"1f:\n\t"				"move" 				"jmp L100\n\t"				".p2align 4,,7\n\t"				"L100:\n\t"				"movl %%eax, %%edx\n\t"				"notl %%edx\n\t"				"movl %%eax,0(%%edi)\n\t"				"movl %%eax,4(%%edi)\n\t"				"movl %%eax,8(%%edi)\n\t"				"movl %%eax,12(%%edi)\n\t"				"movl %%edx,16(%%edi)\n\t"				"movl %%edx,20(%%edi)\n\t"				"movl %%eax,24(%%edi)\n\t"				"movl %%eax,28(%%edi)\n\t"				"movl %%eax,32(%%edi)\n\t"				"movl %%eax,36(%%edi)\n\t"				"movl %%edx,40(%%edi)\n\t"				"movl %%edx,44(%%edi)\n\t"				"movl %%eax,48(%%edi)\n\t"				"movl %%eax,52(%%edi)\n\t"				"movl %%edx,56(%%edi)\n\t"				"movl %%edx,60(%%edi)\n\t"				"rcll $1, %%eax\n\t"				"leal 64(%%edi), %%edi\n\t"				"decl %%ecx\n\t"				"jnz  L100\n\t"				: "=D" (p)				: "D" (p), "c" (len), "a" (1)				: "edx"			);			do_tick();			BAILR		} while (!done);	}	/* Now move the data around 	 * First move the data up half of the segment size we are testing	 * Then move the data to the original location + 32 bytes	 */	for (j=0; j<segs; j++) {		start = (unsigned long)map[j].start;		end = (unsigned long)map[j].end;		pe = start;		p = start;		done = 0;		do {			/* Check for overflow */			if (pe + SPINSZ*4 > pe) {				pe += SPINSZ*4;			} else {				pe = end;			}			if (pe >= end) {				pe = end;				done++;			}			if (p == pe ) {				break;			}			pp = p + ((pe - p) / 2);			len  = ((unsigned long)pe - (unsigned long)p) / 8;			for(i=0; i<iter; i++) {				asm __volatile__ (					"cld\n"					"jmp L110\n\t"					".p2align 4,,7\n\t"					"L110:\n\t"					"movl %1,%%edi\n\t"					"movl %0,%%esi\n\t"					"movl %2,%%ecx\n\t"					"rep\n\t"					"movsl\n\t"					"movl %0,%%edi\n\t"					"addl $32,%%edi\n\t"					"movl %1,%%esi\n\t"					"movl %2,%%ecx\n\t"					"subl $8,%%ecx\n\t"					"rep\n\t"					"movsl\n\t"					"movl %0,%%edi\n\t"					"movl $8,%%ecx\n\t"					"rep\n\t"					"movsl\n\t"					:: "g" (p), "g" (pp), "g" (len)					: "edi", "esi", "ecx"				);				do_tick();				BAILR			}			p = pe;		} while (!done);	}	/* Now check the data 	 * The error checking is rather crude.  We just check that the	 * adjacent words are the same.	 */	for (j=0; j<segs; j++) {		start = (unsigned long)map[j].start;		end = (unsigned long)map[j].end;		pe = start;		p = start;		done = 0;		do {			/* Check for overflow */			if (pe + SPINSZ*4 > pe) {				pe += SPINSZ*4;			} else {				pe = end;			}			if (pe >= end) {				pe = end;				done++;			}			if (p == pe ) {				break;			}			asm __volatile__ (				"jmp L120\n\t"				".p2align 4,,7\n\t"				"L120:\n\t"				"movl (%%edi),%%ecx\n\t"				"cmpl 4(%%edi),%%ecx\n\t"				"jnz L121\n\t"				"L122:\n\t"				"addl $8,%%edi\n\t"				"cmpl %%edx,%%edi\n\t"				"jb L120\n"				"jmp L123\n\t"				"L121:\n\t"				"pushl %%edx\n\t"				"pushl 4(%%edi)\n\t"				"pushl %%ecx\n\t"				"pushl %%edi\n\t"				"call mv_error\n\t"				"popl %%edi\n\t"				"addl $8,%%esp\n\t"				"popl %%edx\n\t"				"jmp L122\n"				"L123:\n\t"				: "=D" (p)				: "D" (p), "d" (pe)				: "ecx"			);			do_tick();			BAILR		} while (!done);	}}#endif#if 0int main(int argc,char **argv){	char *buf;	buf = (char*)malloc(0x10000000);	map[0].start = (unsigned long*)buf;	map[0].end = (unsigned long*)(buf + 0x10000000);	addr_tst1();	addr_tst2();	movinv1(2,0,~0);}#endif

⌨️ 快捷键说明

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