Add remoteproc platform APIs
authorWendy Liang <jliang@xilinx.com>
Mon, 1 Aug 2016 04:08:02 +0000 (21:08 -0700)
committerWendy Liang <jliang@xilinx.com>
Thu, 13 Oct 2016 05:01:46 +0000 (22:01 -0700)
Add remoteproc platform APIs to setup the hil_proc
with the input platform user data.

Signed-off-by: Wendy Liang <jliang@xilinx.com>
lib/include/openamp/remoteproc_plat.h [new file with mode: 0644]
lib/remoteproc/CMakeLists.txt
lib/remoteproc/remoteproc_plat.c [new file with mode: 0644]

diff --git a/lib/include/openamp/remoteproc_plat.h b/lib/include/openamp/remoteproc_plat.h
new file mode 100644 (file)
index 0000000..457c5f9
--- /dev/null
@@ -0,0 +1,105 @@
+#ifndef _REMOTEPROC_PLAT_H_
+#define _REMOTEPROC_PLAT_H_
+
+/*
+ * Copyright (c) 2016 Xilinx, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       remoteproc_platform.h
+ *
+ * DESCRIPTION
+ *
+ *       This file defines the platform data structure, user can use those
+ *       structures to specify platform dependent data. Remoteproc drivers
+ *       can use them to get the platform data.
+ *
+ ***************************************************************************/
+
+#include "openamp/hil.h"
+#include "metal/list.h"
+#include "metal/io.h"
+
+
+/** Platform data resource type */
+enum plat_rsc_type {
+       PLAT_RSC_VRING = 0,
+       PLAT_RSC_SHM = 1,
+       PLAT_RSC_RPMSG_CHANNEL = 2,
+       PLAT_RSC_LAST = 3,
+};
+
+/** vring data structure */
+struct plat_vring {
+       unsigned int type;
+       char *ipi_bus_name;
+       char *ipi_dev_name;
+       void *ipi_dev_data;
+       char *vdev_bus_name;
+       char *vdev_name;
+};
+
+/** shared memory structure */
+struct plat_shm {
+       unsigned int type;
+       char *shm_name;
+       size_t size;
+};
+
+/** RPMSG channel structure */
+struct plat_rpmsg_chnl {
+       unsigned int type;
+       char *name;
+};
+
+/**
+ * rproc_init_plat_data
+ *
+ * setup remoteproc common data based on the input platform data.
+ *
+ * @param[in] pdata    - input platform data
+ * @param[in] proc      - hil proc to set with the platform data
+ *
+ * @returns - 0 for success, non-zero for errors.
+ *
+ */
+int rproc_init_plat_data(void *pdata, struct hil_proc *proc);
+
+/**
+ * rproc_close_plat
+ *
+ * close remoteproc platform resource
+ *
+ * @param[in] proc      - hil proc which holds the platform data
+ *
+ */
+void rproc_close_plat(struct hil_proc *proc);
+
+#endif                         /* _REMOTEPROC_PLAT_H_ */
index acd240ae7672d9a0c9ba778f8b3ceb553f20da67..3b54d7847e1eb941055eeb949dd93446e67b4e23 100644 (file)
@@ -2,4 +2,5 @@ collect (PROJECT_LIB_SOURCES elf_loader.c)
 collect (PROJECT_LIB_SOURCES remoteproc.c)
 collect (PROJECT_LIB_SOURCES remoteproc_loader.c)
 collect (PROJECT_LIB_SOURCES rsc_table_parser.c)
+collect (PROJECT_LIB_SOURCES remoteproc_plat.c)
 add_subdirectory (drivers)
diff --git a/lib/remoteproc/remoteproc_plat.c b/lib/remoteproc/remoteproc_plat.c
new file mode 100644 (file)
index 0000000..f49cbe2
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2016 Xilinx, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of Mentor Graphics Corporation nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include "openamp/hil.h"
+#include "openamp/remoteproc_plat.h"
+#include "metal/device.h"
+#include "metal/io.h"
+#include "metal/shmem.h"
+
+/**
+ * rproc_platform_open_metal_dev
+ *
+ * Open metal device and get the I/O region
+ *
+ * @param[in]  bus_name - metal device bus name
+ * @param[in]  dev_name - metal device name
+ * @param[out] dev - return metal device handle
+ * @param[out] io - return metal device I/O region
+ *
+ * @return - 0 for success, non-zero for errors.
+ */
+static int rproc_plat_open_metal_dev(char *bus_name, char *dev_name,
+                                    struct metal_device **dev,
+                                    struct metal_io_region **io)
+{
+       int ret;
+       ret = metal_device_open(bus_name, dev_name, dev);
+       if (ret)
+               return ret;
+       *io = metal_device_io_region(*dev, 0);
+       if (!(*io)) {
+               metal_device_close(*dev);
+               *dev = 0;
+               return -1;
+       }
+       return 0;
+}
+
+int rproc_init_plat_data(void *pdata,
+                            struct hil_proc *proc)
+{
+       unsigned int type;
+       struct metal_device *dev;
+       struct metal_io_region *io;
+       int num_vrings = 0;
+       int num_rpmsg_chnls = 0;
+       int ret;
+
+       if (!proc || !pdata)
+               return -1;
+       memcpy(proc, pdata, sizeof(struct proc_info_hdr));
+
+       pdata += sizeof(struct proc_info_hdr);
+       while(1) {
+               type = *((unsigned int *)pdata);
+               if (type > PLAT_RSC_LAST) {
+                       return -1;
+               } else if (type == PLAT_RSC_LAST) {
+                       proc->vdev.num_vrings = num_vrings;
+                       proc->num_chnls = num_rpmsg_chnls;
+                       return 0;
+               } else if (type == PLAT_RSC_VRING) {
+                       struct plat_vring *pvring =
+                               (struct plat_vring *)pdata;
+                       struct proc_vring *vring = 
+                               &proc->vdev.vring_info[num_vrings];
+                       /* Open the vring IPI device */
+                       if (pvring->ipi_dev_name) {
+                               ret = rproc_plat_open_metal_dev(
+                                               pvring->ipi_bus_name,
+                                               pvring->ipi_dev_name,
+                                               &dev, &io);
+                               if (ret)
+                                       return ret;
+                               vring->intr_info.dev = dev;
+                               vring->intr_info.io = io;
+                               vring->intr_info.vect_id =
+                                       (uintptr_t)dev->irq_info;
+                       }
+                       vring->intr_info.data = pvring->ipi_dev_data;
+                       /* Open the vring descriptor memory device */
+                       if (pvring->vdev_name) {
+                               ret = rproc_plat_open_metal_dev(
+                                               pvring->vdev_bus_name,
+                                               pvring->vdev_name,
+                                               &dev, &io);
+                               if (ret)
+                                       return ret;
+                               vring->dev = dev;
+                               vring->io = io;
+                       }
+                       num_vrings++;
+                       pdata += sizeof(struct plat_vring);
+               } else if (type == PLAT_RSC_SHM) {
+                       struct plat_shm *pshm =
+                               (struct plat_shm *)pdata;
+                       /* Open the shared memory device */
+                       ret = metal_shmem_open(pshm->shm_name,
+                                               pshm->size,
+                                               &io);
+                       if (ret)
+                               return ret;
+                       proc->sh_buff.io = io;
+                       pdata += sizeof(struct plat_shm);
+               } else if (type == PLAT_RSC_RPMSG_CHANNEL) {
+                       struct plat_rpmsg_chnl *pchl =
+                               (struct plat_rpmsg_chnl *)pdata;
+                       strcpy(proc->chnls[num_rpmsg_chnls].name, pchl->name);
+                       num_rpmsg_chnls++;
+                       pdata += sizeof(struct plat_rpmsg_chnl);
+               }
+       }
+
+}
+
+void rproc_close_plat(struct hil_proc *proc)
+{
+       if (!proc)
+               return;
+       int i;
+       int num_vrings = proc->vdev.num_vrings;
+       struct metal_device *dev;
+       struct proc_vring *vring;
+
+       /* Close the vrings devices */
+       for (i = 0; i < num_vrings; i++) {
+               vring = &proc->vdev.vring_info[i];
+               dev = vring->dev;
+               if (dev)
+                       metal_device_close(dev);
+               dev = vring->intr_info.dev;
+               if (dev)
+                       metal_device_close(dev);
+       }
+}