PCI總線與接口技術(shù)
簡(jiǎn)單地探討PCI配置空間,PCI ROM,以及PCI BIOS的調(diào)用。
1、PCI總線的發(fā)展歷史
1990年,起源于Intel架構(gòu)開(kāi)發(fā)實(shí)驗(yàn)室,全稱是Peripheral Component Interconnect,首先在服務(wù)器中使用,代替了原來(lái)的MCA以及EISA,EISA直到2000年才宣告退出歷史舞臺(tái)。直到1994年,才開(kāi)始在PC上廣泛使用,代替了原來(lái)的VESA。在1995年的中期,蘋(píng)果電腦也開(kāi)始使用PCI總線電氣規(guī)范。后來(lái)PCI也增加了許多新的功能,比如66MHz,3.3V標(biāo)準(zhǔn),以及133MHz的PCI-X。2004年,出現(xiàn)了PCI-Express,原來(lái)的PCI總線電氣規(guī)范被稱為了傳統(tǒng)PCI(Conventional PCI)。
2、PCI總線地址空間
獨(dú)立的內(nèi)存以及IO接口,由軟件分配。而另外一個(gè)地址空間-PCI配置空間(PCI Configuration Space),使用獨(dú)立的地址,允許軟件決定每一個(gè)連入的設(shè)備需要多少內(nèi)存以及IO地址空間。通過(guò)設(shè)備配置空間寄存器的設(shè)置,每一個(gè)設(shè)備至多可以申請(qǐng)6個(gè)內(nèi)存以及IO地址空間。PCI配置空間還包括了連入設(shè)備的相關(guān)信息,根據(jù)這些信息,操作系統(tǒng)可以方便地使用相應(yīng)的驅(qū)動(dòng)來(lái)使用這些設(shè)備。為了使PCI總線公平地使用PCI總線,提供了一種等待計(jì)時(shí)的功能,計(jì)時(shí)器在設(shè)備獲得了總線使用權(quán)時(shí)以PCI時(shí)鐘信號(hào)的速率開(kāi)始計(jì)時(shí),直到減為零,設(shè)備釋放總線占有權(quán)。
3、關(guān)于PCI的中斷
四個(gè)中斷,屬于電平觸發(fā)方式(邊沿觸發(fā)方式的中斷容易丟失)。單功能設(shè)備只是使用INTA#,多功能設(shè)備使用多個(gè)中斷。四個(gè)中斷通過(guò)PCI橋(兩個(gè)PCI總線之間)映射到系統(tǒng)中斷上,所以軟件無(wú)從得知是那個(gè)PCI中斷。后來(lái)的PCI加入了消息信號(hào)中斷的機(jī)制,PCI-Express使用的也是消息信號(hào)中斷機(jī)制,而沒(méi)有物理中斷線。
4、PCI電氣規(guī)范
PCI卡的尺寸,長(zhǎng)度為174.63mm,高度為36.068~106.68mm。一下是一幅PCI個(gè)引腳定義的圖。
5、PCI設(shè)備的初始化
機(jī)器上電的時(shí)候,配置軟件必須掃描PCI總線,確定有哪些PCI設(shè)備,然后加載相應(yīng)的驅(qū)動(dòng)程序。所有PCI設(shè)備都必須實(shí)現(xiàn)PCI協(xié)議規(guī)定必須的配置寄存器。而對(duì)PCI配置訪問(wèn)實(shí)際上就是訪問(wèn)設(shè)備的配置寄存器。
6、PCI配置空間
配置空間各項(xiàng)數(shù)據(jù)說(shuō)明:
廠商識(shí)別碼(Vendor ID):標(biāo)識(shí)設(shè)備的制造者,有PCI SIG來(lái)分配。0FFFH表示未配置任何設(shè)備。
設(shè)備識(shí)別碼(Device ID):標(biāo)識(shí)特定的設(shè)備,具體代碼由廠商分配。
版本ID,Revision ID:指定一個(gè)設(shè)備特有的版本號(hào)。
Class Code(分類代碼):用于設(shè)備分類。0BH處為基本分類代碼;0A處為子分類代碼;09H處為標(biāo)識(shí)一個(gè)專用的寄存器級(jí)編程接口,便于設(shè)備的軟件可以與設(shè)備交互數(shù)據(jù)。
命令寄存器(Command):為發(fā)出和響應(yīng)PCI總線命令提供了對(duì)設(shè)備粗略的控制。
狀態(tài)寄存器(Status):用于記錄PCI總線有關(guān)操作的狀態(tài)信息,系統(tǒng)對(duì)該寄存器的讀操作無(wú)特殊要求。
基地址寄存器(Base Address Registers):供地址映射使用,使PCI的IO映射以及內(nèi)存映射與具體設(shè)備無(wú)關(guān)。
擴(kuò)展ROM的基地址寄存器(Expansion ROM Base Address):用來(lái)處理那些配置了局部EPROM或者Flash ROM的基地址和大小。Cache大小寄存器:用來(lái)指定系統(tǒng)中Cache行的長(zhǎng)度,每個(gè)參加Cache協(xié)議的設(shè)備都要使用該寄存器。
延時(shí)計(jì)時(shí)器:該寄存器以PCI總線時(shí)鐘為單位指定PCI總線主設(shè)備的延遲計(jì)時(shí)器。
內(nèi)含自測(cè)寄存器:可選的寄存器,用作內(nèi)含自測(cè)試的控制與狀態(tài)寄存器。
中斷引腳寄存器(Interrupt Pin):用來(lái)表示設(shè)備使用了哪個(gè)PCI中斷引腳。
中斷線寄存器(Interrupt Line):用來(lái)表示設(shè)備中的中斷引腳與系統(tǒng)可編程控制器8259的哪個(gè)中斷輸入線相連接。
MAX_GNT表示設(shè)備需要多長(zhǎng)的突發(fā)傳輸時(shí)間。MAX_LAT表示對(duì)PCI總線進(jìn)行訪問(wèn)的頻繁程度。
Card CIS Pointer:由在卡總線和PCI之間共享芯片的設(shè)備實(shí)現(xiàn)。
子系統(tǒng)廠商標(biāo)識(shí)和子系統(tǒng)標(biāo)識(shí)(Subsystem Vendor ID):用于惟一地標(biāo)識(shí)設(shè)備所駐留的插入卡和子系統(tǒng)。即插即用操作系統(tǒng)可以定位正確的驅(qū)動(dòng)程序,裝載到存儲(chǔ)器。
7、PCI擴(kuò)展ROM
通過(guò)執(zhí)行擴(kuò)展ROM存放的代碼來(lái)完成與設(shè)備相關(guān)的初始化,同時(shí)也可能完成系統(tǒng)引導(dǎo)功能。該機(jī)制允許擴(kuò)展ROM中含有幾個(gè)不同的映像,以適應(yīng)不同的機(jī)器和處理器結(jié)構(gòu)。
凡是支持?jǐn)U展ROM的設(shè)備,必須支持按任意字節(jié)組合方式對(duì)ROM進(jìn)行訪問(wèn),特別強(qiáng)調(diào)的是要支持雙字(DWORD)訪問(wèn)。擴(kuò)展ROM中的信息安排要與現(xiàn)有的適合于ISA和EISA以及MC適配器的Intel X86擴(kuò)展ROM中的頭標(biāo)區(qū)兼容。頭標(biāo)區(qū)中所給信息經(jīng)過(guò)了擴(kuò)充,從而使適配器的功能進(jìn)一步優(yōu)化使用,從而可以使擴(kuò)展ROM中的代碼在運(yùn)行期間所使用的存儲(chǔ)空間最小。
PCI擴(kuò)展ROM中代碼從不在原地執(zhí)行,而是將代碼從ROM中拷貝到RAM中執(zhí)行。這樣可以在初始化和運(yùn)行時(shí)動(dòng)態(tài)地確定代碼長(zhǎng)度,并且能夠改善代碼的執(zhí)行速度。
PCI對(duì)于不同的系統(tǒng)和處理器配置都應(yīng)該包含其編碼映像。每個(gè)映像由ROM首區(qū)(映像開(kāi)始處)+數(shù)據(jù)配置區(qū)(映像的第64KB范圍內(nèi))組成。
ROM首區(qū)內(nèi)容
偏移長(zhǎng)度值說(shuō)明
00H~01H255AAHROM標(biāo)簽字節(jié)
02H~17H22XX保留
18H~19H2XX到PCI數(shù)據(jù)結(jié)構(gòu)指針
數(shù)據(jù)配置區(qū)
偏移量長(zhǎng)度說(shuō)明偏移量長(zhǎng)度說(shuō)明
00H~03H4標(biāo)簽,字符串"PCID"0DH~0FH3分類代碼
04H~05H2供應(yīng)商識(shí)別碼10H~11H2映像長(zhǎng)度
06H~07H2設(shè)備識(shí)別碼12H~13H2代碼數(shù)據(jù)的修改級(jí)別
08H~09H2對(duì)重要產(chǎn)品數(shù)據(jù)的指針14H~14H1代碼類型
0AH~0BH2PCI數(shù)據(jù)結(jié)構(gòu)長(zhǎng)度15H~15H1指示標(biāo)志
0CH~0CH1PCI數(shù)據(jù)結(jié)構(gòu)修改16H~17H2保留
8、關(guān)于PCI設(shè)備的初始化
系統(tǒng)POST首先檢查PCI設(shè)備在配置空間是否使用了擴(kuò)展ROM基地址寄存器(即是否有擴(kuò)展ROM),若使用了,POST將ROM映射到地址空間中一個(gè)未用的部分。
9、PCI BIOS
其主要作用有以下兩點(diǎn):
為應(yīng)用軟件或者PCI總線設(shè)備或者板卡提供服務(wù)調(diào)用。[!--empirenews.page--]
初始化每個(gè)系統(tǒng)PCI設(shè)備。PCI BIOS輪流查詢每個(gè)PCI插槽,查找存在的PCI設(shè)備,讀取存在設(shè)備配置空間的頭標(biāo)區(qū),以決定設(shè)備的廠商號(hào),類型和存儲(chǔ)需求等內(nèi)容。并且將分配的I/O或存儲(chǔ)空間地址回寫(xiě)到每個(gè)設(shè)備配置空間的基地址寄存器中。
PCI BIOS調(diào)用的入口以及返回值說(shuō)明,對(duì)80x86機(jī)器,調(diào)用功能號(hào)為1AH,入口參數(shù)在AX中,返回值在AH中。下面列舉的是比較常用的,更多說(shuō)明請(qǐng)參考PCI BIOS規(guī)則說(shuō)明書(shū)。
功能說(shuō)明入口參數(shù)(AX)返回值說(shuō)明出口參數(shù)(AH)
PCI BIOS存在查詢B101H成功調(diào)用00H
查找PCI 設(shè)備B102H不支持的功能81H
查找PCI 設(shè)備的類代碼B103H錯(cuò)誤的廠商號(hào)83H
產(chǎn)生特殊周期B106H未找到設(shè)備86H
讀配置寄存器-單字節(jié)操作B108H錯(cuò)誤的寄存器號(hào)87H
讀配置寄存器-單字操作B109H設(shè)置失敗88H
讀配置寄存器-雙字操作B10AH緩沖區(qū)太小89H
寫(xiě)配置寄存器-單字操作B10BH
寫(xiě)配置寄存器-單字節(jié)操作B10CH
寫(xiě)配置寄存器-雙字節(jié)操作B10DH
取得中斷線路選項(xiàng)B10EH
設(shè)置PCI中斷B10FH
下面是一個(gè)關(guān)于通過(guò)PCI BIOS調(diào)用讀PCI配置寄存器的例子:
.386
;FUNCTION CODE
PCI_FUNCTION_ID = 0B1H
PCI_BIOS_PRESENT = 01H
FIND_PCI_DEVICE = 02H
FIND_PCI_CLASS_CODE = 03H
GENERATE_SPECIAL_CYCLE = 06H
READ_CONFIG_BYTE = 08H
READ_CONFIG_WORD = 09H
READ_CONFIG_DWORD = 0AH
WRITE_CONFIG_BYTE = 0BH
WRITE_CONFIG_WORD = 0CH
WRITE_CONFIG_DWORD = 0DH
GET_IRQ_ROUTING_OPTIONS = 0EH
SET_PCI_IRQ = 0FH
;RETURN CODE
SUCCESSFUL = 00H
FUNC_NOT_SUPPORTED = 81H
BAD_VENDOR_ID = 83H
DEVICE_NOT_FOUND = 86H
BAD_REGISTER_NUMBER = 87H
SET_FAILED = 88H
BUFFER_TOO_SMALL = 89H
VID = 0H
DID = 2H
PCICMD = 4H
PCISTS = 6H
RID = 8H
CLCD = 9H
CALN = 0CH
LAT = 0DH
HDR = 0EH
BIST = 0FH
BADR0 = 10H
BADR1 = 14H
BADR2 = 18H
BADR3 = 1CH
BADR4 = 20H
BADR5 = 24H
EXPOM = 30H
INTLN = 3CH
INTPIN = 3DH
MINGNT = 3EH
MAXLAT = 3FH
SSTACK SEGMENT STACK PARA USE16
DW 64 DUP(?)
SSTACK ENDS
DATA SEGMENT PARA USE16
MES DB ‘ PCI CARD NOT FOUND! $‘
MES0 DB ‘***********************PCI CONFIG INFO*****************************‘,13,10,‘$‘
MES1 DB ‘PCI BIOS NOT FOUND!‘,10,13,‘$‘
MES2 DB ‘ PCI CONFIG READ ERROR! $‘
MES3 DB ‘ Vendor Identification: 10E8$‘
MES4 DB ‘ Device Identification: 5933$‘
MES5 DB ‘ PCI Command Register: $‘
MES6 DB ‘ PCI Status Register: $‘
MES7 DB ‘ Revision Identification Register: $‘
MES8 DB ‘ Class Code Register: $‘
MES9 DB ‘ Cache Line Size Register: $‘
MES10 DB ‘ Master Latency Timer: $‘
MES11 DB ‘ Header Type: $‘
MES12 DB ‘ Built-in Self-test: $‘
MES13 DB ‘ Base Address Register0: $‘
MES14 DB ‘ Base Address Register1: $‘
MES15 DB ‘ Base Address Register2: $‘
MES16 DB ‘ Base Address Register3: $‘
MES17 DB ‘ Base Address Register4: $‘
MES18 DB ‘ Base Address Register5: $‘
MES19 DB ‘ Expansion Rom Base Address: $‘
MES20 DB ‘ Interrupt Line: $‘
MES21 DB ‘ Interrupt Pin: $‘
MES22 DB ‘ Minimum Grant: $‘
MES23 DB ‘ Maximum Latency: $‘
BN DB ?
DN_FN DB ?
R_VALUE DD ?
V_VID DW ?
V_DID DW ?
V_PCICMD DW ?
V_PCISTS DW ?
V_RID DB ?
V_CLCD DD ?
V_CALN DB ?
V_LAT DB ?
V_HDR DB ?
V_BIST DB ?
V_BADR0 DD ?
V_BADR1 DD ?
V_BADR2 DD ?
V_BADR3 DD ?
V_BADR4 DD ?
V_BADR5 DD ?
V_EXPOM DD ?
V_INTLN DB ?
V_INTPIN DB ?
V_MINGNT DB ?
V_MAXLAT DB ?
DATA ENDS
CODE SEGMENT PARA USE16
ASSUME CS:CODE,DS:DATA,SS:SSTACK
START: MOV AX,DATA
MOV DS,AX
MOV AX,0B101H ;查找PCI BIOS
INT 1AH
JNC JUDGE1 ;如果CF被置位,則PCI BIOS不存在
MOV DX,OFFSET MES1 ;顯示不存在信息
MOV AH,09H
INT 21H
JMP EXIT
JUDGE1: CMP AH,00H
JZ JUDGE2 ;如果不等,則PCI BIOS 不存在
MOV DX,OFFSET MES1 ;顯示不存在信息
MOV AH,09H
INT 21H
JMP EXIT
JUDGE2: CMP EDX,‘ ICP‘ ;如果EDX中放的是"PCI "則說(shuō)明PCI BIOS存在
JZ FIND
MOV DX,OFFSET MES1 ;否則錯(cuò)誤的設(shè)備
MOV AH,09H
INT 21H
JMP EXIT
FIND: MOV AX,0B102H ;找到了PCI BIOS,再查找指定PCI設(shè)備
MOV CX,5933H ;板卡的設(shè)備的ID
MOV DX,10E8H ;板卡的供應(yīng)商ID
MOV SI,0 ;索引
INT 1AH
JNC READ
MOV DX,OFFSET MES
MOV AH,09H
INT 21H
JMP EXIT
READ: MOV BN,BH ;保存總線號(hào)
MOV DN_FN,BL ;保存設(shè)備號(hào)
CALL KENTER ;回車(chē)換行
MOV DX,OFFSET MES0
MOV AH,09H
INT 21H[!--empirenews.page--]
CALL KENTER ;回車(chē)換行
MOV DX,OFFSET MES3 ;輸出供應(yīng)廠商ID
MOV AH,09H
INT 21H
CALL KENTER
MOV DX,OFFSET MES4 ;輸出設(shè)備的ID
MOV AH,09H
INT 21H
CALL KENTER
MOV AX,0B109H ;讀命令寄存器,單字操作
MOV BH,BN
MOV BL,DN_FN
MOV DI,PCICMD
INT 1AH
JC ERROR
MOV DX,OFFSET MES5 ;顯示PCI命令寄存器內(nèi)容
MOV AH,09H
INT 21H
MOV AX,02H
CALL SHOW
CALL KENTER
MOV AX,0B109H ;讀PCI狀態(tài)寄存器內(nèi)容,單字操作
MOV BH,BN
MOV BL,DN_FN
MOV DI,PCISTS
INT 1AH
JC ERROR
MOV DX,OFFSET MES6 ;顯示狀態(tài)寄存器內(nèi)容
MOV AH,09H
INT 21H
MOV AX,02H
CALL SHOW
CALL KENTER
MOV AX,0B108H ;版本號(hào),單字節(jié)操作
MOV BH,BN
MOV BL,DN_FN
MOV DI,RID
INT 1AH
JC ERROR
MOV DX,OFFSET MES7 ;顯示版本號(hào)
MOV AH,09H
INT 21H
MOV AX,01H
CALL SHOW
CALL KENTER
MOV AX,0B108H ;讀中斷引腳信號(hào),單字節(jié)操作
MOV BH,BN
MOV BL,DN_FN
MOV DI,INTLN
INT 1AH
JC ERROR
MOV DX,OFFSET MES20 ;顯示中斷引腳
MOV AH,09H
INT 21H
MOV AX,01H
CALL SHOW
CALL KENTER
MOV AX,0B10AH ;讀配置寄存器,雙字操作
MOV BH,BN ;PCI設(shè)備的總線號(hào)
MOV BL,DN_FN ;設(shè)備以及功能號(hào),入口參數(shù)
MOV DI,BADR0
INT 1AH
JC ERROR
MOV DX,OFFSET MES13 ;基址寄存器0
MOV AH,09H
INT 21H
MOV AX,04H
CALL SHOW
CALL KENTER
MOV AX,0B10AH ;讀配置寄存器,雙字操作
MOV BH,BN ;PCI設(shè)備的總線號(hào)
MOV BL,DN_FN ;設(shè)備及功能號(hào),入口參數(shù)
MOV DI,BADR1
INT 1AH
JC ERROR
PUSH ECX
MOV DX,OFFSET MES14 ;基址寄存器1
MOV AH,09H
INT 21H
MOV AX,04H
POP ECX
CALL SHOW
CALL KENTER
MOV AX,0B10AH ;讀配置寄存器,雙字操作
MOV BH,BN ;PCI設(shè)備的總線號(hào)
MOV BL,DN_FN ;設(shè)備及功能號(hào),入口參數(shù)
MOV DI,BADR2
INT 1AH
JC ERROR
MOV DX,OFFSET MES15 ;基地址寄存器2
MOV AH,09H
INT 21H
MOV AX,04H
CALL SHOW
CALL KENTER
MOV AX,0B10AH ;讀配置寄存器,雙字操作
MOV BH,BN ;PCI設(shè)備的總線號(hào)
MOV BL,DN_FN ;設(shè)備及功能號(hào),入口參數(shù)
MOV DI,BADR3
INT 1AH
JC ERROR
MOV DX,OFFSET MES16 ;基地址寄存器3
MOV AH,09H
INT 21H
MOV AX,04H
CALL SHOW
CALL KENTER
MOV AX,0B10AH ;讀配置寄存器,雙字操作
MOV BH,BN ;PCI設(shè)備的總線號(hào)
MOV BL,DN_FN ;設(shè)備及功能號(hào),入口參數(shù)
MOV DI,BADR4
INT 1AH
JC ERROR
MOV DX,OFFSET MES17 ;基地址寄存器4
MOV AH,09H
INT 21H
MOV AX,04H
CALL SHOW
JMP EXIT
ERROR: CALL KENTER
MOV DX,OFFSET MES2 ;顯示讀錯(cuò)誤信息
MOV AH,09H
INT 21H
EXIT: MOV AH,4CH ;返回DOS
INT 21H
KENTER PROC
MOV DL,0AH
MOV AH,02H
INT 21H
MOV DL,0DH
MOV AH,02H
INT 21H
RET
KENTER ENDP
SHOW PROC NEAR ;顯示子程序
PUSH DX
PUSH DI
PUSH BX
MOV DI,OFFSET R_VALUE
MOV [DI],ECX ;保存獲取的數(shù)據(jù)
ADD DI,AX
DEC DI
MOV CX,AX
C1: MOV AL,[DI]
PUSH AX
SHR AL,4
AND AL,0FH ;取高4位
CMP AL,0AH ;是否是A以上的數(shù)
JB C2
ADD AL,07H
C2: ADD AL,30H
MOV BH,AL
POP AX
AND AL,0FH ;取低4位
CMP AL,0AH
JB C3
ADD AL,07H
C3: ADD AL,30H
MOV BL,AL
MOV AH,2 ;顯示十六進(jìn)制數(shù)對(duì)應(yīng)的ACSII碼
MOV DL,BH
INT 21H
MOV DL,BL
INT 21H
DEC DI
LOOP C1
POP BX
POP DI
POP DX
RET
SHOW ENDP
CODE ENDS
END START