“PCI”協(xié)議基本知識(shí)(1)

PCI協(xié)議是PCIe協(xié)議的基礎(chǔ)。想學(xué)習(xí)PCIe協(xié)議必須先讀懂PCI協(xié)議。
這里很多內(nèi)容我沒有細(xì)究,但是就閱讀的過程來看,PCI協(xié)議的內(nèi)容確實(shí)比較傳統(tǒng),但是也不難懂。
我閱讀的書是機(jī)械工業(yè)出版社的《PCI Express體系結(jié)構(gòu)導(dǎo)讀》,王齊編著。
想講好協(xié)議的內(nèi)容確實(shí)不容易,我讀過一部分NVMe協(xié)議的內(nèi)容,我知道協(xié)議本身讀起來其實(shí)很枯燥。這里王齊作者不光是講了PCI協(xié)議的知識(shí),更多的是附帶講解了很多處理器系統(tǒng)的知識(shí)。不過總體來說其語言還是比較啰嗦的。至少在第1章,一個(gè)重要特征是圖示很少,圍繞一兩個(gè)圖示說明的內(nèi)容能占到很大的篇幅。學(xué)到東西就行吧。
本書分為兩部分,的一部分是PCI總線的基本知識(shí),也足夠我進(jìn)行基本的了解了。PCI的知識(shí)我先看了第一章這么多,接下來直接去看PCIe的內(nèi)容,如有需要再回頭來看PCI的內(nèi)容。
定義
PCI總線是處理器系統(tǒng)的局部總線,作用是連接外部設(shè)備,而不是作為處理器系統(tǒng)總線連接Cache和主存。PCI總線可說是系統(tǒng)總線的延伸,其設(shè)計(jì)考慮了許多與處理器相關(guān)的內(nèi)容,比如Cache共享一致性(Cache Coherent)和數(shù)據(jù)完整性(Data Consistency)。
PCI總線是一條并行總線。
PCI總線是一條共享總線,也就是說同一條總線上所有的PCI設(shè)備共享總線帶寬(顯然將極大地影響總線的利用率)。
PCI總線是一條同步總線。所有設(shè)備都是用統(tǒng)一的CLK信號同步數(shù)據(jù)傳輸。
結(jié)構(gòu)

如上是PCI總線的一個(gè)結(jié)構(gòu)圖。上圖圖示中,HOST主橋即指Host-to-PCI主橋,起到連接處理器和PCI總線的作用。圖中的PCI橋指的是PCI-to-PCI橋,用于PCI總線的擴(kuò)展。這里我給出一個(gè)簡圖,進(jìn)一步說明HOST主橋、PCI橋、PCI總線和PCI設(shè)備之間的關(guān)系。

PCI總線從HOST主橋出發(fā),通過PCI橋的擴(kuò)展,可以延伸出多條總線,連接多個(gè)設(shè)備,最終形成一個(gè)以HOST主橋?yàn)楦?jié)點(diǎn)的PCI總線樹。HOST主橋會(huì)引出第一條PCI總線(PCI總線0),總線下能夠掛載諸如聲卡、網(wǎng)卡、SSD等外圍設(shè)備,以及PCI橋。PCI橋?qū)⒃偻瞥鲆粭l新的PCI總線,從而掛載一顆PCI總線子樹。因此,PCI橋的上下兩端都連接著PCI總線。上端,距離處理器較近的總線被稱為上游總線(Primary Bus),對應(yīng)的下端的總線叫下游總線(Secondary Bus)。通過PCI橋進(jìn)行擴(kuò)展有限制:一顆PCI總線樹上最多掛載包括PCI橋在內(nèi)的256個(gè)PCI設(shè)備。
注意,HOST主橋是一個(gè)特殊的PCI設(shè)備。在PCI規(guī)范中并沒有定義如何設(shè)計(jì)HOST主橋。但是HOST主橋的作用至關(guān)重要,其可以獲取PCI總線的控制權(quán)訪問PCI設(shè)備,也可以被PCI設(shè)備訪問。
地址域
在PCI總線體系結(jié)構(gòu)下,處理器地址空間和PCI設(shè)備的地址空間是相隔離的。在本書中,處理器能直接訪問的的地址空間,也就是主存儲(chǔ)器的物理地址空間,被稱為存儲(chǔ)器域;PCI設(shè)備的地址空間被稱為PCI總線域。HOST主橋正起到這個(gè)隔離的作用。處理器需要通過主橋訪問PCI設(shè)備。在HOST主橋的設(shè)計(jì)中,有很多緩沖,使得處理器總線和PCI總線工作在各自的頻率下互不干擾。因此,處理器和PCI設(shè)備之間的訪問,需要經(jīng)過HOST主橋的地址轉(zhuǎn)換。
本書編寫時(shí),x86的處理器中存儲(chǔ)器域與PCI總線域沒有嚴(yán)格劃分,但是程序員必須知道二者之不同。
當(dāng)一個(gè)PCI設(shè)備的配置空間被初始化后,其在當(dāng)前的PCI總線樹上將擁有一個(gè)獨(dú)立的PCI總線地址空間,這個(gè)空間由BAR (Base Address Register) 寄存器描述。
根據(jù)以上描述,可以知道HOST主橋、PCI總線域和PCI總線樹是一一對應(yīng)關(guān)系。
重要信號
書中的[P9~13]介紹了重要的PCI總線信號。部分信號的說明詳見下下節(jié)“PCI總線事務(wù)時(shí)序”。
總線事務(wù)
從[P9]的表1-2得知,PCI總線協(xié)議中定義了多種總線事務(wù)。


其中,關(guān)于讀寫事務(wù),有三類:I/O讀寫事務(wù)、存儲(chǔ)器讀寫事務(wù)以及配置讀寫事務(wù)。這里主要介紹存儲(chǔ)器讀寫事務(wù)的過程,來集中整理前述的零散知識(shí)。
對于I/O讀寫事務(wù)、存儲(chǔ)器讀寫事務(wù)這樣的數(shù)據(jù)傳輸,處理器與PCI設(shè)備之間相互訪問的方式是地址譯碼方式,也就是通過HOST主橋轉(zhuǎn)換存儲(chǔ)器域和PCI總線域的地址來完成兩端訪問;對于配置讀寫事務(wù)這樣的配置信息傳輸,一般是處理器通過ID譯碼的方式來訪問PCI設(shè)備。使用的ID信號比如Bus Number、Device Number、Function Number、Register Number等等。
對于PCI總線中的存儲(chǔ)器讀寫總線事務(wù),有以下幾種:
1.??? HOST處理器對PCI設(shè)備的BAR空間進(jìn)行數(shù)據(jù)讀寫,BAR空間可以使用存儲(chǔ)器或者I/O譯碼方式,HOST處理器使用PCI總線的存儲(chǔ)器讀寫總線事務(wù)和I/O讀寫總線事務(wù)訪問PCI設(shè)備的BAR空間。
2.??? PCI設(shè)備之間的數(shù)據(jù)傳遞,一個(gè)PCI設(shè)備訪問另一個(gè)PCI設(shè)備的BAR空間,比較少見;
3.??? PCI設(shè)備對主存儲(chǔ)器進(jìn)行數(shù)據(jù)讀寫,也就是DMA操作。PCI規(guī)范中提供了一些中斷信號INTX#以及MSI機(jī)制提交中斷請求(DMA操作接收將產(chǎn)生中斷)。
PCI總線事務(wù)時(shí)序

結(jié)合PCI有關(guān)的信號功能,來說明PCI規(guī)范中,PCI設(shè)備使用總線的時(shí)序。
以下簡述圖中信號的作用。注意,是從申請PCI總線使用權(quán)的PCI設(shè)備的角度去描述的。下文中的PCI主設(shè)備指的是申請使用PCI總線的設(shè)備;目標(biāo)設(shè)備指的是讀寫事務(wù)最終作用到的設(shè)備。信號IRDY#(In Ready)中的"In"和信號TRDY#(Transport Ready)中的"Transport"都是對于PCI主設(shè)備而言的。
上圖中,F(xiàn)RAME#信號表示一個(gè)PCI事務(wù)的開始與結(jié)束,低位有效。PCI設(shè)備(包括HOST主橋)只有通過仲裁獲得當(dāng)前PCI總線的使用權(quán)之后,才能驅(qū)動(dòng)該信號。
AD[31:0],則是PCI總線復(fù)用地址信號與數(shù)據(jù)信號。具體工作過程是,PCI總線在啟動(dòng)后的第一個(gè)周期傳送地址,這個(gè)地址是PCI總線域的存儲(chǔ)器地址或者I/O地址;而在下一個(gè)時(shí)鐘周期傳送數(shù)據(jù)。相應(yīng)的周期被稱為地址周期或者數(shù)據(jù)周期。PCI總線支持突發(fā)傳送,即在一個(gè)地址周期之后,可以緊跟多個(gè)數(shù)據(jù)周期。
C/BE[3:0]#信號(Command/Byte Enable),是PCI總線復(fù)用的命令信號與字節(jié)選通信號。在地址周期中,該信號表示PCI總線的命令,其定義的各項(xiàng)總線事務(wù)見“總線事務(wù)”一節(jié)中的表格;在數(shù)據(jù)周期中,該信號表示字節(jié)選通。其中C/BE3#、C/BE2#、C/BE1#、C/BE0#與數(shù)據(jù)字節(jié)的3、2、1、0對應(yīng),使用這組信號可以對PCI設(shè)備進(jìn)行單個(gè)、字、雙字的訪問。
IRDY#和TRDY#都是低位有效的信號。
IRDY#由PCI主設(shè)備驅(qū)動(dòng)(包括HOST主橋),有效時(shí)信號表示PCI主設(shè)備的數(shù)據(jù)準(zhǔn)備完畢。若是讀事務(wù),則表示PCI主設(shè)備已準(zhǔn)備好接收緩沖,目標(biāo)設(shè)備可以將數(shù)據(jù)發(fā)送到AD[31:0]上;若為寫事務(wù),則表示待寫入數(shù)據(jù)已經(jīng)在AD[31:0]上有效。
TRDY#由目標(biāo)設(shè)備驅(qū)動(dòng),在讀事務(wù)中,表示PCI主設(shè)備需要的數(shù)據(jù)已經(jīng)在AD[31:0]上有效;在寫事務(wù)中,表示目標(biāo)設(shè)備已經(jīng)準(zhǔn)備好接收緩沖。
PCI總線使用IRDY#和TRDY#進(jìn)行傳送控制。結(jié)合以上內(nèi)容,也就是說,在讀操作中,PCI主設(shè)備驅(qū)動(dòng)IRDY#拉低,目標(biāo)設(shè)備驅(qū)動(dòng)TRDY#拉低,方能傳輸數(shù)據(jù);在寫操作中,PCI主設(shè)備驅(qū)動(dòng)TRDY#拉低,目標(biāo)設(shè)備驅(qū)動(dòng)IRDY#拉低,方能傳輸數(shù)據(jù)。
DEVSEL# (Device Selection)信號由目標(biāo)設(shè)備驅(qū)動(dòng),表示目標(biāo)設(shè)備已經(jīng)完成了地址譯碼(告知PCI主設(shè)備,其訪問對象當(dāng)前在PCI總線上),但是不表示目標(biāo)設(shè)備可以與主設(shè)備進(jìn)行數(shù)據(jù)交換。而TRDY#信號表示數(shù)據(jù)有效,PCI主設(shè)備可以向目標(biāo)設(shè)備寫入或者從目標(biāo)設(shè)備讀出數(shù)據(jù)。
簡介主要信號的作用后,現(xiàn)簡述PCI總線事務(wù)的時(shí)序過程。學(xué)習(xí)協(xié)議的枯燥過程中,一個(gè)重要的事情是了解該協(xié)議的事務(wù)時(shí)序,知道主要信號的工作方式;再者就是熟悉讀寫操作的過程,這也是針對協(xié)議編程所當(dāng)具有的基本知識(shí)。
首先,PCI主設(shè)備需要發(fā)送REQ#信號,通過總線仲裁獲得總線使用權(quán)(GNT#信號有效),使用以下步驟完成一個(gè)完整PCI總線事務(wù),對目標(biāo)設(shè)備進(jìn)行存儲(chǔ)器或者I/O地址空間的讀寫訪問。結(jié)合上圖“PCI總線事務(wù)的時(shí)序”。
1.??? PCI主設(shè)備獲得總線使用權(quán)之后,將在CLK1的上升沿置FRAME#信號有效,啟動(dòng)PCI總線事務(wù)。當(dāng)PCI總線事務(wù)結(jié)束后,F(xiàn)RAME#信號將被置為無效。
2.??? PCI總線的第一個(gè)時(shí)鐘周期是地址周期,此時(shí)PCI主設(shè)備將訪問的目的地址和總線命令分別驅(qū)動(dòng)到AD[31:0]和C/BE#信號上。
3.??? 當(dāng)IRDY#、TRDY#和DEVSEL#都有效后,總線事務(wù)將使用數(shù)據(jù)周期進(jìn)行數(shù)據(jù)傳遞;當(dāng)IRDY#和TRDY#沒有同時(shí)有效,PCI總線不能進(jìn)行數(shù)據(jù)傳遞。PCI總線使用這兩個(gè)信號進(jìn)行傳送控制。
4.??? PCI總線支持突發(fā)周期(只有存儲(chǔ)器讀寫事務(wù)支持),也就是說在地址周期之后可以有多個(gè)數(shù)據(jù)周期。