亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 712 | 回復(fù): 0
打印 上一主題 下一主題

Linux中PCI的實(shí)現(xiàn) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2006-03-15 09:47 |只看該作者 |倒序?yàn)g覽
外圍設(shè)備互連(PCI)是一種將系統(tǒng)中外部設(shè)備以結(jié)構(gòu)化與可控制方式連接到起來(lái)的總線標(biāo)準(zhǔn),包括系統(tǒng)部件連接的電氣特性及行為。本章將詳細(xì)討論Linux核心對(duì)系統(tǒng)中的PCI總線與設(shè)備的初始化過(guò)程。

圖6.1 一個(gè)基于PCI的系統(tǒng)示意圖
圖6.1是一個(gè)基于PCI的系統(tǒng)示意圖。PCI總線和PCI-PCI橋接器在連接系統(tǒng)中設(shè)備到上起關(guān)鍵作用,在這個(gè)系統(tǒng)中CPU和視頻設(shè)備被連到PCI bus 0上,它是系統(tǒng)中的主干PCI總線。而PCI-PCI橋接器這個(gè)特殊PCI設(shè)備將主干總線PCI bus 0與下級(jí)總線PCI bus 1連接到一起。PCI標(biāo)準(zhǔn)術(shù)語(yǔ)中,PCI bus 1是PCI-PCI橋接器的downstream而PCI bus 0是此橋接器的up-stream。SCSI和以太網(wǎng)設(shè)備通過(guò)二級(jí)PCI總線連接到這個(gè)系統(tǒng)中。而在物理實(shí)現(xiàn)上,橋接器和二級(jí)PCI總線被集成到一塊PCI卡上。而PCI-ISA橋接器用來(lái)支持古老的ISA設(shè)備,圖中有一個(gè)高級(jí)I/O控制芯片來(lái)控制鍵盤、鼠標(biāo)及軟盤設(shè)備。
6.1  PCI地址空間
CPU和PCI設(shè)備需要存取在它們之間共享的內(nèi)存空間。這塊內(nèi)存區(qū)域被設(shè)備驅(qū)動(dòng)用來(lái)控制PCI設(shè)備并在CPU與PCI設(shè)備之間傳遞信息。最典型的共享內(nèi)存包括設(shè)備的控制與狀態(tài)寄存器。這些寄存器用來(lái)控制設(shè)備并讀取其 信息。例如PCI SCSI設(shè)備驅(qū)動(dòng)可以通過(guò)讀取其狀態(tài)寄存器,找出已準(zhǔn)備好將一塊數(shù)據(jù)寫入SCSI磁盤的SCSI設(shè)備。同時(shí)還可以在設(shè)備加電后,通過(guò)對(duì)控制寄存器寫入信息來(lái)啟動(dòng)設(shè)備。
CPU的系統(tǒng)內(nèi)存可以被用作這種共享內(nèi)存,但是如果采用這種方式,則每次PCI設(shè)備訪問(wèn)此內(nèi)存塊時(shí),CPU將被迫停止工作以等待PCI設(shè)備完成此操作。這種方式將共享內(nèi)存限制成每次只允許一個(gè)系統(tǒng)設(shè)備訪問(wèn)。該策略會(huì)大大降低系統(tǒng)性能。但如果允許系統(tǒng)外設(shè)不受限制地訪問(wèn)主存也不是好辦法。它的危險(xiǎn)之處在于一個(gè)有惡意行為的設(shè)備將使整個(gè)系統(tǒng)置于不穩(wěn)定狀態(tài)。
外設(shè)有其自身的內(nèi)存空間。CPU可以自由存取此空間,但設(shè)備對(duì)系統(tǒng)主存的訪問(wèn)將處于DMA(直接內(nèi)存訪問(wèn))通道的嚴(yán)格控制下。ISA設(shè)備需要存取兩個(gè)地址空間:ISA I/O(輸入輸出)和ISA內(nèi)存。而PCI設(shè)備需要訪問(wèn)三種地址空間:PCI I/O、PCI內(nèi)存和PCI配置空間。CPU則可以訪問(wèn)所有這些地址空間。PCI I/O和 PCI內(nèi)存由設(shè)備驅(qū)動(dòng)程序使用而PCI配置空間被Linux 核心中的PCI初始化代碼使用。
Alpha AXP處理器并不能象訪問(wèn)系統(tǒng)地址空間那樣隨意訪問(wèn)這些地址空間,它只能通過(guò)輔助芯片組來(lái)存取這些 地址空間,如PCI配置空間。Alpha AXP處理器使用稀疏地址映射策略來(lái)從系統(tǒng)巨大的虛擬內(nèi)存中"竊取"一部分并將其映射到PCI地址空間。
6.2  PCI 配置頭

