[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v5 08/10] lib/arm: Add I/O memory copy helpers
This commit introduces two helper functions, `__memcpy_fromio` and `__memcpy_toio`, to provide a robust mechanism for copying data between standard memory and memory-mapped I/O (MMIO) space for the ARM architecture. These functions are designed to handle memory transfers safely, accounting for potential address alignment issues to ensure correctness and improve performance where possible. The implementation is specific to ARM and uses relaxed I/O accessors. __memcpy_fromio: Copies a block of data from an I/O memory source to a destination in standard ("real") memory. The implementation first handles any unaligned bytes at the beginning of the source buffer individually using byte-wise reads. It then copies the bulk of the data using 32-bit reads for efficiency, and finally processes any remaining bytes at the end of the buffer. __memcpy_toio: Copies a block of data from standard memory to a destination in I/O memory space. It follows a similar strategy, handling any initial unaligned portion of the destination buffer byte-by-byte before using more efficient 32-bit writes for the main, aligned part of the transfer. Any trailing bytes are also handled individually. xen/include/xen/lib/arm/io.h Signed-off-by: Oleksii Moisieiev <oleksii_moisieiev@xxxxxxxx> --- Changes in v5: - move memcpy_toio/fromio to the generic place xen/include/xen/lib/arm/io.h | 15 +++++++ xen/lib/Makefile | 1 + xen/lib/arm/Makefile | 1 + xen/lib/arm/io.c | 80 ++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 xen/include/xen/lib/arm/io.h create mode 100644 xen/lib/arm/Makefile create mode 100644 xen/lib/arm/io.c diff --git a/xen/include/xen/lib/arm/io.h b/xen/include/xen/lib/arm/io.h new file mode 100644 index 0000000000..86973660ba --- /dev/null +++ b/xen/include/xen/lib/arm/io.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _XEN_LIB_ARM_IO_H +#define _XEN_LIB_ARM_IO_H + +#include <xen/types.h> + +/* + * Prototypes for I/O memory access functions. + */ +extern void __memcpy_fromio(void *to, const volatile void __iomem *from, + size_t count); +extern void __memcpy_toio(volatile void __iomem *to, const void *from, + size_t count); + +#endif /* _XEN_LIB_ARM_IO_H */ diff --git a/xen/lib/Makefile b/xen/lib/Makefile index 5ccb1e5241..efa8157a72 100644 --- a/xen/lib/Makefile +++ b/xen/lib/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_X86) += x86/ +obj-$(CONFIG_ARM) += arm/ lib-y += bsearch.o lib-y += ctors.o diff --git a/xen/lib/arm/Makefile b/xen/lib/arm/Makefile new file mode 100644 index 0000000000..87250b3822 --- /dev/null +++ b/xen/lib/arm/Makefile @@ -0,0 +1 @@ +obj-y += io.o \ No newline at end of file diff --git a/xen/lib/arm/io.c b/xen/lib/arm/io.c new file mode 100644 index 0000000000..d267bd28e4 --- /dev/null +++ b/xen/lib/arm/io.c @@ -0,0 +1,80 @@ +#include <asm/io.h> +#include <xen/lib/arm/io.h> + +/* + * memcpy_fromio - Copy data from IO memory space to "real" memory space. + * @to: Where to copy to + * @from: Where to copy from + * @count: The size of the area. + */ +void __memcpy_fromio(void *to, const volatile void __iomem *from, + size_t count) +{ + while ( count && !IS_ALIGNED((unsigned long)from, 4) ) + { + *(u8 *)to = readb_relaxed(from); + from++; + to++; + count--; + } + + while ( count >= 4 ) + { + *(u32 *)to = readl_relaxed(from); + from += 4; + to += 4; + count -= 4; + } + + while ( count ) + { + *(u8 *)to = readb_relaxed(from); + from++; + to++; + count--; + } +} + +/* + * memcpy_toio - Copy data from "real" memory space to IO memory space. + * @to: Where to copy to + * @from: Where to copy from + * @count: The size of the area. + */ +void __memcpy_toio(volatile void __iomem *to, const void *from, + size_t count) +{ + while ( count && !IS_ALIGNED((unsigned long)to, 4) ) + { + writeb_relaxed(*(u8 *)from, to); + from++; + to++; + count--; + } + + while ( count >= 4 ) + { + writel_relaxed(*(u32 *)from, to); + from += 4; + to += 4; + count -= 4; + } + + while ( count ) + { + writeb_relaxed(*(u8 *)from, to); + from++; + to++; + count--; + } +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: t + * End: + */ -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |