summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuman Anna <s-anna@ti.com>2019-03-26 18:00:55 -0500
committerSam Nelson <sam.nelson@ti.com>2019-05-21 15:56:15 -0400
commite3ac95416510d12a08f550289d1c069a9e30c7eb (patch)
tree0a85f6b95db0c34c6febe9af98f2be6240e2a20d
parent75d8759d614bcf2d8ea9d0476f9d933abd79f695 (diff)
downloadipc-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.c42
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 */