圖6.2 PCI配置頭
系統(tǒng)中每個(gè)PCI設(shè)備,包括PCI-PCI橋接器在內(nèi),都有一個(gè)配置數(shù)據(jù)結(jié)構(gòu),它通常位于PCI配置地址空間中。PCI配置頭允許系統(tǒng)來(lái)標(biāo)識(shí)與控制設(shè)備。配置頭在PCI配置空間的位置取決于系統(tǒng)中PCI設(shè)備的拓?fù)浣Y(jié)構(gòu)。例如將一個(gè)PCI視頻卡插入不同的PCI槽,其配置頭位置會(huì)變化。但對(duì)系統(tǒng)沒(méi)什么影響,系統(tǒng)將找到每個(gè)PCI設(shè)備與橋接器并使用它們配置頭中的信息來(lái)配置其寄存器。
典型的辦法是用PCI槽相對(duì)主板的位置來(lái)決定其PCI配置頭在配置空間中的偏移。比如主板中的第一個(gè)PCI槽的PCI配置頭位于配置空間偏移0處,而第二個(gè)則位于偏移256處(所有PCI配置頭長(zhǎng)度都相等,為256字節(jié)),其它槽可以由此類推。系統(tǒng)還將提供一種硬件相關(guān)機(jī)制以便PCI設(shè)置代碼能正確的辨認(rèn)出對(duì)應(yīng)PCI總線上所有存在的設(shè)備的PCI配置頭。通過(guò)PCI配置頭中的某些域來(lái)判斷哪些設(shè)備存在及哪些設(shè)備不存在(這個(gè)域叫廠商標(biāo)志域: Vendor Identification field)。對(duì)空PCI槽中這個(gè)域的讀操作將得到一個(gè)值為0xFFFFFFFF的錯(cuò)誤信息。
圖6.2給出了256字節(jié)PCI配置頭的結(jié)構(gòu),它包含以下域:
廠商標(biāo)識(shí)(Vendor Identification)
用來(lái)唯一標(biāo)識(shí)PCI設(shè)備生產(chǎn)廠家的數(shù)值。Digital的PCI廠商標(biāo)識(shí)為0x1011而Intel的為0x8086。
設(shè)備標(biāo)識(shí)(Device Identification)
用來(lái)唯一標(biāo)識(shí)設(shè)備的數(shù)值。Digital 21141快速以太設(shè)備的設(shè)備標(biāo)識(shí)為0x0009。
狀態(tài)(Status)
此域提供PCI標(biāo)準(zhǔn)定義中此設(shè)備的狀態(tài)信息。
命令(Command)
通過(guò)對(duì)此域的寫可以控制此設(shè)備,如允許設(shè)備訪問(wèn)PCI I/O內(nèi)存。
分類代碼(Class Code)
此域標(biāo)識(shí)本設(shè)備的類型。對(duì)于每種類型的視頻,SCSI等設(shè)備都有標(biāo)準(zhǔn)的分類代碼。如SCSI設(shè)備分類代碼為0x0100。
基地址寄存器(Base Address Registers)
這些寄存器用來(lái)決定和分配此設(shè)備可以使用的PCI I/O與PCI內(nèi)存空間的類型,數(shù)量及位置。
中斷引腳(Interrupt Pin)
PCI卡上的四個(gè)物理引腳可以將中斷信號(hào)從插卡上帶到PCI總線上。這四個(gè)引腳標(biāo)準(zhǔn)的標(biāo)記分別為A、B、C及D。中斷引腳域描敘此PCI設(shè)備使用的引腳號(hào)。通常特定設(shè)備都是采用硬連接方式。這也是系統(tǒng)啟動(dòng)時(shí),設(shè)備總使用相同中斷引腳的原因。中斷處理子系統(tǒng)用它來(lái)管理來(lái)自該設(shè)備的中斷。
中斷連線(Interrupt Line)
本設(shè)備配置頭中的中斷連線域用來(lái)在PCI初始化代碼、設(shè)備驅(qū)動(dòng)以及Linux中斷處理子系統(tǒng)間傳遞中斷處理過(guò)程。雖然本域中記錄的這個(gè)數(shù)值對(duì)于設(shè)備驅(qū)動(dòng)毫無(wú)意義。但是它可以將中斷處理過(guò)程從PCI卡上正確路由到Linux操作系統(tǒng)中相應(yīng)的設(shè)備驅(qū)動(dòng)中斷處理代碼中。在
interrupt
一章中將詳細(xì)描敘Linux中斷處理過(guò)程。
6.3  PCI I/O和PCI內(nèi)存地址
這兩個(gè)地址空間用來(lái)實(shí)現(xiàn)PCI設(shè)備和Linux核心中設(shè)備驅(qū)動(dòng)程序之間的通訊。例如DEC21141快速以太網(wǎng)設(shè)備的內(nèi)部寄存器被映射到PIC I/O空間上時(shí),其對(duì)應(yīng)的Linux設(shè)備驅(qū)動(dòng)可以通過(guò)對(duì)這些寄存器的讀寫來(lái)控制此設(shè)備。PCI視頻卡通常使用大量的PCI內(nèi)存空間來(lái)存儲(chǔ)視頻信息。
在PCI系統(tǒng)建立并通過(guò)用PCI配置頭中的命令域來(lái)打開(kāi)這些地址空間前,系統(tǒng)決不允許對(duì)它們進(jìn)行存取。值得注意的是只有PCI配置代碼讀取和寫入PCI配置空間,Linux設(shè)備驅(qū)動(dòng)只讀寫PCI I/O和PCI內(nèi)存地址。
6.4  PCI-ISA 橋接器這種橋接器通過(guò)將PCI I/O和PCI內(nèi)存空間的存取轉(zhuǎn)換成對(duì)ISA I/O和ISA內(nèi)存的存取來(lái)支持古老的ISA設(shè)備。市場(chǎng)上許多主板中同時(shí)包含幾個(gè)ISA總線槽和PCI槽。但今后對(duì)ISA設(shè)備的向后兼容支持將逐漸減弱,最終主板上只會(huì)有PCI槽。早期的Intel 8080 PC就將ISA設(shè)備的ISA地址空間固定了下來(lái)。即使在價(jià)值5000美圓的Alpha AXP 系統(tǒng)中其ISA軟盤控制器地址也和最早IBM PC上的相同。PCI標(biāo)準(zhǔn)將PCI I/O和PCI內(nèi)存的低端部分保留給系統(tǒng)中的ISA外設(shè),另外還使用PCI-ISA橋接器實(shí)現(xiàn)從PCI內(nèi)存訪問(wèn)到ISA內(nèi)存訪問(wèn)的轉(zhuǎn)換。
6.5  PCI-PCI 橋接器
PCI-PCI橋接器是一種將系統(tǒng)中所有PCI總線連接起來(lái)的特殊PCI設(shè)備。在簡(jiǎn)單系統(tǒng)中只存在一條PCI總線,由于受電氣特性的限制,它所連接的PCI設(shè)備個(gè)數(shù)有限。引入PCI-PCI橋接器后系統(tǒng)可以使用更多的PCI設(shè)備。對(duì)于高性能服務(wù)器這是非常重要的。Linux提供了對(duì)PCI-PCI橋接器的全面支持。
6.5.1  PCI-PCI橋接器:PCI I/O和PCI 內(nèi)存窗口PCI-PCI橋接器將PCI I/O和PCI內(nèi)存讀寫請(qǐng)求中的一個(gè)子集向下傳送。例如在圖6.1中,如果來(lái)自PCI 總線0請(qǐng)求是對(duì)SCSI或以太設(shè)備所擁有的PCI I/O或PCI內(nèi)存的讀寫,則此PCI-PCI橋接器將只需把請(qǐng)求從總線0傳遞到PCI總線1上;所有其它PCI I/O和內(nèi)存地址都將被它忽略。這個(gè)過(guò)濾使得這些地址信息不會(huì)在整個(gè)系統(tǒng)中擴(kuò)散。為了實(shí)現(xiàn)這點(diǎn),PCI-PCI橋接器必須編程為有某個(gè)PCI I/O及PCI內(nèi)存基址和上限,只有在這個(gè)地址范圍內(nèi)的PCI地址訪問(wèn)才能從主干總線傳遞到二級(jí)總線。一旦系統(tǒng)中的PCI-PCI橋接器被設(shè)置成這樣,則只要當(dāng)Linux設(shè)備驅(qū)動(dòng)程序通過(guò)這個(gè)窗口訪問(wèn)PCI I/O和PCI內(nèi)存空間時(shí),此PCI-PCI橋接器就將變得透明。這樣也給Linux PCI設(shè)備驅(qū)動(dòng)編寫者提供了方便。我們?cè)谏院蟮挠懻撝袑⒖吹絃inux對(duì)PCI-PCI橋接器非常巧妙的配置。
6.5.2  PCI-PCI橋接器:PCI配置循環(huán)及PCI總線編號(hào)方式

