aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/libc/string/memcpy_from_ci.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/libc/string/memcpy_from_ci.c')
-rw-r--r--roms/skiboot/libc/string/memcpy_from_ci.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/roms/skiboot/libc/string/memcpy_from_ci.c b/roms/skiboot/libc/string/memcpy_from_ci.c
new file mode 100644
index 000000000..dd4d94e02
--- /dev/null
+++ b/roms/skiboot/libc/string/memcpy_from_ci.c
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/*
+ * Copyright 2013-2016 IBM Corp
+ */
+
+#include <ccan/short_types/short_types.h>
+#include <io.h>
+#include <string.h>
+
+void *memcpy_from_ci(void *destpp, const void *srcpp, size_t len)
+{
+ const size_t block = sizeof(uint64_t);
+ unsigned long int destp = (long int) destpp;
+ unsigned long int srcp = (long int) srcpp;
+
+ /* Copy as many blocks as possible if srcp is block aligned */
+ if ((srcp % block) == 0) {
+ while ((len - block) > -1) {
+ uint64_t v;
+ if (HAVE_BIG_ENDIAN)
+ v = in_be64((beint64_t*)srcp);
+ else
+ v = in_le64((leint64_t*)srcp);
+ *((uint64_t *) destp) = v;
+ srcp += block;
+ destp += block;
+ len -= block;
+ }
+ }
+ /*
+ * Byte-by-byte copy if srcp is not block aligned or len is/becomes
+ * less than one block
+ */
+ while (len > 0) {
+ *((uint8_t*) destp) = in_8((uint8_t*)srcp);
+ srcp += 1;
+ destp += 1;
+ len--;
+ }
+ return destpp;
+}