[LIBMETAL PATCH 0/8] Remove I/O mem map API and update I/O block write/read/set APIs

172 views
Skip to first unread message

Wendy Liang

unread,
Jun 1, 2017, 12:48:08 PM6/1/17
to open...@googlegroups.com, Wendy Liang
This patch series do the following changes:
* remove I/O memory mapping APIs
* Add I/O block write/read/set APIs
* remove I/O memory copy and set APIs

The old I/O memory map and I/O memory copy and set APIs requires user API to
know the details of the memory region attributes to decide what memory APIs
to use, which is against the idea to provide I/O memory region operations.


Wendy Liang (8):
limit OS/platform specific APIs for internal usage
io: ops: Add io block_write/read/set ops
examples: use I/O region block_write/read
sys: Add macro for bad virtual address
io: remove I/O memory copy/set APIs
io: remove io_mem_map user API
examples: not use obsolete io_mem_map
FreeRTOS/generic: register generic bus in metal_init

.../zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c | 78 ++++++------
.../generic/zynqmp_r5/zynqmp_amp_demo/sys_init.c | 11 +-
.../zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c | 76 ++++++------
.../zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c | 76 ++++++------
lib/device.c | 2 +-
lib/device.h | 4 +
lib/io.c | 131 +++++++++++++++------
lib/io.h | 94 +++++++--------
lib/sys.h | 3 +
lib/system/freertos/CMakeLists.txt | 2 +-
lib/system/freertos/device.c | 64 ++++++++++
lib/system/freertos/init.c | 2 +
lib/system/freertos/io.c | 48 --------
lib/system/freertos/sys.h | 6 +
lib/system/freertos/zynq7/sys.c | 52 +-------
lib/system/freertos/zynq7/sys.h | 2 +
lib/system/freertos/zynqmp_r5/sys.c | 27 +----
lib/system/freertos/zynqmp_r5/sys.h | 2 +
lib/system/generic/CMakeLists.txt | 2 +-
lib/system/generic/device.c | 66 +++++++++++
lib/system/generic/init.c | 3 +
lib/system/generic/io.c | 48 --------
lib/system/generic/sys.h | 6 +
lib/system/generic/zynq7/sys.c | 53 +--------
lib/system/generic/zynq7/sys.h | 2 +
lib/system/generic/zynqmp_r5/sys.c | 27 +----
lib/system/generic/zynqmp_r5/sys.h | 2 +
lib/system/linux/CMakeLists.txt | 1 -
lib/system/linux/device.c | 10 +-
lib/system/linux/io.c | 44 -------
lib/system/linux/shmem.c | 2 +-
31 files changed, 461 insertions(+), 485 deletions(-)
create mode 100644 lib/system/freertos/device.c
delete mode 100644 lib/system/freertos/io.c
create mode 100644 lib/system/generic/device.c
delete mode 100644 lib/system/generic/io.c
delete mode 100644 lib/system/linux/io.c

--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:20 PM6/1/17
to open...@googlegroups.com, Wendy Liang
Register generic bus in the metal_init() for generic and
FreeRTOS system.

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
lib/system/freertos/init.c | 2 ++
lib/system/generic/init.c | 3 +++
2 files changed, 5 insertions(+)

diff --git a/lib/system/freertos/init.c b/lib/system/freertos/init.c
index e667b0f..fcf4782 100644
--- a/lib/system/freertos/init.c
+++ b/lib/system/freertos/init.c
@@ -44,10 +44,12 @@ struct metal_state _metal;
int metal_sys_init(const struct metal_init_params *params)
{
metal_unused(params);
+ metal_bus_register(&metal_generic_bus);
return metal_irq_init();
}

void metal_sys_finish(void)
{
metal_irq_deinit();
+ metal_bus_unregister(&metal_generic_bus);
}
diff --git a/lib/system/generic/init.c b/lib/system/generic/init.c
index 89f6361..10d6b51 100644
--- a/lib/system/generic/init.c
+++ b/lib/system/generic/init.c
@@ -35,6 +35,7 @@

#include "metal/sys.h"
#include "metal/utilities.h"
+#include "metal/device.h"

extern int metal_irq_init(void);
extern void metal_irq_deinit(void);
@@ -44,10 +45,12 @@ struct metal_state _metal;
int metal_sys_init(const struct metal_init_params *params)
{
metal_unused(params);
+ metal_bus_register(&metal_generic_bus);
return metal_irq_init();
}

void metal_sys_finish(void)
{
metal_irq_deinit();
+ metal_bus_unregister(&metal_generic_bus);
}
--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:20 PM6/1/17
to open...@googlegroups.com, Wendy Liang
Add a macro for bad virtual address.

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
lib/io.h | 6 +-----
lib/sys.h | 3 +++
2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/lib/io.h b/lib/io.h
index eba7c2f..1f76003 100644
--- a/lib/io.h
+++ b/lib/io.h
@@ -167,11 +167,7 @@ static inline size_t metal_io_region_size(struct metal_io_region *io)
static inline void *
metal_io_virt(struct metal_io_region *io, unsigned long offset)
{
-#ifdef METAL_INVALID_IO_VADDR
- return (io->virt != METAL_INVALID_IO_VADDR && offset <= io->size
-#else
- return (offset <= io->size
-#endif
+ return (io->virt != METAL_BAD_VA && offset <= io->size
? (uint8_t *)io->virt + offset
: NULL);
}
diff --git a/lib/sys.h b/lib/sys.h
index 7802784..2638c38 100644
--- a/lib/sys.h
+++ b/lib/sys.h
@@ -61,6 +61,9 @@ typedef int metal_irq_t;
/** Bad physical address value. */
#define METAL_BAD_PHYS ((metal_phys_addr_t)-1)

+/** Bad virtual address value. */
+#define METAL_BAD_VA ((void *)-1)
+
/** Bad IRQ. */
#define METAL_BAD_IRQ ((metal_irq_t)-1)

--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:20 PM6/1/17
to open...@googlegroups.com, Wendy Liang
As io_mem_map is removed, do not use it in the examples

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
.../zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c | 19 ----------------
.../generic/zynqmp_r5/zynqmp_amp_demo/sys_init.c | 11 +++++-----
.../zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c | 25 +---------------------
.../zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c | 20 -----------------
4 files changed, 7 insertions(+), 68 deletions(-)

diff --git a/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c b/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c
index 42393e6..948b8bd 100644
--- a/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c
+++ b/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c
@@ -412,12 +412,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }

/* Store the shared memory0 descriptor device and I/O region */
ch0.shm0_desc_dev = device;
@@ -440,13 +434,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }
-
/* Store the shared memory1 descriptor device and I/O region */
ch0.shm1_desc_dev = device;
ch0.shm1_desc_io = io;
@@ -467,12 +454,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }

/* Store the shared memory device and I/O region */
ch0.shm_dev = device;
diff --git a/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/sys_init.c b/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/sys_init.c
index aef846e..f628feb 100644
--- a/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/sys_init.c
+++ b/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/sys_init.c
@@ -35,6 +35,7 @@
#include "xil_exception.h"
#include "xstatus.h"
#include "xscugic.h"
+#include "xreg_cortexr5.h"

#include "platform_config.h"
#include "metal/io.h"
@@ -73,7 +74,7 @@ struct metal_device metal_dev_table[] = {
0x1000,
(sizeof(metal_phys_addr_t) << 3),
(unsigned long)(-1),
- METAL_UNCACHED,
+ DEVICE_NONSHARED | PRIV_RW_USER_RW,
{NULL},
}
},
@@ -94,7 +95,7 @@ struct metal_device metal_dev_table[] = {
0x1000,
(sizeof(metal_phys_addr_t) << 3),
(unsigned long)(-1),
- METAL_UNCACHED | METAL_SHARED_MEM,
+ NORM_SHARED_NCACHE | PRIV_RW_USER_RW,
{NULL},
}
},
@@ -115,7 +116,7 @@ struct metal_device metal_dev_table[] = {
0x1000,
(sizeof(metal_phys_addr_t) << 3),
(unsigned long)(-1),
- METAL_UNCACHED | METAL_SHARED_MEM,
+ NORM_SHARED_NCACHE | PRIV_RW_USER_RW,
{NULL},
}
},
@@ -133,10 +134,10 @@ struct metal_device metal_dev_table[] = {
{
(void *)0x3ED20000,
&metal_phys[3],
- 0x100000,
+ 0x40000,
(sizeof(metal_phys_addr_t) << 3),
(unsigned long)(-1),
- METAL_UNCACHED | METAL_SHARED_MEM,
+ NORM_SHARED_NCACHE | PRIV_RW_USER_RW,
{NULL},
}
},
diff --git a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c
index 1c41f1a..f15b356 100644
--- a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c
+++ b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c
@@ -362,7 +362,7 @@ static void *ipi_task_echo(void *arg)
sizeof(struct msg_hdr_s) + msg_hdr->len);

shm0_addr_array[i] = (uint64_t)metal_io_virt_to_phys(
- ch->shm_io, msg_hdr);
+ ch->shm_io, d0);
shm0_mg->avails++;
atomic_thread_fence(memory_order_acq_rel);
LPRINTF("Sending shutdown message...\n");
@@ -475,12 +475,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem descriptor.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }

/* Store the shared memory device and I/O region */
ch0.shm0_desc_dev = device;
@@ -502,17 +496,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- /* The metal_io_mem_map() does nothing for Linux userspace, as the memory
- * mapping is done by the kernel. It is put here for the code can be portable
- * across different system.
- */
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem descriptor.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }
-
/* Store the shared memory device and I/O region */
ch0.shm1_desc_dev = device;
ch0.shm1_desc_io = io;
@@ -533,12 +516,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }

/* Store the shared memory device and I/O region */
ch0.shm_dev = device;
diff --git a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c
index 5f0c1e3..35dbfef 100644
--- a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c
+++ b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c
@@ -308,13 +308,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }
-
/* Store the shared memory0 descriptor device and I/O region */
ch0.shm0_desc_dev = device;
ch0.shm0_desc_io = io;
@@ -336,13 +329,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }
-
/* Store the shared memory0 descriptor device and I/O region */
ch0.shm1_desc_dev = device;
ch0.shm1_desc_io = io;
@@ -363,12 +349,6 @@ int main(void)
ret = -ENODEV;
goto out;
}
- if (!metal_io_mem_map(metal_io_phys(io, 0), io, io->size)) {
- LPRINTF("ERROR: Failed to memory map shmem.\n");
- metal_device_close(device);
- ret = -ENODEV;
- goto out;
- }

/* Store the shared memory device and I/O region */
ch0.shm_dev = device;
--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:20 PM6/1/17
to open...@googlegroups.com, Wendy Liang
Add io region block write/read/set operations.
* block write: write a block of memory to I/O region
* blobk read: read a block of memory from I/O region
* block set: fill in a block of memory in the I/O region with
specified data.

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
lib/io.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++-
lib/io.h | 50 +++++++++++++++++++++-
lib/system/linux/shmem.c | 2 +-
3 files changed, 157 insertions(+), 4 deletions(-)

diff --git a/lib/io.c b/lib/io.c
index 817b302..b97760b 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -28,8 +28,113 @@
* POSSIBILITY OF SUCH DAMAGE.
*/

+#include <errno.h>
#include "metal/io.h"

+int metal_io_block_read(struct metal_io_region *io, unsigned long offset,
+ void *restrict dst, int len)
+{
+ void *ptr = metal_io_virt(io, offset);
+ int retlen;
+
+ if (offset > io->size)
+ return -ERANGE;
+ if ((offset + len) > io->size)
+ len = io->size - offset;
+ retlen = len;
+ if (io->ops.block_read) {
+ retlen = (*io->ops.block_read)(
+ io, offset, dst, memory_order_seq_cst, len);
+ } else {
+ while ( len && (
+ ((uintptr_t)dst % sizeof(int)) ||
+ ((uintptr_t)ptr % sizeof(int)))) {
+ *(unsigned char *)dst =
+ *(const unsigned char *)ptr;
+ dst++;
+ ptr++;
+ len--;
+ }
+ for (; len >= (int)sizeof(int); dst += sizeof(int),
+ ptr += sizeof(int),
+ len -= sizeof(int))
+ *(unsigned int *)dst = *(const unsigned int *)ptr;
+ for (; len != 0; dst++, ptr++, len--)
+ *(unsigned char *)dst =
+ *(const unsigned char *)ptr;
+ atomic_thread_fence(memory_order_seq_cst);
+ }
+ return retlen;
+}
+
+int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
+ void *restrict src, int len)
+{
+ void *ptr = metal_io_virt(io, offset);
+ int retlen;
+
+ if (offset > io->size)
+ return -ERANGE;
+ if ((offset + len) > io->size)
+ len = io->size - offset;
+ retlen = len;
+ if (io->ops.block_write) {
+ retlen = (*io->ops.block_write)(
+ io, offset, src, memory_order_seq_cst, len);
+ } else {
+ while ( len && (
+ ((uintptr_t)ptr % sizeof(int)) ||
+ ((uintptr_t)src % sizeof(int)))) {
+ *(unsigned char *)ptr =
+ *(const unsigned char *)src;
+ ptr++;
+ src++;
+ len--;
+ }
+ for (; len >= (int)sizeof(int); ptr += sizeof(int),
+ src += sizeof(int),
+ len -= sizeof(int))
+ *(unsigned int *)ptr = *(const unsigned int *)src;
+ for (; len != 0; ptr++, src++, len--)
+ *(unsigned char *)ptr =
+ *(const unsigned char *)src;
+ atomic_thread_fence(memory_order_seq_cst);
+ }
+ return retlen;
+}
+
+int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
+ unsigned char value, int len)
+{
+ void *ptr = metal_io_virt(io, offset);
+ int retlen = len;
+
+ if (offset > io->size)
+ return -ERANGE;
+ if ((offset + len) > io->size)
+ len = io->size - offset;
+ retlen = len;
+ if (io->ops.block_set) {
+ retlen = (*io->ops.block_set)(
+ io, offset, value, memory_order_seq_cst, len);
+ } else {
+ unsigned int cint = value;
+ unsigned int i;
+
+ for (i = 1; i < sizeof(int); i++)
+ cint |= ((unsigned int)value << (8 * i));
+
+ for (; len && ((uintptr_t)ptr % sizeof(int)); ptr++, len--)
+ *(unsigned char *)ptr = (unsigned char) value;
+ for (; len >= (int)sizeof(int); ptr += sizeof(int),
+ len -= sizeof(int))
+ *(unsigned int *)ptr = cint;
+ for (; len != 0; ptr++, len--)
+ *(unsigned char *)ptr = (unsigned char) value;
+ }
+ return retlen;
+}
+
void *metal_generic_memset_io(void *dst, int c, size_t size)
{
void *retdst = dst;
@@ -40,9 +145,9 @@ void *metal_generic_memset_io(void *dst, int c, size_t size)

for (; size && ((uintptr_t)dst % sizeof(int)); dst++, size--)
*(unsigned char volatile *)dst = (unsigned char) c;
- for(; size >= sizeof(int); dst += sizeof(int), size -= sizeof(int))
+ for (; size >= sizeof(int); dst += sizeof(int), size -= sizeof(int))
*(unsigned int volatile *)dst = cint;
- for(; size != 0; dst++, size--)
+ for (; size != 0; dst++, size--)
*(unsigned char volatile*)dst = (unsigned char) c;
return retdst;
}
diff --git a/lib/io.h b/lib/io.h
index a0f8fcf..eba7c2f 100644
--- a/lib/io.h
+++ b/lib/io.h
@@ -80,6 +80,21 @@ struct metal_io_ops {
uint64_t value,
memory_order order,
int width);
+ int (*block_read)(struct metal_io_region *io,
+ unsigned long offset,
+ void *restrict dst,
+ memory_order order,
+ int len);
+ int (*block_write)(struct metal_io_region *io,
+ unsigned long offset,
+ void *restrict src,
+ memory_order order,
+ int len);
+ void (*block_set)(struct metal_io_region *io,
+ unsigned long offset,
+ unsigned char value,
+ memory_order order,
+ int len);
void (*close)(struct metal_io_region *io);
};

@@ -111,7 +126,7 @@ metal_io_init(struct metal_io_region *io, void *virt,
unsigned page_shift, unsigned int mem_flags,
const struct metal_io_ops *ops)
{
- const struct metal_io_ops nops = {NULL, NULL, NULL};
+ const struct metal_io_ops nops = {NULL, NULL, NULL, NULL, NULL, NULL};
io->virt = virt;
io->physmap = physmap;
io->size = size;
@@ -335,6 +350,39 @@ metal_io_write(struct metal_io_region *io, unsigned long offset,
metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 8)

/**
+ * @brief Read a block from an I/O region.
+ * @param[in] io I/O region handle.
+ * @param[in] offset Offset into I/O region.
+ * @param[in] dst destination to store the read data.
+ * @param[in] len length in bytes to read.
+ * @return On success, number of bytes read. On failure, negative value
+ */
+int metal_io_block_read(struct metal_io_region *io, unsigned long offset,
+ void *restrict dst, int len);
+
+/**
+ * @brief Write a block into an I/O region.
+ * @param[in] io I/O region handle.
+ * @param[in] offset Offset into I/O region.
+ * @param[in] src source to write.
+ * @param[in] len length in bytes to write.
+ * @return On success, number of bytes written. On failure, negative value
+ */
+int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
+ void *restrict src, int len);
+
+/**
+ * @brief fill a block of an I/O region.
+ * @param[in] io I/O region handle.
+ * @param[in] offset Offset into I/O region.
+ * @param[in] value value to fill into the block
+ * @param[in] len length in bytes to fill.
+ * @return On success, number of bytes filled. On failure, negative value
+ */
+int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
+ unsigned char value, int len);
+
+/**
* @brief libmetal memory map
*
* This function is to enable memory mapping to the specified I/O memory.
diff --git a/lib/system/linux/shmem.c b/lib/system/linux/shmem.c
index 2b78ed4..010f3e9 100644
--- a/lib/system/linux/shmem.c
+++ b/lib/system/linux/shmem.c
@@ -49,7 +49,7 @@ static void metal_shmem_io_close(struct metal_io_region *io)
}

static const struct metal_io_ops metal_shmem_io_ops = {
- NULL, NULL, metal_shmem_io_close
+ NULL, NULL, NULL, NULL, NULL, metal_shmem_io_close
};

static int metal_shmem_try_map(struct metal_page_size *ps, int fd, size_t size,
--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:20 PM6/1/17
to open...@googlegroups.com, Wendy Liang
We should have I/O memory map API for user as
the memory should already be mapped when the I/O region
is ready to use.

However, as I/O memory mapping is still required on RTOS
and baremetal systems, we keep the I/O memory mapping
for library internal usage.

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
lib/device.c | 2 +-
lib/device.h | 4 +++
lib/io.c | 2 +-
lib/io.h | 31 -----------------
lib/system/freertos/CMakeLists.txt | 2 +-
lib/system/freertos/device.c | 64 +++++++++++++++++++++++++++++++++++
lib/system/freertos/io.c | 48 ---------------------------
lib/system/freertos/sys.h | 6 ++++
lib/system/freertos/zynq7/sys.c | 52 ++++-------------------------
lib/system/freertos/zynqmp_r5/sys.c | 27 +++------------
lib/system/generic/CMakeLists.txt | 2 +-
lib/system/generic/device.c | 66 +++++++++++++++++++++++++++++++++++++
lib/system/generic/io.c | 48 ---------------------------
lib/system/generic/sys.h | 6 ++++
lib/system/generic/zynq7/sys.c | 53 ++++-------------------------
lib/system/generic/zynqmp_r5/sys.c | 27 +++------------
lib/system/linux/CMakeLists.txt | 1 -
lib/system/linux/device.c | 10 ++++--
lib/system/linux/io.c | 44 -------------------------
19 files changed, 180 insertions(+), 315 deletions(-)
create mode 100644 lib/system/freertos/device.c
delete mode 100644 lib/system/freertos/io.c
create mode 100644 lib/system/generic/device.c
delete mode 100644 lib/system/generic/io.c
delete mode 100644 lib/system/linux/io.c

diff --git a/lib/device.c b/lib/device.c
index 79c1df2..063bf5d 100644
--- a/lib/device.c
+++ b/lib/device.c
@@ -145,7 +145,7 @@ static int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name,
if (strcmp(dev->name, dev_name) != 0)
continue;
*device = dev;
- return 0;
+ return metal_generic_dev_sys_open(dev);
}

return -ENODEV;
diff --git a/lib/device.h b/lib/device.h
index 863b95c..3ba1d5e 100644
--- a/lib/device.h
+++ b/lib/device.h
@@ -171,6 +171,10 @@ metal_device_io_region(struct metal_device *device, unsigned index)

/** @} */

