目录

​​针对第二个问题(中断向量的读取)​​

​​MSI中断​​

​​直接写D或者RD地址空间的寄存器​​

​​ITS​​

​​ CPU 表侧​​

​​   物理设备侧​​

​​优先级的确定​​


问题

1) 单板打开中断路由,配置到不同的核上后,系统会挂住。

2) msi 中断ID cpu是否可以读取。

针对第二个问题(中断向量的读取)

1) 理论上讲 pcie endpoint写入 arm特定地址后,可以读出来,但是实际此地址是只写的。

如下 distributor寄存器描述,

ARM 中断_ci

但distributor到 pe还有 rd以及cpu interface 两个接口,如下面arm官网中的此经典图。

ARM 中断_arm_02

2) 我们再翻看cpu interface的寄存器描述,看到此处有个像是和中断向量相关的,看它的具体介绍为:

ARM 中断_嵌入式硬件_03

我们这里采用non-secure模式,因而实际的偏移量为0x0020这个寄存器

ARM 中断_寄存器_04

代码实现中 irqstat = get_ICC_IAR1(); 接口准确获取了中断号信息。

MSI中断

  在arm gic的msi消息中断实现中,存在两种方式

直接写D或者RD地址空间的寄存器

    这种方式配置比较简单,即将dirstributor中的 setspi_nsr的地址写入到endpoint pcie设备中即可,例如假如此dirstributor所在的地址空间为 0x29800000,setspi_nsr的偏移量为0x40,则将地址0x29800040写入到 enpoint pcie设备msi寄存器的addr字段,同时将中断向量(和具体cpu相关),例如100,写入到msi寄存器的data字段即可,使能msi,此后如果endpoint发生中断,则向cpu 的distributor 发送一个 包含此地址和数据的memory 写命令。cpu就可以处理了。

     整体如下:此处在调试时主要确认CPU采用中断号及d的基地址即可。

     

ARM 中断_stm32_05

ITS

   ITS的基本原理,上一张 arm官网文档中的图,

  

ARM 中断_寄存器_06

     根据这张图,主要分为两个大的部分,红线左侧与红线右侧。这里划分的依据主要在于

   --》左侧部分和硬件强相关

 --》 右侧部分主要为软件对表配置的准确性

 CPU 表侧

   在实际调试过程中,ITS提供了模拟产生中断的机制,可以代替硬件来产生中断,我们可以借此来划分问题的所在。

     模拟中断的ITS命令如下

       

ARM 中断_嵌入式硬件_07

    我们在实战中发现msi中断通过its方式没有到CPU,因而编写代码进行通过int模拟产生中断以划分问题所在。

   

LOCAL struct its_collection *its_build_int_cmd(struct its_cmd_block *cmd,
struct its_cmd_desc *desc)
{
struct its_collection *col;

col = dev_event_to_col(desc->its_inv_cmd.dev,
desc->its_inv_cmd.event_id);

its_encode_cmd(cmd, GITS_CMD_INT);
its_encode_devid(cmd, desc->its_inv_cmd.dev->device_id);
its_encode_event_id(cmd, desc->its_inv_cmd.event_id);
//这里我们打印出devid和eventid,以确认和采用和物理设备一样的ID信息。
printf("pending devid [0x%x] eventid[0x%x]\n",desc->its_inv_cmd.dev->device_id,desc->its_inv_cmd.event_id);

its_fixup_cmd(cmd);

return col;
}

   通过上述代码,测试发现可以正常产生中断,那么问题就在物理设备端了。

   物理设备侧

    its采用的lpi中断,不同于其他三种中断。

   基本原理: ITS收到 pcie endpoint的pcie报文信息,从中提前bus dev func作为devid索引,从配置表中索引出 event,进而查找到对应的中断ID,触发CPU。

   

ARM 中断_arm_08

  

ARM 中断_ci_09

   通过上图:

  在第2)步及之后,我们通过INT命令已经验证是正常的了。

  因而设备侧 出问题的地方:

1)cpu抓取的request id和表里面的不一致,这个只能PCIE分析仪跟踪。

2) msi地址和msi data不对。

       经过再次走读手册及代码,我们发现我们用的这款endpoint器件,其在生成msi memory 写的时候,pcie报文中封装的地址和data字段并不是从标准的msi 寄存器获取的,而是自己又定义了一套,也就是说这个设备即有标准msi寄存器,又有自定义的类msi寄存器。导致我们在配置及调试时走了一些偏差。

路由信息 

ARM 中断_arm_10

   通过上面这张图,可以看到its不经过distributor,那么这种的路由配置应该在ITS里面做的。

     针对走distributor的中断路由

      

ARM 中断_ci_11

 32-1019的中断向量,每个中断向量对应一个此64位大小的寄存器,如果想将某个向量路由到某个cpu上,则

  

*(volatile u64 *)(GICD_IROUTERn + int_id * 8) = core_id;

   

ARM 中断_嵌入式硬件_12

page 6736

ARM 中断_stm32_13

 

优先级的确定

  下图有个很大的隐含意思:即PPI和SGI离PE更近,他们的优先级的设定通过RD进行控制。

GICR_IPRIORITYR<n> is used instead of GICD_IPRIORITYR<n>
   where n = 0 to 7

以上两种类型的中断优先级比spi更高

ARM 中断_寄存器_14

​ARMv8 Virtualization Overview · kernelgo​

LPI寄存器说明

​ARM GIC(六)gicv3架构-LPI - 知乎 (zhihu.com)​