PCIE-1

PCI/PCIe軟件界面

1滥沫。配置空間

PCI spec規(guī)定了PCI設(shè)備必須提供的單獨(dú)地址空間:配置空間(configuration space),前64個(gè)字節(jié)(其地址范圍為0x00~0x3F)是所有PCI設(shè)備必須支持的(有不少簡單的設(shè)備也僅支持這些)姻蚓,此外PCI/PCI-X還擴(kuò)展了0x40~0xFF這段配置空間洽蛀,在這段空間主要存放一些與MSI或者M(jìn)SI-X中斷機(jī)制和電源管理相關(guān)的Capability結(jié)構(gòu)艰亮。

前文提到過炒事,PCI配置空間和內(nèi)存空間是分離的幔托,那么如何訪問這段空間呢颗管?我們首先要對(duì)所有的PCI設(shè)備進(jìn)行編碼以避免沖突陷遮,通常我們是以三段編碼來區(qū)分PCI設(shè)備,即Bus Number, Device Number和Function Number,以后我們簡稱他們?yōu)锽DF垦江。有了BDF我們既可以唯一確定某一PCI設(shè)備帽馋。不同的芯片廠商訪問配置空間的方法略有不同,我們以Intel的芯片組為例,其使用IO空間的CF8h/CFCh地址來訪問PCI設(shè)備的配置寄存器:

CF8h:?CONFIG_ADDRESS绽族。PCI配置空間地址端口姨涡。

CFCh:?CONFIG_DATA。PCI配置空間數(shù)據(jù)端口项秉。

  CONFIG_ADDRESS寄存器格式:

 31 位:Enabled位绣溜。

23:16 位:總線編號(hào)。

15:11 位:設(shè)備編號(hào)娄蔼。

10: 8 位:功能編號(hào)怖喻。

7: 2 位:配置空間寄存器編號(hào)。

1: 0 位:恒為“00”岁诉。這是因?yàn)镃F8h锚沸、CFCh端口是32位端口。

如上涕癣,在CONFIG_ADDRESS端口填入BDF,即可以在CONFIG_DATA上寫入或者讀出PCI配置空間的內(nèi)容哗蜈。

PCIe規(guī)范在PCI規(guī)范的基礎(chǔ)上,將配置空間擴(kuò)展到4KB坠韩。原來的CF8/CFC方法仍然可以訪問所有PCIe設(shè)備配置空間的頭255B距潘,但是該方法訪問不了剩下的(4K-255)配置空間。怎么辦呢只搁?Intel提供了另外一種PCIe配置空間訪問方法:通過將配置空間映射到Memory map IO(MMIO)空間音比,對(duì)PCIe配置空間可以像對(duì)內(nèi)存一樣進(jìn)行讀寫訪問了。如圖

這樣再加上PCI板子上的RAM或者ROM氢惋,整個(gè)PCIe Device空間如下圖:

MMIO這段空間有256MB洞翩,因?yàn)榘凑誔CIe規(guī)范,支持最多256個(gè)buses焰望,每個(gè)Bus支持最多32個(gè)PCI devices骚亿,每個(gè)device支持最多8個(gè)function,也就是說:占用內(nèi)存的最大值為:256 * 32 * 8 * 4K = 256MB。在臺(tái)式機(jī)上我們很多時(shí)候覺得占用256MB空間太浪費(fèi)(造成4G以下memory可用空間變少熊赖,雖然實(shí)際memory可以映射到4G以上来屠,但對(duì)32位OS影響很大),PCI Bus也沒有那么多震鹉,所以可以設(shè)置成最低64MB的妖,即最多64個(gè)Bus。那么這個(gè)256MB的MMIO空間在在哪里呢足陨?我們以Intel的Haswell平臺(tái)為例:

其中PCIEXBAR就是這個(gè)MMIO的起始位置,在4G下面占據(jù)64MB/128MB/256MB空間(4G以上部分不在本文范圍內(nèi)娇未,我們今后會(huì)詳細(xì)介紹固件中的內(nèi)存布局)墨缘,其具體位置可以由平臺(tái)進(jìn)行設(shè)置,設(shè)置寄存器一般在Root complex(下文簡稱RC)中。

如果大家忘記RC镊讼,可以參考前文硬件部分的典型PCIe框圖宽涌。

RC是PCIe體系結(jié)構(gòu)的一個(gè)重要組成部件,也是一個(gè)較為混亂的概念蝶棋。RC的提出與x86處理器系統(tǒng)密切相關(guān)卸亮,PCIe總線規(guī)范中涉及的RC也以x86處理器為例進(jìn)行說明,而且一些在PCIe總線規(guī)范中出現(xiàn)的最新功能也在Intel的x86處理器系統(tǒng)中率先實(shí)現(xiàn)玩裙。事實(shí)上兼贸,只有x86處理器才存在PCIe總線規(guī)范定義的“標(biāo)準(zhǔn)RC”,而在多數(shù)處理器系統(tǒng)吃溅,并不含有在PCIe總線規(guī)范中涉及的溶诞,與RC相關(guān)的全部概念。

在x86處理器系統(tǒng)中决侈,RC內(nèi)部集成了一些PCI設(shè)備螺垢、RCRB(RC Register Block)和Event Collector等組成部件。其中RCRB由一系列的寄存器組成的大雜燴赖歌,而僅存在于x86處理器中枉圃;而Event Collector用來處理來自PCIe設(shè)備的錯(cuò)誤消息報(bào)文和PME消息報(bào)文。RCRB的訪問基地址一般在LPC設(shè)備寄存器上設(shè)置庐冯。

如果將RC中的RCRB孽亲、內(nèi)置的PCI設(shè)備和Event Collector去除,該RC的主要功能與PCI總線中的Host Bridge類似肄扎,其主要作用是完成存儲(chǔ)器域到PCI總線域的地址轉(zhuǎn)換墨林。但是隨著虛擬化技術(shù)的引入,尤其是引入MR-IOV技術(shù)之后犯祠,RC的實(shí)現(xiàn)變得異常復(fù)雜旭等。

2。BAR空間

現(xiàn)在我們來看看在配置空間里具體有些什么衡载。我們以一個(gè)一般的type 0(非Bridge)設(shè)備為例:

其中Device ID和Vendor ID是區(qū)分不同設(shè)備的關(guān)鍵搔耕,OS和UEFI在很多時(shí)候就是通過匹配他們來找到不同的設(shè)備驅(qū)動(dòng)(Class Code有時(shí)也起一定作用)。為了保證其唯一性痰娱,Vendor ID應(yīng)當(dāng)向PCI特別興趣小組(PCI SIG)申請(qǐng)而得到弃榨。

我們重點(diǎn)來了解一下這些Base Address Registers(BAR)。BAR是PCI配置空間中從0x10 到 0x24的6個(gè)register梨睁,用來定義PCI需要的配置空間大小以及配置PCI設(shè)備占用的地址空間鲸睛。

每個(gè)PCI設(shè)備在BAR中描述自己需要占用多少地址空間,UEFI通過所有設(shè)備的這些信息構(gòu)建一張完整的關(guān)系圖坡贺,描述系統(tǒng)中資源的分配情況官辈,然后在合理的將地址空間配置給每個(gè)PCI設(shè)備箱舞。

BAR在bit0來表示該設(shè)備是映射到memory還是IO,bar的bit0是readonly的拳亿,也就是說晴股,設(shè)備寄存器是映射到memory還是IO是由設(shè)備制造商決定的,其他人無法修改肺魁。

下圖是BAR寄存器的結(jié)構(gòu)电湘,分別是Memory和IO:

BAR通過將某些位設(shè)置為只讀,且0來表示需要的地址空間大小鹅经,比如一個(gè)PCI設(shè)備需要占用1MB的地址空間寂呛,那么這個(gè)BAR就需要實(shí)現(xiàn)高12bit是可讀寫的,而20-4bit是只讀且位0瞬雹。地址空間大小的計(jì)算方法如下:

a.向BAR寄存器寫全1

b.讀回寄存器里面的值昧谊,然后clear 上圖中特殊編碼的值,(IO 中bit0酗捌,bit1呢诬, memory中bit0-3)。

c.對(duì)讀回來的值去反胖缤,加一就得到了該設(shè)備需要占用的地址內(nèi)存空間尚镰。

這樣我們就可以在構(gòu)建一張大表,用于記錄所有PCI設(shè)備所需要的空間哪廓。這也是PCI枚舉的主要任務(wù)之一狗唉。另外別忘記設(shè)置Command寄存器enable這些BARs。

3涡真。PCI橋設(shè)備

PCI橋在PCI設(shè)備樹中起到呈上起下的作用分俯。一個(gè)PCI-to-PCI橋它的配置空間如下:

注意其中的三組綠色的BUS Number和多組黃色的BASE/Limit對(duì),它決定了橋和橋下面的PCI設(shè)備子樹相應(yīng)/被分配的Bus和各種資源大小和位置哆料。這些值都是由PCI枚舉程序來設(shè)置的缸剪。

4。Capabilities結(jié)構(gòu)

PCI-X和PCIe總線規(guī)范要求其設(shè)備必須支持Capabilities結(jié)構(gòu)东亦。在PCI總線的基本配置空間中杏节,包含一個(gè)Capabilities Pointer寄存器,該寄存器存放Capabilities結(jié)構(gòu)鏈表的頭指針典阵。在一個(gè)PCIe設(shè)備中奋渔,可能含有多個(gè)Capability結(jié)構(gòu),這些寄存器組成一個(gè)鏈表壮啊,其結(jié)構(gòu)如圖:

PCIe的各種特性如Max Payload嫉鲸、Complete Timeout(CTO)等等都通過這個(gè)鏈表鏈接在一起,Capabilities ID由PCIe spec規(guī)定歹啼。鏈表的好處是如果你不關(guān)心這個(gè)Capabilities(或不知道怎么處理)充坑,直接跳過减江,處理關(guān)心的即可,兼容性比較好捻爷。另外擴(kuò)展性也強(qiáng),新加的功能不會(huì)固定放在某個(gè)位置份企,淘汰的功能刪掉即好也榄。

5。PCI枚舉

PCI枚舉是個(gè)不斷遞歸調(diào)用發(fā)現(xiàn)新設(shè)備的過程司志,PCI枚舉簡單來說主要包括下面幾個(gè)步驟:

A.?利用深度優(yōu)先算法遍歷整個(gè)PCI設(shè)備樹甜紫。從Root Complex出發(fā),尋找設(shè)備和橋骂远。發(fā)現(xiàn)橋后設(shè)置Bus,會(huì)發(fā)現(xiàn)一個(gè)PCI設(shè)備子樹囚霸,遞歸回到A)

B.?遞歸的過程中通過讀取BARs,記錄所有MMIO和IO的需求情況并予以滿足激才。

C.?設(shè)置必要的Capabilities

在整個(gè)過程結(jié)束后拓型,一顆完整的資源分配完畢的樹就建立好了。

6瘸恼。地址譯碼

在PCI總線中定義了兩種“地址譯碼”方式劣挫,一個(gè)是正向譯碼,一個(gè)是負(fù)向譯碼东帅。當(dāng)訪問Bus N時(shí)压固,其下的所有PCI設(shè)備都將對(duì)出現(xiàn)在地址周期中的PCI總線地址進(jìn)行譯碼。如果這個(gè)地址在某個(gè)PCI設(shè)備的BAR空間中命中時(shí)靠闭,這個(gè)PCI設(shè)備將接收這個(gè)PCI總線請(qǐng)求帐我。這個(gè)過程也被稱為PCI總線的正向譯碼,這種方式也是大多數(shù)PCI設(shè)備所采用的譯碼方式愧膀。

但是在PCI總線上的某些設(shè)備拦键,如PCI-to-(E)ISA橋(或LPC)并不使用正向譯碼接收來自PCI總線的請(qǐng)求, PCI BUS N上的總線事務(wù)在三個(gè)時(shí)鐘周期后扇调,沒有得到任何PCI設(shè)備響應(yīng)時(shí)(即總線請(qǐng)求的PCI總線地址不在這些設(shè)備的BAR空間中)矿咕,PCI-to-ISA橋?qū)⒈粍?dòng)地接收這個(gè)數(shù)據(jù)請(qǐng)求。這個(gè)過程被稱為PCI總線的負(fù)向譯碼狼钮√贾可以進(jìn)行負(fù)向譯碼的設(shè)備也被稱為負(fù)向譯碼設(shè)備。

在PCI總線中熬芜,除了PCI-to-(E)ISA橋可以作為負(fù)向譯碼設(shè)備莲镣,PCI橋也可以作為負(fù)向譯碼設(shè)備,但是PCI橋并不是在任何時(shí)候都可以作為負(fù)向譯碼設(shè)備涎拉。在絕大多數(shù)情況下瑞侮,PCI橋無論是處理“來自上游總線(upstream)”的圆,還是處理“來自下游總線(downstream)”的總線事務(wù)時(shí),都使用正向譯碼方式半火。如圖:

在某些特殊應(yīng)用中越妈,PCI橋也可以作為負(fù)向譯碼設(shè)備。PCI總線規(guī)定使用負(fù)向譯碼的PCI橋钮糖,其Base Class Code寄存器為0x06梅掠,Sub Class Code寄存器為0x04,而Interface寄存器為0x01店归;使用正向譯碼方式的PCI橋的Interface寄存器為0x00阎抒。

如筆記本在連接Dock插座時(shí),也使用了PCI橋消痛。因?yàn)樵诖蠖鄶?shù)情況下且叁,筆記本與Dock插座是分離使用的,而且Dock插座上連接的設(shè)備多為慢速設(shè)備秩伞,此時(shí)用于連接Dock插座的PCI橋使用負(fù)向譯碼逞带。在該橋管理的設(shè)備并不參與處理器系統(tǒng)對(duì)PCI總線的枚舉過程。當(dāng)筆記本插入到Dock之后稠歉,系統(tǒng)軟件并不需要重新枚舉Dock中的設(shè)備并為這些設(shè)備分配系統(tǒng)資源掰担,而僅需要使用負(fù)向譯碼PCI橋管理好其下的設(shè)備即可,從而極大降低了Dock對(duì)系統(tǒng)軟件的影響怒炸。

UEFI對(duì)PCI/PCIe的支持

UEFI對(duì)于PCI總線的支持包括以下三個(gè)方面:

1) 提供分配PCI設(shè)備資源的協(xié)議(Protocol)带饱。

2) 提供訪問PCI設(shè)備的協(xié)議(Protocol)。

3) 提供PCI枚舉器阅羹,枚舉PCI總線上的設(shè)備以及分配設(shè)備所需的資源勺疼。

4) 提供各種Lib,方便驅(qū)動(dòng)程序訪問PCI/PCIe配置空間或者M(jìn)MIO/IO空間捏鱼。

1.PCI驅(qū)動(dòng)

UEFI BIOS提供了兩個(gè)主要的模塊來支持PCI總線执庐,一個(gè)是PCI Host Bridge控制器驅(qū)動(dòng),另一個(gè)是PCI總線驅(qū)動(dòng)导梆。

PCI Host Bridge控制器驅(qū)動(dòng)是跟特定的平臺(tái)硬件綁定的轨淌。根據(jù)系統(tǒng)實(shí)際I/O空間和memory map,為PCI設(shè)備指定I/O空間和Memory空間的范圍看尼,并且產(chǎn)生PCI Host Bridge Resource Allocation 協(xié)議(Protocol)供PCI總線驅(qū)動(dòng)使用递鹉。該驅(qū)動(dòng)還對(duì)HostBridge控制器下所有RootBridge設(shè)備產(chǎn)生句柄(Handle),該句柄上安裝了PciRootBridgeIoProtocol藏斩。PCI總線驅(qū)動(dòng)則利用PciRootBridgeIo Protocol枚舉系統(tǒng)中所有PCI設(shè)備躏结,發(fā)現(xiàn)并獲得PCI設(shè)備的Option Rom,并且調(diào)用PCI Host Bridge Resource Allocation 協(xié)議(Protocol)分配PCI設(shè)備資源狰域。PCI Host Bridge Resource Allocation協(xié)議的實(shí)現(xiàn)是跟特定的芯和平臺(tái)相結(jié)合的媳拴,畢竟只有平臺(tái)所有者才知道資源從哪里來和有多少黄橘。每一個(gè)PCI HostBridge Controller下面可以接一個(gè)或者多個(gè)PCI root bridges,PCI Root Bridge會(huì)產(chǎn)生PCI local Bus屈溉。正如我們前文舉得例子塞关,如Intel志強(qiáng)第三代四路服務(wù)器,共四顆CPU子巾,每個(gè)CPU都被劃分了共享但區(qū)隔的Bus, PCI I/O, PCI Memory范圍描孟,其構(gòu)成可以表示成如下圖:

