]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/open-amp.git/commitdiff
Covert to Linux file format
authorWendy Liang <jliang@xilinx.com>
Tue, 5 Jan 2016 22:43:36 +0000 (14:43 -0800)
committerWendy Liang <jliang@xilinx.com>
Tue, 9 Feb 2016 19:20:48 +0000 (11:20 -0800)
Signed-off-by: Wendy Liang <jliang@xilinx.com>
35 files changed:
apps/samples/remote/baremetal/rpc_demo/rsc_table.h
apps/tests/remote/baremetal/echo_test/rsc_table.c
apps/tests/remote/baremetal/echo_test/rsc_table.h
apps/tests/remote/baremetal/func_test_suite/rsc_table.c
apps/tests/remote/baremetal/func_test_suite/rsc_table.h
common/hil/hil.c
common/hil/hil.h
common/llist/llist.c
common/llist/llist.h
common/shm/sh_mem.c
common/shm/sh_mem.h
include/open_amp.h
libs/system/zc702evk/linux/boot.c
libs/system/zc702evk/linux/boot_wrapper.S
libs/system/zc702evk/linux/rsc_table.c
libs/system/zc702evk/linux/rsc_table.h
porting/config/config.c
porting/config/config.h
porting/env/env.h
porting/zc702evk/platform.c
porting/zc702evk/platform.h
porting/zc702evk/platform_info.c
porting/zc702evk/zynq_trampoline.S
remoteproc/elf_loader.c
remoteproc/elf_loader.h
remoteproc/remoteproc_loader.c
remoteproc/remoteproc_loader.h
remoteproc/rsc_table_parser.h
rpmsg/remote_device.c
rpmsg/rpmsg.c
rpmsg/rpmsg_core.h
virtio/virtio.h
virtio/virtio_ring.h
virtio/virtqueue.c
virtio/virtqueue.h

index 60b602e45e2c22da03c7b52682b6c9129fdd0717..60a0548878e2d4f09cfb5add16a2feefdc0175ec 100644 (file)
@@ -1,59 +1,59 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- * Copyright (c) 2015 Xilinx, Inc. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* This file populates resource table for BM remote\r
- * for use by the Linux Master */\r
-\r
-#include <stddef.h>\r
-#include "open_amp.h"\r
-\r
-#define NO_RESOURCE_ENTRIES         8\r
-\r
-/* Resource table for the given remote */\r
-struct remote_resource_table {\r
-       unsigned int version;\r
-       unsigned int num;\r
-       unsigned int reserved[2];\r
-       unsigned int offset[NO_RESOURCE_ENTRIES];\r
-       /* text carveout entry */\r
-#ifdef ZYNQMP_R5\r
-       struct fw_rsc_carveout ocm_0_cout;\r
-       struct fw_rsc_carveout ocm_1_cout;\r
-#else\r
-#ifdef ZYNQ_A9\r
-       struct fw_rsc_carveout elf_cout;\r
-#endif\r
-#endif\r
-       /* rpmsg vdev entry */\r
-       struct fw_rsc_vdev rpmsg_vdev;\r
-       struct fw_rsc_vdev_vring rpmsg_vring0;\r
-       struct fw_rsc_vdev_vring rpmsg_vring1;\r
-};\r
-\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ * Copyright (c) 2015 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.
+ */
+
+/* This file populates resource table for BM remote
+ * for use by the Linux Master */
+
+#include <stddef.h>
+#include "open_amp.h"
+
+#define NO_RESOURCE_ENTRIES         8
+
+/* Resource table for the given remote */
+struct remote_resource_table {
+       unsigned int version;
+       unsigned int num;
+       unsigned int reserved[2];
+       unsigned int offset[NO_RESOURCE_ENTRIES];
+       /* text carveout entry */
+#ifdef ZYNQMP_R5
+       struct fw_rsc_carveout ocm_0_cout;
+       struct fw_rsc_carveout ocm_1_cout;
+#else
+#ifdef ZYNQ_A9
+       struct fw_rsc_carveout elf_cout;
+#endif
+#endif
+       /* rpmsg vdev entry */
+       struct fw_rsc_vdev rpmsg_vdev;
+       struct fw_rsc_vdev_vring rpmsg_vring0;
+       struct fw_rsc_vdev_vring rpmsg_vring1;
+};
+
index 20d4d0b32f5915d4c37943a18a2b3ba6dda9f3b4..b2096d8f4325b2aed3c33bfc356b9b3394e234c2 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- * Copyright (c) 2015 Xilinx, Inc. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* This file populates resource table for BM remote\r
- * for use by the Linux Master */\r
-\r
-#include "open_amp.h"\r
-#include "rsc_table.h"\r
-\r
-/* Place resource table in special ELF section */\r
-#define __section(S)            __attribute__((__section__(#S)))\r
-#define __resource              __section(.resource_table)\r
-\r
-#define RPMSG_IPU_C0_FEATURES        1\r
-\r
-/* VirtIO rpmsg device id */\r
-#define VIRTIO_ID_RPMSG_             7\r
-\r
-/* Remote supports Name Service announcement */\r
-#define VIRTIO_RPMSG_F_NS           0\r
-\r
-#ifdef ZYNQMP_R5\r
-#define OCM_0_START                 0xFFFC0000\r
-#define OCM_0_LEN                   0x20000\r
-#define OCM_1_START                 0xFFFF0000\r
-#define OCM_1_LEN                   0x10000\r
-#define TCM_0_START_DA              0x00000000\r
-#define TCM_0_LEN                   0x10000\r
-#define TCM_0_START_PA              0xFFE00000\r
-#define TCM_1_START_DA              0x00020000\r
-#define TCM_1_LEN                   0x10000\r
-#define TCM_1_START_PA              0xFFE40000\r
-#define NUM_VRINGS                  0x02\r
-#define VRING_ALIGN                 0x1000\r
-#define RING_TX                     0x3ED00000\r
-#define RING_RX                     0x3ED04000\r
-#define VRING_SIZE                  256\r
-\r
-#define NUM_TABLE_ENTRIES           3\r
-#define CARVEOUT_SRC_OFFSETS        offsetof(struct remote_resource_table, ocm_0_cout), \\r
-                                                               offsetof(struct remote_resource_table, ocm_1_cout),\r
-\r
-#define CARVEOUT_SRC                {RSC_CARVEOUT, OCM_0_START, OCM_0_START, OCM_0_LEN, 0, 0, "OCM0_COUT",}, \\r
-                                                       {RSC_CARVEOUT, OCM_1_START, OCM_1_START, OCM_1_LEN, 0, 0, "ELF_DATA_COUT",},\r
-\r
-#else\r
-#ifdef ZYNQ_A9\r
-/* Resource table entries */\r
-#define ELF_START                   0x00000000\r
-#define ELF_END                     0x08000000\r
-#define NUM_VRINGS                  0x02\r
-#define VRING_ALIGN                 0x1000\r
-#define RING_TX                     0x08000000\r
-#define RING_RX                     0x08004000\r
-#define VRING_SIZE                  256\r
-\r
-#define NUM_TABLE_ENTRIES           2\r
-#define CARVEOUT_SRC_OFFSETS        offsetof(struct remote_resource_table, elf_cout),\r
-#define CARVEOUT_SRC                { RSC_CARVEOUT, ELF_START, ELF_START, ELF_END, 0, 0, "ELF_COUT", },\r
-\r
-#endif\r
-#endif\r
-       \r
-\r
-const struct remote_resource_table __resource resources =\r
-{\r
-    /* Version */\r
-    1,\r
-\r
-    /* NUmber of table entries */\r
-    NUM_TABLE_ENTRIES,\r
-    /* reserved fields */\r
-    { 0, 0,},\r
-\r
-    /* Offsets of rsc entries */\r
-    {\r
-        CARVEOUT_SRC_OFFSETS\r
-        offsetof(struct remote_resource_table, rpmsg_vdev),\r
-    },\r
-\r
-    /* End of ELF file */\r
-    CARVEOUT_SRC\r
-\r
-    /* Virtio device entry */\r
-    {   RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, NUM_VRINGS, {0, 0},\r
-    },\r
-\r
-    /* Vring rsc entry - part of vdev rsc entry */\r
-    {\r
-        RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0\r
-    },\r
-    {\r
-        RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0\r
-    },\r
-};\r
-\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ * Copyright (c) 2015 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.
+ */
+
+/* This file populates resource table for BM remote
+ * for use by the Linux Master */
+
+#include "open_amp.h"
+#include "rsc_table.h"
+
+/* Place resource table in special ELF section */
+#define __section(S)            __attribute__((__section__(#S)))
+#define __resource              __section(.resource_table)
+
+#define RPMSG_IPU_C0_FEATURES        1
+
+/* VirtIO rpmsg device id */
+#define VIRTIO_ID_RPMSG_             7
+
+/* Remote supports Name Service announcement */
+#define VIRTIO_RPMSG_F_NS           0
+
+#ifdef ZYNQMP_R5
+#define OCM_0_START                 0xFFFC0000
+#define OCM_0_LEN                   0x20000
+#define OCM_1_START                 0xFFFF0000
+#define OCM_1_LEN                   0x10000
+#define TCM_0_START_DA              0x00000000
+#define TCM_0_LEN                   0x10000
+#define TCM_0_START_PA              0xFFE00000
+#define TCM_1_START_DA              0x00020000
+#define TCM_1_LEN                   0x10000
+#define TCM_1_START_PA              0xFFE40000
+#define NUM_VRINGS                  0x02
+#define VRING_ALIGN                 0x1000
+#define RING_TX                     0x3ED00000
+#define RING_RX                     0x3ED04000
+#define VRING_SIZE                  256
+
+#define NUM_TABLE_ENTRIES           3
+#define CARVEOUT_SRC_OFFSETS        offsetof(struct remote_resource_table, ocm_0_cout), \
+                                                               offsetof(struct remote_resource_table, ocm_1_cout),
+
+#define CARVEOUT_SRC                {RSC_CARVEOUT, OCM_0_START, OCM_0_START, OCM_0_LEN, 0, 0, "OCM0_COUT",}, \
+                                                       {RSC_CARVEOUT, OCM_1_START, OCM_1_START, OCM_1_LEN, 0, 0, "ELF_DATA_COUT",},
+
+#else
+#ifdef ZYNQ_A9
+/* Resource table entries */
+#define ELF_START                   0x00000000
+#define ELF_END                     0x08000000
+#define NUM_VRINGS                  0x02
+#define VRING_ALIGN                 0x1000
+#define RING_TX                     0x08000000
+#define RING_RX                     0x08004000
+#define VRING_SIZE                  256
+
+#define NUM_TABLE_ENTRIES           2
+#define CARVEOUT_SRC_OFFSETS        offsetof(struct remote_resource_table, elf_cout),
+#define CARVEOUT_SRC                { RSC_CARVEOUT, ELF_START, ELF_START, ELF_END, 0, 0, "ELF_COUT", },
+
+#endif
+#endif
+       
+
+const struct remote_resource_table __resource resources =
+{
+    /* Version */
+    1,
+
+    /* NUmber of table entries */
+    NUM_TABLE_ENTRIES,
+    /* reserved fields */
+    { 0, 0,},
+
+    /* Offsets of rsc entries */
+    {
+        CARVEOUT_SRC_OFFSETS
+        offsetof(struct remote_resource_table, rpmsg_vdev),
+    },
+
+    /* End of ELF file */
+    CARVEOUT_SRC
+
+    /* Virtio device entry */
+    {   RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, NUM_VRINGS, {0, 0},
+    },
+
+    /* Vring rsc entry - part of vdev rsc entry */
+    {
+        RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0
+    },
+    {
+        RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0
+    },
+};
+
index a045d03fba16e335fb6dad527596f1c5e6a63dc6..cc0e11801d810aa5d0cffe51cf048206776adfc2 100644 (file)
@@ -1,59 +1,59 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- * Copyright (c) 2015 Xilinx, Inc. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* This file populates resource table for BM remote\r
- * for use by the Linux Master */\r
-\r
-#include <stddef.h>\r
-#include "open_amp.h"\r
-\r
-#define NO_RESOURCE_ENTRIES         8\r
-\r
-/* Resource table for the given remote */\r
-struct remote_resource_table {\r
-    unsigned int version;\r
-    unsigned int num;\r
-    unsigned int reserved[2];\r
-    unsigned int offset[NO_RESOURCE_ENTRIES];\r
-    /* text carveout entry */\r
-#ifdef ZYNQMP_R5\r
-       struct fw_rsc_carveout ocm_0_cout;\r
-    struct fw_rsc_carveout ocm_1_cout;\r
-#else\r
-#ifdef ZYNQ_A9\r
-    struct fw_rsc_carveout elf_cout;\r
-#endif\r
-#endif\r
-    /* rpmsg vdev entry */\r
-    struct fw_rsc_vdev rpmsg_vdev;\r
-    struct fw_rsc_vdev_vring rpmsg_vring0;\r
-    struct fw_rsc_vdev_vring rpmsg_vring1;\r
-};\r
-\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ * Copyright (c) 2015 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.
+ */
+
+/* This file populates resource table for BM remote
+ * for use by the Linux Master */
+
+#include <stddef.h>
+#include "open_amp.h"
+
+#define NO_RESOURCE_ENTRIES         8
+
+/* Resource table for the given remote */
+struct remote_resource_table {
+    unsigned int version;
+    unsigned int num;
+    unsigned int reserved[2];
+    unsigned int offset[NO_RESOURCE_ENTRIES];
+    /* text carveout entry */
+#ifdef ZYNQMP_R5
+       struct fw_rsc_carveout ocm_0_cout;
+    struct fw_rsc_carveout ocm_1_cout;
+#else
+#ifdef ZYNQ_A9
+    struct fw_rsc_carveout elf_cout;
+#endif
+#endif
+    /* rpmsg vdev entry */
+    struct fw_rsc_vdev rpmsg_vdev;
+    struct fw_rsc_vdev_vring rpmsg_vring0;
+    struct fw_rsc_vdev_vring rpmsg_vring1;
+};
+
index 85b11b1dc71953d84074687831febb322bb1ecd1..af8e0e11f40f4518127a96984860c1d6c52cbf93 100644 (file)
@@ -1,89 +1,89 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* This file populates resource table for BM remote\r
- * for use by the Linux Master */\r
-\r
-#include "open_amp.h"\r
-#include "rsc_table.h"\r
-\r
-/* Place resource table in special ELF section */\r
-#define __section(S)            __attribute__((__section__(#S)))\r
-#define __resource              __section(.resource_table)\r
-\r
-#define RPMSG_IPU_C0_FEATURES       1\r
-\r
-/* VirtIO rpmsg device id */\r
-#define VIRTIO_ID_RPMSG_             7\r
-\r
-/* Remote supports Name Service announcement */\r
-#define VIRTIO_RPMSG_F_NS           0\r
-\r
-/* Resource table entries */\r
-#define ELF_START                   0x00000000\r
-#define ELF_END                     0x08000000\r
-#define NUM_VRINGS                                     0x02\r
-#define VRING_ALIGN                                    0x1000\r
-#define RING_TX                     0x08000000\r
-#define RING_RX                     0x08004000\r
-#define VRING_SIZE                  256\r
-\r
-const struct remote_resource_table __resource resources =\r
-{\r
-    /* Version */\r
-    1,\r
-\r
-    /* NUmber of table entries */\r
-    2,\r
-    /* reserved fields */\r
-    {   0, 0,},\r
-\r
-    /* Offsets of rsc entries */\r
-    {\r
-        offsetof(struct remote_resource_table, elf_cout),\r
-        offsetof(struct remote_resource_table, rpmsg_vdev),\r
-    },\r
-\r
-    /* End of ELF file */\r
-    {\r
-        RSC_CARVEOUT, ELF_START, ELF_START, ELF_END, 0, 0, "ELF_COUT",\r
-    },\r
-\r
-    /* Virtio device entry */\r
-    {   RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, NUM_VRINGS, {0, 0},\r
-    },\r
-\r
-    /* Vring rsc entry - part of vdev rsc entry */\r
-    {\r
-        RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0\r
-    },\r
-    {\r
-        RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0\r
-    },\r
-};\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/* This file populates resource table for BM remote
+ * for use by the Linux Master */
+
+#include "open_amp.h"
+#include "rsc_table.h"
+
+/* Place resource table in special ELF section */
+#define __section(S)            __attribute__((__section__(#S)))
+#define __resource              __section(.resource_table)
+
+#define RPMSG_IPU_C0_FEATURES       1
+
+/* VirtIO rpmsg device id */
+#define VIRTIO_ID_RPMSG_             7
+
+/* Remote supports Name Service announcement */
+#define VIRTIO_RPMSG_F_NS           0
+
+/* Resource table entries */
+#define ELF_START                   0x00000000
+#define ELF_END                     0x08000000
+#define NUM_VRINGS                                     0x02
+#define VRING_ALIGN                                    0x1000
+#define RING_TX                     0x08000000
+#define RING_RX                     0x08004000
+#define VRING_SIZE                  256
+
+const struct remote_resource_table __resource resources =
+{
+    /* Version */
+    1,
+
+    /* NUmber of table entries */
+    2,
+    /* reserved fields */
+    {   0, 0,},
+
+    /* Offsets of rsc entries */
+    {
+        offsetof(struct remote_resource_table, elf_cout),
+        offsetof(struct remote_resource_table, rpmsg_vdev),
+    },
+
+    /* End of ELF file */
+    {
+        RSC_CARVEOUT, ELF_START, ELF_START, ELF_END, 0, 0, "ELF_COUT",
+    },
+
+    /* Virtio device entry */
+    {   RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, NUM_VRINGS, {0, 0},
+    },
+
+    /* Vring rsc entry - part of vdev rsc entry */
+    {
+        RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0
+    },
+    {
+        RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0
+    },
+};
index 0a8e95750d5d919b1fe9ece8236a632fc84d1801..842b423db71351e24b6513a14f1be348eb7b9def 100644 (file)
@@ -1,51 +1,51 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* This file populates resource table for BM remote\r
- * for use by the Linux Master */\r
-\r
-#include <stddef.h>\r
-#include "open_amp.h"\r
-\r
-#define NO_RESOURCE_ENTRIES         8\r
-\r
-/* Resource table for the given remote */\r
-struct remote_resource_table {\r
-    unsigned int version;\r
-    unsigned int num;\r
-    unsigned int reserved[2];\r
-    unsigned int offset[NO_RESOURCE_ENTRIES];\r
-    /* text carveout entry */\r
-    struct fw_rsc_carveout elf_cout;\r
-    /* rpmsg vdev entry */\r
-    struct fw_rsc_vdev rpmsg_vdev;\r
-    struct fw_rsc_vdev_vring rpmsg_vring0;\r
-    struct fw_rsc_vdev_vring rpmsg_vring1;\r
-};\r
-\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/* This file populates resource table for BM remote
+ * for use by the Linux Master */
+
+#include <stddef.h>
+#include "open_amp.h"
+
+#define NO_RESOURCE_ENTRIES         8
+
+/* Resource table for the given remote */
+struct remote_resource_table {
+    unsigned int version;
+    unsigned int num;
+    unsigned int reserved[2];
+    unsigned int offset[NO_RESOURCE_ENTRIES];
+    /* text carveout entry */
+    struct fw_rsc_carveout elf_cout;
+    /* rpmsg vdev entry */
+    struct fw_rsc_vdev rpmsg_vdev;
+    struct fw_rsc_vdev_vring rpmsg_vring0;
+    struct fw_rsc_vdev_vring rpmsg_vring1;
+};
+
index 69df0599abd437dba2d52a85ce983cab15a20773..31e1a71eef95155dc0769b116dcef0bbf664b98b 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       hil.c\r
- *\r
- * COMPONENT\r
- *\r
- *         OpenAMP  Stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- *       This file is implementation of generic part of HIL.\r
- *\r
- *\r
- *\r
- **************************************************************************/\r
-\r
-#include "hil.h"\r
-\r
-/*--------------------------- Globals ---------------------------------- */\r
-struct hil_proc_list procs;\r
-\r
-#if defined (OPENAMP_BENCHMARK_ENABLE)\r
-\r
-unsigned long long boot_time_stamp;\r
-unsigned long long shutdown_time_stamp;\r
-\r
-#endif\r
-\r
-extern int platform_get_processor_info(struct hil_proc *proc, int cpu_id);\r
-extern int platform_get_processor_for_fw(char *fw_name);\r
-\r
-/**\r
- * hil_create_proc\r
- *\r
- * This function creates a HIL proc instance for given CPU id and populates\r
- * it with platform info.\r
- *\r
- * @param cpu_id - cpu id\r
- *\r
- * @return - pointer to proc instance\r
- *\r
- */\r
-struct hil_proc *hil_create_proc(int cpu_id) {\r
-    struct hil_proc *proc = NULL;\r
-    struct llist *node = NULL;\r
-    struct llist *proc_hd = procs.proc_list;\r
-    int status;\r
-\r
-    /* If proc already exists then return it */\r
-    while (proc_hd != NULL) {\r
-        proc = (struct hil_proc *) proc_hd->data;\r
-        if (proc->cpu_id == cpu_id) {\r
-            return proc;\r
-        }\r
-        proc_hd = proc_hd->next;\r
-    }\r
-\r
-    /* Allocate memory for proc instance */\r
-    proc = env_allocate_memory(sizeof(struct hil_proc));\r
-    if (!proc) {\r
-        return NULL;\r
-    }\r
-\r
-    /* Get HW specfic info */\r
-    status = platform_get_processor_info(proc, cpu_id);\r
-    if (status) {\r
-        env_free_memory(proc);\r
-        return NULL;\r
-    }\r
-\r
-    /* Enable mapping for the shared memory region */\r
-    env_map_memory((unsigned int) proc->sh_buff.start_addr,\r
-                    (unsigned int) proc->sh_buff.start_addr, proc->sh_buff.size,\r
-                    (SHARED_MEM | UNCACHED));\r
-\r
-    /* Put the new proc in the procs list */\r
-    node = env_allocate_memory(sizeof(struct llist));\r
-\r
-    if (!node) {\r
-        env_free_memory(proc);\r
-        return NULL;\r
-    }\r
-\r
-    node->data = proc;\r
-    add_to_list(&procs.proc_list, node);\r
-\r
-    return proc;\r
-}\r
-\r
-/**\r
- * hil_get_cpuforfw\r
- *\r
- * This function provides the CPU ID for the given firmware.\r
- *\r
- * @param fw_name - name of firmware\r
- *\r
- * @return - cpu id\r
- *\r
- */\r
-int hil_get_cpuforfw(char *fw_name) {\r
-    return (platform_get_processor_for_fw(fw_name));\r
-}\r
-\r
-/**\r
- * hil_delete_proc\r
- *\r
- * This function deletes the given proc instance and frees the\r
- * associated resources.\r
- *\r
- * @param proc - pointer to hil remote_proc instance\r
- *\r
- */\r
-void hil_delete_proc(struct hil_proc *proc) {\r
-    struct llist *proc_hd = NULL;\r
-\r
-    if (!proc)\r
-        return;\r
-\r
-    proc_hd = procs.proc_list;\r
-\r
-    while (proc_hd != NULL) {\r
-        if (proc_hd->data == proc) {\r
-            remove_from_list(&procs.proc_list, proc_hd);\r
-            env_free_memory(proc_hd);\r
-            break;\r
-        }\r
-        proc_hd = proc_hd->next;\r
-    }\r
-\r
-    env_free_memory(proc);\r
-}\r
-\r
-\r
-/**\r
- * hil_isr()\r
- *\r
- * This function is called when interrupt is received for the vring.\r
- * This function gets the corresponding virtqueue and generates\r
- * call back for it.\r
- *\r
- * @param vring_hw   - pointer to vring control block\r
- *\r
- */\r
-void hil_isr(struct proc_vring *vring_hw){\r
-       virtqueue_notification(vring_hw->vq);\r
-}\r
-\r
-/**\r
- * hil_get_proc\r
- *\r
- * This function finds the proc instance based on the given ID\r
- * from the proc list and returns it to user.\r
- *\r
- * @param cpu_id - cpu id\r
- *\r
- * @return - pointer to hil proc instance\r
- *\r
- */\r
-struct hil_proc *hil_get_proc(int cpu_id) {\r
-    struct llist *proc_hd = procs.proc_list;\r
-\r
-    if (!proc_hd)\r
-        return NULL;\r
-\r
-    while (proc_hd != NULL) {\r
-        struct hil_proc *proc = (struct hil_proc *) proc_hd->data;\r
-        if (proc->cpu_id == cpu_id) {\r
-            return proc;\r
-        }\r
-        proc_hd = proc_hd->next;\r
-    }\r
-\r
-    return NULL;\r
-}\r
-\r
-/**\r
- * hil_get_chnl_info\r
- *\r
- * This function returns channels info for given proc.\r
- *\r
- * @param proc - pointer to proc info struct\r
- * @param num_chnls - pointer to integer variable to hold\r
- *                    number of available channels\r
- *\r
- * @return - pointer to channel info control block\r
- *\r
- */\r
-struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls) {\r
-    *num_chnls = proc->num_chnls;\r
-    return (proc->chnls);\r
-}\r
-\r
-/**\r
- * hil_get_vdev_info\r
- *\r
- * This function return virtio device for remote core.\r
- *\r
- * @param proc - pointer to remote proc\r
- *\r
- * @return - pointer to virtio HW device.\r
- *\r
- */\r
-\r
-struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc) {\r
-    return (&proc->vdev);\r
-\r
-}\r
-\r
-/**\r
- * hil_get_vring_info\r
- *\r
- * This function returns vring_info_table. The caller will use\r
- * this table to get the vring HW info which will be subsequently\r
- * used to create virtqueues.\r
- *\r
- * @param vdev - pointer to virtio HW device\r
- * @param num_vrings - pointer to hold number of vrings\r
- *\r
- * @return - pointer to vring hardware info table\r
- */\r
-struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings) {\r
-\r
-    *num_vrings = vdev->num_vrings;\r
-    return (vdev->vring_info);\r
-\r
-}\r
-\r
-/**\r
- * hil_get_shm_info\r
- *\r
- * This function returns shared memory info control block. The caller\r
- * will use this information to create and manage memory buffers for\r
- * vring descriptor table.\r
- *\r
- * @param proc - pointer to proc instance\r
- *\r
- * @return - pointer to shared memory region used for buffers\r
- *\r
- */\r
-struct proc_shm *hil_get_shm_info(struct hil_proc *proc) {\r
-    return (&proc->sh_buff);\r
-}\r
-\r
-/**\r
- * hil_enable_vring_notifications()\r
- *\r
- * This function is called after successful creation of virtqueues.\r
- * This function saves queue handle in the vring_info_table which\r
- * will be used during interrupt handling .This function setups\r
- * interrupt handlers.\r
- *\r
- * @param vring_index - index to vring HW table\r
- * @param vq          - pointer to virtqueue to save in vring HW table\r
- *\r
- * @return            - execution status\r
- */\r
-int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq) {\r
-    struct hil_proc *proc_hw = (struct hil_proc *) vq->vq_dev->device;\r
-    struct proc_vring *vring_hw = &proc_hw->vdev.vring_info[vring_index];\r
-    /* Save virtqueue pointer for later reference */\r
-    vring_hw->vq = vq;\r
-\r
-    if (proc_hw->ops->enable_interrupt) {\r
-        proc_hw->ops->enable_interrupt(vring_hw);\r
-    }\r
-\r
-    return 0;\r
-}\r
-\r
-/**\r
- * hil_vring_notify()\r
- *\r
- * This function generates IPI to let the other side know that there is\r
- * job available for it. The required information to achieve this, like interrupt\r
- * vector, CPU id etc is be obtained from the proc_vring table.\r
- *\r
- * @param vq - pointer to virtqueue\r
- *\r
- */\r
-void hil_vring_notify(struct virtqueue *vq) {\r
-    struct hil_proc *proc_hw = (struct hil_proc *) vq->vq_dev->device;\r
-    struct proc_vring *vring_hw = &proc_hw->vdev.vring_info[vq->vq_queue_index];\r
-\r
-    if (proc_hw->ops->notify) {\r
-        proc_hw->ops->notify(proc_hw->cpu_id, &vring_hw->intr_info);\r
-    }\r
-}\r
-\r
-/**\r
- * hil_get_status\r
- *\r
- * This function is used to check if the given core is up and running.\r
- * This call will return after it is confirmed that remote core has\r
- * started.\r
- *\r
- * @param proc - pointer to proc instance\r
- *\r
- * @return - execution status\r
- */\r
-int hil_get_status(struct hil_proc *proc) {\r
-    /* For future use only.*/\r
-    return 0;\r
-}\r
-\r
-/**\r
- * hil_set_status\r
- *\r
- * This function is used to update the status\r
- * of the given core i.e it is ready for IPC.\r
- *\r
- * @param proc - pointer to remote proc\r
- *\r
- * @return - execution status\r
- */\r
-int hil_set_status(struct hil_proc *proc) {\r
-    /* For future use only.*/\r
-    return 0;\r
-}\r
-\r
-/**\r
- * hil_boot_cpu\r
- *\r
- * This function boots the remote processor.\r
- *\r
- * @param proc       - pointer to remote proc\r
- * @param start_addr - start address of remote cpu\r
- *\r
- * @return - execution status\r
- */\r
-int hil_boot_cpu(struct hil_proc *proc, unsigned int start_addr) {\r
-\r
-    if (proc->ops->boot_cpu) {\r
-        proc->ops->boot_cpu(proc->cpu_id, start_addr);\r
-    }\r
-\r
-#if defined (OPENAMP_BENCHMARK_ENABLE)\r
-    boot_time_stamp = env_get_timestamp();\r
-#endif\r
-\r
-    return 0;\r
-}\r
-\r
-/**\r
- * hil_shutdown_cpu\r
- *\r
- *  This function shutdowns the remote processor\r
- *\r
- * @param proc - pointer to remote proc\r
- *\r
- */\r
-void hil_shutdown_cpu(struct hil_proc *proc) {\r
-    if (proc->ops->shutdown_cpu) {\r
-        proc->ops->shutdown_cpu(proc->cpu_id);\r
-    }\r
-\r
-#if defined (OPENAMP_BENCHMARK_ENABLE)\r
-    shutdown_time_stamp = env_get_timestamp();\r
-#endif\r
-}\r
-\r
-/**\r
- * hil_get_firmware\r
- *\r
- * This function returns address and size of given firmware name passed as\r
- * parameter.\r
- *\r
- * @param fw_name    - name of the firmware\r
- * @param start_addr - pointer t hold start address of firmware\r
- * @param size       - pointer to hold size of firmware\r
- *\r
- * returns -  status of function execution\r
- *\r
- */\r
-int hil_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size){\r
-    return (config_get_firmware(fw_name , start_addr, size));\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       hil.c
+ *
+ * COMPONENT
+ *
+ *         OpenAMP  Stack.
+ *
+ * DESCRIPTION
+ *
+ *       This file is implementation of generic part of HIL.
+ *
+ *
+ *
+ **************************************************************************/
+
+#include "hil.h"
+
+/*--------------------------- Globals ---------------------------------- */
+struct hil_proc_list procs;
+
+#if defined (OPENAMP_BENCHMARK_ENABLE)
+
+unsigned long long boot_time_stamp;
+unsigned long long shutdown_time_stamp;
+
+#endif
+
+extern int platform_get_processor_info(struct hil_proc *proc, int cpu_id);
+extern int platform_get_processor_for_fw(char *fw_name);
+
+/**
+ * hil_create_proc
+ *
+ * This function creates a HIL proc instance for given CPU id and populates
+ * it with platform info.
+ *
+ * @param cpu_id - cpu id
+ *
+ * @return - pointer to proc instance
+ *
+ */
+struct hil_proc *hil_create_proc(int cpu_id) {
+    struct hil_proc *proc = NULL;
+    struct llist *node = NULL;
+    struct llist *proc_hd = procs.proc_list;
+    int status;
+
+    /* If proc already exists then return it */
+    while (proc_hd != NULL) {
+        proc = (struct hil_proc *) proc_hd->data;
+        if (proc->cpu_id == cpu_id) {
+            return proc;
+        }
+        proc_hd = proc_hd->next;
+    }
+
+    /* Allocate memory for proc instance */
+    proc = env_allocate_memory(sizeof(struct hil_proc));
+    if (!proc) {
+        return NULL;
+    }
+
+    /* Get HW specfic info */
+    status = platform_get_processor_info(proc, cpu_id);
+    if (status) {
+        env_free_memory(proc);
+        return NULL;
+    }
+
+    /* Enable mapping for the shared memory region */
+    env_map_memory((unsigned int) proc->sh_buff.start_addr,
+                    (unsigned int) proc->sh_buff.start_addr, proc->sh_buff.size,
+                    (SHARED_MEM | UNCACHED));
+
+    /* Put the new proc in the procs list */
+    node = env_allocate_memory(sizeof(struct llist));
+
+    if (!node) {
+        env_free_memory(proc);
+        return NULL;
+    }
+
+    node->data = proc;
+    add_to_list(&procs.proc_list, node);
+
+    return proc;
+}
+
+/**
+ * hil_get_cpuforfw
+ *
+ * This function provides the CPU ID for the given firmware.
+ *
+ * @param fw_name - name of firmware
+ *
+ * @return - cpu id
+ *
+ */
+int hil_get_cpuforfw(char *fw_name) {
+    return (platform_get_processor_for_fw(fw_name));
+}
+
+/**
+ * hil_delete_proc
+ *
+ * This function deletes the given proc instance and frees the
+ * associated resources.
+ *
+ * @param proc - pointer to hil remote_proc instance
+ *
+ */
+void hil_delete_proc(struct hil_proc *proc) {
+    struct llist *proc_hd = NULL;
+
+    if (!proc)
+        return;
+
+    proc_hd = procs.proc_list;
+
+    while (proc_hd != NULL) {
+        if (proc_hd->data == proc) {
+            remove_from_list(&procs.proc_list, proc_hd);
+            env_free_memory(proc_hd);
+            break;
+        }
+        proc_hd = proc_hd->next;
+    }
+
+    env_free_memory(proc);
+}
+
+
+/**
+ * hil_isr()
+ *
+ * This function is called when interrupt is received for the vring.
+ * This function gets the corresponding virtqueue and generates
+ * call back for it.
+ *
+ * @param vring_hw   - pointer to vring control block
+ *
+ */
+void hil_isr(struct proc_vring *vring_hw){
+       virtqueue_notification(vring_hw->vq);
+}
+
+/**
+ * hil_get_proc
+ *
+ * This function finds the proc instance based on the given ID
+ * from the proc list and returns it to user.
+ *
+ * @param cpu_id - cpu id
+ *
+ * @return - pointer to hil proc instance
+ *
+ */
+struct hil_proc *hil_get_proc(int cpu_id) {
+    struct llist *proc_hd = procs.proc_list;
+
+    if (!proc_hd)
+        return NULL;
+
+    while (proc_hd != NULL) {
+        struct hil_proc *proc = (struct hil_proc *) proc_hd->data;
+        if (proc->cpu_id == cpu_id) {
+            return proc;
+        }
+        proc_hd = proc_hd->next;
+    }
+
+    return NULL;
+}
+
+/**
+ * hil_get_chnl_info
+ *
+ * This function returns channels info for given proc.
+ *
+ * @param proc - pointer to proc info struct
+ * @param num_chnls - pointer to integer variable to hold
+ *                    number of available channels
+ *
+ * @return - pointer to channel info control block
+ *
+ */
+struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc, int *num_chnls) {
+    *num_chnls = proc->num_chnls;
+    return (proc->chnls);
+}
+
+/**
+ * hil_get_vdev_info
+ *
+ * This function return virtio device for remote core.
+ *
+ * @param proc - pointer to remote proc
+ *
+ * @return - pointer to virtio HW device.
+ *
+ */
+
+struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc) {
+    return (&proc->vdev);
+
+}
+
+/**
+ * hil_get_vring_info
+ *
+ * This function returns vring_info_table. The caller will use
+ * this table to get the vring HW info which will be subsequently
+ * used to create virtqueues.
+ *
+ * @param vdev - pointer to virtio HW device
+ * @param num_vrings - pointer to hold number of vrings
+ *
+ * @return - pointer to vring hardware info table
+ */
+struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings) {
+
+    *num_vrings = vdev->num_vrings;
+    return (vdev->vring_info);
+
+}
+
+/**
+ * hil_get_shm_info
+ *
+ * This function returns shared memory info control block. The caller
+ * will use this information to create and manage memory buffers for
+ * vring descriptor table.
+ *
+ * @param proc - pointer to proc instance
+ *
+ * @return - pointer to shared memory region used for buffers
+ *
+ */
+struct proc_shm *hil_get_shm_info(struct hil_proc *proc) {
+    return (&proc->sh_buff);
+}
+
+/**
+ * hil_enable_vring_notifications()
+ *
+ * This function is called after successful creation of virtqueues.
+ * This function saves queue handle in the vring_info_table which
+ * will be used during interrupt handling .This function setups
+ * interrupt handlers.
+ *
+ * @param vring_index - index to vring HW table
+ * @param vq          - pointer to virtqueue to save in vring HW table
+ *
+ * @return            - execution status
+ */
+int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq) {
+    struct hil_proc *proc_hw = (struct hil_proc *) vq->vq_dev->device;
+    struct proc_vring *vring_hw = &proc_hw->vdev.vring_info[vring_index];
+    /* Save virtqueue pointer for later reference */
+    vring_hw->vq = vq;
+
+    if (proc_hw->ops->enable_interrupt) {
+        proc_hw->ops->enable_interrupt(vring_hw);
+    }
+
+    return 0;
+}
+
+/**
+ * hil_vring_notify()
+ *
+ * This function generates IPI to let the other side know that there is
+ * job available for it. The required information to achieve this, like interrupt
+ * vector, CPU id etc is be obtained from the proc_vring table.
+ *
+ * @param vq - pointer to virtqueue
+ *
+ */
+void hil_vring_notify(struct virtqueue *vq) {
+    struct hil_proc *proc_hw = (struct hil_proc *) vq->vq_dev->device;
+    struct proc_vring *vring_hw = &proc_hw->vdev.vring_info[vq->vq_queue_index];
+
+    if (proc_hw->ops->notify) {
+        proc_hw->ops->notify(proc_hw->cpu_id, &vring_hw->intr_info);
+    }
+}
+
+/**
+ * hil_get_status
+ *
+ * This function is used to check if the given core is up and running.
+ * This call will return after it is confirmed that remote core has
+ * started.
+ *
+ * @param proc - pointer to proc instance
+ *
+ * @return - execution status
+ */
+int hil_get_status(struct hil_proc *proc) {
+    /* For future use only.*/
+    return 0;
+}
+
+/**
+ * hil_set_status
+ *
+ * This function is used to update the status
+ * of the given core i.e it is ready for IPC.
+ *
+ * @param proc - pointer to remote proc
+ *
+ * @return - execution status
+ */
+int hil_set_status(struct hil_proc *proc) {
+    /* For future use only.*/
+    return 0;
+}
+
+/**
+ * hil_boot_cpu
+ *
+ * This function boots the remote processor.
+ *
+ * @param proc       - pointer to remote proc
+ * @param start_addr - start address of remote cpu
+ *
+ * @return - execution status
+ */
+int hil_boot_cpu(struct hil_proc *proc, unsigned int start_addr) {
+
+    if (proc->ops->boot_cpu) {
+        proc->ops->boot_cpu(proc->cpu_id, start_addr);
+    }
+
+#if defined (OPENAMP_BENCHMARK_ENABLE)
+    boot_time_stamp = env_get_timestamp();
+#endif
+
+    return 0;
+}
+
+/**
+ * hil_shutdown_cpu
+ *
+ *  This function shutdowns the remote processor
+ *
+ * @param proc - pointer to remote proc
+ *
+ */
+void hil_shutdown_cpu(struct hil_proc *proc) {
+    if (proc->ops->shutdown_cpu) {
+        proc->ops->shutdown_cpu(proc->cpu_id);
+    }
+
+#if defined (OPENAMP_BENCHMARK_ENABLE)
+    shutdown_time_stamp = env_get_timestamp();
+#endif
+}
+
+/**
+ * hil_get_firmware
+ *
+ * This function returns address and size of given firmware name passed as
+ * parameter.
+ *
+ * @param fw_name    - name of the firmware
+ * @param start_addr - pointer t hold start address of firmware
+ * @param size       - pointer to hold size of firmware
+ *
+ * returns -  status of function execution
+ *
+ */
+int hil_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size){
+    return (config_get_firmware(fw_name , start_addr, size));
+}
index 3f276c962bbf9d183d7f6af20acfa36322b9ecbd..0f5ce2d2c939737c2efcad1a60c149b3c95ab340 100644 (file)
-#ifndef _HIL_H_\r
-#define _HIL_H_\r
-\r
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors\r
- *    may be used to endorse or promote products derived from this software\r
- *    without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       hil.h\r
- *\r
- * DESCRIPTION\r
- *\r
- *       This file defines interface layer to access hardware features. This\r
- *       interface is used by both RPMSG and remoteproc components.\r
- *\r
- ***************************************************************************/\r
-\r
-#include "../../virtio/virtio.h"\r
-#include "../../porting/config/config.h"\r
-\r
-/* Configurable parameters */\r
-#define HIL_MAX_CORES                   2\r
-#define HIL_MAX_NUM_VRINGS              2\r
-#define HIL_MAX_NUM_CHANNELS            1\r
-/* Reserved CPU id */\r
-#define HIL_RSVD_CPU_ID                 0xffffffff\r
-\r
-/**\r
- * struct proc_shm\r
- *\r
- * This structure is maintained by hardware interface layer for\r
- * shared memory information. The shared memory provides buffers\r
- * for use by the vring to exchange messages between the cores.\r
- *\r
- */\r
-struct proc_shm\r
-{\r
-    /* Start address of shared memory used for buffers. */\r
-    void *start_addr;\r
-    /* Size of shared memory. */\r
-    unsigned long size;\r
-    /* Attributes for shared memory - cached or uncached. */\r
-    unsigned long flags;\r
-};\r
-\r
-/**\r
-* struct proc_intr\r
-*\r
-* This structure is maintained by hardware interface layer for\r
-* notification(interrupts) mechanism. The most common notification mechanism\r
-* is Inter-Processor Interrupt(IPI). There can be other mechanism depending\r
-* on SoC architecture.\r
-*\r
-*/\r
-struct proc_intr\r
-{\r
-   /* Interrupt number for vring - use for IPI */\r
-   unsigned int vect_id;\r
-   /* Interrupt priority */\r
-   unsigned int priority;\r
-   /* Interrupt trigger type */\r
-   unsigned int trigger_type;\r
-   /* Private data */\r
-   void *data;\r
-};\r
-\r
-/**\r
-* struct proc_vring\r
-*\r
-* This structure is maintained by hardware interface layer to keep\r
-* vring physical memory and notification info.\r
-*\r
-*/\r
-struct proc_vring\r
-{\r
-   /* Pointer to virtqueue encapsulating the vring */\r
-   struct virtqueue *vq;\r
-   /* Vring physical address */\r
-   void *phy_addr;\r
-   /* Number of vring descriptors */\r
-   unsigned short num_descs;\r
-   /* Vring alignment*/\r
-   unsigned long align;\r
-   /* Vring interrupt control block */\r
-   struct proc_intr intr_info;\r
-};\r
-\r
-/**\r
- * struct proc_vdev\r
- *\r
- * This structure represents a virtio HW device for remote processor.\r
- * Currently only one virtio device per processor is supported.\r
- *\r
- */\r
-struct proc_vdev\r
-{\r
-    /* Number of vrings*/\r
-    unsigned int num_vrings;\r
-    /* Virtio device features */\r
-    unsigned int dfeatures;\r
-    /* Virtio gen features */\r
-    unsigned int gfeatures;\r
-    /* Vring info control blocks */\r
-    struct proc_vring vring_info[HIL_MAX_NUM_VRINGS];\r
-};\r
-\r
-/**\r
- * struct proc_chnl\r
- *\r
- * This structure represents channel IDs that would be used by\r
- * the remote in the name service message. This will be extended\r
- * further to support static channel creation.\r
- *\r
- */\r
-struct proc_chnl\r
-{\r
-    /* Channel ID */\r
-    char name[32];\r
-};\r
-\r
-/**\r
-* struct hil_proc\r
-*\r
-* This structure represents a remote processor and encapsulates shared\r
-* memory and notification info required for IPC.\r
-*\r
-*/\r
-struct hil_proc\r
-{\r
-    /* CPU ID as defined by the platform */\r
-    unsigned long cpu_id;\r
-    /* Shared memory info */\r
-    struct proc_shm sh_buff;\r
-    /* Virtio device hardware info */\r
-    struct proc_vdev vdev;\r
-    /* Number of RPMSG channels */\r
-    unsigned long num_chnls;\r
-    /* RPMsg channels array */\r
-    struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS];\r
-    /* HIL platform ops table */\r
-    struct hil_platform_ops *ops;\r
-    /* Attrbites to represent processor role, master or remote . This field is for\r
-     * future use. */\r
-    unsigned long attr;\r
-    /*\r
-     * CPU bitmask - shared variable updated by each core\r
-     * after it has been initialized. This field is for future use.\r
-     */\r
-    unsigned long cpu_bitmask;\r
-    /* Spin lock - This field is for future use. */\r
-    volatile unsigned int *slock;\r
-};\r
-\r
-/**\r
- * struct hil_proc_list\r
- *\r
- * This structure serves as lists for cores present in the system.\r
- * It provides entry point to access remote core parameters.\r
- *\r
- */\r
-struct hil_proc_list {\r
-    struct llist *proc_list;\r
-};\r
-\r
-/**\r
- * hil_create_proc\r
- *\r
- * This function creates a HIL proc instance for given CPU id and populates\r
- * it with platform info.\r
- *\r
- * @param cpu_id - cpu id\r
- *\r
- * @return - pointer to proc instance\r
- *\r
- */\r
-struct hil_proc *hil_create_proc(int cpu_id);\r
-\r
-/**\r
- * hil_delete_proc\r
- *\r
- * This function deletes the given proc instance and frees the\r
- * associated resources.\r
- *\r
- * @param proc - pointer to HIL proc instance\r
- *\r
- */\r
-void hil_delete_proc(struct hil_proc *proc);\r
-\r
-/**\r
- * hil_get_proc\r
- *\r
- * This function finds the proc instance based on the given ID\r
- * from the proc list and returns it to user.\r
- *\r
- * @param cpu_id - cpu id\r
- *\r
- * @return - pointer to proc instance\r
- *\r
- */\r
-struct hil_proc *hil_get_proc(int cpu_id);\r
-\r
-/**\r
- * hil_isr()\r
- *\r
- * This function is called when interrupt is received for the vring.\r
- * This function gets the corresponding virtqueue and generates\r
- * call back for it.\r
- *\r
- * @param vring_hw   - pointer to vring control block\r
- *\r
- */\r
-void hil_isr(struct proc_vring *vring_hw);\r
-\r
-/**\r
- * hil_get_cpuforfw\r
- *\r
- * This function provides the CPU ID for the given firmware.\r
- *\r
- * @param fw_name - name of firmware\r
- *\r
- * @return - cpu id\r
- *\r
- */\r
-int hil_get_cpuforfw(char *fw_name);\r
-\r
-/**\r
- * hil_get_vdev_info\r
- *\r
- * This function return virtio device for remote core.\r
- *\r
- * @param proc - pointer to remote proc\r
- *\r
- * @return - pointer to virtio HW device.\r
- *\r
- */\r
-struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc);\r
-\r
-/**\r
- * hil_get_chnl_info\r
- *\r
- * This function returns channels info for given proc.\r
- *\r
- * @param proc - pointer to proc info struct\r
- * @param num_chnls - pointer to integer variable to hold\r
- *                    number of available channels\r
- *\r
- * @return - pointer to channel info control block\r
- *\r
- */\r
-struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc , int *num_chnls);\r
-\r
-/**\r
- * hil_get_vring_info\r
- *\r
- * This function returns vring_info_table. The caller will use\r
- * this table to get the vring HW info which will be subsequently\r
- * used to create virtqueues.\r
- *\r
- * @param vdev - pointer to virtio HW device\r
- * @param num_vrings - pointer to hold number of vrings\r
- *\r
- * @return - pointer to vring hardware info table\r
- */\r
-struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings);\r
-\r
-/**\r
- * hil_get_shm_info\r
- *\r
- * This function returns shared memory info control block. The caller\r
- * will use this information to create and manage memory buffers for\r
- * vring descriptor table.\r
- *\r
- * @param proc - pointer to proc instance\r
- *\r
- * @return - pointer to shared memory region used for buffers\r
- *\r
- */\r
-struct proc_shm *hil_get_shm_info(struct hil_proc *proc);\r
-\r
-/**\r
- * hil_enable_vring_notifications()\r
- *\r
- * This function is called after successful creation of virtqueues.\r
- * This function saves queue handle in the vring_info_table which\r
- * will be used during interrupt handling .This function setups\r
- * interrupt handlers.\r
- *\r
- * @param vring_index - index to vring HW table\r
- * @param vq          - pointer to virtqueue to save in vring HW table\r
- *\r
- * @return            - execution status\r
- */\r
-int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq);\r
-\r
-/**\r
- * hil_vring_notify()\r
- *\r
- * This function generates IPI to let the other side know that there is\r
- * job available for it. The required information to achieve this, like interrupt\r
- * vector, CPU id etc is be obtained from the proc_vring table.\r
- *\r
- * @param vq - pointer to virtqueue\r
- *\r
- */\r
-void hil_vring_notify(struct virtqueue *vq);\r
-\r
-/**\r
- * hil_get_status\r
- *\r
- * This function is used to check if the given core is up and running.\r
- * This call will return after it is confirmed that remote core has\r
- * started.\r
- *\r
- * @param proc - pointer to proc instance\r
- *\r
- * @return - execution status\r
- */\r
-int hil_get_status(struct hil_proc *proc);\r
-\r
-/**\r
- * hil_set_status\r
- *\r
- * This function is used to update the status\r
- * of the given core i.e it is ready for IPC.\r
- *\r
- * @param proc - pointer to remote proc\r
- *\r
- * @return - execution status\r
- */\r
-\r
-int hil_set_status(struct hil_proc *proc);\r
-\r
-/**\r
- * hil_boot_cpu\r
- *\r
- * This function starts remote processor at given address.\r
- *\r
- * @param proc      - pointer to remote proc\r
- * @param load_addr - load address of remote firmware\r
- *\r
- * @return - execution status\r
- */\r
-int hil_boot_cpu(struct hil_proc *proc , unsigned int load_addr);\r
-\r
-/**\r
- * hil_shutdown_cpu\r
- *\r
- *  This function shutdowns the remote processor\r
- *\r
- * @param proc - pointer to remote proc\r
- *\r
- */\r
-void hil_shutdown_cpu(struct hil_proc *proc);\r
-\r
-/**\r
- * hil_get_firmware\r
- *\r
- * This function returns address and size of given firmware name passed as\r
- * parameter.\r
- *\r
- * @param fw_name    - name of the firmware\r
- * @param start_addr - pointer t hold start address of firmware\r
- * @param size       - pointer to hold size of firmware\r
- *\r
- * returns -  status of function execution\r
- *\r
- */\r
-int hil_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size);\r
-\r
-/**\r
- *\r
- * This structure is an interface between HIL and platform porting\r
- * component. It is required for the user to provide definitions of\r
- * these functions when framework is ported to new hardware platform.\r
- *\r
- */\r
-struct hil_platform_ops\r
-{\r
-    /**\r
-     * enable_interrupt()\r
-     *\r
-     * This function enables interrupt(IPI) for given vring.\r
-     *\r
-     * @param vring_hw - pointer to vring control block\r
-     *\r
-     * @return  - execution status\r
-     */\r
-    int (*enable_interrupt)(struct proc_vring *vring_hw);\r
-\r
+#ifndef _HIL_H_
+#define _HIL_H_
+
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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
+ *
+ *       hil.h
+ *
+ * DESCRIPTION
+ *
+ *       This file defines interface layer to access hardware features. This
+ *       interface is used by both RPMSG and remoteproc components.
+ *
+ ***************************************************************************/
+
+#include "../../virtio/virtio.h"
+#include "../../porting/config/config.h"
+
+/* Configurable parameters */
+#define HIL_MAX_CORES                   2
+#define HIL_MAX_NUM_VRINGS              2
+#define HIL_MAX_NUM_CHANNELS            1
+/* Reserved CPU id */
+#define HIL_RSVD_CPU_ID                 0xffffffff
+
+/**
+ * struct proc_shm
+ *
+ * This structure is maintained by hardware interface layer for
+ * shared memory information. The shared memory provides buffers
+ * for use by the vring to exchange messages between the cores.
+ *
+ */
+struct proc_shm
+{
+    /* Start address of shared memory used for buffers. */
+    void *start_addr;
+    /* Size of shared memory. */
+    unsigned long size;
+    /* Attributes for shared memory - cached or uncached. */
+    unsigned long flags;
+};
+
+/**
+* struct proc_intr
+*
+* This structure is maintained by hardware interface layer for
+* notification(interrupts) mechanism. The most common notification mechanism
+* is Inter-Processor Interrupt(IPI). There can be other mechanism depending
+* on SoC architecture.
+*
+*/
+struct proc_intr
+{
+   /* Interrupt number for vring - use for IPI */
+   unsigned int vect_id;
+   /* Interrupt priority */
+   unsigned int priority;
+   /* Interrupt trigger type */
+   unsigned int trigger_type;
+   /* Private data */
+   void *data;
+};
+
+/**
+* struct proc_vring
+*
+* This structure is maintained by hardware interface layer to keep
+* vring physical memory and notification info.
+*
+*/
+struct proc_vring
+{
+   /* Pointer to virtqueue encapsulating the vring */
+   struct virtqueue *vq;
+   /* Vring physical address */
+   void *phy_addr;
+   /* Number of vring descriptors */
+   unsigned short num_descs;
+   /* Vring alignment*/
+   unsigned long align;
+   /* Vring interrupt control block */
+   struct proc_intr intr_info;
+};
+
+/**
+ * struct proc_vdev
+ *
+ * This structure represents a virtio HW device for remote processor.
+ * Currently only one virtio device per processor is supported.
+ *
+ */
+struct proc_vdev
+{
+    /* Number of vrings*/
+    unsigned int num_vrings;
+    /* Virtio device features */
+    unsigned int dfeatures;
+    /* Virtio gen features */
+    unsigned int gfeatures;
+    /* Vring info control blocks */
+    struct proc_vring vring_info[HIL_MAX_NUM_VRINGS];
+};
+
+/**
+ * struct proc_chnl
+ *
+ * This structure represents channel IDs that would be used by
+ * the remote in the name service message. This will be extended
+ * further to support static channel creation.
+ *
+ */
+struct proc_chnl
+{
+    /* Channel ID */
+    char name[32];
+};
+
+/**
+* struct hil_proc
+*
+* This structure represents a remote processor and encapsulates shared
+* memory and notification info required for IPC.
+*
+*/
+struct hil_proc
+{
+    /* CPU ID as defined by the platform */
+    unsigned long cpu_id;
+    /* Shared memory info */
+    struct proc_shm sh_buff;
+    /* Virtio device hardware info */
+    struct proc_vdev vdev;
+    /* Number of RPMSG channels */
+    unsigned long num_chnls;
+    /* RPMsg channels array */
+    struct proc_chnl chnls[HIL_MAX_NUM_CHANNELS];
+    /* HIL platform ops table */
+    struct hil_platform_ops *ops;
+    /* Attrbites to represent processor role, master or remote . This field is for
+     * future use. */
+    unsigned long attr;
+    /*
+     * CPU bitmask - shared variable updated by each core
+     * after it has been initialized. This field is for future use.
+     */
+    unsigned long cpu_bitmask;
+    /* Spin lock - This field is for future use. */
+    volatile unsigned int *slock;
+};
+
+/**
+ * struct hil_proc_list
+ *
+ * This structure serves as lists for cores present in the system.
+ * It provides entry point to access remote core parameters.
+ *
+ */
+struct hil_proc_list {
+    struct llist *proc_list;
+};
+
+/**
+ * hil_create_proc
+ *
+ * This function creates a HIL proc instance for given CPU id and populates
+ * it with platform info.
+ *
+ * @param cpu_id - cpu id
+ *
+ * @return - pointer to proc instance
+ *
+ */
+struct hil_proc *hil_create_proc(int cpu_id);
+
+/**
+ * hil_delete_proc
+ *
+ * This function deletes the given proc instance and frees the
+ * associated resources.
+ *
+ * @param proc - pointer to HIL proc instance
+ *
+ */
+void hil_delete_proc(struct hil_proc *proc);
+
+/**
+ * hil_get_proc
+ *
+ * This function finds the proc instance based on the given ID
+ * from the proc list and returns it to user.
+ *
+ * @param cpu_id - cpu id
+ *
+ * @return - pointer to proc instance
+ *
+ */
+struct hil_proc *hil_get_proc(int cpu_id);
+
+/**
+ * hil_isr()
+ *
+ * This function is called when interrupt is received for the vring.
+ * This function gets the corresponding virtqueue and generates
+ * call back for it.
+ *
+ * @param vring_hw   - pointer to vring control block
+ *
+ */
+void hil_isr(struct proc_vring *vring_hw);
+
+/**
+ * hil_get_cpuforfw
+ *
+ * This function provides the CPU ID for the given firmware.
+ *
+ * @param fw_name - name of firmware
+ *
+ * @return - cpu id
+ *
+ */
+int hil_get_cpuforfw(char *fw_name);
+
+/**
+ * hil_get_vdev_info
+ *
+ * This function return virtio device for remote core.
+ *
+ * @param proc - pointer to remote proc
+ *
+ * @return - pointer to virtio HW device.
+ *
+ */
+struct proc_vdev *hil_get_vdev_info(struct hil_proc *proc);
+
+/**
+ * hil_get_chnl_info
+ *
+ * This function returns channels info for given proc.
+ *
+ * @param proc - pointer to proc info struct
+ * @param num_chnls - pointer to integer variable to hold
+ *                    number of available channels
+ *
+ * @return - pointer to channel info control block
+ *
+ */
+struct proc_chnl *hil_get_chnl_info(struct hil_proc *proc , int *num_chnls);
+
+/**
+ * hil_get_vring_info
+ *
+ * This function returns vring_info_table. The caller will use
+ * this table to get the vring HW info which will be subsequently
+ * used to create virtqueues.
+ *
+ * @param vdev - pointer to virtio HW device
+ * @param num_vrings - pointer to hold number of vrings
+ *
+ * @return - pointer to vring hardware info table
+ */
+struct proc_vring *hil_get_vring_info(struct proc_vdev *vdev, int *num_vrings);
+
+/**
+ * hil_get_shm_info
+ *
+ * This function returns shared memory info control block. The caller
+ * will use this information to create and manage memory buffers for
+ * vring descriptor table.
+ *
+ * @param proc - pointer to proc instance
+ *
+ * @return - pointer to shared memory region used for buffers
+ *
+ */
+struct proc_shm *hil_get_shm_info(struct hil_proc *proc);
+
+/**
+ * hil_enable_vring_notifications()
+ *
+ * This function is called after successful creation of virtqueues.
+ * This function saves queue handle in the vring_info_table which
+ * will be used during interrupt handling .This function setups
+ * interrupt handlers.
+ *
+ * @param vring_index - index to vring HW table
+ * @param vq          - pointer to virtqueue to save in vring HW table
+ *
+ * @return            - execution status
+ */
+int hil_enable_vring_notifications(int vring_index, struct virtqueue *vq);
+
+/**
+ * hil_vring_notify()
+ *
+ * This function generates IPI to let the other side know that there is
+ * job available for it. The required information to achieve this, like interrupt
+ * vector, CPU id etc is be obtained from the proc_vring table.
+ *
+ * @param vq - pointer to virtqueue
+ *
+ */
+void hil_vring_notify(struct virtqueue *vq);
+
+/**
+ * hil_get_status
+ *
+ * This function is used to check if the given core is up and running.
+ * This call will return after it is confirmed that remote core has
+ * started.
+ *
+ * @param proc - pointer to proc instance
+ *
+ * @return - execution status
+ */
+int hil_get_status(struct hil_proc *proc);
+
+/**
+ * hil_set_status
+ *
+ * This function is used to update the status
+ * of the given core i.e it is ready for IPC.
+ *
+ * @param proc - pointer to remote proc
+ *
+ * @return - execution status
+ */
+
+int hil_set_status(struct hil_proc *proc);
+
+/**
+ * hil_boot_cpu
+ *
+ * This function starts remote processor at given address.
+ *
+ * @param proc      - pointer to remote proc
+ * @param load_addr - load address of remote firmware
+ *
+ * @return - execution status
+ */
+int hil_boot_cpu(struct hil_proc *proc , unsigned int load_addr);
+
+/**
+ * hil_shutdown_cpu
+ *
+ *  This function shutdowns the remote processor
+ *
+ * @param proc - pointer to remote proc
+ *
+ */
+void hil_shutdown_cpu(struct hil_proc *proc);
+
+/**
+ * hil_get_firmware
+ *
+ * This function returns address and size of given firmware name passed as
+ * parameter.
+ *
+ * @param fw_name    - name of the firmware
+ * @param start_addr - pointer t hold start address of firmware
+ * @param size       - pointer to hold size of firmware
+ *
+ * returns -  status of function execution
+ *
+ */
+int hil_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size);
+
+/**
+ *
+ * This structure is an interface between HIL and platform porting
+ * component. It is required for the user to provide definitions of
+ * these functions when framework is ported to new hardware platform.
+ *
+ */
+struct hil_platform_ops
+{
+    /**
+     * enable_interrupt()
+     *
+     * This function enables interrupt(IPI) for given vring.
+     *
+     * @param vring_hw - pointer to vring control block
+     *
+     * @return  - execution status
+     */
+    int (*enable_interrupt)(struct proc_vring *vring_hw);
+
     /**
      * reg_ipi_after_deinit()
      * This function register interrupt(IPI) after openamp resource .
@@ -422,73 +422,73 @@ struct hil_platform_ops
      */
     void (*reg_ipi_after_deinit)(struct proc_vring *vring_hw);
 
-    /**\r
-     * notify()\r
-     *\r
-     * This function generates IPI to let the other side know that there is\r
-     * job available for it.\r
-     *\r
-     * @param cpu_id - ID of CPU which is to be notified\r
-     * @param intr_info - pointer to interrupt info control block\r
-     */\r
-    void (*notify)(int cpu_id , struct proc_intr *intr_info);\r
-\r
-    /**\r
-     * get_status\r
-     *\r
-     * This function is used to check if the given core is\r
-     * up and running. This call will return after it is confirmed\r
-     * that remote core is initialized.\r
-     *\r
-     * @param cpu_id - ID of CPU for which status is requested.\r
-     *\r
-     * @return - execution status\r
-     */\r
-    int (*get_status)(int cpu_id);\r
-\r
-    /**\r
-     * set_status\r
-     *\r
-     * This function is used to update the status\r
-     * of the given core i.e it is ready for IPC.\r
-     *\r
-     * @param cpu_id - ID of CPU for which status is to be set\r
-     *\r
-     * @return - execution status\r
-     */\r
-\r
-    int (*set_status)(int cpu_id);\r
-\r
-    /**\r
-     * boot_cpu\r
-     *\r
-     * This function boots the remote processor.\r
-     *\r
-     * @param cpu_id     - ID of CPU to boot\r
-     * @param start_addr - start address of remote cpu\r
-     *\r
-     * @return - execution status\r
-     */\r
-    int (*boot_cpu)(int cpu_id , unsigned int start_addr);\r
-\r
-    /**\r
-     * shutdown_cpu\r
-     *\r
-     *  This function shutdowns the remote processor.\r
-     *\r
-     * @param cpu_id    - ID of CPU to shutdown\r
-     *\r
-     */\r
-    void (*shutdown_cpu)(int cpu_id);\r
-\r
-};\r
-\r
-/* Utility macros for register read/write */\r
-#define         HIL_MEM_READ8(addr)         *(volatile unsigned char *)(addr)\r
-#define         HIL_MEM_READ16(addr)        *(volatile unsigned short *)(addr)\r
-#define         HIL_MEM_READ32(addr)        *(volatile unsigned long *)(addr)\r
-#define         HIL_MEM_WRITE8(addr,data)   *(volatile unsigned char *)(addr) = (unsigned char)(data)\r
-#define         HIL_MEM_WRITE16(addr,data)  *(volatile unsigned short *)(addr) = (unsigned short)(data)\r
-#define         HIL_MEM_WRITE32(addr,data)  *(volatile unsigned long *)(addr) = (unsigned long)(data)\r
-\r
-#endif /* _HIL_H_ */\r
+    /**
+     * notify()
+     *
+     * This function generates IPI to let the other side know that there is
+     * job available for it.
+     *
+     * @param cpu_id - ID of CPU which is to be notified
+     * @param intr_info - pointer to interrupt info control block
+     */
+    void (*notify)(int cpu_id , struct proc_intr *intr_info);
+
+    /**
+     * get_status
+     *
+     * This function is used to check if the given core is
+     * up and running. This call will return after it is confirmed
+     * that remote core is initialized.
+     *
+     * @param cpu_id - ID of CPU for which status is requested.
+     *
+     * @return - execution status
+     */
+    int (*get_status)(int cpu_id);
+
+    /**
+     * set_status
+     *
+     * This function is used to update the status
+     * of the given core i.e it is ready for IPC.
+     *
+     * @param cpu_id - ID of CPU for which status is to be set
+     *
+     * @return - execution status
+     */
+
+    int (*set_status)(int cpu_id);
+
+    /**
+     * boot_cpu
+     *
+     * This function boots the remote processor.
+     *
+     * @param cpu_id     - ID of CPU to boot
+     * @param start_addr - start address of remote cpu
+     *
+     * @return - execution status
+     */
+    int (*boot_cpu)(int cpu_id , unsigned int start_addr);
+
+    /**
+     * shutdown_cpu
+     *
+     *  This function shutdowns the remote processor.
+     *
+     * @param cpu_id    - ID of CPU to shutdown
+     *
+     */
+    void (*shutdown_cpu)(int cpu_id);
+
+};
+
+/* Utility macros for register read/write */
+#define         HIL_MEM_READ8(addr)         *(volatile unsigned char *)(addr)
+#define         HIL_MEM_READ16(addr)        *(volatile unsigned short *)(addr)
+#define         HIL_MEM_READ32(addr)        *(volatile unsigned long *)(addr)
+#define         HIL_MEM_WRITE8(addr,data)   *(volatile unsigned char *)(addr) = (unsigned char)(data)
+#define         HIL_MEM_WRITE16(addr,data)  *(volatile unsigned short *)(addr) = (unsigned short)(data)
+#define         HIL_MEM_WRITE32(addr,data)  *(volatile unsigned long *)(addr) = (unsigned long)(data)
+
+#endif /* _HIL_H_ */
index 6c9c5ccb3751ab35564abb8e3d00d9ab40c63284..37e888c0d491a658aa74a0a986b63975bd5c42ee 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       llist.c\r
- *\r
- * COMPONENT\r
- *\r
- *         OpenAMP stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- *       Source file for basic linked list service.\r
- *\r
- **************************************************************************/\r
-#include "llist.h"\r
-\r
-#define LIST_NULL  ((void *)0)\r
-/**\r
- * add_to_list\r
- *\r
- * Places new element at the start of the list.\r
- *\r
- * @param head - list head\r
- * @param node - new element to add\r
- *\r
- */\r
-void add_to_list(struct llist **head, struct llist *node) {\r
-\r
-    if (!node)\r
-        return;\r
-\r
-    if (*head) {\r
-        /* Place the new element at the start of list. */\r
-        node->next = *head;\r
-        node->prev = LIST_NULL;\r
-        (*head)->prev = node;\r
-        *head = node;\r
-    } else {\r
-        /* List is empty - assign new element to list head. */\r
-        *head = node;\r
-        (*head)->next = LIST_NULL;\r
-        (*head)->prev = LIST_NULL;\r
-    }\r
-}\r
-\r
-/**\r
- * remove_from_list\r
- *\r
- * Removes the given element from the list.\r
- *\r
- * @param head    - list head\r
- * @param element - element to remove from list\r
- *\r
- */\r
-void remove_from_list(struct llist **head, struct llist *node) {\r
-\r
-    if (!(*head) || !(node))\r
-        return;\r
-\r
-    if (node == *head) {\r
-        /* First element has to be removed. */\r
-        *head = (*head)->next;\r
-    } else if (node->next == LIST_NULL) {\r
-        /* Last element has to be removed. */\r
-        node->prev->next = node->next;\r
-    } else {\r
-        /* Intermediate element has to be removed. */\r
-        node->prev->next = node->next;\r
-        node->next->prev = node->prev;\r
-    }\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       llist.c
+ *
+ * COMPONENT
+ *
+ *         OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ *       Source file for basic linked list service.
+ *
+ **************************************************************************/
+#include "llist.h"
+
+#define LIST_NULL  ((void *)0)
+/**
+ * add_to_list
+ *
+ * Places new element at the start of the list.
+ *
+ * @param head - list head
+ * @param node - new element to add
+ *
+ */
+void add_to_list(struct llist **head, struct llist *node) {
+
+    if (!node)
+        return;
+
+    if (*head) {
+        /* Place the new element at the start of list. */
+        node->next = *head;
+        node->prev = LIST_NULL;
+        (*head)->prev = node;
+        *head = node;
+    } else {
+        /* List is empty - assign new element to list head. */
+        *head = node;
+        (*head)->next = LIST_NULL;
+        (*head)->prev = LIST_NULL;
+    }
+}
+
+/**
+ * remove_from_list
+ *
+ * Removes the given element from the list.
+ *
+ * @param head    - list head
+ * @param element - element to remove from list
+ *
+ */
+void remove_from_list(struct llist **head, struct llist *node) {
+
+    if (!(*head) || !(node))
+        return;
+
+    if (node == *head) {
+        /* First element has to be removed. */
+        *head = (*head)->next;
+    } else if (node->next == LIST_NULL) {
+        /* Last element has to be removed. */
+        node->prev->next = node->next;
+    } else {
+        /* Intermediate element has to be removed. */
+        node->prev->next = node->next;
+        node->next->prev = node->prev;
+    }
+}
index 19091693b3717e8d33d8fba4619b8d077eb4fbfb..004f4e09247771487bc14c4cff1be10d915748a0 100644 (file)
@@ -1,59 +1,59 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       llist.h\r
- *\r
- * COMPONENT\r
- *\r
- *         OpenAMP stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- *       Header file for linked list service.\r
- *\r
- **************************************************************************/\r
-\r
-#ifndef LLIST_H_\r
-#define LLIST_H_\r
-\r
-struct llist {\r
-    void *data;\r
-    unsigned int attr;\r
-    struct llist *next;\r
-    struct llist *prev;\r
-};\r
-\r
-void add_to_list(struct llist **head, struct llist *node);\r
-void remove_from_list(struct llist **head, struct llist *node);\r
-\r
-#endif /* LLIST_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       llist.h
+ *
+ * COMPONENT
+ *
+ *         OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ *       Header file for linked list service.
+ *
+ **************************************************************************/
+
+#ifndef LLIST_H_
+#define LLIST_H_
+
+struct llist {
+    void *data;
+    unsigned int attr;
+    struct llist *next;
+    struct llist *prev;
+};
+
+void add_to_list(struct llist **head, struct llist *node);
+void remove_from_list(struct llist **head, struct llist *node);
+
+#endif /* LLIST_H_ */
index 100a336f2016ee66f54996c6692adca62a0c1841..6a290a4802be4ca329aadba27c873adcad8c50c3 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       sh_mem.c\r
- *\r
- * COMPONENT\r
- *\r
- *         OpenAMP stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- *       Source file for fixed buffer size memory management service. Currently\r
- *       it is only being used to manage shared memory.\r
- *\r
- **************************************************************************/\r
-#include "sh_mem.h"\r
-\r
-/**\r
- * sh_mem_create_pool\r
- *\r
- * Creates new memory pool with the given parameters.\r
- *\r
- * @param start_addr - start address of the memory region\r
- * @param size       - size of the memory\r
- * @param buff_size  - fixed buffer size\r
- *\r
- * @return - pointer to memory pool\r
- *\r
- */\r
-struct sh_mem_pool * sh_mem_create_pool(void *start_addr, unsigned int size,\r
-                unsigned int buff_size) {\r
-    struct sh_mem_pool *mem_pool;\r
-    int status, pool_size;\r
-    int num_buffs, bmp_size;\r
-\r
-    if (!start_addr || !size || !buff_size)\r
-        return NULL;\r
-\r
-    /* Word align the buffer size */\r
-    buff_size = WORD_ALIGN(buff_size);\r
-\r
-    /* Get number of buffers. */\r
-    num_buffs = (size / buff_size) + ((size % buff_size) == 0 ? 0 : 1);\r
-\r
-    /*\r
-     * Size of the bitmap required to maintain buffers info. One word(32 bit) can\r
-     * keep track of 32 buffers.\r
-     */\r
-    bmp_size = (num_buffs / BITMAP_WORD_SIZE)\r
-                    + ((num_buffs % BITMAP_WORD_SIZE) == 0 ? 0 : 1);\r
-\r
-    /* Total size required for pool control block. */\r
-    pool_size = sizeof(struct sh_mem_pool) + WORD_SIZE * bmp_size;\r
-\r
-    /* Create pool control block. */\r
-    mem_pool = env_allocate_memory(pool_size);\r
-\r
-    if (mem_pool) {\r
-        /* Initialize pool parameters */\r
-        env_memset(mem_pool, 0x00, pool_size);\r
-        status = env_create_mutex(&mem_pool->lock , 1);\r
-        if (status){\r
-            env_free_memory(mem_pool);\r
-            return NULL;\r
-        }\r
-        mem_pool->start_addr = start_addr;\r
-        mem_pool->buff_size = buff_size;\r
-        mem_pool->bmp_size = bmp_size;\r
-        mem_pool->total_buffs = num_buffs;\r
-    }\r
-\r
-    return mem_pool;\r
-}\r
-\r
-/**\r
- * sh_mem_get_buffer\r
- *\r
- * Allocates fixed size buffer from the given memory pool.\r
- *\r
- * @param pool - pointer to memory pool\r
- *\r
- * @return - pointer to allocated buffer\r
- *\r
- */\r
-void * sh_mem_get_buffer(struct sh_mem_pool *pool) {\r
-    void *buff = NULL;\r
-    int idx, bit_idx;\r
-\r
-    if (!pool)\r
-        return NULL;\r
-\r
-    env_lock_mutex(pool->lock);\r
-\r
-    if (pool->used_buffs >= pool->total_buffs) {\r
-        env_unlock_mutex(pool->lock);\r
-        return NULL;\r
-    }\r
-\r
-    for (idx = 0; idx < pool->bmp_size; idx++) {\r
-        /*\r
-         * Find the first 0 bit in the buffers bitmap. The 0th bit\r
-         * represents a free buffer.\r
-         */\r
-        bit_idx = get_first_zero_bit(pool->bitmap[idx]);\r
-        if (bit_idx < 32) {\r
-            /* Set bit to mark it as consumed. */\r
-            pool->bitmap[idx] |= (1 << bit_idx);\r
-            buff = (char *) pool->start_addr +\r
-                            pool->buff_size * (idx * BITMAP_WORD_SIZE + bit_idx);\r
-            pool->used_buffs++;\r
-            break;\r
-        }\r
-    }\r
-\r
-    env_unlock_mutex(pool->lock);\r
-\r
-    return buff;\r
-}\r
-\r
-/**\r
- * sh_mem_free_buffer\r
- *\r
- * Frees the given buffer.\r
- *\r
- * @param pool - pointer to memory pool\r
- * @param buff - pointer to buffer\r
- *\r
- * @return  - none\r
- */\r
-void sh_mem_free_buffer(void *buff, struct sh_mem_pool *pool) {\r
-    unsigned long *bitmask;\r
-    int bmp_idx, bit_idx, buff_idx;\r
-\r
-    if (!pool || !buff)\r
-        return;\r
-\r
-    /* Acquire the pool lock */\r
-    env_lock_mutex(pool->lock);\r
-\r
-    /* Map the buffer address to its index. */\r
-    buff_idx = ((char *) buff - (char*) pool->start_addr) / pool->buff_size;\r
-\r
-    /* Translate the buffer index to bitmap index. */\r
-    bmp_idx = buff_idx / BITMAP_WORD_SIZE;\r
-    bit_idx = buff_idx % BITMAP_WORD_SIZE;\r
-    bitmask = &pool->bitmap[bmp_idx];\r
-\r
-    /* Mark the buffer as free */\r
-    *bitmask ^= (1 << bit_idx);\r
-\r
-    pool->used_buffs--;\r
-\r
-    /* Release the pool lock. */\r
-    env_unlock_mutex(pool->lock);\r
-\r
-}\r
-\r
-/**\r
- * sh_mem_delete_pool\r
- *\r
- * Deletes the given memory pool.\r
- *\r
- * @param pool - pointer to memory pool\r
- *\r
- * @return  - none\r
- */\r
-void sh_mem_delete_pool(struct sh_mem_pool *pool) {\r
-\r
-    if (pool) {\r
-        env_delete_mutex(pool->lock);\r
-        env_free_memory(pool);\r
-    }\r
-}\r
-\r
-/**\r
- * get_first_zero_bit\r
- *\r
- * Provides position of first 0 bit in a 32 bit value\r
- *\r
- * @param value - given value\r
- *\r
- * @return - 0th bit position\r
- */\r
-unsigned int get_first_zero_bit(unsigned long value) {\r
-    unsigned int idx;\r
-    unsigned int tmp32;\r
-\r
-    /* Invert value */\r
-    value = ~value;\r
-\r
-    /* (~value) & (2's complement of value) */\r
-    value = (value & (-value)) - 1;\r
-\r
-    /* log2(value) */\r
-\r
-    tmp32 = value - ((value >> 1) & 033333333333)\r
-                    - ((value >> 2) & 011111111111);\r
-\r
-    idx = ((tmp32 + (tmp32 >> 3)) & 030707070707) % 63;\r
-\r
-    return idx;\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+/**************************************************************************
+ * FILE NAME
+ *
+ *       sh_mem.c
+ *
+ * COMPONENT
+ *
+ *         OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ *       Source file for fixed buffer size memory management service. Currently
+ *       it is only being used to manage shared memory.
+ *
+ **************************************************************************/
+#include "sh_mem.h"
+
+/**
+ * sh_mem_create_pool
+ *
+ * Creates new memory pool with the given parameters.
+ *
+ * @param start_addr - start address of the memory region
+ * @param size       - size of the memory
+ * @param buff_size  - fixed buffer size
+ *
+ * @return - pointer to memory pool
+ *
+ */
+struct sh_mem_pool * sh_mem_create_pool(void *start_addr, unsigned int size,
+                unsigned int buff_size) {
+    struct sh_mem_pool *mem_pool;
+    int status, pool_size;
+    int num_buffs, bmp_size;
+
+    if (!start_addr || !size || !buff_size)
+        return NULL;
+
+    /* Word align the buffer size */
+    buff_size = WORD_ALIGN(buff_size);
+
+    /* Get number of buffers. */
+    num_buffs = (size / buff_size) + ((size % buff_size) == 0 ? 0 : 1);
+
+    /*
+     * Size of the bitmap required to maintain buffers info. One word(32 bit) can
+     * keep track of 32 buffers.
+     */
+    bmp_size = (num_buffs / BITMAP_WORD_SIZE)
+                    + ((num_buffs % BITMAP_WORD_SIZE) == 0 ? 0 : 1);
+
+    /* Total size required for pool control block. */
+    pool_size = sizeof(struct sh_mem_pool) + WORD_SIZE * bmp_size;
+
+    /* Create pool control block. */
+    mem_pool = env_allocate_memory(pool_size);
+
+    if (mem_pool) {
+        /* Initialize pool parameters */
+        env_memset(mem_pool, 0x00, pool_size);
+        status = env_create_mutex(&mem_pool->lock , 1);
+        if (status){
+            env_free_memory(mem_pool);
+            return NULL;
+        }
+        mem_pool->start_addr = start_addr;
+        mem_pool->buff_size = buff_size;
+        mem_pool->bmp_size = bmp_size;
+        mem_pool->total_buffs = num_buffs;
+    }
+
+    return mem_pool;
+}
+
+/**
+ * sh_mem_get_buffer
+ *
+ * Allocates fixed size buffer from the given memory pool.
+ *
+ * @param pool - pointer to memory pool
+ *
+ * @return - pointer to allocated buffer
+ *
+ */
+void * sh_mem_get_buffer(struct sh_mem_pool *pool) {
+    void *buff = NULL;
+    int idx, bit_idx;
+
+    if (!pool)
+        return NULL;
+
+    env_lock_mutex(pool->lock);
+
+    if (pool->used_buffs >= pool->total_buffs) {
+        env_unlock_mutex(pool->lock);
+        return NULL;
+    }
+
+    for (idx = 0; idx < pool->bmp_size; idx++) {
+        /*
+         * Find the first 0 bit in the buffers bitmap. The 0th bit
+         * represents a free buffer.
+         */
+        bit_idx = get_first_zero_bit(pool->bitmap[idx]);
+        if (bit_idx < 32) {
+            /* Set bit to mark it as consumed. */
+            pool->bitmap[idx] |= (1 << bit_idx);
+            buff = (char *) pool->start_addr +
+                            pool->buff_size * (idx * BITMAP_WORD_SIZE + bit_idx);
+            pool->used_buffs++;
+            break;
+        }
+    }
+
+    env_unlock_mutex(pool->lock);
+
+    return buff;
+}
+
+/**
+ * sh_mem_free_buffer
+ *
+ * Frees the given buffer.
+ *
+ * @param pool - pointer to memory pool
+ * @param buff - pointer to buffer
+ *
+ * @return  - none
+ */
+void sh_mem_free_buffer(void *buff, struct sh_mem_pool *pool) {
+    unsigned long *bitmask;
+    int bmp_idx, bit_idx, buff_idx;
+
+    if (!pool || !buff)
+        return;
+
+    /* Acquire the pool lock */
+    env_lock_mutex(pool->lock);
+
+    /* Map the buffer address to its index. */
+    buff_idx = ((char *) buff - (char*) pool->start_addr) / pool->buff_size;
+
+    /* Translate the buffer index to bitmap index. */
+    bmp_idx = buff_idx / BITMAP_WORD_SIZE;
+    bit_idx = buff_idx % BITMAP_WORD_SIZE;
+    bitmask = &pool->bitmap[bmp_idx];
+
+    /* Mark the buffer as free */
+    *bitmask ^= (1 << bit_idx);
+
+    pool->used_buffs--;
+
+    /* Release the pool lock. */
+    env_unlock_mutex(pool->lock);
+
+}
+
+/**
+ * sh_mem_delete_pool
+ *
+ * Deletes the given memory pool.
+ *
+ * @param pool - pointer to memory pool
+ *
+ * @return  - none
+ */
+void sh_mem_delete_pool(struct sh_mem_pool *pool) {
+
+    if (pool) {
+        env_delete_mutex(pool->lock);
+        env_free_memory(pool);
+    }
+}
+
+/**
+ * get_first_zero_bit
+ *
+ * Provides position of first 0 bit in a 32 bit value
+ *
+ * @param value - given value
+ *
+ * @return - 0th bit position
+ */
+unsigned int get_first_zero_bit(unsigned long value) {
+    unsigned int idx;
+    unsigned int tmp32;
+
+    /* Invert value */
+    value = ~value;
+
+    /* (~value) & (2's complement of value) */
+    value = (value & (-value)) - 1;
+
+    /* log2(value) */
+
+    tmp32 = value - ((value >> 1) & 033333333333)
+                    - ((value >> 2) & 011111111111);
+
+    idx = ((tmp32 + (tmp32 >> 3)) & 030707070707) % 63;
+
+    return idx;
+}
index 65c97df6674dc981daebb658d4fba8a579f15936..4ba830b7fc2114ed5a76b19dfccd8079b6caa45d 100644 (file)
@@ -1,89 +1,89 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       sh_mem.c\r
- *\r
- * COMPONENT\r
- *\r
- *         IPC Stack for uAMP systems.\r
- *\r
- * DESCRIPTION\r
- *\r
- *       Header file for fixed buffer size memory management service. Currently\r
- *       it is being used to manage shared memory.\r
- *\r
- **************************************************************************/\r
-#ifndef SH_MEM_H_\r
-#define SH_MEM_H_\r
-\r
-#include "../../porting/env/env.h"\r
-\r
-\r
-/* Macros */\r
-#define BITMAP_WORD_SIZE         32\r
-#define WORD_SIZE                sizeof(unsigned long)\r
-#define WORD_ALIGN(a)            (((a) & (WORD_SIZE-1)) != 0)? \\r
-                                 (((a) & (~(WORD_SIZE-1))) + 4):(a)\r
-/*\r
- * This structure represents a  shared memory pool.\r
- *\r
- * @start_addr      - start address of shared memory region\r
- * @lock            - lock to ensure exclusive access\r
- * @size            - size of shared memory*\r
- * @buff_size       - size of each buffer\r
- * @total_buffs     - total number of buffers in shared memory region\r
- * @used_buffs      - number of used buffers\r
- * @bmp_size        - size of bitmap array\r
- * @bitmap          - array to keep record of free and used blocks\r
- *\r
- */\r
-\r
-struct sh_mem_pool {\r
-    void *start_addr;\r
-    LOCK *lock;\r
-    int size;\r
-    int buff_size;\r
-    int total_buffs;\r
-    int used_buffs;\r
-    int bmp_size;\r
-    unsigned long bitmap[0];\r
-};\r
-\r
-/* APIs */\r
-struct sh_mem_pool *sh_mem_create_pool(void *start_addr, unsigned int size,\r
-                unsigned int buff_size);\r
-void sh_mem_delete_pool(struct sh_mem_pool *pool);\r
-void *sh_mem_get_buffer(struct sh_mem_pool *pool);\r
-void sh_mem_free_buffer(void *ptr, struct sh_mem_pool *pool);\r
-unsigned int get_first_zero_bit(unsigned long value);\r
-\r
-#endif /* SH_MEM_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       sh_mem.c
+ *
+ * COMPONENT
+ *
+ *         IPC Stack for uAMP systems.
+ *
+ * DESCRIPTION
+ *
+ *       Header file for fixed buffer size memory management service. Currently
+ *       it is being used to manage shared memory.
+ *
+ **************************************************************************/
+#ifndef SH_MEM_H_
+#define SH_MEM_H_
+
+#include "../../porting/env/env.h"
+
+
+/* Macros */
+#define BITMAP_WORD_SIZE         32
+#define WORD_SIZE                sizeof(unsigned long)
+#define WORD_ALIGN(a)            (((a) & (WORD_SIZE-1)) != 0)? \
+                                 (((a) & (~(WORD_SIZE-1))) + 4):(a)
+/*
+ * This structure represents a  shared memory pool.
+ *
+ * @start_addr      - start address of shared memory region
+ * @lock            - lock to ensure exclusive access
+ * @size            - size of shared memory*
+ * @buff_size       - size of each buffer
+ * @total_buffs     - total number of buffers in shared memory region
+ * @used_buffs      - number of used buffers
+ * @bmp_size        - size of bitmap array
+ * @bitmap          - array to keep record of free and used blocks
+ *
+ */
+
+struct sh_mem_pool {
+    void *start_addr;
+    LOCK *lock;
+    int size;
+    int buff_size;
+    int total_buffs;
+    int used_buffs;
+    int bmp_size;
+    unsigned long bitmap[0];
+};
+
+/* APIs */
+struct sh_mem_pool *sh_mem_create_pool(void *start_addr, unsigned int size,
+                unsigned int buff_size);
+void sh_mem_delete_pool(struct sh_mem_pool *pool);
+void *sh_mem_get_buffer(struct sh_mem_pool *pool);
+void sh_mem_free_buffer(void *ptr, struct sh_mem_pool *pool);
+unsigned int get_first_zero_bit(unsigned long value);
+
+#endif /* SH_MEM_H_ */
index 03b6ddbe94d22955f7d4b6e14bf6a630d8a88161..7507bd881595eb1d33dc32f850cf9658116096a1 100644 (file)
@@ -1,37 +1,37 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef OPEN_AMP_H_\r
-#define OPEN_AMP_H_\r
-\r
-#include "../rpmsg/rpmsg.h"\r
-#include "../remoteproc/remoteproc.h"\r
-\r
-\r
-#endif /* OPEN_AMP_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+#ifndef OPEN_AMP_H_
+#define OPEN_AMP_H_
+
+#include "../rpmsg/rpmsg.h"
+#include "../remoteproc/remoteproc.h"
+
+
+#endif /* OPEN_AMP_H_ */
index 852906a680ed65f18a713ce491e289c384704c0d..fa84dfce84bd2d68c63440605360a7441207d4ec 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include "libfdt/types.h"\r
-#include "libfdt/libfdt.h"\r
-#include "zlib/zlib.h"\r
-\r
-/* External variables. */\r
-extern unsigned int           _image_start;\r
-extern unsigned int           _image_end;\r
-extern unsigned int           _bss_start;\r
-extern unsigned int           _bss_end;\r
-\r
-/* Definitions.*/\r
-#define FIT_IMAGE_START       (void *)&_image_start\r
-#define FIT_IMAGE_END         (void *)&_image_end\r
-\r
-#define BSS_START             (void *)&_bss_start\r
-#define BSS_END               (void *)&_bss_end\r
-\r
-#define BSS_SIZE              (((unsigned int)BSS_END) - ((unsigned int)BSS_START))\r
-\r
-#define XILINX_ARM_MACHINE    3343\r
-\r
-#define KERNEL_RESERVED_SPACE 0x7FF2000\r
-\r
-#define PUTC(a)                 ((*((volatile unsigned int *) 0xE0001030)) = (a))\r
-\r
-/* Globals. */\r
-unsigned int linux_kernel_start, dtb_start, linux_kernel_size, dtb_size;\r
-\r
-/* Static functions. */\r
-static void boot_linux_fit_image(void);\r
-\r
-static int  process_and_relocate_fit_image(char *image_start, unsigned int image_size);\r
-\r
-extern void start_linux_with_dtb (void);\r
-\r
-static void clear_bss(void);\r
-static void invalidate_cache(void);\r
-static void clean_system(void);\r
-\r
-void put_char(char c)\r
-{\r
-       PUTC(c);\r
-       \r
-       while (((*((volatile unsigned int *) 0xE000102C)) &  0x00000008) == 0 );\r
-}\r
-void putstring(const char *str)\r
-{\r
-       while (*str)\r
-       {\r
-          put_char(*str++);\r
-       }\r
-}\r
-\r
-/* Boots the linux kernel. */\r
-void boot_linux(void)\r
-{\r
-   /* Clear BSS*/\r
-   clear_bss();\r
-   \r
-   clean_system();\r
-   \r
-   putstring("\n\r********************************* \n\r");\r
-   putstring("OpenAMP Linux Bootstrap.");\r
-   putstring("\n\r********************************* \n\r");\r
-   \r
-   /* Currently supporting only FIT image format. */\r
-   boot_linux_fit_image();\r
-}\r
-\r
-/* Boots a FIT format linux image. */\r
-static void boot_linux_fit_image(void)\r
-{\r
-       unsigned int image_size, status;\r
-\r
-       char *image_start;\r
-\r
-       /* Retrieve linux image start and end addresses. */\r
-       image_start = (char *)FIT_IMAGE_START;\r
-\r
-    /* Retrieve linux image size. */\r
-       image_size = (FIT_IMAGE_END - FIT_IMAGE_START);\r
-\r
-       /* Check for a valid linux image size. */\r
-       if(image_size > 0){\r
-\r
-               /* let us parse and relocate the FIT image. */\r
-               status = process_and_relocate_fit_image(image_start, image_size);\r
-\r
-               /* Image processed and relocated successfully. */\r
-               if(!status){\r
-\r
-               putstring("\n\rLinux Bootstrap: Booting Linux. \n\r");\r
-       \r
-                       /* Image has been processed and relocated. Now boot linux*/\r
-                       start_linux_with_dtb();\r
-               }\r
-               else\r
-               {\r
-                       /* Go into an error loop. */\r
-                       while(1);\r
-               }\r
-       }\r
-       else\r
-       {\r
-               /* Go into an error loop. */\r
-               while (1);\r
-       }\r
-}\r
-\r
-\r
-/* Returns zero for success. */\r
-static int process_and_relocate_fit_image(char *image_start, unsigned int image_size)\r
-{\r
-       unsigned int fit_image_start, compressed = 0;\r
-       unsigned long kernel_address;\r
-       int size, load_size, load_address, dtb_address;\r
-       char    *conf_name = NULL;\r
-       void *data;\r
-       int cfg_offset, offset, ret;\r
-       z_stream                strm;\r
-\r
-\r
-    putstring("\n\rLinux Bootstrap: Locating Linux Kernel and DTB from FIT image.\n\r");\r
-   \r
-       fit_image_start = (unsigned int)image_start;\r
-\r
-    /* Retrieve default FIT image configuration node. */\r
-    offset = fdt_path_offset((const void *)fit_image_start, "/configurations");\r
-    \r
-    if (offset >= 0)\r
-    {\r
-               /* Retrieve default configuration name. */\r
-               conf_name = (char *)fdt_getprop((const void *)fit_image_start, offset, "default", &size);\r
-    }\r
-    \r
-    if(conf_name)\r
-    {\r
-               /* Retrieve the offset of configuration node. */\r
-               cfg_offset = fdt_subnode_offset((const void *)fit_image_start, offset, conf_name);\r
-       }\r
-       \r
-       /* Retrieve kernel node using the config node. */\r
-    conf_name = (char *)fdt_getprop((const void *)fit_image_start, cfg_offset, "kernel", &size);\r
-    \r
-    if(conf_name)\r
-    {\r
-        offset = fdt_path_offset((const void *)fit_image_start, "/images");\r
-        \r
-        if(offset >= 0)\r
-        {\r
-            offset = fdt_subnode_offset((const void *)fit_image_start, offset, conf_name);\r
-           }\r
-    }\r
-    \r
-    if (offset >= 0)\r
-    {\r
-        /* Retrieve kernel image address and size. */  \r
-        kernel_address = (unsigned long)fdt_getprop((const void *)fit_image_start, offset, "data", &load_size);        \r
-        \r
-        /* Retrieve kernel load address. */\r
-        data = (void *)fdt_getprop((const void *)fit_image_start, offset, "load", &size);\r
-        \r
-        load_address = *((int *)data);\r
-        \r
-        load_address = be32_to_cpu(load_address);\r
-        \r
-        /* Check kernel image for compression. */\r
-        data = (void *)fdt_getprop((const void *)fit_image_start, offset, "compression", &size);\r
-        \r
-        if(data != NULL)\r
-        {\r
-                  if(!(strcmp(data, "gzip")))\r
-                  {\r
-                         compressed =1; \r
-                  }    \r
-               }\r
-    }\r
-    \r
-    memset((void *)load_address, 0, 0x0600000 - load_address);\r
-    \r
-    if(compressed == 1)\r
-    {\r
-               putstring("\n\rLinux Bootstrap: Kernel image is compressed. Starting decompression process. It may take a while...\n\r");\r
-                  \r
-               /* Initialize zlib stream. */\r
-               strm.zalloc   = Z_NULL;\r
-               strm.zfree    = Z_NULL;\r
-               strm.opaque   = Z_NULL;\r
-               strm.avail_in = 0;\r
-               strm.next_in  = Z_NULL;\r
-\r
-               /* Initialize the zlib state for de-compression. */\r
-               ret = inflateInit2(&strm, MAX_WBITS + 16);\r
-\r
-               if(ret == Z_OK)\r
-               {\r
-                       strm.next_in = (Bytef*)kernel_address;\r
-                       strm.avail_out = KERNEL_RESERVED_SPACE;\r
-                       strm.avail_in = load_size;\r
-\r
-                       /* Pointer to output space. */\r
-                       strm.next_out = (Bytef*)load_address;\r
-\r
-                       /* Call the de-compression engine. */\r
-                       ret = inflate(&strm, Z_FINISH);\r
-               }\r
-\r
-               (void)inflateEnd(&strm);\r
-\r
-               if((ret != Z_OK) && (ret != Z_STREAM_END)){\r
-\r
-                  /* return with an error. */\r
-                  return 1;\r
-               }\r
-               \r
-               putstring("\n\rLinux Bootstrap: Linux image decompression complete. \n\r");\r
-\r
-       }\r
-       else\r
-       {\r
-               /* Uncompressed image. Just load to the load address. */\r
-           memcpy((void *)load_address, (void *)kernel_address, load_size);\r
-       }\r
-\r
-       putstring("\n\rLinux Bootstrap: Linux kernel image has been loaded into memory. \n\r");\r
-               \r
-       /* Save kernel load address and size. */\r
-       linux_kernel_start = load_address;\r
-       linux_kernel_size = load_size;\r
-\r
-\r
-       /* Retrieve DTB node using the config node. */\r
-    conf_name = (char *)fdt_getprop((const void *)fit_image_start, cfg_offset, "fdt", &size);\r
-    \r
-    if(conf_name)\r
-    {\r
-        offset = fdt_path_offset((const void *)fit_image_start, "/images");\r
-        \r
-        if(offset >= 0)\r
-        {\r
-            offset = fdt_subnode_offset((const void *)fit_image_start, offset, conf_name);\r
-           }\r
-    }\r
-    \r
-    if (offset >= 0)\r
-    {\r
-        /* Retrieve DTB address and size. */   \r
-        dtb_address = (unsigned long )fdt_getprop((const void *)fit_image_start, offset, "data", &load_size);\r
-    }\r
-    \r
-    dtb_start = (linux_kernel_start + KERNEL_RESERVED_SPACE) & 0xFFFFFF00;\r
-       dtb_size = load_size;\r
-\r
-    memcpy((void *)dtb_start, (void *)dtb_address, load_size);\r
-\r
-       putstring("\n\rLinux Bootstrap: Loaded DTB. \n\r");\r
-               \r
-    return 0;\r
-}\r
-\r
-static void clear_bss(void)\r
-{\r
-    memset(BSS_START, 0, BSS_SIZE);\r
-}\r
-\r
-/*\r
- * The code in this section is for invalidating the cache at startup \r
- * \r
- */\r
\r
-/* ARM Coprocessor registers */\r
-#define         ARM_AR_CP0                 p0\r
-#define         ARM_AR_CP1                 p1\r
-#define         ARM_AR_CP2                 p2\r
-#define         ARM_AR_CP3                 p3\r
-#define         ARM_AR_CP4                 p4\r
-#define         ARM_AR_CP5                 p5\r
-#define         ARM_AR_CP6                 p6\r
-#define         ARM_AR_CP7                 p7\r
-#define         ARM_AR_CP8                 p8\r
-#define         ARM_AR_CP9                 p9\r
-#define         ARM_AR_CP10                p10\r
-#define         ARM_AR_CP11                p11\r
-#define         ARM_AR_CP12                p12\r
-#define         ARM_AR_CP13                p13\r
-#define         ARM_AR_CP14                p14\r
-#define         ARM_AR_CP15                p15\r
-\r
-/* CRn and CRm register values */\r
-#define         ARM_AR_C0                  c0\r
-#define         ARM_AR_C1                  c1\r
-#define         ARM_AR_C2                  c2\r
-#define         ARM_AR_C3                  c3\r
-#define         ARM_AR_C4                  c4\r
-#define         ARM_AR_C5                  c5\r
-#define         ARM_AR_C6                  c6\r
-#define         ARM_AR_C7                  c7\r
-#define         ARM_AR_C8                  c8\r
-#define         ARM_AR_C9                  c9\r
-#define         ARM_AR_C10                 c10\r
-#define         ARM_AR_C11                 c11\r
-#define         ARM_AR_C12                 c12\r
-#define         ARM_AR_C13                 c13\r
-#define         ARM_AR_C14                 c14\r
-#define         ARM_AR_C15                 c15\r
-\r
-/* This define is used to add quotes to anything passed in */\r
-#define         ARM_AR_QUOTES(x)           #x\r
-\r
-/* This macro writes to a coprocessor register */\r
-#define         ARM_AR_CP_WRITE(cp, op1, cp_value, crn, crm, op2)              \\r
-                {                                                              \\r
-                    asm volatile("    MCR    " ARM_AR_QUOTES(cp) ","           \\r
-                                             #op1                              \\r
-                                             ", %0, "                          \\r
-                                             ARM_AR_QUOTES(crn) ","            \\r
-                                             ARM_AR_QUOTES(crm) ","            \\r
-                                             #op2                              \\r
-                                    : /* No outputs */                         \\r
-                                    : "r" (cp_value));                         \\r
-                }\r
-\r
-/* This macro reads from a coprocessor register */\r
-#define         ARM_AR_CP_READ(cp, op1, cp_value_ptr, crn, crm, op2)           \\r
-                {                                                              \\r
-                    asm volatile("    MRC    " ARM_AR_QUOTES(cp) ","           \\r
-                                             #op1                              \\r
-                                             ", %0, "                          \\r
-                                             ARM_AR_QUOTES(crn) ","            \\r
-                                             ARM_AR_QUOTES(crm) ","            \\r
-                                             #op2                                   \\r
-                                        : "=r" (*(unsigned long *)(cp_value_ptr))   \\r
-                                        : /* No inputs */ );                        \\r
-                }\r
-\r
-/* This macro executes a ISB instruction */\r
-#define         ARM_AR_ISB_EXECUTE()                                           \\r
-                {                                                                   \\r
-                    asm volatile("    ISB");                                        \\r
-                }\r
-\r
-/* This macro executes a DSB instruction */\r
-#define         ARM_AR_DSB_EXECUTE()                                           \\r
-                {                                                                   \\r
-                    asm volatile("    DSB");                                        \\r
-                }\r
-\r
-/* CLIDR and CCSIDR mask values */\r
-#define     ARM_AR_MEM_CLIDR_LOC_MASK              0x7000000\r
-#define     ARM_AR_MEM_CCSIDR_LINESIZE_MASK        0x7\r
-#define     ARM_AR_MEM_CCSIDR_ASSOC_MASK           0x3FF\r
-#define     ARM_AR_MEM_CCSIDR_NUMSET_MASK          0x7FFF\r
-\r
-/* CLIDR and CCSIDR shift values */\r
-#define     ARM_AR_MEM_CLIDR_LOC_RSHT_OFFSET       24\r
-#define     ARM_AR_MEM_CCSIDR_ASSOC_RSHT_OFFSET    3\r
-#define     ARM_AR_MEM_CCSIDR_NUMSET_RSHT_OFFSET   13\r
-\r
-/* Extract 'encoded' line length of the cache */\r
-#define     ARM_AR_MEM_CCSIDR_LINESIZE_GET(ccsidr_reg) (ccsidr_reg &                           \\r
-                                                         ARM_AR_MEM_CCSIDR_LINESIZE_MASK)\r
-\r
-/* Extract 'encoded' way size of the cache */\r
-#define     ARM_AR_MEM_CCSIDR_ASSOC_GET(ccsidr_reg)    (ARM_AR_MEM_CCSIDR_ASSOC_MASK &        \\r
-                                                        (ccsidr_reg >>                          \\r
-                                                         ARM_AR_MEM_CCSIDR_ASSOC_RSHT_OFFSET))\r
-\r
-/* Extract 'encoded' maximum number of index size */\r
-#define     ARM_AR_MEM_CCSIDR_NUMSET_GET(ccsidr_reg)   (ARM_AR_MEM_CCSIDR_NUMSET_MASK &       \\r
-                                                        (ccsidr_reg >>                          \\r
-                                                         ARM_AR_MEM_CCSIDR_NUMSET_RSHT_OFFSET))\r
-\r
-/* Refer to chapter B3.12.31 c7, Cache and branch predictor maintenance functions in the\r
- ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition 1360*/\r
-/* Calculate # of bits to be shifted for set size and way size */\r
-\r
-/* log2(line size in bytes) = ccsidr_linesize + 2 + logbase2(4) */\r
-#define     ARM_AR_MEM_L_CALCULATE(linesize)           (linesize + 2 + 2)\r
-\r
-/* log2(nsets) = 32 - way_size_bit_pos */\r
-\r
-/* Find the bit position of way size increment */\r
-#define     ARM_AR_MEM_A_CALCULATE(assoc, a_offset_ref)                                        \\r
-            {                                                                                   \\r
-                unsigned int  temp_pos = 0x80000000;                                                  \\r
-                                                                                                \\r
-                *a_offset_ref = 0;                                                              \\r
-                                                                                                \\r
-                /* Logic to count the number of leading zeros before the first 1 */             \\r
-                while(!((assoc & temp_pos) == temp_pos))                                        \\r
-                {                                                                               \\r
-                    (*a_offset_ref)++;                                                          \\r
-                    temp_pos = temp_pos >> 1;                                                   \\r
-                }                                                                               \\r
-            }\r
-\r
-/* Factor way, cache number, index number */\r
-#define     ARM_AR_MEM_DCCISW_SET(dccisw_ref, level, numsets, assoc, l_offset, a_offset)       \\r
-            {                                                                                   \\r
-                *dccisw_ref = (level | (numsets << l_offset) | (assoc << a_offset));            \\r
-            }\r
-\r
-/* This macro extracts line size, assoc and set size from CCSIDR */\r
-#define     ARM_AR_MEM_CCSIDR_VALS_GET(linesize_ref, assoc_ref, numsets_ref,                   \\r
-                                        l_offset_ref, a_offset_ref)                             \\r
-            {                                                                                   \\r
-                unsigned int  ccsidr_val;                                                             \\r
-                                                                                                \\r
-                /* Read the selected cache's CCSIDR */                                          \\r
-                ARM_AR_CP_READ(ARM_AR_CP15, 1, &ccsidr_val,                           \\r
-                                    ARM_AR_C0, ARM_AR_C0, 0);                         \\r
-                                                                                                \\r
-                /* Extract 'encoded' line length of the cache */                                \\r
-                *linesize_ref = ARM_AR_MEM_CCSIDR_LINESIZE_GET(ccsidr_val);                    \\r
-                                                                                                \\r
-                /* Extract 'encoded' way size of the cache */                                   \\r
-                *assoc_ref = ARM_AR_MEM_CCSIDR_ASSOC_GET(ccsidr_val);                          \\r
-                                                                                                \\r
-                /* Extract 'encoded' maximum number of index size */                            \\r
-                *numsets_ref = ARM_AR_MEM_CCSIDR_NUMSET_GET(ccsidr_val);                       \\r
-                                                                                                \\r
-                /* Calculate # of bits to be shifted for set size and way size */               \\r
-                                                                                                \\r
-                /* log2(line size in bytes) = ccsidr_linesize + 2 + log2(4) */                  \\r
-                *l_offset_ref = ARM_AR_MEM_L_CALCULATE(*linesize_ref);                         \\r
-                                                                                                \\r
-                /* log2(nsets) = 32 - way_size_bit_pos */                                       \\r
-                ARM_AR_MEM_A_CALCULATE(*assoc_ref, a_offset_ref);                              \\r
-            }\r
-\r
-/* This macro invalidates all of the instruction cache at the core level. */\r
-#define     ARM_AR_MEM_ICACHE_ALL_INVALIDATE()                         \\r
-            {                                                           \\r
-                ARM_AR_CP_WRITE(ARM_AR_CP15, 0,               \\r
-                                     0, ARM_AR_C7,                 \\r
-                                     ARM_AR_C5, 0);                \\r
-            }\r
-\r
-\r
-/* This macro invalidates all of the data cache at the core level. */\r
-void     ARM_AR_MEM_DCACHE_ALL_OP( int type)                                                     \r
-{                                                                                   \r
-       unsigned int  clidr_val = 0;                                                          \r
-       unsigned int  clidr_loc = 0;                                                          \r
-       unsigned int  cache_number = 0;                                                       \r
-       unsigned int  cache_type = 0;                                                         \r
-       unsigned int  ccsidr_linesize = 0;                                                    \r
-       unsigned int  ccsidr_assoc = 0;                                                       \r
-       int   ccsidr_numsets = 0;                                                     \r
-       int   way_size_copy = 0;                                                      \r
-       unsigned int  set_size_bit_pos = 0;                                                   \r
-       unsigned int  cache_number_pos = 0;                                                   \r
-       unsigned int  way_size_bit_pos = 0;                                                   \r
-       unsigned int  set_way_value = 0;                                                      \r
-                                                                                                                                                                  \r
-                                                                                                                                                                       \r
-       /* Read CLIDR to extract level of coherence (LOC) */                            \r
-       ARM_AR_CP_READ(ARM_AR_CP15, 1, &clidr_val,                            \r
-                                               ARM_AR_C0, ARM_AR_C0, 1);                         \r
-                                                                                                                                                                       \r
-       /* Extract LOC from CLIDR and align it at bit 1 */                              \r
-       clidr_loc = (clidr_val & ARM_AR_MEM_CLIDR_LOC_MASK) >>                         \r
-                               ARM_AR_MEM_CLIDR_LOC_RSHT_OFFSET;                                  \r
-                                                                                                                                                                       \r
-       /* Proceed only iff LOC is non-zero */                                          \r
-       if (clidr_loc != 0)                                                             \r
-       {                                                                               \r
-               do                                                                          \r
-               {                                                                           \r
-                       /* Extract cache type from CLIDR */                                     \r
-                       cache_number_pos = cache_number + (cache_number >> 1);                  \r
-                       cache_type = (clidr_val >> cache_number_pos) & 0x7;                     \r
-                                                                                                                                                                       \r
-                       /* Continue only iff data cache */                                      \r
-                       if (cache_type >= 2)                                                    \r
-                       {                                                                       \r
-                               /* Select desired cache level in CSSELR */                          \r
-                               ARM_AR_CP_WRITE(ARM_AR_CP15, 2, cache_number,             \r
-                                                                        ARM_AR_C0, ARM_AR_C0, 0);            \r
-                                                                                                                                                                       \r
-                               ARM_AR_ISB_EXECUTE();                                          \r
-                                                                                                                                                                       \r
-                               /* Get data like linesize, assoc and set size */                    \r
-                               ARM_AR_MEM_CCSIDR_VALS_GET(&ccsidr_linesize,                       \r
-                                                                                       &ccsidr_assoc,                          \r
-                                                                                       &ccsidr_numsets,                        \r
-                                                                                       &set_size_bit_pos,                      \r
-                                                                                       &way_size_bit_pos);                     \r
-                                                                                                                                                                       \r
-                               do                                                                  \r
-                               {                                                                   \r
-                                       way_size_copy = ccsidr_assoc;                                   \r
-                                                                                                                                                                       \r
-                                       do                                                              \r
-                                       {                                                               \r
-                                               /* Factor way, cache number, index number */                \r
-                                               ARM_AR_MEM_DCCISW_SET(&set_way_value, cache_number,        \r
-                                                                                          ccsidr_numsets, way_size_copy,       \r
-                                                                                          set_size_bit_pos,                    \r
-                                                                                          way_size_bit_pos);                   \r
-                                                                                                                                                                       \r
-                                               /* Execute invalidate if type = 0 */                        \r
-                                               if (type == 0)                                              \r
-                                               {                                                           \r
-                                                       ARM_AR_CP_WRITE(ARM_AR_CP15, 0,               \r
-                                                                                                set_way_value,                     \r
-                                                                                                ARM_AR_C7,                    \r
-                                                                                                ARM_AR_C6, 2);                \r
-                                               }                                                           \r
-                                               else                                                        \r
-                                               {                                                           \r
-                                                       ARM_AR_CP_WRITE(ARM_AR_CP15, 0,               \r
-                                                                                                set_way_value,                     \r
-                                                                                                ARM_AR_C7,                    \r
-                                                                                                ARM_AR_C14, 2);               \r
-                                               }                                                           \r
-                                                                                                                                                                       \r
-                                       /* decrement the way */                                         \r
-                                       } while((--way_size_copy) >= 0);                                \r
-                                                                                                                                                                       \r
-                               /* decrement the set */                                             \r
-                               } while((--ccsidr_numsets) >= 0);                                   \r
-                                                                                                                                                                       \r
-                       } /* end if */                                                          \r
-                                                                                                                                                                       \r
-                       /* Increment cache number */                                            \r
-                       cache_number += 2;                                                      \r
-                                                                                                                                                                       \r
-               /* end do-while */                                                          \r
-               } while(clidr_loc >= cache_number);                                         \r
-                                                                                                                                                                       \r
-       }                                                                               \r
-                                                                                                                                                                  \r
-       /* Switch back to cache level 0 in CSSELR */                                    \r
-       ARM_AR_CP_WRITE(ARM_AR_CP15, 2, 0,                                    \r
-                                                ARM_AR_C0, ARM_AR_C0, 0);                        \r
-                                                                                                                                                                       \r
-       /* Sync */                                                                      \r
-       ARM_AR_DSB_EXECUTE();                                                      \r
-       ARM_AR_ISB_EXECUTE();                                                      \r
-}\r
-\r
-/* This macro invalidates all of the data cache at the core level. */\r
-void    ARM_AR_MEM_DCACHE_ALL_INVALIDATE(void)         \r
-{\r
-       ARM_AR_MEM_DCACHE_ALL_OP(0);\r
-}\r
-\r
-/* This macro invalidates all of the cache at the core level. */\r
-void     ARM_AR_MEM_CACHE_ALL_INVALIDATE(void)                                                  \r
-{                                                                                   \r
-       ARM_AR_MEM_ICACHE_ALL_INVALIDATE();                                            \r
-       ARM_AR_MEM_DCACHE_ALL_INVALIDATE();                                            \r
-}\r
-\r
-\r
-static void clean_system(void){\r
-\r
-    invalidate_cache();\r
-\r
-}\r
-static void invalidate_cache(void)\r
-{\r
-       ARM_AR_MEM_CACHE_ALL_INVALIDATE();\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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 "libfdt/types.h"
+#include "libfdt/libfdt.h"
+#include "zlib/zlib.h"
+
+/* External variables. */
+extern unsigned int           _image_start;
+extern unsigned int           _image_end;
+extern unsigned int           _bss_start;
+extern unsigned int           _bss_end;
+
+/* Definitions.*/
+#define FIT_IMAGE_START       (void *)&_image_start
+#define FIT_IMAGE_END         (void *)&_image_end
+
+#define BSS_START             (void *)&_bss_start
+#define BSS_END               (void *)&_bss_end
+
+#define BSS_SIZE              (((unsigned int)BSS_END) - ((unsigned int)BSS_START))
+
+#define XILINX_ARM_MACHINE    3343
+
+#define KERNEL_RESERVED_SPACE 0x7FF2000
+
+#define PUTC(a)                 ((*((volatile unsigned int *) 0xE0001030)) = (a))
+
+/* Globals. */
+unsigned int linux_kernel_start, dtb_start, linux_kernel_size, dtb_size;
+
+/* Static functions. */
+static void boot_linux_fit_image(void);
+
+static int  process_and_relocate_fit_image(char *image_start, unsigned int image_size);
+
+extern void start_linux_with_dtb (void);
+
+static void clear_bss(void);
+static void invalidate_cache(void);
+static void clean_system(void);
+
+void put_char(char c)
+{
+       PUTC(c);
+       
+       while (((*((volatile unsigned int *) 0xE000102C)) &  0x00000008) == 0 );
+}
+void putstring(const char *str)
+{
+       while (*str)
+       {
+          put_char(*str++);
+       }
+}
+
+/* Boots the linux kernel. */
+void boot_linux(void)
+{
+   /* Clear BSS*/
+   clear_bss();
+   
+   clean_system();
+   
+   putstring("\n\r********************************* \n\r");
+   putstring("OpenAMP Linux Bootstrap.");
+   putstring("\n\r********************************* \n\r");
+   
+   /* Currently supporting only FIT image format. */
+   boot_linux_fit_image();
+}
+
+/* Boots a FIT format linux image. */
+static void boot_linux_fit_image(void)
+{
+       unsigned int image_size, status;
+
+       char *image_start;
+
+       /* Retrieve linux image start and end addresses. */
+       image_start = (char *)FIT_IMAGE_START;
+
+    /* Retrieve linux image size. */
+       image_size = (FIT_IMAGE_END - FIT_IMAGE_START);
+
+       /* Check for a valid linux image size. */
+       if(image_size > 0){
+
+               /* let us parse and relocate the FIT image. */
+               status = process_and_relocate_fit_image(image_start, image_size);
+
+               /* Image processed and relocated successfully. */
+               if(!status){
+
+               putstring("\n\rLinux Bootstrap: Booting Linux. \n\r");
+       
+                       /* Image has been processed and relocated. Now boot linux*/
+                       start_linux_with_dtb();
+               }
+               else
+               {
+                       /* Go into an error loop. */
+                       while(1);
+               }
+       }
+       else
+       {
+               /* Go into an error loop. */
+               while (1);
+       }
+}
+
+
+/* Returns zero for success. */
+static int process_and_relocate_fit_image(char *image_start, unsigned int image_size)
+{
+       unsigned int fit_image_start, compressed = 0;
+       unsigned long kernel_address;
+       int size, load_size, load_address, dtb_address;
+       char    *conf_name = NULL;
+       void *data;
+       int cfg_offset, offset, ret;
+       z_stream                strm;
+
+
+    putstring("\n\rLinux Bootstrap: Locating Linux Kernel and DTB from FIT image.\n\r");
+   
+       fit_image_start = (unsigned int)image_start;
+
+    /* Retrieve default FIT image configuration node. */
+    offset = fdt_path_offset((const void *)fit_image_start, "/configurations");
+    
+    if (offset >= 0)
+    {
+               /* Retrieve default configuration name. */
+               conf_name = (char *)fdt_getprop((const void *)fit_image_start, offset, "default", &size);
+    }
+    
+    if(conf_name)
+    {
+               /* Retrieve the offset of configuration node. */
+               cfg_offset = fdt_subnode_offset((const void *)fit_image_start, offset, conf_name);
+       }
+       
+       /* Retrieve kernel node using the config node. */
+    conf_name = (char *)fdt_getprop((const void *)fit_image_start, cfg_offset, "kernel", &size);
+    
+    if(conf_name)
+    {
+        offset = fdt_path_offset((const void *)fit_image_start, "/images");
+        
+        if(offset >= 0)
+        {
+            offset = fdt_subnode_offset((const void *)fit_image_start, offset, conf_name);
+           }
+    }
+    
+    if (offset >= 0)
+    {
+        /* Retrieve kernel image address and size. */  
+        kernel_address = (unsigned long)fdt_getprop((const void *)fit_image_start, offset, "data", &load_size);        
+        
+        /* Retrieve kernel load address. */
+        data = (void *)fdt_getprop((const void *)fit_image_start, offset, "load", &size);
+        
+        load_address = *((int *)data);
+        
+        load_address = be32_to_cpu(load_address);
+        
+        /* Check kernel image for compression. */
+        data = (void *)fdt_getprop((const void *)fit_image_start, offset, "compression", &size);
+        
+        if(data != NULL)
+        {
+                  if(!(strcmp(data, "gzip")))
+                  {
+                         compressed =1; 
+                  }    
+               }
+    }
+    
+    memset((void *)load_address, 0, 0x0600000 - load_address);
+    
+    if(compressed == 1)
+    {
+               putstring("\n\rLinux Bootstrap: Kernel image is compressed. Starting decompression process. It may take a while...\n\r");
+                  
+               /* Initialize zlib stream. */
+               strm.zalloc   = Z_NULL;
+               strm.zfree    = Z_NULL;
+               strm.opaque   = Z_NULL;
+               strm.avail_in = 0;
+               strm.next_in  = Z_NULL;
+
+               /* Initialize the zlib state for de-compression. */
+               ret = inflateInit2(&strm, MAX_WBITS + 16);
+
+               if(ret == Z_OK)
+               {
+                       strm.next_in = (Bytef*)kernel_address;
+                       strm.avail_out = KERNEL_RESERVED_SPACE;
+                       strm.avail_in = load_size;
+
+                       /* Pointer to output space. */
+                       strm.next_out = (Bytef*)load_address;
+
+                       /* Call the de-compression engine. */
+                       ret = inflate(&strm, Z_FINISH);
+               }
+
+               (void)inflateEnd(&strm);
+
+               if((ret != Z_OK) && (ret != Z_STREAM_END)){
+
+                  /* return with an error. */
+                  return 1;
+               }
+               
+               putstring("\n\rLinux Bootstrap: Linux image decompression complete. \n\r");
+
+       }
+       else
+       {
+               /* Uncompressed image. Just load to the load address. */
+           memcpy((void *)load_address, (void *)kernel_address, load_size);
+       }
+
+       putstring("\n\rLinux Bootstrap: Linux kernel image has been loaded into memory. \n\r");
+               
+       /* Save kernel load address and size. */
+       linux_kernel_start = load_address;
+       linux_kernel_size = load_size;
+
+
+       /* Retrieve DTB node using the config node. */
+    conf_name = (char *)fdt_getprop((const void *)fit_image_start, cfg_offset, "fdt", &size);
+    
+    if(conf_name)
+    {
+        offset = fdt_path_offset((const void *)fit_image_start, "/images");
+        
+        if(offset >= 0)
+        {
+            offset = fdt_subnode_offset((const void *)fit_image_start, offset, conf_name);
+           }
+    }
+    
+    if (offset >= 0)
+    {
+        /* Retrieve DTB address and size. */   
+        dtb_address = (unsigned long )fdt_getprop((const void *)fit_image_start, offset, "data", &load_size);
+    }
+    
+    dtb_start = (linux_kernel_start + KERNEL_RESERVED_SPACE) & 0xFFFFFF00;
+       dtb_size = load_size;
+
+    memcpy((void *)dtb_start, (void *)dtb_address, load_size);
+
+       putstring("\n\rLinux Bootstrap: Loaded DTB. \n\r");
+               
+    return 0;
+}
+
+static void clear_bss(void)
+{
+    memset(BSS_START, 0, BSS_SIZE);
+}
+
+/*
+ * The code in this section is for invalidating the cache at startup 
+ * 
+ */
+/* ARM Coprocessor registers */
+#define         ARM_AR_CP0                 p0
+#define         ARM_AR_CP1                 p1
+#define         ARM_AR_CP2                 p2
+#define         ARM_AR_CP3                 p3
+#define         ARM_AR_CP4                 p4
+#define         ARM_AR_CP5                 p5
+#define         ARM_AR_CP6                 p6
+#define         ARM_AR_CP7                 p7
+#define         ARM_AR_CP8                 p8
+#define         ARM_AR_CP9                 p9
+#define         ARM_AR_CP10                p10
+#define         ARM_AR_CP11                p11
+#define         ARM_AR_CP12                p12
+#define         ARM_AR_CP13                p13
+#define         ARM_AR_CP14                p14
+#define         ARM_AR_CP15                p15
+
+/* CRn and CRm register values */
+#define         ARM_AR_C0                  c0
+#define         ARM_AR_C1                  c1
+#define         ARM_AR_C2                  c2
+#define         ARM_AR_C3                  c3
+#define         ARM_AR_C4                  c4
+#define         ARM_AR_C5                  c5
+#define         ARM_AR_C6                  c6
+#define         ARM_AR_C7                  c7
+#define         ARM_AR_C8                  c8
+#define         ARM_AR_C9                  c9
+#define         ARM_AR_C10                 c10
+#define         ARM_AR_C11                 c11
+#define         ARM_AR_C12                 c12
+#define         ARM_AR_C13                 c13
+#define         ARM_AR_C14                 c14
+#define         ARM_AR_C15                 c15
+
+/* This define is used to add quotes to anything passed in */
+#define         ARM_AR_QUOTES(x)           #x
+
+/* This macro writes to a coprocessor register */
+#define         ARM_AR_CP_WRITE(cp, op1, cp_value, crn, crm, op2)              \
+                {                                                              \
+                    asm volatile("    MCR    " ARM_AR_QUOTES(cp) ","           \
+                                             #op1                              \
+                                             ", %0, "                          \
+                                             ARM_AR_QUOTES(crn) ","            \
+                                             ARM_AR_QUOTES(crm) ","            \
+                                             #op2                              \
+                                    : /* No outputs */                         \
+                                    : "r" (cp_value));                         \
+                }
+
+/* This macro reads from a coprocessor register */
+#define         ARM_AR_CP_READ(cp, op1, cp_value_ptr, crn, crm, op2)           \
+                {                                                              \
+                    asm volatile("    MRC    " ARM_AR_QUOTES(cp) ","           \
+                                             #op1                              \
+                                             ", %0, "                          \
+                                             ARM_AR_QUOTES(crn) ","            \
+                                             ARM_AR_QUOTES(crm) ","            \
+                                             #op2                                   \
+                                        : "=r" (*(unsigned long *)(cp_value_ptr))   \
+                                        : /* No inputs */ );                        \
+                }
+
+/* This macro executes a ISB instruction */
+#define         ARM_AR_ISB_EXECUTE()                                           \
+                {                                                                   \
+                    asm volatile("    ISB");                                        \
+                }
+
+/* This macro executes a DSB instruction */
+#define         ARM_AR_DSB_EXECUTE()                                           \
+                {                                                                   \
+                    asm volatile("    DSB");                                        \
+                }
+
+/* CLIDR and CCSIDR mask values */
+#define     ARM_AR_MEM_CLIDR_LOC_MASK              0x7000000
+#define     ARM_AR_MEM_CCSIDR_LINESIZE_MASK        0x7
+#define     ARM_AR_MEM_CCSIDR_ASSOC_MASK           0x3FF
+#define     ARM_AR_MEM_CCSIDR_NUMSET_MASK          0x7FFF
+
+/* CLIDR and CCSIDR shift values */
+#define     ARM_AR_MEM_CLIDR_LOC_RSHT_OFFSET       24
+#define     ARM_AR_MEM_CCSIDR_ASSOC_RSHT_OFFSET    3
+#define     ARM_AR_MEM_CCSIDR_NUMSET_RSHT_OFFSET   13
+
+/* Extract 'encoded' line length of the cache */
+#define     ARM_AR_MEM_CCSIDR_LINESIZE_GET(ccsidr_reg) (ccsidr_reg &                           \
+                                                         ARM_AR_MEM_CCSIDR_LINESIZE_MASK)
+
+/* Extract 'encoded' way size of the cache */
+#define     ARM_AR_MEM_CCSIDR_ASSOC_GET(ccsidr_reg)    (ARM_AR_MEM_CCSIDR_ASSOC_MASK &        \
+                                                        (ccsidr_reg >>                          \
+                                                         ARM_AR_MEM_CCSIDR_ASSOC_RSHT_OFFSET))
+
+/* Extract 'encoded' maximum number of index size */
+#define     ARM_AR_MEM_CCSIDR_NUMSET_GET(ccsidr_reg)   (ARM_AR_MEM_CCSIDR_NUMSET_MASK &       \
+                                                        (ccsidr_reg >>                          \
+                                                         ARM_AR_MEM_CCSIDR_NUMSET_RSHT_OFFSET))
+
+/* Refer to chapter B3.12.31 c7, Cache and branch predictor maintenance functions in the
+ ARM Architecture Reference Manual ARMv7-A and ARMv7-R Edition 1360*/
+/* Calculate # of bits to be shifted for set size and way size */
+
+/* log2(line size in bytes) = ccsidr_linesize + 2 + logbase2(4) */
+#define     ARM_AR_MEM_L_CALCULATE(linesize)           (linesize + 2 + 2)
+
+/* log2(nsets) = 32 - way_size_bit_pos */
+
+/* Find the bit position of way size increment */
+#define     ARM_AR_MEM_A_CALCULATE(assoc, a_offset_ref)                                        \
+            {                                                                                   \
+                unsigned int  temp_pos = 0x80000000;                                                  \
+                                                                                                \
+                *a_offset_ref = 0;                                                              \
+                                                                                                \
+                /* Logic to count the number of leading zeros before the first 1 */             \
+                while(!((assoc & temp_pos) == temp_pos))                                        \
+                {                                                                               \
+                    (*a_offset_ref)++;                                                          \
+                    temp_pos = temp_pos >> 1;                                                   \
+                }                                                                               \
+            }
+
+/* Factor way, cache number, index number */
+#define     ARM_AR_MEM_DCCISW_SET(dccisw_ref, level, numsets, assoc, l_offset, a_offset)       \
+            {                                                                                   \
+                *dccisw_ref = (level | (numsets << l_offset) | (assoc << a_offset));            \
+            }
+
+/* This macro extracts line size, assoc and set size from CCSIDR */
+#define     ARM_AR_MEM_CCSIDR_VALS_GET(linesize_ref, assoc_ref, numsets_ref,                   \
+                                        l_offset_ref, a_offset_ref)                             \
+            {                                                                                   \
+                unsigned int  ccsidr_val;                                                             \
+                                                                                                \
+                /* Read the selected cache's CCSIDR */                                          \
+                ARM_AR_CP_READ(ARM_AR_CP15, 1, &ccsidr_val,                           \
+                                    ARM_AR_C0, ARM_AR_C0, 0);                         \
+                                                                                                \
+                /* Extract 'encoded' line length of the cache */                                \
+                *linesize_ref = ARM_AR_MEM_CCSIDR_LINESIZE_GET(ccsidr_val);                    \
+                                                                                                \
+                /* Extract 'encoded' way size of the cache */                                   \
+                *assoc_ref = ARM_AR_MEM_CCSIDR_ASSOC_GET(ccsidr_val);                          \
+                                                                                                \
+                /* Extract 'encoded' maximum number of index size */                            \
+                *numsets_ref = ARM_AR_MEM_CCSIDR_NUMSET_GET(ccsidr_val);                       \
+                                                                                                \
+                /* Calculate # of bits to be shifted for set size and way size */               \
+                                                                                                \
+                /* log2(line size in bytes) = ccsidr_linesize + 2 + log2(4) */                  \
+                *l_offset_ref = ARM_AR_MEM_L_CALCULATE(*linesize_ref);                         \
+                                                                                                \
+                /* log2(nsets) = 32 - way_size_bit_pos */                                       \
+                ARM_AR_MEM_A_CALCULATE(*assoc_ref, a_offset_ref);                              \
+            }
+
+/* This macro invalidates all of the instruction cache at the core level. */
+#define     ARM_AR_MEM_ICACHE_ALL_INVALIDATE()                         \
+            {                                                           \
+                ARM_AR_CP_WRITE(ARM_AR_CP15, 0,               \
+                                     0, ARM_AR_C7,                 \
+                                     ARM_AR_C5, 0);                \
+            }
+
+
+/* This macro invalidates all of the data cache at the core level. */
+void     ARM_AR_MEM_DCACHE_ALL_OP( int type)                                                     
+{                                                                                   
+       unsigned int  clidr_val = 0;                                                          
+       unsigned int  clidr_loc = 0;                                                          
+       unsigned int  cache_number = 0;                                                       
+       unsigned int  cache_type = 0;                                                         
+       unsigned int  ccsidr_linesize = 0;                                                    
+       unsigned int  ccsidr_assoc = 0;                                                       
+       int   ccsidr_numsets = 0;                                                     
+       int   way_size_copy = 0;                                                      
+       unsigned int  set_size_bit_pos = 0;                                                   
+       unsigned int  cache_number_pos = 0;                                                   
+       unsigned int  way_size_bit_pos = 0;                                                   
+       unsigned int  set_way_value = 0;                                                      
+                                                                                                                                                                  
+                                                                                                                                                                       
+       /* Read CLIDR to extract level of coherence (LOC) */                            
+       ARM_AR_CP_READ(ARM_AR_CP15, 1, &clidr_val,                            
+                                               ARM_AR_C0, ARM_AR_C0, 1);                         
+                                                                                                                                                                       
+       /* Extract LOC from CLIDR and align it at bit 1 */                              
+       clidr_loc = (clidr_val & ARM_AR_MEM_CLIDR_LOC_MASK) >>                         
+                               ARM_AR_MEM_CLIDR_LOC_RSHT_OFFSET;                                  
+                                                                                                                                                                       
+       /* Proceed only iff LOC is non-zero */                                          
+       if (clidr_loc != 0)                                                             
+       {                                                                               
+               do                                                                          
+               {                                                                           
+                       /* Extract cache type from CLIDR */                                     
+                       cache_number_pos = cache_number + (cache_number >> 1);                  
+                       cache_type = (clidr_val >> cache_number_pos) & 0x7;                     
+                                                                                                                                                                       
+                       /* Continue only iff data cache */                                      
+                       if (cache_type >= 2)                                                    
+                       {                                                                       
+                               /* Select desired cache level in CSSELR */                          
+                               ARM_AR_CP_WRITE(ARM_AR_CP15, 2, cache_number,             
+                                                                        ARM_AR_C0, ARM_AR_C0, 0);            
+                                                                                                                                                                       
+                               ARM_AR_ISB_EXECUTE();                                          
+                                                                                                                                                                       
+                               /* Get data like linesize, assoc and set size */                    
+                               ARM_AR_MEM_CCSIDR_VALS_GET(&ccsidr_linesize,                       
+                                                                                       &ccsidr_assoc,                          
+                                                                                       &ccsidr_numsets,                        
+                                                                                       &set_size_bit_pos,                      
+                                                                                       &way_size_bit_pos);                     
+                                                                                                                                                                       
+                               do                                                                  
+                               {                                                                   
+                                       way_size_copy = ccsidr_assoc;                                   
+                                                                                                                                                                       
+                                       do                                                              
+                                       {                                                               
+                                               /* Factor way, cache number, index number */                
+                                               ARM_AR_MEM_DCCISW_SET(&set_way_value, cache_number,        
+                                                                                          ccsidr_numsets, way_size_copy,       
+                                                                                          set_size_bit_pos,                    
+                                                                                          way_size_bit_pos);                   
+                                                                                                                                                                       
+                                               /* Execute invalidate if type = 0 */                        
+                                               if (type == 0)                                              
+                                               {                                                           
+                                                       ARM_AR_CP_WRITE(ARM_AR_CP15, 0,               
+                                                                                                set_way_value,                     
+                                                                                                ARM_AR_C7,                    
+                                                                                                ARM_AR_C6, 2);                
+                                               }                                                           
+                                               else                                                        
+                                               {                                                           
+                                                       ARM_AR_CP_WRITE(ARM_AR_CP15, 0,               
+                                                                                                set_way_value,                     
+                                                                                                ARM_AR_C7,                    
+                                                                                                ARM_AR_C14, 2);               
+                                               }                                                           
+                                                                                                                                                                       
+                                       /* decrement the way */                                         
+                                       } while((--way_size_copy) >= 0);                                
+                                                                                                                                                                       
+                               /* decrement the set */                                             
+                               } while((--ccsidr_numsets) >= 0);                                   
+                                                                                                                                                                       
+                       } /* end if */                                                          
+                                                                                                                                                                       
+                       /* Increment cache number */                                            
+                       cache_number += 2;                                                      
+                                                                                                                                                                       
+               /* end do-while */                                                          
+               } while(clidr_loc >= cache_number);                                         
+                                                                                                                                                                       
+       }                                                                               
+                                                                                                                                                                  
+       /* Switch back to cache level 0 in CSSELR */                                    
+       ARM_AR_CP_WRITE(ARM_AR_CP15, 2, 0,                                    
+                                                ARM_AR_C0, ARM_AR_C0, 0);                        
+                                                                                                                                                                       
+       /* Sync */                                                                      
+       ARM_AR_DSB_EXECUTE();                                                      
+       ARM_AR_ISB_EXECUTE();                                                      
+}
+
+/* This macro invalidates all of the data cache at the core level. */
+void    ARM_AR_MEM_DCACHE_ALL_INVALIDATE(void)         
+{
+       ARM_AR_MEM_DCACHE_ALL_OP(0);
+}
+
+/* This macro invalidates all of the cache at the core level. */
+void     ARM_AR_MEM_CACHE_ALL_INVALIDATE(void)                                                  
+{                                                                                   
+       ARM_AR_MEM_ICACHE_ALL_INVALIDATE();                                            
+       ARM_AR_MEM_DCACHE_ALL_INVALIDATE();                                            
+}
+
+
+static void clean_system(void){
+
+    invalidate_cache();
+
+}
+static void invalidate_cache(void)
+{
+       ARM_AR_MEM_CACHE_ALL_INVALIDATE();
+}
index fe5ea68b0781445ade52a4bd3660a57553b5ba1c..6fe145d1780a74cc8d215b8627eacbd6e56cb2fd 100644 (file)
-@*\r
-@* Copyright (c) 2014, Mentor Graphics Corporation\r
-@* All rights reserved.\r
-@*\r
-@* Redistribution and use in source and binary forms, with or without\r
-@* modification, are permitted provided that the following conditions are met:\r
-@*\r
-@* 1. Redistributions of source code must retain the above copyright notice,\r
-@*    this list of conditions and the following disclaimer.\r
-@* 2. Redistributions in binary form must reproduce the above copyright notice,\r
-@*    this list of conditions and the following disclaimer in the documentation\r
-@*    and/or other materials provided with the distribution.\r
-@* 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
-@*    contributors may be used to endorse or promote products derived from this\r
-@*    software without specific prior written permission.\r
-@*\r
-@* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
-@* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
-@* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
-@* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
-@* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
-@* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
-@* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
-@* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
-@* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
-@* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
-@* POSSIBILITY OF SUCH DAMAGE.\r
-\r
-\r
-\r
-    .extern boot_linux\r
-    .extern _bss_end\r
-    .extern linux_kernel_start\r
-    .extern dtb_start\r
-\r
-    @ include FIT format linux image\r
-    .section fit_image, "a"\r
-       .incbin "libs/system/zc702evk/linux/image.ub";\r
-\r
-    .section    bootwrapper, "ax"\r
-\r
-    .code 32\r
-\r
-BOOTSTRAP_BSS_End:\r
-    .long _bss_end\r
-\r
-    .global  bootwrapper_start\r
-bootwrapper_start:\r
-\r
-       MOV         r0, #0xdF\r
-\r
-    @ Switch to SVC mode with IRQs and FIQs OFF\r
-    MSR     CPSR_cxsf, r0\r
-\r
-    @ Disable MMU and caches\r
-\r
-    MRC     p15,#0,r0,c1,c0,#0\r
-    BIC     r0,r0,#0x00001000               @ Clear I bit to disable instruction cache\r
-    BIC     r0,r0,#0x00000005               @ Clear C and M bits (-C-M)\r
-\r
-    @ Disable alignment checking\r
-    BIC            r0,r0,#0x00000002               @ Clear alignement checking bit\r
-\r
-    MCR     p15,#0,r0,c1,c0,#0\r
-    \r
-    MRC     p15,#0,r0,c1,c0,#2\r
-    MOV     r1,#0xF0\r
-    LSL     r1,r1,#16\r
-    ORR     r0,r0,r1\r
-    MCR     p15,#0,r0,c1,c0,#2\r
-\r
-\r
-    MOV     r0,#0x40000000\r
-    FMXR    FPEXC,r0\r
-    \r
-\r
-    @ Setup stack pointer for function calls\r
-    LDR            r0, BOOTSTRAP_BSS_End\r
-\r
-    ADD     r0,r0,#64512\r
-\r
-    @ align stack pointer\r
-    BIC     r0,r0,#0x07\r
-    MOV     sp,r0\r
-\r
-    @ branch to C linux boot function\r
-    B       boot_linux\r
-\r
-    .code 32\r
-    .global  start_linux_with_dtb\r
-    .type start_linux_with_dtb, %function\r
-start_linux_with_dtb:\r
-\r
-    @ Set registers as per Linux boot requirements\r
-    @ For details see:\r
-    @ https://www.kernel.org/doc/Documentation/arm/Booting\r
-\r
-       MOV     r0, #0   @ Set r0 =0\r
-\r
-       LDR     r1, =3343  @ Set r1 = machine type (Xilinx)\r
-\r
-       LDR     r4, =dtb_start\r
-\r
-       LDR     r2, [r4] @ Point r2 to DTB\r
-\r
-       MOV     r3, #0\r
-\r
-       LDR     r4, =linux_kernel_start\r
-\r
-    LDR lr, [r4]\r
-\r
-    MOV pc, lr @ Jump to start of Linux kernel binary\r
-\r
+@*
+@* Copyright (c) 2014, Mentor Graphics Corporation
+@* 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.
+
+
+
+    .extern boot_linux
+    .extern _bss_end
+    .extern linux_kernel_start
+    .extern dtb_start
+
+    @ include FIT format linux image
+    .section fit_image, "a"
+       .incbin "libs/system/zc702evk/linux/image.ub";
+
+    .section    bootwrapper, "ax"
+
+    .code 32
+
+BOOTSTRAP_BSS_End:
+    .long _bss_end
+
+    .global  bootwrapper_start
+bootwrapper_start:
+
+       MOV         r0, #0xdF
+
+    @ Switch to SVC mode with IRQs and FIQs OFF
+    MSR     CPSR_cxsf, r0
+
+    @ Disable MMU and caches
+
+    MRC     p15,#0,r0,c1,c0,#0
+    BIC     r0,r0,#0x00001000               @ Clear I bit to disable instruction cache
+    BIC     r0,r0,#0x00000005               @ Clear C and M bits (-C-M)
+
+    @ Disable alignment checking
+    BIC            r0,r0,#0x00000002               @ Clear alignement checking bit
+
+    MCR     p15,#0,r0,c1,c0,#0
+    
+    MRC     p15,#0,r0,c1,c0,#2
+    MOV     r1,#0xF0
+    LSL     r1,r1,#16
+    ORR     r0,r0,r1
+    MCR     p15,#0,r0,c1,c0,#2
+
+
+    MOV     r0,#0x40000000
+    FMXR    FPEXC,r0
+    
+
+    @ Setup stack pointer for function calls
+    LDR            r0, BOOTSTRAP_BSS_End
+
+    ADD     r0,r0,#64512
+
+    @ align stack pointer
+    BIC     r0,r0,#0x07
+    MOV     sp,r0
+
+    @ branch to C linux boot function
+    B       boot_linux
+
+    .code 32
+    .global  start_linux_with_dtb
+    .type start_linux_with_dtb, %function
+start_linux_with_dtb:
+
+    @ Set registers as per Linux boot requirements
+    @ For details see:
+    @ https://www.kernel.org/doc/Documentation/arm/Booting
+
+       MOV     r0, #0   @ Set r0 =0
+
+       LDR     r1, =3343  @ Set r1 = machine type (Xilinx)
+
+       LDR     r4, =dtb_start
+
+       LDR     r2, [r4] @ Point r2 to DTB
+
+       MOV     r3, #0
+
+       LDR     r4, =linux_kernel_start
+
+    LDR lr, [r4]
+
+    MOV pc, lr @ Jump to start of Linux kernel binary
+
index 7e08efbee6d990730920ac1efcac00bc5e192f90..9e8ffc6477da2b1cf08ebb5bc9394c69e8981f6e 100644 (file)
@@ -1,89 +1,89 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* This file populates resource table for BM remotes\r
- * for use by the Linux Master */\r
-\r
-#include "open_amp.h"\r
-#include "rsc_table.h"\r
-\r
-/* Place resource table in special ELF section */\r
-#define __section(S)            __attribute__((__section__(#S)))\r
-#define __resource              __section(.resource_table)\r
-\r
-#define RPMSG_IPU_C0_FEATURES       1\r
-\r
-/* VirtIO rpmsg device id */\r
-#define VIRTIO_ID_RPMSG_             7\r
-\r
-/* Remote supports Name Service announcement */\r
-#define VIRTIO_RPMSG_F_NS           0\r
-\r
-/* Resource table entries */\r
-#define ELF_START                   0x00000000\r
-#define ELF_END                     0x08000000\r
-#define NUM_VRINGS                                     0x02\r
-#define VRING_ALIGN                                    0x1000\r
-#define RING_TX                     0x08000000\r
-#define RING_RX                     0x08004000\r
-#define VRING_SIZE                  256\r
-\r
-const struct remote_resource_table __resource resources =\r
-{\r
-    /* Version */\r
-    1,\r
-\r
-    /* NUmber of table entries */\r
-    2,\r
-    /* reserved fields */\r
-    {   0, 0,},\r
-\r
-    /* Offsets of rsc entries */\r
-    {\r
-        offsetof(struct remote_resource_table, elf_cout),\r
-        offsetof(struct remote_resource_table, rpmsg_vdev),\r
-    },\r
-\r
-    /* End of ELF file */\r
-    {\r
-        RSC_CARVEOUT, ELF_START, ELF_START, ELF_END, 0, 0, "ELF_COUT",\r
-    },\r
-\r
-    /* Virtio device entry */\r
-    {   RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, NUM_VRINGS, {0, 0},\r
-    },\r
-\r
-    /* Vring rsc entry - part of vdev rsc entry */\r
-    {\r
-        RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0\r
-    },\r
-    {\r
-        RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0\r
-    },\r
-};\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/* This file populates resource table for BM remotes
+ * for use by the Linux Master */
+
+#include "open_amp.h"
+#include "rsc_table.h"
+
+/* Place resource table in special ELF section */
+#define __section(S)            __attribute__((__section__(#S)))
+#define __resource              __section(.resource_table)
+
+#define RPMSG_IPU_C0_FEATURES       1
+
+/* VirtIO rpmsg device id */
+#define VIRTIO_ID_RPMSG_             7
+
+/* Remote supports Name Service announcement */
+#define VIRTIO_RPMSG_F_NS           0
+
+/* Resource table entries */
+#define ELF_START                   0x00000000
+#define ELF_END                     0x08000000
+#define NUM_VRINGS                                     0x02
+#define VRING_ALIGN                                    0x1000
+#define RING_TX                     0x08000000
+#define RING_RX                     0x08004000
+#define VRING_SIZE                  256
+
+const struct remote_resource_table __resource resources =
+{
+    /* Version */
+    1,
+
+    /* NUmber of table entries */
+    2,
+    /* reserved fields */
+    {   0, 0,},
+
+    /* Offsets of rsc entries */
+    {
+        offsetof(struct remote_resource_table, elf_cout),
+        offsetof(struct remote_resource_table, rpmsg_vdev),
+    },
+
+    /* End of ELF file */
+    {
+        RSC_CARVEOUT, ELF_START, ELF_START, ELF_END, 0, 0, "ELF_COUT",
+    },
+
+    /* Virtio device entry */
+    {   RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0, NUM_VRINGS, {0, 0},
+    },
+
+    /* Vring rsc entry - part of vdev rsc entry */
+    {
+        RING_TX, VRING_ALIGN, VRING_SIZE, 1, 0
+    },
+    {
+        RING_RX, VRING_ALIGN, VRING_SIZE, 2, 0
+    },
+};
index 0a8e95750d5d919b1fe9ece8236a632fc84d1801..842b423db71351e24b6513a14f1be348eb7b9def 100644 (file)
@@ -1,51 +1,51 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/* This file populates resource table for BM remote\r
- * for use by the Linux Master */\r
-\r
-#include <stddef.h>\r
-#include "open_amp.h"\r
-\r
-#define NO_RESOURCE_ENTRIES         8\r
-\r
-/* Resource table for the given remote */\r
-struct remote_resource_table {\r
-    unsigned int version;\r
-    unsigned int num;\r
-    unsigned int reserved[2];\r
-    unsigned int offset[NO_RESOURCE_ENTRIES];\r
-    /* text carveout entry */\r
-    struct fw_rsc_carveout elf_cout;\r
-    /* rpmsg vdev entry */\r
-    struct fw_rsc_vdev rpmsg_vdev;\r
-    struct fw_rsc_vdev_vring rpmsg_vring0;\r
-    struct fw_rsc_vdev_vring rpmsg_vring1;\r
-};\r
-\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/* This file populates resource table for BM remote
+ * for use by the Linux Master */
+
+#include <stddef.h>
+#include "open_amp.h"
+
+#define NO_RESOURCE_ENTRIES         8
+
+/* Resource table for the given remote */
+struct remote_resource_table {
+    unsigned int version;
+    unsigned int num;
+    unsigned int reserved[2];
+    unsigned int offset[NO_RESOURCE_ENTRIES];
+    /* text carveout entry */
+    struct fw_rsc_carveout elf_cout;
+    /* rpmsg vdev entry */
+    struct fw_rsc_vdev rpmsg_vdev;
+    struct fw_rsc_vdev_vring rpmsg_vring0;
+    struct fw_rsc_vdev_vring rpmsg_vring1;
+};
+
index 38e72f51983f7ce40b4e2ba738af3badcd1db66b..0f28479fc1cb7e52845387dcf73342137b9a5c62 100644 (file)
@@ -1,95 +1,95 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       config.c\r
- *\r
- * COMPONENT\r
- *\r
- *         OpenAMP stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- *\r
- **************************************************************************/\r
-\r
-#include "config.h"\r
-\r
-/* Start and end addresses of firmware image for remotes. These are defined in the\r
- * object files that are obtained by converting the remote ELF Image into object\r
- * files. These symbols are not used for remotes.\r
- */\r
-extern unsigned char _binary_firmware1_start;\r
-extern unsigned char _binary_firmware1_end;\r
-\r
-extern unsigned char _binary_firmware2_start;\r
-extern unsigned char _binary_firmware2_end;\r
-\r
-#define FIRMWARE1_START  (void *)&_binary_firmware1_start\r
-#define FIRMWARE1_END    (void *)&_binary_firmware1_end\r
-\r
-#define FIRMWARE2_START  (void *)&_binary_firmware2_start\r
-#define FIRMWARE2_END    (void *)&_binary_firmware2_end\r
-\r
-/* Init firmware table */\r
-\r
-const struct firmware_info fw_table[] = { { "firmware1",\r
-                (unsigned int) FIRMWARE1_START, (unsigned int) FIRMWARE1_END },\r
-                { "firmware2", (unsigned int) FIRMWARE2_START,\r
-                (unsigned int) FIRMWARE2_END } };\r
-\r
-/**\r
- * config_get_firmware\r
- *\r
- * Searches the given firmware in firmware table list and provides\r
- * it to caller.\r
- *\r
- * @param fw_name    - name of the firmware\r
- * @param start_addr - pointer t hold start address of firmware\r
- * @param size       - pointer to hold size of firmware\r
- *\r
- * returns -  status of function execution\r
- *\r
- */\r
-\r
-int config_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size) {\r
-    int idx;\r
-    for (idx = 0; idx < sizeof(fw_table) / (sizeof(struct firmware_info));\r
-                    idx++) {\r
-        if (!env_strncmp((char *) fw_table[idx].name, fw_name,\r
-                        sizeof(fw_table[idx].name))) {\r
-            *start_addr = fw_table[idx].start_addr;\r
-            *size = fw_table[idx].end_addr - fw_table[idx].start_addr + 1;\r
-            return 0;\r
-        }\r
-    }\r
-    return -1;\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       config.c
+ *
+ * COMPONENT
+ *
+ *         OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ *
+ **************************************************************************/
+
+#include "config.h"
+
+/* Start and end addresses of firmware image for remotes. These are defined in the
+ * object files that are obtained by converting the remote ELF Image into object
+ * files. These symbols are not used for remotes.
+ */
+extern unsigned char _binary_firmware1_start;
+extern unsigned char _binary_firmware1_end;
+
+extern unsigned char _binary_firmware2_start;
+extern unsigned char _binary_firmware2_end;
+
+#define FIRMWARE1_START  (void *)&_binary_firmware1_start
+#define FIRMWARE1_END    (void *)&_binary_firmware1_end
+
+#define FIRMWARE2_START  (void *)&_binary_firmware2_start
+#define FIRMWARE2_END    (void *)&_binary_firmware2_end
+
+/* Init firmware table */
+
+const struct firmware_info fw_table[] = { { "firmware1",
+                (unsigned int) FIRMWARE1_START, (unsigned int) FIRMWARE1_END },
+                { "firmware2", (unsigned int) FIRMWARE2_START,
+                (unsigned int) FIRMWARE2_END } };
+
+/**
+ * config_get_firmware
+ *
+ * Searches the given firmware in firmware table list and provides
+ * it to caller.
+ *
+ * @param fw_name    - name of the firmware
+ * @param start_addr - pointer t hold start address of firmware
+ * @param size       - pointer to hold size of firmware
+ *
+ * returns -  status of function execution
+ *
+ */
+
+int config_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size) {
+    int idx;
+    for (idx = 0; idx < sizeof(fw_table) / (sizeof(struct firmware_info));
+                    idx++) {
+        if (!env_strncmp((char *) fw_table[idx].name, fw_name,
+                        sizeof(fw_table[idx].name))) {
+            *start_addr = fw_table[idx].start_addr;
+            *size = fw_table[idx].end_addr - fw_table[idx].start_addr + 1;
+            return 0;
+        }
+    }
+    return -1;
 }
index 4eb3f832c5eb2fa6045cbfbf140a830d109138c4..6bba03eaecf9b2b48ffafff43edc80ac31a92de5 100644 (file)
@@ -1,59 +1,59 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef CONFIG_H\r
-#define CONFIG_H\r
-\r
-#include "../env/env.h"\r
-\r
-/* Max supprted ISR counts */\r
-#define ISR_COUNT                       4\r
-\r
-/* Max supported firmwares */\r
-#define FW_COUNT                        4\r
-/**\r
- * Structure to keep track of registered ISR's.\r
- */\r
-struct isr_info {\r
-    int vector;\r
-    int priority;\r
-    int type;\r
-    void *data;\r
-    void (*isr)(int vector, void *data);\r
-};\r
-\r
-struct firmware_info {\r
-    char name[32];\r
-    unsigned int start_addr;\r
-    unsigned int end_addr;\r
-};\r
-\r
-int config_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size);\r
-\r
-#endif\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "../env/env.h"
+
+/* Max supprted ISR counts */
+#define ISR_COUNT                       4
+
+/* Max supported firmwares */
+#define FW_COUNT                        4
+/**
+ * Structure to keep track of registered ISR's.
+ */
+struct isr_info {
+    int vector;
+    int priority;
+    int type;
+    void *data;
+    void (*isr)(int vector, void *data);
+};
+
+struct firmware_info {
+    char name[32];
+    unsigned int start_addr;
+    unsigned int end_addr;
+};
+
+int config_get_firmware(char *fw_name, unsigned int *start_addr, unsigned int *size);
+
+#endif
index c90b74cf5ac182afd4a63614d552354464f2b0e1..a02ad37884be5e515e8bd5262c19972341599736 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- * Copyright (c) 2015 Xilinx, Inc. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
- /**************************************************************************\r
- * FILE NAME\r
- *\r
- *       env.h\r
- *\r
- * COMPONENT\r
- *\r
- *         OpenAMP stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- *       This file defines abstraction layer for OpenAMP stack. The implementor\r
- *       must provide definition of all the functions.\r
- *\r
- * DATA STRUCTURES\r
- *\r
- *        none\r
- *\r
- * FUNCTIONS\r
- *\r
- *       env_allocate_memory\r
- *       env_free_memory\r
- *       env_memset\r
- *       env_memcpy\r
- *       env_strlen\r
- *       env_strcpy\r
- *       env_strncpy\r
- *       env_print\r
- *       env_map_vatopa\r
- *       env_map_patova\r
- *       env_mb\r
- *       env_rmb\r
- *       env_wmb\r
- *       env_create_mutex\r
- *       env_delete_mutex\r
- *       env_lock_mutex\r
- *       env_unlock_mutex\r
- *       env_sleep_msec\r
- *       env_disable_interrupts\r
- *       env_restore_interrupts\r
- *\r
- **************************************************************************/\r
-#ifndef _ENV_H_\r
-#define _ENV_H_\r
-\r
-#include <stdio.h>\r
-\r
-/**\r
- * env_init\r
- *\r
- * Initializes OS/BM environment.\r
- *\r
- * @returns - execution status\r
- */\r
-\r
-int env_init();\r
-\r
-/**\r
- * env_deinit\r
- *\r
- * Uninitializes OS/BM environment.\r
- *\r
- * @returns - execution status\r
- */\r
-\r
-int env_deinit();\r
-/**\r
- * -------------------------------------------------------------------------\r
- *\r
- * Dynamic memory management functions. The parameters\r
- * are similar to standard c functions.\r
- *\r
- *-------------------------------------------------------------------------\r
- **/\r
-\r
-/**\r
- * env_allocate_memory\r
- *\r
- * Allocates memory with the given size.\r
- *\r
- * @param size - size of memory to allocate\r
- *\r
- * @return - pointer to allocated memory\r
- */\r
-void *env_allocate_memory(unsigned int size);\r
-\r
-/**\r
- * env_free_memory\r
- *\r
- * Frees memory pointed by the given parameter.\r
- *\r
- * @param ptr - pointer to memory to free\r
- */\r
-void env_free_memory(void *ptr);\r
-\r
-/**\r
- * -------------------------------------------------------------------------\r
- *\r
- * RTL Functions\r
- *\r
- *-------------------------------------------------------------------------\r
- */\r
-\r
-void env_memset(void *, int, unsigned long);\r
-void env_memcpy(void *, void const *, unsigned long);\r
-size_t env_strlen(const char *);\r
-void env_strcpy(char *, const char *);\r
-int env_strcmp(const char *, const char *);\r
-void env_strncpy(char *, const char *, unsigned long);\r
-int env_strncmp(char *, const char *, unsigned long);\r
-#define env_print(...)  printf(__VA_ARGS__)\r
-\r
-/**\r
- *-----------------------------------------------------------------------------\r
- *\r
- *  Functions to convert physical address to virtual address and vice versa.\r
- *\r
- *-----------------------------------------------------------------------------\r
- */\r
-\r
-/**\r
- * env_map_vatopa\r
- *\r
- * Converts logical address to physical address\r
- *\r
- * @param address - pointer to logical address\r
- *\r
- * @return  - physical address\r
- */\r
-unsigned long env_map_vatopa(void *address);\r
-\r
-/**\r
- * env_map_patova\r
- *\r
- * Converts physical address to logical address\r
- *\r
- * @param address - pointer to physical address\r
- *\r
- * @return  - logical address\r
- *\r
- */\r
-void *env_map_patova(unsigned long address);\r
-\r
-/**\r
- *-----------------------------------------------------------------------------\r
- *\r
- *  Abstractions for memory barrier instructions.\r
- *\r
- *-----------------------------------------------------------------------------\r
- */\r
-\r
-/**\r
- * env_mb\r
- *\r
- * Inserts memory barrier.\r
- */\r
-\r
-void env_mb();\r
-\r
-/**\r
- * env_rmb\r
- *\r
- * Inserts read memory barrier\r
- */\r
-\r
-void env_rmb();\r
-\r
-/**\r
- * env_wmb\r
- *\r
- * Inserts write memory barrier\r
- */\r
-\r
-void env_wmb();\r
-\r
-/**\r
- *-----------------------------------------------------------------------------\r
- *\r
- *  Abstractions for OS lock primitives.\r
- *\r
- *-----------------------------------------------------------------------------\r
- */\r
-\r
-/**\r
- * env_create_mutex\r
- *\r
- * Creates a mutex with given initial count.\r
- *\r
- * @param lock -  pointer to created mutex\r
- * @param count - initial count 0 or 1\r
- *\r
- * @return - status of function execution\r
- */\r
-int env_create_mutex(void **lock , int count);\r
-\r
-/**\r
- * env_delete_mutex\r
- *\r
- * Deletes the given lock.\r
- *\r
- * @param lock - mutex to delete\r
- */\r
-\r
-void env_delete_mutex(void *lock);\r
-\r
-/**\r
- * env_lock_mutex\r
- *\r
- * Tries to acquire the lock, if lock is not available then call to\r
- * this function will suspend.\r
- *\r
- * @param lock - mutex to lock\r
- *\r
- */\r
-\r
-void env_lock_mutex(void *lock);\r
-\r
-/**\r
- * env_unlock_mutex\r
- *\r
- * Releases the given lock.\r
- *\r
- * @param lock - mutex to unlock\r
- */\r
-\r
-void env_unlock_mutex(void *lock);\r
-\r
-/**\r
- * env_create_sync_lock\r
- *\r
- * Creates a synchronization lock primitive. It is used\r
- * when signal has to be sent from the interrupt context to main\r
- * thread context.\r
- *\r
- * @param lock  - pointer to created sync lock object\r
- * @param state - initial state , lock or unlocked\r
- *\r
- * @returns - status of function execution\r
- */\r
-#define LOCKED                 0\r
-#define UNLOCKED               1\r
-\r
-int env_create_sync_lock(void **lock , int state);\r
-\r
-/**\r
- * env_create_sync_lock\r
- *\r
- * Deletes given sync lock object.\r
- *\r
- * @param lock  - sync lock to delete.\r
- *\r
- */\r
-\r
-void env_delete_sync_lock(void *lock);\r
-\r
-\r
-/**\r
- * env_acquire_sync_lock\r
- *\r
- * Tries to acquire the sync lock.\r
- *\r
- * @param lock  - sync lock to acquire.\r
- */\r
-void env_acquire_sync_lock(void *lock);\r
-\r
-/**\r
- * env_release_sync_lock\r
- *\r
- * Releases synchronization lock.\r
- *\r
- * @param lock  - sync lock to release.\r
- */\r
-void env_release_sync_lock(void *lock);\r
-\r
-/**\r
- * env_sleep_msec\r
- *\r
- * Suspends the calling thread for given time in msecs.\r
- *\r
- * @param num_msec -  delay in msecs\r
- */\r
-void env_sleep_msec(int num_msec);\r
-\r
-/**\r
- * env_disable_interrupts\r
- *\r
- * Disables system interrupts\r
- *\r
- */\r
-void env_disable_interrupts();\r
-\r
-/**\r
- * env_restore_interrupts\r
- *\r
- * Enables system interrupts\r
- *\r
- */\r
-void env_restore_interrupts();\r
-\r
-/**\r
- * env_register_isr\r
- *\r
- * Registers interrupt handler for the given interrupt vector.\r
- *\r
- * @param vector - interrupt vector number\r
- * @param data   - private data\r
- * @param isr    - interrupt handler\r
- */\r
-\r
-void env_register_isr(int vector, void *data,\r
-                void (*isr)(int vector, void *data));\r
-\r
-void env_update_isr(int vector, void *data,\r
-                void (*isr)(int vector, void *data));\r
-\r
-/**\r
- * env_enable_interrupt\r
- *\r
- * Enables the given interrupt.\r
- *\r
- * @param vector   - interrupt vector number\r
- * @param priority - interrupt priority\r
- * @param polarity - interrupt polarity\r
- */\r
-\r
-void env_enable_interrupt(unsigned int vector, unsigned int priority,\r
-                unsigned int polarity);\r
-\r
-/**\r
- * env_disable_interrupt\r
- *\r
- * Disables the given interrupt.\r
- *\r
- * @param vector   - interrupt vector number\r
- */\r
-\r
-void env_disable_interrupt(unsigned int vector);\r
-\r
-/**\r
- * env_map_memory\r
- *\r
- * Enables memory mapping for given memory region.\r
- *\r
- * @param pa   - physical address of memory\r
- * @param va   - logical address of memory\r
- * @param size - memory size\r
- * param flags - flags for cache/uncached  and access type\r
- *\r
- * Currently only first byte of flag parameter is used and bits mapping is defined as follow;\r
- *\r
- * Cache bits\r
- * 0x0000_0001 = No cache\r
- * 0x0000_0010 = Write back\r
- * 0x0000_0100 = Write through\r
- * 0x0000_x000 = Not used\r
- *\r
- * Memory types\r
- *\r
- * 0x0001_xxxx = Memory Mapped\r
- * 0x0010_xxxx = IO Mapped\r
- * 0x0100_xxxx = Shared\r
- * 0x1000_xxxx = TLB\r
- */\r
-\r
-/* Macros for caching scheme used by the shared memory */\r
-#define UNCACHED                            (1 << 0)\r
-#define WB_CACHE                            (1 << 1)\r
-#define WT_CACHE                            (1 << 2)\r
-\r
-/* Memory Types */\r
-#define MEM_MAPPED                          (1 << 4)\r
-#define IO_MAPPED                           (1 << 5)\r
-#define SHARED_MEM                          (1 << 6)\r
-#define TLB_MEM                             (1 << 7)\r
-\r
-void env_map_memory(unsigned int pa, unsigned int va, unsigned int size,\r
-                unsigned int flags);\r
-\r
-/**\r
- * env_get_timestamp\r
- *\r
- * Returns a 64 bit time stamp.\r
- *\r
- *\r
- */\r
-unsigned long long env_get_timestamp(void);\r
-\r
-/**\r
- * env_disable_cache\r
- * \r
- * Disables system caches.\r
- *\r
- */\r
-\r
-void env_disable_cache();\r
-\r
-typedef void LOCK;\r
-\r
-#endif /* _ENV_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ * Copyright (c) 2015 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.
+ */
+
+ /**************************************************************************
+ * FILE NAME
+ *
+ *       env.h
+ *
+ * COMPONENT
+ *
+ *         OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ *       This file defines abstraction layer for OpenAMP stack. The implementor
+ *       must provide definition of all the functions.
+ *
+ * DATA STRUCTURES
+ *
+ *        none
+ *
+ * FUNCTIONS
+ *
+ *       env_allocate_memory
+ *       env_free_memory
+ *       env_memset
+ *       env_memcpy
+ *       env_strlen
+ *       env_strcpy
+ *       env_strncpy
+ *       env_print
+ *       env_map_vatopa
+ *       env_map_patova
+ *       env_mb
+ *       env_rmb
+ *       env_wmb
+ *       env_create_mutex
+ *       env_delete_mutex
+ *       env_lock_mutex
+ *       env_unlock_mutex
+ *       env_sleep_msec
+ *       env_disable_interrupts
+ *       env_restore_interrupts
+ *
+ **************************************************************************/
+#ifndef _ENV_H_
+#define _ENV_H_
+
+#include <stdio.h>
+
+/**
+ * env_init
+ *
+ * Initializes OS/BM environment.
+ *
+ * @returns - execution status
+ */
+
+int env_init();
+
+/**
+ * env_deinit
+ *
+ * Uninitializes OS/BM environment.
+ *
+ * @returns - execution status
+ */
+
+int env_deinit();
+/**
+ * -------------------------------------------------------------------------
+ *
+ * Dynamic memory management functions. The parameters
+ * are similar to standard c functions.
+ *
+ *-------------------------------------------------------------------------
+ **/
+
+/**
+ * env_allocate_memory
+ *
+ * Allocates memory with the given size.
+ *
+ * @param size - size of memory to allocate
+ *
+ * @return - pointer to allocated memory
+ */
+void *env_allocate_memory(unsigned int size);
+
+/**
+ * env_free_memory
+ *
+ * Frees memory pointed by the given parameter.
+ *
+ * @param ptr - pointer to memory to free
+ */
+void env_free_memory(void *ptr);
+
+/**
+ * -------------------------------------------------------------------------
+ *
+ * RTL Functions
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void env_memset(void *, int, unsigned long);
+void env_memcpy(void *, void const *, unsigned long);
+size_t env_strlen(const char *);
+void env_strcpy(char *, const char *);
+int env_strcmp(const char *, const char *);
+void env_strncpy(char *, const char *, unsigned long);
+int env_strncmp(char *, const char *, unsigned long);
+#define env_print(...)  printf(__VA_ARGS__)
+
+/**
+ *-----------------------------------------------------------------------------
+ *
+ *  Functions to convert physical address to virtual address and vice versa.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/**
+ * env_map_vatopa
+ *
+ * Converts logical address to physical address
+ *
+ * @param address - pointer to logical address
+ *
+ * @return  - physical address
+ */
+unsigned long env_map_vatopa(void *address);
+
+/**
+ * env_map_patova
+ *
+ * Converts physical address to logical address
+ *
+ * @param address - pointer to physical address
+ *
+ * @return  - logical address
+ *
+ */
+void *env_map_patova(unsigned long address);
+
+/**
+ *-----------------------------------------------------------------------------
+ *
+ *  Abstractions for memory barrier instructions.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/**
+ * env_mb
+ *
+ * Inserts memory barrier.
+ */
+
+void env_mb();
+
+/**
+ * env_rmb
+ *
+ * Inserts read memory barrier
+ */
+
+void env_rmb();
+
+/**
+ * env_wmb
+ *
+ * Inserts write memory barrier
+ */
+
+void env_wmb();
+
+/**
+ *-----------------------------------------------------------------------------
+ *
+ *  Abstractions for OS lock primitives.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+/**
+ * env_create_mutex
+ *
+ * Creates a mutex with given initial count.
+ *
+ * @param lock -  pointer to created mutex
+ * @param count - initial count 0 or 1
+ *
+ * @return - status of function execution
+ */
+int env_create_mutex(void **lock , int count);
+
+/**
+ * env_delete_mutex
+ *
+ * Deletes the given lock.
+ *
+ * @param lock - mutex to delete
+ */
+
+void env_delete_mutex(void *lock);
+
+/**
+ * env_lock_mutex
+ *
+ * Tries to acquire the lock, if lock is not available then call to
+ * this function will suspend.
+ *
+ * @param lock - mutex to lock
+ *
+ */
+
+void env_lock_mutex(void *lock);
+
+/**
+ * env_unlock_mutex
+ *
+ * Releases the given lock.
+ *
+ * @param lock - mutex to unlock
+ */
+
+void env_unlock_mutex(void *lock);
+
+/**
+ * env_create_sync_lock
+ *
+ * Creates a synchronization lock primitive. It is used
+ * when signal has to be sent from the interrupt context to main
+ * thread context.
+ *
+ * @param lock  - pointer to created sync lock object
+ * @param state - initial state , lock or unlocked
+ *
+ * @returns - status of function execution
+ */
+#define LOCKED                 0
+#define UNLOCKED               1
+
+int env_create_sync_lock(void **lock , int state);
+
+/**
+ * env_create_sync_lock
+ *
+ * Deletes given sync lock object.
+ *
+ * @param lock  - sync lock to delete.
+ *
+ */
+
+void env_delete_sync_lock(void *lock);
+
+
+/**
+ * env_acquire_sync_lock
+ *
+ * Tries to acquire the sync lock.
+ *
+ * @param lock  - sync lock to acquire.
+ */
+void env_acquire_sync_lock(void *lock);
+
+/**
+ * env_release_sync_lock
+ *
+ * Releases synchronization lock.
+ *
+ * @param lock  - sync lock to release.
+ */
+void env_release_sync_lock(void *lock);
+
+/**
+ * env_sleep_msec
+ *
+ * Suspends the calling thread for given time in msecs.
+ *
+ * @param num_msec -  delay in msecs
+ */
+void env_sleep_msec(int num_msec);
+
+/**
+ * env_disable_interrupts
+ *
+ * Disables system interrupts
+ *
+ */
+void env_disable_interrupts();
+
+/**
+ * env_restore_interrupts
+ *
+ * Enables system interrupts
+ *
+ */
+void env_restore_interrupts();
+
+/**
+ * env_register_isr
+ *
+ * Registers interrupt handler for the given interrupt vector.
+ *
+ * @param vector - interrupt vector number
+ * @param data   - private data
+ * @param isr    - interrupt handler
+ */
+
+void env_register_isr(int vector, void *data,
+                void (*isr)(int vector, void *data));
+
+void env_update_isr(int vector, void *data,
+                void (*isr)(int vector, void *data));
+
+/**
+ * env_enable_interrupt
+ *
+ * Enables the given interrupt.
+ *
+ * @param vector   - interrupt vector number
+ * @param priority - interrupt priority
+ * @param polarity - interrupt polarity
+ */
+
+void env_enable_interrupt(unsigned int vector, unsigned int priority,
+                unsigned int polarity);
+
+/**
+ * env_disable_interrupt
+ *
+ * Disables the given interrupt.
+ *
+ * @param vector   - interrupt vector number
+ */
+
+void env_disable_interrupt(unsigned int vector);
+
+/**
+ * env_map_memory
+ *
+ * Enables memory mapping for given memory region.
+ *
+ * @param pa   - physical address of memory
+ * @param va   - logical address of memory
+ * @param size - memory size
+ * param flags - flags for cache/uncached  and access type
+ *
+ * Currently only first byte of flag parameter is used and bits mapping is defined as follow;
+ *
+ * Cache bits
+ * 0x0000_0001 = No cache
+ * 0x0000_0010 = Write back
+ * 0x0000_0100 = Write through
+ * 0x0000_x000 = Not used
+ *
+ * Memory types
+ *
+ * 0x0001_xxxx = Memory Mapped
+ * 0x0010_xxxx = IO Mapped
+ * 0x0100_xxxx = Shared
+ * 0x1000_xxxx = TLB
+ */
+
+/* Macros for caching scheme used by the shared memory */
+#define UNCACHED                            (1 << 0)
+#define WB_CACHE                            (1 << 1)
+#define WT_CACHE                            (1 << 2)
+
+/* Memory Types */
+#define MEM_MAPPED                          (1 << 4)
+#define IO_MAPPED                           (1 << 5)
+#define SHARED_MEM                          (1 << 6)
+#define TLB_MEM                             (1 << 7)
+
+void env_map_memory(unsigned int pa, unsigned int va, unsigned int size,
+                unsigned int flags);
+
+/**
+ * env_get_timestamp
+ *
+ * Returns a 64 bit time stamp.
+ *
+ *
+ */
+unsigned long long env_get_timestamp(void);
+
+/**
+ * env_disable_cache
+ * 
+ * Disables system caches.
+ *
+ */
+
+void env_disable_cache();
+
+typedef void LOCK;
+
+#endif /* _ENV_H_ */
index 90d1190d956d31ecb177f6a7597f11cd8d875695..4db5e5e8cd984f927f0c72039b0c9bcdbea18e0d 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       platform.c\r
- *\r
- * DESCRIPTION\r
- *\r
- *       This file is the Implementation of IPC hardware layer interface\r
- *       for Xilinx Zynq ZC702EVK platform.\r
- *\r
- **************************************************************************/\r
-\r
-#include "platform.h"\r
-\r
-/*--------------------------- Globals ---------------------------------- */\r
-struct hil_platform_ops proc_ops = {\r
-    .enable_interrupt  = _enable_interrupt,\r
-    .notify                            = _notify,\r
-    .boot_cpu                  = _boot_cpu,\r
-    .shutdown_cpu              = _shutdown_cpu,\r
-};\r
-\r
-int _enable_interrupt(struct proc_vring *vring_hw) {\r
-\r
-    /* Register ISR*/\r
-    env_register_isr(vring_hw->intr_info.vect_id, vring_hw, platform_isr);\r
-\r
-    /* Enable the interrupts */\r
-    env_enable_interrupt(vring_hw->intr_info.vect_id,\r
-                    vring_hw->intr_info.priority,\r
-                    vring_hw->intr_info.trigger_type);\r
-    return 0;\r
-}\r
-\r
-void _notify(int cpu_id, struct proc_intr *intr_info) {\r
-\r
-    unsigned long mask = 0;\r
-\r
-    mask = ((1 << (GIC_CPU_ID_BASE + cpu_id)) | (intr_info->vect_id))\r
-                    & (GIC_SFI_TRIG_CPU_MASK | GIC_SFI_TRIG_INTID_MASK);\r
-\r
-    HIL_MEM_WRITE32((GIC_DIST_BASE + GIC_DIST_SOFTINT), mask);\r
-}\r
-\r
-extern char zynq_trampoline;\r
-extern char zynq_trampoline_jump;\r
-extern char zynq_trampoline_end;\r
-\r
-int _boot_cpu(int cpu_id, unsigned int load_addr) {\r
-    unsigned int reg;\r
-    unsigned int tramp_size;\r
-    unsigned int tramp_addr = 0;\r
-\r
-    if (load_addr) {\r
-        tramp_size = zynq_trampoline_end - zynq_trampoline;\r
-        if ((load_addr < tramp_size) || (load_addr & 0x3)) {\r
-            return -1;\r
-        }\r
-\r
-        tramp_size = &zynq_trampoline_jump - &zynq_trampoline;\r
-\r
-        /*\r
-         * Trampoline code is copied to address 0 from where remote core is expected to\r
-         * fetch first instruction after reset.If master is using the address 0 then\r
-         * this mem copy will screwed the system. It is user responsibility to not\r
-         * copy trampoline code in such cases.\r
-         *\r
-         */\r
-        env_memcpy((char *)tramp_addr, &zynq_trampoline, tramp_size);\r
-        /* Write image address at the word reserved at the trampoline end */\r
-        HIL_MEM_WRITE32((char *)(tramp_addr + tramp_size), load_addr);\r
-    }\r
-\r
-    unlock_slcr();\r
-\r
-    reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL);\r
-    reg &= ~(A9_CPU_SLCR_CLK_STOP << cpu_id);\r
-    HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);\r
-    /* De-assert reset signal and start clock to start the core */\r
-    reg &= ~(A9_CPU_SLCR_RST << cpu_id);\r
-    HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);\r
-\r
-    lock_slcr();\r
-\r
-    return 0;\r
-}\r
-\r
-void _shutdown_cpu(int cpu_id) {\r
-    unsigned int reg;\r
-\r
-    unlock_slcr();\r
-\r
-    reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL);\r
-    /* Assert reset signal and stop clock to halt the core */\r
-    reg |= (A9_CPU_SLCR_CLK_STOP | A9_CPU_SLCR_RST) << cpu_id;\r
-    HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);\r
-\r
-    lock_slcr();\r
-}\r
-\r
-void platform_isr(int vect_id, void *data) {\r
-    hil_isr(((struct proc_vring *) data));\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       platform.c
+ *
+ * DESCRIPTION
+ *
+ *       This file is the Implementation of IPC hardware layer interface
+ *       for Xilinx Zynq ZC702EVK platform.
+ *
+ **************************************************************************/
+
+#include "platform.h"
+
+/*--------------------------- Globals ---------------------------------- */
+struct hil_platform_ops proc_ops = {
+    .enable_interrupt  = _enable_interrupt,
+    .notify                            = _notify,
+    .boot_cpu                  = _boot_cpu,
+    .shutdown_cpu              = _shutdown_cpu,
+};
+
+int _enable_interrupt(struct proc_vring *vring_hw) {
+
+    /* Register ISR*/
+    env_register_isr(vring_hw->intr_info.vect_id, vring_hw, platform_isr);
+
+    /* Enable the interrupts */
+    env_enable_interrupt(vring_hw->intr_info.vect_id,
+                    vring_hw->intr_info.priority,
+                    vring_hw->intr_info.trigger_type);
+    return 0;
+}
+
+void _notify(int cpu_id, struct proc_intr *intr_info) {
+
+    unsigned long mask = 0;
+
+    mask = ((1 << (GIC_CPU_ID_BASE + cpu_id)) | (intr_info->vect_id))
+                    & (GIC_SFI_TRIG_CPU_MASK | GIC_SFI_TRIG_INTID_MASK);
+
+    HIL_MEM_WRITE32((GIC_DIST_BASE + GIC_DIST_SOFTINT), mask);
+}
+
+extern char zynq_trampoline;
+extern char zynq_trampoline_jump;
+extern char zynq_trampoline_end;
+
+int _boot_cpu(int cpu_id, unsigned int load_addr) {
+    unsigned int reg;
+    unsigned int tramp_size;
+    unsigned int tramp_addr = 0;
+
+    if (load_addr) {
+        tramp_size = zynq_trampoline_end - zynq_trampoline;
+        if ((load_addr < tramp_size) || (load_addr & 0x3)) {
+            return -1;
+        }
+
+        tramp_size = &zynq_trampoline_jump - &zynq_trampoline;
+
+        /*
+         * Trampoline code is copied to address 0 from where remote core is expected to
+         * fetch first instruction after reset.If master is using the address 0 then
+         * this mem copy will screwed the system. It is user responsibility to not
+         * copy trampoline code in such cases.
+         *
+         */
+        env_memcpy((char *)tramp_addr, &zynq_trampoline, tramp_size);
+        /* Write image address at the word reserved at the trampoline end */
+        HIL_MEM_WRITE32((char *)(tramp_addr + tramp_size), load_addr);
+    }
+
+    unlock_slcr();
+
+    reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL);
+    reg &= ~(A9_CPU_SLCR_CLK_STOP << cpu_id);
+    HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);
+    /* De-assert reset signal and start clock to start the core */
+    reg &= ~(A9_CPU_SLCR_RST << cpu_id);
+    HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);
+
+    lock_slcr();
+
+    return 0;
+}
+
+void _shutdown_cpu(int cpu_id) {
+    unsigned int reg;
+
+    unlock_slcr();
+
+    reg = HIL_MEM_READ32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL);
+    /* Assert reset signal and stop clock to halt the core */
+    reg |= (A9_CPU_SLCR_CLK_STOP | A9_CPU_SLCR_RST) << cpu_id;
+    HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + A9_CPU_SLCR_RESET_CTRL, reg);
+
+    lock_slcr();
+}
+
+void platform_isr(int vect_id, void *data) {
+    hil_isr(((struct proc_vring *) data));
+}
index 8ddb231a03c8d9517c2d2afa5423d18669dffc67..4a3b10da497bda70dc89ee30376164502f7e1e8d 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef PLATFORM_H_\r
-#define PLATFORM_H_\r
-\r
-#include <stdio.h>\r
-#include "../common/hil/hil.h"\r
-\r
-/* ------------------------- Macros --------------------------*/\r
-#define ESAL_DP_SLCR_BASE                  0xF8000000\r
-#define PERIPH_BASE                        0xF8F00000\r
-#define GIC_DIST_BASE                      (PERIPH_BASE + 0x00001000)\r
-#define GIC_DIST_SOFTINT                   0xF00\r
-#define GIC_SFI_TRIG_CPU_MASK              0x00FF0000\r
-#define GIC_SFI_TRIG_SATT_MASK             0x00008000\r
-#define GIC_SFI_TRIG_INTID_MASK            0x0000000F\r
-#define GIC_CPU_ID_BASE                    (1 << 4)\r
-#define A9_CPU_SLCR_RESET_CTRL             0x244\r
-#define A9_CPU_SLCR_CLK_STOP               (1 << 4)\r
-#define A9_CPU_SLCR_RST                    (1 << 0)\r
-\r
-#define unlock_slcr()                       HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x08, 0xDF0DDF0D)\r
-#define lock_slcr()                         HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x04, 0x767B767B)\r
-\r
-\r
-/* L2Cpl310 L2 cache controller base address. */\r
-#define         HIL_PL130_BASE              0xF8F02000\r
-\r
-/********************/\r
-/* Register offsets */\r
-/********************/\r
-\r
-#define         HIL_PL130_INVALLINE         0x770\r
-#define         HIL_PL130_CLEANINVLINE      0x7F0\r
-\r
-\r
-#define         HIL_PA_SBZ_MASK             ~(HIL_CACHE_LINE_SIZE - 1UL)\r
-#define         HIL_CACHE_LINE_SIZE         32\r
-#define         HIL_CACHE_INV_ALL_WAYS      0xFF\r
-#define         HIL_CACHE_UNLOCK_ALL_WAYS   0xFFFF0000\r
-#define         HIL_CACHE_CLEAR_INT         0x1FF\r
-\r
-\r
-/* This macro invalidates all Data cache for the specified address\r
-   range at the processor level. */\r
-#define         HIL_L2CACHE_INVALIDATE(addr, size)                                                           \\r
-                {                                                                                                 \\r
-                                                                                                                  \\r
-                    unsigned int  addr_v     = (unsigned int)addr & HIL_PA_SBZ_MASK;                        \\r
-                    unsigned int  l_size     = 0;                                                                 \\r
-                    unsigned int  align_size = ((unsigned int)size + ((unsigned int)addr &                        \\r
-                                          (HIL_CACHE_LINE_SIZE-1UL)));                                      \\r
-                                                                                                                  \\r
-                    do                                                                                            \\r
-                    {                                                                                             \\r
-                        /* Invalidate cache line by PA. */                                                        \\r
-                        HIL_MEM_WRITE32(HIL_PL130_BASE + HIL_PL130_INVALLINE, addr_v);            \\r
-                                                                                                                  \\r
-                        /* Move to the next way */                                                                \\r
-                        addr_v += HIL_CACHE_LINE_SIZE;                                                      \\r
-                        l_size += HIL_CACHE_LINE_SIZE;                                                      \\r
-                                                                                                                  \\r
-                    } while (l_size < align_size);                                                                \\r
-                }\r
-\r
-\r
-/* This macro flushes all data cache to physical memory (writeback cache)\r
-   for the given address range, then invalidates all data cache entries\r
-   at the processor level. */\r
-#define         HIL_L2CACHE_FLUSH_INVAL(addr, size)                                                          \\r
-                {                                                                                                 \\r
-                    volatile unsigned int  addr_v=(unsigned int)addr & HIL_PA_SBZ_MASK;                     \\r
-                    volatile unsigned int  align_size = ((unsigned int)size + ((unsigned int)addr &               \\r
-                                          (HIL_CACHE_LINE_SIZE-1UL)));                                      \\r
-                    volatile unsigned int  addr_end = addr_v + align_size;                                        \\r
-                                                                                                                  \\r
-                    do                                                                                            \\r
-                    {                                                                                             \\r
-                        /* Invalidate cache line by PA. */                                                        \\r
-                        HIL_MEM_WRITE32(HIL_PL130_BASE + HIL_PL130_CLEANINVLINE, addr_v);         \\r
-                                                                                                                  \\r
-                        asm volatile("    DSB");                                                                \\r
-                                                                                                                  \\r
-                        /* Move to the next line. */                                                              \\r
-                        addr_v += HIL_CACHE_LINE_SIZE;                                                      \\r
-                                                                                                                  \\r
-                    } while (addr_v < addr_end);                                                                  \\r
-                }\r
-\r
-\r
-int _enable_interrupt(struct proc_vring *vring_hw);\r
-void _notify(int cpu_id, struct proc_intr *intr_info);\r
-int _boot_cpu(int cpu_id, unsigned int load_addr);\r
-void _shutdown_cpu(int cpu_id);\r
-void platform_isr(int vect_id, void *data);\r
-\r
-#endif /* PLATFORM_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+#ifndef PLATFORM_H_
+#define PLATFORM_H_
+
+#include <stdio.h>
+#include "../common/hil/hil.h"
+
+/* ------------------------- Macros --------------------------*/
+#define ESAL_DP_SLCR_BASE                  0xF8000000
+#define PERIPH_BASE                        0xF8F00000
+#define GIC_DIST_BASE                      (PERIPH_BASE + 0x00001000)
+#define GIC_DIST_SOFTINT                   0xF00
+#define GIC_SFI_TRIG_CPU_MASK              0x00FF0000
+#define GIC_SFI_TRIG_SATT_MASK             0x00008000
+#define GIC_SFI_TRIG_INTID_MASK            0x0000000F
+#define GIC_CPU_ID_BASE                    (1 << 4)
+#define A9_CPU_SLCR_RESET_CTRL             0x244
+#define A9_CPU_SLCR_CLK_STOP               (1 << 4)
+#define A9_CPU_SLCR_RST                    (1 << 0)
+
+#define unlock_slcr()                       HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x08, 0xDF0DDF0D)
+#define lock_slcr()                         HIL_MEM_WRITE32(ESAL_DP_SLCR_BASE + 0x04, 0x767B767B)
+
+
+/* L2Cpl310 L2 cache controller base address. */
+#define         HIL_PL130_BASE              0xF8F02000
+
+/********************/
+/* Register offsets */
+/********************/
+
+#define         HIL_PL130_INVALLINE         0x770
+#define         HIL_PL130_CLEANINVLINE      0x7F0
+
+
+#define         HIL_PA_SBZ_MASK             ~(HIL_CACHE_LINE_SIZE - 1UL)
+#define         HIL_CACHE_LINE_SIZE         32
+#define         HIL_CACHE_INV_ALL_WAYS      0xFF
+#define         HIL_CACHE_UNLOCK_ALL_WAYS   0xFFFF0000
+#define         HIL_CACHE_CLEAR_INT         0x1FF
+
+
+/* This macro invalidates all Data cache for the specified address
+   range at the processor level. */
+#define         HIL_L2CACHE_INVALIDATE(addr, size)                                                           \
+                {                                                                                                 \
+                                                                                                                  \
+                    unsigned int  addr_v     = (unsigned int)addr & HIL_PA_SBZ_MASK;                        \
+                    unsigned int  l_size     = 0;                                                                 \
+                    unsigned int  align_size = ((unsigned int)size + ((unsigned int)addr &                        \
+                                          (HIL_CACHE_LINE_SIZE-1UL)));                                      \
+                                                                                                                  \
+                    do                                                                                            \
+                    {                                                                                             \
+                        /* Invalidate cache line by PA. */                                                        \
+                        HIL_MEM_WRITE32(HIL_PL130_BASE + HIL_PL130_INVALLINE, addr_v);            \
+                                                                                                                  \
+                        /* Move to the next way */                                                                \
+                        addr_v += HIL_CACHE_LINE_SIZE;                                                      \
+                        l_size += HIL_CACHE_LINE_SIZE;                                                      \
+                                                                                                                  \
+                    } while (l_size < align_size);                                                                \
+                }
+
+
+/* This macro flushes all data cache to physical memory (writeback cache)
+   for the given address range, then invalidates all data cache entries
+   at the processor level. */
+#define         HIL_L2CACHE_FLUSH_INVAL(addr, size)                                                          \
+                {                                                                                                 \
+                    volatile unsigned int  addr_v=(unsigned int)addr & HIL_PA_SBZ_MASK;                     \
+                    volatile unsigned int  align_size = ((unsigned int)size + ((unsigned int)addr &               \
+                                          (HIL_CACHE_LINE_SIZE-1UL)));                                      \
+                    volatile unsigned int  addr_end = addr_v + align_size;                                        \
+                                                                                                                  \
+                    do                                                                                            \
+                    {                                                                                             \
+                        /* Invalidate cache line by PA. */                                                        \
+                        HIL_MEM_WRITE32(HIL_PL130_BASE + HIL_PL130_CLEANINVLINE, addr_v);         \
+                                                                                                                  \
+                        asm volatile("    DSB");                                                                \
+                                                                                                                  \
+                        /* Move to the next line. */                                                              \
+                        addr_v += HIL_CACHE_LINE_SIZE;                                                      \
+                                                                                                                  \
+                    } while (addr_v < addr_end);                                                                  \
+                }
+
+
+int _enable_interrupt(struct proc_vring *vring_hw);
+void _notify(int cpu_id, struct proc_intr *intr_info);
+int _boot_cpu(int cpu_id, unsigned int load_addr);
+void _shutdown_cpu(int cpu_id);
+void platform_isr(int vect_id, void *data);
+
+#endif /* PLATFORM_H_ */
index eba0ba5131fda94ee67dd20b144f9944a047d84c..c37df1d0ed72b74a344d047d431c1038009434a4 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       platform_info.c\r
- *\r
- * DESCRIPTION\r
- *\r
- *       This file implements APIs to get platform specific\r
- *       information for OpenAMP. \r
- *\r
- **************************************************************************/\r
-\r
-#include "platform.h"\r
-\r
-/* Reference implementation that show cases platform_get_cpu_info and \r
- platform_get_for_firmware API implementation for Bare metal environment */\r
-\r
-extern struct hil_platform_ops proc_ops;\r
-\r
-/* IPC Device parameters */\r
-#define SHM_ADDR                          (void *)0x08008000\r
-#define SHM_SIZE                          0x00200000\r
-#define VRING0_IPI_VECT                   15\r
-#define VRING1_IPI_VECT                   14\r
-#define MASTER_CPU_ID                     0\r
-#define REMOTE_CPU_ID                     1\r
-\r
-/**\r
- * This array provdes defnition of CPU nodes for master and remote\r
- * context. It contains two nodes beacuse the same file is intended\r
- * to use with both master and remote configurations. On zynq platform\r
- * only one node defintion is required for master/remote as there\r
- * are only two cores present in the platform.\r
- *\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       platform_info.c
+ *
+ * DESCRIPTION
+ *
+ *       This file implements APIs to get platform specific
+ *       information for OpenAMP. 
+ *
+ **************************************************************************/
+
+#include "platform.h"
+
+/* Reference implementation that show cases platform_get_cpu_info and 
+ platform_get_for_firmware API implementation for Bare metal environment */
+
+extern struct hil_platform_ops proc_ops;
+
+/* IPC Device parameters */
+#define SHM_ADDR                          (void *)0x08008000
+#define SHM_SIZE                          0x00200000
+#define VRING0_IPI_VECT                   15
+#define VRING1_IPI_VECT                   14
+#define MASTER_CPU_ID                     0
+#define REMOTE_CPU_ID                     1
+
+/**
+ * This array provdes defnition of CPU nodes for master and remote
+ * context. It contains two nodes beacuse the same file is intended
+ * to use with both master and remote configurations. On zynq platform
+ * only one node defintion is required for master/remote as there
+ * are only two cores present in the platform.
+ *
  * Only platform specific info is populated here. Rest of information
- * is obtained during resource table parsing.The platform specific\r
- * information includes;\r
- *\r
- * -CPU ID\r
- * -Shared Memory\r
- * -Interrupts\r
- * -Channel info.\r
- *\r
- * Although the channel info is not platform specific information\r
- * but it is conveneient to keep it in HIL so that user can easily\r
- * provide it without modifying the generic part.\r
- *\r
- * It is good idea to define hil_proc structure with platform\r
- * specific fields populated as this can be easily copied to hil_proc\r
- * structure passed as parameter in platform_get_processor_info. The\r
- * other option is to populate the required structures individually\r
- * and copy them one by one to hil_proc structure in platform_get_processor_info\r
- * function. The first option is adopted here.\r
- *\r
- *\r
- * 1) First node in the array is intended for the remote contexts and it\r
- *    defines Master CPU ID, shared memory, interrupts info, number of channels\r
- *    and there names. This node defines only one channel\r
- *   "rpmsg-openamp-demo-channel".\r
- *\r
- * 2)Second node is required by the master and it defines remote CPU ID,\r
- *   shared memory and interrupts info. In general no channel info is required by the\r
- *   Master node, however in baremetal master and linux remote case the linux\r
- *   rpmsg bus driver behaves as master so the rpmsg driver on linux side still needs\r
- *   channel info. This information is not required by the masters for baremetal\r
- *   remotes. \r
- *\r
- */\r
-struct hil_proc proc_table []=\r
-{\r
-\r
-    /* CPU node for remote context */\r
-    {\r
-        /* CPU ID of master */\r
-        MASTER_CPU_ID,\r
-\r
-        /* Shared memory info - Last field is not used currently */\r
-        {\r
-            SHM_ADDR, SHM_SIZE, 0x00\r
-        },\r
-\r
-        /* VirtIO device info */\r
-        {\r
-            /* Leave these three fields empty as these are obtained from rsc\r
-             * table.\r
-             */\r
-             0, 0, 0,\r
-\r
-             /* Vring info */\r
-            {\r
-\r
-                {\r
-                     /* Provide only vring interrupts info here. Other fields are\r
-                      * obtained from the resource table so leave them empty.\r
-                      */\r
-                     NULL, NULL, 0, 0,\r
-                     {\r
-                         VRING0_IPI_VECT,0x1006,1,NULL\r
-                     }\r
-                },\r
-                {\r
-                    NULL, NULL, 0, 0,\r
-                    {\r
-                        VRING1_IPI_VECT,0x1006,1,NULL\r
-                    }\r
-                }\r
-            }\r
-        },\r
-\r
-        /* Number of RPMSG channels */\r
-        1,\r
-\r
-        /* RPMSG channel info - Only channel name is expected currently */\r
-        {\r
-            {"rpmsg-openamp-demo-channel"}\r
-        },\r
-\r
-        /* HIL platform ops table. */\r
-        &proc_ops,\r
-\r
-        /* Next three fields are for future use only */\r
-        0,\r
-        0,\r
-        NULL\r
-    },\r
-\r
-    /* CPU node for remote context */\r
-    {\r
-        /* CPU ID of remote */\r
-        REMOTE_CPU_ID,\r
-\r
-        /* Shared memory info - Last field is not used currently */\r
-        {\r
-            SHM_ADDR, SHM_SIZE, 0x00\r
-        },\r
-\r
-        /* VirtIO device info */\r
-        {\r
-            0, 0, 0,\r
-            {\r
-                {\r
-                    /* Provide vring interrupts info here. Other fields are obtained\r
-                     * from the rsc table so leave them empty.\r
-                     */\r
-                    NULL, NULL, 0, 0,\r
-                    {\r
-                        VRING0_IPI_VECT,0x1006,1\r
-                    }\r
-                },\r
-                {\r
-                    NULL, NULL, 0, 0,\r
-                    {\r
-                        VRING1_IPI_VECT,0x1006,1\r
-                    }\r
-                }\r
-            }\r
-        },\r
-\r
-        /* Number of RPMSG channels */\r
-        1,\r
-\r
-        /* RPMSG channel info - Only channel name is expected currently */\r
-        {\r
-            {"rpmsg-openamp-demo-channel"}\r
-        },\r
-\r
-        /* HIL platform ops table. */\r
-        &proc_ops,\r
-\r
-        /* Next three fields are for future use only */\r
-        0,\r
-        0,\r
-        NULL\r
-    }\r
-};\r
-\r
-/**\r
- * platform_get_processor_info\r
- *\r
- * Copies the target info from the user defined data structures to\r
- * HIL proc  data structure.In case of remote contexts this function\r
- * is called with the reserved CPU ID HIL_RSVD_CPU_ID, because for\r
- * remotes there is only one master.\r
- *\r
- * @param proc   - HIL proc to populate\r
- * @param cpu_id - CPU ID\r
- *\r
- * return  - status of execution\r
- */\r
-int platform_get_processor_info(struct hil_proc *proc , int cpu_id) {\r
-    int idx;\r
-    for(idx = 0; idx < sizeof(proc_table)/sizeof(struct hil_proc); idx++) {\r
-        if((cpu_id == HIL_RSVD_CPU_ID) || (proc_table[idx].cpu_id == cpu_id) ) {\r
-            env_memcpy(proc,&proc_table[idx], sizeof(struct hil_proc));\r
-            return 0;\r
-        }\r
-    }\r
-    return -1;\r
-}\r
-\r
-int platform_get_processor_for_fw(char *fw_name) {\r
-\r
-    return 1;\r
-}\r
+ * is obtained during resource table parsing.The platform specific
+ * information includes;
+ *
+ * -CPU ID
+ * -Shared Memory
+ * -Interrupts
+ * -Channel info.
+ *
+ * Although the channel info is not platform specific information
+ * but it is conveneient to keep it in HIL so that user can easily
+ * provide it without modifying the generic part.
+ *
+ * It is good idea to define hil_proc structure with platform
+ * specific fields populated as this can be easily copied to hil_proc
+ * structure passed as parameter in platform_get_processor_info. The
+ * other option is to populate the required structures individually
+ * and copy them one by one to hil_proc structure in platform_get_processor_info
+ * function. The first option is adopted here.
+ *
+ *
+ * 1) First node in the array is intended for the remote contexts and it
+ *    defines Master CPU ID, shared memory, interrupts info, number of channels
+ *    and there names. This node defines only one channel
+ *   "rpmsg-openamp-demo-channel".
+ *
+ * 2)Second node is required by the master and it defines remote CPU ID,
+ *   shared memory and interrupts info. In general no channel info is required by the
+ *   Master node, however in baremetal master and linux remote case the linux
+ *   rpmsg bus driver behaves as master so the rpmsg driver on linux side still needs
+ *   channel info. This information is not required by the masters for baremetal
+ *   remotes. 
+ *
+ */
+struct hil_proc proc_table []=
+{
+
+    /* CPU node for remote context */
+    {
+        /* CPU ID of master */
+        MASTER_CPU_ID,
+
+        /* Shared memory info - Last field is not used currently */
+        {
+            SHM_ADDR, SHM_SIZE, 0x00
+        },
+
+        /* VirtIO device info */
+        {
+            /* Leave these three fields empty as these are obtained from rsc
+             * table.
+             */
+             0, 0, 0,
+
+             /* Vring info */
+            {
+
+                {
+                     /* Provide only vring interrupts info here. Other fields are
+                      * obtained from the resource table so leave them empty.
+                      */
+                     NULL, NULL, 0, 0,
+                     {
+                         VRING0_IPI_VECT,0x1006,1,NULL
+                     }
+                },
+                {
+                    NULL, NULL, 0, 0,
+                    {
+                        VRING1_IPI_VECT,0x1006,1,NULL
+                    }
+                }
+            }
+        },
+
+        /* Number of RPMSG channels */
+        1,
+
+        /* RPMSG channel info - Only channel name is expected currently */
+        {
+            {"rpmsg-openamp-demo-channel"}
+        },
+
+        /* HIL platform ops table. */
+        &proc_ops,
+
+        /* Next three fields are for future use only */
+        0,
+        0,
+        NULL
+    },
+
+    /* CPU node for remote context */
+    {
+        /* CPU ID of remote */
+        REMOTE_CPU_ID,
+
+        /* Shared memory info - Last field is not used currently */
+        {
+            SHM_ADDR, SHM_SIZE, 0x00
+        },
+
+        /* VirtIO device info */
+        {
+            0, 0, 0,
+            {
+                {
+                    /* Provide vring interrupts info here. Other fields are obtained
+                     * from the rsc table so leave them empty.
+                     */
+                    NULL, NULL, 0, 0,
+                    {
+                        VRING0_IPI_VECT,0x1006,1
+                    }
+                },
+                {
+                    NULL, NULL, 0, 0,
+                    {
+                        VRING1_IPI_VECT,0x1006,1
+                    }
+                }
+            }
+        },
+
+        /* Number of RPMSG channels */
+        1,
+
+        /* RPMSG channel info - Only channel name is expected currently */
+        {
+            {"rpmsg-openamp-demo-channel"}
+        },
+
+        /* HIL platform ops table. */
+        &proc_ops,
+
+        /* Next three fields are for future use only */
+        0,
+        0,
+        NULL
+    }
+};
+
+/**
+ * platform_get_processor_info
+ *
+ * Copies the target info from the user defined data structures to
+ * HIL proc  data structure.In case of remote contexts this function
+ * is called with the reserved CPU ID HIL_RSVD_CPU_ID, because for
+ * remotes there is only one master.
+ *
+ * @param proc   - HIL proc to populate
+ * @param cpu_id - CPU ID
+ *
+ * return  - status of execution
+ */
+int platform_get_processor_info(struct hil_proc *proc , int cpu_id) {
+    int idx;
+    for(idx = 0; idx < sizeof(proc_table)/sizeof(struct hil_proc); idx++) {
+        if((cpu_id == HIL_RSVD_CPU_ID) || (proc_table[idx].cpu_id == cpu_id) ) {
+            env_memcpy(proc,&proc_table[idx], sizeof(struct hil_proc));
+            return 0;
+        }
+    }
+    return -1;
+}
+
+int platform_get_processor_for_fw(char *fw_name) {
+
+    return 1;
+}
index a916d6be54770056c762e554c7a66455b9bceb4a..e11fa319fc5572568c50b2ca90ae75dddb8df862 100644 (file)
@@ -1,39 +1,39 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-.global zynq_trampoline\r
-zynq_trampoline:\r
-       ldr r0, [pc]\r
-       bx r0\r
-.global zynq_trampoline_jump\r
-zynq_trampoline_jump:\r
-       .word\r
-.global zynq_trampoline_end\r
-zynq_trampoline_end:\r
-       \r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+.global zynq_trampoline
+zynq_trampoline:
+       ldr r0, [pc]
+       bx r0
+.global zynq_trampoline_jump
+zynq_trampoline_jump:
+       .word
+.global zynq_trampoline_end
+zynq_trampoline_end:
+       
index a551d2317a8f910b12cb0bc07438bbd1146f2ece..7d4a21d23f43a8075a01c5f3411fc3437697041a 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include "elf_loader.h"\r
-\r
-/* Local functions. */\r
-\r
-static int elf_loader_get_needed_sections(struct elf_decode_info *elf_info);\r
-static int elf_loader_relocs_specific(struct elf_decode_info *elf_info,\r
-                Elf32_Shdr *section);\r
-static void *elf_loader_get_entry_point_address(\r
-                struct elf_decode_info *elf_info);\r
-static int elf_loader_relocate_link(struct elf_decode_info *elf_info);\r
-static int elf_loader_seek_and_read(void *firmware, void *destination,\r
-                Elf32_Off offset, Elf32_Word size);\r
-static int elf_loader_read_headers(void *firmware,\r
-                struct elf_decode_info *elf_info);\r
-static int elf_loader_load_sections(void *firmware,\r
-                struct elf_decode_info *elf_info);\r
-static int elf_loader_get_decode_info(void *firmware,\r
-                struct elf_decode_info *elf_info);\r
-static int elf_loader_reloc_entry(struct elf_decode_info *elf_info,\r
-                Elf32_Rel *rel_entry);\r
-static Elf32_Addr elf_loader_get_dynamic_symbol_addr(\r
-                struct elf_decode_info *elf_info, int index);\r
-\r
-/**\r
- * elf_loader_init\r
- *\r
- * Initializes ELF loader.\r
- *\r
- * @param loader    - pointer to remoteproc loader\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-int elf_loader_init(struct remoteproc_loader *loader) {\r
-\r
-    /* Initialize loader function table */\r
-    loader->load_firmware = elf_loader_load_remote_firmware;\r
-    loader->retrieve_entry = elf_loader_retrieve_entry_point;\r
-    loader->retrieve_rsc = elf_loader_retrieve_resource_section;\r
-    loader->attach_firmware = elf_loader_attach_firmware;\r
-    loader->detach_firmware = elf_loader_detach_firmware;\r
-    loader->retrieve_load_addr = elf_get_load_address;\r
-\r
-    return RPROC_SUCCESS;\r
-}\r
-\r
-/**\r
- * elf_loader_attach_firmware\r
- *\r
- * Attaches an ELF firmware to the loader\r
- *\r
- * @param loader    - pointer to remoteproc loader\r
- * @param firmware -  pointer to the firmware start location\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-int elf_loader_attach_firmware(struct remoteproc_loader *loader, void *firmware) {\r
-\r
-    struct elf_decode_info *elf_info;\r
-    int status;\r
-\r
-    /* Allocate memory for decode info structure. */\r
-    elf_info = env_allocate_memory(sizeof(struct elf_decode_info));\r
-\r
-    if (!elf_info) {\r
-        return RPROC_ERR_NO_MEM;\r
-    }\r
-\r
-    /* Clear the ELF decode struct. */\r
-    env_memset(elf_info, 0, sizeof(struct elf_decode_info));\r
-\r
-    /* Get the essential information to decode the ELF. */\r
-    status = elf_loader_get_decode_info(firmware, elf_info);\r
-\r
-    if (status) {\r
-        /* Free memory. */\r
-        env_free_memory(elf_info);\r
-        return status;\r
-    }\r
-\r
-    elf_info->firmware = firmware;\r
-    loader->fw_decode_info = elf_info;\r
-\r
-    return status;\r
-}\r
-\r
-/**\r
- * elf_loader_detach_firmware\r
- *\r
- * Detaches ELF firmware from the loader\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-int elf_loader_detach_firmware(struct remoteproc_loader *loader) {\r
-\r
-    struct elf_decode_info *elf_info =\r
-                    (struct elf_decode_info *) loader->fw_decode_info;\r
-    if (elf_info) {\r
-        /* Free memory. */\r
-        env_free_memory(elf_info->shstrtab);\r
-        env_free_memory(elf_info->section_headers_start);\r
-        env_free_memory(elf_info);\r
-    }\r
-\r
-    return RPROC_SUCCESS;\r
-}\r
-\r
-/**\r
- * elf_loader_retrieve_entry_point\r
- *\r
- * Retrieves the ELF entrypoint.\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- *\r
- * @return  - entrypoint\r
- */\r
-void *elf_loader_retrieve_entry_point(struct remoteproc_loader *loader) {\r
-\r
-    return elf_loader_get_entry_point_address(\r
-                    (struct elf_decode_info *)loader->fw_decode_info);\r
-}\r
-\r
-/**\r
- * elf_loader_retrieve_resource_section\r
- *\r
- * Retrieves the resource section.\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- * @param size   - pointer to contain the size of the section\r
- *\r
- * @return  - pointer to resource section\r
- */\r
-void *elf_loader_retrieve_resource_section(struct remoteproc_loader *loader,\r
-                unsigned int *size) {\r
-\r
-    Elf32_Shdr *rsc_header;\r
-    void* resource_section = NULL;\r
-    struct elf_decode_info *elf_info =\r
-                    (struct elf_decode_info *) loader->fw_decode_info;\r
-\r
-    if (elf_info->rsc) {\r
-        /* Retrieve resource section header. */\r
-        rsc_header = elf_info->rsc;\r
-        /* Retrieve resource section size. */\r
-        *size = rsc_header->sh_size;\r
-\r
-        /* Locate the start of resource section. */\r
-        resource_section = (void *) ((unsigned int) elf_info->firmware\r
-                        + rsc_header->sh_offset);\r
-    }\r
-\r
-    /* Return the address of resource section. */\r
-    return resource_section;\r
-}\r
-\r
-/**\r
- * elf_loader_load_remote_firmware\r
- *\r
- * Loads the ELF firmware.\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-int elf_loader_load_remote_firmware(struct remoteproc_loader *loader) {\r
-\r
-    struct elf_decode_info *elf_info =\r
-                    (struct elf_decode_info *) loader->fw_decode_info;\r
-    int status;\r
-\r
-    /* Load ELF sections. */\r
-    status = elf_loader_load_sections(elf_info->firmware, elf_info);\r
-\r
-    if (!status) {\r
-\r
-        /* Perform dynamic relocations if needed. */\r
-        status = elf_loader_relocate_link(elf_info);\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/**\r
- * elf_get_load_address\r
- *\r
- * Provides firmware load address.\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- *\r
- * @return  - load address pointer\r
- */\r
-void *elf_get_load_address(struct remoteproc_loader *loader) {\r
-\r
-    struct elf_decode_info *elf_info =\r
-                    (struct elf_decode_info *) loader->fw_decode_info;\r
-    int status = 0;\r
-    Elf32_Shdr *current = (Elf32_Shdr *) (elf_info->section_headers_start);\r
-\r
-    /* Traverse all sections except the reserved null section. */\r
-    int section_count = elf_info->elf_header.e_shnum - 1;\r
-    while ((section_count > 0) && (status == 0)) {\r
-        /* Compute the pointer to section header. */\r
-        current = (Elf32_Shdr *) (((unsigned char *) current)\r
-                        + elf_info->elf_header.e_shentsize);\r
-        /* Get the name of current section. */\r
-        char *current_name = elf_info->shstrtab + current->sh_name;\r
-        if(!env_strcmp(current_name , ".text")){\r
-            return ((void *) (current->sh_addr));\r
-        }\r
-        /* Move to the next section. */\r
-        section_count--;\r
-    }\r
-\r
-    return (RPROC_ERR_PTR);\r
-}\r
-/**\r
- * elf_loader_get_needed_sections\r
- *\r
- * Retrieves the sections we need during the load and link from the\r
- * section headers list.\r
- *\r
- * @param elf_info  - ELF object decode info container.\r
- *\r
- * @return- Pointer to the ELF section header.\r
- */\r
-\r
-static int elf_loader_get_needed_sections(struct elf_decode_info *elf_info) {\r
-    Elf32_Shdr *current = (Elf32_Shdr *) (elf_info->section_headers_start);\r
-\r
-    /* We are interested in the following sections:\r
-     .dynsym\r
-     .dynstr\r
-     .rel.plt\r
-     .rel.dyn\r
-     */\r
-    int sections_to_find = 5;\r
-\r
-    /* Search for sections but skip the reserved null section. */\r
-\r
-    int section_count = elf_info->elf_header.e_shnum - 1;\r
-    while ((section_count > 0) && (sections_to_find > 0)) {\r
-        /* Compute the section header pointer. */\r
-        current = (Elf32_Shdr *) (((unsigned char *) current)\r
-                        + elf_info->elf_header.e_shentsize);\r
-\r
-        /* Get the name of current section. */\r
-        char *current_name = elf_info->shstrtab + current->sh_name;\r
-\r
-        /* Proceed if the section is allocatable and is not executable. */\r
-        if ((current->sh_flags & SHF_ALLOC)\r
-                        && !(current->sh_flags & SHF_EXECINSTR)) {\r
-            /* Check for '.dynsym' or '.dynstr' or '.rel.plt' or '.rel.dyn'. */\r
-            if (*current_name == '.') {\r
-                current_name++;\r
-\r
-                /* Check for '.dynsym' or 'dynstr'. */\r
-                if (*current_name == 'd') {\r
-                    current_name++;\r
-\r
-                    /* Check for '.dynsym'. */\r
-                    if (env_strncmp(current_name, "ynsym", 5) == 0) {\r
-                        elf_info->dynsym = current;\r
-                        sections_to_find--;\r
-                    }\r
-\r
-                    /* Check for '.dynstr'. */\r
-                    else if (env_strncmp(current_name, "ynstr", 5) == 0) {\r
-                        elf_info->dynstr = current;\r
-                        sections_to_find--;\r
-                    }\r
-                }\r
-\r
-                /* Check for '.rel.plt' or '.rel.dyn'. */\r
-                else if (*current_name == 'r') {\r
-                    current_name++;\r
-\r
-                    /* Check for '.rel.plt'. */\r
-                    if (env_strncmp(current_name, "el.plt", 6) == 0) {\r
-                        elf_info->rel_plt = current;\r
-                        sections_to_find--;\r
-                    }\r
-\r
-                    /* Check for '.rel.dyn'. */\r
-                    else if (env_strncmp(current_name, "el.dyn", 6) == 0) {\r
-                        elf_info->rel_dyn = current;\r
-                        sections_to_find--;\r
-                    }\r
-\r
-                    /* Check for '.resource_table'. */\r
-                    else if (env_strncmp(current_name, "esource_table", 13)\r
-                                    == 0) {\r
-                        elf_info->rsc = current;\r
-                        sections_to_find--;\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        /* Move to the next section. */\r
-        section_count--;\r
-    }\r
-\r
-    /* Return remaining sections section. */\r
-    return (sections_to_find);\r
-}\r
-\r
-/**\r
- * elf_loader_relocs_specific\r
- *\r
- * Processes the relocations contained in the specified section.\r
- *\r
- * @param elf_info - elf decoding information.\r
- * @param section  - header of the specified relocation section.\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-static int elf_loader_relocs_specific(struct elf_decode_info *elf_info,\r
-                Elf32_Shdr *section) {\r
-\r
-    unsigned char *section_load_addr = (unsigned char*) section->sh_addr;\r
-    int status = 0;\r
-    int i;\r
-\r
-    /* Check the section type. */\r
-    if (section->sh_type == SHT_REL) {\r
-        /* Traverse the list of relocation entries contained in the section. */\r
-        for (i = 0; (i < section->sh_size) && (status == 0);\r
-                        i += section->sh_entsize) {\r
-            /* Compute the relocation entry address. */\r
-            Elf32_Rel *rel_entry = (Elf32_Rel *) (section_load_addr + i);\r
-\r
-            /* Process the relocation entry. */\r
-            status = elf_loader_reloc_entry(elf_info, rel_entry);\r
-        }\r
-    }\r
-\r
-    /* Return status to caller. */\r
-    return (status);\r
-}\r
-\r
-/**\r
- * elf_loader_get_entry_point_address\r
- *\r
- * Retrieves the entry point address from the specified ELF object.\r
- *\r
- * @param elf_info       - elf object decode info container.\r
- * @param runtime_buffer - buffer containing ELF sections which are\r
- *                         part of runtime.\r
- *\r
- * @return - entry point address of the specified ELF object.\r
- */\r
-static void *elf_loader_get_entry_point_address(\r
-                struct elf_decode_info *elf_info) {\r
-    return ((void *) elf_info->elf_header.e_entry);\r
-}\r
-\r
-/**\r
- * elf_loader_relocate_link\r
- *\r
- * Relocates and links the given ELF object.\r
- *\r
- * @param elf_info       - elf object decode info container.\r
-\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-\r
-static int elf_loader_relocate_link(struct elf_decode_info *elf_info) {\r
-    int status = 0;\r
-\r
-    /* Check of .rel.dyn section exists in the ELF. */\r
-    if (elf_info->rel_dyn) {\r
-        /* Relocate and link .rel.dyn section. */\r
-        status = elf_loader_relocs_specific(elf_info, elf_info->rel_dyn);\r
-    }\r
-\r
-    /* Proceed to check if .rel.plt section exists, if no error encountered yet. */\r
-    if (status == 0 && elf_info->rel_plt) {\r
-        /* Relocate and link .rel.plt section. */\r
-        status = elf_loader_relocs_specific(elf_info, elf_info->rel_plt);\r
-    }\r
-\r
-    /* Return status to caller */\r
-    return (status);\r
-}\r
-\r
-/**\r
- * elf_loader_seek_and_read\r
- *\r
- * Seeks to the specified offset in the given file and reads the data\r
- * into the specified destination location.\r
- *\r
- * @param firmware     - firmware to read from.\r
- * @param destination - Location into which the data should be read.\r
- * @param offset      - Offset to seek in the file.\r
- * @param size        - Size of the data to read.\r
-\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-\r
-static int elf_loader_seek_and_read(void *firmware, void *destination,\r
-                Elf32_Off offset, Elf32_Word size) {\r
-    char *src = (char *) firmware;\r
-\r
-    /* Seek to the specified offset. */\r
-    src = src + offset;\r
-\r
-    /* Read the data. */\r
-    env_memcpy((char *) destination, src, size);\r
-\r
-    /* Return status to caller. */\r
-    return (0);\r
-}\r
-\r
-/**\r
- * elf_loader_read_headers\r
- *\r
- * Reads the ELF headers (ELF header, section headers and the section\r
- * headers string table) essential to access further information from\r
- * the file containing the ELF object.\r
- *\r
- * @param firmware    - firmware to read from.\r
- * @param elf_info - ELF object decode info container.\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-static int elf_loader_read_headers(void *firmware,\r
-                struct elf_decode_info *elf_info) {\r
-    int status = 0;\r
-    unsigned int section_count;\r
-\r
-    /* Read the ELF header. */\r
-    status = elf_loader_seek_and_read(firmware, &(elf_info->elf_header), 0,\r
-                    sizeof(Elf32_Ehdr));\r
-\r
-    /* Ensure the read was successful. */\r
-    if (!status) {\r
-        /* Get section count from the ELF header. */\r
-        section_count = elf_info->elf_header.e_shnum;\r
-\r
-        /* Allocate memory to read in the section headers. */\r
-        elf_info->section_headers_start = env_allocate_memory(\r
-                        section_count * elf_info->elf_header.e_shentsize);\r
-\r
-        /* Check if the allocation was successful. */\r
-        if (elf_info->section_headers_start) {\r
-            /* Read the section headers list. */\r
-            status = elf_loader_seek_and_read(firmware,\r
-                            elf_info->section_headers_start,\r
-                            elf_info->elf_header.e_shoff,\r
-                            section_count * elf_info->elf_header.e_shentsize);\r
-\r
-            /* Ensure the read was successful. */\r
-            if (!status) {\r
-                /* Compute the pointer to section header string table section. */\r
-                Elf32_Shdr *section_header_string_table =\r
-                                (Elf32_Shdr *) (elf_info->section_headers_start\r
-                                                + elf_info->elf_header.e_shstrndx\r
-                                                                * elf_info->elf_header.e_shentsize);\r
-\r
-                /* Allocate the memory for section header string table. */\r
-                elf_info->shstrtab = env_allocate_memory(\r
-                                section_header_string_table->sh_size);\r
-\r
-                /* Ensure the allocation was successful. */\r
-                if (elf_info->shstrtab) {\r
-                    /* Read the section headers string table. */\r
-                    status = elf_loader_seek_and_read(firmware,\r
-                                    elf_info->shstrtab,\r
-                                    section_header_string_table->sh_offset,\r
-                                    section_header_string_table->sh_size);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    /* Return status to caller. */\r
-    return (status);\r
-}\r
-\r
-/**\r
- * elf_loader_file_read_sections\r
- *\r
- * Reads the ELF section contents from the specified file containing\r
- * the ELF object.\r
- *\r
- * @param firmware - firmware to read from.\r
- * @param elf_info - ELF object decode info container.\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-static int elf_loader_load_sections(void *firmware,\r
-                struct elf_decode_info *elf_info) {\r
-    int status = 0;\r
-    Elf32_Shdr *current = (Elf32_Shdr *) (elf_info->section_headers_start);\r
-\r
-    /* Traverse all sections except the reserved null section. */\r
-    int section_count = elf_info->elf_header.e_shnum - 1;\r
-    while ((section_count > 0) && (status == 0)) {\r
-        /* Compute the pointer to section header. */\r
-        current = (Elf32_Shdr *) (((unsigned char *) current)\r
-                        + elf_info->elf_header.e_shentsize);\r
-\r
-        /* Make sure the section can be allocated and is not empty. */\r
-        if ((current->sh_flags & SHF_ALLOC) && (current->sh_size)) {\r
-            char *destination = NULL;\r
-\r
-            /* Check if the section is part of runtime and is not section with\r
-             * no-load attributes such as BSS or heap. */\r
-            if ((current->sh_type & SHT_NOBITS) == 0) {\r
-                /* Compute the destination address where the section should\r
-                 * be copied. */\r
-                destination = (char *) (current->sh_addr);\r
-                status = elf_loader_seek_and_read(firmware, destination,\r
-                                current->sh_offset, current->sh_size);\r
-            }\r
-        }\r
-\r
-        /* Move to the next section. */\r
-        section_count--;\r
-    }\r
-\r
-    /* Return status to caller. */\r
-    return (status);\r
-}\r
-\r
-/**\r
- * elf_loader_get_decode_info\r
- *\r
- * Retrieves the information necessary to decode the ELF object for\r
- * loading, relocating and linking.\r
- *\r
- * @param firmware - firmware to read from.\r
- * @param elf_info - ELF object decode info container.\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-static int elf_loader_get_decode_info(void *firmware,\r
-                struct elf_decode_info *elf_info) {\r
-    int status;\r
-\r
-    /* Read the ELF headers (ELF header and section headers including\r
-     * the section header string table). */\r
-    status = elf_loader_read_headers(firmware, elf_info);\r
-\r
-    /* Ensure that ELF headers were read successfully. */\r
-    if (!status) {\r
-        /* Retrieve the sections required for load. */\r
-        elf_loader_get_needed_sections(elf_info);\r
-\r
-    }\r
-\r
-    /* Return status to caller. */\r
-    return (status);\r
-}\r
-\r
-/**\r
- * elf_loader_get_dynamic_symbol_addr\r
- *\r
- * Retrieves the (relocatable) address of the symbol specified as\r
- * index from the given ELF object.\r
- *\r
- * @param elf_info - ELF object decode info container.\r
- * @param index    - Index of the desired symbol in the dynamic symbol table.\r
- *\r
- * @return - Address of the specified symbol.\r
- */\r
-static Elf32_Addr elf_loader_get_dynamic_symbol_addr(\r
-                struct elf_decode_info *elf_info, int index) {\r
-    Elf32_Sym *symbol_entry = (Elf32_Sym *) (elf_info->dynsym_addr\r
-                    + index * elf_info->dynsym->sh_entsize);\r
-\r
-    /* Return the symbol address. */\r
-    return (symbol_entry->st_value);\r
-}\r
-\r
-/**\r
- * elf_loader_reloc_entry\r
- *\r
- * Processes the specified relocation entry. It handles the relocation\r
- * and linking both cases.\r
- *\r
- *\r
- * @param elf_info - ELF object decode info container.\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-static int elf_loader_reloc_entry(struct elf_decode_info *elf_info,\r
-                Elf32_Rel *rel_entry) {\r
-    unsigned char rel_type = ELF32_R_TYPE(rel_entry->r_info);\r
-    int status = 0;\r
-\r
-    switch (rel_type) {\r
-    case R_ARM_ABS32: /* 0x02 */\r
-    {\r
-        Elf32_Addr sym_addr = elf_loader_get_dynamic_symbol_addr(elf_info,\r
-                        ELF32_R_SYM(rel_entry->r_info));\r
-\r
-        if (sym_addr) {\r
-            *((unsigned int *) (rel_entry->r_offset)) = (unsigned int) sym_addr;\r
-            break;\r
-        }\r
-    }\r
-\r
-        break;\r
-\r
-    default:\r
-        break;\r
-    }\r
-\r
-    return status;\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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 "elf_loader.h"
+
+/* Local functions. */
+
+static int elf_loader_get_needed_sections(struct elf_decode_info *elf_info);
+static int elf_loader_relocs_specific(struct elf_decode_info *elf_info,
+                Elf32_Shdr *section);
+static void *elf_loader_get_entry_point_address(
+                struct elf_decode_info *elf_info);
+static int elf_loader_relocate_link(struct elf_decode_info *elf_info);
+static int elf_loader_seek_and_read(void *firmware, void *destination,
+                Elf32_Off offset, Elf32_Word size);
+static int elf_loader_read_headers(void *firmware,
+                struct elf_decode_info *elf_info);
+static int elf_loader_load_sections(void *firmware,
+                struct elf_decode_info *elf_info);
+static int elf_loader_get_decode_info(void *firmware,
+                struct elf_decode_info *elf_info);
+static int elf_loader_reloc_entry(struct elf_decode_info *elf_info,
+                Elf32_Rel *rel_entry);
+static Elf32_Addr elf_loader_get_dynamic_symbol_addr(
+                struct elf_decode_info *elf_info, int index);
+
+/**
+ * elf_loader_init
+ *
+ * Initializes ELF loader.
+ *
+ * @param loader    - pointer to remoteproc loader
+ *
+ * @return  - 0 if success, error otherwise
+ */
+int elf_loader_init(struct remoteproc_loader *loader) {
+
+    /* Initialize loader function table */
+    loader->load_firmware = elf_loader_load_remote_firmware;
+    loader->retrieve_entry = elf_loader_retrieve_entry_point;
+    loader->retrieve_rsc = elf_loader_retrieve_resource_section;
+    loader->attach_firmware = elf_loader_attach_firmware;
+    loader->detach_firmware = elf_loader_detach_firmware;
+    loader->retrieve_load_addr = elf_get_load_address;
+
+    return RPROC_SUCCESS;
+}
+
+/**
+ * elf_loader_attach_firmware
+ *
+ * Attaches an ELF firmware to the loader
+ *
+ * @param loader    - pointer to remoteproc loader
+ * @param firmware -  pointer to the firmware start location
+ *
+ * @return  - 0 if success, error otherwise
+ */
+int elf_loader_attach_firmware(struct remoteproc_loader *loader, void *firmware) {
+
+    struct elf_decode_info *elf_info;
+    int status;
+
+    /* Allocate memory for decode info structure. */
+    elf_info = env_allocate_memory(sizeof(struct elf_decode_info));
+
+    if (!elf_info) {
+        return RPROC_ERR_NO_MEM;
+    }
+
+    /* Clear the ELF decode struct. */
+    env_memset(elf_info, 0, sizeof(struct elf_decode_info));
+
+    /* Get the essential information to decode the ELF. */
+    status = elf_loader_get_decode_info(firmware, elf_info);
+
+    if (status) {
+        /* Free memory. */
+        env_free_memory(elf_info);
+        return status;
+    }
+
+    elf_info->firmware = firmware;
+    loader->fw_decode_info = elf_info;
+
+    return status;
+}
+
+/**
+ * elf_loader_detach_firmware
+ *
+ * Detaches ELF firmware from the loader
+ *
+ * @param loader - pointer to remoteproc loader
+ *
+ * @return  - 0 if success, error otherwise
+ */
+int elf_loader_detach_firmware(struct remoteproc_loader *loader) {
+
+    struct elf_decode_info *elf_info =
+                    (struct elf_decode_info *) loader->fw_decode_info;
+    if (elf_info) {
+        /* Free memory. */
+        env_free_memory(elf_info->shstrtab);
+        env_free_memory(elf_info->section_headers_start);
+        env_free_memory(elf_info);
+    }
+
+    return RPROC_SUCCESS;
+}
+
+/**
+ * elf_loader_retrieve_entry_point
+ *
+ * Retrieves the ELF entrypoint.
+ *
+ * @param loader - pointer to remoteproc loader
+ *
+ * @return  - entrypoint
+ */
+void *elf_loader_retrieve_entry_point(struct remoteproc_loader *loader) {
+
+    return elf_loader_get_entry_point_address(
+                    (struct elf_decode_info *)loader->fw_decode_info);
+}
+
+/**
+ * elf_loader_retrieve_resource_section
+ *
+ * Retrieves the resource section.
+ *
+ * @param loader - pointer to remoteproc loader
+ * @param size   - pointer to contain the size of the section
+ *
+ * @return  - pointer to resource section
+ */
+void *elf_loader_retrieve_resource_section(struct remoteproc_loader *loader,
+                unsigned int *size) {
+
+    Elf32_Shdr *rsc_header;
+    void* resource_section = NULL;
+    struct elf_decode_info *elf_info =
+                    (struct elf_decode_info *) loader->fw_decode_info;
+
+    if (elf_info->rsc) {
+        /* Retrieve resource section header. */
+        rsc_header = elf_info->rsc;
+        /* Retrieve resource section size. */
+        *size = rsc_header->sh_size;
+
+        /* Locate the start of resource section. */
+        resource_section = (void *) ((unsigned int) elf_info->firmware
+                        + rsc_header->sh_offset);
+    }
+
+    /* Return the address of resource section. */
+    return resource_section;
+}
+
+/**
+ * elf_loader_load_remote_firmware
+ *
+ * Loads the ELF firmware.
+ *
+ * @param loader - pointer to remoteproc loader
+ *
+ * @return  - 0 if success, error otherwise
+ */
+int elf_loader_load_remote_firmware(struct remoteproc_loader *loader) {
+
+    struct elf_decode_info *elf_info =
+                    (struct elf_decode_info *) loader->fw_decode_info;
+    int status;
+
+    /* Load ELF sections. */
+    status = elf_loader_load_sections(elf_info->firmware, elf_info);
+
+    if (!status) {
+
+        /* Perform dynamic relocations if needed. */
+        status = elf_loader_relocate_link(elf_info);
+    }
+
+    return status;
+}
+
+/**
+ * elf_get_load_address
+ *
+ * Provides firmware load address.
+ *
+ * @param loader - pointer to remoteproc loader
+ *
+ * @return  - load address pointer
+ */
+void *elf_get_load_address(struct remoteproc_loader *loader) {
+
+    struct elf_decode_info *elf_info =
+                    (struct elf_decode_info *) loader->fw_decode_info;
+    int status = 0;
+    Elf32_Shdr *current = (Elf32_Shdr *) (elf_info->section_headers_start);
+
+    /* Traverse all sections except the reserved null section. */
+    int section_count = elf_info->elf_header.e_shnum - 1;
+    while ((section_count > 0) && (status == 0)) {
+        /* Compute the pointer to section header. */
+        current = (Elf32_Shdr *) (((unsigned char *) current)
+                        + elf_info->elf_header.e_shentsize);
+        /* Get the name of current section. */
+        char *current_name = elf_info->shstrtab + current->sh_name;
+        if(!env_strcmp(current_name , ".text")){
+            return ((void *) (current->sh_addr));
+        }
+        /* Move to the next section. */
+        section_count--;
+    }
+
+    return (RPROC_ERR_PTR);
+}
+/**
+ * elf_loader_get_needed_sections
+ *
+ * Retrieves the sections we need during the load and link from the
+ * section headers list.
+ *
+ * @param elf_info  - ELF object decode info container.
+ *
+ * @return- Pointer to the ELF section header.
+ */
+
+static int elf_loader_get_needed_sections(struct elf_decode_info *elf_info) {
+    Elf32_Shdr *current = (Elf32_Shdr *) (elf_info->section_headers_start);
+
+    /* We are interested in the following sections:
+     .dynsym
+     .dynstr
+     .rel.plt
+     .rel.dyn
+     */
+    int sections_to_find = 5;
+
+    /* Search for sections but skip the reserved null section. */
+
+    int section_count = elf_info->elf_header.e_shnum - 1;
+    while ((section_count > 0) && (sections_to_find > 0)) {
+        /* Compute the section header pointer. */
+        current = (Elf32_Shdr *) (((unsigned char *) current)
+                        + elf_info->elf_header.e_shentsize);
+
+        /* Get the name of current section. */
+        char *current_name = elf_info->shstrtab + current->sh_name;
+
+        /* Proceed if the section is allocatable and is not executable. */
+        if ((current->sh_flags & SHF_ALLOC)
+                        && !(current->sh_flags & SHF_EXECINSTR)) {
+            /* Check for '.dynsym' or '.dynstr' or '.rel.plt' or '.rel.dyn'. */
+            if (*current_name == '.') {
+                current_name++;
+
+                /* Check for '.dynsym' or 'dynstr'. */
+                if (*current_name == 'd') {
+                    current_name++;
+
+                    /* Check for '.dynsym'. */
+                    if (env_strncmp(current_name, "ynsym", 5) == 0) {
+                        elf_info->dynsym = current;
+                        sections_to_find--;
+                    }
+
+                    /* Check for '.dynstr'. */
+                    else if (env_strncmp(current_name, "ynstr", 5) == 0) {
+                        elf_info->dynstr = current;
+                        sections_to_find--;
+                    }
+                }
+
+                /* Check for '.rel.plt' or '.rel.dyn'. */
+                else if (*current_name == 'r') {
+                    current_name++;
+
+                    /* Check for '.rel.plt'. */
+                    if (env_strncmp(current_name, "el.plt", 6) == 0) {
+                        elf_info->rel_plt = current;
+                        sections_to_find--;
+                    }
+
+                    /* Check for '.rel.dyn'. */
+                    else if (env_strncmp(current_name, "el.dyn", 6) == 0) {
+                        elf_info->rel_dyn = current;
+                        sections_to_find--;
+                    }
+
+                    /* Check for '.resource_table'. */
+                    else if (env_strncmp(current_name, "esource_table", 13)
+                                    == 0) {
+                        elf_info->rsc = current;
+                        sections_to_find--;
+                    }
+                }
+            }
+        }
+
+        /* Move to the next section. */
+        section_count--;
+    }
+
+    /* Return remaining sections section. */
+    return (sections_to_find);
+}
+
+/**
+ * elf_loader_relocs_specific
+ *
+ * Processes the relocations contained in the specified section.
+ *
+ * @param elf_info - elf decoding information.
+ * @param section  - header of the specified relocation section.
+ *
+ * @return  - 0 if success, error otherwise
+ */
+static int elf_loader_relocs_specific(struct elf_decode_info *elf_info,
+                Elf32_Shdr *section) {
+
+    unsigned char *section_load_addr = (unsigned char*) section->sh_addr;
+    int status = 0;
+    int i;
+
+    /* Check the section type. */
+    if (section->sh_type == SHT_REL) {
+        /* Traverse the list of relocation entries contained in the section. */
+        for (i = 0; (i < section->sh_size) && (status == 0);
+                        i += section->sh_entsize) {
+            /* Compute the relocation entry address. */
+            Elf32_Rel *rel_entry = (Elf32_Rel *) (section_load_addr + i);
+
+            /* Process the relocation entry. */
+            status = elf_loader_reloc_entry(elf_info, rel_entry);
+        }
+    }
+
+    /* Return status to caller. */
+    return (status);
+}
+
+/**
+ * elf_loader_get_entry_point_address
+ *
+ * Retrieves the entry point address from the specified ELF object.
+ *
+ * @param elf_info       - elf object decode info container.
+ * @param runtime_buffer - buffer containing ELF sections which are
+ *                         part of runtime.
+ *
+ * @return - entry point address of the specified ELF object.
+ */
+static void *elf_loader_get_entry_point_address(
+                struct elf_decode_info *elf_info) {
+    return ((void *) elf_info->elf_header.e_entry);
+}
+
+/**
+ * elf_loader_relocate_link
+ *
+ * Relocates and links the given ELF object.
+ *
+ * @param elf_info       - elf object decode info container.
+
+ *
+ * @return  - 0 if success, error otherwise
+ */
+
+static int elf_loader_relocate_link(struct elf_decode_info *elf_info) {
+    int status = 0;
+
+    /* Check of .rel.dyn section exists in the ELF. */
+    if (elf_info->rel_dyn) {
+        /* Relocate and link .rel.dyn section. */
+        status = elf_loader_relocs_specific(elf_info, elf_info->rel_dyn);
+    }
+
+    /* Proceed to check if .rel.plt section exists, if no error encountered yet. */
+    if (status == 0 && elf_info->rel_plt) {
+        /* Relocate and link .rel.plt section. */
+        status = elf_loader_relocs_specific(elf_info, elf_info->rel_plt);
+    }
+
+    /* Return status to caller */
+    return (status);
+}
+
+/**
+ * elf_loader_seek_and_read
+ *
+ * Seeks to the specified offset in the given file and reads the data
+ * into the specified destination location.
+ *
+ * @param firmware     - firmware to read from.
+ * @param destination - Location into which the data should be read.
+ * @param offset      - Offset to seek in the file.
+ * @param size        - Size of the data to read.
+
+ *
+ * @return  - 0 if success, error otherwise
+ */
+
+static int elf_loader_seek_and_read(void *firmware, void *destination,
+                Elf32_Off offset, Elf32_Word size) {
+    char *src = (char *) firmware;
+
+    /* Seek to the specified offset. */
+    src = src + offset;
+
+    /* Read the data. */
+    env_memcpy((char *) destination, src, size);
+
+    /* Return status to caller. */
+    return (0);
+}
+
+/**
+ * elf_loader_read_headers
+ *
+ * Reads the ELF headers (ELF header, section headers and the section
+ * headers string table) essential to access further information from
+ * the file containing the ELF object.
+ *
+ * @param firmware    - firmware to read from.
+ * @param elf_info - ELF object decode info container.
+ *
+ * @return  - 0 if success, error otherwise
+ */
+static int elf_loader_read_headers(void *firmware,
+                struct elf_decode_info *elf_info) {
+    int status = 0;
+    unsigned int section_count;
+
+    /* Read the ELF header. */
+    status = elf_loader_seek_and_read(firmware, &(elf_info->elf_header), 0,
+                    sizeof(Elf32_Ehdr));
+
+    /* Ensure the read was successful. */
+    if (!status) {
+        /* Get section count from the ELF header. */
+        section_count = elf_info->elf_header.e_shnum;
+
+        /* Allocate memory to read in the section headers. */
+        elf_info->section_headers_start = env_allocate_memory(
+                        section_count * elf_info->elf_header.e_shentsize);
+
+        /* Check if the allocation was successful. */
+        if (elf_info->section_headers_start) {
+            /* Read the section headers list. */
+            status = elf_loader_seek_and_read(firmware,
+                            elf_info->section_headers_start,
+                            elf_info->elf_header.e_shoff,
+                            section_count * elf_info->elf_header.e_shentsize);
+
+            /* Ensure the read was successful. */
+            if (!status) {
+                /* Compute the pointer to section header string table section. */
+                Elf32_Shdr *section_header_string_table =
+                                (Elf32_Shdr *) (elf_info->section_headers_start
+                                                + elf_info->elf_header.e_shstrndx
+                                                                * elf_info->elf_header.e_shentsize);
+
+                /* Allocate the memory for section header string table. */
+                elf_info->shstrtab = env_allocate_memory(
+                                section_header_string_table->sh_size);
+
+                /* Ensure the allocation was successful. */
+                if (elf_info->shstrtab) {
+                    /* Read the section headers string table. */
+                    status = elf_loader_seek_and_read(firmware,
+                                    elf_info->shstrtab,
+                                    section_header_string_table->sh_offset,
+                                    section_header_string_table->sh_size);
+                }
+            }
+        }
+    }
+
+    /* Return status to caller. */
+    return (status);
+}
+
+/**
+ * elf_loader_file_read_sections
+ *
+ * Reads the ELF section contents from the specified file containing
+ * the ELF object.
+ *
+ * @param firmware - firmware to read from.
+ * @param elf_info - ELF object decode info container.
+ *
+ * @return  - 0 if success, error otherwise
+ */
+static int elf_loader_load_sections(void *firmware,
+                struct elf_decode_info *elf_info) {
+    int status = 0;
+    Elf32_Shdr *current = (Elf32_Shdr *) (elf_info->section_headers_start);
+
+    /* Traverse all sections except the reserved null section. */
+    int section_count = elf_info->elf_header.e_shnum - 1;
+    while ((section_count > 0) && (status == 0)) {
+        /* Compute the pointer to section header. */
+        current = (Elf32_Shdr *) (((unsigned char *) current)
+                        + elf_info->elf_header.e_shentsize);
+
+        /* Make sure the section can be allocated and is not empty. */
+        if ((current->sh_flags & SHF_ALLOC) && (current->sh_size)) {
+            char *destination = NULL;
+
+            /* Check if the section is part of runtime and is not section with
+             * no-load attributes such as BSS or heap. */
+            if ((current->sh_type & SHT_NOBITS) == 0) {
+                /* Compute the destination address where the section should
+                 * be copied. */
+                destination = (char *) (current->sh_addr);
+                status = elf_loader_seek_and_read(firmware, destination,
+                                current->sh_offset, current->sh_size);
+            }
+        }
+
+        /* Move to the next section. */
+        section_count--;
+    }
+
+    /* Return status to caller. */
+    return (status);
+}
+
+/**
+ * elf_loader_get_decode_info
+ *
+ * Retrieves the information necessary to decode the ELF object for
+ * loading, relocating and linking.
+ *
+ * @param firmware - firmware to read from.
+ * @param elf_info - ELF object decode info container.
+ *
+ * @return  - 0 if success, error otherwise
+ */
+static int elf_loader_get_decode_info(void *firmware,
+                struct elf_decode_info *elf_info) {
+    int status;
+
+    /* Read the ELF headers (ELF header and section headers including
+     * the section header string table). */
+    status = elf_loader_read_headers(firmware, elf_info);
+
+    /* Ensure that ELF headers were read successfully. */
+    if (!status) {
+        /* Retrieve the sections required for load. */
+        elf_loader_get_needed_sections(elf_info);
+
+    }
+
+    /* Return status to caller. */
+    return (status);
+}
+
+/**
+ * elf_loader_get_dynamic_symbol_addr
+ *
+ * Retrieves the (relocatable) address of the symbol specified as
+ * index from the given ELF object.
+ *
+ * @param elf_info - ELF object decode info container.
+ * @param index    - Index of the desired symbol in the dynamic symbol table.
+ *
+ * @return - Address of the specified symbol.
+ */
+static Elf32_Addr elf_loader_get_dynamic_symbol_addr(
+                struct elf_decode_info *elf_info, int index) {
+    Elf32_Sym *symbol_entry = (Elf32_Sym *) (elf_info->dynsym_addr
+                    + index * elf_info->dynsym->sh_entsize);
+
+    /* Return the symbol address. */
+    return (symbol_entry->st_value);
+}
+
+/**
+ * elf_loader_reloc_entry
+ *
+ * Processes the specified relocation entry. It handles the relocation
+ * and linking both cases.
+ *
+ *
+ * @param elf_info - ELF object decode info container.
+ *
+ * @return  - 0 if success, error otherwise
+ */
+static int elf_loader_reloc_entry(struct elf_decode_info *elf_info,
+                Elf32_Rel *rel_entry) {
+    unsigned char rel_type = ELF32_R_TYPE(rel_entry->r_info);
+    int status = 0;
+
+    switch (rel_type) {
+    case R_ARM_ABS32: /* 0x02 */
+    {
+        Elf32_Addr sym_addr = elf_loader_get_dynamic_symbol_addr(elf_info,
+                        ELF32_R_SYM(rel_entry->r_info));
+
+        if (sym_addr) {
+            *((unsigned int *) (rel_entry->r_offset)) = (unsigned int) sym_addr;
+            break;
+        }
+    }
+
+        break;
+
+    default:
+        break;
+    }
+
+    return status;
+}
index 8584368f197f2cf25218941bf196be00d8b7c2dc..003751cc030ebd2c9666c9d41e81ae76449a4425 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-\r
-#ifndef ELF_LOADER_H_\r
-#define ELF_LOADER_H_\r
-\r
-#include "remoteproc_loader.h"\r
-\r
-/* ELF base types - 32-bit. */\r
-typedef     unsigned int          Elf32_Addr;\r
-typedef     unsigned short        Elf32_Half;\r
-typedef     unsigned int          Elf32_Off;\r
-typedef     signed int            Elf32_Sword;\r
-typedef     unsigned int          Elf32_Word;\r
-\r
-/* Size of ELF identifier field in the ELF file header. */\r
-#define     EI_NIDENT       16\r
-\r
-/* ELF file header */\r
-typedef struct\r
-{\r
-    unsigned char           e_ident[EI_NIDENT];\r
-    Elf32_Half              e_type;\r
-    Elf32_Half              e_machine;\r
-    Elf32_Word              e_version;\r
-    Elf32_Addr              e_entry;\r
-    Elf32_Off               e_phoff;\r
-    Elf32_Off               e_shoff;\r
-    Elf32_Word              e_flags;\r
-    Elf32_Half              e_ehsize;\r
-    Elf32_Half              e_phentsize;\r
-    Elf32_Half              e_phnum;\r
-    Elf32_Half              e_shentsize;\r
-    Elf32_Half              e_shnum;\r
-    Elf32_Half              e_shstrndx;\r
-\r
-} Elf32_Ehdr;\r
-\r
-/* e_ident */\r
-#define     ET_NONE         0\r
-#define     ET_REL          1               /* Re-locatable file         */\r
-#define     ET_EXEC         2               /* Executable file           */\r
-#define     ET_DYN          3               /* Shared object file        */\r
-#define     ET_CORE         4               /* Core file                 */\r
-#define     ET_LOOS         0xfe00          /* Operating system-specific */\r
-#define     ET_HIOS         0xfeff          /* Operating system-specific */\r
-#define     ET_LOPROC       0xff00          /* remote_proc-specific        */\r
-#define     ET_HIPROC       0xffff          /* remote_proc-specific        */\r
-\r
-/* e_machine */\r
-#define     EM_ARM          40              /* ARM/Thumb Architecture    */\r
-\r
-/* e_version */\r
-#define     EV_CURRENT      1               /* Current version           */\r
-\r
-/* e_ident[] Identification Indexes */\r
-#define     EI_MAG0         0               /* File identification       */\r
-#define     EI_MAG1         1               /* File identification       */\r
-#define     EI_MAG2         2               /* File identification       */\r
-#define     EI_MAG3         3               /* File identification       */\r
-#define     EI_CLASS        4               /* File class                */\r
-#define     EI_DATA         5               /* Data encoding             */\r
-#define     EI_VERSION      6               /* File version              */\r
-#define     EI_OSABI        7               /* Operating system/ABI identification */\r
-#define     EI_ABIVERSION   8               /* ABI version               */\r
-#define     EI_PAD          9               /* Start of padding bytes    */\r
-#define     EI_NIDENT       16              /* Size of e_ident[]         */\r
-\r
-/* EI_MAG0 to EI_MAG3 - A file's first 4 bytes hold amagic number, identifying the file as an ELF object file */\r
-#define     ELFMAG0         0x7f            /* e_ident[EI_MAG0]          */\r
-#define     ELFMAG1         'E'             /* e_ident[EI_MAG1]          */\r
-#define     ELFMAG2         'L'             /* e_ident[EI_MAG2]          */\r
-#define     ELFMAG3         'F'             /* e_ident[EI_MAG3]          */\r
-\r
-/* EI_CLASS - The next byte, e_ident[EI_CLASS], identifies the file's class, or capacity. */\r
-#define     ELFCLASSNONE    0               /* Invalid class             */\r
-#define     ELFCLASS32      1               /* 32-bit objects            */\r
-#define     ELFCLASS64      2               /* 64-bit objects            */\r
-\r
-/* EI_DATA - Byte e_ident[EI_DATA] specifies the data encoding of the remote_proc-specific data in the object\r
-file. The following encodings are currently defined. */\r
-#define     ELFDATANONE     0               /* Invalid data encoding     */\r
-#define     ELFDATA2LSB     1               /* See Data encodings, below */\r
-#define     ELFDATA2MSB     2               /* See Data encodings, below */\r
-\r
-/* EI_OSABI - We do not define an OS specific ABI */\r
-#define     ELFOSABI_NONE   0\r
-\r
-/* ELF section header. */\r
-typedef struct\r
-{\r
-    Elf32_Word              sh_name;\r
-    Elf32_Word              sh_type;\r
-    Elf32_Word              sh_flags;\r
-    Elf32_Addr              sh_addr;\r
-    Elf32_Off               sh_offset;\r
-    Elf32_Word              sh_size;\r
-    Elf32_Word              sh_link;\r
-    Elf32_Word              sh_info;\r
-    Elf32_Word              sh_addralign;\r
-    Elf32_Word              sh_entsize;\r
-\r
-} Elf32_Shdr;\r
-\r
-/* sh_type */\r
-#define     SHT_NULL                0\r
-#define     SHT_PROGBITS            1\r
-#define     SHT_SYMTAB              2\r
-#define     SHT_STRTAB              3\r
-#define     SHT_RELA                4\r
-#define     SHT_HASH                5\r
-#define     SHT_DYNAMIC             6\r
-#define     SHT_NOTE                7\r
-#define     SHT_NOBITS              8\r
-#define     SHT_REL                 9\r
-#define     SHT_SHLIB               10\r
-#define     SHT_DYNSYM              11\r
-#define     SHT_INIT_ARRAY          14\r
-#define     SHT_FINI_ARRAY          15\r
-#define     SHT_PREINIT_ARRAY       16\r
-#define     SHT_GROUP               17\r
-#define     SHT_SYMTAB_SHNDX        18\r
-#define     SHT_LOOS                0x60000000\r
-#define     SHT_HIOS                0x6fffffff\r
-#define     SHT_LOPROC              0x70000000\r
-#define     SHT_HIPROC              0x7fffffff\r
-#define     SHT_LOUSER              0x80000000\r
-#define     SHT_HIUSER              0xffffffff\r
-\r
-/* sh_flags */\r
-#define     SHF_WRITE       0x1\r
-#define     SHF_ALLOC       0x2\r
-#define     SHF_EXECINSTR   0x4\r
-#define     SHF_MASKPROC    0xf0000000\r
-\r
-/* Relocation entry (without addend) */\r
-typedef struct\r
-{\r
-    Elf32_Addr              r_offset;\r
-    Elf32_Word              r_info;\r
-\r
-} Elf32_Rel;\r
-\r
-/* Relocation entry with addend */\r
-typedef struct\r
-{\r
-    Elf32_Addr              r_offset;\r
-    Elf32_Word              r_info;\r
-    Elf32_Sword             r_addend;\r
-\r
-} Elf32_Rela;\r
-\r
-/* Macros to extract information from 'r_info' field of relocation entries */\r
-#define     ELF32_R_SYM(i)  ((i)>>8)\r
-#define     ELF32_R_TYPE(i) ((unsigned char)(i))\r
-\r
-/* Symbol table entry */\r
-typedef struct\r
-{\r
-    Elf32_Word              st_name;\r
-    Elf32_Addr              st_value;\r
-    Elf32_Word              st_size;\r
-    unsigned char           st_info;\r
-    unsigned char           st_other;\r
-    Elf32_Half              st_shndx;\r
-\r
-} Elf32_Sym;\r
-\r
-/* ARM specific dynamic relocation codes */\r
-#define     R_ARM_GLOB_DAT     21              /* 0x15 */\r
-#define     R_ARM_JUMP_SLOT    22      /* 0x16 */\r
-#define     R_ARM_RELATIVE     23      /* 0x17 */\r
-#define     R_ARM_ABS32             2          /* 0x02 */\r
-\r
-\r
-/* ELF decoding information */\r
-struct elf_decode_info\r
-{\r
-    Elf32_Ehdr      elf_header;\r
-    unsigned char   *section_headers_start;\r
-    char            *shstrtab;\r
-\r
-    Elf32_Shdr      *dynsym;\r
-    Elf32_Shdr      *dynstr;\r
-    Elf32_Shdr      *rel_plt;\r
-    Elf32_Shdr      *rel_dyn;\r
-    Elf32_Shdr      *rsc;\r
-\r
-    unsigned char   *dynsym_addr;\r
-    unsigned char   *dynstr_addr;\r
-\r
-    char            *firmware;\r
-\r
-};\r
-\r
-\r
-\r
-/* ELF Loader functions. */\r
-int elf_loader_init(struct remoteproc_loader *loader);\r
-void *elf_loader_retrieve_entry_point(struct remoteproc_loader *loader);\r
-void *elf_loader_retrieve_resource_section(struct remoteproc_loader *loader, unsigned int *size);\r
-int elf_loader_load_remote_firmware(struct remoteproc_loader *loader);\r
-int elf_loader_attach_firmware(struct remoteproc_loader *loader, void *firmware);\r
-int elf_loader_detach_firmware(struct remoteproc_loader *loader);\r
-void *elf_get_load_address(struct remoteproc_loader *loader);\r
-\r
-#endif /* ELF_LOADER_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+
+#ifndef ELF_LOADER_H_
+#define ELF_LOADER_H_
+
+#include "remoteproc_loader.h"
+
+/* ELF base types - 32-bit. */
+typedef     unsigned int          Elf32_Addr;
+typedef     unsigned short        Elf32_Half;
+typedef     unsigned int          Elf32_Off;
+typedef     signed int            Elf32_Sword;
+typedef     unsigned int          Elf32_Word;
+
+/* Size of ELF identifier field in the ELF file header. */
+#define     EI_NIDENT       16
+
+/* ELF file header */
+typedef struct
+{
+    unsigned char           e_ident[EI_NIDENT];
+    Elf32_Half              e_type;
+    Elf32_Half              e_machine;
+    Elf32_Word              e_version;
+    Elf32_Addr              e_entry;
+    Elf32_Off               e_phoff;
+    Elf32_Off               e_shoff;
+    Elf32_Word              e_flags;
+    Elf32_Half              e_ehsize;
+    Elf32_Half              e_phentsize;
+    Elf32_Half              e_phnum;
+    Elf32_Half              e_shentsize;
+    Elf32_Half              e_shnum;
+    Elf32_Half              e_shstrndx;
+
+} Elf32_Ehdr;
+
+/* e_ident */
+#define     ET_NONE         0
+#define     ET_REL          1               /* Re-locatable file         */
+#define     ET_EXEC         2               /* Executable file           */
+#define     ET_DYN          3               /* Shared object file        */
+#define     ET_CORE         4               /* Core file                 */
+#define     ET_LOOS         0xfe00          /* Operating system-specific */
+#define     ET_HIOS         0xfeff          /* Operating system-specific */
+#define     ET_LOPROC       0xff00          /* remote_proc-specific        */
+#define     ET_HIPROC       0xffff          /* remote_proc-specific        */
+
+/* e_machine */
+#define     EM_ARM          40              /* ARM/Thumb Architecture    */
+
+/* e_version */
+#define     EV_CURRENT      1               /* Current version           */
+
+/* e_ident[] Identification Indexes */
+#define     EI_MAG0         0               /* File identification       */
+#define     EI_MAG1         1               /* File identification       */
+#define     EI_MAG2         2               /* File identification       */
+#define     EI_MAG3         3               /* File identification       */
+#define     EI_CLASS        4               /* File class                */
+#define     EI_DATA         5               /* Data encoding             */
+#define     EI_VERSION      6               /* File version              */
+#define     EI_OSABI        7               /* Operating system/ABI identification */
+#define     EI_ABIVERSION   8               /* ABI version               */
+#define     EI_PAD          9               /* Start of padding bytes    */
+#define     EI_NIDENT       16              /* Size of e_ident[]         */
+
+/* EI_MAG0 to EI_MAG3 - A file's first 4 bytes hold amagic number, identifying the file as an ELF object file */
+#define     ELFMAG0         0x7f            /* e_ident[EI_MAG0]          */
+#define     ELFMAG1         'E'             /* e_ident[EI_MAG1]          */
+#define     ELFMAG2         'L'             /* e_ident[EI_MAG2]          */
+#define     ELFMAG3         'F'             /* e_ident[EI_MAG3]          */
+
+/* EI_CLASS - The next byte, e_ident[EI_CLASS], identifies the file's class, or capacity. */
+#define     ELFCLASSNONE    0               /* Invalid class             */
+#define     ELFCLASS32      1               /* 32-bit objects            */
+#define     ELFCLASS64      2               /* 64-bit objects            */
+
+/* EI_DATA - Byte e_ident[EI_DATA] specifies the data encoding of the remote_proc-specific data in the object
+file. The following encodings are currently defined. */
+#define     ELFDATANONE     0               /* Invalid data encoding     */
+#define     ELFDATA2LSB     1               /* See Data encodings, below */
+#define     ELFDATA2MSB     2               /* See Data encodings, below */
+
+/* EI_OSABI - We do not define an OS specific ABI */
+#define     ELFOSABI_NONE   0
+
+/* ELF section header. */
+typedef struct
+{
+    Elf32_Word              sh_name;
+    Elf32_Word              sh_type;
+    Elf32_Word              sh_flags;
+    Elf32_Addr              sh_addr;
+    Elf32_Off               sh_offset;
+    Elf32_Word              sh_size;
+    Elf32_Word              sh_link;
+    Elf32_Word              sh_info;
+    Elf32_Word              sh_addralign;
+    Elf32_Word              sh_entsize;
+
+} Elf32_Shdr;
+
+/* sh_type */
+#define     SHT_NULL                0
+#define     SHT_PROGBITS            1
+#define     SHT_SYMTAB              2
+#define     SHT_STRTAB              3
+#define     SHT_RELA                4
+#define     SHT_HASH                5
+#define     SHT_DYNAMIC             6
+#define     SHT_NOTE                7
+#define     SHT_NOBITS              8
+#define     SHT_REL                 9
+#define     SHT_SHLIB               10
+#define     SHT_DYNSYM              11
+#define     SHT_INIT_ARRAY          14
+#define     SHT_FINI_ARRAY          15
+#define     SHT_PREINIT_ARRAY       16
+#define     SHT_GROUP               17
+#define     SHT_SYMTAB_SHNDX        18
+#define     SHT_LOOS                0x60000000
+#define     SHT_HIOS                0x6fffffff
+#define     SHT_LOPROC              0x70000000
+#define     SHT_HIPROC              0x7fffffff
+#define     SHT_LOUSER              0x80000000
+#define     SHT_HIUSER              0xffffffff
+
+/* sh_flags */
+#define     SHF_WRITE       0x1
+#define     SHF_ALLOC       0x2
+#define     SHF_EXECINSTR   0x4
+#define     SHF_MASKPROC    0xf0000000
+
+/* Relocation entry (without addend) */
+typedef struct
+{
+    Elf32_Addr              r_offset;
+    Elf32_Word              r_info;
+
+} Elf32_Rel;
+
+/* Relocation entry with addend */
+typedef struct
+{
+    Elf32_Addr              r_offset;
+    Elf32_Word              r_info;
+    Elf32_Sword             r_addend;
+
+} Elf32_Rela;
+
+/* Macros to extract information from 'r_info' field of relocation entries */
+#define     ELF32_R_SYM(i)  ((i)>>8)
+#define     ELF32_R_TYPE(i) ((unsigned char)(i))
+
+/* Symbol table entry */
+typedef struct
+{
+    Elf32_Word              st_name;
+    Elf32_Addr              st_value;
+    Elf32_Word              st_size;
+    unsigned char           st_info;
+    unsigned char           st_other;
+    Elf32_Half              st_shndx;
+
+} Elf32_Sym;
+
+/* ARM specific dynamic relocation codes */
+#define     R_ARM_GLOB_DAT     21              /* 0x15 */
+#define     R_ARM_JUMP_SLOT    22      /* 0x16 */
+#define     R_ARM_RELATIVE     23      /* 0x17 */
+#define     R_ARM_ABS32             2          /* 0x02 */
+
+
+/* ELF decoding information */
+struct elf_decode_info
+{
+    Elf32_Ehdr      elf_header;
+    unsigned char   *section_headers_start;
+    char            *shstrtab;
+
+    Elf32_Shdr      *dynsym;
+    Elf32_Shdr      *dynstr;
+    Elf32_Shdr      *rel_plt;
+    Elf32_Shdr      *rel_dyn;
+    Elf32_Shdr      *rsc;
+
+    unsigned char   *dynsym_addr;
+    unsigned char   *dynstr_addr;
+
+    char            *firmware;
+
+};
+
+
+
+/* ELF Loader functions. */
+int elf_loader_init(struct remoteproc_loader *loader);
+void *elf_loader_retrieve_entry_point(struct remoteproc_loader *loader);
+void *elf_loader_retrieve_resource_section(struct remoteproc_loader *loader, unsigned int *size);
+int elf_loader_load_remote_firmware(struct remoteproc_loader *loader);
+int elf_loader_attach_firmware(struct remoteproc_loader *loader, void *firmware);
+int elf_loader_detach_firmware(struct remoteproc_loader *loader);
+void *elf_get_load_address(struct remoteproc_loader *loader);
+
+#endif /* ELF_LOADER_H_ */
index a8f87075e07a7181821ad301929bf5a90e6287e3..487c9134355bb8e62d887635b531e00f43752b1a 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include "remoteproc_loader.h"\r
-\r
-/**\r
- * remoteproc_loader_init\r
- *\r
- * Initializes the remoteproc loader.\r
- *\r
- * @param type - loader type\r
- *\r
- * @return  - remoteproc_loader\r
- */\r
-struct remoteproc_loader * remoteproc_loader_init(enum loader_type type) {\r
-\r
-    struct remoteproc_loader *loader;\r
-\r
-    /* Check for valid loader type. */\r
-    if (type >= LAST_LOADER) {\r
-        return RPROC_NULL ;\r
-    }\r
-\r
-    /* Allocate a loader handle. */\r
-    loader = env_allocate_memory(sizeof(struct remoteproc_loader));\r
-\r
-    if (!loader) {\r
-        return RPROC_NULL ;\r
-    }\r
-\r
-    /* Clear loader handle. */\r
-    env_memset(loader, 0, sizeof(struct remoteproc_loader));\r
-\r
-    /* Save loader type. */\r
-    loader->type = type;\r
-\r
-    switch (type) {\r
-\r
-    case ELF_LOADER:\r
-        elf_loader_init(loader);\r
-        break;\r
-\r
-    default:\r
-        /* Loader not supported. */\r
-        env_free_memory(loader);\r
-        loader = RPROC_NULL;\r
-        break;\r
-    }\r
-\r
-    return loader;\r
-}\r
-\r
-/**\r
- * remoteproc_loader_delete\r
- *\r
- * Deletes the remoteproc loader.\r
- *\r
- * @param loader    - pointer to remoteproc loader\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-int remoteproc_loader_delete(struct remoteproc_loader *loader) {\r
-\r
-    int status = 0;\r
-\r
-    if (!loader) {\r
-        return RPROC_ERR_PARAM;\r
-    }\r
-\r
-    /* Check if a firmware is attached. */\r
-    if (loader->remote_firmware) {\r
-\r
-        /* Detach firmware first. */\r
-        status = loader->detach_firmware(loader);\r
-    }\r
-\r
-    /* Recover the allocated memory. */\r
-    env_free_memory(loader);\r
-\r
-    return status;\r
-}\r
-\r
-/**\r
- * remoteproc_loader_attach_firmware\r
- *\r
- * Attaches an ELF firmware to the loader\r
- *\r
- * @param loader    - pointer to remoteproc loader\r
- * @param firmware  - pointer to the firmware start location\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-int remoteproc_loader_attach_firmware(struct remoteproc_loader *loader,\r
-                void *firmware_image) {\r
-\r
-    int status = RPROC_SUCCESS;\r
-\r
-    if (!loader || !firmware_image) {\r
-        return RPROC_ERR_PARAM;\r
-    }\r
-\r
-    if (loader->attach_firmware) {\r
-\r
-        /* Check if a firmware is already attached. */\r
-        if (loader->remote_firmware) {\r
-\r
-            /* Detach firmware first. */\r
-            status = loader->detach_firmware(loader);\r
-        }\r
-\r
-        /* Attach firmware. */\r
-        if (!status) {\r
-            status = loader->attach_firmware(loader, firmware_image);\r
-\r
-            /* Save firmware address. */\r
-            if (!status) {\r
-                loader->remote_firmware = firmware_image;\r
-            }\r
-        }\r
-    }else{\r
-        status = RPROC_ERR_LOADER;\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/**\r
- * remoteproc_loader_retrieve_entry_point\r
- *\r
- * Provides entry point address.\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- *\r
- * @return  - entrypoint\r
- */\r
-void *remoteproc_loader_retrieve_entry_point(struct remoteproc_loader *loader) {\r
-\r
-    if (!loader) {\r
-        return RPROC_NULL ;\r
-    }\r
-\r
-    if (loader->retrieve_entry) {\r
-        return loader->retrieve_entry(loader);\r
-    } else {\r
-        return RPROC_NULL ;\r
-    }\r
-}\r
-\r
-/**\r
- * remoteproc_loader_retrieve_resource_section\r
- *\r
- * Provides resource section address.\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- * @param size   - pointer to hold size of resource section\r
- *\r
- * @return  - pointer to resource section\r
- */\r
-void *remoteproc_loader_retrieve_resource_section(\r
-                struct remoteproc_loader *loader, unsigned int *size) {\r
-\r
-    if (!loader) {\r
-        return RPROC_NULL ;\r
-    }\r
-\r
-    if (loader->retrieve_rsc) {\r
-        return loader->retrieve_rsc(loader, size);\r
-    } else {\r
-        return RPROC_NULL ;\r
-    }\r
-}\r
-\r
-/**\r
- * remoteproc_loader_load_remote_firmware\r
- *\r
- * Loads the firmware in memory\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- *\r
- * @return  - 0 if success, error otherwise\r
- */\r
-int remoteproc_loader_load_remote_firmware(struct remoteproc_loader *loader) {\r
-\r
-    if (!loader) {\r
-        return RPROC_ERR_PARAM;\r
-    }\r
-\r
-    if (loader->load_firmware) {\r
-        return loader->load_firmware(loader);\r
-    } else {\r
-        return RPROC_ERR_LOADER;\r
-    }\r
-}\r
-\r
-/**\r
- * remoteproc_get_load_address\r
- *\r
- * Provides firmware load address.\r
- *\r
- * @param loader - pointer to remoteproc loader\r
- *\r
- * @return  - load address pointer\r
- */\r
-void *remoteproc_get_load_address(struct remoteproc_loader *loader){\r
-\r
-    if (!loader) {\r
-        return RPROC_ERR_PTR;\r
-    }\r
-\r
-    if (loader->retrieve_load_addr) {\r
-        return loader->retrieve_load_addr(loader);\r
-    } else {\r
-        return RPROC_ERR_PTR;\r
-    }\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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 "remoteproc_loader.h"
+
+/**
+ * remoteproc_loader_init
+ *
+ * Initializes the remoteproc loader.
+ *
+ * @param type - loader type
+ *
+ * @return  - remoteproc_loader
+ */
+struct remoteproc_loader * remoteproc_loader_init(enum loader_type type) {
+
+    struct remoteproc_loader *loader;
+
+    /* Check for valid loader type. */
+    if (type >= LAST_LOADER) {
+        return RPROC_NULL ;
+    }
+
+    /* Allocate a loader handle. */
+    loader = env_allocate_memory(sizeof(struct remoteproc_loader));
+
+    if (!loader) {
+        return RPROC_NULL ;
+    }
+
+    /* Clear loader handle. */
+    env_memset(loader, 0, sizeof(struct remoteproc_loader));
+
+    /* Save loader type. */
+    loader->type = type;
+
+    switch (type) {
+
+    case ELF_LOADER:
+        elf_loader_init(loader);
+        break;
+
+    default:
+        /* Loader not supported. */
+        env_free_memory(loader);
+        loader = RPROC_NULL;
+        break;
+    }
+
+    return loader;
+}
+
+/**
+ * remoteproc_loader_delete
+ *
+ * Deletes the remoteproc loader.
+ *
+ * @param loader    - pointer to remoteproc loader
+ *
+ * @return  - 0 if success, error otherwise
+ */
+int remoteproc_loader_delete(struct remoteproc_loader *loader) {
+
+    int status = 0;
+
+    if (!loader) {
+        return RPROC_ERR_PARAM;
+    }
+
+    /* Check if a firmware is attached. */
+    if (loader->remote_firmware) {
+
+        /* Detach firmware first. */
+        status = loader->detach_firmware(loader);
+    }
+
+    /* Recover the allocated memory. */
+    env_free_memory(loader);
+
+    return status;
+}
+
+/**
+ * remoteproc_loader_attach_firmware
+ *
+ * Attaches an ELF firmware to the loader
+ *
+ * @param loader    - pointer to remoteproc loader
+ * @param firmware  - pointer to the firmware start location
+ *
+ * @return  - 0 if success, error otherwise
+ */
+int remoteproc_loader_attach_firmware(struct remoteproc_loader *loader,
+                void *firmware_image) {
+
+    int status = RPROC_SUCCESS;
+
+    if (!loader || !firmware_image) {
+        return RPROC_ERR_PARAM;
+    }
+
+    if (loader->attach_firmware) {
+
+        /* Check if a firmware is already attached. */
+        if (loader->remote_firmware) {
+
+            /* Detach firmware first. */
+            status = loader->detach_firmware(loader);
+        }
+
+        /* Attach firmware. */
+        if (!status) {
+            status = loader->attach_firmware(loader, firmware_image);
+
+            /* Save firmware address. */
+            if (!status) {
+                loader->remote_firmware = firmware_image;
+            }
+        }
+    }else{
+        status = RPROC_ERR_LOADER;
+    }
+
+    return status;
+}
+
+/**
+ * remoteproc_loader_retrieve_entry_point
+ *
+ * Provides entry point address.
+ *
+ * @param loader - pointer to remoteproc loader
+ *
+ * @return  - entrypoint
+ */
+void *remoteproc_loader_retrieve_entry_point(struct remoteproc_loader *loader) {
+
+    if (!loader) {
+        return RPROC_NULL ;
+    }
+
+    if (loader->retrieve_entry) {
+        return loader->retrieve_entry(loader);
+    } else {
+        return RPROC_NULL ;
+    }
+}
+
+/**
+ * remoteproc_loader_retrieve_resource_section
+ *
+ * Provides resource section address.
+ *
+ * @param loader - pointer to remoteproc loader
+ * @param size   - pointer to hold size of resource section
+ *
+ * @return  - pointer to resource section
+ */
+void *remoteproc_loader_retrieve_resource_section(
+                struct remoteproc_loader *loader, unsigned int *size) {
+
+    if (!loader) {
+        return RPROC_NULL ;
+    }
+
+    if (loader->retrieve_rsc) {
+        return loader->retrieve_rsc(loader, size);
+    } else {
+        return RPROC_NULL ;
+    }
+}
+
+/**
+ * remoteproc_loader_load_remote_firmware
+ *
+ * Loads the firmware in memory
+ *
+ * @param loader - pointer to remoteproc loader
+ *
+ * @return  - 0 if success, error otherwise
+ */
+int remoteproc_loader_load_remote_firmware(struct remoteproc_loader *loader) {
+
+    if (!loader) {
+        return RPROC_ERR_PARAM;
+    }
+
+    if (loader->load_firmware) {
+        return loader->load_firmware(loader);
+    } else {
+        return RPROC_ERR_LOADER;
+    }
+}
+
+/**
+ * remoteproc_get_load_address
+ *
+ * Provides firmware load address.
+ *
+ * @param loader - pointer to remoteproc loader
+ *
+ * @return  - load address pointer
+ */
+void *remoteproc_get_load_address(struct remoteproc_loader *loader){
+
+    if (!loader) {
+        return RPROC_ERR_PTR;
+    }
+
+    if (loader->retrieve_load_addr) {
+        return loader->retrieve_load_addr(loader);
+    } else {
+        return RPROC_ERR_PTR;
+    }
+}
index eca849c172db77fdb6d8e9c580e946e60eb9dcb5..eeb7bb31a511792d9fc6b73812c02161dd37b385 100644 (file)
@@ -1,92 +1,92 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       remoteproc_loader.h\r
- *\r
- * COMPONENT\r
- *\r
- *         OpenAMP stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- *       This file provides definitions for remoteproc loader\r
- *\r
- *\r
- **************************************************************************/\r
-#ifndef REMOTEPROC_LOADER_H_\r
-#define REMOTEPROC_LOADER_H_\r
-\r
-#include "remoteproc.h"\r
-\r
-/**\r
- * enum loader_type - dynamic name service announcement flags\r
- *\r
- * @ELF_LOADER: an ELF loader\r
- * @FIT_LOADER: a loader for Flattened Image Trees\r
- */\r
-enum loader_type {\r
-    ELF_LOADER = 0, FIT_LOADER = 1, LAST_LOADER = 2,\r
-};\r
-\r
-/* Loader structure definition. */\r
-\r
-struct remoteproc_loader {\r
-    enum loader_type type;\r
-    void *remote_firmware;\r
-    /* Pointer to firmware decoded info control block */\r
-    void *fw_decode_info;\r
-\r
-    /* Loader callbacks. */\r
-    void *(*retrieve_entry)(struct remoteproc_loader *loader);\r
-    void *(*retrieve_rsc)(struct remoteproc_loader *loader, unsigned int *size);\r
-    int (*load_firmware)(struct remoteproc_loader *loader);\r
-    int (*attach_firmware)(struct remoteproc_loader *loader, void *firmware);\r
-    int (*detach_firmware)(struct remoteproc_loader *loader);\r
-    void *(*retrieve_load_addr)(struct remoteproc_loader *loader);\r
-\r
-};\r
-\r
-/* RemoteProc Loader functions. */\r
-struct remoteproc_loader * remoteproc_loader_init(enum loader_type type);\r
-int remoteproc_loader_delete(struct remoteproc_loader *loader);\r
-int remoteproc_loader_attach_firmware(struct remoteproc_loader *loader,\r
-                void *firmware_image);\r
-void *remoteproc_loader_retrieve_entry_point(struct remoteproc_loader *loader);\r
-void *remoteproc_loader_retrieve_resource_section(\r
-                struct remoteproc_loader *loader, unsigned int* size);\r
-int remoteproc_loader_load_remote_firmware(struct remoteproc_loader *loader);\r
-void *remoteproc_get_load_address(struct remoteproc_loader *loader);\r
-\r
-/* Supported loaders */\r
-extern int elf_loader_init(struct remoteproc_loader *loader);\r
-\r
-#endif /* REMOTEPROC_LOADER_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       remoteproc_loader.h
+ *
+ * COMPONENT
+ *
+ *         OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ *       This file provides definitions for remoteproc loader
+ *
+ *
+ **************************************************************************/
+#ifndef REMOTEPROC_LOADER_H_
+#define REMOTEPROC_LOADER_H_
+
+#include "remoteproc.h"
+
+/**
+ * enum loader_type - dynamic name service announcement flags
+ *
+ * @ELF_LOADER: an ELF loader
+ * @FIT_LOADER: a loader for Flattened Image Trees
+ */
+enum loader_type {
+    ELF_LOADER = 0, FIT_LOADER = 1, LAST_LOADER = 2,
+};
+
+/* Loader structure definition. */
+
+struct remoteproc_loader {
+    enum loader_type type;
+    void *remote_firmware;
+    /* Pointer to firmware decoded info control block */
+    void *fw_decode_info;
+
+    /* Loader callbacks. */
+    void *(*retrieve_entry)(struct remoteproc_loader *loader);
+    void *(*retrieve_rsc)(struct remoteproc_loader *loader, unsigned int *size);
+    int (*load_firmware)(struct remoteproc_loader *loader);
+    int (*attach_firmware)(struct remoteproc_loader *loader, void *firmware);
+    int (*detach_firmware)(struct remoteproc_loader *loader);
+    void *(*retrieve_load_addr)(struct remoteproc_loader *loader);
+
+};
+
+/* RemoteProc Loader functions. */
+struct remoteproc_loader * remoteproc_loader_init(enum loader_type type);
+int remoteproc_loader_delete(struct remoteproc_loader *loader);
+int remoteproc_loader_attach_firmware(struct remoteproc_loader *loader,
+                void *firmware_image);
+void *remoteproc_loader_retrieve_entry_point(struct remoteproc_loader *loader);
+void *remoteproc_loader_retrieve_resource_section(
+                struct remoteproc_loader *loader, unsigned int* size);
+int remoteproc_loader_load_remote_firmware(struct remoteproc_loader *loader);
+void *remoteproc_get_load_address(struct remoteproc_loader *loader);
+
+/* Supported loaders */
+extern int elf_loader_init(struct remoteproc_loader *loader);
+
+#endif /* REMOTEPROC_LOADER_H_ */
index 4e436c8f17c90ef24a4d0e4b5e3984c1ad84ed13..2ed6fecaa2072dc85e7ab114dcfed53565c9d9d2 100644 (file)
@@ -1,53 +1,53 @@
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#ifndef RSC_TABLE_PARSER_H\r
-#define RSC_TABLE_PARSER_H\r
-\r
-#include "remoteproc.h"\r
-#include "../porting/env/env.h"\r
-#include "../common/hil/hil.h"\r
-\r
-#define RSC_TAB_SUPPORTED_VERSION           1\r
-#define RSC_TAB_HEADER_SIZE                 12\r
-#define RSC_TAB_MAX_VRINGS                  2\r
-\r
-/* Standard control request handling. */\r
-typedef int (*rsc_handler)(struct remote_proc *rproc, void * rsc);\r
-\r
-/* Function prototypes */\r
-int handle_rsc_table(struct remote_proc *rproc, struct resource_table *rsc_table,\r
-                int len);\r
-int handle_carve_out_rsc(struct remote_proc *rproc, void *rsc);\r
-int handle_trace_rsc(struct remote_proc *rproc, void *rsc);\r
-int handle_dev_mem_rsc(struct remote_proc *rproc, void *rsc);\r
-int handle_vdev_rsc(struct remote_proc *rproc, void *rsc);\r
-int handle_mmu_rsc(struct remote_proc *rproc, void *rsc);\r
-\r
-#endif /* RSC_TABLE_PARSER_H */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+#ifndef RSC_TABLE_PARSER_H
+#define RSC_TABLE_PARSER_H
+
+#include "remoteproc.h"
+#include "../porting/env/env.h"
+#include "../common/hil/hil.h"
+
+#define RSC_TAB_SUPPORTED_VERSION           1
+#define RSC_TAB_HEADER_SIZE                 12
+#define RSC_TAB_MAX_VRINGS                  2
+
+/* Standard control request handling. */
+typedef int (*rsc_handler)(struct remote_proc *rproc, void * rsc);
+
+/* Function prototypes */
+int handle_rsc_table(struct remote_proc *rproc, struct resource_table *rsc_table,
+                int len);
+int handle_carve_out_rsc(struct remote_proc *rproc, void *rsc);
+int handle_trace_rsc(struct remote_proc *rproc, void *rsc);
+int handle_dev_mem_rsc(struct remote_proc *rproc, void *rsc);
+int handle_vdev_rsc(struct remote_proc *rproc, void *rsc);
+int handle_mmu_rsc(struct remote_proc *rproc, void *rsc);
+
+#endif /* RSC_TABLE_PARSER_H */
index d7f694571183f83567870c0e14a0793d1f7dc3a1..29e721ca1b5d72fbfd2c54ceccd91d365a03ed38 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- * Copyright (c) 2015 Xilinx, Inc. All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       remote_device.c\r
- *\r
- * COMPONENT\r
- *\r
- *       OpenAMP Stack\r
- *\r
- * DESCRIPTION\r
- *\r
- * This file provides services to manage the remote devices.It also implements\r
- * the interface defined by the virtio and provides few other utility functions.\r
- *\r
- *\r
- **************************************************************************/\r
-\r
-#include "rpmsg.h"\r
-\r
-/* Macro to initialize vring HW info */\r
-#define INIT_VRING_ALLOC_INFO(ring_info,vring_hw)                             \\r
-                         (ring_info).phy_addr  = (vring_hw).phy_addr;         \\r
-                         (ring_info).align     = (vring_hw).align;             \\r
-                         (ring_info).num_descs = (vring_hw).num_descs\r
-\r
-/* Local functions */\r
-static int rpmsg_rdev_init_channels(struct remote_device *rdev);\r
-\r
-/* Ops table for virtio device */\r
-virtio_dispatch rpmsg_rdev_config_ops =\r
-{\r
-    rpmsg_rdev_create_virtqueues,\r
-    rpmsg_rdev_get_status,\r
-    rpmsg_rdev_set_status,\r
-    rpmsg_rdev_get_feature,\r
-    rpmsg_rdev_set_feature,\r
-    rpmsg_rdev_negotiate_feature,\r
-    rpmsg_rdev_read_config,\r
-    rpmsg_rdev_write_config,\r
-    rpmsg_rdev_reset\r
-};\r
-\r
-/**\r
- * rpmsg_rdev_init\r
- *\r
- * This function creates and initializes the remote device. The remote device\r
- * encapsulates virtio device.\r
- *\r
- * @param rdev              - pointer to newly created remote device\r
- * @param dev-id            - ID of device to create , remote cpu id\r
- * @param role              - role of the other device, Master or Remote\r
- * @param channel_created   - callback function for channel creation\r
- * @param channel_destroyed - callback function for channel deletion\r
- * @param default_cb        - default callback for channel\r
- *\r
- * @return - status of function execution\r
- *\r
- */\r
-int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,\r
-                rpmsg_chnl_cb_t channel_created,\r
-                rpmsg_chnl_cb_t channel_destroyed,\r
-                rpmsg_rx_cb_t default_cb) {\r
-\r
-    struct remote_device *rdev_loc;\r
-    struct virtio_device *virt_dev;\r
-    struct hil_proc *proc;\r
-    struct proc_shm *shm;\r
-    int status;\r
-\r
-    /* Initialize HIL data structures for given device */\r
-    proc = hil_create_proc(dev_id);\r
-\r
-    if (!proc) {\r
-        return RPMSG_ERR_DEV_ID;\r
-    }\r
-\r
-    /* Create software representation of remote processor. */\r
-    rdev_loc = (struct remote_device *) env_allocate_memory(\r
-                    sizeof(struct remote_device));\r
-\r
-    if (!rdev_loc) {\r
-        return RPMSG_ERR_NO_MEM;\r
-    }\r
-\r
-    env_memset(rdev_loc, 0x00, sizeof(struct remote_device));\r
-    status = env_create_mutex(&rdev_loc->lock, 1);\r
-\r
-    if (status != RPMSG_SUCCESS) {\r
-\r
-        /* Cleanup required in case of error is performed by caller */\r
-        return status;\r
-    }\r
-\r
-    rdev_loc->proc = proc;\r
-    rdev_loc->role = role;\r
-    rdev_loc->channel_created = channel_created;\r
-    rdev_loc->channel_destroyed = channel_destroyed;\r
-    rdev_loc->default_cb = default_cb;\r
-\r
-    /* Initialize the virtio device */\r
-    virt_dev = &rdev_loc->virt_dev;\r
-    virt_dev->device = proc;\r
-    virt_dev->func = &rpmsg_rdev_config_ops;\r
-    if (virt_dev->func->set_features != RPMSG_NULL) {\r
-        virt_dev->func->set_features(virt_dev, proc->vdev.dfeatures);\r
-    }\r
-\r
-    if (rdev_loc->role == RPMSG_REMOTE) {\r
-        /*\r
-         * Since device is RPMSG Remote so we need to manage the\r
-         * shared buffers. Create shared memory pool to handle buffers.\r
-         */\r
-        shm = hil_get_shm_info(proc);\r
-        rdev_loc->mem_pool = sh_mem_create_pool(shm->start_addr, shm->size,\r
-                        RPMSG_BUFFER_SIZE);\r
-\r
-        if (!rdev_loc->mem_pool) {\r
-            return RPMSG_ERR_NO_MEM;\r
-        }\r
-    }\r
-\r
-    /* Initialize channels for RPMSG Remote */\r
-    status = rpmsg_rdev_init_channels(rdev_loc);\r
-\r
-    if (status != RPMSG_SUCCESS) {\r
-        return status;\r
-    }\r
-\r
-    *rdev = rdev_loc;\r
-\r
-    return RPMSG_SUCCESS;\r
-}\r
-\r
-/**\r
- * rpmsg_rdev_deinit\r
- *\r
- * This function un-initializes the remote device.\r
- *\r
- * @param rdev - pointer to remote device to deinit.\r
- *\r
- * @return - none\r
- *\r
- */\r
-void rpmsg_rdev_deinit(struct remote_device *rdev) {\r
-    struct llist *rp_chnl_head, *rp_chnl_temp, *node;\r
-    struct rpmsg_channel *rp_chnl;\r
-\r
-    rp_chnl_head = rdev->rp_channels;\r
-\r
-    while (rp_chnl_head != RPMSG_NULL ) {\r
-\r
-        rp_chnl_temp = rp_chnl_head->next;\r
-        rp_chnl = (struct rpmsg_channel *) rp_chnl_head->data;\r
-\r
-        if (rdev->channel_destroyed) {\r
-            rdev->channel_destroyed(rp_chnl);\r
-        }\r
-\r
-        if ((rdev->support_ns) && (rdev->role == RPMSG_MASTER)) {\r
-            rpmsg_send_ns_message(rdev, rp_chnl, RPMSG_NS_DESTROY);\r
-        }\r
-\r
-        /* Delete default endpoint for channel */\r
-        if (rp_chnl->rp_ept) {\r
-            rpmsg_destroy_ept(rp_chnl->rp_ept);\r
-        }\r
-\r
-        _rpmsg_delete_channel(rp_chnl);\r
-        rp_chnl_head = rp_chnl_temp;\r
-    }\r
-\r
-    /* Delete name service endpoint */\r
-    node = rpmsg_rdev_get_endpoint_from_addr(rdev,RPMSG_NS_EPT_ADDR);\r
-    if (node) {\r
-        _destroy_endpoint(rdev, (struct rpmsg_endpoint *) node->data);\r
-    }\r
-\r
-    if (rdev->rvq) {\r
-        virtqueue_free(rdev->rvq);\r
-    }\r
-    if (rdev->tvq) {\r
-        virtqueue_free(rdev->tvq);\r
-    }\r
-    if (rdev->mem_pool) {\r
-        sh_mem_delete_pool(rdev->mem_pool);\r
-    }\r
-    if (rdev->lock) {\r
-        env_delete_mutex(rdev->lock);\r
-    }\r
-\r
-    env_free_memory(rdev);\r
-}\r
-\r
-/**\r
- * rpmsg_rdev_get_chnl_node_from_id\r
- *\r
- * This function returns channel node based on channel name.\r
- *\r
- * @param stack      - pointer to remote device\r
- * @param rp_chnl_id - rpmsg channel name\r
- *\r
- * @return - channel node\r
- *\r
- */\r
-struct llist *rpmsg_rdev_get_chnl_node_from_id(struct remote_device *rdev,\r
-                char *rp_chnl_id) {\r
-    struct rpmsg_channel *rp_chnl;\r
-    struct llist *rp_chnl_head;\r
-\r
-    rp_chnl_head = rdev->rp_channels;\r
-\r
-    env_lock_mutex(rdev->lock);\r
-    while (rp_chnl_head) {\r
-        rp_chnl = (struct rpmsg_channel *) rp_chnl_head->data;\r
-        if (env_strncmp(rp_chnl->name, rp_chnl_id, sizeof(rp_chnl->name))\r
-                        == 0) {\r
-            env_unlock_mutex(rdev->lock);\r
-            return rp_chnl_head;\r
-        }\r
-        rp_chnl_head = rp_chnl_head->next;\r
-    }\r
-    env_unlock_mutex(rdev->lock);\r
-\r
-    return RPMSG_NULL ;\r
-}\r
-\r
-/**\r
- * rpmsg_rdev_get_chnl_from_addr\r
- *\r
- * This function returns channel node based on src/dst address.\r
- *\r
- * @param rdev - pointer remote device control block\r
- * @param addr - src/dst address\r
- *\r
- * @return - channel node\r
- *\r
- */\r
-struct llist *rpmsg_rdev_get_chnl_from_addr(struct remote_device *rdev,\r
-                unsigned long addr) {\r
-    struct rpmsg_channel *rp_chnl;\r
-    struct llist *rp_chnl_head;\r
-\r
-    rp_chnl_head = rdev->rp_channels;\r
-\r
-    env_lock_mutex(rdev->lock);\r
-    while (rp_chnl_head) {\r
-        rp_chnl = (struct rpmsg_channel *) rp_chnl_head->data;\r
-        if ((rp_chnl->src == addr) || (rp_chnl->dst == addr)) {\r
-            env_unlock_mutex(rdev->lock);\r
-            return rp_chnl_head;\r
-        }\r
-        rp_chnl_head = rp_chnl_head->next;\r
-    }\r
-    env_unlock_mutex(rdev->lock);\r
-\r
-    return RPMSG_NULL ;\r
-}\r
-\r
-/**\r
- * rpmsg_rdev_get_endpoint_from_addr\r
- *\r
- * This function returns endpoint node based on src address.\r
- *\r
- * @param rdev - pointer remote device control block\r
- * @param addr - src address\r
- *\r
- * @return - endpoint node\r
- *\r
- */\r
-struct llist *rpmsg_rdev_get_endpoint_from_addr(struct remote_device *rdev,\r
-                unsigned long addr) {\r
-    struct llist *rp_ept_lut_head;\r
-\r
-    rp_ept_lut_head = rdev->rp_endpoints;\r
-\r
-    env_lock_mutex(rdev->lock);\r
-    while (rp_ept_lut_head) {\r
-        struct rpmsg_endpoint *rp_ept =\r
-                        (struct rpmsg_endpoint *) rp_ept_lut_head->data;\r
-        if (rp_ept->addr == addr) {\r
-            env_unlock_mutex(rdev->lock);\r
-            return rp_ept_lut_head;\r
-        }\r
-        rp_ept_lut_head = rp_ept_lut_head->next;\r
-    }\r
-    env_unlock_mutex(rdev->lock);\r
-\r
-    return RPMSG_NULL ;\r
-}\r
-/*\r
- * rpmsg_rdev_notify\r
- *\r
- * This function checks whether remote device is up or not. If it is up then\r
- * notification is sent based on device role to start IPC.\r
- *\r
- * @param rdev - pointer to remote device\r
- *\r
- * @return - status of function execution\r
- *\r
- */\r
-int rpmsg_rdev_notify(struct remote_device *rdev) {\r
-    int status = RPMSG_SUCCESS;\r
-\r
-    if (rdev->role == RPMSG_REMOTE) {\r
-        status = hil_get_status(rdev->proc);\r
-\r
-        /*\r
-         * Let the remote device know that Master is ready for\r
-         * communication.\r
-         */\r
-        if (!status)\r
-            virtqueue_kick(rdev->rvq);\r
-\r
-    } else {\r
-            status = hil_set_status(rdev->proc);\r
-    }\r
-\r
-    if (status == RPMSG_SUCCESS) {\r
-        rdev->state = RPMSG_DEV_STATE_ACTIVE;\r
-    }\r
-\r
-    return status;\r
-}\r
-/**\r
- * rpmsg_rdev_init_channels\r
- *\r
- * This function is only applicable to RPMSG remote. It obtains channel IDs\r
- * from the HIL and creates RPMSG channels corresponding to each ID.\r
- *\r
- * @param rdev - pointer to remote device\r
- *\r
- * @return  - status of function execution\r
- *\r
- */\r
-int rpmsg_rdev_init_channels(struct remote_device *rdev) {\r
-    struct rpmsg_channel *rp_chnl;\r
-    struct proc_chnl *chnl_info;\r
-    int num_chnls, idx;\r
-\r
-    if (rdev->role == RPMSG_MASTER) {\r
-\r
-        chnl_info = hil_get_chnl_info(rdev->proc, &num_chnls);\r
-        for (idx = 0; idx < num_chnls; idx++) {\r
-\r
-            rp_chnl = _rpmsg_create_channel(rdev, chnl_info[idx].name, 0x00,\r
-                           RPMSG_NS_EPT_ADDR);\r
-            if (!rp_chnl) {\r
-                return RPMSG_ERR_NO_MEM;\r
-            }\r
-\r
-            rp_chnl->rp_ept = rpmsg_create_ept(rp_chnl, rdev->default_cb, rdev,\r
-                            RPMSG_ADDR_ANY);\r
-\r
-            if (!rp_chnl->rp_ept) {\r
-                return RPMSG_ERR_NO_MEM;\r
-            }\r
-\r
-            rp_chnl->src = rp_chnl->rp_ept->addr;\r
-        }\r
-    }\r
-\r
-    return RPMSG_SUCCESS;\r
-}\r
-\r
-/**\r
- *------------------------------------------------------------------------\r
- * The rest of the file implements the virtio device interface as defined\r
- * by the virtio.h file.\r
- *------------------------------------------------------------------------\r
- */\r
-int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,\r
-                const char *names[], vq_callback *callbacks[],\r
-                struct virtqueue *vqs_[]) {\r
-    struct remote_device *rdev;\r
-    struct vring_alloc_info ring_info;\r
-    struct virtqueue *vqs[RPMSG_MAX_VQ_PER_RDEV];\r
-    struct proc_vring *vring_table;\r
-    void *buffer;\r
-    struct llist node;\r
-    int idx, num_vrings, status;\r
-\r
-    rdev = (struct remote_device*) dev;\r
-\r
-    /* Get the vring HW info for the given virtio device */\r
-    vring_table = hil_get_vring_info(&rdev->proc->vdev,\r
-                    &num_vrings);\r
-\r
-    if (num_vrings > nvqs) {\r
-        return RPMSG_ERR_MAX_VQ;\r
-    }\r
-\r
-    /* Create virtqueue for each vring. */\r
-    for (idx = 0; idx < num_vrings; idx++) {\r
-\r
-        INIT_VRING_ALLOC_INFO( ring_info, vring_table[idx]);\r
-\r
-        if (rdev->role == RPMSG_REMOTE) {\r
-            env_memset((void*) ring_info.phy_addr, 0x00,\r
-                            vring_size(vring_table[idx].num_descs,\r
-                                            vring_table[idx].align));\r
-        }\r
-\r
-        status = virtqueue_create(dev, idx, (char *) names[idx], &ring_info,\r
-                        callbacks[idx], hil_vring_notify,\r
-                        &vqs[idx]);\r
-\r
-        if (status != RPMSG_SUCCESS) {\r
-            return status;\r
-        }\r
-    }\r
-\r
-    //FIXME - a better way to handle this , tx for master is rx for remote and vice versa.\r
-    if (rdev->role == RPMSG_MASTER) {\r
-        rdev->tvq = vqs[0];\r
-        rdev->rvq = vqs[1];\r
-    } else {\r
-        rdev->tvq = vqs[1];\r
-        rdev->rvq = vqs[0];\r
-    }\r
-\r
-    if (rdev->role == RPMSG_REMOTE) {\r
-        for (idx = 0; ((idx < rdev->rvq->vq_nentries)\r
-                        && (idx < rdev->mem_pool->total_buffs / 2));\r
-                        idx++) {\r
-\r
-            /* Initialize TX virtqueue buffers for remote device */\r
-            buffer = sh_mem_get_buffer(rdev->mem_pool);\r
-\r
-            if (!buffer) {\r
-                return RPMSG_ERR_NO_BUFF;\r
-            }\r
-\r
-            node.data = buffer;\r
-            node.attr = RPMSG_BUFFER_SIZE;\r
-            node.next = RPMSG_NULL;\r
-\r
-            env_memset(buffer, 0x00, RPMSG_BUFFER_SIZE);\r
-            status = virtqueue_add_buffer(rdev->rvq, &node, 0, 1, buffer);\r
-\r
-            if (status != RPMSG_SUCCESS) {\r
-                return status;\r
-            }\r
-        }\r
-    }\r
-\r
-    return RPMSG_SUCCESS;\r
-}\r
-\r
-unsigned char rpmsg_rdev_get_status(struct virtio_device *dev) {\r
-    return 0;\r
-}\r
-\r
-void rpmsg_rdev_set_status(struct virtio_device *dev, unsigned char status) {\r
-\r
-}\r
-\r
-uint32_t rpmsg_rdev_get_feature(struct virtio_device *dev) {\r
-    return dev->features;\r
-}\r
-\r
-void rpmsg_rdev_set_feature(struct virtio_device *dev, uint32_t feature) {\r
-    dev->features |= feature;\r
-}\r
-\r
-uint32_t rpmsg_rdev_negotiate_feature(struct virtio_device *dev,\r
-                uint32_t features) {\r
-    return 0;\r
-}\r
-/*\r
- * Read/write a variable amount from the device specific (ie, network)\r
- * configuration region. This region is encoded in the same endian as\r
- * the guest.\r
- */\r
-void rpmsg_rdev_read_config(struct virtio_device *dev, uint32_t offset,\r
-                void *dst, int length) {\r
-    return;\r
-}\r
-void rpmsg_rdev_write_config(struct virtio_device *dev, uint32_t offset,\r
-                void *src, int length) {\r
-    return;\r
-}\r
-void rpmsg_rdev_reset(struct virtio_device *dev) {\r
-    return;\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ * Copyright (c) 2015 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       remote_device.c
+ *
+ * COMPONENT
+ *
+ *       OpenAMP Stack
+ *
+ * DESCRIPTION
+ *
+ * This file provides services to manage the remote devices.It also implements
+ * the interface defined by the virtio and provides few other utility functions.
+ *
+ *
+ **************************************************************************/
+
+#include "rpmsg.h"
+
+/* Macro to initialize vring HW info */
+#define INIT_VRING_ALLOC_INFO(ring_info,vring_hw)                             \
+                         (ring_info).phy_addr  = (vring_hw).phy_addr;         \
+                         (ring_info).align     = (vring_hw).align;             \
+                         (ring_info).num_descs = (vring_hw).num_descs
+
+/* Local functions */
+static int rpmsg_rdev_init_channels(struct remote_device *rdev);
+
+/* Ops table for virtio device */
+virtio_dispatch rpmsg_rdev_config_ops =
+{
+    rpmsg_rdev_create_virtqueues,
+    rpmsg_rdev_get_status,
+    rpmsg_rdev_set_status,
+    rpmsg_rdev_get_feature,
+    rpmsg_rdev_set_feature,
+    rpmsg_rdev_negotiate_feature,
+    rpmsg_rdev_read_config,
+    rpmsg_rdev_write_config,
+    rpmsg_rdev_reset
+};
+
+/**
+ * rpmsg_rdev_init
+ *
+ * This function creates and initializes the remote device. The remote device
+ * encapsulates virtio device.
+ *
+ * @param rdev              - pointer to newly created remote device
+ * @param dev-id            - ID of device to create , remote cpu id
+ * @param role              - role of the other device, Master or Remote
+ * @param channel_created   - callback function for channel creation
+ * @param channel_destroyed - callback function for channel deletion
+ * @param default_cb        - default callback for channel
+ *
+ * @return - status of function execution
+ *
+ */
+int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,
+                rpmsg_chnl_cb_t channel_created,
+                rpmsg_chnl_cb_t channel_destroyed,
+                rpmsg_rx_cb_t default_cb) {
+
+    struct remote_device *rdev_loc;
+    struct virtio_device *virt_dev;
+    struct hil_proc *proc;
+    struct proc_shm *shm;
+    int status;
+
+    /* Initialize HIL data structures for given device */
+    proc = hil_create_proc(dev_id);
+
+    if (!proc) {
+        return RPMSG_ERR_DEV_ID;
+    }
+
+    /* Create software representation of remote processor. */
+    rdev_loc = (struct remote_device *) env_allocate_memory(
+                    sizeof(struct remote_device));
+
+    if (!rdev_loc) {
+        return RPMSG_ERR_NO_MEM;
+    }
+
+    env_memset(rdev_loc, 0x00, sizeof(struct remote_device));
+    status = env_create_mutex(&rdev_loc->lock, 1);
+
+    if (status != RPMSG_SUCCESS) {
+
+        /* Cleanup required in case of error is performed by caller */
+        return status;
+    }
+
+    rdev_loc->proc = proc;
+    rdev_loc->role = role;
+    rdev_loc->channel_created = channel_created;
+    rdev_loc->channel_destroyed = channel_destroyed;
+    rdev_loc->default_cb = default_cb;
+
+    /* Initialize the virtio device */
+    virt_dev = &rdev_loc->virt_dev;
+    virt_dev->device = proc;
+    virt_dev->func = &rpmsg_rdev_config_ops;
+    if (virt_dev->func->set_features != RPMSG_NULL) {
+        virt_dev->func->set_features(virt_dev, proc->vdev.dfeatures);
+    }
+
+    if (rdev_loc->role == RPMSG_REMOTE) {
+        /*
+         * Since device is RPMSG Remote so we need to manage the
+         * shared buffers. Create shared memory pool to handle buffers.
+         */
+        shm = hil_get_shm_info(proc);
+        rdev_loc->mem_pool = sh_mem_create_pool(shm->start_addr, shm->size,
+                        RPMSG_BUFFER_SIZE);
+
+        if (!rdev_loc->mem_pool) {
+            return RPMSG_ERR_NO_MEM;
+        }
+    }
+
+    /* Initialize channels for RPMSG Remote */
+    status = rpmsg_rdev_init_channels(rdev_loc);
+
+    if (status != RPMSG_SUCCESS) {
+        return status;
+    }
+
+    *rdev = rdev_loc;
+
+    return RPMSG_SUCCESS;
+}
+
+/**
+ * rpmsg_rdev_deinit
+ *
+ * This function un-initializes the remote device.
+ *
+ * @param rdev - pointer to remote device to deinit.
+ *
+ * @return - none
+ *
+ */
+void rpmsg_rdev_deinit(struct remote_device *rdev) {
+    struct llist *rp_chnl_head, *rp_chnl_temp, *node;
+    struct rpmsg_channel *rp_chnl;
+
+    rp_chnl_head = rdev->rp_channels;
+
+    while (rp_chnl_head != RPMSG_NULL ) {
+
+        rp_chnl_temp = rp_chnl_head->next;
+        rp_chnl = (struct rpmsg_channel *) rp_chnl_head->data;
+
+        if (rdev->channel_destroyed) {
+            rdev->channel_destroyed(rp_chnl);
+        }
+
+        if ((rdev->support_ns) && (rdev->role == RPMSG_MASTER)) {
+            rpmsg_send_ns_message(rdev, rp_chnl, RPMSG_NS_DESTROY);
+        }
+
+        /* Delete default endpoint for channel */
+        if (rp_chnl->rp_ept) {
+            rpmsg_destroy_ept(rp_chnl->rp_ept);
+        }
+
+        _rpmsg_delete_channel(rp_chnl);
+        rp_chnl_head = rp_chnl_temp;
+    }
+
+    /* Delete name service endpoint */
+    node = rpmsg_rdev_get_endpoint_from_addr(rdev,RPMSG_NS_EPT_ADDR);
+    if (node) {
+        _destroy_endpoint(rdev, (struct rpmsg_endpoint *) node->data);
+    }
+
+    if (rdev->rvq) {
+        virtqueue_free(rdev->rvq);
+    }
+    if (rdev->tvq) {
+        virtqueue_free(rdev->tvq);
+    }
+    if (rdev->mem_pool) {
+        sh_mem_delete_pool(rdev->mem_pool);
+    }
+    if (rdev->lock) {
+        env_delete_mutex(rdev->lock);
+    }
+
+    env_free_memory(rdev);
+}
+
+/**
+ * rpmsg_rdev_get_chnl_node_from_id
+ *
+ * This function returns channel node based on channel name.
+ *
+ * @param stack      - pointer to remote device
+ * @param rp_chnl_id - rpmsg channel name
+ *
+ * @return - channel node
+ *
+ */
+struct llist *rpmsg_rdev_get_chnl_node_from_id(struct remote_device *rdev,
+                char *rp_chnl_id) {
+    struct rpmsg_channel *rp_chnl;
+    struct llist *rp_chnl_head;
+
+    rp_chnl_head = rdev->rp_channels;
+
+    env_lock_mutex(rdev->lock);
+    while (rp_chnl_head) {
+        rp_chnl = (struct rpmsg_channel *) rp_chnl_head->data;
+        if (env_strncmp(rp_chnl->name, rp_chnl_id, sizeof(rp_chnl->name))
+                        == 0) {
+            env_unlock_mutex(rdev->lock);
+            return rp_chnl_head;
+        }
+        rp_chnl_head = rp_chnl_head->next;
+    }
+    env_unlock_mutex(rdev->lock);
+
+    return RPMSG_NULL ;
+}
+
+/**
+ * rpmsg_rdev_get_chnl_from_addr
+ *
+ * This function returns channel node based on src/dst address.
+ *
+ * @param rdev - pointer remote device control block
+ * @param addr - src/dst address
+ *
+ * @return - channel node
+ *
+ */
+struct llist *rpmsg_rdev_get_chnl_from_addr(struct remote_device *rdev,
+                unsigned long addr) {
+    struct rpmsg_channel *rp_chnl;
+    struct llist *rp_chnl_head;
+
+    rp_chnl_head = rdev->rp_channels;
+
+    env_lock_mutex(rdev->lock);
+    while (rp_chnl_head) {
+        rp_chnl = (struct rpmsg_channel *) rp_chnl_head->data;
+        if ((rp_chnl->src == addr) || (rp_chnl->dst == addr)) {
+            env_unlock_mutex(rdev->lock);
+            return rp_chnl_head;
+        }
+        rp_chnl_head = rp_chnl_head->next;
+    }
+    env_unlock_mutex(rdev->lock);
+
+    return RPMSG_NULL ;
+}
+
+/**
+ * rpmsg_rdev_get_endpoint_from_addr
+ *
+ * This function returns endpoint node based on src address.
+ *
+ * @param rdev - pointer remote device control block
+ * @param addr - src address
+ *
+ * @return - endpoint node
+ *
+ */
+struct llist *rpmsg_rdev_get_endpoint_from_addr(struct remote_device *rdev,
+                unsigned long addr) {
+    struct llist *rp_ept_lut_head;
+
+    rp_ept_lut_head = rdev->rp_endpoints;
+
+    env_lock_mutex(rdev->lock);
+    while (rp_ept_lut_head) {
+        struct rpmsg_endpoint *rp_ept =
+                        (struct rpmsg_endpoint *) rp_ept_lut_head->data;
+        if (rp_ept->addr == addr) {
+            env_unlock_mutex(rdev->lock);
+            return rp_ept_lut_head;
+        }
+        rp_ept_lut_head = rp_ept_lut_head->next;
+    }
+    env_unlock_mutex(rdev->lock);
+
+    return RPMSG_NULL ;
+}
+/*
+ * rpmsg_rdev_notify
+ *
+ * This function checks whether remote device is up or not. If it is up then
+ * notification is sent based on device role to start IPC.
+ *
+ * @param rdev - pointer to remote device
+ *
+ * @return - status of function execution
+ *
+ */
+int rpmsg_rdev_notify(struct remote_device *rdev) {
+    int status = RPMSG_SUCCESS;
+
+    if (rdev->role == RPMSG_REMOTE) {
+        status = hil_get_status(rdev->proc);
+
+        /*
+         * Let the remote device know that Master is ready for
+         * communication.
+         */
+        if (!status)
+            virtqueue_kick(rdev->rvq);
+
+    } else {
+            status = hil_set_status(rdev->proc);
+    }
+
+    if (status == RPMSG_SUCCESS) {
+        rdev->state = RPMSG_DEV_STATE_ACTIVE;
+    }
+
+    return status;
+}
+/**
+ * rpmsg_rdev_init_channels
+ *
+ * This function is only applicable to RPMSG remote. It obtains channel IDs
+ * from the HIL and creates RPMSG channels corresponding to each ID.
+ *
+ * @param rdev - pointer to remote device
+ *
+ * @return  - status of function execution
+ *
+ */
+int rpmsg_rdev_init_channels(struct remote_device *rdev) {
+    struct rpmsg_channel *rp_chnl;
+    struct proc_chnl *chnl_info;
+    int num_chnls, idx;
+
+    if (rdev->role == RPMSG_MASTER) {
+
+        chnl_info = hil_get_chnl_info(rdev->proc, &num_chnls);
+        for (idx = 0; idx < num_chnls; idx++) {
+
+            rp_chnl = _rpmsg_create_channel(rdev, chnl_info[idx].name, 0x00,
+                           RPMSG_NS_EPT_ADDR);
+            if (!rp_chnl) {
+                return RPMSG_ERR_NO_MEM;
+            }
+
+            rp_chnl->rp_ept = rpmsg_create_ept(rp_chnl, rdev->default_cb, rdev,
+                            RPMSG_ADDR_ANY);
+
+            if (!rp_chnl->rp_ept) {
+                return RPMSG_ERR_NO_MEM;
+            }
+
+            rp_chnl->src = rp_chnl->rp_ept->addr;
+        }
+    }
+
+    return RPMSG_SUCCESS;
+}
+
+/**
+ *------------------------------------------------------------------------
+ * The rest of the file implements the virtio device interface as defined
+ * by the virtio.h file.
+ *------------------------------------------------------------------------
+ */
+int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
+                const char *names[], vq_callback *callbacks[],
+                struct virtqueue *vqs_[]) {
+    struct remote_device *rdev;
+    struct vring_alloc_info ring_info;
+    struct virtqueue *vqs[RPMSG_MAX_VQ_PER_RDEV];
+    struct proc_vring *vring_table;
+    void *buffer;
+    struct llist node;
+    int idx, num_vrings, status;
+
+    rdev = (struct remote_device*) dev;
+
+    /* Get the vring HW info for the given virtio device */
+    vring_table = hil_get_vring_info(&rdev->proc->vdev,
+                    &num_vrings);
+
+    if (num_vrings > nvqs) {
+        return RPMSG_ERR_MAX_VQ;
+    }
+
+    /* Create virtqueue for each vring. */
+    for (idx = 0; idx < num_vrings; idx++) {
+
+        INIT_VRING_ALLOC_INFO( ring_info, vring_table[idx]);
+
+        if (rdev->role == RPMSG_REMOTE) {
+            env_memset((void*) ring_info.phy_addr, 0x00,
+                            vring_size(vring_table[idx].num_descs,
+                                            vring_table[idx].align));
+        }
+
+        status = virtqueue_create(dev, idx, (char *) names[idx], &ring_info,
+                        callbacks[idx], hil_vring_notify,
+                        &vqs[idx]);
+
+        if (status != RPMSG_SUCCESS) {
+            return status;
+        }
+    }
+
+    //FIXME - a better way to handle this , tx for master is rx for remote and vice versa.
+    if (rdev->role == RPMSG_MASTER) {
+        rdev->tvq = vqs[0];
+        rdev->rvq = vqs[1];
+    } else {
+        rdev->tvq = vqs[1];
+        rdev->rvq = vqs[0];
+    }
+
+    if (rdev->role == RPMSG_REMOTE) {
+        for (idx = 0; ((idx < rdev->rvq->vq_nentries)
+                        && (idx < rdev->mem_pool->total_buffs / 2));
+                        idx++) {
+
+            /* Initialize TX virtqueue buffers for remote device */
+            buffer = sh_mem_get_buffer(rdev->mem_pool);
+
+            if (!buffer) {
+                return RPMSG_ERR_NO_BUFF;
+            }
+
+            node.data = buffer;
+            node.attr = RPMSG_BUFFER_SIZE;
+            node.next = RPMSG_NULL;
+
+            env_memset(buffer, 0x00, RPMSG_BUFFER_SIZE);
+            status = virtqueue_add_buffer(rdev->rvq, &node, 0, 1, buffer);
+
+            if (status != RPMSG_SUCCESS) {
+                return status;
+            }
+        }
+    }
+
+    return RPMSG_SUCCESS;
+}
+
+unsigned char rpmsg_rdev_get_status(struct virtio_device *dev) {
+    return 0;
+}
+
+void rpmsg_rdev_set_status(struct virtio_device *dev, unsigned char status) {
+
+}
+
+uint32_t rpmsg_rdev_get_feature(struct virtio_device *dev) {
+    return dev->features;
+}
+
+void rpmsg_rdev_set_feature(struct virtio_device *dev, uint32_t feature) {
+    dev->features |= feature;
+}
+
+uint32_t rpmsg_rdev_negotiate_feature(struct virtio_device *dev,
+                uint32_t features) {
+    return 0;
+}
+/*
+ * Read/write a variable amount from the device specific (ie, network)
+ * configuration region. This region is encoded in the same endian as
+ * the guest.
+ */
+void rpmsg_rdev_read_config(struct virtio_device *dev, uint32_t offset,
+                void *dst, int length) {
+    return;
+}
+void rpmsg_rdev_write_config(struct virtio_device *dev, uint32_t offset,
+                void *src, int length) {
+    return;
+}
+void rpmsg_rdev_reset(struct virtio_device *dev) {
+    return;
+}
index 630f110b49b37f87e06debabd3f60261d0154671..0066fca02d08e53c7cbed1a0f35302b85e2d5c40 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/**************************************************************************\r
- * FILE NAME\r
- *\r
- *       rpmsg.c\r
- *\r
- * COMPONENT\r
- *\r
- *       OpenAMP stack.\r
- *\r
- * DESCRIPTION\r
- *\r
- * Main file for the RPMSG driver. This file implements APIs as defined by\r
- * RPMSG documentation(Linux docs) and also provides some utility functions.\r
- *\r
- * RPMSG driver represents each processor/core to which it communicates with\r
- * remote_device control block.\r
- * Each remote device(processor) defines its role in the communication i.e\r
- * whether it is RPMSG Master or Remote. If the device(processor) to which\r
- * driver is talking is RPMSG master then RPMSG driver implicitly behaves as\r
- * Remote and vice versa.\r
- * RPMSG Master is responsible for initiating communications with the Remote\r
- * and shared buffers management. Terms remote device/core/proc are used\r
- * interchangeably for the processor to which RPMSG driver is communicating\r
- * irrespective of the fact whether it is RPMSG Remote or Master.\r
- *\r
- **************************************************************************/\r
-#include "rpmsg.h"\r
-\r
-/**\r
- * rpmsg_init\r
- *\r
- * Thus function allocates and initializes the rpmsg driver resources for\r
- * given device ID(cpu id). The successful return from this function leaves\r
- * fully enabled IPC link.\r
- *\r
- * @param dev_id            - remote device for which driver is to\r
- *                            be initialized\r
- * @param rdev              - pointer to newly created remote device\r
- * @param channel_created   - callback function for channel creation\r
- * @param channel_destroyed - callback function for channel deletion\r
- * @param default_cb        - default callback for channel I/O\r
- * @param role              - role of the other device, Master or Remote\r
- *\r
- * @return - status of function execution\r
- *\r
- */\r
-\r
-int rpmsg_init(int dev_id, struct remote_device **rdev,\r
-                rpmsg_chnl_cb_t channel_created,\r
-                rpmsg_chnl_cb_t channel_destroyed,\r
-                rpmsg_rx_cb_t default_cb, int role) {\r
-    int status;\r
-\r
-    /* Initialize IPC environment */\r
-    status = env_init();\r
-    if (status == RPMSG_SUCCESS) {\r
-        /* Initialize the remote device for given cpu id */\r
-        status = rpmsg_rdev_init(rdev, dev_id, role, channel_created,\r
-                        channel_destroyed, default_cb);\r
-        if (status == RPMSG_SUCCESS) {\r
-            /* Kick off IPC with the remote device */\r
-            status = rpmsg_start_ipc(*rdev);\r
-        }\r
-    }\r
-\r
-    /* Deinit system in case of error */\r
-    if (status != RPMSG_SUCCESS) {\r
-        rpmsg_deinit(*rdev);\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/**\r
- * rpmsg_deinit\r
- *\r
- * Thus function frees rpmsg driver resources for given remote device.\r
- *\r
- * @param rdev  -  pointer to device to de-init\r
- *\r
- */\r
-\r
-void rpmsg_deinit(struct remote_device *rdev) {\r
-    if (rdev) {\r
-        rpmsg_rdev_deinit(rdev);\r
-        env_deinit();\r
-    }\r
-}\r
-\r
-/**\r
- * This function sends rpmsg "message" to remote device.\r
- *\r
- * @param rp_chnl - pointer to rpmsg channel\r
- * @param src     - source address of channel\r
- * @param dst     - destination address of channel\r
- * @param data    - data to transmit\r
- * @param size    - size of data\r
- * @param wait    - boolean, wait or not for buffer to become\r
- *                  available\r
- *\r
- * @return - status of function execution\r
- *\r
- */\r
-\r
-int rpmsg_send_offchannel_raw(struct rpmsg_channel *rp_chnl, unsigned long src,\r
-                unsigned long dst, char *data, int size, int wait) {\r
-    struct remote_device *rdev;\r
-    struct rpmsg_hdr *rp_hdr;\r
-    void *buffer;\r
-    int status = RPMSG_SUCCESS;\r
-    unsigned short idx;\r
-    int tick_count = 0;\r
-    unsigned long buff_len;\r
-\r
-    if (!rp_chnl) {\r
-        return RPMSG_ERR_PARAM;\r
-    }\r
-\r
-    /* Get the associated remote device for channel. */\r
-    rdev = rp_chnl->rdev;\r
-\r
-    /* Validate device state */\r
-    if (rp_chnl->state != RPMSG_CHNL_STATE_ACTIVE\r
-                    || rdev->state != RPMSG_DEV_STATE_ACTIVE) {\r
-        return RPMSG_ERR_DEV_STATE;\r
-    }\r
-\r
-    /* Lock the device to enable exclusive access to virtqueues */\r
-    env_lock_mutex(rdev->lock);\r
-    /* Get rpmsg buffer for sending message. */\r
-    buffer = rpmsg_get_tx_buffer(rdev, &buff_len, &idx);\r
-    if (!buffer && !wait) {\r
-        status = RPMSG_ERR_NO_MEM;\r
-    }\r
-    env_unlock_mutex(rdev->lock);\r
-\r
-    if (status == RPMSG_SUCCESS) {\r
-\r
-        while (!buffer) {\r
-            /*\r
-             * Wait parameter is true - pool the buffer for\r
-             * 15 secs as defined by the APIs.\r
-             */\r
-            env_sleep_msec(RPMSG_TICKS_PER_INTERVAL);\r
-            env_lock_mutex(rdev->lock);\r
-            buffer = rpmsg_get_tx_buffer(rdev, &buff_len, &idx);\r
-            env_unlock_mutex(rdev->lock);\r
-            tick_count += RPMSG_TICKS_PER_INTERVAL;\r
-            if (tick_count >= (RPMSG_TICK_COUNT / RPMSG_TICKS_PER_INTERVAL)) {\r
-                status = RPMSG_ERR_NO_BUFF;\r
-                break;\r
-            }\r
-        }\r
-\r
-        if (status == RPMSG_SUCCESS) {\r
-            //FIXME : may be just copy the data size equal to buffer length and Tx it.\r
-            if (size > (buff_len - sizeof(struct rpmsg_hdr)))\r
-                status = RPMSG_ERR_BUFF_SIZE;\r
-\r
-            if (status == RPMSG_SUCCESS) {\r
-                rp_hdr = (struct rpmsg_hdr *) buffer;\r
-\r
-                /* Initialize RPMSG header. */\r
-                rp_hdr->dst = dst;\r
-                rp_hdr->src = src;\r
-                rp_hdr->len = size;\r
-\r
-                /* Copy data to rpmsg buffer. */\r
-                env_memcpy(rp_hdr->data, data, size);\r
-\r
-                env_lock_mutex(rdev->lock);\r
-                /* Enqueue buffer on virtqueue. */\r
-                status = rpmsg_enqueue_buffer(rdev, buffer, buff_len, idx);\r
-                if (status == RPMSG_SUCCESS) {\r
-                    /* Let the other side know that there is a job to process. */\r
-                    virtqueue_kick(rdev->tvq);\r
-                }\r
-                env_unlock_mutex(rdev->lock);\r
-            }\r
-\r
-        }\r
-    }\r
-\r
-    /* Do cleanup in case of error.*/\r
-    if (status != RPMSG_SUCCESS) {\r
-        rpmsg_free_buffer(rdev, buffer);\r
-    }\r
-\r
-    return status;\r
-}\r
-\r
-/**\r
- * rpmsg_get_buffer_size\r
- *\r
- * Returns buffer size available for sending messages.\r
- *\r
- * @param channel - pointer to rpmsg channel\r
- *\r
- * @return - buffer size\r
- *\r
- */\r
-int rpmsg_get_buffer_size(struct rpmsg_channel *rp_chnl) {\r
-    struct remote_device *rdev;\r
-    int length;\r
-\r
-    if (!rp_chnl) {\r
-        return RPMSG_ERR_PARAM;\r
-    }\r
-\r
-    /* Get associated remote device for channel. */\r
-    rdev = rp_chnl->rdev;\r
-\r
-    /* Validate device state */\r
-    if (rp_chnl->state != RPMSG_CHNL_STATE_ACTIVE\r
-                    || rdev->state != RPMSG_DEV_STATE_ACTIVE) {\r
-        return RPMSG_ERR_DEV_STATE;\r
-    }\r
-\r
-    env_lock_mutex(rdev->lock);\r
-\r
-    if (rdev->role == RPMSG_REMOTE) {\r
-        /*\r
-         * If device role is Remote then buffers are provided by us\r
-         * (RPMSG Master), so just provide the macro.\r
-         */\r
-        length = RPMSG_BUFFER_SIZE - sizeof(struct rpmsg_hdr);\r
-    } else {\r
-        /*\r
-         * If other core is Master then buffers are provided by it,\r
-         * so get the buffer size from the virtqueue.\r
-         */\r
-        length = (int) virtqueue_get_desc_size(rdev->tvq) - sizeof(struct rpmsg_hdr);\r
-    }\r
-\r
-    env_unlock_mutex(rdev->lock);\r
-\r
-    return length;\r
-}\r
-\r
-/**\r
- * rpmsg_create_ept\r
- *\r
- * This function creates rpmsg endpoint for the rpmsg channel.\r
- *\r
- * @param channel - pointer to rpmsg channel\r
- * @param cb      - Rx completion call back\r
- * @param priv    - private data\r
- * @param addr    - endpoint src address\r
- *\r
- * @return - pointer to endpoint control block\r
- *\r
- */\r
-struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rp_chnl,\r
-                rpmsg_rx_cb_t cb, void *priv, unsigned long addr) {\r
-\r
-    struct remote_device *rdev = RPMSG_NULL;\r
-    struct rpmsg_endpoint *rp_ept = RPMSG_NULL;\r
-\r
-    if (!rp_chnl || !cb) {\r
-        return RPMSG_NULL ;\r
-    }\r
-\r
-    rdev = rp_chnl->rdev;\r
-\r
-    rp_ept = _create_endpoint(rdev, cb, priv, addr);\r
-\r
-    if (rp_ept) {\r
-        rp_ept->rp_chnl = rp_chnl;\r
-    }\r
-\r
-    return rp_ept;\r
-}\r
-\r
-/**\r
- * rpmsg_destroy_ept\r
- *\r
- * This function deletes rpmsg endpoint and performs cleanup.\r
- *\r
- * @param rp_ept - pointer to endpoint to destroy\r
- *\r
- */\r
-void rpmsg_destroy_ept(struct rpmsg_endpoint *rp_ept) {\r
-\r
-    struct remote_device *rdev;\r
-    struct rpmsg_channel *rp_chnl;\r
-\r
-    if (!rp_ept)\r
-        return;\r
-\r
-    rp_chnl = rp_ept->rp_chnl;\r
-    rdev = rp_chnl->rdev;\r
-\r
-    _destroy_endpoint(rdev, rp_ept);\r
-}\r
-\r
-/**\r
- * rpmsg_create_channel\r
- *\r
- * This function provides facility to create channel dynamically. It sends\r
- * Name Service announcement to remote device to let it know about the channel\r
- * creation. There must be an active communication among the cores (or atleast\r
- * one rpmsg channel must already exist) before using this API to create new\r
- * channels.\r
- *\r
- * @param rdev - pointer to remote device\r
- * @param name - channel name\r
- *\r
- * @return - pointer to new rpmsg channel\r
- *\r
- */\r
-struct rpmsg_channel *rpmsg_create_channel(struct remote_device *rdev,\r
-                char *name) {\r
-\r
-    struct rpmsg_channel *rp_chnl;\r
-    struct rpmsg_endpoint *rp_ept;\r
-\r
-    if (!rdev || !name) {\r
-        return RPMSG_NULL ;\r
-    }\r
-\r
-    /* Create channel instance */\r
-    rp_chnl = _rpmsg_create_channel(rdev, name, RPMSG_NS_EPT_ADDR,\r
-                    RPMSG_NS_EPT_ADDR);\r
-    if (!rp_chnl) {\r
-        return RPMSG_NULL ;\r
-    }\r
-\r
-    /* Create default endpoint for the channel */\r
-    rp_ept = rpmsg_create_ept(rp_chnl , rdev->default_cb, rdev,\r
-                    RPMSG_ADDR_ANY);\r
-\r
-    if (!rp_ept) {\r
-        _rpmsg_delete_channel(rp_chnl);\r
-        return RPMSG_NULL;\r
-    }\r
-\r
-    rp_chnl->rp_ept = rp_ept;\r
-    rp_chnl->src = rp_ept->addr;\r
-    rp_chnl->state = RPMSG_CHNL_STATE_NS;\r
-\r
-    /* Notify the application of channel creation event */\r
-    if (rdev->channel_created) {\r
-        rdev->channel_created(rp_chnl);\r
-    }\r
-\r
-    /* Send NS announcement to remote processor */\r
-    rpmsg_send_ns_message(rdev, rp_chnl, RPMSG_NS_CREATE);\r
-\r
-    return rp_chnl;\r
-}\r
-\r
-/**\r
- * rpmsg_delete_channel\r
- *\r
- * Deletes the given RPMSG channel. The channel must first be created with the\r
- * rpmsg_create_channel API.\r
- *\r
- * @param rp_chnl - pointer to rpmsg channel to delete\r
- *\r
- */\r
-void rpmsg_delete_channel(struct rpmsg_channel *rp_chnl) {\r
-\r
-    struct remote_device *rdev;\r
-\r
-    if (!rp_chnl) {\r
-        return;\r
-    }\r
-\r
-    rdev = rp_chnl->rdev;\r
-\r
-    if (rp_chnl->state > RPMSG_CHNL_STATE_IDLE) {\r
-        /* Notify the other processor that channel no longer exists */\r
-        rpmsg_send_ns_message(rdev, rp_chnl, RPMSG_NS_DESTROY);\r
-    }\r
-\r
-    /* Notify channel deletion to application */\r
-    if (rdev->channel_destroyed) {\r
-        rdev->channel_destroyed(rp_chnl);\r
-    }\r
-\r
-    rpmsg_destroy_ept(rp_chnl->rp_ept);\r
-    _rpmsg_delete_channel(rp_chnl);\r
-\r
-    return;\r
-}\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       rpmsg.c
+ *
+ * COMPONENT
+ *
+ *       OpenAMP stack.
+ *
+ * DESCRIPTION
+ *
+ * Main file for the RPMSG driver. This file implements APIs as defined by
+ * RPMSG documentation(Linux docs) and also provides some utility functions.
+ *
+ * RPMSG driver represents each processor/core to which it communicates with
+ * remote_device control block.
+ * Each remote device(processor) defines its role in the communication i.e
+ * whether it is RPMSG Master or Remote. If the device(processor) to which
+ * driver is talking is RPMSG master then RPMSG driver implicitly behaves as
+ * Remote and vice versa.
+ * RPMSG Master is responsible for initiating communications with the Remote
+ * and shared buffers management. Terms remote device/core/proc are used
+ * interchangeably for the processor to which RPMSG driver is communicating
+ * irrespective of the fact whether it is RPMSG Remote or Master.
+ *
+ **************************************************************************/
+#include "rpmsg.h"
+
+/**
+ * rpmsg_init
+ *
+ * Thus function allocates and initializes the rpmsg driver resources for
+ * given device ID(cpu id). The successful return from this function leaves
+ * fully enabled IPC link.
+ *
+ * @param dev_id            - remote device for which driver is to
+ *                            be initialized
+ * @param rdev              - pointer to newly created remote device
+ * @param channel_created   - callback function for channel creation
+ * @param channel_destroyed - callback function for channel deletion
+ * @param default_cb        - default callback for channel I/O
+ * @param role              - role of the other device, Master or Remote
+ *
+ * @return - status of function execution
+ *
+ */
+
+int rpmsg_init(int dev_id, struct remote_device **rdev,
+                rpmsg_chnl_cb_t channel_created,
+                rpmsg_chnl_cb_t channel_destroyed,
+                rpmsg_rx_cb_t default_cb, int role) {
+    int status;
+
+    /* Initialize IPC environment */
+    status = env_init();
+    if (status == RPMSG_SUCCESS) {
+        /* Initialize the remote device for given cpu id */
+        status = rpmsg_rdev_init(rdev, dev_id, role, channel_created,
+                        channel_destroyed, default_cb);
+        if (status == RPMSG_SUCCESS) {
+            /* Kick off IPC with the remote device */
+            status = rpmsg_start_ipc(*rdev);
+        }
+    }
+
+    /* Deinit system in case of error */
+    if (status != RPMSG_SUCCESS) {
+        rpmsg_deinit(*rdev);
+    }
+
+    return status;
+}
+
+/**
+ * rpmsg_deinit
+ *
+ * Thus function frees rpmsg driver resources for given remote device.
+ *
+ * @param rdev  -  pointer to device to de-init
+ *
+ */
+
+void rpmsg_deinit(struct remote_device *rdev) {
+    if (rdev) {
+        rpmsg_rdev_deinit(rdev);
+        env_deinit();
+    }
+}
+
+/**
+ * This function sends rpmsg "message" to remote device.
+ *
+ * @param rp_chnl - pointer to rpmsg channel
+ * @param src     - source address of channel
+ * @param dst     - destination address of channel
+ * @param data    - data to transmit
+ * @param size    - size of data
+ * @param wait    - boolean, wait or not for buffer to become
+ *                  available
+ *
+ * @return - status of function execution
+ *
+ */
+
+int rpmsg_send_offchannel_raw(struct rpmsg_channel *rp_chnl, unsigned long src,
+                unsigned long dst, char *data, int size, int wait) {
+    struct remote_device *rdev;
+    struct rpmsg_hdr *rp_hdr;
+    void *buffer;
+    int status = RPMSG_SUCCESS;
+    unsigned short idx;
+    int tick_count = 0;
+    unsigned long buff_len;
+
+    if (!rp_chnl) {
+        return RPMSG_ERR_PARAM;
+    }
+
+    /* Get the associated remote device for channel. */
+    rdev = rp_chnl->rdev;
+
+    /* Validate device state */
+    if (rp_chnl->state != RPMSG_CHNL_STATE_ACTIVE
+                    || rdev->state != RPMSG_DEV_STATE_ACTIVE) {
+        return RPMSG_ERR_DEV_STATE;
+    }
+
+    /* Lock the device to enable exclusive access to virtqueues */
+    env_lock_mutex(rdev->lock);
+    /* Get rpmsg buffer for sending message. */
+    buffer = rpmsg_get_tx_buffer(rdev, &buff_len, &idx);
+    if (!buffer && !wait) {
+        status = RPMSG_ERR_NO_MEM;
+    }
+    env_unlock_mutex(rdev->lock);
+
+    if (status == RPMSG_SUCCESS) {
+
+        while (!buffer) {
+            /*
+             * Wait parameter is true - pool the buffer for
+             * 15 secs as defined by the APIs.
+             */
+            env_sleep_msec(RPMSG_TICKS_PER_INTERVAL);
+            env_lock_mutex(rdev->lock);
+            buffer = rpmsg_get_tx_buffer(rdev, &buff_len, &idx);
+            env_unlock_mutex(rdev->lock);
+            tick_count += RPMSG_TICKS_PER_INTERVAL;
+            if (tick_count >= (RPMSG_TICK_COUNT / RPMSG_TICKS_PER_INTERVAL)) {
+                status = RPMSG_ERR_NO_BUFF;
+                break;
+            }
+        }
+
+        if (status == RPMSG_SUCCESS) {
+            //FIXME : may be just copy the data size equal to buffer length and Tx it.
+            if (size > (buff_len - sizeof(struct rpmsg_hdr)))
+                status = RPMSG_ERR_BUFF_SIZE;
+
+            if (status == RPMSG_SUCCESS) {
+                rp_hdr = (struct rpmsg_hdr *) buffer;
+
+                /* Initialize RPMSG header. */
+                rp_hdr->dst = dst;
+                rp_hdr->src = src;
+                rp_hdr->len = size;
+
+                /* Copy data to rpmsg buffer. */
+                env_memcpy(rp_hdr->data, data, size);
+
+                env_lock_mutex(rdev->lock);
+                /* Enqueue buffer on virtqueue. */
+                status = rpmsg_enqueue_buffer(rdev, buffer, buff_len, idx);
+                if (status == RPMSG_SUCCESS) {
+                    /* Let the other side know that there is a job to process. */
+                    virtqueue_kick(rdev->tvq);
+                }
+                env_unlock_mutex(rdev->lock);
+            }
+
+        }
+    }
+
+    /* Do cleanup in case of error.*/
+    if (status != RPMSG_SUCCESS) {
+        rpmsg_free_buffer(rdev, buffer);
+    }
+
+    return status;
+}
+
+/**
+ * rpmsg_get_buffer_size
+ *
+ * Returns buffer size available for sending messages.
+ *
+ * @param channel - pointer to rpmsg channel
+ *
+ * @return - buffer size
+ *
+ */
+int rpmsg_get_buffer_size(struct rpmsg_channel *rp_chnl) {
+    struct remote_device *rdev;
+    int length;
+
+    if (!rp_chnl) {
+        return RPMSG_ERR_PARAM;
+    }
+
+    /* Get associated remote device for channel. */
+    rdev = rp_chnl->rdev;
+
+    /* Validate device state */
+    if (rp_chnl->state != RPMSG_CHNL_STATE_ACTIVE
+                    || rdev->state != RPMSG_DEV_STATE_ACTIVE) {
+        return RPMSG_ERR_DEV_STATE;
+    }
+
+    env_lock_mutex(rdev->lock);
+
+    if (rdev->role == RPMSG_REMOTE) {
+        /*
+         * If device role is Remote then buffers are provided by us
+         * (RPMSG Master), so just provide the macro.
+         */
+        length = RPMSG_BUFFER_SIZE - sizeof(struct rpmsg_hdr);
+    } else {
+        /*
+         * If other core is Master then buffers are provided by it,
+         * so get the buffer size from the virtqueue.
+         */
+        length = (int) virtqueue_get_desc_size(rdev->tvq) - sizeof(struct rpmsg_hdr);
+    }
+
+    env_unlock_mutex(rdev->lock);
+
+    return length;
+}
+
+/**
+ * rpmsg_create_ept
+ *
+ * This function creates rpmsg endpoint for the rpmsg channel.
+ *
+ * @param channel - pointer to rpmsg channel
+ * @param cb      - Rx completion call back
+ * @param priv    - private data
+ * @param addr    - endpoint src address
+ *
+ * @return - pointer to endpoint control block
+ *
+ */
+struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rp_chnl,
+                rpmsg_rx_cb_t cb, void *priv, unsigned long addr) {
+
+    struct remote_device *rdev = RPMSG_NULL;
+    struct rpmsg_endpoint *rp_ept = RPMSG_NULL;
+
+    if (!rp_chnl || !cb) {
+        return RPMSG_NULL ;
+    }
+
+    rdev = rp_chnl->rdev;
+
+    rp_ept = _create_endpoint(rdev, cb, priv, addr);
+
+    if (rp_ept) {
+        rp_ept->rp_chnl = rp_chnl;
+    }
+
+    return rp_ept;
+}
+
+/**
+ * rpmsg_destroy_ept
+ *
+ * This function deletes rpmsg endpoint and performs cleanup.
+ *
+ * @param rp_ept - pointer to endpoint to destroy
+ *
+ */
+void rpmsg_destroy_ept(struct rpmsg_endpoint *rp_ept) {
+
+    struct remote_device *rdev;
+    struct rpmsg_channel *rp_chnl;
+
+    if (!rp_ept)
+        return;
+
+    rp_chnl = rp_ept->rp_chnl;
+    rdev = rp_chnl->rdev;
+
+    _destroy_endpoint(rdev, rp_ept);
+}
+
+/**
+ * rpmsg_create_channel
+ *
+ * This function provides facility to create channel dynamically. It sends
+ * Name Service announcement to remote device to let it know about the channel
+ * creation. There must be an active communication among the cores (or atleast
+ * one rpmsg channel must already exist) before using this API to create new
+ * channels.
+ *
+ * @param rdev - pointer to remote device
+ * @param name - channel name
+ *
+ * @return - pointer to new rpmsg channel
+ *
+ */
+struct rpmsg_channel *rpmsg_create_channel(struct remote_device *rdev,
+                char *name) {
+
+    struct rpmsg_channel *rp_chnl;
+    struct rpmsg_endpoint *rp_ept;
+
+    if (!rdev || !name) {
+        return RPMSG_NULL ;
+    }
+
+    /* Create channel instance */
+    rp_chnl = _rpmsg_create_channel(rdev, name, RPMSG_NS_EPT_ADDR,
+                    RPMSG_NS_EPT_ADDR);
+    if (!rp_chnl) {
+        return RPMSG_NULL ;
+    }
+
+    /* Create default endpoint for the channel */
+    rp_ept = rpmsg_create_ept(rp_chnl , rdev->default_cb, rdev,
+                    RPMSG_ADDR_ANY);
+
+    if (!rp_ept) {
+        _rpmsg_delete_channel(rp_chnl);
+        return RPMSG_NULL;
+    }
+
+    rp_chnl->rp_ept = rp_ept;
+    rp_chnl->src = rp_ept->addr;
+    rp_chnl->state = RPMSG_CHNL_STATE_NS;
+
+    /* Notify the application of channel creation event */
+    if (rdev->channel_created) {
+        rdev->channel_created(rp_chnl);
+    }
+
+    /* Send NS announcement to remote processor */
+    rpmsg_send_ns_message(rdev, rp_chnl, RPMSG_NS_CREATE);
+
+    return rp_chnl;
+}
+
+/**
+ * rpmsg_delete_channel
+ *
+ * Deletes the given RPMSG channel. The channel must first be created with the
+ * rpmsg_create_channel API.
+ *
+ * @param rp_chnl - pointer to rpmsg channel to delete
+ *
+ */
+void rpmsg_delete_channel(struct rpmsg_channel *rp_chnl) {
+
+    struct remote_device *rdev;
+
+    if (!rp_chnl) {
+        return;
+    }
+
+    rdev = rp_chnl->rdev;
+
+    if (rp_chnl->state > RPMSG_CHNL_STATE_IDLE) {
+        /* Notify the other processor that channel no longer exists */
+        rpmsg_send_ns_message(rdev, rp_chnl, RPMSG_NS_DESTROY);
+    }
+
+    /* Notify channel deletion to application */
+    if (rdev->channel_destroyed) {
+        rdev->channel_destroyed(rp_chnl);
+    }
+
+    rpmsg_destroy_ept(rp_chnl->rp_ept);
+    _rpmsg_delete_channel(rp_chnl);
+
+    return;
+}
index 4586333e1b021b6d8ead20263c51f3bb66225db5..95f4e5605e1b811228d0ce5c45d8133393dd4215 100644 (file)
-/*\r
- * Copyright (c) 2014, Mentor Graphics Corporation\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions are met:\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice,\r
- *    this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright notice,\r
- *    this list of conditions and the following disclaimer in the documentation\r
- *    and/or other materials provided with the distribution.\r
- * 3. Neither the name of Mentor Graphics Corporation nor the names of its\r
- *    contributors may be used to endorse or promote products derived from this\r
- *    software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\r
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
- * POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-\r
-#ifndef _RPMSG_CORE_H_\r
-#define _RPMSG_CORE_H_\r
-\r
-#include "../common/compiler/compiler.h"\r
-#include "../porting/env/env.h"\r
-#include "../virtio/virtio.h"\r
-#include "../common/hil/hil.h"\r
-#include "../common/shm/sh_mem.h"\r
-#include "../common/llist/llist.h"\r
-#include "rpmsg.h"\r
-\r
-/* Configurable parameters */\r
-#define RPMSG_BUFFER_SIZE                       512\r
-#define RPMSG_MAX_VQ_PER_RDEV                   2\r
-#define RPMSG_NS_EPT_ADDR                       0x35\r
-#define RPMSG_ADDR_BMP_SIZE                     4\r
-\r
-/* Definitions for device types , null pointer, etc.*/\r
-#define RPMSG_SUCCESS                           0\r
-#define RPMSG_NULL                              (void *)0\r
-#define RPMSG_REMOTE                            0\r
-#define RPMSG_MASTER                            1\r
-#define RPMSG_TRUE                              1\r
-#define RPMSG_FALSE                             0\r
-\r
-/* RPMSG channel states. */\r
-#define RPMSG_CHNL_STATE_IDLE                   0\r
-#define RPMSG_CHNL_STATE_NS                     1\r
-#define RPMSG_CHNL_STATE_ACTIVE                 2\r
-\r
-/* Remote processor/device states. */\r
-#define RPMSG_DEV_STATE_IDLE                    0\r
-#define RPMSG_DEV_STATE_ACTIVE                  1\r
-\r
-/* Total tick count for 15secs - 1msec tick. */\r
-#define RPMSG_TICK_COUNT                        15000\r
-\r
-/* Time to wait - In multiple of 10 msecs. */\r
-#define RPMSG_TICKS_PER_INTERVAL                10\r
-\r
-/* Error macros. */\r
-#define RPMSG_ERRORS_BASE                       -3000\r
-#define RPMSG_ERR_NO_MEM                        (RPMSG_ERRORS_BASE - 1)\r
-#define RPMSG_ERR_NO_BUFF                       (RPMSG_ERRORS_BASE - 2)\r
-#define RPMSG_ERR_MAX_VQ                        (RPMSG_ERRORS_BASE - 3)\r
-#define RPMSG_ERR_PARAM                         (RPMSG_ERRORS_BASE - 4)\r
-#define RPMSG_ERR_DEV_STATE                     (RPMSG_ERRORS_BASE - 5)\r
-#define RPMSG_ERR_BUFF_SIZE                     (RPMSG_ERRORS_BASE - 6)\r
-#define RPMSG_ERR_DEV_ID                        (RPMSG_ERRORS_BASE - 7)\r
-#define RPMSG_ERR_DEV_ADDR                      (RPMSG_ERRORS_BASE - 8)\r
-\r
-struct rpmsg_channel;\r
-typedef void (*rpmsg_rx_cb_t)(struct rpmsg_channel *, void *, int, void *, unsigned long);\r
-typedef void (*rpmsg_chnl_cb_t)(struct rpmsg_channel *rp_chl);\r
-/**\r
- * remote_device\r
- *\r
- * This structure is maintained by RPMSG driver to represent remote device/core.\r
- *\r
- * @virtd_dev           - virtio device for remote core\r
- * @rvq                 - Rx virtqueue for virtio device\r
- * @tvq                 - Tx virtqueue for virtio device\r
- * @proc                - reference to remote processor\r
- * @rp_channels         - rpmsg channels list for the device\r
- * @rp_endpoints        - rpmsg endpoints list for the device\r
- * @mem_pool            - shared memory pool\r
- * @bitmap              - bitmap for channels addresses\r
- * @channel_created     - create channel callback\r
- * @channel_destroyed   - delete channel callback\r
- * @default_cb          - default callback handler for RX data on channel\r
- * @lock                - remote device mutex\r
- * @role                - role of the remote device, RPMSG_MASTER/RPMSG_REMOTE\r
- * @state               - remote device state, IDLE/ACTIVE\r
- * @support_ns          - if device supports name service announcement\r
- *\r
- */\r
-struct remote_device {\r
-    struct virtio_device virt_dev;\r
-    struct virtqueue *rvq;\r
-    struct virtqueue *tvq;\r
-    struct hil_proc *proc;\r
-    struct llist *rp_channels;\r
-    struct llist *rp_endpoints;\r
-    struct sh_mem_pool *mem_pool;\r
-    unsigned long bitmap[RPMSG_ADDR_BMP_SIZE];\r
-    rpmsg_chnl_cb_t channel_created;\r
-    rpmsg_chnl_cb_t channel_destroyed;\r
-    rpmsg_rx_cb_t default_cb;\r
-    LOCK *lock;\r
-    unsigned int role;\r
-    unsigned int state;\r
-    int support_ns;\r
-};\r
-\r
-/* Core functions */\r
-int rpmsg_start_ipc(struct remote_device *rdev);\r
-struct rpmsg_channel *_rpmsg_create_channel(struct remote_device *rdev,\r
-                char *name, unsigned long src, unsigned long dst);\r
-void _rpmsg_delete_channel(struct rpmsg_channel * rp_chnl);\r
-struct rpmsg_endpoint *_create_endpoint(struct remote_device *rdev,\r
-               rpmsg_rx_cb_t cb, void *priv, unsigned long addr);\r
-void _destroy_endpoint(struct remote_device *rdev,\r
-               struct rpmsg_endpoint *rp_ept);\r
-void rpmsg_send_ns_message(struct remote_device *rdev,\r
-                struct rpmsg_channel *rp_chnl, unsigned long flags);\r
-int rpmsg_enqueue_buffer(struct remote_device *rdev, void *buffer,\r
-                unsigned long len, unsigned short idx);\r
-void rpmsg_return_buffer(struct remote_device *rdev, void *buffer,\r
-                unsigned long len, unsigned short idx);\r
-void *rpmsg_get_tx_buffer(struct remote_device *rdev, unsigned long *len,\r
-                unsigned short *idx);\r
-void rpmsg_free_buffer(struct remote_device *rdev, void *buffer);\r
-void rpmsg_free_channel(struct rpmsg_channel* rp_chnl);\r
-void * rpmsg_get_rx_buffer(struct remote_device *rdev, unsigned long *len,\r
-                unsigned short *idx);\r
-int rpmsg_get_address(unsigned long *bitmap, int size);\r
-int rpmsg_release_address(unsigned long *bitmap, int size, int addr);\r
-int rpmsg_is_address_set(unsigned long *bitmap, int size,\r
-                int addr);\r
-int rpmsg_set_address(unsigned long *bitmap, int size, int addr);\r
-void rpmsg_ns_callback(struct rpmsg_channel *server_chnl,\r
-                void *data, int len, void *priv, unsigned long src);\r
-\r
-/* Remote device functions */\r
-int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,\r
-                rpmsg_chnl_cb_t channel_created,\r
-                rpmsg_chnl_cb_t channel_destroyed,\r
-                rpmsg_rx_cb_t default_cb);\r
-void rpmsg_rdev_deinit(struct remote_device *rdev);\r
-struct llist *rpmsg_rdev_get_chnl_node_from_id(struct remote_device *rdev,\r
-                char *rp_chnl_id);\r
-struct llist *rpmsg_rdev_get_chnl_from_addr(struct remote_device *rdev,\r
-                unsigned long addr);\r
-struct llist *rpmsg_rdev_get_endpoint_from_addr(struct remote_device *rdev,\r
-               unsigned long addr);\r
-int rpmsg_rdev_notify(struct remote_device *rdev);\r
-int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,\r
-                const char *names[], vq_callback *callbacks[],\r
-                struct virtqueue *vqs[]);\r
-unsigned char rpmsg_rdev_get_status(struct virtio_device *dev);\r
-\r
-void rpmsg_rdev_set_status(struct virtio_device *dev, unsigned char status);\r
-\r
-uint32_t rpmsg_rdev_get_feature(struct virtio_device *dev);\r
-\r
-void rpmsg_rdev_set_feature(struct virtio_device *dev, uint32_t feature);\r
-\r
-uint32_t rpmsg_rdev_negotiate_feature(struct virtio_device *dev,\r
-                uint32_t features);\r
-/*\r
- * Read/write a variable amount from the device specific (ie, network)\r
- * configuration region. This region is encoded in the same endian as\r
- * the guest.\r
- */\r
-void rpmsg_rdev_read_config(struct virtio_device *dev, uint32_t offset,\r
-                void *dst, int length);\r
-void rpmsg_rdev_write_config(struct virtio_device *dev, uint32_t offset,\r
-                void *src, int length);\r
-void rpmsg_rdev_reset(struct virtio_device *dev);\r
-\r
-#endif /* _RPMSG_CORE_H_ */\r
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * 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.
+ */
+
+
+#ifndef _RPMSG_CORE_H_
+#define _RPMSG_CORE_H_
+
+#include "../common/compiler/compiler.h"
+#include "../porting/env/env.h"
+#include "../virtio/virtio.h"
+#include "../common/hil/hil.h"
+#include "../common/shm/sh_mem.h"
+#include "../common/llist/llist.h"
+#include "rpmsg.h"
+
+/* Configurable parameters */
+#define RPMSG_BUFFER_SIZE                       512
+#define RPMSG_MAX_VQ_PER_RDEV                   2
+#define RPMSG_NS_EPT_ADDR                       0x35
+#define RPMSG_ADDR_BMP_SIZE                     4
+
+/* Definitions for device types , null pointer, etc.*/
+#define RPMSG_SUCCESS                           0
+#define RPMSG_NULL                              (void *)0
+#define RPMSG_REMOTE                            0
+#define RPMSG_MASTER                            1
+#define RPMSG_TRUE                              1
+#define RPMSG_FALSE                             0
+
+/* RPMSG channel states. */
+#define RPMSG_CHNL_STATE_IDLE                   0
+#define RPMSG_CHNL_STATE_NS                     1
+#define RPMSG_CHNL_STATE_ACTIVE                 2
+
+/* Remote processor/device states. */
+#define RPMSG_DEV_STATE_IDLE                    0
+#define RPMSG_DEV_STATE_ACTIVE                  1
+
+/* Total tick count for 15secs - 1msec tick. */
+#define RPMSG_TICK_COUNT                        15000
+
+/* Time to wait - In multiple of 10 msecs. */
+#define RPMSG_TICKS_PER_INTERVAL                10
+
+/* Error macros. */
+#define RPMSG_ERRORS_BASE                       -3000
+#define RPMSG_ERR_NO_MEM                        (RPMSG_ERRORS_BASE - 1)
+#define RPMSG_ERR_NO_BUFF                       (RPMSG_ERRORS_BASE - 2)
+#define RPMSG_ERR_MAX_VQ                        (RPMSG_ERRORS_BASE - 3)
+#define RPMSG_ERR_PARAM                         (RPMSG_ERRORS_BASE - 4)
+#define RPMSG_ERR_DEV_STATE                     (RPMSG_ERRORS_BASE - 5)
+#define RPMSG_ERR_BUFF_SIZE                     (RPMSG_ERRORS_BASE - 6)
+#define RPMSG_ERR_DEV_ID                        (RPMSG_ERRORS_BASE - 7)
+#define RPMSG_ERR_DEV_ADDR                      (RPMSG_ERRORS_BASE - 8)
+
+struct rpmsg_channel;
+typedef void (*rpmsg_rx_cb_t)(struct rpmsg_channel *, void *, int, void *, unsigned long);
+typedef void (*rpmsg_chnl_cb_t)(struct rpmsg_channel *rp_chl);
+/**
+ * remote_device
+ *
+ * This structure is maintained by RPMSG driver to represent remote device/core.
+ *
+ * @virtd_dev           - virtio device for remote core
+ * @rvq                 - Rx virtqueue for virtio device
+ * @tvq                 - Tx virtqueue for virtio device
+ * @proc                - reference to remote processor
+ * @rp_channels         - rpmsg channels list for the device
+ * @rp_endpoints        - rpmsg endpoints list for the device
+ * @mem_pool            - shared memory pool
+ * @bitmap              - bitmap for channels addresses
+ * @channel_created     - create channel callback
+ * @channel_destroyed   - delete channel callback
+ * @default_cb          - default callback handler for RX data on channel
+ * @lock                - remote device mutex
+ * @role                - role of the remote device, RPMSG_MASTER/RPMSG_REMOTE
+ * @state               - remote device state, IDLE/ACTIVE
+ * @support_ns          - if device supports name service announcement
+ *
+ */
+struct remote_device {
+    struct virtio_device virt_dev;
+    struct virtqueue *rvq;
+    struct virtqueue *tvq;
+    struct hil_proc *proc;
+    struct llist *rp_channels;
+    struct llist *rp_endpoints;
+    struct sh_mem_pool *mem_pool;
+    unsigned long bitmap[RPMSG_ADDR_BMP_SIZE];
+    rpmsg_chnl_cb_t channel_created;
+    rpmsg_chnl_cb_t channel_destroyed;
+    rpmsg_rx_cb_t default_cb;
+    LOCK *lock;
+    unsigned int role;
+    unsigned int state;
+    int support_ns;
+};
+
+/* Core functions */
+int rpmsg_start_ipc(struct remote_device *rdev);
+struct rpmsg_channel *_rpmsg_create_channel(struct remote_device *rdev,
+                char *name, unsigned long src, unsigned long dst);
+void _rpmsg_delete_channel(struct rpmsg_channel * rp_chnl);
+struct rpmsg_endpoint *_create_endpoint(struct remote_device *rdev,
+               rpmsg_rx_cb_t cb, void *priv, unsigned long addr);
+void _destroy_endpoint(struct remote_device *rdev,
+               struct rpmsg_endpoint *rp_ept);
+void rpmsg_send_ns_message(struct remote_device *rdev,
+                struct rpmsg_channel *rp_chnl, unsigned long flags);
+int rpmsg_enqueue_buffer(struct remote_device *rdev, void *buffer,
+                unsigned long len, unsigned short idx);
+void rpmsg_return_buffer(struct remote_device *rdev, void *buffer,
+                unsigned long len, unsigned short idx);
+void *rpmsg_get_tx_buffer(struct remote_device *rdev, unsigned long *len,
+                unsigned short *idx);
+void rpmsg_free_buffer(struct remote_device *rdev, void *buffer);
+void rpmsg_free_channel(struct rpmsg_channel* rp_chnl);
+void * rpmsg_get_rx_buffer(struct remote_device *rdev, unsigned long *len,
+                unsigned short *idx);
+int rpmsg_get_address(unsigned long *bitmap, int size);
+int rpmsg_release_address(unsigned long *bitmap, int size, int addr);
+int rpmsg_is_address_set(unsigned long *bitmap, int size,
+                int addr);
+int rpmsg_set_address(unsigned long *bitmap, int size, int addr);
+void rpmsg_ns_callback(struct rpmsg_channel *server_chnl,
+                void *data, int len, void *priv, unsigned long src);
+
+/* Remote device functions */
+int rpmsg_rdev_init(struct remote_device **rdev, int dev_id, int role,
+                rpmsg_chnl_cb_t channel_created,
+                rpmsg_chnl_cb_t channel_destroyed,
+                rpmsg_rx_cb_t default_cb);
+void rpmsg_rdev_deinit(struct remote_device *rdev);
+struct llist *rpmsg_rdev_get_chnl_node_from_id(struct remote_device *rdev,
+                char *rp_chnl_id);
+struct llist *rpmsg_rdev_get_chnl_from_addr(struct remote_device *rdev,
+                unsigned long addr);
+struct llist *rpmsg_rdev_get_endpoint_from_addr(struct remote_device *rdev,
+               unsigned long addr);
+int rpmsg_rdev_notify(struct remote_device *rdev);
+int rpmsg_rdev_create_virtqueues(struct virtio_device *dev, int flags, int nvqs,
+                const char *names[], vq_callback *callbacks[],
+                struct virtqueue *vqs[]);
+unsigned char rpmsg_rdev_get_status(struct virtio_device *dev);
+
+void rpmsg_rdev_set_status(struct virtio_device *dev, unsigned char status);
+
+uint32_t rpmsg_rdev_get_feature(struct virtio_device *dev);
+
+void rpmsg_rdev_set_feature(struct virtio_device *dev, uint32_t feature);
+
+uint32_t rpmsg_rdev_negotiate_feature(struct virtio_device *dev,
+                uint32_t features);
+/*
+ * Read/write a variable amount from the device specific (ie, network)
+ * configuration region. This region is encoded in the same endian as
+ * the guest.
+ */
+void rpmsg_rdev_read_config(struct virtio_device *dev, uint32_t offset,
+                void *dst, int length);
+void rpmsg_rdev_write_config(struct virtio_device *dev, uint32_t offset,
+                void *src, int length);
+void rpmsg_rdev_reset(struct virtio_device *dev);
+
+#endif /* _RPMSG_CORE_H_ */
index 19ea191b88836df4e3eb92734eb723907af59e08..ab11dcdc08ea884f6d10fde8e696e1d4db71ca63 100644 (file)
-/*-\r
- * This header is BSD licensed so anyone can use the definitions to implement\r
- * compatible drivers/servers.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- *    notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- *    notice, this list of conditions and the following disclaimer in the\r
- *    documentation and/or other materials provided with the distribution.\r
- * 3. Neither the name of IBM nor the names of its contributors\r
- *    may be used to endorse or promote products derived from this software\r
- *    without specific prior written permission.\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE\r
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
- * SUCH DAMAGE.\r
- *\r
- * $FreeBSD$\r
- */\r
-\r
-#ifndef _VIRTIO_H_\r
-#define _VIRTIO_H_\r
-\r
-#include "virtqueue.h"\r
-\r
-/* VirtIO device IDs. */\r
-#define VIRTIO_ID_NETWORK    0x01\r
-#define VIRTIO_ID_BLOCK      0x02\r
-#define VIRTIO_ID_CONSOLE    0x03\r
-#define VIRTIO_ID_ENTROPY    0x04\r
-#define VIRTIO_ID_BALLOON    0x05\r
-#define VIRTIO_ID_IOMEMORY   0x06\r
-#define VIRTIO_ID_RPMSG                 0x07 /* virtio remote remote_proc messaging */\r
-#define VIRTIO_ID_SCSI       0x08\r
-#define VIRTIO_ID_9P         0x09\r
-\r
-/* Status byte for guest to report progress. */\r
-#define VIRTIO_CONFIG_STATUS_RESET     0x00\r
-#define VIRTIO_CONFIG_STATUS_ACK       0x01\r
-#define VIRTIO_CONFIG_STATUS_DRIVER    0x02\r
-#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04\r
-#define VIRTIO_CONFIG_STATUS_FAILED    0x80\r
-\r
-/*\r
- * Generate interrupt when the virtqueue ring is\r
- * completely used, even if we've suppressed them.\r
- */\r
-#define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24)\r
-\r
-/*\r
- * The guest should never negotiate this feature; it\r
- * is used to detect faulty drivers.\r
- */\r
-#define VIRTIO_F_BAD_FEATURE (1 << 30)\r
-\r
-/*\r
- * Some VirtIO feature bits (currently bits 28 through 31) are\r
- * reserved for the transport being used (eg. virtio_ring), the\r
- * rest are per-device feature bits.\r
- */\r
-#define VIRTIO_TRANSPORT_F_START      28\r
-#define VIRTIO_TRANSPORT_F_END        32\r
-\r
-typedef struct _virtio_dispatch_ virtio_dispatch;\r
-\r
-struct virtio_feature_desc {\r
-    uint32_t      vfd_val;\r
-    const char    *vfd_str;\r
-};\r
-\r
-/*\r
- * Structure definition for virtio devices for use by the\r
- * applications/drivers\r
- *\r
- */\r
-\r
-struct virtio_device {\r
-    /*\r
-     * Since there is no generic device structure so\r
-     * keep its type as void. The driver layer will take\r
-     * care of it.\r
-     */\r
-    void *device;\r
-\r
-    /* Device name */\r
-    char *name;\r
-\r
-    /* List of virtqueues encapsulated by virtio device. */\r
-    //TODO : Need to implement a list service for ipc stack.\r
-    void *vq_list;\r
-\r
-    /* Virtio device specific features */\r
-    uint32_t features;\r
-\r
-    /* Virtio dispatch table */\r
-    virtio_dispatch *func;\r
-\r
-    /*\r
-     * Pointer to hold some private data, useful\r
-     * in callbacks.\r
-     */\r
-    void *data;\r
-};\r
-\r
-/* \r
- * Helper functions.\r
- */ \r
-const char *virtio_dev_name(uint16_t devid);\r
-void       virtio_describe(struct virtio_device *dev, const char *msg,\r
-           uint32_t features, struct virtio_feature_desc *feature_desc);\r
-\r
-/*\r
- * Functions for virtio device configuration as defined in Rusty Russell's paper.\r
- * Drivers are expected to implement these functions in their respective codes.\r
- * \r
- */\r
-\r
-struct _virtio_dispatch_ {\r
-    int (*create_virtqueues)(struct virtio_device *dev, int flags, int nvqs,\r
-                    const char *names[], vq_callback *callbacks[],\r
-                    struct virtqueue *vqs[]);\r
-    uint8_t (*get_status)(struct virtio_device *dev);\r
-    void (*set_status)(struct virtio_device *dev, uint8_t status);\r
-    uint32_t (*get_features)(struct virtio_device *dev);\r
-    void (*set_features)(struct virtio_device *dev, uint32_t feature);\r
-    uint32_t (*negotiate_features)(struct virtio_device *dev, uint32_t features);\r
-\r
-    /*\r
-     * Read/write a variable amount from the device specific (ie, network)\r
-     * configuration region. This region is encoded in the same endian as\r
-     * the guest.\r
-     */\r
-    void (*read_config)(struct virtio_device *dev, uint32_t offset, void *dst,\r
-                    int length);\r
-    void (*write_config)(struct virtio_device *dev, uint32_t offset, void *src,\r
-                    int length);\r
-    void (*reset_device)(struct virtio_device *dev);\r
-\r
-};\r
-\r
-#endif /* _VIRTIO_H_ */\r
+/*-
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * 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 IBM 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 IBM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _VIRTIO_H_
+#define _VIRTIO_H_
+
+#include "virtqueue.h"
+
+/* VirtIO device IDs. */
+#define VIRTIO_ID_NETWORK    0x01
+#define VIRTIO_ID_BLOCK      0x02
+#define VIRTIO_ID_CONSOLE    0x03
+#define VIRTIO_ID_ENTROPY    0x04
+#define VIRTIO_ID_BALLOON    0x05
+#define VIRTIO_ID_IOMEMORY   0x06
+#define VIRTIO_ID_RPMSG                 0x07 /* virtio remote remote_proc messaging */
+#define VIRTIO_ID_SCSI       0x08
+#define VIRTIO_ID_9P         0x09
+
+/* Status byte for guest to report progress. */
+#define VIRTIO_CONFIG_STATUS_RESET     0x00
+#define VIRTIO_CONFIG_STATUS_ACK       0x01
+#define VIRTIO_CONFIG_STATUS_DRIVER    0x02
+#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04
+#define VIRTIO_CONFIG_STATUS_FAILED    0x80
+
+/*
+ * Generate interrupt when the virtqueue ring is
+ * completely used, even if we've suppressed them.
+ */
+#define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24)
+
+/*
+ * The guest should never negotiate this feature; it
+ * is used to detect faulty drivers.
+ */
+#define VIRTIO_F_BAD_FEATURE (1 << 30)
+
+/*
+ * Some VirtIO feature bits (currently bits 28 through 31) are
+ * reserved for the transport being used (eg. virtio_ring), the
+ * rest are per-device feature bits.
+ */
+#define VIRTIO_TRANSPORT_F_START      28
+#define VIRTIO_TRANSPORT_F_END        32
+
+typedef struct _virtio_dispatch_ virtio_dispatch;
+
+struct virtio_feature_desc {
+    uint32_t      vfd_val;
+    const char    *vfd_str;
+};
+
+/*
+ * Structure definition for virtio devices for use by the
+ * applications/drivers
+ *
+ */
+
+struct virtio_device {
+    /*
+     * Since there is no generic device structure so
+     * keep its type as void. The driver layer will take
+     * care of it.
+     */
+    void *device;
+
+    /* Device name */
+    char *name;
+
+    /* List of virtqueues encapsulated by virtio device. */
+    //TODO : Need to implement a list service for ipc stack.
+    void *vq_list;
+
+    /* Virtio device specific features */
+    uint32_t features;
+
+    /* Virtio dispatch table */
+    virtio_dispatch *func;
+
+    /*
+     * Pointer to hold some private data, useful
+     * in callbacks.
+     */
+    void *data;
+};
+
+/* 
+ * Helper functions.
+ */ 
+const char *virtio_dev_name(uint16_t devid);
+void       virtio_describe(struct virtio_device *dev, const char *msg,
+           uint32_t features, struct virtio_feature_desc *feature_desc);
+
+/*
+ * Functions for virtio device configuration as defined in Rusty Russell's paper.
+ * Drivers are expected to implement these functions in their respective codes.
+ * 
+ */
+
+struct _virtio_dispatch_ {
+    int (*create_virtqueues)(struct virtio_device *dev, int flags, int nvqs,
+                    const char *names[], vq_callback *callbacks[],
+                    struct virtqueue *vqs[]);
+    uint8_t (*get_status)(struct virtio_device *dev);
+    void (*set_status)(struct virtio_device *dev, uint8_t status);
+    uint32_t (*get_features)(struct virtio_device *dev);
+    void (*set_features)(struct virtio_device *dev, uint32_t feature);
+    uint32_t (*negotiate_features)(struct virtio_device *dev, uint32_t features);
+
+    /*
+     * Read/write a variable amount from the device specific (ie, network)
+     * configuration region. This region is encoded in the same endian as
+     * the guest.
+     */
+    void (*read_config)(struct virtio_device *dev, uint32_t offset, void *dst,
+                    int length);
+    void (*write_config)(struct virtio_device *dev, uint32_t offset, void *src,
+                    int length);
+    void (*reset_device)(struct virtio_device *dev);
+
+};
+
+#endif /* _VIRTIO_H_ */
index 966602a656fb83889706f353888fb4a4325fd763..8e902ab59c2bc1ba37d6e13ca1dd85a1b9383a26 100644 (file)
-/*-\r
- * Copyright Rusty Russell IBM Corporation 2007.\r
- *\r
- * This header is BSD licensed so anyone can use the definitions to implement\r
- * compatible drivers/servers.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- *    notice, this list of conditions and the following disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- *    notice, this list of conditions and the following disclaimer in the\r
- *    documentation and/or other materials provided with the distribution.\r
- * 3. Neither the name of IBM nor the names of its contributors\r
- *    may be used to endorse or promote products derived from this software\r
- *    without specific prior written permission.\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\r
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE\r
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
- * SUCH DAMAGE.\r
- *\r
- * $FreeBSD$\r
- */\r
-\r
-#ifndef VIRTIO_RING_H\r
-#define        VIRTIO_RING_H\r
-\r
-/* This marks a buffer as continuing via the next field. */\r
-#define VRING_DESC_F_NEXT       1\r
-/* This marks a buffer as write-only (otherwise read-only). */\r
-#define VRING_DESC_F_WRITE      2\r
-/* This means the buffer contains a list of buffer descriptors. */\r
-#define VRING_DESC_F_INDIRECT  4\r
-\r
-/* The Host uses this in used->flags to advise the Guest: don't kick me\r
- * when you add a buffer.  It's unreliable, so it's simply an\r
- * optimization.  Guest will still kick if it's out of buffers. */\r
-#define VRING_USED_F_NO_NOTIFY  1\r
-/* The Guest uses this in avail->flags to advise the Host: don't\r
- * interrupt me when you consume a buffer.  It's unreliable, so it's\r
- * simply an optimization.  */\r
-#define VRING_AVAIL_F_NO_INTERRUPT      1\r
-\r
-/* VirtIO ring descriptors: 16 bytes.\r
- * These can chain together via "next". */\r
-struct vring_desc {\r
-        /* Address (guest-physical). */\r
-        uint64_t addr;\r
-        /* Length. */\r
-        uint32_t len;\r
-        /* The flags as indicated above. */\r
-        uint16_t flags;\r
-        /* We chain unused descriptors via this, too. */\r
-        uint16_t next;\r
-};\r
-\r
-struct vring_avail {\r
-        uint16_t flags;\r
-        uint16_t idx;\r
-        uint16_t ring[0];\r
-};\r
-\r
-/* uint32_t is used here for ids for padding reasons. */\r
-struct vring_used_elem {\r
-        /* Index of start of used descriptor chain. */\r
-        uint32_t id;\r
-        /* Total length of the descriptor chain which was written to. */\r
-        uint32_t len;\r
-};\r
-\r
-struct vring_used {\r
-        uint16_t flags;\r
-        uint16_t idx;\r
-        struct vring_used_elem ring[0];\r
-};\r
-\r
-struct vring {\r
-       unsigned int num;\r
-\r
-       struct vring_desc *desc;\r
-       struct vring_avail *avail;\r
-       struct vring_used *used;\r
-};\r
-\r
-/* The standard layout for the ring is a continuous chunk of memory which\r
- * looks like this.  We assume num is a power of 2.\r
- *\r
- * struct vring {\r
- *      // The actual descriptors (16 bytes each)\r
- *      struct vring_desc desc[num];\r
- *\r
- *      // A ring of available descriptor heads with free-running index.\r
- *      __u16 avail_flags;\r
- *      __u16 avail_idx;\r
- *      __u16 available[num];\r
- *      __u16 used_event_idx;\r
- *\r
- *      // Padding to the next align boundary.\r
- *      char pad[];\r
- *\r
- *      // A ring of used descriptor heads with free-running index.\r
- *      __u16 used_flags;\r
- *      __u16 used_idx;\r
- *      struct vring_used_elem used[num];\r
- *      __u16 avail_event_idx;\r
- * };\r
- *\r
- * NOTE: for VirtIO PCI, align is 4096.\r
- */\r
-\r
-/*\r
- * We publish the used event index at the end of the available ring, and vice\r
- * versa. They are at the end for backwards compatibility.\r
- */\r
-#define vring_used_event(vr)   ((vr)->avail->ring[(vr)->num])\r
-#define vring_avail_event(vr)  (*(uint16_t *)&(vr)->used->ring[(vr)->num])\r
-\r
-static inline int\r
-vring_size(unsigned int num, unsigned long align)\r
-{\r
-       int size;\r
-\r
-       size = num * sizeof(struct vring_desc);\r
-       size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) +\r
-           sizeof(uint16_t);\r
-       size = (size + align - 1) & ~(align - 1);\r
-       size += sizeof(struct vring_used) +\r
-           (num * sizeof(struct vring_used_elem)) + sizeof(uint16_t);\r
-       return (size);\r
-}\r
-\r
-static inline void\r
-vring_init(struct vring *vr, unsigned int num, uint8_t *p,\r
-    unsigned long align)\r
-{\r
-        vr->num = num;\r
-        vr->desc = (struct vring_desc *) p;\r
-        vr->avail = (struct vring_avail *) (p +\r
-           num * sizeof(struct vring_desc));\r
-        vr->used = (void *)\r
-           (((unsigned long) &vr->avail->ring[num] + align-1) & ~(align-1));\r
-}\r
-\r
-/*\r
- * The following is used with VIRTIO_RING_F_EVENT_IDX.\r
- *\r
- * Assuming a given event_idx value from the other size, if we have\r
- * just incremented index from old to new_idx, should we trigger an\r
- * event?\r
- */\r
-static inline int\r
-vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)\r
-{\r
-\r
-       return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old);\r
-}\r
-#endif /* VIRTIO_RING_H */\r
+/*-
+ * Copyright Rusty Russell IBM Corporation 2007.
+ *
+ * This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * 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 IBM 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 IBM 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef VIRTIO_RING_H
+#define        VIRTIO_RING_H
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT       1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE      2
+/* This means the buffer contains a list of buffer descriptors. */
+#define VRING_DESC_F_INDIRECT  4
+
+/* The Host uses this in used->flags to advise the Guest: don't kick me
+ * when you add a buffer.  It's unreliable, so it's simply an
+ * optimization.  Guest will still kick if it's out of buffers. */
+#define VRING_USED_F_NO_NOTIFY  1
+/* The Guest uses this in avail->flags to advise the Host: don't
+ * interrupt me when you consume a buffer.  It's unreliable, so it's
+ * simply an optimization.  */
+#define VRING_AVAIL_F_NO_INTERRUPT      1
+
+/* VirtIO ring descriptors: 16 bytes.
+ * These can chain together via "next". */
+struct vring_desc {
+        /* Address (guest-physical). */
+        uint64_t addr;
+        /* Length. */
+        uint32_t len;
+        /* The flags as indicated above. */
+        uint16_t flags;
+        /* We chain unused descriptors via this, too. */
+        uint16_t next;
+};
+
+struct vring_avail {
+        uint16_t flags;
+        uint16_t idx;
+        uint16_t ring[0];
+};
+
+/* uint32_t is used here for ids for padding reasons. */
+struct vring_used_elem {
+        /* Index of start of used descriptor chain. */
+        uint32_t id;
+        /* Total length of the descriptor chain which was written to. */
+        uint32_t len;
+};
+
+struct vring_used {
+        uint16_t flags;
+        uint16_t idx;
+        struct vring_used_elem ring[0];
+};
+
+struct vring {
+       unsigned int num;
+
+       struct vring_desc *desc;
+       struct vring_avail *avail;
+       struct vring_used *used;
+};
+
+/* The standard layout for the ring is a continuous chunk of memory which
+ * looks like this.  We assume num is a power of 2.
+ *
+ * struct vring {
+ *      // The actual descriptors (16 bytes each)
+ *      struct vring_desc desc[num];
+ *
+ *      // A ring of available descriptor heads with free-running index.
+ *      __u16 avail_flags;
+ *      __u16 avail_idx;
+ *      __u16 available[num];
+ *      __u16 used_event_idx;
+ *
+ *      // Padding to the next align boundary.
+ *      char pad[];
+ *
+ *      // A ring of used descriptor heads with free-running index.
+ *      __u16 used_flags;
+ *      __u16 used_idx;
+ *      struct vring_used_elem used[num];
+ *      __u16 avail_event_idx;
+ * };
+ *
+ * NOTE: for VirtIO PCI, align is 4096.
+ */
+
+/*
+ * We publish the used event index at the end of the available ring, and vice
+ * versa. They are at the end for backwards compatibility.
+ */
+#define vring_used_event(vr)   ((vr)->avail->ring[(vr)->num])
+#define vring_avail_event(vr)  (*(uint16_t *)&(vr)->used->ring[(vr)->num])
+
+static inline int
+vring_size(unsigned int num, unsigned long align)
+{
+       int size;
+
+       size = num * sizeof(struct vring_desc);
+       size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) +
+           sizeof(uint16_t);
+       size = (size + align - 1) & ~(align - 1);
+       size += sizeof(struct vring_used) +
+           (num * sizeof(struct vring_used_elem)) + sizeof(uint16_t);
+       return (size);
+}
+
+static inline void
+vring_init(struct vring *vr, unsigned int num, uint8_t *p,
+    unsigned long align)
+{
+        vr->num = num;
+        vr->desc = (struct vring_desc *) p;
+        vr->avail = (struct vring_avail *) (p +
+           num * sizeof(struct vring_desc));
+        vr->used = (void *)
+           (((unsigned long) &vr->avail->ring[num] + align-1) & ~(align-1));
+}
+
+/*
+ * The following is used with VIRTIO_RING_F_EVENT_IDX.
+ *
+ * Assuming a given event_idx value from the other size, if we have
+ * just incremented index from old to new_idx, should we trigger an
+ * event?
+ */
+static inline int
+vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
+{
+
+       return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old);
+}
+#endif /* VIRTIO_RING_H */
index 4286b4d9145957500e34854a08f03b330dafc018..5bc91cd8cfc2924a80056c16e4e15411a2c577f6 100644 (file)
-/*-\r
- * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- *    notice unmodified, this list of conditions, and the following\r
- *    disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- *    notice, this list of conditions and the following disclaimer in the\r
- *    documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-#include "virtqueue.h"\r
-\r
-/* Prototype for internal functions. */\r
-static void vq_ring_init(struct virtqueue *);\r
-static void vq_ring_update_avail(struct virtqueue *, uint16_t);\r
-static uint16_t vq_ring_add_buffer(struct virtqueue *, struct vring_desc *,\r
-        uint16_t, struct llist *, int, int);\r
-static int vq_ring_enable_interrupt(struct virtqueue *, uint16_t);\r
-static void vq_ring_free_chain(struct virtqueue *, uint16_t);\r
-static int vq_ring_must_notify_host(struct virtqueue *vq);\r
-static void vq_ring_notify_host(struct virtqueue *vq);\r
-static int virtqueue_nused(struct virtqueue *vq);\r
-\r
-/**\r
- * virtqueue_create - Creates new VirtIO queue\r
- *\r
- * @param device    - Pointer to VirtIO device\r
- * @param id        - VirtIO queue ID , must be unique\r
- * @param name      - Name of VirtIO queue\r
- * @param ring      - Pointer to vring_alloc_info control block\r
- * @param callback  - Pointer to callback function, invoked\r
- *                    when message is available on VirtIO queue\r
- * @param notify    - Pointer to notify function, used to notify\r
- *                    other side that there is job available for it\r
- * @param v_queue   - Created VirtIO queue.\r
- *\r
- * @return          - Function status\r
- */\r
-int virtqueue_create(struct virtio_device *virt_dev, unsigned short id, char *name,\r
-        struct vring_alloc_info *ring, void (*callback)(struct virtqueue *vq),\r
-        void (*notify)(struct virtqueue *vq),\r
-        struct virtqueue **v_queue) {\r
-\r
-    struct virtqueue *vq = VQ_NULL;\r
-    int status = VQUEUE_SUCCESS;\r
-    uint32_t vq_size = 0;\r
-\r
-    VQ_PARAM_CHK(ring == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);\r
-    VQ_PARAM_CHK(ring->num_descs == 0, status, ERROR_VQUEUE_INVLD_PARAM);\r
-    VQ_PARAM_CHK(ring->num_descs & (ring->num_descs - 1), status,\r
-            ERROR_VRING_ALIGN);\r
-\r
-    //TODO : Error check for indirect buffer addition\r
-\r
-    if (status == VQUEUE_SUCCESS) {\r
-\r
-        vq_size = sizeof(struct virtqueue)\r
-                + (ring->num_descs) * sizeof(struct vq_desc_extra);\r
-        vq = (struct virtqueue *) env_allocate_memory(vq_size);\r
-\r
-        if (vq == VQ_NULL) {\r
-            return (ERROR_NO_MEM);\r
-        }\r
-\r
-        env_memset(vq, 0x00, vq_size);\r
-\r
-        vq->vq_dev = virt_dev;\r
-        env_strncpy(vq->vq_name, name, VIRTQUEUE_MAX_NAME_SZ);\r
-        vq->vq_queue_index = id;\r
-        vq->vq_alignment = ring->align;\r
-        vq->vq_nentries = ring->num_descs;\r
-        vq->vq_free_cnt = vq->vq_nentries;\r
-        vq->callback = callback;\r
-        vq->notify = notify;\r
-\r
-        //TODO : Whether we want to support indirect addition or not.\r
-        vq->vq_ring_size = vring_size(ring->num_descs, ring->align);\r
-        vq->vq_ring_mem = (void *) ring->phy_addr;\r
-\r
-        /* Initialize vring control block in virtqueue. */\r
-        vq_ring_init(vq);\r
-\r
-        /* Disable callbacks - will be enabled by the application\r
-         * once initialization is completed.\r
-         */\r
-        virtqueue_disable_cb(vq);\r
-\r
-        *v_queue = vq;\r
-\r
-        //TODO : Need to add cleanup in case of error used with the indirect buffer addition\r
-        //TODO: do we need to save the new queue in db based on its id\r
-    }\r
-\r
-    return (status);\r
-}\r
-\r
-/**\r
- * virtqueue_add_buffer()   - Enqueues new buffer in vring for consumption\r
- *                            by other side. Readable buffers are always\r
- *                            inserted before writable buffers\r
- *\r
- * @param vq                - Pointer to VirtIO queue control block.\r
- * @param buffer            - Pointer to buffer list\r
- * @param readable          - Number of readable buffers\r
- * @param writable          - Number of writable buffers\r
- * @param cookie            - Pointer to hold call back data\r
- *\r
- * @return                  - Function status\r
- */\r
-int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,\r
-        int readable, int writable, void *cookie) {\r
-\r
-    struct vq_desc_extra *dxp = VQ_NULL;\r
-    int status = VQUEUE_SUCCESS;\r
-    uint16_t head_idx;\r
-    uint16_t idx;\r
-    int needed;\r
-\r
-    needed = readable + writable;\r
-\r
-    VQ_PARAM_CHK(vq == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);\r
-    VQ_PARAM_CHK(needed < 1, status, ERROR_VQUEUE_INVLD_PARAM);\r
-    VQ_PARAM_CHK(vq->vq_free_cnt == 0, status, ERROR_VRING_FULL);\r
-\r
-    //TODO: Add parameters validation for indirect buffer addition\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    if (status == VQUEUE_SUCCESS) {\r
-\r
-        //TODO : Indirect buffer addition support\r
-\r
-        VQASSERT(vq, cookie != VQ_NULL, "enqueuing with no cookie");\r
-\r
-        head_idx = vq->vq_desc_head_idx;\r
-        VQ_RING_ASSERT_VALID_IDX(vq, head_idx);\r
-        dxp = &vq->vq_descx[head_idx];\r
-\r
-        VQASSERT(vq, (dxp->cookie == VQ_NULL), "cookie already exists for index");\r
-\r
-        dxp->cookie = cookie;\r
-        dxp->ndescs = needed;\r
-\r
-        /* Enqueue buffer onto the ring. */\r
-        idx = vq_ring_add_buffer(vq, vq->vq_ring.desc, head_idx, buffer,\r
-                readable, writable);\r
-\r
-        vq->vq_desc_head_idx = idx;\r
-        vq->vq_free_cnt -= needed;\r
-\r
-        if (vq->vq_free_cnt == 0)\r
-            VQ_RING_ASSERT_CHAIN_TERM(vq);\r
-        else\r
-            VQ_RING_ASSERT_VALID_IDX(vq, idx);\r
-\r
-        /*\r
-         * Update vring_avail control block fields so that other\r
-         * side can get buffer using it.\r
-         */\r
-        vq_ring_update_avail(vq, head_idx);\r
-    }\r
-\r
-    VQUEUE_IDLE(vq);\r
-\r
-    return (status);\r
-}\r
-\r
-/**\r
- * virtqueue_add_single_buffer - Enqueues single buffer in vring\r
- *\r
- * @param vq                    - Pointer to VirtIO queue control block\r
- * @param cookie                - Pointer to hold call back data\r
- * @param buffer_addr           - Address of buffer\r
- * @param len                   - Length of buffer\r
- * @param writable              - If buffer writable\r
- * @param has_next              - If buffers for subsequent call are\r
- *                                to be chained\r
- *\r
- * @return                      - Function status\r
- */\r
-int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,\r
-        void *buffer_addr, uint32_t len, int writable, boolean has_next) {\r
-\r
-    struct vq_desc_extra *dxp;\r
-    struct vring_desc *dp;\r
-    uint16_t head_idx;\r
-    uint16_t idx;\r
-    int status = VQUEUE_SUCCESS;\r
-\r
-    VQ_PARAM_CHK(vq == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);\r
-    VQ_PARAM_CHK(vq->vq_free_cnt == 0, status, ERROR_VRING_FULL);\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    if (status == VQUEUE_SUCCESS) {\r
-\r
-        VQASSERT(vq, cookie != VQ_NULL, "enqueuing with no cookie");\r
-\r
-        head_idx = vq->vq_desc_head_idx;\r
-        dxp = &vq->vq_descx[head_idx];\r
-\r
-        dxp->cookie = cookie;\r
-        dxp->ndescs = 1;\r
-        idx = head_idx;\r
-\r
-        dp = &vq->vq_ring.desc[idx];\r
-        dp->addr = env_map_vatopa(buffer_addr);\r
-        dp->len = len;\r
-        dp->flags = 0;\r
-        idx = dp->next;\r
-\r
-        if (has_next)\r
-            dp->flags |= VRING_DESC_F_NEXT;\r
-        if (writable)\r
-            dp->flags |= VRING_DESC_F_WRITE;\r
-\r
-        vq->vq_desc_head_idx = idx;\r
-        vq->vq_free_cnt--;\r
-\r
-        if (vq->vq_free_cnt == 0)\r
-            VQ_RING_ASSERT_CHAIN_TERM(vq);\r
-        else\r
-            VQ_RING_ASSERT_VALID_IDX(vq, idx);\r
-\r
-        vq_ring_update_avail(vq, head_idx);\r
-    }\r
-\r
-    VQUEUE_IDLE(vq);\r
-\r
-    return (status);\r
-}\r
-\r
-/**\r
- * virtqueue_get_buffer - Returns used buffers from VirtIO queue\r
- *\r
- * @param vq            - Pointer to VirtIO queue control block\r
- * @param len           - Length of conumed buffer\r
- *\r
- * @return              - Pointer to used buffer\r
- */\r
-void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len) {\r
-    struct vring_used_elem *uep;\r
-    void *cookie;\r
-    uint16_t used_idx, desc_idx;\r
-\r
-    if ((vq == VQ_NULL) || (vq->vq_used_cons_idx == vq->vq_ring.used->idx))\r
-        return (VQ_NULL);\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    used_idx = vq->vq_used_cons_idx++ & (vq->vq_nentries - 1);\r
-    uep = &vq->vq_ring.used->ring[used_idx];\r
-\r
-    env_rmb();\r
-\r
-    desc_idx = (uint16_t) uep->id;\r
-    if (len != VQ_NULL)\r
-        *len = uep->len;\r
-\r
-    vq_ring_free_chain(vq, desc_idx);\r
-\r
-    cookie = vq->vq_descx[desc_idx].cookie;\r
-    vq->vq_descx[desc_idx].cookie = VQ_NULL;\r
-\r
-    VQUEUE_IDLE(vq);\r
-\r
-    return (cookie);\r
-}\r
-\r
-/**\r
- * virtqueue_free   - Frees VirtIO queue resources\r
- *\r
- * @param vq        - Pointer to VirtIO queue control block\r
- *\r
- */\r
-void virtqueue_free(struct virtqueue *vq) {\r
-\r
-    if (vq != VQ_NULL) {\r
-\r
-        if (vq->vq_free_cnt != vq->vq_nentries) {\r
-            env_print("\r\nWARNING %s: freeing non-empty virtqueue\r\n", vq->vq_name);\r
-        }\r
-\r
-        //TODO : Need to free indirect buffers here\r
-\r
-        if (vq->vq_ring_mem != VQ_NULL) {\r
-            vq->vq_ring_size = 0;\r
-            vq->vq_ring_mem = VQ_NULL;\r
-        }\r
-\r
-        env_free_memory(vq);\r
-    }\r
-}\r
-\r
-/**\r
- * virtqueue_get_available_buffer   - Returns buffer available for use in the\r
- *                                    VirtIO queue\r
- *\r
- * @param vq                        - Pointer to VirtIO queue control block\r
- * @param avail_idx                 - Pointer to index used in vring desc table\r
- * @param len                       - Length of buffer\r
- *\r
- * @return                          - Pointer to available buffer\r
- */\r
-void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx,\r
-        uint32_t *len) {\r
-\r
-    uint16_t head_idx = 0;\r
-    void *buffer;\r
-\r
-    if (vq->vq_available_idx == vq->vq_ring.avail->idx) {\r
-        return (VQ_NULL);\r
-    }\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    head_idx = vq->vq_available_idx++ & (vq->vq_nentries - 1);\r
-    *avail_idx = vq->vq_ring.avail->ring[head_idx];\r
-\r
-    env_rmb();\r
-\r
-    buffer = env_map_patova(vq->vq_ring.desc[*avail_idx].addr);\r
-    *len = vq->vq_ring.desc[*avail_idx].len;\r
-\r
-    VQUEUE_IDLE(vq);\r
-\r
-    return (buffer);\r
-}\r
-\r
-/**\r
- * virtqueue_add_consumed_buffer - Returns consumed buffer back to VirtIO queue\r
- *\r
- * @param vq                     - Pointer to VirtIO queue control block\r
- * @param head_idx               - Index of vring desc containing used buffer\r
- * @param len                    - Length of buffer\r
- *\r
- * @return                       - Function status\r
- */\r
-int virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx,\r
-        uint32_t len) {\r
-\r
-    struct vring_used_elem *used_desc = VQ_NULL;\r
-    uint16_t used_idx;\r
-\r
-    if ((head_idx > vq->vq_nentries) || (head_idx < 0)) {\r
-        return (ERROR_VRING_NO_BUFF);\r
-    }\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    used_idx = vq->vq_ring.used->idx & (vq->vq_nentries - 1);\r
-    used_desc = &(vq->vq_ring.used->ring[used_idx]);\r
-    used_desc->id = head_idx;\r
-    used_desc->len = len;\r
-\r
-    env_wmb();\r
-\r
-    vq->vq_ring.used->idx++;\r
-\r
-    VQUEUE_IDLE(vq);\r
-\r
-    return (VQUEUE_SUCCESS);\r
-}\r
-\r
-/**\r
- * virtqueue_enable_cb  - Enables callback generation\r
- *\r
- * @param vq            - Pointer to VirtIO queue control block\r
- *\r
- * @return              - Function status\r
- */\r
-int virtqueue_enable_cb(struct virtqueue *vq) {\r
-\r
-    return (vq_ring_enable_interrupt(vq, 0));\r
-}\r
-\r
-/**\r
- * virtqueue_enable_cb - Disables callback generation\r
- *\r
- * @param vq           - Pointer to VirtIO queue control block\r
- *\r
- */\r
-void virtqueue_disable_cb(struct virtqueue *vq) {\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) {\r
-        vring_used_event(&vq->vq_ring)= vq->vq_used_cons_idx - vq->vq_nentries\r
-        - 1;\r
-    } else {\r
-        vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;\r
-    }\r
-\r
-    VQUEUE_IDLE(vq);\r
-}\r
-\r
-/**\r
- * virtqueue_kick - Notifies other side that there is buffer available for it.\r
- *\r
- * @param vq      - Pointer to VirtIO queue control block\r
- */\r
-void virtqueue_kick(struct virtqueue *vq) {\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    /* Ensure updated avail->idx is visible to host. */\r
-    env_mb();\r
-\r
-    if (vq_ring_must_notify_host(vq))\r
-        vq_ring_notify_host(vq);\r
-\r
-    vq->vq_queued_cnt = 0;\r
-\r
-    VQUEUE_IDLE(vq);\r
-}\r
-\r
-/**\r
- * virtqueue_dump Dumps important virtqueue fields , use for debugging purposes\r
- *\r
- * @param vq - Pointer to VirtIO queue control block\r
- */\r
-void virtqueue_dump(struct virtqueue *vq) {\r
-\r
-    if (vq == VQ_NULL)\r
-        return;\r
-\r
-    env_print("VQ: %s - size=%d; free=%d; used=%d; queued=%d; "\r
-            "desc_head_idx=%d; avail.idx=%d; used_cons_idx=%d; "\r
-            "used.idx=%d; avail.flags=0x%x; used.flags=0x%x\r\n", vq->vq_name,\r
-            vq->vq_nentries, vq->vq_free_cnt, virtqueue_nused(vq),\r
-            vq->vq_queued_cnt, vq->vq_desc_head_idx, vq->vq_ring.avail->idx,\r
-            vq->vq_used_cons_idx, vq->vq_ring.used->idx,\r
-            vq->vq_ring.avail->flags, vq->vq_ring.used->flags);\r
-}\r
-\r
-/**\r
- * virtqueue_get_desc_size - Returns vring descriptor size\r
- *\r
- * @param vq            - Pointer to VirtIO queue control block\r
- *\r
- * @return              - Descriptor length\r
- */\r
-uint32_t virtqueue_get_desc_size(struct virtqueue *vq) {\r
-    uint16_t head_idx = 0;\r
-    uint16_t avail_idx = 0;\r
-    uint32_t len = 0;\r
-\r
-    if (vq->vq_available_idx == vq->vq_ring.avail->idx) {\r
-        return (VQ_NULL);\r
-    }\r
-\r
-    VQUEUE_BUSY(vq);\r
-\r
-    head_idx = vq->vq_available_idx & (vq->vq_nentries - 1);\r
-    avail_idx = vq->vq_ring.avail->ring[head_idx];\r
-    len = vq->vq_ring.desc[avail_idx].len;\r
-\r
-    VQUEUE_IDLE(vq);\r
-\r
-    return (len);\r
-}\r
-/**************************************************************************\r
- *                            Helper Functions                            *\r
- **************************************************************************/\r
-\r
-/**\r
- *\r
- * vq_ring_add_buffer\r
- *\r
- */\r
-static uint16_t vq_ring_add_buffer(struct virtqueue *vq,\r
-        struct vring_desc *desc, uint16_t head_idx, struct llist *buffer,\r
-        int readable, int writable) {\r
-\r
-    struct vring_desc *dp;\r
-    int i, needed;\r
-    uint16_t idx;\r
-\r
-    needed = readable + writable;\r
-\r
-    for (i = 0, idx = head_idx; (i < needed && buffer != VQ_NULL);\r
-            i++, idx = dp->next, buffer = buffer->next) {\r
-\r
-        VQASSERT(vq, idx != VQ_RING_DESC_CHAIN_END,\r
-                "premature end of free desc chain");\r
-\r
-        dp = &desc[idx];\r
-        dp->addr = env_map_vatopa(buffer->data);\r
-        dp->len = buffer->attr;\r
-        dp->flags = 0;\r
-\r
-        if (i < needed - 1)\r
-            dp->flags |= VRING_DESC_F_NEXT;\r
-\r
-        /* Readable buffers are inserted into vring before the writable buffers.*/\r
-        if (i >= readable)\r
-            dp->flags |= VRING_DESC_F_WRITE;\r
-    }\r
-\r
-    return (idx);\r
-}\r
-\r
-/**\r
- *\r
- * vq_ring_free_chain\r
- *\r
- */\r
-static void vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx) {\r
-    struct vring_desc *dp;\r
-    struct vq_desc_extra *dxp;\r
-\r
-    VQ_RING_ASSERT_VALID_IDX(vq, desc_idx);\r
-    dp = &vq->vq_ring.desc[desc_idx];\r
-    dxp = &vq->vq_descx[desc_idx];\r
-\r
-    if (vq->vq_free_cnt == 0)\r
-        VQ_RING_ASSERT_CHAIN_TERM(vq);\r
-\r
-    vq->vq_free_cnt += dxp->ndescs;\r
-    dxp->ndescs--;\r
-\r
-    if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) {\r
-        while (dp->flags & VRING_DESC_F_NEXT) {\r
-            VQ_RING_ASSERT_VALID_IDX(vq, dp->next);\r
-            dp = &vq->vq_ring.desc[dp->next];\r
-            dxp->ndescs--;\r
-        }\r
-    }\r
-\r
-    VQASSERT(vq, (dxp->ndescs == 0),\r
-            "failed to free entire desc chain, remaining");\r
-\r
-    /*\r
-     * We must append the existing free chain, if any, to the end of\r
-     * newly freed chain. If the virtqueue was completely used, then\r
-     * head would be VQ_RING_DESC_CHAIN_END (ASSERTed above).\r
-     */\r
-    dp->next = vq->vq_desc_head_idx;\r
-    vq->vq_desc_head_idx = desc_idx;\r
-}\r
-\r
-/**\r
- *\r
- * vq_ring_init\r
- *\r
- */\r
-static void vq_ring_init(struct virtqueue *vq) {\r
-    struct vring *vr;\r
-    unsigned char *ring_mem;\r
-    int i, size;\r
-\r
-    ring_mem = vq->vq_ring_mem;\r
-    size = vq->vq_nentries;\r
-    vr = &vq->vq_ring;\r
-\r
-    vring_init(vr, size, ring_mem, vq->vq_alignment);\r
-\r
-    for (i = 0; i < size - 1; i++)\r
-        vr->desc[i].next = i + 1;\r
-    vr->desc[i].next = VQ_RING_DESC_CHAIN_END;\r
-}\r
-\r
-/**\r
- *\r
- * vq_ring_update_avail\r
- *\r
- */\r
-static void vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx) {\r
-    uint16_t avail_idx;\r
-\r
-    /*\r
-     * Place the head of the descriptor chain into the next slot and make\r
-     * it usable to the host. The chain is made available now rather than\r
-     * deferring to virtqueue_notify() in the hopes that if the host is\r
-     * currently running on another CPU, we can keep it processing the new\r
-     * descriptor.\r
-     */\r
-    avail_idx = vq->vq_ring.avail->idx & (vq->vq_nentries - 1);\r
-    vq->vq_ring.avail->ring[avail_idx] = desc_idx;\r
-\r
-    env_wmb();\r
-\r
-    vq->vq_ring.avail->idx++;\r
-\r
-    /* Keep pending count until virtqueue_notify(). */\r
-    vq->vq_queued_cnt++;\r
-}\r
-\r
-/**\r
- *\r
- * vq_ring_enable_interrupt\r
- *\r
- */\r
-static int vq_ring_enable_interrupt(struct virtqueue *vq, uint16_t ndesc) {\r
-\r
-    /*\r
-     * Enable interrupts, making sure we get the latest index of\r
-     * what's already been consumed.\r
-     */\r
-    if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) {\r
-        vring_used_event(&vq->vq_ring)= vq->vq_used_cons_idx + ndesc;\r
-    } else {\r
-        vq->vq_ring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;\r
-    }\r
-\r
-    env_mb();\r
-\r
-    /*\r
-     * Enough items may have already been consumed to meet our threshold\r
-     * since we last checked. Let our caller know so it processes the new\r
-     * entries.\r
-     */\r
-    if (virtqueue_nused(vq) > ndesc) {\r
-        return (1);\r
-    }\r
-\r
-    return (0);\r
-}\r
-\r
-/**\r
- *\r
- * virtqueue_interrupt\r
- *\r
- */\r
-void virtqueue_notification(struct virtqueue *vq) {\r
-\r
-    if (vq->callback != VQ_NULL)\r
-        vq->callback(vq);\r
-}\r
-\r
-/**\r
- *\r
- * vq_ring_must_notify_host\r
- *\r
- */\r
-static int vq_ring_must_notify_host(struct virtqueue *vq) {\r
-    uint16_t new_idx, prev_idx, event_idx;\r
-\r
-    if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) {\r
-        new_idx = vq->vq_ring.avail->idx;\r
-        prev_idx = new_idx - vq->vq_queued_cnt;\r
-        event_idx = vring_avail_event(&vq->vq_ring);\r
-\r
-        return (vring_need_event(event_idx, new_idx, prev_idx) != 0);\r
-    }\r
-\r
-    return ((vq->vq_ring.used->flags & VRING_USED_F_NO_NOTIFY) == 0);\r
-}\r
-\r
-/**\r
- *\r
- * vq_ring_notify_host\r
- *\r
- */\r
-static void vq_ring_notify_host(struct virtqueue *vq) {\r
-\r
-    if (vq->notify != VQ_NULL)\r
-        vq->notify(vq);\r
-}\r
-\r
-/**\r
- *\r
- * virtqueue_nused\r
- *\r
- */\r
-static int virtqueue_nused(struct virtqueue *vq) {\r
-    uint16_t used_idx, nused;\r
-\r
-    used_idx = vq->vq_ring.used->idx;\r
-\r
-    nused = (uint16_t) (used_idx - vq->vq_used_cons_idx);\r
-    VQASSERT(vq, nused <= vq->vq_nentries, "used more than available");\r
-\r
-    return (nused);\r
-}\r
+/*-
+ * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
+ * 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 unmodified, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 "virtqueue.h"
+
+/* Prototype for internal functions. */
+static void vq_ring_init(struct virtqueue *);
+static void vq_ring_update_avail(struct virtqueue *, uint16_t);
+static uint16_t vq_ring_add_buffer(struct virtqueue *, struct vring_desc *,
+        uint16_t, struct llist *, int, int);
+static int vq_ring_enable_interrupt(struct virtqueue *, uint16_t);
+static void vq_ring_free_chain(struct virtqueue *, uint16_t);
+static int vq_ring_must_notify_host(struct virtqueue *vq);
+static void vq_ring_notify_host(struct virtqueue *vq);
+static int virtqueue_nused(struct virtqueue *vq);
+
+/**
+ * virtqueue_create - Creates new VirtIO queue
+ *
+ * @param device    - Pointer to VirtIO device
+ * @param id        - VirtIO queue ID , must be unique
+ * @param name      - Name of VirtIO queue
+ * @param ring      - Pointer to vring_alloc_info control block
+ * @param callback  - Pointer to callback function, invoked
+ *                    when message is available on VirtIO queue
+ * @param notify    - Pointer to notify function, used to notify
+ *                    other side that there is job available for it
+ * @param v_queue   - Created VirtIO queue.
+ *
+ * @return          - Function status
+ */
+int virtqueue_create(struct virtio_device *virt_dev, unsigned short id, char *name,
+        struct vring_alloc_info *ring, void (*callback)(struct virtqueue *vq),
+        void (*notify)(struct virtqueue *vq),
+        struct virtqueue **v_queue) {
+
+    struct virtqueue *vq = VQ_NULL;
+    int status = VQUEUE_SUCCESS;
+    uint32_t vq_size = 0;
+
+    VQ_PARAM_CHK(ring == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
+    VQ_PARAM_CHK(ring->num_descs == 0, status, ERROR_VQUEUE_INVLD_PARAM);
+    VQ_PARAM_CHK(ring->num_descs & (ring->num_descs - 1), status,
+            ERROR_VRING_ALIGN);
+
+    //TODO : Error check for indirect buffer addition
+
+    if (status == VQUEUE_SUCCESS) {
+
+        vq_size = sizeof(struct virtqueue)
+                + (ring->num_descs) * sizeof(struct vq_desc_extra);
+        vq = (struct virtqueue *) env_allocate_memory(vq_size);
+
+        if (vq == VQ_NULL) {
+            return (ERROR_NO_MEM);
+        }
+
+        env_memset(vq, 0x00, vq_size);
+
+        vq->vq_dev = virt_dev;
+        env_strncpy(vq->vq_name, name, VIRTQUEUE_MAX_NAME_SZ);
+        vq->vq_queue_index = id;
+        vq->vq_alignment = ring->align;
+        vq->vq_nentries = ring->num_descs;
+        vq->vq_free_cnt = vq->vq_nentries;
+        vq->callback = callback;
+        vq->notify = notify;
+
+        //TODO : Whether we want to support indirect addition or not.
+        vq->vq_ring_size = vring_size(ring->num_descs, ring->align);
+        vq->vq_ring_mem = (void *) ring->phy_addr;
+
+        /* Initialize vring control block in virtqueue. */
+        vq_ring_init(vq);
+
+        /* Disable callbacks - will be enabled by the application
+         * once initialization is completed.
+         */
+        virtqueue_disable_cb(vq);
+
+        *v_queue = vq;
+
+        //TODO : Need to add cleanup in case of error used with the indirect buffer addition
+        //TODO: do we need to save the new queue in db based on its id
+    }
+
+    return (status);
+}
+
+/**
+ * virtqueue_add_buffer()   - Enqueues new buffer in vring for consumption
+ *                            by other side. Readable buffers are always
+ *                            inserted before writable buffers
+ *
+ * @param vq                - Pointer to VirtIO queue control block.
+ * @param buffer            - Pointer to buffer list
+ * @param readable          - Number of readable buffers
+ * @param writable          - Number of writable buffers
+ * @param cookie            - Pointer to hold call back data
+ *
+ * @return                  - Function status
+ */
+int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
+        int readable, int writable, void *cookie) {
+
+    struct vq_desc_extra *dxp = VQ_NULL;
+    int status = VQUEUE_SUCCESS;
+    uint16_t head_idx;
+    uint16_t idx;
+    int needed;
+
+    needed = readable + writable;
+
+    VQ_PARAM_CHK(vq == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
+    VQ_PARAM_CHK(needed < 1, status, ERROR_VQUEUE_INVLD_PARAM);
+    VQ_PARAM_CHK(vq->vq_free_cnt == 0, status, ERROR_VRING_FULL);
+
+    //TODO: Add parameters validation for indirect buffer addition
+
+    VQUEUE_BUSY(vq);
+
+    if (status == VQUEUE_SUCCESS) {
+
+        //TODO : Indirect buffer addition support
+
+        VQASSERT(vq, cookie != VQ_NULL, "enqueuing with no cookie");
+
+        head_idx = vq->vq_desc_head_idx;
+        VQ_RING_ASSERT_VALID_IDX(vq, head_idx);
+        dxp = &vq->vq_descx[head_idx];
+
+        VQASSERT(vq, (dxp->cookie == VQ_NULL), "cookie already exists for index");
+
+        dxp->cookie = cookie;
+        dxp->ndescs = needed;
+
+        /* Enqueue buffer onto the ring. */
+        idx = vq_ring_add_buffer(vq, vq->vq_ring.desc, head_idx, buffer,
+                readable, writable);
+
+        vq->vq_desc_head_idx = idx;
+        vq->vq_free_cnt -= needed;
+
+        if (vq->vq_free_cnt == 0)
+            VQ_RING_ASSERT_CHAIN_TERM(vq);
+        else
+            VQ_RING_ASSERT_VALID_IDX(vq, idx);
+
+        /*
+         * Update vring_avail control block fields so that other
+         * side can get buffer using it.
+         */
+        vq_ring_update_avail(vq, head_idx);
+    }
+
+    VQUEUE_IDLE(vq);
+
+    return (status);
+}
+
+/**
+ * virtqueue_add_single_buffer - Enqueues single buffer in vring
+ *
+ * @param vq                    - Pointer to VirtIO queue control block
+ * @param cookie                - Pointer to hold call back data
+ * @param buffer_addr           - Address of buffer
+ * @param len                   - Length of buffer
+ * @param writable              - If buffer writable
+ * @param has_next              - If buffers for subsequent call are
+ *                                to be chained
+ *
+ * @return                      - Function status
+ */
+int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
+        void *buffer_addr, uint32_t len, int writable, boolean has_next) {
+
+    struct vq_desc_extra *dxp;
+    struct vring_desc *dp;
+    uint16_t head_idx;
+    uint16_t idx;
+    int status = VQUEUE_SUCCESS;
+
+    VQ_PARAM_CHK(vq == VQ_NULL, status, ERROR_VQUEUE_INVLD_PARAM);
+    VQ_PARAM_CHK(vq->vq_free_cnt == 0, status, ERROR_VRING_FULL);
+
+    VQUEUE_BUSY(vq);
+
+    if (status == VQUEUE_SUCCESS) {
+
+        VQASSERT(vq, cookie != VQ_NULL, "enqueuing with no cookie");
+
+        head_idx = vq->vq_desc_head_idx;
+        dxp = &vq->vq_descx[head_idx];
+
+        dxp->cookie = cookie;
+        dxp->ndescs = 1;
+        idx = head_idx;
+
+        dp = &vq->vq_ring.desc[idx];
+        dp->addr = env_map_vatopa(buffer_addr);
+        dp->len = len;
+        dp->flags = 0;
+        idx = dp->next;
+
+        if (has_next)
+            dp->flags |= VRING_DESC_F_NEXT;
+        if (writable)
+            dp->flags |= VRING_DESC_F_WRITE;
+
+        vq->vq_desc_head_idx = idx;
+        vq->vq_free_cnt--;
+
+        if (vq->vq_free_cnt == 0)
+            VQ_RING_ASSERT_CHAIN_TERM(vq);
+        else
+            VQ_RING_ASSERT_VALID_IDX(vq, idx);
+
+        vq_ring_update_avail(vq, head_idx);
+    }
+
+    VQUEUE_IDLE(vq);
+
+    return (status);
+}
+
+/**
+ * virtqueue_get_buffer - Returns used buffers from VirtIO queue
+ *
+ * @param vq            - Pointer to VirtIO queue control block
+ * @param len           - Length of conumed buffer
+ *
+ * @return              - Pointer to used buffer
+ */
+void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len) {
+    struct vring_used_elem *uep;
+    void *cookie;
+    uint16_t used_idx, desc_idx;
+
+    if ((vq == VQ_NULL) || (vq->vq_used_cons_idx == vq->vq_ring.used->idx))
+        return (VQ_NULL);
+
+    VQUEUE_BUSY(vq);
+
+    used_idx = vq->vq_used_cons_idx++ & (vq->vq_nentries - 1);
+    uep = &vq->vq_ring.used->ring[used_idx];
+
+    env_rmb();
+
+    desc_idx = (uint16_t) uep->id;
+    if (len != VQ_NULL)
+        *len = uep->len;
+
+    vq_ring_free_chain(vq, desc_idx);
+
+    cookie = vq->vq_descx[desc_idx].cookie;
+    vq->vq_descx[desc_idx].cookie = VQ_NULL;
+
+    VQUEUE_IDLE(vq);
+
+    return (cookie);
+}
+
+/**
+ * virtqueue_free   - Frees VirtIO queue resources
+ *
+ * @param vq        - Pointer to VirtIO queue control block
+ *
+ */
+void virtqueue_free(struct virtqueue *vq) {
+
+    if (vq != VQ_NULL) {
+
+        if (vq->vq_free_cnt != vq->vq_nentries) {
+            env_print("\r\nWARNING %s: freeing non-empty virtqueue\r\n", vq->vq_name);
+        }
+
+        //TODO : Need to free indirect buffers here
+
+        if (vq->vq_ring_mem != VQ_NULL) {
+            vq->vq_ring_size = 0;
+            vq->vq_ring_mem = VQ_NULL;
+        }
+
+        env_free_memory(vq);
+    }
+}
+
+/**
+ * virtqueue_get_available_buffer   - Returns buffer available for use in the
+ *                                    VirtIO queue
+ *
+ * @param vq                        - Pointer to VirtIO queue control block
+ * @param avail_idx                 - Pointer to index used in vring desc table
+ * @param len                       - Length of buffer
+ *
+ * @return                          - Pointer to available buffer
+ */
+void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx,
+        uint32_t *len) {
+
+    uint16_t head_idx = 0;
+    void *buffer;
+
+    if (vq->vq_available_idx == vq->vq_ring.avail->idx) {
+        return (VQ_NULL);
+    }
+
+    VQUEUE_BUSY(vq);
+
+    head_idx = vq->vq_available_idx++ & (vq->vq_nentries - 1);
+    *avail_idx = vq->vq_ring.avail->ring[head_idx];
+
+    env_rmb();
+
+    buffer = env_map_patova(vq->vq_ring.desc[*avail_idx].addr);
+    *len = vq->vq_ring.desc[*avail_idx].len;
+
+    VQUEUE_IDLE(vq);
+
+    return (buffer);
+}
+
+/**
+ * virtqueue_add_consumed_buffer - Returns consumed buffer back to VirtIO queue
+ *
+ * @param vq                     - Pointer to VirtIO queue control block
+ * @param head_idx               - Index of vring desc containing used buffer
+ * @param len                    - Length of buffer
+ *
+ * @return                       - Function status
+ */
+int virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx,
+        uint32_t len) {
+
+    struct vring_used_elem *used_desc = VQ_NULL;
+    uint16_t used_idx;
+
+    if ((head_idx > vq->vq_nentries) || (head_idx < 0)) {
+        return (ERROR_VRING_NO_BUFF);
+    }
+
+    VQUEUE_BUSY(vq);
+
+    used_idx = vq->vq_ring.used->idx & (vq->vq_nentries - 1);
+    used_desc = &(vq->vq_ring.used->ring[used_idx]);
+    used_desc->id = head_idx;
+    used_desc->len = len;
+
+    env_wmb();
+
+    vq->vq_ring.used->idx++;
+
+    VQUEUE_IDLE(vq);
+
+    return (VQUEUE_SUCCESS);
+}
+
+/**
+ * virtqueue_enable_cb  - Enables callback generation
+ *
+ * @param vq            - Pointer to VirtIO queue control block
+ *
+ * @return              - Function status
+ */
+int virtqueue_enable_cb(struct virtqueue *vq) {
+
+    return (vq_ring_enable_interrupt(vq, 0));
+}
+
+/**
+ * virtqueue_enable_cb - Disables callback generation
+ *
+ * @param vq           - Pointer to VirtIO queue control block
+ *
+ */
+void virtqueue_disable_cb(struct virtqueue *vq) {
+
+    VQUEUE_BUSY(vq);
+
+    if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) {
+        vring_used_event(&vq->vq_ring)= vq->vq_used_cons_idx - vq->vq_nentries
+        - 1;
+    } else {
+        vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+    }
+
+    VQUEUE_IDLE(vq);
+}
+
+/**
+ * virtqueue_kick - Notifies other side that there is buffer available for it.
+ *
+ * @param vq      - Pointer to VirtIO queue control block
+ */
+void virtqueue_kick(struct virtqueue *vq) {
+
+    VQUEUE_BUSY(vq);
+
+    /* Ensure updated avail->idx is visible to host. */
+    env_mb();
+
+    if (vq_ring_must_notify_host(vq))
+        vq_ring_notify_host(vq);
+
+    vq->vq_queued_cnt = 0;
+
+    VQUEUE_IDLE(vq);
+}
+
+/**
+ * virtqueue_dump Dumps important virtqueue fields , use for debugging purposes
+ *
+ * @param vq - Pointer to VirtIO queue control block
+ */
+void virtqueue_dump(struct virtqueue *vq) {
+
+    if (vq == VQ_NULL)
+        return;
+
+    env_print("VQ: %s - size=%d; free=%d; used=%d; queued=%d; "
+            "desc_head_idx=%d; avail.idx=%d; used_cons_idx=%d; "
+            "used.idx=%d; avail.flags=0x%x; used.flags=0x%x\r\n", vq->vq_name,
+            vq->vq_nentries, vq->vq_free_cnt, virtqueue_nused(vq),
+            vq->vq_queued_cnt, vq->vq_desc_head_idx, vq->vq_ring.avail->idx,
+            vq->vq_used_cons_idx, vq->vq_ring.used->idx,
+            vq->vq_ring.avail->flags, vq->vq_ring.used->flags);
+}
+
+/**
+ * virtqueue_get_desc_size - Returns vring descriptor size
+ *
+ * @param vq            - Pointer to VirtIO queue control block
+ *
+ * @return              - Descriptor length
+ */
+uint32_t virtqueue_get_desc_size(struct virtqueue *vq) {
+    uint16_t head_idx = 0;
+    uint16_t avail_idx = 0;
+    uint32_t len = 0;
+
+    if (vq->vq_available_idx == vq->vq_ring.avail->idx) {
+        return (VQ_NULL);
+    }
+
+    VQUEUE_BUSY(vq);
+
+    head_idx = vq->vq_available_idx & (vq->vq_nentries - 1);
+    avail_idx = vq->vq_ring.avail->ring[head_idx];
+    len = vq->vq_ring.desc[avail_idx].len;
+
+    VQUEUE_IDLE(vq);
+
+    return (len);
+}
+/**************************************************************************
+ *                            Helper Functions                            *
+ **************************************************************************/
+
+/**
+ *
+ * vq_ring_add_buffer
+ *
+ */
+static uint16_t vq_ring_add_buffer(struct virtqueue *vq,
+        struct vring_desc *desc, uint16_t head_idx, struct llist *buffer,
+        int readable, int writable) {
+
+    struct vring_desc *dp;
+    int i, needed;
+    uint16_t idx;
+
+    needed = readable + writable;
+
+    for (i = 0, idx = head_idx; (i < needed && buffer != VQ_NULL);
+            i++, idx = dp->next, buffer = buffer->next) {
+
+        VQASSERT(vq, idx != VQ_RING_DESC_CHAIN_END,
+                "premature end of free desc chain");
+
+        dp = &desc[idx];
+        dp->addr = env_map_vatopa(buffer->data);
+        dp->len = buffer->attr;
+        dp->flags = 0;
+
+        if (i < needed - 1)
+            dp->flags |= VRING_DESC_F_NEXT;
+
+        /* Readable buffers are inserted into vring before the writable buffers.*/
+        if (i >= readable)
+            dp->flags |= VRING_DESC_F_WRITE;
+    }
+
+    return (idx);
+}
+
+/**
+ *
+ * vq_ring_free_chain
+ *
+ */
+static void vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx) {
+    struct vring_desc *dp;
+    struct vq_desc_extra *dxp;
+
+    VQ_RING_ASSERT_VALID_IDX(vq, desc_idx);
+    dp = &vq->vq_ring.desc[desc_idx];
+    dxp = &vq->vq_descx[desc_idx];
+
+    if (vq->vq_free_cnt == 0)
+        VQ_RING_ASSERT_CHAIN_TERM(vq);
+
+    vq->vq_free_cnt += dxp->ndescs;
+    dxp->ndescs--;
+
+    if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) {
+        while (dp->flags & VRING_DESC_F_NEXT) {
+            VQ_RING_ASSERT_VALID_IDX(vq, dp->next);
+            dp = &vq->vq_ring.desc[dp->next];
+            dxp->ndescs--;
+        }
+    }
+
+    VQASSERT(vq, (dxp->ndescs == 0),
+            "failed to free entire desc chain, remaining");
+
+    /*
+     * We must append the existing free chain, if any, to the end of
+     * newly freed chain. If the virtqueue was completely used, then
+     * head would be VQ_RING_DESC_CHAIN_END (ASSERTed above).
+     */
+    dp->next = vq->vq_desc_head_idx;
+    vq->vq_desc_head_idx = desc_idx;
+}
+
+/**
+ *
+ * vq_ring_init
+ *
+ */
+static void vq_ring_init(struct virtqueue *vq) {
+    struct vring *vr;
+    unsigned char *ring_mem;
+    int i, size;
+
+    ring_mem = vq->vq_ring_mem;
+    size = vq->vq_nentries;
+    vr = &vq->vq_ring;
+
+    vring_init(vr, size, ring_mem, vq->vq_alignment);
+
+    for (i = 0; i < size - 1; i++)
+        vr->desc[i].next = i + 1;
+    vr->desc[i].next = VQ_RING_DESC_CHAIN_END;
+}
+
+/**
+ *
+ * vq_ring_update_avail
+ *
+ */
+static void vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx) {
+    uint16_t avail_idx;
+
+    /*
+     * Place the head of the descriptor chain into the next slot and make
+     * it usable to the host. The chain is made available now rather than
+     * deferring to virtqueue_notify() in the hopes that if the host is
+     * currently running on another CPU, we can keep it processing the new
+     * descriptor.
+     */
+    avail_idx = vq->vq_ring.avail->idx & (vq->vq_nentries - 1);
+    vq->vq_ring.avail->ring[avail_idx] = desc_idx;
+
+    env_wmb();
+
+    vq->vq_ring.avail->idx++;
+
+    /* Keep pending count until virtqueue_notify(). */
+    vq->vq_queued_cnt++;
+}
+
+/**
+ *
+ * vq_ring_enable_interrupt
+ *
+ */
+static int vq_ring_enable_interrupt(struct virtqueue *vq, uint16_t ndesc) {
+
+    /*
+     * Enable interrupts, making sure we get the latest index of
+     * what's already been consumed.
+     */
+    if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) {
+        vring_used_event(&vq->vq_ring)= vq->vq_used_cons_idx + ndesc;
+    } else {
+        vq->vq_ring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
+    }
+
+    env_mb();
+
+    /*
+     * Enough items may have already been consumed to meet our threshold
+     * since we last checked. Let our caller know so it processes the new
+     * entries.
+     */
+    if (virtqueue_nused(vq) > ndesc) {
+        return (1);
+    }
+
+    return (0);
+}
+
+/**
+ *
+ * virtqueue_interrupt
+ *
+ */
+void virtqueue_notification(struct virtqueue *vq) {
+
+    if (vq->callback != VQ_NULL)
+        vq->callback(vq);
+}
+
+/**
+ *
+ * vq_ring_must_notify_host
+ *
+ */
+static int vq_ring_must_notify_host(struct virtqueue *vq) {
+    uint16_t new_idx, prev_idx, event_idx;
+
+    if (vq->vq_flags & VIRTQUEUE_FLAG_EVENT_IDX) {
+        new_idx = vq->vq_ring.avail->idx;
+        prev_idx = new_idx - vq->vq_queued_cnt;
+        event_idx = vring_avail_event(&vq->vq_ring);
+
+        return (vring_need_event(event_idx, new_idx, prev_idx) != 0);
+    }
+
+    return ((vq->vq_ring.used->flags & VRING_USED_F_NO_NOTIFY) == 0);
+}
+
+/**
+ *
+ * vq_ring_notify_host
+ *
+ */
+static void vq_ring_notify_host(struct virtqueue *vq) {
+
+    if (vq->notify != VQ_NULL)
+        vq->notify(vq);
+}
+
+/**
+ *
+ * virtqueue_nused
+ *
+ */
+static int virtqueue_nused(struct virtqueue *vq) {
+    uint16_t used_idx, nused;
+
+    used_idx = vq->vq_ring.used->idx;
+
+    nused = (uint16_t) (used_idx - vq->vq_used_cons_idx);
+    VQASSERT(vq, nused <= vq->vq_nentries, "used more than available");
+
+    return (nused);
+}
index 3362d5e9a4144a70c1765643b424c3721a405ee0..d86dbb8dfeeed00bc45b6bac6e78873d07db8099 100644 (file)
-#ifndef VIRTQUEUE_H_\r
-#define VIRTQUEUE_H_\r
-\r
-/*-\r
- * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- * 1. Redistributions of source code must retain the above copyright\r
- *    notice unmodified, this list of conditions, and the following\r
- *    disclaimer.\r
- * 2. Redistributions in binary form must reproduce the above copyright\r
- *    notice, this list of conditions and the following disclaimer in the\r
- *    documentation and/or other materials provided with the distribution.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- *\r
- * $FreeBSD$\r
- */\r
-\r
-#include <stdint.h>\r
-typedef         uint8_t                             boolean;\r
-\r
-#include "virtio_ring.h"\r
-#include "../porting/env/env.h"\r
-#include "../common/llist/llist.h"\r
-\r
-/*Error Codes*/\r
-#define VQ_ERROR_BASE                                 -3000\r
-#define ERROR_VRING_FULL                              (VQ_ERROR_BASE - 1)\r
-#define ERROR_INVLD_DESC_IDX                          (VQ_ERROR_BASE - 2)\r
-#define ERROR_EMPTY_RING                              (VQ_ERROR_BASE - 3)\r
-#define ERROR_NO_MEM                                  (VQ_ERROR_BASE - 4)\r
-#define ERROR_VRING_MAX_DESC                          (VQ_ERROR_BASE - 5)\r
-#define ERROR_VRING_ALIGN                             (VQ_ERROR_BASE - 6)\r
-#define ERROR_VRING_NO_BUFF                           (VQ_ERROR_BASE - 7)\r
-#define ERROR_VQUEUE_INVLD_PARAM                      (VQ_ERROR_BASE - 8)\r
-\r
-#define true                                          1\r
-#define false                                         0\r
-#define VQUEUE_SUCCESS                                0\r
-#define VQUEUE_DEBUG                                  false\r
-\r
-//TODO:\r
-/* This is temporary macro to replace C NULL support.\r
- * At the moment all the RTL specific functions are present in env.\r
- * */\r
-#define VQ_NULL                                       0\r
-\r
-/* The maximum virtqueue size is 2^15. Use that value as the end of\r
- * descriptor chain terminator since it will never be a valid index\r
- * in the descriptor table. This is used to verify we are correctly\r
- * handling vq_free_cnt.\r
- */\r
-#define VQ_RING_DESC_CHAIN_END                         32768\r
-#define VIRTQUEUE_FLAG_INDIRECT                        0x0001\r
-#define VIRTQUEUE_FLAG_EVENT_IDX                       0x0002\r
-#define VIRTQUEUE_MAX_NAME_SZ                          32\r
-\r
-/* Support for indirect buffer descriptors. */\r
-#define VIRTIO_RING_F_INDIRECT_DESC    (1 << 28)\r
-\r
-/* Support to suppress interrupt until specific index is reached. */\r
-#define VIRTIO_RING_F_EVENT_IDX        (1 << 29)\r
-\r
-/*\r
- * Hint on how long the next interrupt should be postponed. This is\r
- * only used when the EVENT_IDX feature is negotiated.\r
- */\r
-typedef enum {\r
-    VQ_POSTPONE_SHORT,\r
-    VQ_POSTPONE_LONG,\r
-    VQ_POSTPONE_EMPTIED    /* Until all available desc are used. */\r
-} vq_postpone_t;\r
-\r
-struct virtqueue {\r
-    //TODO: Need to define proper structure for\r
-    //        virtio device with RPmsg and paravirtualization.\r
-\r
-    struct virtio_device *vq_dev;\r
-    char vq_name[VIRTQUEUE_MAX_NAME_SZ];\r
-    uint16_t vq_queue_index;\r
-    uint16_t vq_nentries;\r
-    uint32_t vq_flags;\r
-    int vq_alignment;\r
-    int vq_ring_size;\r
-    boolean vq_inuse;\r
-    void *vq_ring_mem;\r
-    void (*callback)(struct virtqueue *vq);\r
-    void (*notify)(struct virtqueue *vq);\r
-    int vq_max_indirect_size;\r
-    int vq_indirect_mem_size;\r
-    struct vring vq_ring;\r
-    uint16_t vq_free_cnt;\r
-    uint16_t vq_queued_cnt;\r
-\r
-    /*\r
-     * Head of the free chain in the descriptor table. If\r
-     * there are no free descriptors, this will be set to\r
-     * VQ_RING_DESC_CHAIN_END.\r
-     */\r
-    uint16_t vq_desc_head_idx;\r
-\r
-    /*\r
-     * Last consumed descriptor in the used table,\r
-     * trails vq_ring.used->idx.\r
-     */\r
-    uint16_t vq_used_cons_idx;\r
-\r
-    /*\r
-     * Last consumed descriptor in the available table -\r
-     * used by the consumer side.\r
-     */\r
-    uint16_t vq_available_idx;\r
-\r
-    uint8_t padd;\r
-\r
-    /*\r
-     * Used by the host side during callback. Cookie\r
-     * holds the address of buffer received from other side.\r
-     * Other fields in this structure are not used currently.\r
-     */\r
-\r
-    struct vq_desc_extra {\r
-        void *cookie;\r
-        struct vring_desc *indirect;\r
-        uint32_t indirect_paddr;\r
-        uint16_t ndescs;\r
-    } vq_descx[0];\r
-};\r
-\r
-/* struct to hold vring specific information */\r
-struct vring_alloc_info {\r
-    void         *phy_addr;\r
-    uint32_t     align;\r
-    uint16_t     num_descs;\r
-    uint16_t     pad;\r
-};\r
-\r
-typedef void   vq_callback(struct virtqueue *);\r
-typedef void   vq_notify(struct virtqueue *);\r
-\r
-#if (VQUEUE_DEBUG == true)\r
-\r
-#define VQASSERT(_vq, _exp, _msg) do{ \\r
-    if (!(_exp)){ env_print("%s: %s - "_msg, __func__, (_vq)->vq_name); while(1);} \\r
-    } while(0)\r
-\r
-#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx)            \\r
-    VQASSERT((_vq), (_idx) < (_vq)->vq_nentries,        \\r
-    "invalid ring index")\r
-\r
-#define VQ_RING_ASSERT_CHAIN_TERM(_vq)                \\r
-    VQASSERT((_vq), (_vq)->vq_desc_head_idx ==            \\r
-    VQ_RING_DESC_CHAIN_END,    "full ring terminated incorrectly: invalid head")\r
-\r
-#define VQ_PARAM_CHK(condition, status_var, status_err)                 \\r
-                       if ((status_var == 0) && (condition))            \\r
-                       {                                                \\r
-                           status_var = status_err;                     \\r
-                       }\r
-\r
-#define VQUEUE_BUSY(vq)         if ((vq)->vq_inuse == false)                 \\r
-                                    (vq)->vq_inuse = true;                   \\r
-                                else                                         \\r
-                                    VQASSERT(vq, (vq)->vq_inuse == false,    \\r
-                                        "VirtQueue already in use")\r
-\r
-#define VQUEUE_IDLE(vq)            ((vq)->vq_inuse = false)\r
-\r
-#else\r
-\r
-#define KASSERT(cond, str)\r
-#define VQASSERT(_vq, _exp, _msg)\r
-#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx)\r
-#define VQ_RING_ASSERT_CHAIN_TERM(_vq)\r
-#define VQ_PARAM_CHK(condition, status_var, status_err)\r
-#define VQUEUE_BUSY(vq)\r
-#define VQUEUE_IDLE(vq)\r
-\r
-#endif\r
-\r
-int virtqueue_create(struct virtio_device *device, unsigned short id, char *name,\r
-        struct vring_alloc_info *ring, void (*callback)(struct virtqueue *vq),\r
-        void (*notify)(struct virtqueue *vq), struct virtqueue **v_queue);\r
-\r
-int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,\r
-        int readable, int writable, void *cookie);\r
-\r
-int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,\r
-        void* buffer_addr, uint32_t len, int writable, boolean has_next);\r
-\r
-void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len);\r
-\r
-void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx,\r
-        uint32_t *len);\r
-\r
-int virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx,\r
-        uint32_t len);\r
-\r
-void virtqueue_disable_cb(struct virtqueue *vq);\r
-\r
-int virtqueue_enable_cb(struct virtqueue *vq);\r
-\r
-void virtqueue_kick(struct virtqueue *vq);\r
-\r
-void virtqueue_free(struct virtqueue *vq);\r
-\r
-void virtqueue_dump(struct virtqueue *vq);\r
-\r
-void virtqueue_notification(struct virtqueue *vq);\r
-\r
-uint32_t virtqueue_get_desc_size(struct virtqueue *vq);\r
-\r
-#endif /* VIRTQUEUE_H_ */\r
+#ifndef VIRTQUEUE_H_
+#define VIRTQUEUE_H_
+
+/*-
+ * Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
+ * 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 unmodified, 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <stdint.h>
+typedef         uint8_t                             boolean;
+
+#include "virtio_ring.h"
+#include "../porting/env/env.h"
+#include "../common/llist/llist.h"
+
+/*Error Codes*/
+#define VQ_ERROR_BASE                                 -3000
+#define ERROR_VRING_FULL                              (VQ_ERROR_BASE - 1)
+#define ERROR_INVLD_DESC_IDX                          (VQ_ERROR_BASE - 2)
+#define ERROR_EMPTY_RING                              (VQ_ERROR_BASE - 3)
+#define ERROR_NO_MEM                                  (VQ_ERROR_BASE - 4)
+#define ERROR_VRING_MAX_DESC                          (VQ_ERROR_BASE - 5)
+#define ERROR_VRING_ALIGN                             (VQ_ERROR_BASE - 6)
+#define ERROR_VRING_NO_BUFF                           (VQ_ERROR_BASE - 7)
+#define ERROR_VQUEUE_INVLD_PARAM                      (VQ_ERROR_BASE - 8)
+
+#define true                                          1
+#define false                                         0
+#define VQUEUE_SUCCESS                                0
+#define VQUEUE_DEBUG                                  false
+
+//TODO:
+/* This is temporary macro to replace C NULL support.
+ * At the moment all the RTL specific functions are present in env.
+ * */
+#define VQ_NULL                                       0
+
+/* The maximum virtqueue size is 2^15. Use that value as the end of
+ * descriptor chain terminator since it will never be a valid index
+ * in the descriptor table. This is used to verify we are correctly
+ * handling vq_free_cnt.
+ */
+#define VQ_RING_DESC_CHAIN_END                         32768
+#define VIRTQUEUE_FLAG_INDIRECT                        0x0001
+#define VIRTQUEUE_FLAG_EVENT_IDX                       0x0002
+#define VIRTQUEUE_MAX_NAME_SZ                          32
+
+/* Support for indirect buffer descriptors. */
+#define VIRTIO_RING_F_INDIRECT_DESC    (1 << 28)
+
+/* Support to suppress interrupt until specific index is reached. */
+#define VIRTIO_RING_F_EVENT_IDX        (1 << 29)
+
+/*
+ * Hint on how long the next interrupt should be postponed. This is
+ * only used when the EVENT_IDX feature is negotiated.
+ */
+typedef enum {
+    VQ_POSTPONE_SHORT,
+    VQ_POSTPONE_LONG,
+    VQ_POSTPONE_EMPTIED    /* Until all available desc are used. */
+} vq_postpone_t;
+
+struct virtqueue {
+    //TODO: Need to define proper structure for
+    //        virtio device with RPmsg and paravirtualization.
+
+    struct virtio_device *vq_dev;
+    char vq_name[VIRTQUEUE_MAX_NAME_SZ];
+    uint16_t vq_queue_index;
+    uint16_t vq_nentries;
+    uint32_t vq_flags;
+    int vq_alignment;
+    int vq_ring_size;
+    boolean vq_inuse;
+    void *vq_ring_mem;
+    void (*callback)(struct virtqueue *vq);
+    void (*notify)(struct virtqueue *vq);
+    int vq_max_indirect_size;
+    int vq_indirect_mem_size;
+    struct vring vq_ring;
+    uint16_t vq_free_cnt;
+    uint16_t vq_queued_cnt;
+
+    /*
+     * Head of the free chain in the descriptor table. If
+     * there are no free descriptors, this will be set to
+     * VQ_RING_DESC_CHAIN_END.
+     */
+    uint16_t vq_desc_head_idx;
+
+    /*
+     * Last consumed descriptor in the used table,
+     * trails vq_ring.used->idx.
+     */
+    uint16_t vq_used_cons_idx;
+
+    /*
+     * Last consumed descriptor in the available table -
+     * used by the consumer side.
+     */
+    uint16_t vq_available_idx;
+
+    uint8_t padd;
+
+    /*
+     * Used by the host side during callback. Cookie
+     * holds the address of buffer received from other side.
+     * Other fields in this structure are not used currently.
+     */
+
+    struct vq_desc_extra {
+        void *cookie;
+        struct vring_desc *indirect;
+        uint32_t indirect_paddr;
+        uint16_t ndescs;
+    } vq_descx[0];
+};
+
+/* struct to hold vring specific information */
+struct vring_alloc_info {
+    void         *phy_addr;
+    uint32_t     align;
+    uint16_t     num_descs;
+    uint16_t     pad;
+};
+
+typedef void   vq_callback(struct virtqueue *);
+typedef void   vq_notify(struct virtqueue *);
+
+#if (VQUEUE_DEBUG == true)
+
+#define VQASSERT(_vq, _exp, _msg) do{ \
+    if (!(_exp)){ env_print("%s: %s - "_msg, __func__, (_vq)->vq_name); while(1);} \
+    } while(0)
+
+#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx)            \
+    VQASSERT((_vq), (_idx) < (_vq)->vq_nentries,        \
+    "invalid ring index")
+
+#define VQ_RING_ASSERT_CHAIN_TERM(_vq)                \
+    VQASSERT((_vq), (_vq)->vq_desc_head_idx ==            \
+    VQ_RING_DESC_CHAIN_END,    "full ring terminated incorrectly: invalid head")
+
+#define VQ_PARAM_CHK(condition, status_var, status_err)                 \
+                       if ((status_var == 0) && (condition))            \
+                       {                                                \
+                           status_var = status_err;                     \
+                       }
+
+#define VQUEUE_BUSY(vq)         if ((vq)->vq_inuse == false)                 \
+                                    (vq)->vq_inuse = true;                   \
+                                else                                         \
+                                    VQASSERT(vq, (vq)->vq_inuse == false,    \
+                                        "VirtQueue already in use")
+
+#define VQUEUE_IDLE(vq)            ((vq)->vq_inuse = false)
+
+#else
+
+#define KASSERT(cond, str)
+#define VQASSERT(_vq, _exp, _msg)
+#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx)
+#define VQ_RING_ASSERT_CHAIN_TERM(_vq)
+#define VQ_PARAM_CHK(condition, status_var, status_err)
+#define VQUEUE_BUSY(vq)
+#define VQUEUE_IDLE(vq)
+
+#endif
+
+int virtqueue_create(struct virtio_device *device, unsigned short id, char *name,
+        struct vring_alloc_info *ring, void (*callback)(struct virtqueue *vq),
+        void (*notify)(struct virtqueue *vq), struct virtqueue **v_queue);
+
+int virtqueue_add_buffer(struct virtqueue *vq, struct llist *buffer,
+        int readable, int writable, void *cookie);
+
+int virtqueue_add_single_buffer(struct virtqueue *vq, void *cookie,
+        void* buffer_addr, uint32_t len, int writable, boolean has_next);
+
+void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len);
+
+void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx,
+        uint32_t *len);
+
+int virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx,
+        uint32_t len);
+
+void virtqueue_disable_cb(struct virtqueue *vq);
+
+int virtqueue_enable_cb(struct virtqueue *vq);
+
+void virtqueue_kick(struct virtqueue *vq);
+
+void virtqueue_free(struct virtqueue *vq);
+
+void virtqueue_dump(struct virtqueue *vq);
+
+void virtqueue_notification(struct virtqueue *vq);
+
+uint32_t virtqueue_get_desc_size(struct virtqueue *vq);
+
+#endif /* VIRTQUEUE_H_ */