UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Newbie eanjum
Newbie
2,490 Views
Registered: ‎03-03-2014

Address of shared buffers provided by RPMSG driver in Linux- FreeRTOS AMP system on ZYNQ zc702evk target

Environment:

  • Xilinx Zynq zc702evk Platform
  • Petalinux v2013-10
  • Linux-FreeRTOS AMP System , ug978-petalinux-zynq-amp


Problem Description:
In Linux-FreeRTOS AMP system, Linux RPMSG driver provides buffers for consumption by the FreeRTOS. The physical address of buffers provided by the Linux is not used as such by the FreeRTOS, instead FreeRTOS application masks Most Significant Byte of the address before accessing the memory.


The Linux RPMSG bus driver puts buffers in the vring descriptors of Virtqueue , which are supposed to carry the physical address, then why is the address not used by the FreeRTOS application without modification. In fact, buffer address provided by the Linux RPMSG driver does not even present in the shared memory region, and therefore masking is required to get the correct data from the memory.


So the question is, why addresses of buffers posted by the Linux do not reflect actual physical address in memory?

See the FreeRTOS application code snippet below, which does this address masking;

/* Function to receive message from Linux from rxvring. */
void read_message(void)
{
    struct vring_used volatile *ring_rx_used = (void *)RING_RX_USED;
    unsigned int index = ring_rx_used->idx % VRING_SIZE;

    struct vring_desc volatile *ring_rx = (void *)RING_RX;
    
    //-------------------------    WHYYYYYYYYYYYYYYYYYYYY --------------------------------
    //WHY VRING ADDR MASK IS REQUIRED , AS VRING DESC ARE SUPPOSED TO CARRY PHYSICAL ADDRESS
    //---------------------------------------------------------------------------------------
    
    
    struct rpmsg_hdr *hdr = (struct rpmsg_hdr *)(ring_rx[index].addr &
            VRING_ADDR_MASK);

    /* Update index */
    ring_rx_used->ring[index].id = index;
    ring_rx_used->ring[index].len = PACKET_LEN_MAX;
    ring_rx_used->idx += 1; // last index 0 keep increasing

    /* Create a req structure to pass to handler */
    struct remoteproc_request req;
    req.__hdr = hdr;
    req.state = *(unsigned int *)hdr->data;

    if (rxcallback_handler != NULL) {
        rxcallback_handler(&req, hdr->data, hdr->len);
    }

    Xil_L1DCacheFlush();
    return;
}

Thanks in advance for any help.

Tags (4)
0 Kudos