+#ifdef METAL_INTERNAL
+extern int metal_generic_dev_sys_open(struct metal_device *dev);
+#endif /* METAL_INTERNAL */
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/io.c b/lib/io.c
index 850f47b..5d08d7a 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -115,7 +115,7 @@ int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
len = io->size - offset;
retlen = len;
if (io->ops.block_set) {
- retlen = (*io->ops.block_set)(
+ (*io->ops.block_set)(
io, offset, value, memory_order_seq_cst, len);
} else {
unsigned int cint = value;
diff --git a/lib/io.h b/lib/io.h
index 24905e9..e439beb 100644
--- a/lib/io.h
+++ b/lib/io.h
@@ -50,23 +50,6 @@ extern "C" {
/** \defgroup io IO Interfaces
* @{ */

-/** I/O memory flags macros for caching scheme */
-
-/** Cache bits */
-#define METAL_CACHE_UNKNOWN 0x0 /** Use cache, unknown cache type */
-#define METAL_UNCACHED 0x1 /** No cache */
-#define METAL_CACHE_WB 0x2 /** Write back */
-#define METAL_CACHE_WT 0x4 /** Write through */
-
-/** Memory types */
-#define METAL_MEM_MAPPED 0x10 /** Memory mapped */
-#define METAL_IO_MAPPED 0x20 /** I/O mapped */
-#define METAL_SHARED_MEM 0x40 /** Shared memory */
-
-/** DMA cache bits */
-#define METAL_DMA_NO_CACHE_OPS 0x0 /** No cache ops in DMA transaction */
-#define METAL_DMA_CACHE_OPS 0x1 /** Require cache ops in DMA transaction */
-
struct metal_io_region;

/** Generic I/O operations. */
@@ -378,20 +361,6 @@ int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
unsigned char value, int len);

-/**
- * @brief libmetal memory map
- *
- * This function is to enable memory mapping to the specified I/O memory.
- *
- * @param[in] pa physical memory start address
- * @param[in] io memory region
- * @param[in] size size of the memory range
- * @return logical address if suceeded, or 0 if failed.
- */
-void *metal_io_mem_map(metal_phys_addr_t pa,
- struct metal_io_region *io,
- size_t size);
-
#ifdef __cplusplus
}
#endif
diff --git a/lib/system/freertos/CMakeLists.txt b/lib/system/freertos/CMakeLists.txt
index c21d676..b941dcd 100644
--- a/lib/system/freertos/CMakeLists.txt
+++ b/lib/system/freertos/CMakeLists.txt
@@ -6,8 +6,8 @@ collect (PROJECT_LIB_HEADERS condition.h)

collect (PROJECT_LIB_SOURCES init.c)
collect (PROJECT_LIB_SOURCES irq.c)
+collect (PROJECT_LIB_SOURCES device.c)
collect (PROJECT_LIB_SOURCES cache.c)
-collect (PROJECT_LIB_SOURCES io.c)
collect (PROJECT_LIB_SOURCES shmem.c)
collect (PROJECT_LIB_SOURCES condition.c)
collect (PROJECT_LIB_SOURCES time.c)
diff --git a/lib/system/freertos/device.c b/lib/system/freertos/device.c
new file mode 100644
index 0000000..1198b0d
--- /dev/null
+++ b/lib/system/freertos/device.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017, Xilinx Inc. and Contributors. 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 Xilinx 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 linux/bus.c
+ * @brief Linux libmetal bus definitions.
+ */
+
+#include "metal/device.h"
+#include "metal/sys.h"
+#include "metal/utilities.h"
+
+int metal_generic_dev_sys_open(struct metal_device *dev)
+{
+ struct metal_io_region *io;
+ unsigned long p;
+ size_t size;
+ void *va;
+ unsigned i;
+
+ /* map I/O memory regions */
+ for (i = 0; i < dev->num_regions; i++) {
+ io = &dev->regions[i];
+ va = io->virt;
+ size = io->size;
+ if (size >> io->page_shift)
+ size = (size_t)1 << io->page_shift;
+ for (p = 0; p <= (io->size >> io->page_shift); p++) {
+ metal_machine_io_mem_map(va, io->physmap[p],
+ size, io->mem_flags);
+ va += size;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/lib/system/freertos/io.c b/lib/system/freertos/io.c
deleted file mode 100644
index e238ffc..0000000
--- a/lib/system/freertos/io.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016, Xilinx Inc. and Contributors. 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 Xilinx 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 freertos/io.c
- * @brief FreeRTOS libmetal I/O handling.
- */
-
-#include "metal/io.h"
-
-extern void metal_machine_io_mem_map(metal_phys_addr_t pa,
- size_t size, unsigned int flags);
-
-void *metal_io_mem_map(metal_phys_addr_t pa,
- struct metal_io_region *io, size_t size)
-{
- unsigned int flags = io->mem_flags;
- metal_machine_io_mem_map(pa, size, flags);
- return metal_io_phys_to_virt(io, pa);
-}
-
diff --git a/lib/system/freertos/sys.h b/lib/system/freertos/sys.h
index 3034ca4..7fef30a 100644
--- a/lib/system/freertos/sys.h
+++ b/lib/system/freertos/sys.h
@@ -69,6 +69,12 @@ void sys_irq_restore_enable(void);
*/
void sys_irq_save_disable(void);

+/**
+ * @brief memory mapping
+ */
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
+ size_t size, unsigned int flags);
+
#endif /* METAL_INTERNAL */

#ifdef __cplusplus
diff --git a/lib/system/freertos/zynq7/sys.c b/lib/system/freertos/zynq7/sys.c
index 7e60e79..735415d 100644
--- a/lib/system/freertos/zynq7/sys.c
+++ b/lib/system/freertos/zynq7/sys.c
@@ -51,28 +51,6 @@
/* Mask off lower bits of addr */
#define ARM_AR_MEM_TTB_SECT_SIZE_MASK (~(ARM_AR_MEM_TTB_SECT_SIZE-1UL))

-/* Define shift to convert memory address to index of translation table entry (descriptor).
- Shift 20 bits (for a 1MB section) - 2 bits (for a 4 byte TTB descriptor) */
-#define ARM_AR_MEM_TTB_SECT_TO_DESC_SHIFT (20-2)
-
-/* Macro used to make a 32-bit value with the specified bit set */
-#define ESAL_GE_MEM_32BIT_SET(bit_num) (1UL<<(bit_num))
-
-#define ARM_AR_MEM_TTB_DESC_BACKWARDS ESAL_GE_MEM_32BIT_SET(4)
-#define ARM_AR_MEM_TTB_DESC_AP_MANAGER (ESAL_GE_MEM_32BIT_SET(10) | \
- ESAL_GE_MEM_32BIT_SET(11))
-#define ARM_AR_MEM_TTB_DESC_SECT ESAL_GE_MEM_32BIT_SET(1)
-
-/* Define translation table descriptor bits */
-#define ARM_AR_MEM_TTB_DESC_B ESAL_GE_MEM_32BIT_SET(2)
-#define ARM_AR_MEM_TTB_DESC_C ESAL_GE_MEM_32BIT_SET(3)
-#define ARM_AR_MEM_TTB_DESC_TEX ESAL_GE_MEM_32BIT_SET(12)
-#define ARM_AR_MEM_TTB_DESC_S ESAL_GE_MEM_32BIT_SET(16)
-
-/* Define all access (manager access permission / not cachable / not bufferd) */
-#define ARM_AR_MEM_TTB_DESC_ALL_ACCESS (ARM_AR_MEM_TTB_DESC_AP_MANAGER | \
- ARM_AR_MEM_TTB_DESC_SECT)
-
static unsigned int int_old_val = XIL_EXCEPTION_ALL;

void sys_irq_restore_enable(void)
@@ -116,17 +94,17 @@ void __attribute__((weak)) metal_generic_default_poll(void)
asm volatile("wfi");
}

-void metal_machine_io_mem_map(metal_phys_addr_t pa,
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
size_t size, unsigned int flags)
{
unsigned int section_offset;
unsigned int ttb_addr;
- unsigned int ttb_value;

+ if (!flags)
+ return va;
/* Ensure the virtual and physical addresses are aligned on a
section boundary */
pa &= ARM_AR_MEM_TTB_SECT_SIZE_MASK;
- ttb_value = ARM_AR_MEM_TTB_DESC_ALL_ACCESS;

/* Loop through entire region of memory (one MMU section at a time).
Each section requires a TTB entry. */
@@ -136,27 +114,9 @@ void metal_machine_io_mem_map(metal_phys_addr_t pa,
/* Calculate translation table entry for this memory section */
ttb_addr = (pa + section_offset);

- /* Build translation table entry value */
-
- /* Set cache related bits in translation table entry.
- NOTE: Default is uncached instruction and data. */
- if ((flags & METAL_CACHE_WB)) {
- /* Update translation table entry value */
- ttb_value |=
- (ARM_AR_MEM_TTB_DESC_B |
- ARM_AR_MEM_TTB_DESC_C);
- } else if ((flags & METAL_CACHE_WT)) {
- /* Update translation table entry value */
- ttb_value |= ARM_AR_MEM_TTB_DESC_C;
- }
- /* In case of un-cached memory, set TEX 0 bit to set memory
- attribute to normal. */
- else if ((flags & METAL_UNCACHED)) {
- ttb_value |= ARM_AR_MEM_TTB_DESC_TEX;
- }
-
/* Write translation table entry value to entry address */
- Xil_SetTlbAttributes(ttb_addr, ttb_value);
-
+ Xil_SetTlbAttributes(ttb_addr, flags);
}
+
+ return va;
}
diff --git a/lib/system/freertos/zynqmp_r5/sys.c b/lib/system/freertos/zynqmp_r5/sys.c
index 1bcd186..6593102 100644
--- a/lib/system/freertos/zynqmp_r5/sys.c
+++ b/lib/system/freertos/zynqmp_r5/sys.c
@@ -89,31 +89,14 @@ void __attribute__((weak)) metal_generic_default_poll(void)
asm volatile("wfi");
}

