設備樹的interrupt( 找到interrupt-parent )


https://www.cnblogs.com/linhaostudy/p/8168942.html
 
interrupts
一個計算機系統中大量設備都是通過中斷請求CPU服務的,所以設備節點就需要在指定中斷號。常用的屬性;
 
interrupt-controller 一個空屬性用來聲明這個node接收中斷,即一個node是一個中斷控制器;
 
#interrupt-cells,是中斷控制器節點的屬性,用來標識這個控制器需要幾個單位做中斷描述符,用來描述子節點"interrupts"屬性使用了父節點中的interrupt屬性的具體哪個值;一般,如果父節點的該屬性的值為3,則子節點的interrupts一個cell的三個32bits的整數值分別為:<中斷域 中斷 觸發方式>,如果父節點的該屬性為2,則是<中斷 觸發方式> interrupt-parent,標識此設備節點屬於哪一個中斷控制器,如果沒有設置這個屬性,會自動依附父節點的;
 
interrups,一個中斷標識符列表,表示每一個中斷輸出信號;
 
 1 / {  2     model = "Marvell Armada 375 family SoC";  3     compatible = "marvell,armada375";  4  soc {  5         #address-cells = <2>;  6         #size-cells = <1>;  7         interrupt-parent = <&gic>;  8 
 9         internal-regs { 10             compatible = "simple-bus"; 11             #address-cells = <1>; 12             #size-cells = <1>; 13 
14  timer@c600 { 15                 compatible = "arm,cortex-a9-twd-timer"; 16                 reg = <0xc600 0x20>; 17                 interrupts = <GIC_PPI 13 (IRQ_TYPE_EDGE_RISING | GIC_CPU_MASK_SIMPLE(2))>; 18                 clocks = <&coreclk 2>; 19  }; 20 
21             gic: interrupt-controller@d000 { 22                 compatible = "arm,cortex-a9-gic"; 23                 #interrupt-cells = <3>; 24                 #address-cells = <0>; 25                 interrupt-controller; 26                 reg = <0xd000 0x1000>, 27                       <0xc100 0x100>; 28  }; 29  } 30 
31         pcie-controller { 32             compatible = "marvell,armada-370-pcie"; 33             #address-cells = <3>; 34             #size-cells = <2>; 35 
36             pcie@1,0 { 37                 #address-cells = <3>; 38                 #size-cells = <2>; 39                 #interrupt-cells = <1>; 40                 interrupt-map-mask = <0 0 0 0>; 41                 interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; 42  }; 43         };

首先我們看到timer@c600這個設備節點下定義了interrupts屬性,這說明該設備可以產生中斷,但是這個屬性下描述了幾個中斷我們是看不出來的(如果有經驗了,我們能猜出只是一個中斷,現在我們按照規則確認)。因為該節點沒有interrupt-parent屬性,那么認為設備樹的父節點internal-regs就是中斷父節點,在internal-regs父節點下還是沒有interrupt-parent屬性,那么還是繼續找設備樹父節點,找到了soc,在該節點下邊有interrupt-parent屬性。該屬性引用的標簽為gic,搜索整個設備樹,interrupt-controller@d000的標簽為gic。gic節點下有interrupt-controller屬性,說明他是一個中斷控制器。gic節點還有屬性#interrupt-cells = <3>,說明在該控制器的interrupt domain下,中斷源(interrupt specifier)用3個u32表示,我們再看timer@c600下的interrupts屬性也確實由3個u32組成(可以參考GIC的規范,第一個u32表示中斷類型,第二個是中斷號,第三個是中斷觸發條件)。這個例子說明如果中斷產生設備的中斷源和中斷控制器的中斷源是一一對應的,那么可以不需要interrupt nexus節點及相關的屬性來表示中斷映射。

 

再看pcie@1,0這個節點,有#interrupt-cells屬性,但是沒有interrupt-controller屬性,這說明他是一個interrupt nexus節點。該節點的#interrupt-cells屬性為1,說明該interrupt nexus節點管轄下的中斷源用1個u32表示就可以了。在pcie@1,0節點下邊沒有子節點,且也沒有節點的interrupt-parent屬性指向pcie@1,0節點,所以從設備樹上看不到該interrupt domain下的中斷產生設備,可能的原因是這些中斷產生設備軟件可以動態識別所以不需要設備樹描述。因為interrupt-map-mask屬性是由中斷產生設備的地址和中斷源(interrupt specifier)組成,且中斷源用1個u32表示,那么可以推測中斷產生設備地址由3個u32組成。這里需要注意的是pcie@1,0節點的#address-cells屬性為3,是說該總線下邊的設備地址用3個u32表示,但並不代表中斷產生設備的設備地址也一定3個u32表示,此處不能說是巧合,但是我們要清楚中斷產生設備的地址由幾個u32組成是由該設備所在總線決定的,對於pcie總線也確實是3,但是其他總線可能存在其他種的情況。現在我們來分析interrupt-map屬性,前三個數字是中斷設備地址,第四個數字是中斷設備的中斷源。因為interrupt-map-mask是全0,這樣不管與什么數字做與運算結果都是0,interrupt-map屬性的前4個數字也都是0,這說明在pcie@1,0下邊所有的中斷映射到中斷父節點的中斷都是一個中斷。接着是指向gic的<phandle>,因為gic節點下#address-cells屬性為0,所以后邊不需要描述中斷父設備的地址了,后邊3個數字都是表示中斷父設備中斷源的。一句話描述就是pcie@1,0下的所有中斷都映射到gic,GIC_SPI類型的第29號中斷,觸發類型為高電平觸發。這個例子說明在中斷樹的最下邊可以是interrupt nexus節點。

 

以上例子中斷樹的根是gic,gic下邊有兩個孩子,一個是中斷設備timer@c600,一個是interrupt nexus節點pcie@1,0。gic直接管轄的interrupt domain用3個u32表示中斷源,timer@c600在這個interrupt domain下。pcie@1,0下定義了一個新的interrupt domain,在該interrupt domain下,中斷源用1個u32表示,pcie@1,0用interrupt-map和interrupt-map-mask屬性將下邊所有設備的中斷映射到一個gic下邊的中斷上。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM