SMBUS访问

来源:互联网 发布:域名设置邮箱服务器 编辑:程序博客网 时间:2024/05/17 22:55

#include <windows.h>
#include <stdio.h>
#include "winio.h"

#pragma comment(lib,"WinIo.lib")

#define IO_SC0x0cf8//config space control address
#define IO_DA0x0cfc//config space data address
#define BASEADDRESS0x80000000//PCI-SMBus init address
#define DIMM00x0a0//memory device ID
#define DIMM10x0a2
#define DIMM20x0a4

/*
1s=1000(ms)
1s=1,000,000(μs)
1s=1,000,000,000(ns)
1s=1,000,000,000,000(ps)
*/
//高精度延时
void DelayUs(__int64 Us)
{
LARGE_INTEGER CurrTicks,TicksCount;
QueryPerformanceFrequency(&TicksCount);
QueryPerformanceCounter(&CurrTicks);

TicksCount.QuadPart=TicksCount.QuadPart*Us/1000000i64;
TicksCount.QuadPart+=CurrTicks.QuadPart;

while(CurrTicks.QuadPart<TicksCount.QuadPart)
QueryPerformanceCounter(&CurrTicks);
}

bool WaitReady(DWORD base)
{
DWORD STATUS;
do{
GetPortVal(base, &STATUS,1);
}while((STATUS&0x01)!=0);
return TRUE;
}

void ChkSMbus()
{
DWORD base=BASEADDRESS+(0<<16)+(0x1f<<11)+(0<<8);
DWORD RetVal=0;
SetPortVal(IO_SC,base+0x0f2,4);
GetPortVal(IO_DA,&RetVal,1);
printf("LPC(%08X) FUN_DIS: %02X/n",base,RetVal);
}

BYTE ReadSPD(DWORD base,BYTE offset,BYTE DEVID)
{
DWORD RetVal=0;
SetPortVal(base,0x0fe,1);
//output Base+04, (DeviceID+1)
SetPortVal(base+0x04,DEVID+1,1);
//out Base+03, offset
SetPortVal(base+0x03,offset,1);
//out Base+02, 48H
SetPortVal(base+0x02,0x48,1);
//wait 200ms
DelayUs(200*1000);
//wait smbus ready
if(WaitReady(base))
{//input base+05
GetPortVal(base+0x05,&RetVal,1);
}
return (BYTE)RetVal;
}

//byte0: the size of SPD used
bool SPD_BYTE0(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
RetVal=ReadSPD(base,0,DEVID);
if(RetVal>=128)
{
printf("The size of SPD used: %dbytes/n",RetVal);
return TRUE;
}
else
return FALSE;
}

//byte1: total size of SPD
void SPD_BYTE1(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
RetVal=ReadSPD(base,1,DEVID);
printf("Total size of SPD: %dbytes/n",(1<<RetVal));
}

//byte2: Memory Type
void SPD_BYTE2(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
RetVal=ReadSPD(base,2,DEVID);
//printf("TYPE Value: %d/n",RetVal);
switch(RetVal)
{
case 0x04:
printf("Memory Type is: SDRAM/n");
break;
case 0x07:
printf("Memory Type is: SDRAM DDR/n");
break;
default:
printf("Memory Type is: Other/n");
break;
}
}

//byte9: Cycle time
void SPD_BYTE9(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
float CylTime=0;
int temp;
RetVal=ReadSPD(base,9,DEVID);
//printf("Cycle time value: %dbytes/n",RetVal);
temp=(int)RetVal&0x0F;
if(temp<=9)
CylTime=(RetVal&0x0F)/10;
else
printf("Read Cycle time error!/n");

temp=(int)((RetVal&0x0F0)/16);
if(temp!=0)
CylTime=CylTime+temp;
else
printf("Read Cycle time error!/n");

//printf("Cyle Time is: %fns/n",CylTime);
temp=(int)2000/CylTime;
printf("RAM FSB=%dMHz/n",temp);
}

//byte31: Memory size
int SPD_BYTE1F(DWORD base,BYTE DEVID)
{
DWORD RetVal=0;
int RAMSZ=0;
RetVal=ReadSPD(base,0x1f,DEVID);
//printf("TYPE Value: %d/n",RetVal);
switch(RetVal)
{
case 0x04:RAMSZ=16;break;
case 0x08:RAMSZ=32;break;
case 0x10:RAMSZ=64;break;
case 0x20:RAMSZ=128;break;
case 0x40:RAMSZ=256;break;
case 0x80:RAMSZ=512;break;
case 0x01:RAMSZ=1024;break;
case 0x02:RAMSZ=2048;break;
default:RAMSZ=0;
}
return RAMSZ;
}

int main(int argc, char* argv[])
{
DWORD dataddr;
DWORD baseddr;
DWORD dwPortVal;
bool bResult;
int busID=0;
int deviceID=0;
int funID=0;
BYTE offset=0;

busID=strtoul(argv[1],NULL,16);
deviceID=strtoul(argv[2],NULL,16);
funID=strtoul(argv[3],NULL,16);
//ChkSMbus();
//get SMbus base address
dataddr=BASEADDRESS+(busID<<16)+(deviceID<<11)+(funID<<8);

// Call InitializeWinIo to initialize the WinIo library.
bResult = InitializeWinIo();

if(bResult)
{
//Get SMBus base address
SetPortVal(IO_SC,dataddr+0x20,4);
GetPortVal(IO_DA,&dwPortVal,4);
baseddr=dwPortVal&0x0FFFFFFF0;
printf("SMBus base address=%08X/n",baseddr);
if(WaitReady(baseddr))
{//read SPD info
//read Slot0 memory info
if(SPD_BYTE0(baseddr,DIMM0)==TRUE)
{
//SPD_BYTE1(baseddr,DIMM0);
SPD_BYTE2(baseddr,DIMM0);
SPD_BYTE9(baseddr,DIMM0);
printf("RAMSZ=%dMB/n",SPD_BYTE1F(baseddr,DIMM0));
}
else
{
printf("DIMM0: Read error!/n");
}

//read Slot1 memory info
if(SPD_BYTE0(baseddr,DIMM1)==TRUE)
{
//SPD_BYTE1(baseddr,DIMM0);
SPD_BYTE2(baseddr,DIMM1);
SPD_BYTE9(baseddr,DIMM1);
printf("RAMSZ=%dMB/n",SPD_BYTE1F(baseddr,DIMM1));
}
else
{
printf("DIMM1: Read error!/n");
}
}
}
else
{
printf("Error during initialization of WinIo./n");
exit(1);
}
// When you're done using WinIo, call ShutdownWinIo
ShutdownWinIo();
return 0;
}

不支持ICH7以上chip

原创粉丝点击