-void metal_machine_io_mem_map(metal_phys_addr_t pa,
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
size_t size, unsigned int flags)
{
- unsigned int r5_flags;
size_t rsize = MPU_REGION_SIZE_MIN;
metal_phys_addr_t base_pa;

- /* Assume DEVICE_SHARED if nothing indicates this is memory. */
- r5_flags = DEVICE_SHARED;
- if ((flags & METAL_SHARED_MEM)) {
- r5_flags = NORM_SHARED_NCACHE;
- if ((flags & METAL_CACHE_WB)) {
- r5_flags = NORM_SHARED_WB_WA;
- } else if ((flags & METAL_CACHE_WT)) {
- r5_flags = NORM_SHARED_WT_NWA;
- }
- } else {
- r5_flags = NORM_NSHARED_NCACHE;
- if ((flags & METAL_CACHE_WB)) {
- r5_flags = NORM_NSHARED_WB_WA;
- } else if ((flags & METAL_CACHE_WT)) {
- r5_flags = NORM_NSHARED_WT_NWA;
- }
- }
-
+ if (!flags)
+ return va;
while(1) {
if (rsize < size) {
rsize <<= 1;
@@ -127,6 +110,6 @@ void metal_machine_io_mem_map(metal_phys_addr_t pa,
break;
}
}
- Xil_SetMPURegion(base_pa, rsize, r5_flags | PRIV_RW_USER_RW);
- return;
+ Xil_SetMPURegion(base_pa, rsize, flags);
+ return va;
}
diff --git a/lib/system/generic/CMakeLists.txt b/lib/system/generic/CMakeLists.txt
index 5e33671..03341b2 100644
--- a/lib/system/generic/CMakeLists.txt
+++ b/lib/system/generic/CMakeLists.txt
@@ -6,9 +6,9 @@ collect (PROJECT_LIB_HEADERS irq.h)

collect (PROJECT_LIB_SOURCES init.c)
collect (PROJECT_LIB_SOURCES shmem.c)
+collect (PROJECT_LIB_SOURCES device.c)
collect (PROJECT_LIB_SOURCES condition.c)
collect (PROJECT_LIB_SOURCES cache.c)
-collect (PROJECT_LIB_SOURCES io.c)
collect (PROJECT_LIB_SOURCES irq.c)
collect (PROJECT_LIB_SOURCES time.c)
collect (PROJECT_LIB_SOURCES sleep.c)
diff --git a/lib/system/generic/device.c b/lib/system/generic/device.c
new file mode 100644
index 0000000..f83153b
--- /dev/null
+++ b/lib/system/generic/device.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017, Xilinx Inc. and Contributors. 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 Xilinx 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 linux/bus.c
+ * @brief Linux libmetal bus definitions.
+ */
+
+#include "metal/device.h"
+#include "metal/sys.h"
+#include "metal/utilities.h"
+
+int metal_generic_dev_sys_open(struct metal_device *dev)
+{
+ struct metal_io_region *io;
+ unsigned long p;
+ size_t size;
+ void *va;
+ unsigned i;
+
+ /* map I/O memory regions */
+ for (i = 0; i < dev->num_regions; i++) {
+ io = &dev->regions[i];
+ va = io->virt;
+ size = io->size;
+ if (!size)
+ break;
+ if (size >> io->page_shift)
+ size = (size_t)1 << io->page_shift;
+ for (p = 0; p <= (io->size >> io->page_shift); p++) {
+ metal_machine_io_mem_map(va, io->physmap[p],
+ size, io->mem_flags);
+ va += size;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/lib/system/generic/io.c b/lib/system/generic/io.c
deleted file mode 100644
index 5bff6bf..0000000
--- a/lib/system/generic/io.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2016, Xilinx Inc. and Contributors. 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 Xilinx 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 generic/io.c
- * @brief Generic libmetal I/O handling.
- */
-
-#include "metal/io.h"
-
-extern void metal_machine_io_mem_map(metal_phys_addr_t pa,
- size_t size, unsigned int flags);
-
-void *metal_io_mem_map(metal_phys_addr_t pa,
- struct metal_io_region *io, size_t size)
-{
- unsigned int flags = io->mem_flags;
- metal_machine_io_mem_map(pa, size, flags);
- return metal_io_phys_to_virt(io, pa);
-}
-
diff --git a/lib/system/generic/sys.h b/lib/system/generic/sys.h
index c3607f7..56415eb 100644
--- a/lib/system/generic/sys.h
+++ b/lib/system/generic/sys.h
@@ -78,6 +78,12 @@ void sys_irq_restore_enable(void);
*/
void sys_irq_save_disable(void);

+/**
+ * @brief memory mapping
+ */
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
+ size_t size, unsigned int flags);
+
#endif /* METAL_INTERNAL */

#ifdef __cplusplus
diff --git a/lib/system/generic/zynq7/sys.c b/lib/system/generic/zynq7/sys.c
index 39d8259..212918e 100644
--- a/lib/system/generic/zynq7/sys.c
+++ b/lib/system/generic/zynq7/sys.c
@@ -51,29 +51,6 @@
/* Mask off lower bits of addr */
#define ARM_AR_MEM_TTB_SECT_SIZE_MASK (~(ARM_AR_MEM_TTB_SECT_SIZE-1UL))

-/* Define shift to convert memory address to index of translation table entry (descriptor).
- Shift 20 bits (for a 1MB section) - 2 bits (for a 4 byte TTB descriptor) */
-#define ARM_AR_MEM_TTB_SECT_TO_DESC_SHIFT (20-2)
-
-/* Macro used to make a 32-bit value with the specified bit set */
-#define ESAL_GE_MEM_32BIT_SET(bit_num) (1UL<<(bit_num))
-
-#define ARM_AR_MEM_TTB_DESC_BACKWARDS ESAL_GE_MEM_32BIT_SET(4)
-#define ARM_AR_MEM_TTB_DESC_AP_MANAGER (ESAL_GE_MEM_32BIT_SET(10) | \
- ESAL_GE_MEM_32BIT_SET(11))
-#define ARM_AR_MEM_TTB_DESC_SECT ESAL_GE_MEM_32BIT_SET(1)
-
-/* Define translation table descriptor bits */
-#define ARM_AR_MEM_TTB_DESC_B ESAL_GE_MEM_32BIT_SET(2)
-#define ARM_AR_MEM_TTB_DESC_C ESAL_GE_MEM_32BIT_SET(3)
-#define ARM_AR_MEM_TTB_DESC_TEX ESAL_GE_MEM_32BIT_SET(12)
-#define ARM_AR_MEM_TTB_DESC_S ESAL_GE_MEM_32BIT_SET(16)
-
-/* Define all access (manager access permission / not cachable / not bufferd) */
-#define ARM_AR_MEM_TTB_DESC_ALL_ACCESS (ARM_AR_MEM_TTB_DESC_AP_MANAGER | \
- ARM_AR_MEM_TTB_DESC_SECT)
-
-
static unsigned int int_old_val = XIL_EXCEPTION_ALL;

void sys_irq_restore_enable(void)
@@ -117,17 +94,17 @@ void __attribute__((weak)) metal_generic_default_poll(void)
asm volatile("wfi");
}

-void metal_machine_io_mem_map(metal_phys_addr_t pa,
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
size_t size, unsigned int flags)
{
unsigned int section_offset;
unsigned int ttb_addr;
- unsigned int ttb_value;

+ if (!flags)
+ return va;
/* Ensure the virtual and physical addresses are aligned on a
section boundary */
pa &= ARM_AR_MEM_TTB_SECT_SIZE_MASK;
- ttb_value = ARM_AR_MEM_TTB_DESC_ALL_ACCESS;

/* Loop through entire region of memory (one MMU section at a time).
Each section requires a TTB entry. */
@@ -137,27 +114,9 @@ void metal_machine_io_mem_map(metal_phys_addr_t pa,
/* Calculate translation table entry for this memory section */
ttb_addr = (pa + section_offset);

- /* Build translation table entry value */
-
- /* Set cache related bits in translation table entry.
- NOTE: Default is uncached instruction and data. */
- if ((flags & METAL_CACHE_WB)) {
- /* Update translation table entry value */
- ttb_value |=
- (ARM_AR_MEM_TTB_DESC_B |
- ARM_AR_MEM_TTB_DESC_C);
- } else if ((flags & METAL_CACHE_WT)) {
- /* Update translation table entry value */
- ttb_value |= ARM_AR_MEM_TTB_DESC_C;
- }
- /* In case of un-cached memory, set TEX 0 bit to set memory
- attribute to normal. */
- else if ((flags & METAL_UNCACHED)) {
- ttb_value |= ARM_AR_MEM_TTB_DESC_TEX;
- }
-
/* Write translation table entry value to entry address */
- Xil_SetTlbAttributes(ttb_addr, ttb_value);
-
+ Xil_SetTlbAttributes(ttb_addr, flags);
}
+
+ return va;
}
diff --git a/lib/system/generic/zynqmp_r5/sys.c b/lib/system/generic/zynqmp_r5/sys.c
index 74c305f..9891fdf 100644
--- a/lib/system/generic/zynqmp_r5/sys.c
+++ b/lib/system/generic/zynqmp_r5/sys.c
@@ -89,31 +89,14 @@ void __attribute__((weak)) metal_generic_default_poll(void)
asm volatile("wfi");
}

-void metal_machine_io_mem_map(metal_phys_addr_t pa,
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
size_t size, unsigned int flags)
{
- unsigned int r5_flags;
size_t rsize = MPU_REGION_SIZE_MIN;
metal_phys_addr_t base_pa;

- /* Assume DEVICE_SHARED if nothing indicates this is memory. */
- r5_flags = DEVICE_SHARED;
- if ((flags & METAL_SHARED_MEM)) {
- r5_flags = NORM_SHARED_NCACHE;
- if ((flags & METAL_CACHE_WB)) {
- r5_flags = NORM_SHARED_WB_WA;
- } else if ((flags & METAL_CACHE_WT)) {
- r5_flags = NORM_SHARED_WT_NWA;
- }
- } else {
- r5_flags = NORM_NSHARED_NCACHE;
- if ((flags & METAL_CACHE_WB)) {
- r5_flags = NORM_NSHARED_WB_WA;
- } else if ((flags & METAL_CACHE_WT)) {
- r5_flags = NORM_NSHARED_WT_NWA;
- }
- }
-
+ if (!flags)
+ return va;
while(1) {
if (rsize < size) {
rsize <<= 1;
@@ -127,6 +110,6 @@ void metal_machine_io_mem_map(metal_phys_addr_t pa,
break;
}
}
- Xil_SetMPURegion(base_pa, rsize, r5_flags | PRIV_RW_USER_RW);
- return;
+ Xil_SetMPURegion(base_pa, rsize, flags);
+ return va;
}
diff --git a/lib/system/linux/CMakeLists.txt b/lib/system/linux/CMakeLists.txt
index 86aa72d..4049c51 100644
--- a/lib/system/linux/CMakeLists.txt
+++ b/lib/system/linux/CMakeLists.txt
@@ -11,7 +11,6 @@ collect (PROJECT_LIB_SOURCES utilities.c)
collect (PROJECT_LIB_SOURCES condition.c)
collect (PROJECT_LIB_SOURCES irq.c)
collect (PROJECT_LIB_SOURCES cache.c)
-collect (PROJECT_LIB_SOURCES io.c)
collect (PROJECT_LIB_SOURCES time.c)
collect (PROJECT_LIB_SOURCES sleep.c)

diff --git a/lib/system/linux/device.c b/lib/system/linux/device.c
index 6966e25..2e858b8 100644
--- a/lib/system/linux/device.c
+++ b/lib/system/linux/device.c
@@ -249,8 +249,7 @@ static int metal_uio_dev_open(struct linux_bus *lbus, struct linux_device *ldev)
metal_map(ldev->fd, offset, size, 0, 0, &virt));
if (!result) {
io = &ldev->device.regions[ldev->device.num_regions];
- metal_io_init(io, virt, phys, size, -1,
- METAL_UNCACHED | METAL_IO_MAPPED, NULL);
+ metal_io_init(io, virt, phys, size, -1, 0, NULL);
ldev->device.num_regions++;
}
}
@@ -619,3 +618,10 @@ void metal_linux_bus_finish(void)
metal_bus_unregister(bus);
}
}
+
+int metal_generic_dev_sys_open(struct metal_device *dev)
+{
+ (void)dev;
+ return 0;
+}
+
diff --git a/lib/system/linux/io.c b/lib/system/linux/io.c
deleted file mode 100644
index 31c82b6..0000000
--- a/lib/system/linux/io.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2016, Xilinx Inc. and Contributors. 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 Xilinx 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 linux/io.c
- * @brief Linux libmetal I/O handling.
- */
-
-#include "metal/io.h"
-
-void *metal_io_mem_map(metal_phys_addr_t pa,
- struct metal_io_region *io, size_t size)
-{
- (void)size;
- return metal_io_phys_to_virt(io, pa);
-}
-
--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:20 PM6/1/17
to open...@googlegroups.com, Wendy Liang
Limit OS/platform specific APIs for library internal usage only.

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
lib/system/freertos/zynq7/sys.h | 2 ++
lib/system/freertos/zynqmp_r5/sys.h | 2 ++
lib/system/generic/zynq7/sys.h | 2 ++
lib/system/generic/zynqmp_r5/sys.h | 2 ++
4 files changed, 8 insertions(+)

diff --git a/lib/system/freertos/zynq7/sys.h b/lib/system/freertos/zynq7/sys.h
index 14db980..746087c 100644
--- a/lib/system/freertos/zynq7/sys.h
+++ b/lib/system/freertos/zynq7/sys.h
@@ -46,6 +46,7 @@
extern "C" {
#endif

+#ifdef METAL_INTERNAL

#if !defined(MAX_IRQS)
#define MAX_IRQS ((int)XSCUGIC_MAX_NUM_INTR_INPUTS) /**< maximum number of irqs */
@@ -61,6 +62,7 @@ static inline void sys_irq_disable(unsigned int vector)
XScuGic_DisableIntr(XPAR_SCUGIC_0_DIST_BASEADDR, vector);
}

+#endif /* METAL_INTERNAL */

#ifdef __cplusplus
}
diff --git a/lib/system/freertos/zynqmp_r5/sys.h b/lib/system/freertos/zynqmp_r5/sys.h
index 45abffc..def14ca 100644
--- a/lib/system/freertos/zynqmp_r5/sys.h
+++ b/lib/system/freertos/zynqmp_r5/sys.h
@@ -46,6 +46,7 @@
extern "C" {
#endif

+#ifdef METAL_INTERNAL

#if !defined(MAX_IRQS)
#define MAX_IRQS ((int)XSCUGIC_MAX_NUM_INTR_INPUTS) /**< maximum number of irqs */
@@ -61,6 +62,7 @@ static inline void sys_irq_disable(unsigned int vector)
XScuGic_DisableIntr(XPAR_SCUGIC_0_DIST_BASEADDR, vector);
}

+#endif /* METAL_INTERNAL */

#ifdef __cplusplus
}
diff --git a/lib/system/generic/zynq7/sys.h b/lib/system/generic/zynq7/sys.h
index 1eebdab..1d282a6 100644
--- a/lib/system/generic/zynq7/sys.h
+++ b/lib/system/generic/zynq7/sys.h
@@ -46,6 +46,7 @@
extern "C" {
#endif

+#ifdef METAL_INTERNAL

#if !defined(MAX_IRQS)
#define MAX_IRQS ((int)XSCUGIC_MAX_NUM_INTR_INPUTS) /**< maximum number of irqs */
@@ -61,6 +62,7 @@ static inline void sys_irq_disable(unsigned int vector)
XScuGic_DisableIntr(XPAR_SCUGIC_0_DIST_BASEADDR, vector);
}

+#endif /* METAL_INTERNAL */

#ifdef __cplusplus
}
diff --git a/lib/system/generic/zynqmp_r5/sys.h b/lib/system/generic/zynqmp_r5/sys.h
index 082d45a..c1a6782 100644
--- a/lib/system/generic/zynqmp_r5/sys.h
+++ b/lib/system/generic/zynqmp_r5/sys.h
@@ -46,6 +46,7 @@
extern "C" {
#endif

+#ifdef METAL_INTERNAL

#if !defined(MAX_IRQS)
#define MAX_IRQS ((int)XSCUGIC_MAX_NUM_INTR_INPUTS) /**< maximum number of irqs */
@@ -61,6 +62,7 @@ static inline void sys_irq_disable(unsigned int vector)
XScuGic_DisableIntr(XPAR_SCUGIC_0_DIST_BASEADDR, vector);
}

+#endif /* METAL_INTERNAL */

#ifdef __cplusplus
}
--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:21 PM6/1/17
to open...@googlegroups.com, Wendy Liang
As I/O block write/read/set is introduced, remove the obsolete
I/O memory copy/set APIs.

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
lib/io.c | 48 ------------------------------------------------
lib/io.h | 25 -------------------------
2 files changed, 73 deletions(-)

diff --git a/lib/io.c b/lib/io.c
index b97760b..850f47b 100644
--- a/lib/io.c
+++ b/lib/io.c
@@ -135,51 +135,3 @@ int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
return retlen;
}

-void *metal_generic_memset_io(void *dst, int c, size_t size)
-{
- void *retdst = dst;
- unsigned int cint = (unsigned char)c;
- unsigned int i;
- for (i = 1; i < sizeof(int); i++)
- cint |= (c << (8 * i));
-
- for (; size && ((uintptr_t)dst % sizeof(int)); dst++, size--)
- *(unsigned char volatile *)dst = (unsigned char) c;
- for (; size >= sizeof(int); dst += sizeof(int), size -= sizeof(int))
- *(unsigned int volatile *)dst = cint;
- for (; size != 0; dst++, size--)
- *(unsigned char volatile*)dst = (unsigned char) c;
- return retdst;
-}
-
-void *metal_generic_memcpy_io(void *dst, const void *src, size_t size)
-{
- void *retdst = dst;
- while (size && (
- ((uintptr_t)dst % sizeof(int)) ||
- ((uintptr_t)src % sizeof(int)))) {
- *(unsigned char volatile *)dst =
- *(const unsigned char volatile *)src;
- dst++;
- src++;
- size--;
- }
- for (; size >= sizeof(int);
- dst += sizeof(int), src += sizeof(int), size -= sizeof(int))
- *(unsigned int volatile *)dst =
- *(const unsigned int volatile *)src;
- for (; size != 0; dst++, src++, size--)
- *(unsigned char volatile *)dst =
- *(const unsigned char volatile *)src;
- return retdst;
-}
-
-void *metal_memset_io(void *dst, int c, size_t size)
-{
- return metal_generic_memset_io(dst, c, size);
-}
-
-void *metal_memcpy_io(void *dst, const void *src, size_t size)
-{
- return metal_generic_memcpy_io(dst, src, size);
-}
diff --git a/lib/io.h b/lib/io.h
index 1f76003..24905e9 100644
--- a/lib/io.h
+++ b/lib/io.h
@@ -392,31 +392,6 @@ void *metal_io_mem_map(metal_phys_addr_t pa,
struct metal_io_region *io,
size_t size);

-/**
- * @brief libmetal set device memory
- *
- * This function is to fill the device memory with the specified value.
- *
- * @param[in] dst target memory
- * @param[in] c val to fill
- * @param[in] size size of memory to fill.
- * @return pointer to the target memory
- */
-void *metal_memset_io(void *dst, int c, size_t size);
-
-/**
- * @brief libmetal copy to target memory
- *
- * This function is to copy specified memory area.
- * The source memory or the destination memory can be device memory.
- *
- * @param[in] dst target memory
- * @param[in] src source memory
- * @param[in] size size of memory to copy.
- * @return pointer to the target memory
- */
-void *metal_memcpy_io(void *dst, const void *src, size_t size);
-
#ifdef __cplusplus
}
#endif
--
2.7.4

Wendy Liang

unread,
Jun 1, 2017, 12:48:21 PM6/1/17
to open...@googlegroups.com, Wendy Liang
Use libmetal I/O region block_write/read APIs to copy
data to/from the I/O region instead of memcpy().

Signed-off-by: Wendy Liang <jli...@xilinx.com>
---
.../zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c | 59 ++++++++++++++++------
.../zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c | 51 ++++++++++++++-----
.../zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c | 56 +++++++++++++++-----
3 files changed, 123 insertions(+), 43 deletions(-)

diff --git a/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c b/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c
index a11011f..42393e6 100644
--- a/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c
+++ b/examples/system/generic/zynqmp_r5/zynqmp_amp_demo/libmetal_amp_demo.c
@@ -93,6 +93,7 @@
#define D0_SHM_OFFSET 0x00000
#define D1_SHM_OFFSET 0x20000

+#define BUF_SIZE_MAX 512
#define SHUTDOWN "shutdown"

#define LPRINTF(format, ...) \
@@ -223,14 +224,20 @@ static void *ipi_task_echod(void *arg)
shm_addr_t *shm0_addr_array, *shm1_addr_array;
struct msg_hdr_s *msg_hdr;
unsigned int flags;
- void *d0, *d1;
+ void *d0, *d1, *lbuf;
metal_phys_addr_t d0_pa;
+ int len;

shm0_mg = (struct shm_mg_s *)metal_io_virt(ch->shm0_desc_io, 0);
shm1_mg = (struct shm_mg_s *)metal_io_virt(ch->shm1_desc_io, 0);
shm0_addr_array = (void *)shm0_mg + sizeof(struct shm_mg_s);
shm1_addr_array = (void *)shm1_mg + sizeof(struct shm_mg_s);
d1 = metal_io_virt(ch->shm_io, ch->d1_start_offset);
+ lbuf = malloc(BUF_SIZE_MAX);
+ if (!lbuf) {
+ LPRINTF("ERROR: Failed to allocate local buffer for msg.\n");
+ return NULL;
+ }

LPRINTF("Wait for echo test to start.\n");
while (1) {
@@ -245,36 +252,55 @@ static void *ipi_task_echod(void *arg)
} while(1);
atomic_thread_fence(memory_order_acq_rel);
while(shm0_mg->used != shm0_mg->avails) {
- d0_pa = (metal_phys_addr_t)shm0_addr_array[shm0_mg->used];
+ d0_pa = (metal_phys_addr_t)
+ shm0_addr_array[shm0_mg->used];
d0 = metal_io_phys_to_virt(ch->shm_io, d0_pa);
if (!d0) {
- LPRINTF("ERROR: failed to get rx address: 0x%lx.\n",
+ LPRINTF("ERROR: failed to get rx addr:0x%lx.\n",
d0_pa);
- return NULL;
+ goto out;
+ }
+ /* Copy msg header from shared buf to local mem */
+ len = metal_io_block_read(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d0),
+ lbuf, sizeof(struct msg_hdr_s));
+ if (len < (int)sizeof(struct msg_hdr_s)) {
+ LPRINTF("ERROR: Failed to get msg header.\n");
+ goto out;
}
- msg_hdr = (struct msg_hdr_s *)d0;
+ msg_hdr = lbuf;
if (msg_hdr->len < 0) {
LPRINTF("ERROR: wrong msg length: %d.\n",
(int)msg_hdr->len);
- return NULL;
-#if DEBUG
+ goto out;
} else {
+ /* Copy msg data from shared buf to local mem */
+ d0 += sizeof(struct msg_hdr_s);
+ len = metal_io_block_read(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d0),
+ lbuf + sizeof(struct msg_hdr_s),
+ msg_hdr->len);
+#if DEBUG
LPRINTF("received: %d, %d\n",
(int)msg_hdr->index, (int)msg_hdr->len);
#endif
- }
- if (msg_hdr->len) {
- if (!strncmp((d0 + sizeof(struct msg_hdr_s)),
+ /* Check if the it is the shutdown message */
+ if (!strncmp((lbuf + sizeof(struct msg_hdr_s)),
SHUTDOWN, sizeof(SHUTDOWN))) {
LPRINTF("Received shutdown message\n");
- return NULL;
+ goto out;
}
}
- memcpy(d1, d0, sizeof(struct msg_hdr_s) + msg_hdr->len);
+ /* Copy the message back to the other end */
+ metal_io_block_write(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d1),
+ lbuf,
+ sizeof(struct msg_hdr_s) + msg_hdr->len);

/* Update the d1 address */
- shm1_addr_array[shm1_mg->avails] = (uint64_t)metal_io_virt_to_phys(
- ch->shm_io, d1);
+ shm1_addr_array[shm1_mg->avails] =
+ (uint64_t)metal_io_virt_to_phys(
+ ch->shm_io, d1);
d1 += (sizeof(struct msg_hdr_s) + msg_hdr->len);
shm0_mg->used++;
shm1_mg->avails++;
@@ -282,10 +308,13 @@ static void *ipi_task_echod(void *arg)
atomic_thread_fence(memory_order_acq_rel);

/* Send the message */
- metal_io_write32(ch->ipi_io, IPI_TRIG_OFFSET, ch->ipi_mask);
+ metal_io_write32(ch->ipi_io, IPI_TRIG_OFFSET,
+ ch->ipi_mask);
}
}

+out:
+ free(lbuf);
return NULL;
}

diff --git a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c
index a019bbc..1c41f1a 100644
--- a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c
+++ b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demo.c
@@ -89,6 +89,7 @@

#define PKGS_TOTAL 1024

+#define BUF_SIZE_MAX 512
#define SHUTDOWN "shutdown"

#define LPRINTF(format, ...) \
@@ -243,7 +244,7 @@ static void *ipi_task_echo(void *arg)
struct shm_mg_s *shm0_mg, *shm1_mg;
shm_addr_t *shm0_addr_array, *shm1_addr_array;
struct msg_hdr_s *msg_hdr, *msg_hdr_echo;
- void *d0, *d1;
+ void *d0, *d1, *lbuf, *tmpptr;
metal_phys_addr_t d1_pa;
unsigned long long tstart, tend;
long long tdiff;
@@ -254,6 +255,11 @@ static void *ipi_task_echo(void *arg)
shm0_addr_array = (void *)shm0_mg + sizeof(struct shm_mg_s);
shm1_addr_array = (void *)shm1_mg + sizeof(struct shm_mg_s);
d0 = metal_io_virt(ch->shm_io, ch->d0_start_offset);
+ lbuf = malloc(BUF_SIZE_MAX);
+ if (!lbuf) {
+ LPRINTF("ERROR: Failed to allocate local buffer for msg.\n");
+ return NULL;
+ }

