pci中斷是可選的,中斷是電平觸發,低電平有效,集電極開路驅動。中斷訊號與pci clk非同步,裝置一旦斷言為低,則要維持低電平狀態,直到驅動程式清除這個中斷請求。pci中斷可以為通過鏈的方式來共享。下文會仔細分析。
如圖1所示:在pci 匯流排上中斷請求訊號引出腳有inta# - intd# 4個,單功能裝置只能使用inta#,而對於多功能裝置,各功能裝置可任意接至pci 匯流排的四條中斷申請線inta# - intd# 。與中斷密切相關的pci配置暫存器是中斷引腳暫存器(interrupt pin:0x3c) 和中斷線暫存器(interrupt line:0x3b)。
圖1中斷的硬體結構
中斷引腳暫存器(interrupt pin:0x3c):
它是乙個8 位的暫存器,由介面設計者根據pci裝置使用的pci 匯流排中斷引腳(inta# - intd#)來設定:如果裝置使用inta#腳來申請中斷,該暫存器應寫入1;如果裝置使用intb#腳來申請中斷,該暫存器應寫入2;如果裝置使用intc#腳來申請中斷,該暫存器應寫入3 ;如果裝置使用intd#腳來申請中斷,該暫存器應寫入4;如果裝置不使用中斷,該暫存器應寫入0,0x05 到0xff為保留值。
中斷線暫存器(interrupt line:0x3b):
對於x86 系列的pc 機,各個插槽的inta# - intd#引腳由主機板設計者通過可程式設計路由器接到由主從兩個8259a 組成的系統中斷控制器的irq0 - irq15 引腳共計16個引腳中的未使用引腳上。中斷線暫存器(interrupt line)用於儲存中斷路由資訊的暫存器,在初始化和配置系統時,host把路由資訊寫入到該暫存器。在pci 介面卡配置空間中,該暫存器的值表明裝置的中斷引腳( inta# - intd#)被連線到系統中斷控制器的哪乙個引腳(1rqo - irq15中的哪乙個)上了。裝置本身不使用這個值,裝置驅動和作業系統使用該值來決定中斷的優先權和中斷向量資訊, 義,值0 —15 對應16個irq 引腳號,值255 用於表示「未知」或「沒有連線到中斷控制器」,值16 到254 保留。例如:某裝置的inta#被路由至irq3 腳,其中斷線暫存器的值會設定為3。
可程式設計中斷控制器(pic:programmable interrupt controller) 是用來檢測中斷申請。如圖1所示。可程式設計中斷路由器整合在pci/ isa 橋晶元(南橋)中,並且提供了四個中斷輸入端inta#、intb#、intc#、intd#;通過路由器程式設計可以使其與系統中斷控制器的輸入端irqi連線。
intx#線怎樣路由到irqi 線上,由系統定義。如果系統的中斷控制器有四個未使用的中斷請求訊號腳可供使用,如圖1所示的irqw,irqx ,irqy,irqz ,下面給出的路由機制可以將所有裝置的中斷請求均勻地分配到四條irq線上。
設:mb = irq 引腳號( irqw:0 ,irqx:1 ,irqy:2 ,irqz:3) d = 裝置號
i = intx # 線號( inta#:0 ,intb#:1 , intc#:2 , intd#:3)
mb = ( d + i) mod 4
在母板上的裝置號
在pci裝置上的中斷腳
在母板上的中斷腳
0,4,8,12,
16,20,24,28
inta#
irqw
intb#
irqx
intc#
irqy
intd#
irqz
1,5,9,13
17,21,25,29
inta#
irqx
intb#
irqy
intc#
irqz
intd#
irqw
2,6,10,14
18,22,26,30
inta#
irqy
intb#
irqz
intc#
irqw
intd#
irqx
3,7,11,15
19,23,27,31
inta#
irqz
intb#
irqw
intc#
irqx
intd#
irqy
如下圖2以com express的pci中斷路由為例:
圖2 com express的中斷路由
按照上面的中斷路由表,圖1 設計中四個裝置的七個中斷的路由情況為:
裝置0 的inta#, 裝置2 的intc# 連線irqw
裝置1 的inta# 連線irqx
裝置2 的inta#, 裝置1 的intb# 連線irqy
裝置3 的inta#, 裝置2 的intb# 連線irqz
如此,通過中斷腳和中斷線配置暫存器實現了中斷的路由和自動配置。
系統必須為每個中斷提供對應的中斷服務程式,所有中斷服務程式的入口位址即中斷向量通常組織在一起形成乙個中斷入口表,在windows 作業系統中該表稱為中斷描述符表。 由於pci 的中斷是可以共享的,如圖1所示,按照路由機制,裝置0的inta#和裝置2的intc#共享irqw線而在中斷入口表中,所有由irqw線送來的中斷中只能有乙個中斷,其服務程式的入口儲存在系統中斷入口表中。那麼其他中斷服務程式的入口如何組織呢? 這一般應由作業系統決定,通常,如果多個裝置使用同乙個中斷請求線irqi,則後登記的中斷入口會覆蓋先登記的服務程式的入口,先登記中斷的入口被儲存在後登記中斷的服務程式中,依次形成一條鏈。 按照路由機制,如果系統在建立中斷入口表時,先掃瞄到裝置0 的inta#中斷,則裝置0 中斷服務程式的入口位址先被寫入中斷入口表中irqw 對應的表項,其後又掃瞄到裝置2 的intc#也使用了irqw線申請中斷,系統便把裝置2 的intc#中斷服務程式的入口位址寫入中斷入口表中irqw對應的表項,而裝置o的inta#中斷服務程式的入口位址儲存在裝置2的intc#的中斷服務程式中,如此形成一條鏈。
當某條irq 線有裝置申請中斷時,cpu首先轉入最後登記入口的中斷服務中,可查詢該裝置的中斷請求位,若該位被置1,則執行該程式,否則找到下乙個共享中斷的入口,轉入下乙個中斷服務程式執行,在該程式中再查詢該裝置的中斷請求位,判斷是否是該裝置提出的中斷,依次類推。
如此實現了中斷的共享處理。
pci匯流排的中斷共享由硬體與軟體兩部分組成。
硬體上,採用電平觸發的辦法:中斷訊號在系統一側用電阻接高,而要產生中斷的板卡上利用三極體的集電極將訊號拉低。這樣不管有幾塊板產生中斷,中斷訊號都是低;而只有當所有板卡的中斷都得到處理後,中斷訊號才會恢復高電平。
軟體上,採用中斷鏈的方法:假設系統啟動時,發現板卡a用了中斷7,就會將中斷7對應的記憶體區指向a卡對應的中斷服務程式入口isr_a;然後系統發現板卡b也用中斷7,這時就會將中斷7對應的記憶體區指向isr_b,同時將isr_b的結束指向isr_a。以此類推,就會形成乙個中斷鏈。而當有中斷發生時,系統跳轉到中斷7對應的記憶體,也就是isr_b。isr_b就要檢查是不是b卡的中斷,如果是,要處理,並將板卡上的拉低電路放開;如果不是,則呼叫isr_a。這樣就完成了中斷的共享
把中斷路由到對應的cpu上
當cpu使能後 使能時就會進行初始化 就可以正行執行了,當然也包括處理中斷,但是這個時候,中斷還沒有路由到對應的cpu上。這裡呢就分析一下中斷是怎麼路由到它自己對應的cpu上的。看一下函式呼叫 usrroot usrsmpinit usrenablecpu usrsmpcpuenablehook v...
Linux中斷機制
中斷 interrupt 被定義為乙個事件,該事件改變處理器執行的指令順序,這樣的事件與cpu晶元內外部硬體電路產生的電訊號相對應。中斷通常分為同步 synchronous 中斷和非同步 asynchronous 中斷。同步中斷指的是當指令執行時由cpu控制單元產生的,之所以稱為同步,是因為只有在一...
乙個PCI中斷非同步的問題
最近發現由於pci資料傳輸錯誤導致io request得到的資料不正確,這種現象讓我們思考,為什麼系統都已經發現了pci錯誤,io request還能正確結束呢?按照慣例思考,pci傳輸出錯,io request就應該fail掉,但是,事實不是這樣。難道這個問題和pci的中斷非同步有關係?因此,這裡...