summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 98b7ca1)
raw | patch | inline | side by side (parent: 98b7ca1)
author | Wendy Liang <jliang@xilinx.com> | |
Tue, 5 Jan 2016 22:43:36 +0000 (14:43 -0800) | ||
committer | Wendy 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:
diff --git a/apps/samples/remote/baremetal/rpc_demo/rsc_table.h b/apps/samples/remote/baremetal/rpc_demo/rsc_table.h
index 60b602e45e2c22da03c7b52682b6c9129fdd0717..60a0548878e2d4f09cfb5add16a2feefdc0175ec 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 <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;
+};
+
diff --git a/apps/tests/remote/baremetal/echo_test/rsc_table.c b/apps/tests/remote/baremetal/echo_test/rsc_table.c
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
+ },
+};
+
diff --git a/apps/tests/remote/baremetal/echo_test/rsc_table.h b/apps/tests/remote/baremetal/echo_test/rsc_table.h
index a045d03fba16e335fb6dad527596f1c5e6a63dc6..cc0e11801d810aa5d0cffe51cf048206776adfc2 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 <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;
+};
+
diff --git a/apps/tests/remote/baremetal/func_test_suite/rsc_table.c b/apps/tests/remote/baremetal/func_test_suite/rsc_table.c
index 85b11b1dc71953d84074687831febb322bb1ecd1..af8e0e11f40f4518127a96984860c1d6c52cbf93 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
-/* 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
+ },
+};
diff --git a/apps/tests/remote/baremetal/func_test_suite/rsc_table.h b/apps/tests/remote/baremetal/func_test_suite/rsc_table.h
index 0a8e95750d5d919b1fe9ece8236a632fc84d1801..842b423db71351e24b6513a14f1be348eb7b9def 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
-/* 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;
+};
+
diff --git a/common/hil/hil.c b/common/hil/hil.c
index 69df0599abd437dba2d52a85ce983cab15a20773..31e1a71eef95155dc0769b116dcef0bbf664b98b 100644 (file)
--- a/common/hil/hil.c
+++ b/common/hil/hil.c
-/*\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));
+}
diff --git a/common/hil/hil.h b/common/hil/hil.h
index 3f276c962bbf9d183d7f6af20acfa36322b9ecbd..0f5ce2d2c939737c2efcad1a60c149b3c95ab340 100644 (file)
--- a/common/hil/hil.h
+++ b/common/hil/hil.h
-#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 .
*/
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_ */
diff --git a/common/llist/llist.c b/common/llist/llist.c
index 6c9c5ccb3751ab35564abb8e3d00d9ab40c63284..37e888c0d491a658aa74a0a986b63975bd5c42ee 100644 (file)
--- a/common/llist/llist.c
+++ b/common/llist/llist.c
-/*\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;
+ }
+}
diff --git a/common/llist/llist.h b/common/llist/llist.h
index 19091693b3717e8d33d8fba4619b8d077eb4fbfb..004f4e09247771487bc14c4cff1be10d915748a0 100644 (file)
--- a/common/llist/llist.h
+++ b/common/llist/llist.h
-/*\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_ */
diff --git a/common/shm/sh_mem.c b/common/shm/sh_mem.c
index 100a336f2016ee66f54996c6692adca62a0c1841..6a290a4802be4ca329aadba27c873adcad8c50c3 100644 (file)
--- a/common/shm/sh_mem.c
+++ b/common/shm/sh_mem.c
-/*\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;
+}
diff --git a/common/shm/sh_mem.h b/common/shm/sh_mem.h
index 65c97df6674dc981daebb658d4fba8a579f15936..4ba830b7fc2114ed5a76b19dfccd8079b6caa45d 100644 (file)
--- a/common/shm/sh_mem.h
+++ b/common/shm/sh_mem.h
-/*\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_ */
diff --git a/include/open_amp.h b/include/open_amp.h
index 03b6ddbe94d22955f7d4b6e14bf6a630d8a88161..7507bd881595eb1d33dc32f850cf9658116096a1 100644 (file)
--- a/include/open_amp.h
+++ b/include/open_amp.h
-/*\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)
-/*\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)
-/*\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)
--- a/porting/config/config.c
+++ b/porting/config/config.c
-/*\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)
--- a/porting/config/config.h
+++ b/porting/config/config.h
-/*\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
diff --git a/porting/env/env.h b/porting/env/env.h
index c90b74cf5ac182afd4a63614d552354464f2b0e1..a02ad37884be5e515e8bd5262c19972341599736 100644 (file)
--- a/porting/env/env.h
+++ b/porting/env/env.h
-/*\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)
-/*\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)
--- a/remoteproc/elf_loader.c
+++ b/remoteproc/elf_loader.c
-/*\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)
--- a/remoteproc/elf_loader.h
+++ b/remoteproc/elf_loader.h
-/*\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)
-/*\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)
-/*\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 */
diff --git a/rpmsg/remote_device.c b/rpmsg/remote_device.c
index d7f694571183f83567870c0e14a0793d1f7dc3a1..29e721ca1b5d72fbfd2c54ceccd91d365a03ed38 100644 (file)
--- a/rpmsg/remote_device.c
+++ b/rpmsg/remote_device.c
-/*\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;
+}
diff --git a/rpmsg/rpmsg.c b/rpmsg/rpmsg.c
index 630f110b49b37f87e06debabd3f60261d0154671..0066fca02d08e53c7cbed1a0f35302b85e2d5c40 100644 (file)
--- a/rpmsg/rpmsg.c
+++ b/rpmsg/rpmsg.c
-/*\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;
+}
diff --git a/rpmsg/rpmsg_core.h b/rpmsg/rpmsg_core.h
index 4586333e1b021b6d8ead20263c51f3bb66225db5..95f4e5605e1b811228d0ce5c45d8133393dd4215 100644 (file)
--- a/rpmsg/rpmsg_core.h
+++ b/rpmsg/rpmsg_core.h
-/*\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_ */
diff --git a/virtio/virtio.h b/virtio/virtio.h
index 19ea191b88836df4e3eb92734eb723907af59e08..ab11dcdc08ea884f6d10fde8e696e1d4db71ca63 100644 (file)
--- a/virtio/virtio.h
+++ b/virtio/virtio.h
-/*-\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_ */
diff --git a/virtio/virtio_ring.h b/virtio/virtio_ring.h
index 966602a656fb83889706f353888fb4a4325fd763..8e902ab59c2bc1ba37d6e13ca1dd85a1b9383a26 100644 (file)
--- a/virtio/virtio_ring.h
+++ b/virtio/virtio_ring.h
-/*-\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 */
diff --git a/virtio/virtqueue.c b/virtio/virtqueue.c
index 4286b4d9145957500e34854a08f03b330dafc018..5bc91cd8cfc2924a80056c16e4e15411a2c577f6 100644 (file)
--- a/virtio/virtqueue.c
+++ b/virtio/virtqueue.c
-/*-\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);
+}
diff --git a/virtio/virtqueue.h b/virtio/virtqueue.h
index 3362d5e9a4144a70c1765643b424c3721a405ee0..d86dbb8dfeeed00bc45b6bac6e78873d07db8099 100644 (file)
--- a/virtio/virtqueue.h
+++ b/virtio/virtqueue.h
-#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_ */