Linux - Devicetree规范: 中断和中断映射

adtxl
2024-10-22 / 0 评论 / 31 阅读 / 正在检测是否收录...

转载自https://blog.csdn.net/guoqx/article/details/124241733

2.4 中断和中断映射 Interrupts and Interrupt Mapping

DTSpec采用Open Firmware Recommended Practice:Interrupt Mapping, Version 0.9 中规定的表示中断的中断树模型。在设备树中存在一个逻辑中断树,它代表了平台硬件中中断的层次和路径。虽然一般被称为中断树,但在技术上是一个有向无环图(directed acyclic graph)。

中断源到中断控制器的物理线路在devicetree中用interrupt-parent属性表示。代表中断产生设备的节点包含一个interrupt-parent属性,它有一个phandle值,指向的是该设备的中断被接受的设备,通常是一个中断控制器。如果一个产生中断的设备没有interrupt-parent属性,那么它的interrupt-parent就被认为是它的devicetree的父节点。

每个产生中断的设备都包含一个interrupts属性,其值描述了该设备的一个或多个中断源。每个中断源用一个名为interrupt specifier的信息结构所表示。interrupt specifier的格式和含义是特定于中断域的,也就是说,它依赖于其中断域根部节点上的属性。中断域的根节点使用#interrupt-cells属性来定义编码interrupt-specifer所需的值的数量。例如,对于Open PIC中断控制器来说,一个interrupt-specifer需要两个32位的值,由中断号和中断的电平/感应信息组成。

中断域是解释interrupt specifier的上下文。域的根是(1)一个中断控制器(interrupt controller)或(2)一个中断关系(interrupt nexus)。

  1. 中断控制器是一个物理设备,需要一个驱动程序来处理通过它路由的中断。它也可以级联到另一个中断域中。中断控制器是由devicetree中该节点上的显示的interrupt-controller属性所指定。
  2. 中断关系定义了一个中断域和另一个中断域之间的转换。这种转换是基于特定于中断域和总线的信息。这种域之间的转换是通过interrupt-map属性进行的。例如,一个PCI控制器设备节点可以是一个interrupt nexus,它定义了从PCI中断命名空间(INTA、INTB等)到具有中断请求(IRQ)编号的中断控制器的转换。

当对中断树的遍历到达一个没有中断属性的中断控制器节点,从而没有明确的中断父节点时,中断树的根就确定了。

请看图2.3,这是一个带有中断父级关系的设备树的图形表示例子。它既显示了设备树的自然结构,也显示了每个节点在逻辑中断树中的位置。

image.png

图2.3 中断树举例

在图2.3的例子中:

  • open-pic中断控制器是整个中断树的根节点
  • 这个中断树有三个子设备,它们的中断会直接传递给open-pic

     第一个子设备:device 1
    
     第二个子设备:PCI host controller
    
     第三个子设备:GPIO Controller
    
  • 有三个中断域;一个open-pic根节点,一个PCI host bridge,还有一个位于GPIO Controller节点
  • 有两个中断关系节点(nexus nodes), 一个位于PCI host bridge, 另一个位于GPIO controller。

2.4.1 产生中断的设备的属性 Properties for interrupt Generating Devices

中断 interrupts

属性名称:compatible

值类型: <prop-encoded-array> ,由任意数量的interrupt specifiers(中断解释)编码组成

说明:

设备节点的interrupts属性定义了由设备产生的一个或多个中断。

interrupts属性的值由任意数量的interrupt specifiers组成。interrupt specifiers的格式是由中断域的根的binding定义的。

interrupts-extended属性覆盖interrupts-extended属性,通常只应使用其中之一。

示例:

在一个开放的PIC兼容的中断域中,一个常见的interrupt specifier的定义包括两个单元;一个中断号和电平/感应(level/sense)信息。请看下面的例子,它定义了一个单一的interrupt specifier,中断号为0xA,电平/感应编码为8。

interrupts = <0xA 8>;

中断父节点 interrupt-parent

属性名称:interrupt-parent

值类型: <phandle> 

说明:

因为中断树中节点的层次结构可能与设备树不一致,所以interrupt-parent属性可用来明确定义中断父节点。该值是指向中断父节点的phandle。如果一个设备没有这个属性,它的中断父节点就被认为是它的设备树父节点。

中断扩展 interrupt-extended

属性名称:interrupt-extended

值类型: <phandle>  <prop-encoded-array>

说明:

interrupts-extended属性列出了一个设备产生的中断。当一个设备连接到多个中断控制器时,应使用interrupts-extended而不是interrupts,因为它为每个interrupt specifier编码了一个父级phandle。

示例:

这个例子显示了一个有两个中断输出的设备是如何连接到两个独立的中断控制器的,将使用interrupt-extended属性来描述连接。 pic是一个中断控制器,#interrupt-cells设定为为2,而gic是一个中断控制器,##interrupt-cells设定为1。

interrupts-extended = <&pic 0xA 8>, <&gic 0xda>;

中断和中断-扩展属性是相互排斥的。一个设备节点应该使用一个或另一个,但不能同时使用。只有在需要与不理解interruptsextended的软件兼容时,才允许同时使用。

如果interrupts-extended和interrupts都存在,那么interrupts-extended优先。

2.4.2 中断控制器属性 Properties for Interrupt Controllers

#interrupt-cells 

属性名称:#interrupt-cells

值类型: <u32>

说明:

#interrupt-cells属性定义了编码一个interrupt specifier所需的单元数,这个interrupt specifier存在于某个中断域中。

interrupt-controller

属性名称:interrupt-controller

值类型: <empty>

说明:

interrupt-controller属性定义了一个中断控制器节点。

2.4.3 中断关系属性 Interrupt Nexus Properties

一个interrupt nexus节点必须有一个#interrupt-cells属性。

interrupt-map

属性名称:interrupt-map

值类型: <prop-encoded-array> , 表示为任意数量的interrupt mapping条目。

说明:

中断映射interrupt-map是节点上的一个属性,它将一个中断域与一组父中断域连接起来,并指定子域中的interrupt specifier如何映射到它们各自的父域中。

中断映射是一个表格,每一行都是由五个部分组成的映射条目:子单元地址、子中断specifier、中断父节点、父单元地址、父中断specifier。

子单元地址

被映射的子节点的单元地址。需要指定的32位单元的数量由子节点所在的总线节点的#address-cell属性描述。

子节点中断指定器

子中断specifier

指定该组件所需的32位单元的数量由该节点--包含中断映射属性的节点的#interrupt-cell属性描述。

中断父节点

一个单一的<phandle>值,指向子域被映射到的中断父域的节点。

父单元地址

在中断父域中的单元地址。指定该地址所需的32位单元的数量由#address-cells属性描述,该节点由

interrupt-parent字段所指向的节点的#address-cells属性描述。

父中断specifier

父域中的中断specifier。指定该组件所需的32位单元的数量由interrupt-parent字段所指向的节点的#interrupt-cells属性描述。

单元-地址和中断specifier组成一对,将这对数据与子组件在中断映射表中形成一个匹配关系,然后在中断映射表上进行查找。因为单元中断指定器中的一些字段可能不相关,所以在进行查找之前要应用一个屏蔽。这个掩码在interrupt-map-mask属性中定义(见2.4.3节)。

注意:子节点和中断父节点都需要定义#address-cell和#interrupt-cells属性。如果不需要单位地址组件,#address-cells应明确定义为0。

interrupt-map-mask

属性名称:interrupt-map-mask

值类型: <prop-encoded-array> ,  编码形式为bit mask

说明:

为中断树中的中断关系节点指定一个interrupt-map-mask属性。该属性指定了一个掩码。在interrupt-map属性里指定的表中进行查询,将查找到的单元中断specifier和此掩码进行与操作。

#interrupt-cells

属性名称:#interrupt-cells

值类型: <u32>

说明:

#interrupt-cells属性定义了为一个中断域编码一个中断specifier所需的单元数。

2.4.4 中断映射示例 Interrupt Mapping Example

下面显示了一个devicetree片段,带有一个PCI总线控制器和一个中断映射。中断映射描述了两个PCI slots (IDSEL

0x11, 0x12)的路由信息。1号和2号插槽的INTA、INTB、INTC和INTD引脚被连接到Open PIC中断控制器。

soc {

    compatible = "simple-bus";

    #address-cells = <1>;

    #size-cells = <1>;

    open-pic {

        clock-frequency = <0>;

        interrupt-controller;

        #address-cells = <0>;

        #interrupt-cells = <2>;

    };

    pci {

        #interrupt-cells = <1>;

        #size-cells = <2>;

        #address-cells = <3>;

        interrupt-map-mask = <0xf800 0 0 7>;

        interrupt-map = <

            /* IDSEL 0x11 - PCI slot 1 */

            0x8800 0 0 1 &open-pic 2 1 /* INTA */

            0x8800 0 0 2 &open-pic 3 1 /* INTB */

            0x8800 0 0 3 &open-pic 4 1 /* INTC */

            0x8800 0 0 4 &open-pic 1 1 /* INTD */

            /* IDSEL 0x12 - PCI slot 2 */

            0x9000 0 0 1 &open-pic 3 1 /* INTA */

            0x9000 0 0 2 &open-pic 4 1 /* INTB */

            0x9000 0 0 3 &open-pic 1 1 /* INTC */

            0x9000 0 0 4 &open-pic 2 1 /* INTD */

        >;

    };

};

有interrupt-controller属性的节点,也就是Open PIC节点是一个中断控制器。

中断映射表中的每一行由五个部分组成:一个子单元地址和中断specifier,它被映射到一个interrupt-parent节点,具有指定的父单元地址和中断specifier。

比如终端映射表的第一行:

0x8800 0 0 1 &open-pic 2 1 /* INTA */

各个部分如下:

child unit address: 0x8800 0 0

   #address-cells = <3>,所以三个数字。0x8800由bus number (0x0 << 16), device number (0x11 << 11),  and function number(0x0 << 8)组成。
child interrupt specifier: 1

    表示INTA,#interrupt-cells = <1>,所以只一个数字。
interrupt parent: &open-pic0

    表示中断父节点的phandle值。
parent unit address: (empty because #address-cells = <0> in the open-pic node)
parent interrupt specifier: 2 1

#interrupt-cells为2,所以是2个数字。值<2>指定INTA所连接的中断控制器上的物理中断源编号。值<1>指定level/sense编码。

在这个例子中,中断映射掩码属性的值是<0xf800 0 0 7>。在执行中断映射表的查找之前,该掩码被应用到子单元中断specifier上。

要查找open-pic的中断源的号码,此中断为IDSEL 0x12(slot 2),function 0x3的INTB。具体操作如下:

  • 子单元地址和中断specifier组成值为<0x9300 0 0 2>

      - 地址的编码包括总线号`(0x0 << 16)`,设备号`(0x12 << 11)`,和功能号`(0x3 << 8)`。
    
      - 中断specifier为2,这是根据PCI绑定的INTB的编码。
    
  • 使用中断映射掩码值<0xf800 0 0 7>,得到的结果是<0x9000 0 0 2>
  • 这个结果在中断映射表中被查询,它被映射到父中断specifier<4 1>
0

评论 (0)

取消