📄 lib.c
字号:
/* lib.c - MemTest-86 Version 3.0 * * Released under version 2 of the Gnu Public License. * By Chris Brady, cbrady@sgi.com */#include "io.h"#include "serial.h"#include "test.h"#include "config.h"#include "screen_buffer.h"extern int fast_mode;int slock = 0, lsr = 0;short serial_cons = SERIAL_CONSOLE_DEFAULT;char buf[18];struct ascii_map_str { int ascii; int keycode;};char *codes[] = { " Divide", " Debug", " NMI", " Brkpnt", "Overflow", " Bound", " Inv_Op", " No_Math", "Double_Fault", "Seg_Over", " Inv_TSS", " Seg_NP", "Stack_Fault", "Gen_Prot", "Page_Fault", " Resvd", " FPE", "Alignment", " Mch_Chk", "SIMD FPE"};struct eregs { ulong esp; ulong ebp; ulong esi; ulong edi; ulong edx; ulong ecx; ulong ebx; ulong eax; ulong vect; ulong code; ulong eip; ulong cs; ulong eflag;};int memcmp(const void *s1, const void *s2, ulong count){ const unsigned char *src1 = s1, *src2 = s2; int i; for(i = 0; i < count; i++) { if (src1[i] != src2[i]) { return (int)src1[i] - (int)src2[i]; } } return 0;}void *memmove(void *dest, const void *src, ulong n){ long i; char *d = (char *)dest, *s = (char *)src; /* If src == dest do nothing */ if (dest < src) { for(i = 0; i < n; i++) { d[i] = s[i]; } } else if (dest > src) { for(i = n -1; i >= 0; i--) { d[i] = s[i]; } } return dest;}/* * Scroll the error message area of the screen as needed * Starts at line LINE_SCROLL and ends at line 23 */void scroll(void){ int i, j; char *s, tmp; /* Only scroll if at the bottom of the screen */ if (v->msg_line < 23) { v->msg_line++; } else { /* If scroll lock is on, loop till it is cleared */ while (slock) { check_input(); } for (i=LINE_SCROLL; i<23; i++) { s = (char *)(SCREEN_ADR + ((i+1) * 160)); for (j=0; j<160; j+=2, s+=2) { *(s-160) = *s; tmp = get_scrn_buf(i+1, j/2); set_scrn_buf(i, j/2, tmp); } } /* Clear the newly opened line */ s = (char *)(SCREEN_ADR + (23 * 160)); for (j=0; j<80; j++) { *s = ' '; set_scrn_buf(23, j, ' '); s += 2; } tty_print_region(LINE_SCROLL, 0, 23, 79); }}/* * Print characters on screen */void cprint(int y, int x, const char *text){ register int i; char *dptr; dptr = (char *)(SCREEN_ADR + (160*y) + (2*x)); for (i=0; text[i]; i++) { *dptr = text[i]; dptr += 2; } tty_print_line(y, x, text);}void itoa(char s[], int n){ int i, sign; if((sign = n) < 0) n = -n; i=0; do { s[i++] = n % 10 + '0'; } while ((n /= 10) > 0); if(sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s);}void reverse(char s[]){ int c, i, j; for(j = 0; s[j] != 0; j++) ; for(i=0, j = j - 1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; }}/* * Print a people friendly address */void aprint(int y, int x, ulong page){ /* page is in multiples of 4K */ if ((page << 2) < 9999) { dprint(y, x, page << 2, 4, 0); cprint(y, x+4, "K"); } else if ((page >>8) < 9999) { dprint(y, x, (page + (1 << 7)) >> 8, 4, 0); cprint(y, x+4, "M"); } else if ((page >>18) < 9999) { dprint(y, x, (page + (1 << 17)) >> 18, 4, 0); cprint(y, x+4, "G"); } else { dprint(y, x, (page + (1 << 27)) >> 28, 4, 0); cprint(y, x+4, "T"); }}/* * Print a decimal number on screen */void dprint(int y, int x, ulong val, int len, int right){ ulong j, k; int i, flag=0; if (val > 999999999 || len > 9) { return; } for(i=0, j=1; i<len-1; i++) { j *= 10; } if (!right) { for (i=0; j>0; j/=10) { k = val/j; if (k > 9) { j *= 100; continue; } if (flag || k || j == 1) { buf[i++] = k + '0'; flag++; } else { buf[i++] = ' '; } val -= k * j; } } else { for(i=0; i<len; j/=10) { if (j) { k = val/j; if (k > 9) { j *= 100; len++; continue; } if (k == 0 && flag == 0) { continue; } buf[i++] = k + '0'; val -= k * j; } else { if (flag == 0 && i < len-1) { buf[i++] = '0'; } else { buf[i++] = ' '; } } flag++; } } buf[i] = 0; cprint(y,x,buf);}/* * Print a hex number on screen at least digits long */void hprint2(int y,int x, unsigned long val, int digits){ unsigned long j; int i, idx, flag = 0; for (i=0, idx=0; i<8; i++) { j = val >> (28 - (4 * i)); j &= 0xf; if (j < 10) { if (flag || j || i == 7) { buf[idx++] = j + '0'; flag++; } else { buf[idx++] = '0'; } } else { buf[idx++] = j + 'a' - 10; flag++; } } if (digits > 8) { digits = 8; } if (flag > digits) { digits = flag; } buf[idx] = 0; cprint(y,x,buf + (idx - digits));}/* * Print a hex number on screen exactly digits long */void hprint3(int y,int x, unsigned long val, int digits){ unsigned long j; int i, idx, flag = 0; for (i=0, idx=0; i<digits; i++) { j = 0xf & val; val /= 16; if (j < 10) { if (flag || j || i == 7) { buf[digits - ++idx] = j + '0'; flag++; } else { buf[digits - ++idx] = '0'; } } else { buf[digits - ++idx] = j + 'a' - 10; flag++; } } buf[idx] = 0; cprint(y,x,buf);}/* * Print a hex number on screen */void hprint(int y, int x, unsigned long val){ return hprint2(y, x, val, 8);}/* * Print an address in 0000m0000k0000 notation */void xprint(int y,int x, ulong val){ ulong j; j = (val & 0xffc00000) >> 20; dprint(y, x, j, 4, 0); cprint(y, x+4, "m"); j = (val & 0xffc00) >> 10; dprint(y, x+5, j, 4, 0); cprint(y, x+9, "k"); j = val & 0x3ff; dprint(y, x+10, j, 4, 0);}/* Handle an interrupt */void inter(struct eregs *trap_regs){ int i, line; unsigned char *pp; ulong address = 0; /* Get the page fault address */ if (trap_regs->vect == 14) { __asm__("movl %%cr2,%0":"=r" (address)); }#ifdef PARITY_MEM /* Check for a parity error */ if (trap_regs->vect == 2) { parity_err(trap_regs->edi, trap_regs->esi); return; }#endif /* clear scrolling region */ pp=(unsigned char *)(SCREEN_ADR+(2*80*(LINE_SCROLL-2))); for(i=0; i<2*80*(24-LINE_SCROLL-2); i++, pp+=2) { *pp = ' '; } line = LINE_SCROLL-2; cprint(line, 0, "Unexpected Interrupt - Halting"); cprint(line+2, 0, " Type: "); if (trap_regs->vect <= 19) { cprint(line+2, 7, codes[trap_regs->vect]); } else { hprint(line+2, 7, trap_regs->vect); } cprint(line+3, 0, " PC: "); hprint(line+3, 7, trap_regs->eip); cprint(line+4, 0, " CS: "); hprint(line+4, 7, trap_regs->cs); cprint(line+5, 0, "Eflag: "); hprint(line+5, 7, trap_regs->eflag); cprint(line+6, 0, " Code: "); hprint(line+6, 7, trap_regs->code); if (trap_regs->vect == 14) { /* Page fault address */ cprint(line+7, 0, " Addr: "); hprint(line+7, 7, address); } cprint(line+2, 20, "eax: "); hprint(line+2, 25, trap_regs->eax); cprint(line+3, 20, "ebx: "); hprint(line+3, 25, trap_regs->ebx); cprint(line+4, 20, "ecx: "); hprint(line+4, 25, trap_regs->ecx); cprint(line+5, 20, "edx: "); hprint(line+5, 25, trap_regs->edx); cprint(line+6, 20, "edi: "); hprint(line+6, 25, trap_regs->edi); cprint(line+7, 20, "esi: "); hprint(line+7, 25, trap_regs->esi); cprint(line+8, 20, "ebp: "); hprint(line+8, 25, trap_regs->ebp); cprint(line+9, 20, "esp: "); hprint(line+9, 25, trap_regs->esp); cprint(line+1, 38, "Stack:"); for (i=0; i<12; i++) { hprint(line+2+i, 38, trap_regs->esp+(4*i)); hprint(line+2+i, 47, *(ulong*)(trap_regs->esp+(4*i))); hprint(line+2+i, 57, trap_regs->esp+(4*(i+12))); hprint(line+2+i, 66, *(ulong*)(trap_regs->esp+(4*(i+12)))); } cprint(line+11, 0, "CS:EIP: "); pp = (unsigned char *)trap_regs->eip; for(i = 0; i < 10; i++) { hprint2(line+11, 8+(3*i), pp[i], 2); } while(1) { check_input(); }}void set_cache(int val){ extern struct cpu_ident cpu_id; /* 386's don't have a cache */ if ((cpu_id.cpuid < 1) && (cpu_id.type == 3)) { cprint(LINE_INFO, COL_CACHE, "none"); return; } switch(val) { case 0: cache_off(); cprint(LINE_INFO, COL_CACHE, "off"); break; case 1: cache_on(); cprint(LINE_INFO, COL_CACHE, " on"); break; }}int get_key() { int c; c = inb(0x64); if ((c & 1) == 0) { if (serial_cons) { int comstat; comstat = serial_echo_inb(UART_LSR); if (comstat & UART_LSR_DR) { c = serial_echo_inb(UART_RX); /* Pressing '.' has same effect as 'c' on a keyboard. Oct 056 Dec 46 Hex 2E Ascii . */ return (ascii_to_keycode(c)); } } return(0); } c = inb(0x60); return((c));}void check_input(void){ unsigned char c; if ((c = get_key())) { switch(c & 0x7f) { case 1: /* "ESC" key was pressed, bail out. */ cprint(LINE_RANGE, COL_MID+23, "Halting... "); /* tell the BIOS to do a warm start */ *((unsigned short *)0x472) = 0x1234; outb(0xfe,0x64); break; case 46: /* c - Configure */ get_config(); break; case 28: /* CR - clear scroll lock */ slock = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -