This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

将Hyperlink和pcie合在一起之后,Pcie无法响应MSI中断



我将Hyperlink工程和基于BIOS的PCIE工程合在一起用来测试我板卡上的DSP1和DSP2之间的通信,板卡上总共有4个DSP。DSP1首先通过Hyperlink往DSP2发送数据,DSP2响应到Hyperlink中断后,将数据搬移到DDR3 0xc0000 0000开始的地址,数据总共1GB。DSP2将数据接收完之后,通过PCIE返回给DSP1,双方的链路都连通了,DSP1的PCIE 接收buffer也有数据,但是DSP1没有响应中断,而是停在了图片中所示的位置,这个地址是属于csl_vect段,该段是给hyperlink分配的,所以我在想是不是Hyperlink 和pcie的中断是不是有什么冲突,求大神解决一下。

  • Hi Chuanjiang,

                  CSL的intc模块不能和BIOS的中断管理共同使用。 您需要把Hyperlink工程中的Intc中断管理代码改为让BOIS统一管理。

  • 可是应该怎么改呢,给Hyperlink建立一个HWI?能不能给我说详细一点,或者有一个基于BIOS版本的Hyperlink的例程让给我参考一下。谢谢了

  • cuanjiang,

                   您把CSL Intc相关代码都屏蔽掉。 假设Hyperlink工程中使用了中断4,中断函数为Hyperlink_ISR。 您参照PCIe BOIS工程的模式,把这个中断函数挂到BOIS的HWI上。

  • Jane Lu,

            谢谢您的回复!我按照你的思路尝试了修改,可是发觉了一个问题,Pcie是一级中断,一级事件直接触发corepac,比较容易设置,但是hyperlink没有触发核0的一级中断事件,我就无从下手了。我想知道对于Hyperlink这种二级事件,如何利用BIOS进行设置,还有就是设置hyperlink中断寄存器的代码不应该被屏蔽吧。我把工程发给你,你帮我看看Hyperlink那部分该怎么改吧,谢谢了!

            

    multi_test_send_dsp1_1[3].rar
  • Chuanjiang,

                 由于我的BOIS版本问题以及您提供的工程还缺少一些链接文件,我这边不能直接改一个能编译的工程给您,抱歉。

                  我看了一下您的工程,有三个地方用到了中断:

                   SRIO, 使用了4号中断,采用手动方式,软件代码直接写中断向量表:  VEC_ENTRY   SRIO_Doorbell_ISR   //(vectors.asm)

                   PCIe, 使用了5号中断, 采用BOIS的Hwi_create()来初始化中断

                   Hyperlink, 中断号是hyplnk_EXAMPLE_COREPAC_VEC, 使用了intc模块来管理中断。

                  通常,一个工程最好用一种方式管理中断,不然不同方式同时使用,会有冲突问题。

                  假设手动直接写中断向量表的方式,您可以参考下面的代码:

    a)  这段代码初始化SRIO, PCIE, Hyperlink的事件到4,5,6号中断。 您也可以根据需要将其拆成3个函数,注意INTMUX1 寄存器,IER等寄存器的赋值在3个函数中不要覆盖,需采用“或”方式

           代码中用到的函数以及全局变量您可以参考STK软件包的common文件。  http://www.deyisupport.com/question_answer/dsp_arm/c6000_multicore/f/53/t/47664.aspx?pi2132219853=1

    int uiHyLink_pend_host_event_num;

    void SRIO_PCIe_Hyperlink_Interrupts_Init(void)
    {
     /* Disable Global host interrupts. */
     gpCIC0_regs->GLOBAL_ENABLE_HINT_REG= 0;
        /* Modify this event number if it is not on Shannon DSP */
     uiHyLink_pend_host_event_num= 33;

     /*map HyperLink Interrupt events (111) to CIC0 out33*/
     KeyStone_CIC_event_map(gpCIC0_regs, CSL_INTC0_VUSR_INT_O, 33);

     /* Enable Global host interrupts. */
     gpCIC0_regs->GLOBAL_ENABLE_HINT_REG= 1;

     /* on Shannon, CIC0 out33 event number are 22 on core0  
     map this event 22 to INT6 */
     /* map PCIe MSI event to INT5 */
     /*map SRIO doorbell interrupts to INT4 */
     CGEM_regs->INTMUX1 =
      (CSL_GEM_INTDST_N_PLUS_16<<CSL_CGEM_INTMUX1_INTSEL4_SHIFT)
      |(CSL_GEM_PCIEXPRESS_MSI_INTN<<CSL_CGEM_INTMUX1_INTSEL5_SHIFT)
      |(22<<CSL_CGEM_INTMUX1_INTSEL6_SHIFT);
     
      /*Clear all DSP core events*/
     CGEM_regs->EVTCLR[0]=  0xFFFFFFFF;
     CGEM_regs->EVTCLR[1]=  0xFFFFFFFF;
     CGEM_regs->EVTCLR[2]=  0xFFFFFFFF;
     CGEM_regs->EVTCLR[3]=  0xFFFFFFFF;

     //clear DSP core interrupt flag
     ICR= IFR;

     //enable INT4, 5
     IER = 3|(1<<4)|(1<<5)|(1<<6);//

     /*Interrupt Service Table Pointer to begining of LL2 memory*/
     ISTP= 0x800000;

     //enable GIE
     TSR = TSR|1;

     interrupt_cfg.interrupt_map = interrupt_map;
     interrupt_cfg.uiNumInterruptMap =
      sizeof(interrupt_map)/sizeof(SRIO_Interrupt_Map);

     /*interrupt rate control is not used in this test*/
     interrupt_cfg.interrupt_rate= NULL;
        interrupt_cfg.uiNumInterruptRateCfg= 0;

     interrupt_cfg.doorbell_route_ctl= SRIO_DOORBELL_ROUTE_TO_DEDICATE_INT;

     srio_cfg.interrupt_cfg = &interrupt_cfg;

    }

     

    b)  把BIOS相关的Hwi_create()代码屏蔽,Hyperlink部分的hyplnkExampleInstallIsr()代码也可屏蔽。 如果采用上面这个初始化代码,SRIO部分的SRIO_Interrupts_Init()也屏蔽掉。

    c) 中断服务程序增加interrupt关键字

    //void hyplnkExampleIsr (void *eventId)

    interrupt  void hyplnkExampleIsr()

    //void hwi_isr(UArg arg) {

    interrupt void  PCIe_isr()

    d) vectors.asm 文件中,增加5,6号中断的ISR程序:

    vectors:
     VEC_RESET _c_int00       ;RESET
     VEC_DUMMY      ;NMI/Exception
     VEC_DUMMY     ;RSVD
     VEC_DUMMY     ;RSVD
     VEC_ENTRY       SRIO_Doorbell_ISR  ;interrupt 4
     VEC_ENTRY         PCIe_isr ;interrupt 5
     VEC_ENTRY       hyplnkExampleIsr ;interrupt 6
     VEC_DUMMY        ;interrupt 7
     VEC_DUMMY       ;interrupt 8
     VEC_DUMMY     ;interrupt 9
     VEC_DUMMY     ;interrupt 10
     VEC_DUMMY     ;interrupt 11
     VEC_DUMMY     ;interrupt 12
     VEC_DUMMY     ;interrupt 13
     VEC_DUMMY     ;interrupt 14
     VEC_DUMMY     ;interrupt 15
     
     .end
     

     

  • Jane Lu,

              我 根据您给我的回复对程序进行了修改,我没有将上述中断初始化代码拆成3个函数,而是在SRIO、Hyperlink、Pcie子函数里面都调用了该初始化函数对中断进行了初始化。现在遇到了一个问题,Hyperlink可以正常的接受中断、搬移数据,PCIE RC(DSP1)端可以响应中断但是无法正常的接受数据,DSP2和DSP1代码停留在了下面截图所示的位置,我不知道为何如此,需要您的帮助,谢谢!

  • Chuanjian,

                请把DSP1和DSP2的寄存器值都提供一下。

                从DSP2的PC值上看,它响应中断14, 您查一下中断14有没有使能,是哪个事件路由到14号中断。

                 关于DSP1不能正常收数据,能具体描述一下现象吗?

  • Jane Lu,

            谢谢您的回复!

            你说的DSP1和DSP2的寄存器值指的是什么寄存器的值啊?

            我查看了中断14,发现其并没有使能,也没有事件路由到上面,在.asm文件中14号是被设置成了DUMMY的。我将中断服务程序分配到了.vecs_all段中,但是我查看.map文件时发现除了.vecs_all段还有.csl_vect以及.vect我不知道这两个段是如何出现的有什么作用,会不会对中断产生影响。在PCIE的代码中,我只是将HWI_create()相关代码去掉了,依然使用BIOS创建了名为getlink()的函数,在该函数中进行中断和数据的发送。DSP1不能正常接收数据的现象是它进入了中断服务函数Pcie_isr()中,但是一直停留在pcie_recv()函数中的CAHE_invL2()子函数中的最后一行代码,无法跳出。你可以查看一下之前我给你发送的工程代码就知道了。

  • Chuanjiang,

                    您把两个DSP的view->register->control Register 提供一下。

                    关于DSP1停留在pcie_recv()函数中的CAHE_invL2()子函数中的最后一行代码,无法跳出, 您把这个DSP的core register也提供一下。

  • Jane LU,

              对于之前遇到的DSP2停留在.asm INT14代码行的问题,我把.cfg文件中所有关于BIOS的代码都隐掉之后问题解决了。但是现在又遇见一个新的问题,就是PCIE RC端(DSP1)有时能正确响应中断搬移数据,有时却不能,不能时会停留在pcie_isr()函数的子函数pcie_recv()函数的CACHE_invL2()子函数或者CACHE_invL1()子函数,见附图所示,DSP1的core register也如附图所示。我不知道这是不是cache一致性引起的问题,需要您的帮助,谢谢!!

  • 您好,

                   从PC指针所在位置看,是cache回写没有结束。 您查一下hCache的回写地址和长度,是否正常。 您再查一下堆栈有没有溢出。

                  另外 没有看到view->register->control Register 的值,请提供一下。

  • Jane Lu,

              问题已经解决了,是PCIE两端没有匹配好的问题。谢谢你的答复!!