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.

AM2434: PCIE failed to configure Region Window size. Failed to transfer 16K data.

Part Number: AM2434

Hi Team,

This is FAE Jayden, my customer O-NET encountered the following problems when using PCIE to output 16K data. Please help to check whether the configuration method is correct and whether there is a reference demo.

Pls refer to the attachment below for details. Thanks.

PCIE addressing range configuration issues.docx

Brs

Jayden

  • Pls help improve the priority due to the urgency of the project. Many Thanks.

  • Hello Jayden,

    in general you can have up to six BARs on the EP (inbound address translation) of various sizes, as long as the size is a power of two, and the addresses are aligned to the size. Alignment is required both for the base address and the target address, for both inbound and outbound mappings.

    The RC can have only two BARs, but in addition passes through any transaction that doesn't match a bar.

    It's not fully clear to me what they're trying to do here, but my first guess regarding their immediate issue would be that the EP's IOmap_BufferRecv array isn't aligned on 4KB. Maybe they could start by checking the address of this array in the EP's local memory.

    Best Regards,

    Dominic

  • Hi Dominic,

    Thanks for your reply! 

        1.The project needs to implement two functions, so you need two bars, the first one is 0x0000~0x01000, and the other is 0x4000~0x7000.
        2.The receive buffer is aligned with the keyword __attribute__((aligned(4096)) and should already be aligned. However, the buffer in the address range 0x4000 to 0x7000 still appears, and only part of the data can be received.
        3.Attach the code for the test.

  • Hi Dominic,

    Thanks for your reply! 

        1.The project needs to implement two functions, so you need two bars, the first one is 0x0000~0x01000, and the other is 0x4000~0x7000.
        2.The receive buffer is aligned with the keyword __attribute__((aligned(4096)) and should already be aligned. However, the buffer in the address range 0x4000 to 0x7000 still appears, and only part of the data can be received.
        3.Attach the code for the test.

    //recieve 
    
    #include <string.h>
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <kernel/dpl/DebugP.h>
    #include <drivers/soc.h>
    #include <drivers/pcie.h>
    
    #include "IOmap_Post.h"
    #include "IOmap_Buffer.h"
    
    
    /******** Buffer *******/
    #define BUF_SIZE            (0x1000/4)
    #define IOMAP_BUFFER_SIZE   (0x3000/4)
    
    
    
    /**********************************************************************
     ********************** PEIC MAP  recv buffer**************************
     *********************************************************************/
    uint32_t IOmap_PostRecv[BUF_SIZE]  __attribute__((aligned(4096)));
    uint32_t IOmap_BufferRecv[IOMAP_BUFFER_SIZE]  __attribute__((aligned(4096)));
    
    /**********************************************************************
     ********************** PEIC MAP  send buffer**************************
     *********************************************************************/
    uint32_t IOmap_PostSend[BUF_SIZE]  __attribute__((aligned(4096)));
    uint32_t IOmap_BufferSend[IOMAP_BUFFER_SIZE]  __attribute__((aligned(4096)));
    
    
    static void Pcie_getRemoteVendor(void)
    {
        uint32_t devId = 0;
        uint32_t vndId = 0;
        int32_t status = 0;
    
        /* Get EP Device Id and Vendor Id */
        status = Pcie_getVendorId(gPcieHandle[CONFIG_PCIE0], PCIE_LOCATION_REMOTE, &vndId, &devId);
        if (SystemP_SUCCESS == status)
        {
            DebugP_log ("Endpoint Device ID: %XX\r\n", devId);
            DebugP_log ("Endpoint Vendor ID: %XX\r\n", vndId);
        }
        else
        {
            DebugP_logError ("Unable to read Endpoint Device & Vendor ID\r\n");
        }
    }
    
    
    static void Pcie_recvData(uint32_t *recvBuff, uint32_t recvLen)
    {
        CacheP_inv (recvBuff, recvLen, CacheP_TYPE_ALL);
    }
    
    static void Pcie_sendData(uint32_t *sendBuff, uint32_t sendLen)
    {
        void *transBufAddr = (void *)(CONFIG_PCIE0_OB_REGION0_LOWER);
    
        memcpy(transBufAddr, sendBuff, sendLen);
        CacheP_wbInv(transBufAddr, sendLen, CacheP_TYPE_ALL);
    }
    
    static void Pcie_sendData1(uint32_t *sendBuff, uint32_t sendLen)
    {
        void *transBufAddr = (void *)(CONFIG_PCIE0_OB_REGION1_LOWER);
    
        memcpy(transBufAddr, sendBuff, sendLen);
        CacheP_wbInv(transBufAddr, sendLen, CacheP_TYPE_ALL);
    }
    
    void pcie_Task(void *args)
    {
        rt_kprintf("Device in EP mode\r\n");
        //Pcie_getRemoteVendor();
    
        while(1)
        {
            Pcie_recvData(IOmap_PostRecv, sizeof(IOmap_PostRecv));
            Pcie_recvData(IOmap_BufferRecv, sizeof(IOmap_BufferRecv));
    
            rt_thread_delay(10);
        }
    
    }
    
    
    int Pcie_taskCreateInit(void)
    {
    
        rt_kprintf("Pcie_taskCreateInit!\r\n");
    
        if(pdTRUE != xTaskCreate((TaskFunction_t)pcie_Task,                         /* Pointer to the function that implements the task. */
                                 (const char*)"pcieTask",                           /* Text name for the task.  This is to facilitate debugging only. */
                                 (uint32_t)1024,                                    /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                 (void*)RT_NULL,                                    /* We are not using the task parameter. */
                                 (UBaseType_t)configMAX_PRIORITIES-3,               /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                 (TaskHandle_t*)NULL) )
        {
            while(1);
        }
    
    
        return 0;
    }
    INIT_APP_EXPORT(Pcie_taskCreateInit);

    //SEND
    
    #include <string.h>
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    #include <kernel/dpl/DebugP.h>
    #include <drivers/soc.h>
    #include <drivers/pcie.h>
    
    #include "IOmap_Post.h"
    #include "IOmap_Buffer.h"
    
    
    /******** Buffer *******/
    #define BUF_SIZE            (0x1000/4)
    #define IOMAP_BUFFER_SIZE   (0x3000/4)
    
    
    /**********************************************************************
     ********************** PEIC MAP  recv buffer**************************
     *********************************************************************/
    uint32_t IOmap_PostRecv[BUF_SIZE]  __attribute__((aligned(4096)));
    uint32_t IOmap_BufferRecv[IOMAP_BUFFER_SIZE]  __attribute__((aligned(4096)));
    
    /**********************************************************************
     ********************** PEIC MAP  send buffer**************************
     *********************************************************************/
    uint32_t IOmap_PostSend[BUF_SIZE]  __attribute__((aligned(4096)));
    uint32_t IOmap_BufferSend[IOMAP_BUFFER_SIZE]  __attribute__((aligned(4096)));
    
    
    static void Pcie_getRemoteVendor(void)
    {
        uint32_t devId = 0;
        uint32_t vndId = 0;
        int32_t status = 0;
    
        /* Get EP Device Id and Vendor Id */
        status = Pcie_getVendorId(gPcieHandle[CONFIG_PCIE0], PCIE_LOCATION_REMOTE, &vndId, &devId);
        if (SystemP_SUCCESS == status)
        {
            DebugP_log ("Endpoint Device ID: %XX\r\n", devId);
            DebugP_log ("Endpoint Vendor ID: %XX\r\n", vndId);
        }
        else
        {
            DebugP_logError ("Unable to read Endpoint Device & Vendor ID\r\n");
        }
    }
    
    
    static void Pcie_recvData(uint32_t *recvBuff, uint32_t recvLen)
    {
        CacheP_inv (recvBuff, recvLen, CacheP_TYPE_ALL);
    }
    
    static void Pcie_sendData(uint32_t *sendBuff, uint32_t sendLen)
    {
        void *transBufAddr = (void *)(CONFIG_PCIE0_OB_REGION0_LOWER);
    
        memcpy(transBufAddr, sendBuff, sendLen);
        CacheP_wbInv(transBufAddr, sendLen, CacheP_TYPE_ALL);
    }
    
    static void Pcie_sendData1(uint32_t *sendBuff, uint32_t sendLen)
    {
        void *transBufAddr = (void *)(CONFIG_PCIE0_OB_REGION1_LOWER);
    
        memcpy(transBufAddr, sendBuff, sendLen);
        CacheP_wbInv(transBufAddr, sendLen, CacheP_TYPE_ALL);
    }
    
    
    static void buffer_init(void)
    {
    	uint32_t ui = 0;
    	for(ui = 0; ui < BUF_SIZE; ui++)
    	{
    		IOmap_PostSend[ui] = 0xA5A55A5A;
    	}
    	
    	for(ui = 0; ui < IOMAP_BUFFER_SIZE; ui++)
    	{
    		IOmap_PostSend[ui] = 0xA5A55A5A;
    	}
    }
    
    
    void pcie_Task(void *args)
    {
        rt_kprintf("Device in RC mode\r\n");
    	
    	Pcie_getRemoteVendor();
    	buffer_init();
    	
        while(1)
        {
            Pcie_sendData(IOmap_PostSend, sizeof(IOmap_PostSend));
            Pcie_sendData(IOmap_BufferSend, sizeof(IOmap_BufferSend));
    
            rt_thread_delay(10);
        }
    
    }
    
    
    int Pcie_taskCreateInit(void)
    {
    
        rt_kprintf("Pcie_taskCreateInit!\r\n");
    
        if(pdTRUE != xTaskCreate((TaskFunction_t)pcie_Task,                         /* Pointer to the function that implements the task. */
                                 (const char*)"pcieTask",                           /* Text name for the task.  This is to facilitate debugging only. */
                                 (uint32_t)1024,                                    /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                 (void*)RT_NULL,                                    /* We are not using the task parameter. */
                                 (UBaseType_t)configMAX_PRIORITIES-3,               /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                 (TaskHandle_t*)NULL) )
        {
            while(1);
        }
    
    
        return 0;
    }
    INIT_APP_EXPORT(Pcie_taskCreateInit);
  • Hello Jayden,

    they need to align the IOmap_BufferRecv to 16 KB if they want to map that as a 16 KB BAR.

    Currently the address modulo 16KB should be 0x1000, i.e. for example 0x70005000 (you can check the .map file for the actual address). Attempting to map that address via a 16KB BAR actually maps starting at 0x70004000. If the RC then writes 16KB to that BAR it actually modifies the memory from 0x70004000 to 0x70007fff., but their buffer lies at 0x70005000 ot 0x70008fff. If they only look at buffer it seems as if only the first 12 KB of the buffer are being modified. They probably also corrupted the memory preceding that buffer.

    Regards,

    Dominic