圖6.3 0類型PCI配置循環(huán)

圖6.4 1類型PCI配置循環(huán)
為了讓CPU上運(yùn)行的PCI初始化代碼能訪問(wèn)位于分支PCI總線上的設(shè)備,必須為橋接器提供某種機(jī)制以便它可以決定是否將配置循環(huán)從主干接口傳遞到其二級(jí)接口。循環(huán)是出現(xiàn)在PCI總線上的一個(gè)地址。PCI 標(biāo)準(zhǔn)定義了兩種PCI配置尋址格式;類型0和類型1;它們分別如圖6.3及6.4所示。類型0 PCI配置循環(huán)不包含總線序號(hào),同時(shí)在此PCI總線上對(duì)應(yīng)于這個(gè)PCI配置地址的所有PCI設(shè)備都會(huì)來(lái)對(duì)它們進(jìn)行解釋。類型0 配置循環(huán)的11 位到31位用來(lái)進(jìn)行PCI設(shè)備選擇。有種設(shè)計(jì)方式是讓每位代表系統(tǒng)中一個(gè)不同的設(shè)備。這時(shí)11位對(duì)應(yīng)PCI槽0中的PCI設(shè)備而12位標(biāo)識(shí)槽1中的設(shè)備等等,如此類推。另外一種方式是直接將設(shè)備的槽號(hào)寫入到位31到11中。系統(tǒng)使用哪種機(jī)制依賴于系統(tǒng)PCI內(nèi)存控制器。
類型1 PCI配置循環(huán)包含一個(gè)PCI總線序號(hào),同時(shí)這種配置循環(huán)將被除橋接器外的所有PCI設(shè)備所忽略。所有發(fā)現(xiàn)類型1 配置循環(huán)的PCI-PCI橋接器把它們看到的地址傳遞到各自的下級(jí)PCI總線。至于PCI-PCI橋接器是否忽略類型1 配置循環(huán)或?qū)⑵鋫鬟f到PCI總線則依賴于PCI-PCI橋接器的配置方式。每個(gè)PCI-PCI橋接器都擁有一個(gè)主干總線接口序號(hào)以及一個(gè)二級(jí)總線接口序號(hào)。主干總線是那個(gè)離CPU最近的PCI總線而二級(jí)總線是離它稍遠(yuǎn)的PCI總線。任何PCI-PCI橋接器還包含一個(gè)從屬總線序號(hào),這是所有二級(jí)總線接口所橋接的PCI總線中序號(hào)最大的那個(gè);蛘哒f(shuō)這個(gè)從屬總線序號(hào)是PCI-PCI橋接器向下連接中PCI總線的最大序號(hào)。當(dāng)PCI-PCI橋接器看到類型1 PCI配置循環(huán)時(shí)它將進(jìn)行如下操作:

  • 如果此總線序號(hào)不在橋接器的二級(jí)總線序號(hào)和從屬總線序號(hào)之間則忽略掉它。
  • 如果此總線序號(hào)與橋接器的二級(jí)總線序號(hào)相同則將其轉(zhuǎn)換成類型0 配置命令。
  • 如果此總線序號(hào)位于橋接器的二級(jí)總線序號(hào)與從屬總線序號(hào)之間則將它不作改變的傳遞到二級(jí)總線接口中。

所以如果想尋址PCI-PCI配置例4中總線3上的設(shè)備1,我們繼續(xù)從CPU中產(chǎn)生一個(gè)類型1 配置命令。橋接器1將其傳遞給總線1。橋接器2雖然忽略它但會(huì)將其轉(zhuǎn)換成一個(gè)類型0 配置命令并送到總線3上,在那里設(shè)備1將作出相應(yīng)反應(yīng)。
PCI配置中總線序號(hào)由操作系統(tǒng)來(lái)分配。但是序號(hào)分配策略必須遵循對(duì)系統(tǒng)中所有PCI-PCI橋接器都正確的描敘:
“位于PCI-PCI橋接器后所有的PCI總線必須位于二級(jí)總線序號(hào)和從屬總線序號(hào)之間”。
如果這個(gè)規(guī)則被打破,則PCI-PCI橋接器將不能正確的傳遞與轉(zhuǎn)換類型1 PCI配置循環(huán),同時(shí)系統(tǒng)將找不到或者不能正確地初始化系統(tǒng)中的PCI設(shè)備。為了滿足這個(gè)序號(hào)分配策略,Linux以特殊的順序配置這些特殊的設(shè)備。
PCI-PCI總線序號(hào)分配
一節(jié)詳細(xì)描敘了Linux的PCI橋接器與總線序號(hào)分配策略。
6.6  Linux PCI 初始化過(guò)程
Linux中的PCI初始化代碼邏輯上可分成三個(gè)部分:
PCI 設(shè)備驅(qū)動(dòng)
這個(gè)偽設(shè)備驅(qū)動(dòng)程序?qū)目偩0開(kāi)始搜索PCI系統(tǒng)并定位系統(tǒng)中所有的PCI設(shè)備與橋接器。它將建立起一個(gè)描敘系統(tǒng)拓?fù)浣Y(jié)構(gòu)的數(shù)據(jù)結(jié)構(gòu)鏈表。另外它還為所有的橋接器進(jìn)行編號(hào)。

PCI BIOS


這個(gè)軟件層提供了在bib-pci-bios定義中描敘的服務(wù)。即使Alpha AXP沒(méi)有BIOS服務(wù),Linux核心也將為它提供具有相同功能的代碼。

PCI Fixup
系統(tǒng)相關(guān)補(bǔ)丁代碼將整理PCI初始化最后階段的一些系統(tǒng)相關(guān)事物。
6.6.1  Linux 核心PCI數(shù)據(jù)結(jié)構(gòu)

圖6.5 Linux核心PCI數(shù)據(jù)結(jié)構(gòu)
Linux核心初始化PCI系統(tǒng)時(shí)同時(shí)也建立了反應(yīng)系統(tǒng)中真實(shí)PCI拓?fù)涞臄?shù)據(jù)結(jié)構(gòu)。 圖6.5顯示了圖6.1所標(biāo)識(shí)的PCI示例系統(tǒng)中數(shù)據(jù)結(jié)構(gòu)間關(guān)系。每個(gè)PCI設(shè)備(包括PCI-PCI橋接器)用一個(gè)pci_dev數(shù)據(jù)結(jié)構(gòu)來(lái)描敘。每個(gè)PCI總線用一個(gè)pci_bus數(shù)據(jù)結(jié)構(gòu)來(lái)描敘。這樣系統(tǒng)中形成了一個(gè)PCI總線樹,每棵樹上由一些子PCI設(shè)備組成。由于PCI總線僅能通過(guò)PCI-PCI橋接器(除了主干PCI總線0)存取,所以pci_bus結(jié)構(gòu)中包含一個(gè)指向PCI-PCI橋接器的指針。這個(gè)PCI設(shè)備是PCI總線的父PCI總線的子設(shè)備。
在圖6.5中沒(méi)有顯示出來(lái)的是一個(gè)指向系統(tǒng)中所有PCI設(shè)備的指針,pci_devices。系統(tǒng)中所有的PCI設(shè)備將其各自的pci_dev數(shù)據(jù)結(jié)構(gòu)加入此隊(duì)列中。這個(gè)隊(duì)列被Linux核心用來(lái)迅速查找系統(tǒng)中所有的PCI設(shè)備。
6.6.2  PCI設(shè)備驅(qū)動(dòng)
PCI設(shè)備驅(qū)動(dòng)根本不是真正的設(shè)備驅(qū)動(dòng),它僅是在系統(tǒng)初始化時(shí)由操作系統(tǒng)調(diào)用的一些函數(shù)。PCI初始化代碼將掃描系統(tǒng)中所有的PCI總線以找到系統(tǒng)中所有的PCI設(shè)備(包括PCI-PCI橋接器)。
它通過(guò)PCI BIOS代碼來(lái)檢查當(dāng)前PCI總線的每個(gè)插槽是否已被占用。如果被占用則它建立一個(gè)pci_dev數(shù)據(jù)結(jié)構(gòu)來(lái)描敘此設(shè)備并將其連接到已知PCI設(shè)備鏈表中(由pci_devices指向)。
首先PCI初始化代碼掃描PCI總線0。它將試圖讀取對(duì)每個(gè)PCI槽中可能的PCI設(shè)備廠商標(biāo)志與設(shè)備標(biāo)志域。當(dāng)發(fā)現(xiàn)槽被占用后將建立一個(gè)pci_dev結(jié)構(gòu)來(lái)描敘此設(shè)備。所有這些PCI初始化代碼建立的pci_dev結(jié)構(gòu)(包括PCI-PCI橋接器)將被連接到一個(gè)單向鏈表pci_devices中。
如果這個(gè)PCI設(shè)備是一個(gè)PCI-PCI橋接器則建立一個(gè)pci_bus結(jié)構(gòu)并將其連接到由pci_root指向的pci_dev結(jié)構(gòu)和pci_bus樹中。PCI初始化代碼通過(guò)類別代碼0x060400來(lái)判斷此PCI設(shè)備是否是一個(gè)PCI-PCI橋接器。然后Linux 核心代碼將配置此PCI-PCI橋接器下方的PCI設(shè)備。如果有更多的橋接器被找到則進(jìn)行同樣的配置。顯然這個(gè)過(guò)程使用了深度優(yōu)先搜索算法;系統(tǒng)中PCI拓?fù)鋵⒃谶M(jìn)行廣度映射前先進(jìn)行深度優(yōu)先映射。圖6.1中Linux將在配置PCI總線0上的視頻設(shè)備前先配置PCI設(shè)備1上的以太與SCSI設(shè)備。
由于Linux優(yōu)先搜索從屬的PCI總線,它必須處理PCI-PCI橋接器二級(jí)總線與從屬總線序號(hào)。在下面的pci-pci總線序號(hào)分配中將進(jìn)行詳細(xì)討論。
配置PCI-PCI橋接器 - 指定PCI總線序號(hào)