LPRINTF("Start echo flood testing....\n");
LPRINTF("It sends msgs to the remote.\n");
@@ -264,19 +270,27 @@ static void *ipi_task_echo(void *arg)
shm1_mg->avails = 0;
shm1_mg->used = 0;
for (i = 0; i < PKGS_TOTAL; i++) {
- tstart = get_timestamp();
/* Construct a message to send */
- msg_hdr = (struct msg_hdr_s *)d0;
+ tmpptr = lbuf;
+ msg_hdr = tmpptr;
msg_hdr->index = i;
msg_hdr->len = sizeof(tstart);
- d0 += (sizeof(struct msg_hdr_s));
- metal_memcpy_io(d0, (void *)&tstart, msg_hdr->len);
+ tmpptr += sizeof(struct msg_hdr_s);
+ tstart = get_timestamp();
+ *(unsigned long long *)tmpptr = tstart;
+
+ /* copy message to shared buffer */
+ metal_io_block_write(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d0),
+ msg_hdr,
+ sizeof(struct msg_hdr_s) + msg_hdr->len);
+
/* Update the shared memory management information
* Tell the other end where the d0 buffer is.
*/
shm0_addr_array[i] = (shm_addr_t)metal_io_virt_to_phys(
- ch->shm_io, msg_hdr);
- d0 += msg_hdr->len;
+ ch->shm_io, d0);
+ d0 += sizeof(struct msg_hdr_s) + msg_hdr->len;
shm0_mg->avails++;

/* memory barrier */
@@ -307,7 +321,7 @@ static void *ipi_task_echo(void *arg)
if (!d1) {
LPRINTF("ERROR: failed to get rx address: 0x%lx.\n",
d1_pa);
- return NULL;
+ goto out;
}
msg_hdr_echo = (struct msg_hdr_s *)d1;

@@ -315,7 +329,7 @@ static void *ipi_task_echo(void *arg)
if (msg_hdr_echo->index != (uint32_t)i) {
LPRINTF("ERROR: wrong msg: expected: %d, actual: %d\n",
i, msg_hdr_echo->index);
- return NULL;
+ goto out;
}
d1 += sizeof(struct msg_hdr_s);
d0 += sizeof(struct msg_hdr_s);
@@ -324,7 +338,7 @@ static void *ipi_task_echo(void *arg)
LPRINTF("ERROR: wrong message, [%d], %llu:%llu\n",
i, *(unsigned long long *)d0,
*(unsigned long long *)d1);
- return NULL;
+ goto out;
}
d0 += msg_hdr_echo->len;
shm1_mg->used++;
@@ -335,11 +349,18 @@ static void *ipi_task_echo(void *arg)
tdiff = tend - tstart;

/* Send shutdown message */
- msg_hdr = (struct msg_hdr_s *)d0;
+ tmpptr = lbuf;
+ msg_hdr = tmpptr;
msg_hdr->index = i;
- d0 += sizeof(struct msg_hdr_s);
- sprintf(d0, SHUTDOWN);
- msg_hdr->len = sizeof(d0);
+ msg_hdr->len = strlen(SHUTDOWN);
+ tmpptr += sizeof(struct msg_hdr_s);
+ sprintf(tmpptr, SHUTDOWN);
+ /* copy message to shared buffer */
+ metal_io_block_write(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d0),
+ msg_hdr,
+ sizeof(struct msg_hdr_s) + msg_hdr->len);
+
shm0_addr_array[i] = (uint64_t)metal_io_virt_to_phys(
ch->shm_io, msg_hdr);
shm0_mg->avails++;
@@ -353,6 +374,8 @@ static void *ipi_task_echo(void *arg)
LPRINTF("Total packages: %d, time_avg = %lds, %ldns\n",
i, (long int)tdiff_avg_s, (long int)tdiff_avg_ns);

+out:
+ free(lbuf);
return NULL;
}

diff --git a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c
index 7615bb3..5f0c1e3 100644
--- a/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c
+++ b/examples/system/linux/zynqmp/zynqmp_amp_demo/libmetal_amp_demod.c
@@ -58,6 +58,7 @@
#define D0_SHM_OFFSET 0x00000
#define D1_SHM_OFFSET 0x20000

+#define BUF_SIZE_MAX 512
#define SHUTDOWN "shutdown"

#define LPRINTF(format, ...) \
@@ -155,14 +156,20 @@ static void *ipi_task_echod(void *arg)
shm_addr_t *shm0_addr_array, *shm1_addr_array;
struct msg_hdr_s *msg_hdr;
unsigned int flags;
- void *d0, *d1;
+ void *d0, *d1, *lbuf;
metal_phys_addr_t d0_pa;
+ int len;

shm0_mg = (struct shm_mg_s *)metal_io_virt(ch->shm0_desc_io, 0);
shm1_mg = (struct shm_mg_s *)metal_io_virt(ch->shm1_desc_io, 0);
shm0_addr_array = (void *)shm0_mg + sizeof(struct shm_mg_s);
shm1_addr_array = (void *)shm1_mg + sizeof(struct shm_mg_s);
d1 = metal_io_virt(ch->shm_io, ch->d1_start_offset);
+ lbuf = malloc(BUF_SIZE_MAX);
+ if (!lbuf) {
+ LPRINTF("ERROR: Failed to allocate local buffer for msg.\n");
+ return NULL;
+ }

LPRINTF("Wait for echo test to start.\n");
while (1) {
@@ -180,33 +187,51 @@ static void *ipi_task_echod(void *arg)
d0_pa = (metal_phys_addr_t)shm0_addr_array[shm0_mg->used];
d0 = metal_io_phys_to_virt(ch->shm_io, d0_pa);
if (!d0) {
- LPRINTF("ERROR: failed to get rx address: 0x%lx.\n",
+ LPRINTF("ERROR: failed to get rx addr:0x%lx.\n",
d0_pa);
- return NULL;
+ goto out;
+ }
+ /* Copy msg header from shared buf to local mem */
+ len = metal_io_block_read(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d0),
+ lbuf, sizeof(struct msg_hdr_s));
+ if (len < (int)sizeof(struct msg_hdr_s)) {
+ LPRINTF("ERROR: failed to get msg header.\n");
+ goto out;
}
- msg_hdr = (struct msg_hdr_s *)d0;
+ msg_hdr = lbuf;
if (msg_hdr->len < 0) {
LPRINTF("ERROR: wrong msg length: %d.\n",
(int)msg_hdr->len);
- return NULL;
-#if DEBUG
+ goto out;
} else {
+ /* copy msg data from shared buf to local mem */
+ d0 += sizeof(struct msg_hdr_s);
+ len = metal_io_block_read(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d0),
+ lbuf + sizeof(struct msg_hdr_s),
+ msg_hdr->len);
+#if DEBUG
LPRINTF("received: %d, %d\n",
(int)msg_hdr->index, (int)msg_hdr->len);
#endif
- }
- if (msg_hdr->len) {
- if (!strncmp((d0 + sizeof(struct msg_hdr_s)),
+ /* Check if the it is the shutdown message */
+ if (!strncmp((lbuf + sizeof(struct msg_hdr_s)),
SHUTDOWN, sizeof(SHUTDOWN))) {
LPRINTF("Received shutdown message\n");
- return NULL;
+ goto out;
}
}
- memcpy(d1, d0, sizeof(struct msg_hdr_s) + msg_hdr->len);
+ /* Copy the message back to the other end */
+ metal_io_block_write(ch->shm_io,
+ metal_io_virt_to_offset(ch->shm_io, d1),
+ lbuf,
+ sizeof(struct msg_hdr_s) + msg_hdr->len);

/* Update the d1 address */
- shm1_addr_array[shm1_mg->avails] = (uint64_t)metal_io_virt_to_phys(
- ch->shm_io, d1);
+ shm1_addr_array[shm1_mg->avails] =
+ (uint64_t)metal_io_virt_to_phys(
+ ch->shm_io, d1);
d1 += (sizeof(struct msg_hdr_s) + msg_hdr->len);
shm0_mg->used++;
shm1_mg->avails++;
@@ -214,10 +239,13 @@ static void *ipi_task_echod(void *arg)
atomic_thread_fence(memory_order_acq_rel);

/* Send the message */
- metal_io_write32(ch->ipi_io, IPI_TRIG_OFFSET, ch->ipi_mask);
+ metal_io_write32(ch->ipi_io, IPI_TRIG_OFFSET,
+ ch->ipi_mask);
}
}

+out:
+ free(lbuf);
return NULL;
}

--
2.7.4

Reply all
Reply to author
Forward
0 new messages