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 Self Test Kit的一些疑问

Other Parts Discussed in Thread: TMS320C6655

你好,目前小弟正学习PCIE的调试,有一下几点想请TI的技术大牛帮忙解释一下。

1.1 PCIE initialization process 

PCIE初始化

The PCIE initialization process in the STK is implemented to match real PCIE network initialization as much as possible. 

Following is the basic flow for RC and EP remote loopback test:

EP initializes BAR mask and properties, which indicates the PCI address space request to RC. In the STK, one BAR is initialized for prefetchable space, one BAR is initialized for non-prefetchable space.

EP 端步骤一:EP写BAR mask1010h,1014等)表示PCIe地址及空间大小的寄存器,提供给RC//实际操作中,我这个配置由LINUX端来完成,也能完成连接和数据收发

EP initializes MSI Capabilities Register, which indicates the number of interrupt vectors request to RC.

EP 端步骤二:EP写中断向量号到MSI_CAP(1050h寄存器,提供给RC。//实际上EP写了0x000B7005到1050h

EP starts physical link training, and waits for link training completion…

EP 端步骤三:EP启动物理链接训练,等待链接完成//实验结果,连接完成

RC initializes the base and limit of PCIE address space.

RC 端步骤四:初始化基地址和PCIE地址空间//实验结果,连接完成

RC starts physical link training, and waits for link training completion …

RC 端步骤五:RC开始物理链接训练,此时EP正在等待链接//实验结果,连接完成

RC reads BAR mask and properties from EP, allocates PCI address space accordingly, writes the PCI start address to the BAR register of EP, and then RC configures its own outbound memory regions to map the PCI address space to its own local access window.

RC 端步骤六:RC读取BAR mask(远程+1010h1014等),并分配地址空间。写PCI起始地址到EP端的BAR寄存器(300h-33ch),然后RC配置linux自身的outboud地址映射到本地存储空间//实验结果,连接完成

EP polls the BAR register value, once it gets valid PCIE address set by RC, EP configures its own inbound memory regions to map the PCI address space to its own local address space.

RC 端步骤七:EP端查询BAR寄存器(300h-33ch)的值,一旦有被RC配置,EP就设置自身的inbound地址映射到本地的存储空间//实验结果,连接完成

RC reads the MSI capabilities register of EP, allocates interrupt vectors accordingly, writes start index and number of the allocated interrupt vectors to EP MSI registers.

RC 端步骤八:RC读取MSI_CAP(远程1050h)寄存器的值,同时分配中断向量号,写start index(这个是什么?)和中断向量号到MSI_IRQ寄存器(远程054h)。//实验结果,未完成,不明白这一步RC如何操作。

1.1.1.1 EP to RC MSI interrupt test

EP发送MSI中断到RC

EP MSI interrupts are generated by a PCIe 32-bit memory write transaction from EP PCIE window to MSI_IRQ register in RC. To generate MSI interrupts, following steps need to be taken:

1. Ensure that the MSI support has been enabled in the device (Set MSI_EN bit in MSI Capabilities Register (MSI_CAP).)

确认MSI_CAP(1050h中的MSI_EN已经被使能//实测MSI_CAP = 0x00b70005

2. EP Reads the value of the MSI Data Register in the local PCIe configuration space and determines the number of MSI vectors allocated from RC, generates the MSI_DATA which will be used to write to MSI_IRQ

EP读取MSI_DATA105ch,这样EP就得到了RC的中断向量号,到时候产生中断就是将这个值写到MSI_IRQ054h)//失败,读上来的MSI_DATA值都是0

3. EP issues a memory write transaction to the RC MSI_IRQ register’s mapping address in EP’s outbound window. In RC, the access to MSI_IRQ goes through BAR0 with default mapping.

EP发布一个内存写传输中断到EP端的outbound,地址映射到RC 端的MSI_IRQ寄存器。//失败

In PCIE STK test, if RC runs on core 0, to generate MSI interrupt to core 0, the MSI_data is set as “8” (DNUM+8).

在PCIE STK测试中,EP要发送一个MSI中断到RCMSI_data(原105ch,不是64bit模式,1050h)需要被设置成8(DNUM+8)//这个MSI_data的设置由EP端来写还是RC写,什么时候写?DNUM是什么值?//失败


本人实际调试中,RC: Linux;   EP:TMS320C6655;平台:sys/bios。能正常完成数据收发,但无法完成MSI中断。

感谢解答

KeyStone_PCIE_STK_Guide解读.doc
  • 请问你的PCIe怎么调试的,插在PC机主板上了吗

  • 我是插在linux平台上主机上的

  • 您好,我现在想要调试PCIe遇到点麻烦,电脑主板上只有一个PCIe插槽并被显卡占用,市场上也找不到PCI转PCIe的转接板,请问您有什么好的建议吗?

  • MSI data reg可以通过RC端寄存器进行MSI alloation进行配置,如下是个例子(你也可以在置顶帖中下载Keystone STK包获得源代码)

    而配置原则就是EP端和RC端要协商好MSI interrupt number,如果你系统是LINUX,你需要直接加个代码进行这个配置。

    Uint32 uiMSI_index= 0; //index of the next free MSI vector
    /*PCIE MSI allocation for one device.
    msi_regs: pointer to remote configuration space. For loopback test, pointer to local bus space
    MSI_address: PCIE address for EP to write to generate MSI*/
    void KeyStone_PCIE_RC_MSI_allocate(PCIE_MSI_Regs * msi_regs,
    unsigned long long PCIE_MSI_address)
    {
    Uint32 MSI_CAP, uiNum_MSI_requested, uiNum_MSI_allocated;
    Uint32 MULT_MSG_EN;

    MSI_CAP= msi_regs->MSI_CAP;
    if(0==(MSI_CAP&CSL_PCIE_CFG_SPACE_ENDPOINT_MSI_CAP_MSI_EN_MASK))
    return; //MSI is not enabled in this device

    if(uiMSI_index>=32)
    {
    puts("all 32 MSI vector are used, no free MSI be allocated for this device!");
    msi_regs->MSI_CAP= MSI_CAP&(~CSL_PCIE_CFG_SPACE_ENDPOINT_MSI_CAP_MSI_EN_MASK);
    return;
    }

    //read number of the MSI vectors requested by EP
    uiNum_MSI_requested= 1<<((msi_regs->MSI_CAP
    &CSL_PCIE_CFG_SPACE_ENDPOINT_MSI_CAP_MULT_MSG_CAP_MASK)
    >>CSL_PCIE_CFG_SPACE_ENDPOINT_MSI_CAP_MULT_MSG_CAP_SHIFT);

    if(uiMSI_index+uiNum_MSI_requested>=32)
    uiNum_MSI_allocated= 32- uiMSI_index;
    else
    uiNum_MSI_allocated= uiNum_MSI_requested;

    //align to power of 2
    MULT_MSG_EN= 31 - _lmbd(1, uiNum_MSI_allocated);

    //write the number of the allocated vectors for the EP
    msi_regs->MSI_CAP= (MSI_CAP&(~CSL_PCIE_CFG_SPACE_ENDPOINT_MSI_CAP_MULT_MSG_EN_MASK))
    |(MULT_MSG_EN<<CSL_PCIE_CFG_SPACE_ENDPOINT_MSI_CAP_MULT_MSG_EN_SHIFT);

    //write the PCIE address for EP to write to generate MSI
    msi_regs->MSI_LOW32= _loll(PCIE_MSI_address);
    msi_regs->MSI_UP32 = _hill(PCIE_MSI_address);

    uiNum_MSI_allocated= 1<<MULT_MSG_EN;

    //align MSI index to the power of 2 boundary
    if(uiMSI_index&(uiNum_MSI_allocated-1))
    {
    uiMSI_index= (uiMSI_index+uiNum_MSI_allocated)&(~(uiNum_MSI_allocated-1));
    }

    //write the index of the first MSI allocation for the EP
    msi_regs->MSI_DATA= uiMSI_index;
    }