|
pci 學習筆記 (2011-04-02 15:40)
分類: study&research
PCI是Peripheral Component Interconnect(外設部件互連標準)的縮寫,它是目前個人電腦中使用最為廣泛的接口,其位寬為32位或64位,工作頻率為33MHz,最大數(shù)據(jù)傳輸率為133MB/sec(32位)和266MB/sec(64位)。可插接顯卡、聲卡、網(wǎng)卡、內(nèi)置Modem、內(nèi)置ADSL Modem、USB2.0卡、IEEE1394卡、IDE接口卡、RAID卡、電視卡、視頻采集卡以及其它種類繁多的擴展卡.
目前PCI-E是PCI最新的發(fā)展方向,串行,點對點傳輸,每個傳輸通道獨享帶寬;支持雙向傳輸模式和數(shù)據(jù)分通道傳輸模式;在PCI-E 3.0規(guī)范中,X32端口的雙向速率高達320Gbps,可以滿足新一代的I/O接口,比如:千兆(GE)、萬兆(10GE)的以太網(wǎng)技術(shù)、4G/8G的FC技術(shù)
一. PCI 引腳
![]() 1. 接口控制管腳 (出問題時常測這些管腳) FRAME#:幀周期信號。Master驅(qū)動,表示一次訪問的開始和持續(xù)時間。 FRAME#無效時,是傳輸?shù)淖詈笠粋€數(shù)據(jù)周期。 IRDY#:Master準備好信號。 TRDY#:Slave準備好信號。 當這兩者同時有效時,才能進行完整的數(shù)據(jù)傳輸,否則即為等待周期。 在寫周期,IRDY#信號有效時,表示有效的數(shù)據(jù)信號已在AD0~AD31中建立; 在讀周期,IRDY#信號有效時,表示Master已做好接收數(shù)據(jù)的準備。 在寫周期,TRDY#信號有效,表示Slave已做好了接收數(shù)據(jù)的準備。 在讀周期,TRDY#信號有效,表示有效數(shù)據(jù)已被送入AD0~AD31中, STOP#:停止數(shù)據(jù)傳送信號,由Slave發(fā)出。當它有效時,表示Slave請求Master終止當前的數(shù)據(jù)傳送。 IDSEL:初始化設備選擇信號。在讀寫配置空間時,用作Slave的片選信號(Slave通常把IDSEL連到AD[31:0]上的一根,PFA中的device id就是這么確定的) DEVSEL#:設備選擇信號,由Slave驅(qū)動,該信號有效時,當前Slave設備已被選中 三.PCI配置空間
256字節(jié)的PCI配置空間分為64字節(jié)的頭標區(qū)和192字節(jié)的設備相關區(qū)兩部分。頭標區(qū)的各個寄存器用來唯一地識別設備;設備相關區(qū)則保存一些與設備相關的數(shù)據(jù)。
配置空間的頭標區(qū)又分為兩部分:前16個字節(jié)的定義在各種類型的PCI設備中都是一樣的;剩余的字節(jié)隨設備類型不同而有所不同。位于偏移地址0EH處的頭標類型字段規(guī)定了頭標區(qū)的布局結(jié)構(gòu)。目前,規(guī)范定義了三種頭標類型。
因為PCI網(wǎng)卡的頭標類型是0,所以下面我們就來詳細說說其布局結(jié)構(gòu),至于其他類型的頭標請讀者自行閱讀。圖3就是頭標類型0的頭標區(qū)的布局。頭標區(qū)中的寄存器根據(jù)功能可分成下面幾組:
1. 設備的識別 (1) 供應商代碼:該寄存器用于識別PCI設備的制造商,具體代碼由PCI SIG(http://www.)分配。0FFFFH是無效的供應商代碼。 (2) 設備代碼。該寄存器用來標識某供應商生產(chǎn)的具體設備,代碼由各供應商定義。供應商代碼和設備代碼,讀者可以到網(wǎng)站http://www./查閱。
圖3 頭標類型0的頭標區(qū)的布局
(3) 版本號。該寄存器用來定義指定設備的版本信息。 (4) 頭標類型。該字段的第7位為“1”標識該設備是多功能設備,為“0”標識為單功能設備;該字段的0~6位就是上文表中所述的頭標類型。 (5) 設備分類代碼。用來標識設備的總體功能和特定的寄存器級編程接口。 上面5個字段均為只讀類型,所有的PCI設備都必須實現(xiàn)其功能。
2. 設備控制和設備狀態(tài) (1) 命令寄存器為一個設備發(fā)出和響應PCI總線命令提供粗略的控制。圖4就是命令寄存器格式。
圖4 命令寄存器格式
我們比較感興趣的位有: a.位0(I/O空間控制):控制對I/O空間訪問的響應。該位為0時,禁止設備響應對I/O空間的訪問;該位為1時,允許設備響應I/O空間的訪問。缺省設置為0。 b.位1(存儲器空間控制):控制一個設備對存儲器空間訪問的響應。該位為0時,禁止響應;該位為1時,允許設備響應對存儲器空間的訪問。缺省設置為0。
至于其他位的功能,讀者若有興趣可以自行查閱。
(2) 狀態(tài)寄存器用來記錄PCI總線有關的狀態(tài)信息。
3. 基址寄存器 PCI設備中,除了配置空間外,還有兩個物理空間:內(nèi)存空間和I/O空間。為了訪問這兩個地址空間,就必須使用基址寄存器。頭標類型0中涉及3種基址寄存器:內(nèi)存空間基址寄存器、I/O空間基址寄存器和擴展ROM基址寄存器。關于基址寄存器,我們下一章重點講述。
4. 其他寄存器 其他寄存器包括一些本文不涉及到的寄存器,如中斷引腳、中斷線等等。有興趣的讀者可以自行閱讀。
四.PCI配置空間的訪問 上面說過,PCI規(guī)范使用從0CF8H~0CFFH 這8個I/O地址來訪問所有設備的PCI配置空間。這8個字節(jié)實際上構(gòu)成了兩個32位寄存器:0CF8H寄存器叫做“配置地址寄存器”;0CFCH叫做“配置數(shù)據(jù)寄存器”。當要訪問配置空間的寄存器時,先向地址寄存器寫上目標地址,然后就可以從數(shù)據(jù)寄存器中讀寫數(shù)據(jù)了J。
我們說過,PCI配置空間對應于一個PCI邏輯設備,所以要訪問一個配置空間的某個寄存器,必須要指定:PCI總線號、PCI設備號、PCI設備功能號和寄存器號。配置地址寄存器的格式如下:
第0、1位上的“0”是用來要求你只能按雙字(4字節(jié))來讀寫配置空間寄存器。第31位“使能位”用來決定是否允許訪問配置空間:為“1”時表示可以訪問;為“0”時表示不可以訪問。
例如,為了讀總線號0、設備號17H、功能號0的30H寄存器,你可以使用下面的代碼:
五.PCI配置空間的遍歷 從上面的配置地址寄存器的格式我們可以看出:總線號從0~255、設備號從0~31、功能號從0~7。根據(jù)配置空間的第0個寄存器是否返回0FFFFH值來判斷是否存在該PCI設備。下面是PCI配置空間遍歷的流程圖:
圖5遍歷PCI配置空間流程圖 六.基址寄存器 PCI設備中,除了配置空間外,還有兩個物理空間:內(nèi)存空間和I/O空間。為了訪問這兩個地址空間,就必須使用基址寄存器。頭標類型0中涉及3種基址寄存器:內(nèi)存空間基址寄存器、I/O空間基址寄存器和擴展ROM基址寄存器。
PCI設備可以在地址空間中浮動是PCI局部總線中最重要的功能之一。它能夠簡化設備的配置過程。在系統(tǒng)上電時,與設備無關的系統(tǒng)軟件必須確定有哪些設備存在,同時建立一個統(tǒng)一的地址映射關系,并確定一個設備是否有擴展ROM。
1. 地址映射 加電軟件在引導操作系統(tǒng)之前必須建立一個統(tǒng)一的地址映射。也就是說,必須確定在系統(tǒng)中有多少存儲器以及系統(tǒng)中的I/O控制器要求多少地址空間。當這些信息確定之后,加電軟件便可以把I/O控制器映射到合理的地址空間并引導系統(tǒng)。為了使這種映射能夠做到與響應的設備無關,從而在配置空間的頭標區(qū)中安排了一個供映射時使用的基址寄存器。
在所有的基址寄存器中,位0均為只讀位并且用來決定能夠是存儲器空間還是I/O空間。如果該位為0,則表示映射到存儲器空間;若為1則表示映射到I/O地址空間。
2. 存儲器基地址寄存器 映射到存儲器空間的基址寄存器可以是32位寬度,也可以是64位寬度(支持映射到一個64位地址空間時)(如圖6)。
圖6 32/64存儲器基地址寄存器格式
其中位0要用硬件方法使其恒為0。而位2和位1兩位用來表示映射類型,具體如下:
至于位3,若數(shù)據(jù)是可預取的,就應將它置為1,否則清0。該寄存器的區(qū)域各位用來將一設備映射到存儲器空間。
基地址寄存器中用于32位存儲器譯碼器的位【31::4】和用于64位存儲器譯碼器的位【63::4】稱為基地址單元。它的作用是:確定與譯碼器相關的存儲器的大小;給譯碼器分配地址。如果存儲器設備需要小于4K的存儲空間,規(guī)范建議存儲器范圍強行設為4KB。
3. I/O基地址寄存器 映射到I/O空間的基址寄存器寬度總是32位(如圖7):
圖7 I/O基地址寄存器格式
其中位0值為1(用硬件實現(xiàn)的),位1為保留位并且其讀出值必須為0,其余各位用來把設備映射到I/O空間。
當基地址寄存器位0的返回值為1時,表示這是一個I/O譯碼器,而不是存儲器譯碼器,位1保留并總是返回0,【31::2】是基地址單元,并用于確定需要的I/O塊容量,設置它的起始地址。
規(guī)范要求映射它的控制寄存器組到I/O空間的 設備不必請求每個I/O基地址寄存器超過256個單元。
4. 確定塊容量和分配地址范圍 要確定存儲器的容量或I/O空間大小可以通過簡單地向基地址寄存器寫入全“1”并回讀來確定。若返回一個是0值,則表示未實現(xiàn)基地址寄存器;如果讀回地值為非0,則編程人員通過從基地址單元的最低有效位向上掃描返回值以找到第一個被成功置“1”的位來確定所需存儲器的容量或I/0空間的大小。假設寄存器的位0是一個加權(quán)二進制1,那么位1的值就是2,位2的值就是4,依此類推。這樣,在基地址單元中第一個發(fā)現(xiàn)的1所對應的加權(quán)二進制值便是所需的空間數(shù)。這也是寄存器的第一個可讀/可寫位,在它之上的所有位鈞定義為可讀/可寫位。這個信息發(fā)現(xiàn)后,程序?qū)?/SPAN>32/64位存儲器起始地址或32位I/O地址寫入基地址寄存器中。
5. 擴展ROM基地址寄存器 有些PCI設備,尤其是那些準備用于PC結(jié)構(gòu)擴展板上的設備,需要EPROM作為擴展ROM。為此,在配置空間偏移地址30H處開始定義了四個字節(jié)的寄存器,用來處理這個擴展ROM的基地址和大小。(如圖8) 圖8 擴展ROM基地址寄存器格式
該寄存器和32位基地址寄存器相比,除了位的編碼和用途不同之外,其它功能完全相似。它的高21位對應于擴展ROM基地址的高21位。一個設備實際實現(xiàn)的位數(shù)取決于該設備要求多大的地址空間。例如,一個設備要求它的擴展ROM映射到一64KB存儲區(qū)域時,它就應該實現(xiàn)此寄存器的高16位,其它5位用硬件方法使它們恒為0。凡是支持擴展ROM的設備必須實現(xiàn)這個寄存器。 與設備無關的配置軟件通過對擴展ROM基址寄存器的地址位上寫入全“1”,然后再讀回以確定設備要求多大的地址范圍。所有的無關位上都返回0,從而有效地指出了地址邊界,也就知道了設備要求的這一塊地址空間的大小。一個設備要求的地址空間范圍不能超過16MB。
這個寄存器的位0用來控制相應的設備是否能夠接受對其擴展ROM的訪問。當該位為0時,禁止訪問設備的擴展ROM地址空間;當該位為1時,允許將本寄存器的其它位作為參數(shù)進行地址譯碼。命令寄存器中的存儲器空間位優(yōu)先于擴展ROM的使能位,但是,如果存儲器空間位和擴展ROM的的使能位同時為1時,設備就必須響應對其擴展ROM的訪問。擴展ROM的使能位在復位后應該為0。
七.PCI拓撲結(jié)構(gòu)
十.linux的PCI子系統(tǒng)初始化流程 第一步:Linux分配數(shù)據(jù)結(jié)構(gòu)pci_contoller,并初始化,包括PCI的mem/io空間范圍和訪問PCI配置空間所需的handler。 第二步:PCI設備的枚舉:掃描系統(tǒng)上所有PCI設備,初始化它們的配置空間。(硬件上的初始化) 第三步:用數(shù)據(jù)結(jié)構(gòu)將PCI設備信息聯(lián)系起來,構(gòu)建PCI樹。(軟件上的初始化) 第四步:加載PCI設備驅(qū)動。 1 初始化PCI控制器 pci_controller結(jié)構(gòu)是內(nèi)核描述PCI子系統(tǒng)信息的數(shù)據(jù)結(jié)構(gòu),里面定義了可供PCI設備使用的mem資源和io資源的范圍,訪問pci設備配置空間的handler等等。 函數(shù)調(diào)用關系:
注意:執(zhí)行完 pciauto_bus_scan后,所有pci設備(包括橋)的配置空間都已經(jīng)傻瓜式的簡單初始化
pci_dev->resouce[]中保存的才是cpu internal address(EA),可以對這些地址進行用ioremap,在驅(qū)動程序?qū)ar所指位置讀寫的時候一定要用這
4 加載PCI設備驅(qū)動
|
|
|
來自: clover_xian > 《我的圖書館》