diff options
author | Suman Anna <s-anna@ti.com> | 2019-03-26 18:00:55 -0500 |
---|---|---|
committer | Sam Nelson <sam.nelson@ti.com> | 2019-05-21 15:56:15 -0400 |
commit | e3ac95416510d12a08f550289d1c069a9e30c7eb (patch) | |
tree | 0a85f6b95db0c34c6febe9af98f2be6240e2a20d | |
parent | 75d8759d614bcf2d8ea9d0476f9d933abd79f695 (diff) | |
download | ipc-e3ac95416510d12a08f550289d1c069a9e30c7eb.tar.gz |
omapl138: VirtQueue: Add vdev status synchronization logic
The VirtQueue objects are currently initialized using the vring
addresses from the corresponding vring entries in the resource
table. The memory for vrings is always allocated on the Linux
kernel at runtime, and the resource table entry is updated with
the corresponding allocated address.
This allocation always used to happen during the vdev resource
handling previously on the Linux kernel side, but this behavior
has changed in newer Linux kernels > 4.19. The memory is allocated
now after all the resources are handled, and the resource table
is updated only when the virtio_rpmsg_bus driver is probed, and
only if a FW_RSC_ADDR_ANY is passed in the resource table. This
driver can be installed after the remoteproc is up, which results
in the RTOS code using a stale value.
Resolve this by adding a synchronization logic for the vdev
status (set during virtio_rpmsg_bus probe on kernel-side). The
synchronization is added during the creation of the first VirtQueue
object. This can probably be done in module startup as well since
the VirtQueue code on OMAPL138 is a XDC module, but the design
follows the non-XDC usage as on DRA7xx/AM57xx platforms.
Signed-off-by: Suman Anna <s-anna@ti.com>
-rw-r--r-- | packages/ti/ipc/family/omapl138/VirtQueue.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/packages/ti/ipc/family/omapl138/VirtQueue.c b/packages/ti/ipc/family/omapl138/VirtQueue.c index a1f525f..3210c59 100644 --- a/packages/ti/ipc/family/omapl138/VirtQueue.c +++ b/packages/ti/ipc/family/omapl138/VirtQueue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2018, Texas Instruments Incorporated + * Copyright (c) 2011-2019, Texas Instruments Incorporated * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,6 +69,7 @@ #include <ti/sdo/ipc/notifyDrivers/IInterrupt.h> #include <ti/sdo/ipc/family/da830/InterruptDsp.h> +#include <ti/ipc/remoteproc/rsc_types.h> #include <ti/ipc/remoteproc/Resource.h> #include <ti/ipc/MultiProc.h> @@ -80,6 +81,17 @@ #include <ti/ipc/rpmsg/_VirtQueue.h> #include <ti/ipc/rpmsg/virtio_ring.h> +/* + * The following three VIRTIO_* defines must match those in + * <Linux_kernel>/include/uapi/linux/virtio_config.h + */ +#define VIRTIO_CONFIG_S_ACKNOWLEDGE 1 +#define VIRTIO_CONFIG_S_DRIVER 2 +#define VIRTIO_CONFIG_S_DRIVER_OK 4 + +#define VRING_BUFS_PRIMED (VIRTIO_CONFIG_S_ACKNOWLEDGE | \ + VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK) + /* Used for defining the size of the virtqueue registry */ #define NUM_QUEUES 2 @@ -116,6 +128,31 @@ static inline UInt mapVAtoPA(Void * va) return (UInt)va; } +/*! + * ======== _VirtQueue_init ======== + * + * This function waits for the VirtQueue vdev status to be ready before + * proceeding with the actual VirtQueue create. This synchronization + * ensures that the vring resources are updated properly in the resource + * table before the RTOS code can really use them. + * + * Since _VirtQueue_init is not called by XDC-VirtQueue module clients, this + * function is called in the first VirtQueue fxn called: VirtQueue_create. + */ +static Void _VirtQueue_init() +{ + if (!VirtQueue_module->virtQueueInitialized) { + Log_print1(Diags_USER1, "_VirtQueue_init: VDEV status: 0x%x\n", + Resource_getVdevStatus(VIRTIO_ID_RPMSG)); + Log_print0(Diags_USER1, "_VirtQueue_init: Polling VDEV status...\n"); + while (Resource_getVdevStatus(VIRTIO_ID_RPMSG) != VRING_BUFS_PRIMED); + Log_print1(Diags_USER1, "_VirtQueue_init: VDEV status synced: 0x%x\n", + Resource_getVdevStatus(VIRTIO_ID_RPMSG)); + + VirtQueue_module->virtQueueInitialized = 1; + } +} + /* * ======== VirtQueue_Instance_init ======== */ @@ -126,6 +163,9 @@ Int VirtQueue_Instance_init(VirtQueue_Object *vq, UInt16 remoteProcId, void *vringAddr = NULL; Cache_Mar marValue; + /* Perform one-time initialization (mimic non-XDC behavior): */ + _VirtQueue_init(); + VirtQueue_module->traceBufPtr = Resource_getTraceBufPtr(); /* Create the thread protection gate */ |