在设备树中,节点的中断输出单元格大小为 1,但其中断父节点似乎有#interrupt-cells = 3。为什么?
In device tree, a node's interrupts output cell size is 1 but its interrupt-parent seems to have #interrupt-cells = 3. Why?
我正在通过修改现有文件来制作一个 dts 文件,但通过挖掘绑定文档仍然很难理解设备树语法和含义。这是另一个我无法理解的。请帮帮我..
在linux-5.15源代码中,我在arch/arm64/boot/dts/arm/fvp-base-revc.dts(显示部分)中看到,
#include "rtsm_ve-motherboard.dtsi"
#include "rtsm_ve-motherboard-rs2.dtsi"
/ {
model = "FVP Base RevC";
compatible = "arm,fvp-base-revc", "arm,vexpress";
interrupt-parent = <&gic>; <== see this
#address-cells = <2>;
#size-cells = <2>;
...
gic: interrupt-controller@2f000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>; <=== see this
#address-cells = <2>;
#size-cells = <2>;
ranges;
interrupt-controller;
....
};
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, <== see these lines (3 values per cell)
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
};
所以因为 gic
有 #incterrupt-cells = <3>,(对于中断类型、编号和标志),生成 4 个中断的 timer
节点每个中断单元有 3 个值。但是在之前包含的文件 rtsm_ve-motherboard.dtsi
中,我看到了这一行。
v2m_serial0: serial@90000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x090000 0x1000>;
interrupts = <5>; <== see this, (1 value per cell, why?)
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
clock-names = "uartclk", "apb_pclk";
};
v2m_serial1: serial@a0000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0a0000 0x1000>;
interrupts = <6>; <== see this, (1 value per cell, why?)
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
clock-names = "uartclk", "apb_pclk";
};
为什么这里的中断值只有1个单元格? (interrupts = <6>) 我在绑定文档或现有的 dts 文件中找不到任何指定 #interrupt-cells = 1
的中断控制器。
为什么v2m_serial0节点只有一个值interrupts
值?
v2m_serial0: serial@90000
的路径是:
/bus@8000000/motherboard-bus@8000000/iofpga-bus@300000000/serial@90000
向根移动,具有 #interrupt-cells
属性 的第一个节点是 bus@8000000
。 bus@8000000
节点部分定义在“rtsm_ve-motherboard.dtsi”文件中:
bus@8000000 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0x8000000 0 0x8000000 0x18000000>;
motherboard-bus@8000000 {
…
节点在“rtsm_ve-motherboard-rs2.dtsi”中定义了额外的material,现在不重要,在“fvp-base-revc.dts" 文件,其中包含 #interrupt-cells
属性:
bus@8000000 {
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
<0 0 1 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
<0 0 2 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
<0 0 3 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<0 0 4 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
<0 0 5 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
<0 0 6 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
…
<0 0 43 &gic 0 0 GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
<0 0 44 &gic 0 0 GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
};
#interrupt-cells
属性 的值为 1,这就是为什么子节点中的 interrupts
属性每个中断有一个单元格。
interrupt-map
属性 正在将单单元中断值映射到 &gic
中断控制器中的中断。上面的每个映射元素由 9 个单元格组成,包括:
- 设备的 2 个地址单元格 (
#address-cells = <2>
)
- 设备的 1 个中断单元 (
#interrupt-cells = <1>
)
- 1 个包含上游中断控制器 phandle 的单元格
- 上游中断控制器的 2 个地址单元 (
#address-cells = <2>
)
- 3 个用于上游中断控制器的中断单元 (
#interrupt-cells = <3>
)
interrupt-map-mask
属性由3个单元格组成,包括:
- 2 个地址掩码单元匹配设备
reg
属性 (#address-cells = <2>
)
- 1 个中断屏蔽单元匹配设备
interrupt
属性 (#interrupt-cells = <1>
)
v2m_serial0: serial@90000
节点具有以下 reg
和 interrupts
属性:
reg = <0x090000 0x1000>;
interrupts = <5>;
地址和中断单元的组合值是 <0x090000 0x1000 5>
。当AND与interrupt-map-mask
属性值<0 0 63>
运算时,结果为<0 0 5>
,匹配中断映射元素<0 0 5 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>
。因此,设备的 interrupts
属性 值映射到 &gic
中断控制器的 <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>
中断值。
在“drivers/of/irq.c”中由of_irq_parse_raw()
完成中断映射解析匹配。
我正在通过修改现有文件来制作一个 dts 文件,但通过挖掘绑定文档仍然很难理解设备树语法和含义。这是另一个我无法理解的。请帮帮我..
在linux-5.15源代码中,我在arch/arm64/boot/dts/arm/fvp-base-revc.dts(显示部分)中看到,
#include "rtsm_ve-motherboard.dtsi"
#include "rtsm_ve-motherboard-rs2.dtsi"
/ {
model = "FVP Base RevC";
compatible = "arm,fvp-base-revc", "arm,vexpress";
interrupt-parent = <&gic>; <== see this
#address-cells = <2>;
#size-cells = <2>;
...
gic: interrupt-controller@2f000000 {
compatible = "arm,gic-v3";
#interrupt-cells = <3>; <=== see this
#address-cells = <2>;
#size-cells = <2>;
ranges;
interrupt-controller;
....
};
timer {
compatible = "arm,armv8-timer";
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, <== see these lines (3 values per cell)
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
};
所以因为 gic
有 #incterrupt-cells = <3>,(对于中断类型、编号和标志),生成 4 个中断的 timer
节点每个中断单元有 3 个值。但是在之前包含的文件 rtsm_ve-motherboard.dtsi
中,我看到了这一行。
v2m_serial0: serial@90000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x090000 0x1000>;
interrupts = <5>; <== see this, (1 value per cell, why?)
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
clock-names = "uartclk", "apb_pclk";
};
v2m_serial1: serial@a0000 {
compatible = "arm,pl011", "arm,primecell";
reg = <0x0a0000 0x1000>;
interrupts = <6>; <== see this, (1 value per cell, why?)
clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>;
clock-names = "uartclk", "apb_pclk";
};
为什么这里的中断值只有1个单元格? (interrupts = <6>) 我在绑定文档或现有的 dts 文件中找不到任何指定 #interrupt-cells = 1
的中断控制器。
为什么v2m_serial0节点只有一个值interrupts
值?
v2m_serial0: serial@90000
的路径是:
/bus@8000000/motherboard-bus@8000000/iofpga-bus@300000000/serial@90000
向根移动,具有 #interrupt-cells
属性 的第一个节点是 bus@8000000
。 bus@8000000
节点部分定义在“rtsm_ve-motherboard.dtsi”文件中:
bus@8000000 {
compatible = "simple-bus";
#address-cells = <2>;
#size-cells = <1>;
ranges = <0 0x8000000 0 0x8000000 0x18000000>;
motherboard-bus@8000000 {
…
节点在“rtsm_ve-motherboard-rs2.dtsi”中定义了额外的material,现在不重要,在“fvp-base-revc.dts" 文件,其中包含 #interrupt-cells
属性:
bus@8000000 {
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 63>;
interrupt-map = <0 0 0 &gic 0 0 GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
<0 0 1 &gic 0 0 GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
<0 0 2 &gic 0 0 GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
<0 0 3 &gic 0 0 GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
<0 0 4 &gic 0 0 GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
<0 0 5 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
<0 0 6 &gic 0 0 GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
…
<0 0 43 &gic 0 0 GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
<0 0 44 &gic 0 0 GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
};
#interrupt-cells
属性 的值为 1,这就是为什么子节点中的 interrupts
属性每个中断有一个单元格。
interrupt-map
属性 正在将单单元中断值映射到 &gic
中断控制器中的中断。上面的每个映射元素由 9 个单元格组成,包括:
- 设备的 2 个地址单元格 (
#address-cells = <2>
) - 设备的 1 个中断单元 (
#interrupt-cells = <1>
) - 1 个包含上游中断控制器 phandle 的单元格
- 上游中断控制器的 2 个地址单元 (
#address-cells = <2>
) - 3 个用于上游中断控制器的中断单元 (
#interrupt-cells = <3>
)
interrupt-map-mask
属性由3个单元格组成,包括:
- 2 个地址掩码单元匹配设备
reg
属性 (#address-cells = <2>
) - 1 个中断屏蔽单元匹配设备
interrupt
属性 (#interrupt-cells = <1>
)
v2m_serial0: serial@90000
节点具有以下 reg
和 interrupts
属性:
reg = <0x090000 0x1000>;
interrupts = <5>;
地址和中断单元的组合值是 <0x090000 0x1000 5>
。当AND与interrupt-map-mask
属性值<0 0 63>
运算时,结果为<0 0 5>
,匹配中断映射元素<0 0 5 &gic 0 0 GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>
。因此,设备的 interrupts
属性 值映射到 &gic
中断控制器的 <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>
中断值。
在“drivers/of/irq.c”中由of_irq_parse_raw()
完成中断映射解析匹配。