📄 extra.c
字号:
// This is the extra stuff added to the memtest+ from memtest.org// Code from Eric Nelson and Wee// (Checked without vendor-specific optimization before adding)/* extra.c - * * Released under version 2 of the Gnu Public License. * */#include "test.h"#include "screen_buffer.h"#include "pci.h"#include "extra.h"static int claim = 0;static int ctrl = -1;struct memory_controller { unsigned vendor; unsigned device; int worked; void (*change_timing)(int cas, int rcd, int rp, int ras);};static struct memory_controller mem_ctr[] = { /* AMD 64*/ { 0x1022, 0x1100, 1, change_timing_amd64}, //AMD64 hypertransport link /* nVidia */ { 0x10de, 0x01E0, 0, change_timing_nf2}, // nforce2 /* Intel */ { 0x8086, 0x2570, 0, change_timing_i875}, //Intel i848/i865 { 0x8086, 0x2578, 0, change_timing_i875}, //Intel i875P { 0x8086, 0x2580, 0, change_timing_i925}, //Intel i915P/G { 0x8086, 0x2584, 0, change_timing_i925}, //Intel i925X { 0x8086, 0x2770, 0, change_timing_i925}, //Intel Lakeport { 0x8086, 0x3580, 0, change_timing_i852}, //Intel i852GM - i855GM/GME (But not i855PM)};struct drc { unsigned t_rwt; unsigned t_wrt; unsigned t_ref; unsigned t_en2t; unsigned t_rwqb; unsigned t_rct; unsigned t_rrd; unsigned t_wr;};static struct drc a64;void find_memctr(void) // Basically copy from the find_controller function{ unsigned long vendor; unsigned long device; unsigned long a64; int i= 0; int result; result = pci_conf_read(0, 0, 0, PCI_VENDOR_ID, 2, &vendor); result = pci_conf_read(0, 0, 0, PCI_DEVICE_ID, 2, &device); pci_conf_read(0, 24, 0, 0x00, 4, &a64); if( a64 == 0x11001022) { ctrl = 0; return; } if (result == 0) { for(i = 1; i < sizeof(mem_ctr)/sizeof(mem_ctr[0]); i++) { if ((mem_ctr[i].vendor == vendor) && (mem_ctr[i].device == device)) { ctrl = i; return; } } } ctrl = -1;}void a64_parameter(void){ ulong dramtlr; if ( 0 == pci_conf_read(0, 24, 2, 0x88, 4, &dramtlr) ) { a64.t_rct = 7 + ((dramtlr>>4) & 0x0F); a64.t_rrd = 0 + ((dramtlr>>16) & 0x7); a64.t_wr = 2 + ((dramtlr>>28) & 0x1); } if ( 0 == pci_conf_read(0, 24, 2, 0x8C, 4, &dramtlr) ) { a64.t_rwt = 1 + ((dramtlr>>4) & 0x07); a64.t_wrt = 1 + (dramtlr & 0x1); a64.t_ref = 1 + ((dramtlr>>11) & 0x3); } if ( 0 == pci_conf_read(0, 24, 2, 0x90, 4, &dramtlr) ) { a64.t_en2t = 1 + ((dramtlr>>28) & 0x1); a64.t_rwqb = 2 << ((dramtlr>>14) & 0x3); }}void change_timing(int cas, int rcd, int rp, int ras){ find_memctr(); if ((ctrl == -1) || ( ctrl > sizeof(mem_ctr)/sizeof(mem_ctr[0]))) { return; } mem_ctr[ctrl].change_timing(cas, rcd, rp, ras); restart();}void amd64_option(){ int rwt=0, wrt=0, ref=0, en2t=0, rct=0, rrd=0, rwqb=0, wr = 0, flag=0; if ((ctrl == -1) || ( ctrl > sizeof(mem_ctr)/sizeof(mem_ctr[0]))) { return; } if (mem_ctr[ctrl].worked) { a64_parameter(); cprint(POP_Y+1, POP_X+4, "AMD64 options"); cprint(POP_Y+3, POP_X+4, "(1) Rd-Wr Delay : "); dprint(POP_Y+3, POP_X+24, a64.t_rwt, 2, 0); cprint(POP_Y+4, POP_X+4, "(2) Wr-Rd Delay : "); dprint(POP_Y+4, POP_X+24, a64.t_wrt, 2, 0); cprint(POP_Y+5, POP_X+4, "(3) Rd/Wr Bypass : "); dprint(POP_Y+5, POP_X+24, a64.t_rwqb, 2, 0); cprint(POP_Y+6, POP_X+4, "(4) Refresh Rate : "); switch ( a64.t_ref) { case 1 : cprint(POP_Y+6, POP_X+23, "15.6us"); break; case 2 : cprint(POP_Y+6, POP_X+23, " 7.8us"); break; case 3 : cprint(POP_Y+6, POP_X+23, " 3.9us"); break; } cprint(POP_Y+7, POP_X+4, "(5) Command Rate :"); dprint(POP_Y+7, POP_X+24, a64.t_en2t, 2, 0); cprint(POP_Y+7, POP_X+26, "T "); cprint(POP_Y+8, POP_X+4, "(6) Row Cycle Time: "); dprint(POP_Y+8, POP_X+24, a64.t_rct, 2, 0); cprint(POP_Y+9, POP_X+4, "(7) RAS-RAS Delay : "); dprint(POP_Y+9, POP_X+24, a64.t_rrd, 2, 0); cprint(POP_Y+10, POP_X+4, "(8) Write Recovery: "); dprint(POP_Y+10, POP_X+24, a64.t_wr, 2, 0); cprint(POP_Y+11, POP_X+4,"(0) Cancel "); while(!flag) { switch(get_key()) { case 2: popclear(); // read-to-write delay cprint(POP_Y+3, POP_X+4, "Rd-Wr delay "); cprint(POP_Y+4, POP_X+4, " (2 - 6 cycles)"); cprint(POP_Y+5, POP_X+4, "Current: "); dprint(POP_Y+5, POP_X+14, a64.t_rwt, 4, 0); cprint(POP_Y+7, POP_X+4, "New: "); rwt = getval(POP_Y+7, POP_X+12, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 3: popclear(); // read-to-write delay cprint(POP_Y+3, POP_X+4, "Wr-Rd delay "); cprint(POP_Y+4, POP_X+4, " (1 - 2 cycles)"); cprint(POP_Y+5, POP_X+4, "Current: "); dprint(POP_Y+5, POP_X+14, a64.t_wrt, 4, 0); cprint(POP_Y+7, POP_X+4, "New: "); wrt = getval(POP_Y+7, POP_X+12, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 4: popclear(); // Read write queue bypass count cprint(POP_Y+3, POP_X+4, "Rd/Wr bypass "); cprint(POP_Y+4, POP_X+4, " (2, 4 or 8 )"); cprint(POP_Y+5, POP_X+4, "Current: "); dprint(POP_Y+5, POP_X+14, a64.t_rwqb, 2, 0); cprint(POP_Y+7, POP_X+4, "New: "); rwqb = getval(POP_Y+7, POP_X+11, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 5: popclear(); // refresh rate cprint(POP_Y+3, POP_X+4, "Refresh rate "); cprint(POP_Y+4, POP_X+4, "Current: "); switch ( a64.t_ref){ case 1 : cprint(POP_Y+4, POP_X+14, "15.6us"); break; case 2 : cprint(POP_Y+4, POP_X+14, "7.8us "); break; case 3 : cprint(POP_Y+4, POP_X+14, "3.9us "); break; } cprint(POP_Y+6, POP_X+4, "New: "); cprint(POP_Y+7, POP_X+4, "(1) 15.6us"); cprint(POP_Y+8, POP_X+4, "(2) 7.8us "); cprint(POP_Y+9, POP_X+4, "(3) 3.9us "); ref = getval(POP_Y+6, POP_X+11, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 6: popclear(); //Enable 2T command and addressing cprint(POP_Y+3, POP_X+4, "Command rate:"); cprint(POP_Y+5, POP_X+4, "(1) 1T "); //only supoprted by CG revision and later cprint(POP_Y+6, POP_X+4, "(2) 2T "); en2t = getval(POP_Y+3, POP_X+22, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 7: popclear(); //Row cycle time cprint(POP_Y+3, POP_X+4, "Row cycle time: "); cprint(POP_Y+4, POP_X+4, " (7 - 20 cycles)"); cprint(POP_Y+5, POP_X+4, "Current: "); dprint(POP_Y+5, POP_X+14, a64.t_rct, 4, 0); cprint(POP_Y+7, POP_X+4, "New: "); rct = getval(POP_Y+7, POP_X+12, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 8: popclear(); //Active-to-Active RAS Delay cprint(POP_Y+3, POP_X+4, "RAS-RAS Delay: "); cprint(POP_Y+4, POP_X+4, " (2 - 4 cycles)"); cprint(POP_Y+5, POP_X+4, "Current: "); dprint(POP_Y+5, POP_X+14, a64.t_rrd, 2, 0); cprint(POP_Y+7, POP_X+4, "New: "); rrd = getval(POP_Y+7, POP_X+12, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 9: popclear(); //Active-to-Active RAS Delay cprint(POP_Y+3, POP_X+4, "Write Recovery: "); cprint(POP_Y+4, POP_X+4, " (2 - 3 cycles)"); cprint(POP_Y+5, POP_X+4, "Current: "); dprint(POP_Y+5, POP_X+14, a64.t_wr, 2, 0); cprint(POP_Y+7, POP_X+4, "New: "); wr = getval(POP_Y+7, POP_X+12, 0); amd64_tweak(rwt, wrt, ref,en2t, rct, rrd, rwqb, wr); break; case 11: case 57: flag++; /* 0/CR - Cancel */ break; } } }}void get_option(){ int cas =0, rp=0, rcd=0, ras=0, sflag = 0 ; while(!sflag) { switch(get_key()) { case 2: popclear(); cas = get_cas(); popclear(); cprint(POP_Y+3, POP_X+8, "tRCD: "); rcd = getval(POP_Y+3, POP_X+15, 0); popclear(); cprint(POP_Y+3, POP_X+8, "tRP: "); rp = getval(POP_Y+3, POP_X+15, 0); popclear(); cprint(POP_Y+3, POP_X+8, "tRAS: "); ras = getval(POP_Y+3, POP_X+15, 0); popclear(); change_timing(cas, rcd, rp, ras); break; case 3: popclear(); cas = get_cas(); change_timing(cas, 0, 0, 0); sflag++; break; case 4: popclear(); cprint(POP_Y+3, POP_X+8, "tRCD: "); rcd =getval(POP_Y+3, POP_X+15, 0); change_timing(0, rcd, 0, 0); sflag++; break; case 5: popclear(); cprint(POP_Y+3, POP_X+8, "tRP: "); rp =getval(POP_Y+3, POP_X+15, 0); change_timing(0, 0, rp, 0); sflag++; break; case 6: popclear(); cprint(POP_Y+3, POP_X+8, "tRAS: "); ras =getval(POP_Y+3, POP_X+15, 0); change_timing(0, 0, 0, ras); sflag++; break; case 7: popclear(); amd64_option(); sflag++; popclear(); break; case 8: break; case 11: case 57: sflag++; /* 0/CR - Cancel */ break; } }}void get_option_1(){ int rp=0, rcd=0, ras=0, sflag = 0 ; while(!sflag) { switch(get_key()) { case 2: popclear(); cprint(POP_Y+3, POP_X+8, "tRCD: "); rcd = getval(POP_Y+3, POP_X+15, 0); popclear(); cprint(POP_Y+3, POP_X+8, "tRP: "); rp = getval(POP_Y+3, POP_X+15, 0); popclear(); cprint(POP_Y+3, POP_X+8, "tRAS: "); ras = getval(POP_Y+3, POP_X+15, 0); popclear(); change_timing(0, rcd, rp, ras); break; case 3: popclear(); cprint(POP_Y+3, POP_X+8, "tRCD: "); rcd =getval(POP_Y+3, POP_X+15, 0); change_timing(0, rcd, 0, 0); break; case 4: popclear(); cprint(POP_Y+3, POP_X+8, "tRP: "); rp =getval(POP_Y+3, POP_X+15, 0); change_timing(0, 0, rp, 0); break; case 5: popclear(); cprint(POP_Y+3, POP_X+8, "tRAS: "); ras =getval(POP_Y+3, POP_X+15, 0); change_timing(0, 0, 0, ras); break; case 6: popclear(); amd64_option(); sflag++; popclear(); break; case 7: break; case 11: case 57: sflag++; /* 0/CR - Cancel */ break; } }}void get_menu(void){ int menu ; find_memctr(); disclaimer(); switch(ctrl) { case 0: menu = 2; break; case 1: case 2: case 3: case 4: menu = 0; break; case 5: menu = 1; break; case 6: menu = 0; break; default: menu = -1; break; } if (menu == -1) { popclear(); } else if (menu == 0) { cprint(POP_Y+1, POP_X+2, "Modify Timing:"); cprint(POP_Y+3, POP_X+5, "(1) Modify All "); cprint(POP_Y+4, POP_X+5, "(2) Modify tCAS "); cprint(POP_Y+5, POP_X+5, "(3) Modify tRCD "); cprint(POP_Y+6, POP_X+5, "(4) Modify tRP "); cprint(POP_Y+7, POP_X+5, "(5) Modify tRAS "); cprint(POP_Y+8, POP_X+5, "(0) Cancel"); wait_keyup(); get_option(); } else if (menu == 1) { cprint(POP_Y+1, POP_X+2, "Modify Timing:"); cprint(POP_Y+3, POP_X+5, "(1) Modify All "); cprint(POP_Y+4, POP_X+5, "(2) Modify tRCD "); cprint(POP_Y+5, POP_X+5, "(3) Modify tRP "); cprint(POP_Y+6, POP_X+5, "(4) Modify tRAS "); cprint(POP_Y+7, POP_X+5, "(0) Cancel"); wait_keyup(); get_option(); } else // AMD64 special menu { cprint(POP_Y+1, POP_X+2, "Modify Timing:"); cprint(POP_Y+3, POP_X+5, "(1) Modify All "); cprint(POP_Y+4, POP_X+5, "(2) Modify tRCD "); cprint(POP_Y+5, POP_X+5, "(3) Modify tRP "); cprint(POP_Y+6, POP_X+5, "(4) Modify tRAS "); cprint(POP_Y+7, POP_X+5, "(5) AMD64 Options"); cprint(POP_Y+8, POP_X+5, "(0) Cancel"); wait_keyup(); get_option_1(); }}int get_cas(void){ int i852=0, cas=0; ulong drc, ddr; long *ptr; switch(ctrl) { case 0: ddr = 1; break; case 1: case 2: case 3: ddr = 1; break; case 4: pci_conf_read( 0, 0, 0, 0x44, 4, &ddr); ddr &= 0xFFFFC000; ptr=(long*)(ddr+0x120); drc = *ptr; if ((drc & 3) == 2) ddr = 2; else ddr = 1; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -