中断
中断一般包括中断产生设备和中断处理设备。中断控制器负责处理中断,每一个中断都有对应的中断号及触发条件。中断产生设备可能有多个中断源,有时多个中断源对应中断控制器中的一个中断,这种情况中断产生设备的中断源称之为中断控制器中对应中断的子中断。一般情况中断产生设备数量要多于中断控制器,多个中断产生设备的中断都由一个中断控制器处理,这种多对一的关系也很像一个树形结构,所以在设备树中,中断也被描述成树,叫中断树。以下表述的时候为了明确是在说中断树,在父节点和子节点前边我们都加上“中断”二字,是为了防止和设备树的父节点、子节点混淆(虽然大部分情况设备树的父子关系就是中断树的父子关系,但是因为存在特例,所以我们还是强调是中断父子关系)。
中断产生设备用interrupts属性描述中断源(interrupt specifier),因为不同的硬件描述中断源需要的数据量不同,所以interrupts属性的类型也是
中断控制器节点用interrupt-controller属性表示自己是中断控制器,这个属性的类型是空,不用设置值,只要存在这个节点就表示该节点是中断控制器。除了这个属性外,中断控制器节点还有#interrupt-cells属性,用来表示该中断控制器直接管理下的interrupt domain(后边我们会讲中断控制器的中断子节点interrupt nexus节点有单独的interrupt domain)用几个u32表示一个中断源(interrupt specifier)。中断控制器节点就包括interrupt-controller和#interrupt-cells两个关于中断的属性。中断控制器的#address-cells属性和中断映射有关系,但是该属性不是为中断设计的,中断映射只是用到了这个属性而已。
前边说中断控制器中的一个中断可能对应中断产生设备中的多个中断源,那这种对应关系用什么描述呢?我们还说过#interrupt-celll属性不仅是中断控制器节点的属性,还是interrupt nexus节点的属性,这个interrupt nexus节点就是描述中断映射关系的,该节点通过interrupt-map,interrupt-map-mask属性描述中断映射关系。 interrupt-map属性是
还记得前边说过中断设备的中断源和中断控制器的中断源可能是多对一的关系,如果每个子中断都用interrupt-map中的一行表示,那么 interrupt-map属性将非常大。为了让多个子中断共享映射关系,引入了interrupt-map-mask属性,该属性的类型也是
我们再来复习一下,整个中断树的最底层是中断产生设备(也可能是从interrupt nexus节点),中断产生设备用interrupts属性描述他能产生的中断。因为他的中断父设备可能和设备树的父设备不同,那么用 interrupt-parent属性指向他的中断父设备。他的中断父设备可能是中断控制器(如果中断产生设备的中断和中断控制器的中断是一一对应的,或者最底层是interrupt nexus节点),也可能是interrupt nexus节点(如果最底层是中断产生设备,且需要映射)。interrupt nexus节点及他的所有直接子节点构成了一个interrupt domain,在该interrupt domain下中断源怎样表示由#interrupt-cells属性决定,如何由中断子设备中断源找到中断父设备中断源由interrupt-map和 interrupt-map-mask属性决定。interrupt nexus的父节点可能还是一个interrupt nexus父节点,也可能是一个中断控制器,当向上找到最后一个中断控制器,并且该中断控制器再也没有中断父设备时,整个中断树就遍历完成了。中断控制器用interrupt-controller属性表示自己是中断控制器,并且用#interrupt-cells属性表示他所直接管理的 interrupt domain用几个u32表示一个中断源。根据中断树的特性,一个设备树中是有可能有多个中断树的。
以上是中断在设备树中如何描述的规则,听起来是挺复杂的,但只要理解了就很简单,为了帮助理解我们举一个实际的例子。为了突出中断部分,我们做了简化。
/ {
model = "Marvell Armada 375 family SoC";
compatible = "marvell,armada375";
soc {
#address-cells = <2>;
#size-cells = <1>;
interrupt-parent = <&gic>;
internal-regs {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
timer@c600 {
compatible = "arm,cortex-a9-twd-timer";
reg = <0xc600 0x20>;
interrupts =
clocks = <&coreclk 2>;
};
gic: interrupt-controller@d000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
#address-cells = <0>;
interrupt-controller;
reg = <0xd000 0x1000>,
<0xc100 0x100>;
};
}
pcie-controller {
compatible = "marvell,armada-370-pcie";
#address-cells = <3>;
#size-cells = <2>;
pcie@1,0 {
#address-cells = <3>;
#size-cells = <2>;
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &gic GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
};
};
}
首先我们看到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的
以上例子中断树的根是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下边的中断上。
2015职称计算机考试书PowerPoint2007中 .. 定价:¥45 优惠价:¥42 更多书籍 | |
2015年全国职称计算机考试教材(2007模 .. 定价:¥225 优惠价:¥213 更多书籍 |