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 + -
显示快捷键?