具體的查找方式主要通過(guò)vxd程序中首先向io地址0xcf8寫入最高位為1的雙字0x80000000,這個(gè)數(shù)的第16到23位代表了總線號(hào),第11到15位代表了設(shè)備號(hào),第8到14位代表了功能號(hào),然后就可以讀取io地址0xcfc的雙字,如果有效的話說(shuō)明此pci配置空間地址上掛了一個(gè)pci卡,從0xcfc讀出的數(shù)則為此pci卡配置空間的第一個(gè)雙字,即vendorID和deviceID,我是將vendorID和deviceID一起使用的,即判斷讀出的雙字是否等于我在9052配置eeprom中標(biāo)定的數(shù),如果是則說(shuō)明找到了我的pci卡,如果不是則繼續(xù)找。向0xcf8寫入的數(shù)+0x800,在繼續(xù)
讀0xcfc,依次下去,直到找到。如果當(dāng)此數(shù)加到0x80ffff00時(shí)還沒(méi)找到(即總線號(hào)搜索完畢),則表明沒(méi)法找到,那就要找找自己的原因了,可能是板子的配置錯(cuò)了。
找到了pci卡的配置空間后,讀出space0的基地址,然后進(jìn)行物理地址到線性地址的轉(zhuǎn)換,我又偷了懶,vtools提供的example中有實(shí)現(xiàn)此功能的vxd源代碼,直接用vc++編譯成vxd就可以共win app使用了。所以實(shí)際上我的app程序使用了兩個(gè)vxd,一個(gè)用來(lái)專門找卡,一個(gè)用來(lái)地址轉(zhuǎn)換。
至于app如何調(diào)用vxd,可以參看vc的參考書(shū),一般都有介紹。
下面將一下如何安裝vxd到系統(tǒng)中,我編的vxd都是動(dòng)態(tài)加載的(pnp一般都用動(dòng)態(tài)加載vxd)要編寫一個(gè)inf文件以便系統(tǒng)將vxd安裝進(jìn)去。我用的是windriver生成的inf文件模板,然后再按照需要進(jìn)行修改,自然加上我的大名了。編完了inf文件后,就可以安裝了。一般情況如果你插上pci卡windows啟動(dòng)后就會(huì)發(fā)現(xiàn)新硬件,你只要按照以前安裝硬件的步驟進(jìn)行就可以了只是在選擇安裝文件時(shí)選擇自己編寫的inf文件就可以了。我覺(jué)得一般的安裝過(guò)程就是將vxd文件拷入系統(tǒng)的文件夾,即windows目錄下,以便當(dāng)app加載vxd時(shí),系統(tǒng)可以找到vxd程序,進(jìn)行動(dòng)態(tài)加載。
下面是我的inf文件
:
[Version]
Signature=$CHICAGO$ ;必須這么寫
Class=PLX ;可以自己改
Provider=%SHENLI% ;制作者
[Manufacturer]
%Manufacture%=SECTION0
[SECTION0]
%my_card%=my.install,PCI\VEN_10b5&DEV_9050 ;my.install表示了安裝過(guò)程所要做的事,
[my.install]
CopyFiles=CopyFiles_PLX10b5 ;主要做拷貝文件和注冊(cè)表添加
AddReg=AddReg_PLX10b5
[CopyFiles_PLX10b5]
Vxd8_25.vxd
[AddReg_PLX10b5]
HKR,,DevLoader,0,Vxd8_25.vxd
[Strings]
Manufacture="BUAA202" ;這些信息會(huì)在安裝時(shí)顯示
my_card="PLX9052"
下面提供了vxd中查詢pci卡的代碼,這個(gè)代碼是參考清華bbs驅(qū)動(dòng)版精華區(qū)huyuguang大蝦的大作,他提供了更詳細(xì)的代碼
有興趣可以參考。
BOOL findpci(DWORD DeviceVendor,PCIINF *pciinf)//我的卡的DeviceVendor=0x905210b5
{
DWORD io_cf8;
DWORD io_cfc;
int i;
DWORD buf[16];
io_cf8=0x80000000;
for(;;)
{
DWORD_OUT(0xcf8,io_cf8);//向0xcf8輸出雙字 io_cf8
io_cfc=DWORD_IN(0xcfc); //從0xcfc讀入雙字
if(io_cfc==DeviceVendor)//find pci9052
{
for(i=0;i<16;i++)
{
DWORD_OUT(0xcf8,io_cf8+4*i);
buf[i]=DWORD_IN(0xcfc);
}
pciinf->VendorID=(WORD)(buf[0]&0xffff);
pciinf->DeviceID=(WORD)((buf[0]&0xffff0000)/0x10000);
pciinf->Command=(WORD)(buf[1]&0xffff);
pciinf->Status=(WORD)((buf[1]&0xffff0000)/0x10000);
pciinf->RevisionID=(UCHAR)(buf[2]&0xff);
pciinf->CacheLineSize=(UCHAR)(buf[3]&0xff);
pciinf->LatencyTimer=(UCHAR)((buf[3]&0xff00)/0x100);
pciinf->HeaderType=(UCHAR)((buf[3]&0xff0000)/0x10000);
pciinf->BIST=(UCHAR)((buf[3]&0xff000000)/0x1000000);
pciinf->BaseAddresses[0]=buf[4];
pciinf->BaseAddresses[1]=buf[5];
pciinf->BaseAddresses[2]=buf[6];
pciinf->BaseAddresses[3]=buf[7];
pciinf->BaseAddresses[4]=buf[8];
pciinf->BaseAddresses[5]=buf[9];
pciinf->SubsystemVendorID=(USHORT)(buf[11]&0xffff);
pciinf->SubsystemID=(USHORT)((buf[12]&0xffff0000)/0x10000);
pciinf->InterruptLine=(UCHAR)(buf[15]&0xff);
pciinf->InterruptPin=(UCHAR)((buf[15]&0xff00)/0x100);
pciinf->MinimumGrant=(UCHAR)((buf[15]&0xff0000)/0x10000);
pciinf->MaximumLatency=(UCHAR)((buf[15]&0xff000000)/0x1000000);
break;
}
else
io_cf8+=0x800;
if(io_cf8>=0x80ffff00)
return 1;
}
return 0;
}
以上都是我這次制作卡的一些心得,還有很多不清楚的地方,寫出來(lái)只是想讓感興趣的pci門外漢了解一下,但愿能有所幫助?隙ㄓ泻芏噱e(cuò)誤,希望各位大蝦指正,但求不會(huì)誤人子弟。pci大蝦見(jiàn)笑了。





