設備樹的interrupt

来源:https://www.cnblogs.com/linhaostudy/archive/2018/01/01/8168942.html
-Advertisement-
Play Games

http://www.cnblogs.com/targethero/p/5080499.html https://www.cnblogs.com/xiaojiang1025/p/6131381.html interrupts 一個電腦系統中大量設備都是通過中斷請求CPU服務的,所以設備節點就需要在 ...


http://www.cnblogs.com/targethero/p/5080499.html https://www.cnblogs.com/xiaojiang1025/p/6131381.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下邊的中斷上。