小華的部落格: PCI IRQ Routing Table Specification

搜尋此網誌

網頁

星期三, 9月 26, 2007

PCI IRQ Routing Table Specification

~~~轉載請註明出處~~~by 小華的部落格
在x86歷史的演進中,有很多的BIOS工程師對於PCI IRQ Routing Table還是搞不清楚,我剛入行的時候也是一樣,對於這個東西一點概念都沒有,只知道是因為IRQ#不夠用,所以才需要去繞線(Routing)。

[為何要繞? 背景是什麼?]
依照我自己研究出來的歷史,我發現可能的原因是因為PCI設備越來越多,然後當時的中斷控制器是串聯的8259A,所以只有IRQ0~IRQ15可以用,且IRQ2已經連接 "僕8259" (第二顆中斷控制器),所以剩下來15支IRQ#可以用,但是又因為x86系統在早期的設計中,有些IRQ#已經分配給固定的設備使用,所以剩下來沒幾支可以用,可是設備又那麼多,所以如何去分配剩下來的IRQ就是大家討論的話題。

[IRQ繞線的歷史發展]
依照我查到的資料,早期的作業系統Windows 95年代左右,PCI設備要使用哪一支IRQ中斷線是靠PCI卡上面的"跳線"去控制,所以有可能會因為兩個PCI設備跳同一支"IRQ#"而造成衝突導致當機或是藍底白字。
後來改用BIOS Setup Menu內去控制,也就是可以進去BIOS設定畫面去設定IRQ分配。

因此為了解決PCI設備越來越多,但是IRQ不夠用的情況,所以微軟找上的晶片廠商也就是Intel合作開發PIRQ Route Controller,簡單說就是微軟想在他的作業系統上面支援"共享IRQ中斷架構"的驅動程式,但是需要硬體配合,因此定義了PCI IRQ Routing Table來規範硬體線路要怎樣繞線,且需要BIOS支援哪些資訊。

[為什麼是PCI設備而不是ISA設備?]
因為當時PCI Bus取代了傳統的周邊匯流排,所以PCI設備橫行,且設備需要服務就是透過中斷請求線IRQ#請求服務,對於OS端來說,這個服務就是驅動程式,至於CPU如何把控制權交給OS,則是靠IDT (interrupt Description Table),相關詳細資料請看Windows核心說明。

[跟DOS有關嗎?]
應該是無關,除非你在DOS下替你的PCI設備寫了一個驅動程式,或是你的PCI設備在DOS模式下要工作,不過應該也是沒啥機會這樣做吧,所以PIRQ Routing都是針對Windows作業系統而言,因為與設備驅動程式管理有關。

[Windows 作業系統的改變]
對於微軟自己定義的規範中,他最希望的就是能夠共享IRQ,所以在作業系統的改變就是要能分辨是哪個PCI Device透過IRQ發出請求,這是因為可能有好幾個PCI 設備都用同一支IRQ#中斷請求,所以OS 必須要能夠讓正確的驅動程式去服務發出中斷的設備,因此在撰寫OS 端的 Driver 時有了新的規範(針對共享IRQ的驅動程式有其規範)。

[Chipset的改變]
起先為了微軟的規範,Inetl 在南橋ICH上面多了幾支接腳(PIRQA~PIRQD),這幾支接腳又有對應的暫存器可以組態他們,例如下面範例:

PIRQA Register 60h bit3:0 <--PIRQA那隻接腳的設定暫存器在LPC Reg60h,其中bit3:0定義如下
=================================================================================
IRQ Routing — R/W. (ISA compatible.)
Value IRQ
0000b Reserved
0001b Reserved
0010b Reserved
0011b IRQ3
0100b IRQ4
0101b IRQ5
0110b IRQ6
0111b IRQ7
...
由上面範例可以看出每支PIRQ接腳都可以用"軟體"設定的方式橋接到IRQ#的任何一支。
也由於上面範例我們可以知道,OS 必須"先知道哪些IRQ可以被使用" 還有"哪些IRQ已經被使用",因為OS本身有自己配置IRQ#的演算方式,因此必須要先知道這些資訊,才有辦法去對PIRQ#繞線。

[BIOS的支援]
所以BIOS要提供"PIRQ Routing Table"給作業系統,然後OS就可以得到這些資訊,但是又因為OS版本不同(Win95/Win95/Win2000/WinXp or Acpi OS/non-ACPI OS..等分類),所以透過的傳遞管道也不同。

[後來的演變]
隨著PCI設備越來越多PIRQ只有4支接腳已經不夠用,所以後來擴充到8支,分別是PIRQA~PIRQH。

