📄 memory.~pas
字号:
unit Memory;
interface
uses OMCDrv, CmnTnC;
type
DWord = LongWord;
tCtrl_Info = packed record
index, poll, cap, mode: integer;
dwBus, dwDev, dwFunc: DWord;
end; tTimings = packed record CAS, RCD, RP, RAS: single; end; tgRAMInfo = packed record DRAMClock: double; RamSize: DWord; DRAMCoef, DRAMCnls, DRAMType, DRAMAccel: string; end; tGetFSBMethod = procedure (lCPUClock, FSB: double; Mult: single; var GRAMInfo: tGRAMInfo); tGetTmngsMethod = procedure (var Timings: tTimings; var gRAMInfo: tGRAMInfo); tSetupECCMethod = procedure; Memory_Controller = packed record VendorID, DeviceID: Word; name: string; tested: integer; GetFSBMethod: tGetFSBMethod; GetTmngsMethod: tGetTmngsMethod; SetupECCMethod: tSetupECCMethod; end;
cMemory = class
private
public
fCtrl_Info: tCtrl_Info;
fTimings: tTimings;
fgRAMInfo: tgRAMInfo;
constructor Create;
destructor Destroy; override;
procedure DetectMemCtrl;
function GetPhysMemSize: DWord;
procedure FillMemCtrlInfo(lCPUClock, FSB: double; Mult: single);
end;
var
MemInfo: cMemory;
implementation
uses SysUtils, Windows, Dialogs;
//nVidia nForce 2 Methods
procedure poll_fsb_nf2(lCPUClock, FSB: double; Mult: single; var gRAMInfo: tGRAMInfo);
var
mempll: DWord;
mem_m, mem_n: byte;
begin
//Get the coef (COEF = N/M) - Here is for Crush17
oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 3, $70, mempll);
mem_m:=mempll and $0F; mem_n:=(mempll shr 4) and $0F;
//ShowMessage(format('%x', [oHWIO.MemReadLong($5620)]));
//If something goes wrong, the chipset is probably a Crush18
if (mem_m = 0) or (mem_n = 0) then begin oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 3, $7C, mempll); mem_m:=mempll and $0F; mem_n:=(mempll shr 4) and $0F; end;
//Computing DRAM Frequency
gRAMInfo.DRAMClock:=FSB*(mem_n/mem_m);
//Forming DRAM : FSB Divider
if (mem_n = mem_m) then gRAMInfo.DRAMCoef:='1:1'
else gRAMInfo.DRAMCoef:=IntToStr(mem_m)+':'+IntToStr(mem_n);
end;
procedure poll_timings_nf2(var Timings: tTimings; var gRAMInfo: tGRAMInfo);
var
dramtlr, dramtlr2, dramtlr3, temp: DWord;
dimm1p, dimm2p, dimm3p: DWord;
begin
oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 1, $90, dramtlr);
oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 1, $A0, dramtlr2);
oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 1, $84, dramtlr3);
oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 2, $40, dimm1p);
oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 2, $44, dimm2p);
oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 2, $48, dimm3p);
//CAS Latency (tCAS)
temp:=(dramtlr2 shr 4) and $7; if (temp = $2) then Timings.CAS:=2 else if (temp = $6) then Timings.CAS:=2.5 else if (temp = $3) then Timings.CAS:=3; //RAS-To-CAS (tRCD) Timings.RCD:=(dramtlr shr 20) and $F; //RAS Precharge (tRP) Timings.RP:=(dramtlr shr 28) and $F; //RAS Active to precharge (tRAS) Timings.RAS:=(dramtlr shr 15) and $F; //Print 64 or 128 bits mode //If DIMM1 & DIMM3 or DIMM1 & DIMM2 populated, than Dual Channel. if (((dimm3p and 1)+(dimm2p and 1) = 2) or ((dimm3p and 1)+(dimm1p and 1) = 2)) then gRAMInfo.DRAMCnls:='Dual' else gRAMInfo.DRAMCnls:='Single'; gRAMInfo.DRAMType:='DDR-SDRAM'end;
//AMD64 Methods
procedure poll_fsb_amd64(lCPUClock, FSB: double; Mult: single; var gRAMInfo: tGRAMInfo);
var
dramchr, temp: DWord;
clockratio: single;
begin
oHWIO.IPCIIORef.GetPCIRDWord(0, 24, 2, $94, dramchr);
temp:=(dramchr shr 20) and $7;
clockratio:=Mult;
case temp of
$0: clockratio:=trunc(Mult*2.0);
$2: clockratio:=trunc((Mult*3.0/2.0)+0.81); $4: clockratio:=trunc((Mult*4.0/3.0)+0.81); $5: clockratio:=trunc((Mult*6.0/5.0)+0.81); $6: clockratio:=trunc((Mult*10.0/9.0)+0.81); $7: clockratio:=trunc(Mult+0.81); end; gRAMInfo.DRAMClock:=lCPUClock/clockratio; gRAMInfo.DRAMCoef:='CPU/'+IntToStr(trunc(clockratio));end;procedure poll_timings_amd64(var Timings: tTimings; var gRAMInfo: tGRAMInfo);var dramtlr, dramclr, temp: DWord;begin oHWIO.IPCIIORef.GetPCIRDWord(0, 24, 2, $88, dramtlr); oHWIO.IPCIIORef.GetPCIRDWord(0, 24, 2, $90, dramclr); //CAS Latency (tCAS) temp:=dramtlr and $7; if (temp = $1) then Timings.CAS:=2 else if (temp = $2) then Timings.CAS:=3 else if (temp = $5) then Timings.CAS:=2.5; //RAS-To-CAS (tRCD) Timings.RCD:=(dramtlr shr 12) and $7; //RAS Precharge (tRP) Timings.RP:=(dramtlr shr 24) and $7; //RAS Active to precharge (tRAS) Timings.RAS:=(dramtlr shr 20) and $F; if (((dramclr shr 16) and 1) = 1) then gRAMInfo.DRAMCnls:='Dual' else gRAMInfo.DRAMCnls:='Single'; gRAMInfo.DRAMType:='DDR-SDRAM'end;//nVidia nForce 4 SLI Intel Editionprocedure poll_fsb_nf4ie(lCPUClock, FSB: double; Mult: single; var gRAMInfo: tGRAMInfo);var mratio, nratio: byte; reg60: DWord; reg74: Word; DRAMRatio: double;begin //Find dramratio oHWIO.IPCIIORef.GetPCIRWord(0, 0, 2, $74, reg74); oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 2, $60, reg60); mratio:=reg74 and $F; nratio:=(reg74 shr 4) and $F; //If M or N = 0, then M or N = 16 if (mratio = 0) then mratio:=16; if (nratio = 0) then nratio:=16; //Check if synchro or pseudo-synchro mode if (((reg60 shr 22) and 1) = 1) then DRAMRatio:=1 else DRAMRatio:=nratio/mratio; gRAMInfo.DRAMClock:=FSB*DRAMRatio; if (DRAMRatio = 1) then gRAMInfo.DRAMCoef:='1:1' else gRAMInfo.DRAMCoef:=IntToStr(mratio)+':'+IntToStr(nratio);end;procedure poll_timings_nf4ie(var Timings: tTimings; var gRAMInfo: tGRAMInfo);var regd0, reg8c, reg9c: DWord; reg80: byte;begin //Now, read Registers oHWIO.IPCIIORef.GetPCIRDWord( 0, 1, 1, $D0, regd0); oHWIO.IPCIIORef.GetPCIRByte( 0, 1, 1, $80, reg80); oHWIO.IPCIIORef.GetPCIRDWord( 0, 1, 0, $8C, reg8c); oHWIO.IPCIIORef.GetPCIRDWord( 0, 1, 0, $9C, reg9c); //Then, detect timings Timings.CAS:=(regd0 shr 4) and $7; Timings.RCD:=(reg8c shr 24) and $F; Timings.RP:=(reg9c shr 8) and $F; Timings.RAS:=(reg8c shr 16) and $3F; if ((reg80 and $3) <> 0) then gRAMInfo.DRAMCnls:='Dual' else gRAMInfo.DRAMCnls:='Single'; gRAMInfo.DRAMType:='DDRII-SDRAM'end;
//Intel i875 Methods
procedure poll_fsb_i875(lCPUClock, FSB: double; Mult: single; var gRAMInfo: tGRAMInfo);
var
smfs: DWord;
mchcfg: Word;
DRAMRatio: single;
begin
oHWIO.IPCIIORef.GetPCIRWord(0, 0, 0, $C6, mchcfg);
smfs:=(mchcfg shr 10) and 3;
DRAMRatio:=1;
gRAMInfo.DRAMCoef:='1:1';
if ((mchcfg and 3) = 3) then begin DRAMRatio:=1; gRAMInfo.DRAMCoef:='1:1'; end;
if ((mchcfg and 3) = 2) then
begin
if (smfs = 2) then begin DRAMRatio:=1; gRAMInfo.DRAMCoef:='1:1'; end; if (smfs = 1) then begin DRAMRatio:=1.25; gRAMInfo.DRAMCoef:='5:4'; end; if (smfs = 0) then begin DRAMRatio:=1.5; gRAMInfo.DRAMCoef:='3:2'; end; end;
if ((mchcfg and 3) = 1) then
begin
if (smfs = 2) then begin DRAMRatio:=0.6666666666; gRAMInfo.DRAMCoef:='2:3'; end; if (smfs = 1) then begin DRAMRatio:=0.8; gRAMInfo.DRAMCoef:='4:5'; end; if (smfs = 0) then begin DRAMRatio:=1; gRAMInfo.DRAMCoef:='1:1'; end; end; if ((mchcfg and 3) = 0) then begin DRAMRatio:=0.75; gRAMInfo.DRAMCoef:='3:4'; end;
gRAMInfo.DRAMClock:=FSB/DRAMRatio;
end;
procedure poll_timings_i875(var Timings: tTimings; var gRAMInfo: tGRAMInfo);
var
dev6, dev62, temp: DWord;
tmp1, tmp2: DWord;
begin
//Read the MMR Base Address & Define the pointer
oHWIO.IPCIIORef.GetPCIRDWord(0, 6, 0, $10, dev6);
//Now, the PAT ritual ! (Kant and Luciano will love this)
oHWIO.IPCIIORef.GetPCIRDWord(0, 6, 0, $40, dev62); tmp2:=oHWIO.MemReadLong(dev6+$68); tmp1:=oHWIO.MemReadLong(dev6+$60); if (((dev62 and $3) = 0) and (((tmp2 shr 14) and 1) = 1)) then gRAMInfo.DRAMAccel:='Enabled' else gRAMInfo.DRAMAccel:='Disabled'; //CAS Latency (tCAS)
temp:=(tmp1 shr 5) and $3; if (temp = $0) then Timings.CAS:=2.5 else if (temp = $1) then Timings.CAS:=2 else Timings.CAS:=3; //RAS-To-CAS (tRCD) temp:=(tmp1 shr 2) and $3; if (temp = $0) then Timings.RCD:=4 else if (temp = $1) then Timings.RCD:=3 else Timings.RCD:= 2; //RAS Precharge (tRP) temp:=tmp1 and $3; if (temp = $0) then Timings.RP:=4 else if (temp = $1) then Timings.RP:=3 else Timings.RP:=2; //RAS Active to precharge (tRAS) temp:=(tmp1 shr 7) and $7; Timings.RAS:=10-temp;
//64 or 128 bits mode
if (((tmp2 shr 21) and 3) > 0) then gRAMInfo.DRAMCnls:='Dual'
else gRAMInfo.DRAMCnls:='Single'; gRAMInfo.DRAMType:='DDR-SDRAM'end;//Intel i925 Methodsprocedure poll_fsb_i925(lCPUClock, FSB: double; Mult: single; var gRAMInfo: tGRAMInfo);var mchcfg, mchcfg2, dev0, drc, idetect, tmp: DWord; DRAMRatio: single;begin oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 0, $02, idetect); idetect:=(idetect shr 16) and $FFFF; //Find dramratio oHWIO.IPCIIORef.GetPCIRDWord(0, 0, 0, $44, dev0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -