zoukankan      html  css  js  c++  java
  • 【分享】扩展MPSoC中断

    扩展MPSoC中断

    付汉杰 hankf@xilinx.com

    1. MPSoC的中断处理介绍

    MPSoC是带ARM处理器和FPGA(PL)的SoC,包含4核A53及其常用外部模块(PS)。A53(PS)使用Arm GIC-400,属于GICv2架构。如果想了解GIC-400的具体细节,请参考文档APU GIC: CoreLink GIC-400 Generic Interrupt Controller, DDI 0471B, r0p1。

    MPSoC的A53(PS)的中断细节,在Xilinx的UG1085的Table 13‐1: System Interrupts部分做了详细介绍。

    需要注意的是,UG1085的Table 13‐1描述的是芯片的内部连线,是硬件中断号,和Linux Kernel使用的软件中断号(逻辑中断号)有区别。有的SOC只有一个中断控制器,有的SOC有多个串联/并联的中断控制器。Linux Kernel为了各种处理复杂的中断控制器设计,并给中断提供统一的API,在内部使用统一编址的的软件中断号。同时,GIC的Linux Kernel驱动内部有一个表,用于转换硬件中断号和软件中断号。这样的好处是,即使不同SoC系统里有不同的中断控制器结构,驱动程序也可以忽略这些细节,使用统一的API,比如platform_get_irq,从Device Tree里获取中断号,并向Linux Kernel注册驱动程序的中断处理程序。另外,设备的Device Tree里的中断号是局部的,在它所属的中断控制器里保持唯一即可。Linux Kernel使用的软件中断号,是整个Linux Kernel系统的,需要在Linux Kernel范围内保持唯一。
    更多信息可以参考Linux Kernel代码,以及Linux kernel的中断子系统之(二):IRQ Domain介绍

    MPSoC的Device Tree的软件中断号,比UG1085的Table 13‐1提供的硬件中断号小32。这是因为A53内部的中断号0-31是私有中断。
    以GEM0为例,UG1085的Table 13‐1提供的硬件中断号是89,Device Tree里的设备号是0x39(57),驱动程序里使用platform_get_irq(pdev, 0)获取软件中断号。

    VCU TRD 2020.2基于zcu106_llp2_xv20的PetaLinux工程里的GEM0的中断信息:

    		ethernet@ff0b0000 {
    			compatible = "cdns,zynqmp-gemcdns,gem";
    			interrupt-parent = <0x04>;
    			interrupts = <0x00 0x39 0x04 0x00 0x39 0x04>;
    		};
    

    UG1085的Table 13‐1里GEM0的硬件中断号
    MPSoC GEM0 Interrupt

    UG1085的Table 35‐6: PS-PL Interrupts Summary,使用的是Device Tree里的软件中断号。

    MPSoC PL-PS Interrupt

    需要更多信息,可以参考MPSoC Device tree interrupt number for PL-PS interrupt, Zynq-7000 mapping irq number into device tree value

    2. 扩展PL中断

    在FPGA(PL)部分,可以的扩展很多外部设备,比如串口、I2C、Can等。A53(PS)为PL的外部设备预留了16个中断,相关描述如下。

    PS-PL Interrupts
    The interrupts from the processing system I/O peripherals (IOP) are routed to the PL. In the 
    other direction, the PL can asynchronously assert 16 interrupts to the PS. These interrupts 
    are assigned a priority level routed to interrupt controllers which aggregate and route them 
    to appropriate processor. Additionally, FIQ/IRQ interrupts are available which are routed 
    directly to the private peripheral interrupt unit of the interrupt controller. Table 35-6 
    summarizes the interrupts.
    

    PL到A53(PS)的外部设备预留了16个中断,在Table 13‐1有如下表述。

    MPSoC PL-PS Interrupt

    VCU TRD 2020.2设计里,使用了很多PL中断。以Video Phy为例,在工程zcu106_llp2_xv20里,它连接到了PL中断的第3位(从0开始计数),对应的硬件中断号是124,减去32后是92(0x5c)。

    zcu106_llp2_xv20 PL Interrupt

    在以zcu106_llp2_xv20为硬件工程编译的PetaLinux工程里,Video Phy的中断信息如下,确实是0x5c。

    	vid_phy_controller@a0130000 {
    		compatible = "xlnx,vid-phy-controller-2.2xlnx,vid-phy-controller-2.1";
    		interrupt-names = "irq";
    		interrupt-parent = <0x04>;
    		interrupts = <0x00 0x5c 0x04>;
    
    	};
    

    3. 扩展AXI Intc中断

    有时候,PL-PS的中断还不够用。这时可以使用Xilinx的axi_intc(AXI Interrupt controller)做扩展。Xilinx Wiki网站上的文章Cascade Interrupt Controller support in DTG有详细描述。

    总结起来,有下面三步。

    3.1. AXI Intc PL连接

    在PL设计里添加axi_intc(AXI Interrupt controller),把axi_intc的中断输出连接到GIC的PL中断输入,把其它外设的中断输出连接到axi_intc的中断输入。

    3.2. AXI Intc Device Tree

    然后在Device Tree里,声明axi_intc的输出在GIC的中断号。

    axi_interrupt-controller {
    interrupt-parent = "gic"
    interrupts = <0 89 1>;
    }
    

    3.3. AXI Intc外设的Device Tree

    外设的Device Tree里,需要声明interrupt-parent是axi_intc,并声明它在axi_intc内部的中断号。interrupt-parent后面的字符串,是Device Tree里axi_intc里的标号。如果有多个axi_intc,每个axi_intc的标号(Label)不一样。每个外设的Device Tree里,需要指定自己对应的axi_intc的标号(Label)。

    axi_gpio {
    interrupt-parent = "axi_intc";
    interrupts = <0 1>;
    }
    

    axi_intc的文档,也可以参考 Xilinx Interrupt Controller

    4. 扩展MIO中断

    下面整合之前的文章,通过MIO接入外设中断

    Zynq-7000和MPSoC有很多MIO管脚。如果外设有中断,也可以通过MIO连接中断。这时候,MIO作为GPIO控制器,加载GPIO驱动。下面的描述中,GPIO就是MIO对应的GPIO设备。

    4.1. GPIO中断控制器

    按下列模式,在GPIO的设备树里声明为中断控制器

    &gpio0 {
    #interrupt-cells = <2>;
    interrupt-controller;
    };

    GPIO的中断说明,在Linux的文件Documentation/devicetree/bindings/gpio/gpio-zynq.txt里。主要内容如下:

    - interrupt-controller   : Marks the device node as an interrupt controller.
    - #interrupt-cells : Should be 2.  The first cell is the GPIO number.
                           The second cell bits[3:0] is used to specify trigger type and level flags:
                               1 = low-to-high edge triggered.
                               2 = high-to-low edge triggered.
                               4 = active high level-sensitive.
                               8 = active low level-sensitive.
    
    

    4.2. 外设使用GPIO中断控制器

    外设的设备树里,添加下列行,声明gpio0为自己的中断控制器,并声明对应的MIO引脚和中断内心。

    touchscreen@0 {
    interrupt-parent = <&gpio0>;
    interrupts = <52 2>; /* MIO 52, falling edge */
    };

    5. 检查Linux中断信息

    Linux在/proc/interrupts文件里,提供了系统的中断信息。使用命令“cat /proc/interrupts”,可以显示软件中断号、中断在各CPU发生的次数、中断所属中断控制器名称、硬件中断号,驱动程序名称。
    读“/proc/interrupts”的内容时,会调用kernelirqProc.c中的函数int show_interrupts(struct seq_file *p, void *v)。

    下面是一个例子。

    root@zcu106_vcu_llp2_nv16:~# cat /proc/interrupts
               CPU0       CPU1       CPU2       CPU3
      3:      18945       9421      13324      23628     GICv2  30 Level     arch_timer
      6:          0          0          0          0     GICv2  67 Level     zynqmp_ipi
     12:          0          0          0          0     GICv2 155 Level     axi-pmon, axi-pmon
     13:          0          0          0          0     GICv2 156 Level     zynqmp-dma
     14:          0          0          0          0     GICv2 157 Level     zynqmp-dma
     15:          0          0          0          0     GICv2 158 Level     zynqmp-dma
     16:          0          0          0          0     GICv2 159 Level     zynqmp-dma
     17:          0          0          0          0     GICv2 160 Level     zynqmp-dma
     18:          0          0          0          0     GICv2 161 Level     zynqmp-dma
     19:          0          0          0          0     GICv2 162 Level     zynqmp-dma
     20:          0          0          0          0     GICv2 163 Level     zynqmp-dma
     21:          0          0          0          0     GICv2 164 Level     Mali_GP_MMU, Mali_GP, Mali_PP0_MMU, Mali_PP0, Mali_PP1_MMU, Mali_PP1
     22:          0          0          0          0     GICv2 109 Level     zynqmp-dma
     23:          0          0          0          0     GICv2 110 Level     zynqmp-dma
     24:          0          0          0          0     GICv2 111 Level     zynqmp-dma
     25:          0          0          0          0     GICv2 112 Level     zynqmp-dma
     26:          0          0          0          0     GICv2 113 Level     zynqmp-dma
     27:          0          0          0          0     GICv2 114 Level     zynqmp-dma
     28:          0          0          0          0     GICv2 115 Level     zynqmp-dma
     29:          0          0          0          0     GICv2 116 Level     zynqmp-dma
     31:        144          0          0          0     GICv2  95 Level     eth0, eth0
     33:        121          0          0          0     GICv2  49 Level     cdns-i2c
     34:        140          0          0          0     GICv2  50 Level     cdns-i2c
     35:          0          0          0          0     GICv2  42 Level     ff960000.memory-controller
     36:          0          0          0          0     GICv2  57 Level     axi-pmon, axi-pmon
     37:         43          0          0          0     GICv2  47 Level     ff0f0000.spi
     38:          0          0          0          0     GICv2  58 Level     ffa60000.rtc
     39:          0          0          0          0     GICv2  59 Level     ffa60000.rtc
     40:          0          0          0          0     GICv2 165 Level     ahci-ceva[fd0c0000.ahci]
     41:        232          0          0          0     GICv2  81 Level     mmc0
     42:        133          0          0          0     GICv2  53 Level     xuartps
     44:          0          0          0          0     GICv2  84 Edge      ff150000.watchdog
     45:          0          0          0          0     GICv2  88 Level     ams-irq
     46:         12          0          0          0     GICv2 154 Level     fd4c0000.dma
     47:          0          0          0          0     GICv2 151 Level     fd4a0000.zynqmp-display
     48:          0          0          0          0     GICv2 122 Level     xilinx_framebuffer
     49:          0          0          0          0     GICv2 141 Level     xilinx_framebuffer
     50:          0          0          0          0     GICv2 142 Level     xilinx_framebuffer
     51:          0          0          0          0     GICv2 143 Level     xilinx_framebuffer
     52:          0          0          0          0     GICv2 123 Level     xilinx-hdmi-rx
     53:          0          0          0          0     GICv2 121 Level     xilinx_framebuffer
     54:          1          0          0      42423     GICv2 125 Level     xilinx-hdmitxss
     55:          0          0          0      42426     GICv2 127 Level     xlnx-mixer
     56:         81          0          0          0     GICv2 126 Level     a00d0000.i2c
     57:          0          0          0          0     GICv2 139 Edge      a00d1000.sync_ip
     58:          4          0          0          0     GICv2 128 Level     a0200000.al5e, a0220000.al5d
     59:         16          0          0          0     GICv2 124 Level     xilinx-vphy
     60:          0          0          0          0     GICv2  97 Level     xhci-hcd:usb1
    IPI0:      2763       1869       2597       1312       Rescheduling interrupts
    IPI1:        21         26         19         36       Function call interrupts
    IPI2:         0          0          0          0       CPU stop interrupts
    IPI3:         0          0          0          0       CPU stop (for crash dump) interrupts
    IPI4:         0          0          0          0       Timer broadcast interrupts
    IPI5:         0          0          0          0       IRQ work interrupts
    IPI6:         0          0          0          0       CPU wake-up interrupts
    

    从上面打印信息,也可以看到硬件中断号、软件中断号(逻辑中断号)不一样。

    目录/proc/irq下面会为每个rq创建一个以irq编号为名字的子目录。每个子目录最重要的文件是smp_affinity。通过更改smp_affinity的值,可以更改处理中断的CPU。比如下面缺省情况下,读出来中断59的smp_affinity是f,对应2进制1111,表示四个处理器都能处理中断59。后来执行命令“echo 2 > /proc/irq/59/smp_affinity”,把其改为2,就只有CPU-1能处理中断59。

    root@zcu106_vcu_llp2_nv16:~# ls /proc/irq/48 -l
    total 0
    -r--r--r--    1 root     root             0 Apr 28 06:54 affinity_hint
    -r--r--r--    1 root     root             0 Apr 28 06:54 effective_affinity
    -r--r--r--    1 root     root             0 Apr 28 06:54 effective_affinity_list
    -r--r--r--    1 root     root             0 Apr 28 06:54 node
    -rw-r--r--    1 root     root             0 Apr 28 06:25 smp_affinity
    -rw-r--r--    1 root     root             0 Apr 28 06:54 smp_affinity_list
    -r--r--r--    1 root     root             0 Apr 28 06:54 spurious
    dr-xr-xr-x    2 root     root             0 Apr 28 06:54 xilinx_framebuffer
    
    root@zcu106_vcu_llp2_nv16:~# ls /proc/irq/59 -l
    total 0
    -r--r--r--    1 root     root             0 Apr 28 06:54 affinity_hint
    -r--r--r--    1 root     root             0 Apr 28 06:54 effective_affinity
    -r--r--r--    1 root     root             0 Apr 28 06:54 effective_affinity_list
    -r--r--r--    1 root     root             0 Apr 28 06:54 node
    -rw-r--r--    1 root     root             0 Apr 28 06:54 smp_affinity
    -rw-r--r--    1 root     root             0 Apr 28 06:54 smp_affinity_list
    -r--r--r--    1 root     root             0 Apr 28 06:54 spurious
    dr-xr-xr-x    2 root     root             0 Apr 28 06:54 xilinx-vphy
    root@zcu106_vcu_llp2_nv16:~# cat /proc/irq/59/smp_affinity
    f
    root@zcu106_vcu_llp2_nv16:~# echo 2 >  /proc/irq/59/smp_affinity
    root@zcu106_vcu_llp2_nv16:~# cat /proc/irq/59/smp_affinity
    2
    root@zcu106_vcu_llp2_nv16:~# echo 4 >  /proc/irq/59/smp_affinity
    root@zcu106_vcu_llp2_nv16:~# cat /proc/irq/59/smp_affinity
    4
    

    Linux的中断信息,可以参考问 Linux 中断和smp_affinity, Linux 中断和 IRQ 调节

  • 相关阅读:
    《C程序设计语言》练习1-10
    《C程序设计语言》练习 1-8,1-9
    被这个C程序折腾死了
    《C程序设计语言》练习 1-6,1-7
    利用圆解一元二次方程
    三角插值的 Fourier 系数推导
    利用离散 Fourier 变换解一元二次方程
    关于selenium IDE找不到元素
    【★】深入BGP原理和思想【第一部】
    【★】深入BGP原理和思想【第一部】
  • 原文地址:https://www.cnblogs.com/hankfu/p/14714317.html
Copyright © 2011-2022 走看看