圖6.6 配置PCI系統(tǒng):第一部分
為了讓PCI-PCI橋接器可以傳遞PCI I/O、PCI內(nèi)存或PCI配置地址空間,它們需要如下內(nèi)容:
Primary Bus Number:主干總線序號(hào)
位于PCI-PCI橋接器上方的總線序號(hào)
Secondary Bus Number:二級(jí)總線序號(hào)
位于PCI-PCI橋接器下方的總線序號(hào)
Subordinate Bus Number:從屬總線序號(hào)
在橋接器下方可達(dá)的最大總線序號(hào)
PCI I/O and PCI Memory Windows:PCI I/O與PCI內(nèi)存窗口
對(duì)于PCI-PCI橋接器下方所有PCI I/O地址空間與PCI內(nèi)存地址空間的窗口基址和大小。
配置任一PCI-PCI橋接器時(shí)我們對(duì)此橋接器的從屬總線序號(hào)一無(wú)所知。不知道是否還有下一級(jí)橋接器存在,同時(shí)也不知道指派給它們的序號(hào)是什么。但可以使用深度優(yōu)先遍歷算法來(lái)對(duì)掃描出指定PCI-PCI橋接器連接的每條總線,同時(shí)將它們編號(hào)。當(dāng)找到一個(gè)PCI-PCI橋接器時(shí),其二級(jí)總線被編號(hào)并且將臨時(shí)從屬序號(hào)0xff指派給它以便對(duì)其所有下屬PCI-PCI橋接器進(jìn)行掃描與指定序號(hào)。以上過(guò)程看起來(lái)十分復(fù)雜,下面將提供一個(gè)實(shí)例以幫助理解。
PCI-PCI 橋接器序號(hào)分配:步驟1
考慮圖6.6所顯示的拓?fù)浣Y(jié)構(gòu),第一個(gè)被掃描到的橋接器將是橋1。所以橋1下方的總線將被編號(hào)成總線1,同時(shí)橋1被設(shè)置為二級(jí)總線1且擁有臨時(shí)總線序號(hào)0xff。這意味著所有PCI總線序號(hào)為1或以上的類型1 PCI配置地址將被通過(guò)橋1傳遞到PCI總線1上。如果其總線序號(hào)為1則此配置循環(huán)將被轉(zhuǎn)換成類型0 配置循環(huán),對(duì)于其它序號(hào)不作轉(zhuǎn)換。這正是Linux PCI初始化代碼所需要的按序訪問(wèn)及掃描 PCI總線1。

圖6.7 配置PCI系統(tǒng):第二部分
PCI-PCI 橋接器序號(hào)分配:第二步
由于Linux使用深度優(yōu)先算法,初始化代碼將繼續(xù)掃描PCI總線1。在此處它將發(fā)現(xiàn)一個(gè)PCI-PCI橋接器2。除此橋接器2外再?zèng)]有其它橋接器存在,因此它被分配給從屬總線序號(hào)2,這正好和其二級(jí)接口序號(hào)相同。圖6.7畫出了此處的PCI-PCI橋接器與總線的編號(hào)情況。

圖6.8 配置PCI系統(tǒng):第三部分
PCI-PCI 橋接器序號(hào)分配:步驟三
PCI初始化代碼將繼續(xù)掃描總線1并發(fā)現(xiàn)另外一個(gè)PCI-PCI橋接器,橋3。橋3的主干總線接口序號(hào)被設(shè)置成1,二級(jí)總線接口序號(hào)為3,同時(shí)從屬總線序號(hào)為0xff。圖6.8給出了系統(tǒng)現(xiàn)在的配置情況。 帶總線序號(hào)1、2或者3的類型1 PCI配置循環(huán)將被發(fā)送到正確的PCI總線。

圖6.9 配置PCI系統(tǒng):第四部分
PCI-PCI 橋接器序號(hào)分配:步驟四
Linux開(kāi)始沿PCI總線3向下掃描PCI-PCI橋接器。PCI總線3上有另外一個(gè)PCI-PCI橋接器(橋4), 橋4的主干總線序號(hào)被設(shè)置成3,二級(jí)總線序號(hào)為4。由于它是此分支上最后一個(gè)橋接器所以它的從屬總線接口序號(hào)為4。初始化代碼將重新從PCI-PCI橋接器3開(kāi)始并將其從屬總線序號(hào)設(shè)為4。 最后PCI初始化代碼將PCI-PCI橋接器1的從屬總線序號(hào)設(shè)置為4。圖6.9給出了最后的總線序號(hào)分配情況。
6.6.3  PCI BIOS 函數(shù)
PCI BIOS函數(shù)是一組適用于所有平臺(tái)的標(biāo)準(zhǔn)過(guò)程。在Intel和Alpha AXP系統(tǒng)上沒(méi)有區(qū)別。雖然在CPU控制下可以用它們對(duì)所有PCI地址空間進(jìn)行訪問(wèn)。但只有Linux核心代碼和設(shè)備驅(qū)動(dòng)才能使用它們。

6.6.4  PCI 補(bǔ)丁代碼
在Alpha AXP平臺(tái)上的PCI補(bǔ)丁代碼所作工作量要大于Intel平臺(tái)。
基于Intel的系統(tǒng)在系統(tǒng)啟動(dòng)時(shí)就已經(jīng)由系統(tǒng)BIOS完成了PCI系統(tǒng)的配置。Linux只需要完成簡(jiǎn)單的映射配置. 非Intel系統(tǒng)將需要更多的配置:

  • 為每個(gè)設(shè)備分配PCI I/O及PCI內(nèi)存空間。
  • 為系統(tǒng)中每個(gè)PCI-PCI橋接器配置PCI I/O和PCI內(nèi)存地址窗口。
  • 為這些設(shè)備產(chǎn)生中斷連線值;用來(lái)控制設(shè)備的中斷處理。

下一節(jié)將描敘這些代碼的工作過(guò)程。
確定設(shè)備所需PCI I/O和PCI內(nèi)存空間的大小系統(tǒng)要查詢每個(gè)PCI設(shè)備需要多少PCI I/O于PCI內(nèi)存地址空間。為了完成這項(xiàng)工作,每個(gè)基地址寄存器將被寫上全1并讀取出來(lái)。設(shè)備將把不必要的地址位設(shè)為0從而有效的定義所需地址空間。