至今2007,OS 與 Intel 在這部份的演變也越來越複雜,因為後來的Intel 提出了新一代的中斷控制器APIC,所以在南橋ICH內就分成了兩種中斷控制器PIC與I/O APIC兩種,又因為OS演變成ACPI OS,所以原先PCI IRQ Routing Table Spec內所描述的方式就變成了ACPI Spec內的方式,簡單說就是BIOS傳遞PIRQ Routing方式也從Legacy OS方式演變成ACPI Mode方式(原本Table放在記憶體,現在改放在ASL Code)。

另外由於南橋ICH有兩種PIC,所以進入ACPI OS時是採用Legacy PIC mode 還是APIC mode 也會影響BIOS提供PIRQ Routing Table的方式,所以在ACPI Mode 底下又分成APIC Mode方式或是Non-APIC Mode(PIC Mode)方式。

~~~轉載請註明出處~~~by 小華的部落格

[結論]
PIRQ#是南橋上面的接腳,連接到PCI 的INTA#~INTD#,原本INTA#~INTD#應該直接接到PIC上面的IRQ#接腳,但是因為IRQ#不夠用,所以微軟才與Intel合作,多做了幾支接腳出來,然後用軟體方式去配置這些多出來的接腳PIRQ#要繞線到哪個IRQ#,且作業系統的驅動程式可支援共享IRQ中斷,所以在Chipset 端把這種機制稱之為PIRQ Route Controller (具有PIRQ繞線功能的控制器,也就是某某一代的南橋開始把這個功能整合進去南橋晶片內)。

而BIOS所扮演的角色就是提供PIRQ Routing Table,這個Table的結構如同微軟的PCI IRQ Routing Table的規範,而當系統演變到ACPI 後,BIOS也改變了提供Table的方式,也就是改遵循ACPI Spec內的規範去提供這些資訊。

上述這些資訊只是我整理的筆記的一部分概要,詳細內容可以參考相關資料說明,畢竟我也是花了一個多星期的時間才整理出整個PIRQ的歷史,是對是錯我也不清楚,畢竟過去的架構我來不及參與,只能就我收集到的資料作一個描述,如有誤請先進指教。 ~~~轉載請註明出處~~~by 小華的部落格

[後記]
1)當ACPI OS 系統處在APIC Mode的時候,PIRQA~PIRQH會直接對應在APIC 的IRQ16~IRQ23而不需要繞線。
2)APIC 目前可提供的中斷請求線有 IRQ0~IRQ255 ,目前只使用IRQ0~IRQ23
3)APIC 前面的IRQ0#~IRQ15對應到PIC的IRQ0~IRQ15
4)PIRQ Routing 是指: IRQ不夠用才需要透過PIRQ Routing Controller繞線,所以只針對PIC,而APIC模式則不需要繞線。
4)APIC Mode只需要描述哪些PCI Device共用了哪些PIRQ線。
5)non-APIC mode則需要描述哪些PIC的IRQ#可以被使用,描述的內容如同PCI IRQ Routing Table,差別在於用ASL Code描述
6)APIC有分成Local APIC與I/O APIC,這邊所提到的都是指I/O APIC。

[Reference]
http://www.microsoft.com/whdc/archive/pciirq.mspx
http://www.microsoft.com/taiwan/whdc/system/CEC/ACPI-MP.mspx
http://www.google.com

[補充資料]
VGA IRQ的配置


早期VGA卡還在ISA時代的時候, 透過BIOS啟動系統時, 會得到interrupt 第一順位, 而且有固定存取區域在UMB(Upper Memory Black)裡頭與系統相對印; 在PnP時代, BIOS系統直接在啟動系統時給予IRQ#編號, 無論你是AGP or PCI都變成由BIOS指定位置, 而不再像ISA時代需要跟其他人搶系統控制權.

順便一提的是, MS系統推出雙螢幕(Dual VGA)的概念的時候, 一些VGA-BIOS沒規劃好的顯示卡就出現問題. 因為在BIOS啟動系統的時候, 會依照設定順序尋找開機起始用的顯示卡(預設是PCI), 結果因為有兩張PCI顯示卡(或者主機板的晶片採用SIS55xx系列, VIA早期586時代晶片都有這種現象), 反而推選不出一個可以啟動的System VGA, 變成必須在佈線的時候強制規定哪邊是佔用較高優先權的現象...

到了AGP時代, 變成系統直接佔用, 不再有IRQ衝突的事情.....對廠商對BIOS規劃人員也變得比較簡單點了....

display card在古老時代是不需要IRQ的,當時diplay card本身不過是被動式的介面,顯示記憶體都是由CPU來控制寫入或讀出與搬移(如HOYO兄所說),所以那時就是單純的使用 Linear address mapping 來處理,而遇到較大而複雜的畫面記憶體處理時,就用視訊記憶體頁切換來應付,然而隨著顯示的需求越來越複雜,VGA card和CPU間的溝通需求也越來越多,VGA本身也搭載了功能強大的GPU,可算是一個小的專門處理影像的CPU了.這時候 VGA Card不再是一個只會聽CPU命令的單元了,它開始會對CPU提出要求,以進行一些需要取用北橋資源的動作,此時就需要IRQ來做"舉手發言".

目前市面上仍然有一些VGA是不需要IRQ的,但並不代表它們不是高階顯示卡,而是視廠商所使用的技術而定.
一般的 VGA IRQ 預設大都在IRQ 11,除非有佔用系統會自動轉到別的IRQ...

PIRQ配置演算法(4 支PIRQ的時候)
PCI SLOT 中斷共有四個
INT a/b/c/d
一般的接法是
Slot1 a/b/c/d 接到南橋 a/b/c/d
Slot2 a/b/c/d 接到南橋 b/c/d/a
Slot3 a/b/c/d 接到南橋 c/d/a/b
Slot4 a/b/c/d 接到南橋 d/a/b/c
而卡上 通常是從 int a 接起
所以兩片使用一個中斷的PCI 卡會變成個別接到 int a / int b, 而不會通通都接到int a 了

PCI 要求裝置的中斷要共享,唯一缺點就是 "共享的部分" 要多消耗一些程式碼去確定中斷是給誰的
另有一些ON BOARD 的裝置已經固定接到其中的一些中斷訊號線上了,看看主機板說明書上有沒有寫
這樣你就可以知道INT a/b/c/d 哪些是完全可以獨立運作的。

中斷經過IRQ Routing table 去轉成我們常說的中斷號碼 IRQ# 這個在BIOS中可以設定,也可以自動配置。如果有獨立中斷的SLOT 就可以拿來用在IDE Card/SCSI Card這種講究效能的裝置上。

另外就是給一些卡使用,因為這些卡的驅動程式不肯跟別人分享中斷,如果分享就不肯工作。
還有一種卡和別人分享就容易當機。

有一些ISA 規格的裝置一定會佔用固定的中斷,如果不用可以DISABLE,不過 PCI 還是只有四個給你的SLOT用空再多也沒用要分享的依舊要分享
irq-0 Timer
irq-1 Keyboard
irq-2 Cascade
irq-3 Com2
irq-4 Com1
irq-7 LPT1
irq-8 RTC
irq-12 PS/2
irq-13 FPU
irq-14 IDE1
irq-15 IDE2

大部分的VGA 都沒有配中斷,另外 Win2k ACPI 會把IRQ routing table 通通都設成同一個中斷號碼 沒辦法改 效能會降低 因為每個PCI卡的驅動程式都會檢查一遍 看看是不是自己的中斷,每次也只會有一個說是他的中斷這在高速裝置是很糟糕的。

6 則留言:

匿名 提到...

前辈你好,每每细细品味你的文章我都感到受益匪浅。真的希望你能持續給我這樣的初學者更多的文章。其實也希望干BIOS的人都能看到你的佳作,也允許我以後把你的文章轉載到自己的部落里。


還有,在大陸其實有很多的BIOS engineer,可是還有很多人也想多了解BIOS卻是苦於沒有比較好的網路論壇。而你成了很耀眼的一顆星星,在大陸這面有好多好多的人都關注你的部落格的。


一直關注中!!

匿名 提到...

谢谢你的分享!!

切菜-切到澇賽 提到...

補充一下, 上面有提到 LOCAL APIC and I/O APIC.. 事實上, 我認為 APIC 這個東西是由 INTEL 的 CPU architecture team 搞出來的, 所以, LOCAL APIC 實際上是指CPU 內部的 APIC, 而 Chipset 的部份, 就是所謂的 I/O APIC.

klhsieh 提到...

Thank you very much!
You supply wonderful knowledge!

匿名 提到...

其實 ISA 後期,
也有 PnP 阿 !

我記得 PnP 就是為解決 IRQ 分配 而來 !

映像中 有 PnP 的ISA 音效卡 !

Linux 有個 isapnptools 套件喔 !

Samuel Yang 提到...

APIC 前面的IRQ0#~IRQ15對應到PIC的IRQ0~IRQ15
這句話到底是什麼意思?
apic不是有0~23個irq可用
pirqA~pirqH 已經對應到IRQ16-23
那0-15 irq到底是怎樣運作?
還是只要是0-15就是PIC來處理
而16-23則是APIC處理?