lfzxs
驱动牛犊
驱动牛犊
  • 注册日期2004-09-03
  • 最后登录2008-04-07
  • 粉丝1
  • 关注0
  • 积分60分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
阅读:5051回复:9

怎么读到内存的SPD信息?

楼主#
更多 发布于:2008-01-23 14:04
在WIN2K环境下,很少做底层的东西,不知道如何入手!
lfzxs
驱动牛犊
驱动牛犊
  • 注册日期2004-09-03
  • 最后登录2008-04-07
  • 粉丝1
  • 关注0
  • 积分60分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2008-01-23 14:06
找到的一段C代码,但没有成功
===========================================
#include   <windows.h>
#include   <stdio.h>
#include   "winio.h"

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

#define   IO_SC 0x0cf8 //config   space   control   address
#define   IO_DA 0x0cfc //config   space   data   address
#define   BASEADDRESS 0x80000000 //PCI-SMBus   init   address
#define   DIMM0 0x0a0 //memory   device   ID
#define   DIMM1 0x0a2
#define   DIMM2 0x0a4

/*
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;
}
lfzxs
驱动牛犊
驱动牛犊
  • 注册日期2004-09-03
  • 最后登录2008-04-07
  • 粉丝1
  • 关注0
  • 积分60分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2008-01-24 17:20
没人点指一下吗?!
hunbalo
驱动牛犊
驱动牛犊
  • 注册日期2004-04-21
  • 最后登录2020-10-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望124点
  • 贡献值0点
  • 好评度85点
  • 原创分1分
  • 专家分0分
  • 社区居民
地板#
发布于:2008-01-29 10:40
windows下不能直接操作物理地址及io地址, 不知道你这个winio library都实现了些什么,还有一点就是不通的主板smbus的物理地址可能不同,如果smbus是挂在pci总线上的,这个地址是动态的。
lfzxs
驱动牛犊
驱动牛犊
  • 注册日期2004-09-03
  • 最后登录2008-04-07
  • 粉丝1
  • 关注0
  • 积分60分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2008-01-29 11:21
winio library是Windows下直接读写IO的一个连接库,
如果smbus是挂在pci总线上的那要怎么取?
hunbalo
驱动牛犊
驱动牛犊
  • 注册日期2004-04-21
  • 最后登录2020-10-20
  • 粉丝0
  • 关注0
  • 积分11分
  • 威望124点
  • 贡献值0点
  • 好评度85点
  • 原创分1分
  • 专家分0分
  • 社区居民
5楼#
发布于:2008-01-29 12:39
不知道你的这个io库是不是能访问所有的空间, 如果是挂在pci上的,自己枚举找到设备类型,操作0xcf8, 0xcfc这两个端口来枚举。就可以找到为其映射的物理地址 。
具体的代码可以参考linux, grub下pci部分代码 。
lfzxs
驱动牛犊
驱动牛犊
  • 注册日期2004-09-03
  • 最后登录2008-04-07
  • 粉丝1
  • 关注0
  • 积分60分
  • 威望6点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2008-02-12 10:35
已经枚举出来了,但找不到SMBUS对应的类型?!
枚举的信息:
===============================================================
PCI   device   has   found,the   pci   config   address=80000000
its   Bus   Numer   is   0  
its   Device   Number   is   0  
its   Functin   Number   is   0  
this   devices   deviceID   and   vendorID=07411039
Status and Command =22100007
Class Code and Revision ID==06000003
Base Address Register==D0000000
===============================================================
PCI   device   has   found,the   pci   config   address=80000800
its   Bus   Numer   is   0  
its   Device   Number   is   1  
its   Functin   Number   is   0  
this   devices   deviceID   and   vendorID=00031039
Status and Command =00000107
Class Code and Revision ID==06040000
ist and Header Type and Latency Timer and Cacne Line Size==00012000
Base Address Register==20020100
Base Address Register==2020B0B0
Base Address Register==CFE0CFD0
Base Address Register==CFB0BFA0
Max_Lat Min_Gnt Interrupt Pin Interrupt line==000A0000
===============================================================
PCI   device   has   found,the   pci   config   address=80001000
its   Bus   Numer   is   0  
its   Device   Number   is   2  
its   Functin   Number   is   0  
this   devices   deviceID   and   vendorID=00081039
Status and Command =0200000F
Class Code and Revision ID==06010025
ist and Header Type and Latency Timer and Cacne Line Size==00800000
===============================================================
PCI   device   has   found,the   pci   config   address=80001800
its   Bus   Numer   is   0  
its   Device   Number   is   3  
its   Functin   Number   is   0  
this   devices   deviceID   and   vendorID=70011039
Status and Command =82800007
Class Code and Revision ID==0C03100F
ist and Header Type and Latency Timer and Cacne Line Size==00802008
Base Address Register==CFFF9000
Max_Lat Min_Gnt Interrupt Pin Interrupt line==50000114
===============================================================
PCI   device   has   found,the   pci   config   address=80002000
its   Bus   Numer   is   0  
its   Device   Number   is   4  
its   Functin   Number   is   0  
this   devices   deviceID   and   vendorID=09001039
Status and Command =02900107
Class Code and Revision ID==02000090
ist and Header Type and Latency Timer and Cacne Line Size==00002000
Base Address Register==0000D401
Base Address Register==CFFF8000
Reserved ==FFFE0000
Max_Lat Min_Gnt Interrupt Pin Interrupt line==0B340113
===============================================================
PCI   device   has   found,the   pci   config   address=80010000
its   Bus   Numer   is   1  
its   Device   Number   is   0  
its   Functin   Number   is   0  
this   devices   deviceID   and   vendorID=63301039
Status and Command =02300003
Class Code and Revision ID==03000000
ist and Header Type and Latency Timer and Cacne Line Size==80000000
Base Address Register==C0000008
Base Address Register==CFEE0000
Base Address Register==0000BC01
Max_Lat Min_Gnt Interrupt Pin Interrupt line==00000110
buaawr
驱动牛犊
驱动牛犊
  • 注册日期2004-05-11
  • 最后登录2008-10-16
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望30点
  • 贡献值0点
  • 好评度13点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2008-04-03 09:54
不同家的chipset function的位置都不一样,你几乎不可能知道哪个是定义SMBUS base的register。所以,除非你认识那家chipset公司的人告诉你,否则你只能想别的办法了。我是没有办法。
beervista
驱动牛犊
驱动牛犊
  • 注册日期2007-06-19
  • 最后登录2008-04-23
  • 粉丝0
  • 关注0
  • 积分60分
  • 威望7点
  • 贡献值0点
  • 好评度6点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2008-04-03 13:43
你用的sb是哪个
rajie
驱动牛犊
驱动牛犊
  • 注册日期2002-08-24
  • 最后登录2009-06-26
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2008-06-16 19:44
DOS下成功过,不过WINDOWS下面有IO端口访问的权限,末成功
游客

返回顶部