圖6.10 PCI配置頭:基地址寄存器
有兩類基本的基地址寄存器,一類標(biāo)識(shí)設(shè)備寄存器必須駐留的地址空間;另一類是PCI I/O或PCI內(nèi)存空間。此寄存器的0位來(lái)進(jìn)行類型的區(qū)分。圖6.10給出了對(duì)應(yīng)于PCI內(nèi)存和PCI I/O兩種不同類型的基地址寄存器。
確定某個(gè)基地址寄存器所需地址空間大小時(shí),先向此寄存器寫入全1再讀取此寄存器,設(shè)備將在某些位填上0來(lái)形成一個(gè)二進(jìn)制數(shù)表示所需有效地址空間。
以初始化DEC 21142 PCI快速以太設(shè)備為例,它將告訴系統(tǒng)需要0x100字節(jié)的PCI I/O空間或者PCI內(nèi)存空間。于是初始化代碼為其分配空間?臻g分配完畢后,就可以在那些地址上看到21142的控制與狀態(tài)寄存器。
為PCI-PCI橋接器與設(shè)備分配PCI I/O與PCI內(nèi)存象所有內(nèi)存一樣,PCI I/O和PCI內(nèi)存空間是非常有限甚至匱乏。非Intel系統(tǒng)的PCI補(bǔ)丁代碼(或者Intel 系統(tǒng)的BIOS代碼)必須為每個(gè)設(shè)備分配其所要求的內(nèi)存。PCI I/O和PCI內(nèi)存必須以自然對(duì)齊方式分配給每個(gè)設(shè)備。比如如果一個(gè)設(shè)備要求0xB0大小的PCI I/O空間則它必須和一個(gè)0xB0倍數(shù)的地址對(duì)齊。除此以外,對(duì)于任何指定橋接器,其PCI I/O和PCI內(nèi)存基址必須以在1M字節(jié)邊界上以4K字節(jié)方式對(duì)齊。所以在橋接器下方的設(shè)備的地址空間必須位于任意指定設(shè)備上方的PCI-PCI橋接器的內(nèi)存范圍內(nèi)。進(jìn)行有效的空間分配是一件比較困難的工作。
Linux使用的算法依賴于由PCI設(shè)備驅(qū)動(dòng)程序建立的描敘PCI設(shè)備的總線/設(shè)備樹,每個(gè)設(shè)備的地址空間按照PCI I/O內(nèi)存順序的升序來(lái)分配。同時(shí)再次使用遍歷算法來(lái)遍歷由PCI初始化代碼建立的pci_bus和 pci_dev結(jié)構(gòu)。從根PCI總線開(kāi)始(由pci_boot指向)PCI補(bǔ)丁代碼將完成下列工作:

  • 使當(dāng)前全局PCI I/O和內(nèi)存的基址在4K,邊界在1M上對(duì)齊。
  • 對(duì)于當(dāng)前總線上的每個(gè)設(shè)備(按照PCI I/O內(nèi)存需要的升序排列)

    • 在PCI I/O和PCI內(nèi)存中為其分配空間
    • 為全局PCI I/O和內(nèi)存基址同時(shí)加上一個(gè)適當(dāng)值
    • 授予設(shè)備對(duì)PCI I/O和PCI內(nèi)存的使用權(quán)


  • 為對(duì)于當(dāng)前總線下方的所有總線循環(huán)分配空間。注意這將改變?nèi)諴CI I/O和內(nèi)存基址。
  • 使當(dāng)前全局PCI I/O和內(nèi)存的基址和邊界分別在4K和1M對(duì)齊,以便確定當(dāng)前PCI-PCI橋接器所需的PCI I/O和PCI內(nèi)存基址及大小。
  • 對(duì)此PCI-PCI橋接器編程,將其PCI I/O和PCI內(nèi)存基址及界限連接到總線上。
  • 打開(kāi)PCI-PCI橋接器上的PCI I/O和PCI內(nèi)存訪問(wèn)橋接功能。這時(shí)在此橋接器主干PCI總線上位于此橋接器PCI I/O和PCI內(nèi)存地址窗口中的任何PCI I/O或者PCI內(nèi)存地址將被橋接到二級(jí)PCI總線上。

以圖6.1中的PCI系統(tǒng)為例,PCI補(bǔ)丁代碼將以如下方式設(shè)置系統(tǒng):
對(duì)齊PCI基址
PCI I/O基址為0x4000而PCI內(nèi)存基址為0x100000。這樣允許PCI-ISA橋接器將此地址以下的地址轉(zhuǎn)換成ISA地址循環(huán)。
視頻設(shè)備
我們按照它的請(qǐng)求從當(dāng)前PCI內(nèi)存基址開(kāi)始分配0x200000字節(jié)給它,這樣可以在邊界上對(duì)齊。PCI內(nèi)存基址被移到0x400000同時(shí)PCI I/O基址保持在0x4000。
PCI-PCI 橋接器
現(xiàn)在我們將穿過(guò)PCI-PCI橋接器來(lái)分配PCI內(nèi)存,注意此時(shí)我們無(wú)需對(duì)齊這些基址,因?yàn)樗鼈円呀?jīng)自然對(duì)齊。
以太網(wǎng)設(shè)備
它需要0xB0字節(jié)的PCI I/O和PCI內(nèi)存空間。這些空間從PCI I/O地址0x4000和PCI內(nèi)存地址 0x400000處開(kāi)始。PCI內(nèi)存基址被移動(dòng)到0x4000B0同時(shí)PCI I/O基址移動(dòng)到0x40B0。
SCSI 設(shè)備
它需要0x1000字節(jié)PCI內(nèi)存,所以它將在自然對(duì)齊后從從0x401000處開(kāi)始分配空間。PCI I/O基址仍然在0x40B0而PCI內(nèi)存基址被移動(dòng)到0x402000。
PCI-PCI 橋接器的PCI I/O和內(nèi)存窗口
現(xiàn)在我們重新回到橋接器并將其PCI I/O窗口設(shè)置成0x4000和0x40B0之間, 同時(shí)其PCI內(nèi)存窗口被設(shè)置到0x400000和0x402000之間。這樣此PCI-PCI橋接器將忽略對(duì)視頻設(shè)備的PCI內(nèi)存訪問(wèn)但傳遞對(duì)以太網(wǎng)設(shè)備或者SCSI設(shè)備的訪問(wèn)。

本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/15169/showart_85446.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP