[meta-xilinx] Linux/FreeRTOS AMP vrings

Edward Wingate edwingate8 at gmail.com
Wed Sep 2 15:06:31 PDT 2015


On Wed, Sep 2, 2015 at 1:26 PM, Wendy Liang <wendy.liang at xilinx.com> wrote:
> rpmsg_probe() from drivers/rpmsg/virtio_rpmsg_bus.c will allocate the buffers, and in the end
> it will call virtqueue_add() from drivers/virtio/virtio_ring.c to set the addr.
> You can add some print into those functions to see what value from Linux side it get.

I already did so in both linux-xlnx 3.14 and 3.19 and things are as
described in my previous message.
The 3 prints I added/looked at are:

1) Existing print in rpmsg_probe() showing vring buffer allocation at:
virtio_rpmsg_bus virtio0: buffers: va 9f440000, dma 0x1e440000

2) Here is the loop in rpmsg_probe() that calls virtqueue_add():
for (i = 0; i < vrp->num_bufs / 2; i++) {
    struct scatterlist sg;
    cpu_addr = vrp->rbufs + i * RPMSG_BUF_SIZE;
    cpu_addr_dma = rbufs_guest_addr_kva + i*RPMSG_BUF_SIZE;

    dev_dbg(&vdev->dev, "buf %d, cpu_addr %p, cpu_addr_dma, %p\n", i,
cpu_addr, cpu_addr_dma);
    sg_init_one(&sg, cpu_addr_dma, RPMSG_BUF_SIZE);

    err = virtqueue_add_inbuf(vrp->rvq, &sg, 1, cpu_addr,
                            GFP_KERNEL);
    WARN_ON(err); /* sanity check; this can't really happen */
}

I added the dev_dbg() print and this is the result:
virtio_rpmsg_bus virtio0: buf 0, cpu_addr 9f440000, cpu_addr_dma, 9f440000
virtio_rpmsg_bus virtio0: buf 1, cpu_addr 9f440200, cpu_addr_dma, 9f440200
virtio_rpmsg_bus virtio0: buf 2, cpu_addr 9f440400, cpu_addr_dma, 9f440400
... [snipped]
virtio_rpmsg_bus virtio0: buf 253, cpu_addr 9f45fa00, cpu_addr_dma, 9f45fa00
virtio_rpmsg_bus virtio0: buf 254, cpu_addr 9f45fc00, cpu_addr_dma, 9f45fc00
virtio_rpmsg_bus virtio0: buf 255, cpu_addr 9f45fe00, cpu_addr_dma, 9f45fe00

I don't what to make of the fact that cpu_addr and cpu_addr_dma are
set to the same virtual address value.

3) Here is where virtqueue_add() sets the buffer addresses in the
vring descriptors.
No looping occurs here in this case because (out_sgs + in_sgs) == 1,
as can be verified by looking at virtqueue_add_inbuf() call above.

for (; n < (out_sgs + in_sgs); n++) {
    for (sg = sgs[n]; sg; sg = sg_next(sg)) {
        desc[i].flags = cpu_to_virtio16(_vq->vdev, VRING_DESC_F_NEXT |
VRING_DESC_F_WRITE);
        desc[i].addr = cpu_to_virtio64(_vq->vdev, sg_phys(sg));
        desc[i].len = cpu_to_virtio32(_vq->vdev, sg->length);
        pr_debug("desc %d addr %llx\n", i, desc[i].addr);
        prev = i;
        i = virtio16_to_cpu(_vq->vdev, desc[i].next);
    }
}

I added the pr_debug() after desc[i].addr is set and here are the results:
desc 0 addr 1f440000
desc 1 addr 1f440200
desc 2 addr 1f440400
... [snipped]
desc 253 addr 1f45fa00
desc 254 addr 1f45fc00
desc 255 addr 1f45fe00

virtqueue_add() is populating the vring descriptors with buffer
addresses of 0x1f440xxx instead of the expected 0x1e440xxx.

Trying to decipher what sg_phys() does is where I get lost, but I
think that's where the 0x1f440xxx addresses are ultimately coming
from.



More information about the meta-xilinx mailing list