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.

How to read/write data from/to PRU-ICSS shared mem with Linux driver (Linux Kernel 4.4.12)

Hi,

I'm using the AM57xx with "ti-processor-sdk-linux-rt-am57xx-evm-03.00.00.04" and linux-rt-4.4.12.

Within the PRU ethernetdriver (prueth.c) everything works fine. But how do i accsess memory from outside the pru ethernetdriver for example from an ptp driver function like get_time ? 

At linux 3.2.0 there was something like READ_HWREG_PADDR to read data via virtual address. I can't find in linux 4.4.12.

I tried to use "memcpy_fromio" but I got an error (Unable to handle kernel NULL pointer...)

  • Hi Janin,

    You’ll need to map the physically memory to virtual memory using linux kernal ioremap system call. See for example usb-musb.c for how the usb physical registers are map using ioremap:

    static void __iomem *otg_base;

    otg_base = ioremap(OMAP34XX_HSUSB_OTG_BASE, SZ_4K);

    __raw_readl(otg_base + OTG_SYSSTATUS)));

    Regards,
    Pavel
  • this doesn't work. 

    i try to explain more detailed what we try to do.

    We have the prueth.c in this we implemented ioctl. in the ioctl function we call (devided by the command given to ioctl) another function. let's name this function fct_test() for example. this fct_test()  is defined in a other .c file test.c. And within the function fct_test in the test.c we try to read/write the shared memory of the pruss.

    we tried to implement your suggestion but it didn't work. i also thougth you should use ioremap only once.

     

  • Hi Janin,

    From what I understand, you are able to access (read/write) PRU-ICSS shared memory (PRUSS_DATA_RAM2) from withing the PRU-ICSS, but you are not able to access PRUSS_DATA_RAM2 from external host (i.e. Cortex-A15 ARM, DSP1, etc).

    Which physical address exactly you are trying to access?

    To access PRUSS_DATA_RAM2 memory from outside the PRU-ICSS you should set up the global memory map, as explained in the AM572x TRM, section 30.1.4.4.2 PRU-ICSS Global Memory Map

    Regards,
    Pavel
  • Hi Pavel,
    i can access the PRU shared mem (PRUSS_DATA_RAM2 with address 0x4B28 0000) from the PRU and from the PRU ethernet driver which is implemented in prueth.c and containing files.
    Now i have implemented ioctl within the pru ethernet driver to trigger some functions we need in addition. the sources for the function we need in addition and which are triggered from the ioctl are in other *.c files. and now i am not able to access the pru memory from this c files.

    Do we have the possibility to answer this question in "private chat" or via e-mail. then i am able to send you the stripped sources i think it is easier to understand what we want to do, if you see this.
  • Janin Wolfinger said:
    i can access the PRU shared mem (PRUSS_DATA_RAM2 with address 0x4B28 0000) from the PRU and from the PRU ethernet driver which is implemented in prueth.c and containing files.

    0x4B280000 is not shared data RAM address nor for PRU-ICSS1 neither for PRU-ICSS2.

    For PRU-ICSS1 (PRU0), the shared data RAM start address is 0x4B210000 (0x4B200000 + 0x00010000). The range is from 0x4B210000 to 0x4B21FFFF.

    For PRU-ICSS2 (PRU1), the shared data RAM start address is 0x4B290000 (0x4B280000 + 0x00010000). The range is from 0x4B290000 to 0x4B29FFFF.

    See again AM572x TRM, section 30.1.4.4.2 PRU-ICSS Global Memory Map, Example 3

    Janin Wolfinger said:
    Now i have implemented ioctl within the pru ethernet driver to trigger some functions we need in addition. the sources for the function we need in addition and which are triggered from the ioctl are in other *.c files. and now i am not able to access the pru memory from this c files.



    Are these other C files located in ti-processor-sdk-linux-rt-am57xx-evm-03.00.00.04/board-support/linux-rt-4.4.12 ? Or these are user space applications?

    Janin Wolfinger said:
    Do we have the possibility to answer this question in "private chat" or via e-mail. then i am able to send you the stripped sources i think it is easier to understand what we want to do, if you see this.

    We provide support in e2e only.

    Regards,
    Pavel

  • If these other C files are located in ti-processor-sdk-linux-rt-am57xx-evm-03.00.00.04/board-support/linux-rt-4.4.12/ you can try the below things:

    1. try with __iomem, writew(), readw() and memcpy_toio(), see the example code below:

    void __iomem *sram_base = prueth->mem[PRUETH_MEM_SHARED_RAM].va;
    void __iomem *sram;

    sram = sram_base + HOST_QUEUE_SIZE_ADDR;
    writew(HOST_QUEUE_1_SIZE, sram);

    sram = sram_base + HOST_Q1_RX_CONTEXT_OFFSET;
    memcpy_toio(sram, queue_infos[PRUETH_PORT_QUEUE_HOST], sizeof(queue_infos[PRUETH_PORT_QUEUE_HOST]));


    void __iomem *shared_ram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
    u16 bd_rd_ptr;

    bd_rd_ptr = readw(&queue_desc->rd_ptr);
    rd_buf_desc = readl(shared_ram + bd_rd_ptr);
    writel(0, shared_ram + bd_rd_ptr);

    2. try with *pru_d_da_to_va() and/or *pru_da_to_va() functions from the below file
    ti-processor-sdk-linux-rt-am57xx-evm-03.00.00.04/board-support/linux-rt-4.4.12/drivers/remoteproc/pru_rpoc.c

    3. see the PRU example, it is using shared RAM

    ti-processor-sdk-linux-rt-am57xx-evm-03.00.00.04/example-applications/pru-icss-4.0.2/pru_cape/pru_demo/hw_pruss.h
    ti-processor-sdk-linux-rt-am57xx-evm-03.00.00.04/example-applications/pru-icss-4.0.2/pru_cape/pru_demo/pru.c

    If you are using user space application, you can try with mmap()

    Regards,
    Pavel
  • One more suggestion. In the PRU Ethernet Driver (prueth.c) wiki page we have the below note:

    As the boards boot, the prussN_eth device tree node causes the ti-prueth driver to be probed. This probe function does several things to prepare the PRU-ICSS Ethernet ports:

    Requests ownership of the PRUSS memory regions from the pruss driver

    This is done with pruss_request_mem_region(). This function might prevent you from access the shared data RAM from outside the prueth.c You can try to release the shared data RAM2 with pruss_release_mem_region() before trying to access it from outside the prueth.c


    Regards,
    Pavel

  • Thanks we are testing this at moment.
  • Hi Janin Wolfinger

    Did you use am572x_idk or your custom board?

    Thanks
    wang