其他情況可見上文。PCI設(shè)備驅(qū)動(dòng)不會(huì)使用PCI Root Bridge I/O協(xié)議訪問PCI設(shè)備砰左,而是會(huì)使用PCI總線驅(qū)動(dòng)為PCI設(shè)備產(chǎn)生的PCI IO Protocol來訪問PCI設(shè)備的IO/MEMORY空間和配置空間。PCI Root Bridge I/O協(xié)議(Protocol)是安裝在RootBridge設(shè)備的句柄上(handle)场航,同時(shí)在該handle上也會(huì)有表明RootBridge設(shè)備的DevicePath協(xié)議(Protocol)缠导,如下圖所示

PCI總線驅(qū)動(dòng)在BDS階段會(huì)枚舉整個(gè)PCI設(shè)備樹并分配資源(BUS,MMIO和IO等)溉痢,它還會(huì)在不同的枚舉點(diǎn)調(diào)用Notify event通知平臺(tái)僻造,平臺(tái)的Hook可以掛接在這些點(diǎn)上做些特殊的動(dòng)作。具體各種點(diǎn)的定義請(qǐng)參閱UEFI spec孩饼。

PCI bus驅(qū)動(dòng)在這里:tianocore/edk2

2髓削。PCI Lib

在MdePackage下有很多PCI lib。有Cf8/CFC形式訪問配置空間的镀娶,有PCIe方式訪問的立膛。都有些許不同。注意Cf8/CFC只能訪問255以內(nèi)的梯码,而PCIe方式訪問的要配置正確PCIe base address PCD宝泵。

結(jié)語

本篇沒有介紹下列內(nèi)容,以后有機(jī)會(huì)再補(bǔ)轩娶。

1. Non-transparent bridge

2. LPC

3. 各種PCIe的feature

4. MSI中斷處理

如果你還覺得意猶未盡儿奶,仔細(xì)思考一下下面這些問題并找找資料有助于你更深入了解PCI/PCIe

1. 前文說過,PCIe的速度和Lane的數(shù)目是在Training的時(shí)候由Root Port和EndPoint協(xié)調(diào)得到的鳄抒。那這個(gè)Training的過程發(fā)生在什么時(shí)候呢? (提示闯捎,Hard Strap,Soft Strap, Wait for BIOS/Bifurcation)。

2. UEFI PCI Bus枚舉發(fā)生在BDS階段许溅,很靠后瓤鼻。那我們?nèi)绻谛酒跏蓟A段需要對(duì)PCI設(shè)備MMIO空間的寄存器甚至Bridge后面的設(shè)備做些設(shè)置,該怎么辦呢闹司?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娱仔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子游桩,更是在濱河造成了極大的恐慌牲迫,老刑警劉巖耐朴,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異盹憎,居然都是意外死亡筛峭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門陪每,熙熙樓的掌柜王于貴愁眉苦臉地迎上來影晓,“玉大人,你說我怎么就攤上這事檩禾」仪” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵盼产,是天一觀的道長饵婆。 經(jīng)常有香客問我,道長戏售,這世上最難降的妖魔是什么侨核? 我笑而不...
    開封第一講書人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮灌灾,結(jié)果婚禮上搓译,老公的妹妹穿的比我還像新娘。我一直安慰自己锋喜,他們只是感情好些己,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著跑芳,像睡著了一般轴总。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上博个,一...
    開封第一講書人閱讀 52,246評(píng)論 1 308
  • 那天怀樟,我揣著相機(jī)與錄音,去河邊找鬼盆佣。 笑死往堡,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的共耍。 我是一名探鬼主播虑灰,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼痹兜!你這毒婦竟也來了穆咐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎对湃,沒想到半個(gè)月后崖叫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拍柒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年心傀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拆讯。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡脂男,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出种呐,到底是詐尸還是另有隱情宰翅,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布爽室,位于F島的核電站堕油,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏肮之。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一卜录、第九天 我趴在偏房一處隱蔽的房頂上張望戈擒。 院中可真熱鬧,春花似錦艰毒、人聲如沸筐高。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柑土。三九已至,卻和暖如春绊汹,著一層夾襖步出監(jiān)牢的瞬間稽屏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來泰國打工西乖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留狐榔,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓获雕,卻偏偏與公主長得像薄腻,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子届案,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容