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.

PCIE问题

Other Parts Discussed in Thread: TMS320C6678

调用K1STK这个文件夹下的KeyStone的PCIE例程实现两片TMS320C6678进行通信。EP端可以发送中断给RC,要是让RC给EP端发中断,在这个例程基础上如何修改?文档里面只是简单地说了一句RC可以给EP发中断,但是并没有详细的说。还望高人指点。

  • EP给RC发中断是PCIE协议要求的,协议中也规定了实现流程,STK提供了相应示例。

    而PCIE协议没有要求RC给EP发中断,不过KeyStone作为EP时如果gpPCIE_app_regs->MSI_IRQ寄存器被写的话也可以触发中断。所以,只要RC可以写到EP的gpPCIE_app_regs->MSI_IRQ寄存器就可以。

  • 首先。RC如果往EP端的gpPCIE_app_regs->MSI_IRQ这个寄存器里写数据,这个是通过远端访问的吗?还是通过outbound的方式去触发它。这是第一个问题。我看那个EP给RC的中断在STK里面是通过outbound触发的。那我这个RC给EP是直接写?还是通过什么机制给它写。第二个问题是写什么?往这个寄存器里随意写吗?第三个问题是我用不用做这个中断的初始化,还是直接将那个PCIE的一级中断挂到那14个可用中断上,然后修改一下.asm文件里面的内容就可以,还是它的中断是二级中断吗?要用CIC和INTC去转一下吗,谢谢

  • 首先。RC如果往EP端的gpPCIE_app_regs->MSI_IRQ这个寄存器里写数据,这个是通过远端访问的吗?还是通过outbound的方式去触发它。这是第一个问题。我看那个EP给RC的中断在STK里面是通过outbound触发的。那我这个RC给EP是直接写?还是通过什么机制给它写。第二个问题是写什么?往这个寄存器里随意写吗?第三个问题是我用不用做这个中断的初始化,还是直接将那个PCIE的一级中断挂到那14个可用中断上,然后修改一下.asm文件里面的内容就可以,还是它的中断是二级中断吗?要用CIC和INTC去转一下吗,谢谢

  • RC如果往EP端的gpPCIE_app_regs->MSI_IRQ这个寄存器里写数据,是通过outbound窗口直接写。可以把RC的一个outbound region映射到EP的BAR0,而gpPCIE_app_regs->MSI_IRQ在EP的BAR0的空间内。

    不论是RC还是EP模式,KeyStone一共支持32个MSI中断(参见PCIE user guide 的 Table 2-10 PCIESS Interrupt Events),中断路由的配置也一样。

    区别在于,RC往EP写可以是0~31之间的任意值;而EP往RC写时需遵循PCIE协议规定的中断号分配和使用机制。

     

  • 好的我明白了,那也就是我的RC的一个outbound region专门做成发送中断的,在EP端的Inbound时候把BAR0还有BAR0 MASK配置好,使他能收到这个outbound的地址。然后在IB_offset这个寄存器把偏移地址改成是0x21800054,就可以收到RC写来的数据了。在中断服务函数直接置标记位就可以了是吧。那EP端的中断直接把CSL_GEM_PCIEXPRESS_MSI_INTN这个事件挂到4号中断就可以接收到了吧?

  • 你的理解基本正确。

    不过BAR0的inbound映射是固定的(直接映射到gpPCIE_app_regs),不可配。

    所以你在RC端访问寄存器的地址应该是(BAR0 对应的outbound region起始地址)+(MSI_IRQ在gpPCIE_app_regs中的偏移)

  • 谢谢,那我可不可以这么理解,BAR0是专门用来传输中断信号的呢,因为PCIE的文档里面说的是BAR0和MSI_IRQ有着关系。那我就认为是BAR0是专门用来接收中断的可以吗?

  • BAR0的Inbound是固定的,那也就是说我在IB_OFFSET这个寄存器里面随便写个地址就可以。他对我BAR0的接收中断不影响。我在RC端配置的outbound region的起始地址只要和我的EP端BAR0的地址对上,然后设置好MASK。RC端只要往你说的那个地址随便写个数就可以了是吧,EP端就会收到我的中断?

  • BAR0是专门用来访问gpPCIE_app_regs的,其中包括MSI_IRQ。

    IB_OFFSET和BAR0的inbound映射没有关系,IB_OFFSET是用来设置其它BAR的inbound映射的.

  • 那您看我这样配置EP是否可以收到RC的中断。首先RC端outbound的配置是:OB_SZIE = 8M ,OB_OFFSET_INDEX0 = 0X20000001(最后一位是使能region0的),然后EP端的配置是BAR0 = 0X20000000。BAR0的MASK配置成0x7FFFFF。IB_BAR0 = 0,IB_START0_LO = 0X20000000,IB_OFFSET0 = 任意值(这个不影响)。然后EP端中断的初始化直接用的是STK里面的PCIE工程的Keystone_Interrupt_Init()这个,EP端的中断应该也是直接挂到4号中断就可以了吧。也就是CSL_GEM_PCIEXPRESS_MSI_INTN<<CSL_CGEM_INTMUX1_INTSEL4_SHIFT,然后在RC端的位置是我往0X60000000 + (((Uint32)&gpPCIE_app_regs->MSI_IRQ)-(Uint32)gpPCIE_app_regs)这个位置随便写个数字。然后它就会路由到PCIE的地址0x20000054这个位置,然后EP端通过BAR配置好应该就可以接收到了吧。我在中断服务函数里面置标记位,发现标记为没被置上,我这样的配置对不对啊

  • 1, 以下配置不需要因为BAR0到gpPCIE_app_regs的映射是硬件固定的,我不确定你的配置会不会画蛇添足,所以建议去掉。

    IB_BAR0 = 0,IB_START0_LO = 0X20000000,IB_OFFSET0 = 任意值。

    2,参见PCIE user guide 的 Table 2-10 PCIESS Interrupt Events,不是每个MSI中断事件都直接送到所有的核。比如,直接送到核0的只有MSI事件0,8,16和24.

  • 那就是说我要是往1核写中断应该是只能写1,9,17,25这个中断事件吗?是把这些数字往EP端的MSI_IRQ里写还是随便写都能触发。写过去了就能进中断服务函数吗?用不用去看看MSI_IRQx_STATUS这个寄存器呢?

  • 往EP端的MSI_IRQ里写1,9,17,25就可以触发EP的1核中断.

    中断相关的配置和处理照STK例程做就可以了.

  • Brighton Feng您好,昨天我按照你的意思试了一下我写的中断,还是没送过去(两片DSP之间的通信),我给你说一下我详细的配置,你看一下哪里有毛病。我在RC端的配置是OB_OFFSET_INDEX0 = 0x20000001(使能region0。)EP端的BAR0的值是0x20000000。然后像您说的其他地址映射我也没配,您说它是直接映射过去的。其他的中断设置还有中断服务函数我也没动。然后我在主程序上来就是RC端向EP端写中断,我分别用了以下这些方式:

    *((Uint32*)(CSL_PCIE_REGS+((Uint32)&gpPCIE_app_regs->MSI_IRQ)-(Uint32)gpPCIE_app_regs))=9;(写9的原因是EP端跑的1核,CSL_PCIE_REGS这个值是0x60000000)
    *((unsigned int *)(0x60000054)) = 9;
    *((unsigned int *)(0x60000000) + 84) = 9;(写84是因为0x54是84)
    *((volatile uint32_t *)(0x60000000) + 84) = 9;

    然后EP端上来就是死循环查询中断标志,

    while(1)
    {
    if(1 == gudInterruptFlag)
    break;
    }

    但是没有收到中断,后来我想是不是因为没有

    KeyStone_PCIE_RC_MSI_allocate((PCIE_MSI_Regs *)&(gpPCIE_remote_EP_regs->MSI_CAP),
    0x20000000+((Uint32)&gpPCIE_app_regs->MSI_IRQ)-(Uint32)gpPCIE_app_regs);

    KeyStone_PCIE_generate_MSI(1,
    (Uint32*)(CSL_PCIE_REGS+((Uint32)&gpPCIE_app_regs->MSI_IRQ)-(Uint32)gpPCIE_app_regs));

    这两句,我就把这两句加上了,但是还是没有进中断,可能是我这两句改的也不对,具体的我把我的工程发给您,还得麻烦您帮我看下。后来我想是不是我得先找个地址开辟region0啊,就是说我在(0x80000000+(MSI_IRQ的偏移))往这个地址里面写1或者9。相当于我是用0x80000000开辟了region0,然后再去映射的。想得到您的回复


    PCIE.rar
  • 以下两种写法是对的:

    *((Uint32*)(CSL_PCIE_REGS+((Uint32)&gpPCIE_app_regs->MSI_IRQ)-(Uint32)gpPCIE_app_regs))=9;(写9的原因是EP端跑的1核,CSL_PCIE_REGS这个值是0x60000000)
    *((unsigned int *)(0x60000054)) = 9;

    KeyStone_PCIE_RC_MSI_allocate() 和KeyStone_PCIE_generate_MSI()是用来实现PCIE协议要求的EP到RC的中断,与你现在要实现的功能无关。

    建议你分两步来定位:

    1,RC能正确读写gpPCIE_app_regs

    运行程序后,检查相关寄存器:EP的MSI_IRQ,BAR0;RC的outbound region寄存器...

    2,中断被触发

    运行程序后,检查相关寄存器:gpCGEM_regs->EVTFLAG, IFR, IER...

  • 收到您的回复谢谢,那也就是不用80000000这个位置的28到24bit选region了是吗?文档上说internal address是用来选择开辟哪个region的。那这个internal address是我发送数据的源地址呢还是我的PCIE的窗口地址(0x60000000到0x6FFFFFFF)。打个比方,对于region1来说,我是用0x80800000还是用0x60800000来选择开辟region1啊

  • 如果outbound region的大小是8MB的话,region1的起始地址就是0x60800000

  • 那与我的internal地址有关系吗?internal地址是可以随便用的吗,就是我从第一个DSP到第二个DSP传输数据的源地址

  • 不太明白你的问题,你是问的一个新问题吗?

    之前讨论的中断问题就一次写操作*((unsigned int *)(0x60000054)) = 9;和其它的地址没有关系。写操作既把一个常数写到一个目的地址,不需要源地址啊。

     

  • 哦好的,我知道了谢谢您