阅读:5193回复:9
怎么读到内存的SPD信息?
在WIN2K环境下,很少做底层的东西,不知道如何入手!
|
|
沙发#
发布于: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; } |
|
板凳#
发布于:2008-01-24 17:20
没人点指一下吗?!
|
|
地板#
发布于:2008-01-29 10:40
windows下不能直接操作物理地址及io地址, 不知道你这个winio library都实现了些什么,还有一点就是不通的主板smbus的物理地址可能不同,如果smbus是挂在pci总线上的,这个地址是动态的。
|
|
地下室#
发布于:2008-01-29 11:21
winio library是Windows下直接读写IO的一个连接库,
如果smbus是挂在pci总线上的那要怎么取? |
|
5楼#
发布于:2008-01-29 12:39
不知道你的这个io库是不是能访问所有的空间, 如果是挂在pci上的,自己枚举找到设备类型,操作0xcf8, 0xcfc这两个端口来枚举。就可以找到为其映射的物理地址 。
具体的代码可以参考linux, grub下pci部分代码 。 |
|
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 |
|
7楼#
发布于:2008-04-03 09:54
不同家的chipset function的位置都不一样,你几乎不可能知道哪个是定义SMBUS base的register。所以,除非你认识那家chipset公司的人告诉你,否则你只能想别的办法了。我是没有办法。
|
|
8楼#
发布于:2008-04-03 13:43
你用的sb是哪个
|
|
9楼#
发布于:2008-06-16 19:44
DOS下成功过,不过WINDOWS下面有IO端口访问的权限,末成功
|
|