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.

TMDX654IDKEVM: How to read written data on PCIe EP side.

Part Number: TMDX654IDKEVM

Hello TI-Team.

I have currently one PCIe Root Complex connected to an PCie End Point with a Male-To-Male PCIe cable (both boards are the TMDX654IDKEVM and are running with the Linux SDK).

I am able to write data from RC side into a resource space of the EP. Now i was wondering how can i access on the data i have written on EP side. Is there a common way to read/write data on EP side? I have tried to access the /dev/mem, but i was not able to map the memory.

Thank you for your help!

Felix Windt

  • Dear TI-team,

    Felix is working for SE on an investigation for an PCIe as an fast interface on our next generation of product. Please provide a first guidance or reference as he is kind of blocked by this problem.

    Many thanks in advance.
    BR Joern Graewe

  • Hi Felix,

    1. Which linux-SDK version are you you using?

    2. How are you exactly trying to access the /dev/mem? Can you share the code snippet and the errno you receive?

    3. Can you please confirm the value of "CONFIG_STRICT_DEVMEM" Flag in [SDK-Directory]/board-support/linux-[version_string]/arch/arm64/configs/

    4. You can try the "devmem" or "hexdump" commands from command line.

    Regards,

    Tanmay

  • Hey Tanmay,

    thank you for your answer.

    1. I'm using the 07.03 linux-sdk version.

    2.1

    int PAGE_SIZE = 1;
    #define MAP_SIZE 1UL
    #define MAP_MASK (MAP_SIZE - 1)
    
    int main(int argc, char *argv[]) {
    
        void *map_base;
        off_t target = 0x10200000;
    
        int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
        map_base = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, target);
    
        if((unsigned long )map_base == -1) //prevent from Segmentaion fault
        {
            printf("mmap can't map memory\n");
            return 1;
        }
        
        printf("Memory mapped at address %p. \n", map_base);
        fflush(stdout);
    
        uint16_t* memory = (uint16_t*) map_base;
        
        printf("Value at address 0x%x: 0x%x\n", (unsigned int) target, memory[0]);
        fflush(stdout);
        
        munmap (map_base, MAP_SIZE);
        return 0;
    }

    2.2 On some addresses i get an "Unhandled Exception in EL3".

    Unhandled Exception in EL3.
    x30            = 0x00000000700054c0
    x0             = 0x0000ffff83af0400
    x1             = 0x0000ffff83af0000
    x2             = 0x0000000000000000
    x3             = 0x0000000000000000
    x4             = 0x00000000004009ec
    x5             = 0x00000000063f1eca
    x6             = 0x000000000000000a
    x7             = 0x000000000000000a
    x8             = 0x0000000000000040
    x9             = 0xffffff80ffffffc8
    x10            = 0x0000000000000000
    x11            = 0x0000ffffdbecc450
    x12            = 0x0000000000000001
    x13            = 0x0000000000000010
    x14            = 0x0000000000000000
    x15            = 0x0000000000000000
    x16            = 0x0000000000411030
    x17            = 0x0000ffff836d8528
    x18            = 0x0000000000000000
    x19            = 0x00000000004008f0
    x20            = 0x0000000000000000
    x21            = 0x00000000004006b0
    x22            = 0x0000000000000000
    x23            = 0x0000000000000000
    x24            = 0x0000000000000000
    x25            = 0x0000000000000000
    x26            = 0x0000000000000000
    x27            = 0x0000000000000000
    x28            = 0x0000000000000000
    x29            = 0x0000ffffdbecc560
    scr_el3        = 0x000000000000073d
    sctlr_el3      = 0x0000000030cd183f
    cptr_el3       = 0x0000000000000000
    tcr_el3        = 0x0000000080803520
    daif           = 0x00000000000002c0
    mair_el3       = 0x00000000004404ff
    spsr_el3       = 0x0000000080000000
    elr_el3        = 0x0000000000400858
    ttbr0_el3      = 0x0000000070010b00
    esr_el3        = 0x0000000092000010
    far_el3        = 0x0000ffff83af0400
    spsr_el1       = 0x0000000020000000
    elr_el1        = 0x0000ffff8374e3d0
    spsr_abt       = 0x0000000000000000
    spsr_und       = 0x0000000000000000
    spsr_irq       = 0x0000000000000000
    spsr_fiq       = 0x0000000000000000
    sctlr_el1      = 0x0000000034d4d91d
    actlr_el1      = 0x0000000000000000
    cpacr_el1      = 0x0000000000300000
    csselr_el1     = 0x0000000000000000
    sp_el1         = 0xffff800014110000
    esr_el1        = 0x0000000056000000
    ttbr0_el1      = 0x00000008c9160000
    ttbr1_el1      = 0x0cb6000080e00000
    mair_el1       = 0x0000bbff440c0400
    amair_el1      = 0x0000000000000000
    tcr_el1        = 0x00000032f5507510
    tpidr_el1      = 0xffff80086ebf0000
    tpidr_el0      = 0x0000ffff83b54400
    tpidrro_el0    = 0x0000000000000000
    par_el1        = 0x0000000000000000
    mpidr_el1      = 0x0000000080000100
    afsr0_el1      = 0x0000000000000000
    afsr1_el1      = 0x0000000000000000
    contextidr_el1 = 0x0000000000000000
    vbar_el1       = 0xffff800010081800
    cntp_ctl_el0   = 0x0000000000000005
    cntp_cval_el0  = 0x0000007f83e09994
    cntv_ctl_el0   = 0x0000000000000000
    cntv_cval_el0  = 0x0000000000000000
    cntkctl_el1    = 0x00000000000000d6
    sp_el0         = 0x0000ffffdbecc560
    isr_el1        = 0x0000000000000040
    dacr32_el2     = 0x0000000000000000
    ifsr32_el2     = 0x0000000000000000
    cpuectlr_el1   = 0x0000000000000040
    cpumerrsr_el1  = 0x000000001a10076e
    l2merrsr_el1   = 0x000000001320f5f0
    cpuactlr_el1   = 0x00001000090ca000

    We guessed that these errors occure when we try to map areas in /dev/mem with memory holes/leaks.
    On other addresses i get an "segmentation fault (core dumped)".

    But on a few i was able to read, but not on those addresses we need.

    3. "CONFIG_STRICT_DEVMEM" is set to "y"

    4. "devmem" does not exist on the board and with "hexdump" i get the following message.

    Regards,
    Felix

  • Hi Felix,

    "devmem" does not exist on the board

    Sorry, but it is "devmem2" command and not devmem. It is there in the linux file-system. Can you try that?

    Regards,
    Tanmay

  • Hi Tanmay,

    the devmem2 command exists. Thank you for the info.

    We were able to read into the BAR's of the Endpoint in his own physical memory, but the output was always 0xFFFFFFFF. (we also tried the other BAR addresses) Even if we wrote something beforehand from RC side or EP side into one of the BARs(shown in the picture down below), we were able to read nothing more than 0xFFFFFFFF.


    Our BAR addresses for the EP (found on RC side):


    Regards,
    Felix

  • Hi Tanmay,

    Do i have to translate the address in order to read something and if so, what do i need?
    Has the IB_OFFSET something to do with that?
    I read something about that in this and in this document

    Is there something on EP side, which shows me the BARs?

    Regards,
    Felix

  • Felix, 

    I am trying to follow the discussion above. Could you try the following steps:

    1. In RC side, issue the following command on Linux prompt:

        /usr/sbin/lspci -vvv 

        This will list EP's exposed memory map so we can write/read from RC. 

    2. Further you can use devmem2 utility in RC's linux command prompt, to manually probe EP's BAR settings. Note that devmem2 utility directly addresses physical memory so no conversion from virtual memory is needed. In below example, I am probing EP's BAR register by writing all F's, then read back, that will tell the EP's BAR mask setting. Note that PCIe BAR0 of EP is at offset 0x10 of the PCIe structure. 

    Note that Step 2 is not needed if the EP is already setup correctly, where we can see the correct writable EP memory region address via lcpsi utility. 

    regards

    Jian

  • Hi Jian,

    we followed your instruction and came to the same results. We can see our PCI devices with the exposed memory map if we enter lspci -vvv.
    We can read our written data back with devmem2 on root complex side too. But we are still not able to read the value on endpoint side via the endpoint.
    What we do is following:

    1. We write data from RC to EP (works)
    2. We read data with RC (is working like Jian has discribed)
    3. We want to read data which has been written by RC to EP with the EP.

    Another question regarding this problem:
    Do we need to extend the pci-endpoint-test driver for this purpose? Or what are the physical addresses of the PCIe-EP device in the /dev/mem of the EP?

    Kind regards
    Felix