arm64: klib: Optimised memory functions
authorCatalin Marinas <catalin.marinas@arm.com>
Thu, 21 Mar 2013 16:16:43 +0000 (16:16 +0000)
committerCatalin Marinas <catalin.marinas@arm.com>
Thu, 21 Mar 2013 17:39:29 +0000 (17:39 +0000)
This patch introduces AArch64-specific memory functions (memcpy,
memmove, memchr, memset). These functions are not optimised for any CPU
implementation but can be used as a starting point once hardware is
available.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
arch/arm64/include/asm/Kbuild
arch/arm64/include/asm/string.h [new file with mode: 0644]
arch/arm64/kernel/arm64ksyms.c
arch/arm64/lib/Makefile
arch/arm64/lib/memchr.S [new file with mode: 0644]
arch/arm64/lib/memcpy.S [new file with mode: 0644]
arch/arm64/lib/memmove.S [new file with mode: 0644]
arch/arm64/lib/memset.S [new file with mode: 0644]

index e5fe4f99fe1000b373f311ce54c874a0158e2c45..a13a4a493d56462f00d502684d192178af0d7956 100644 (file)
@@ -39,7 +39,6 @@ generic-y += shmbuf.h
 generic-y += sizes.h
 generic-y += socket.h
 generic-y += sockios.h
-generic-y += string.h
 generic-y += switch_to.h
 generic-y += swab.h
 generic-y += termbits.h
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
new file mode 100644 (file)
index 0000000..be8a644
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_STRING_H
+#define __ASM_STRING_H
+
+#define __HAVE_ARCH_MEMCPY
+extern void *memcpy(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMMOVE
+extern void *memmove(void *, const void *, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMCHR
+extern void *memchr(const void *, int, __kernel_size_t);
+
+#define __HAVE_ARCH_MEMSET
+extern void *memset(void *, int, __kernel_size_t);
+
+#endif
index aa3e948f78857bb1e64278c79e57916abbb2e5a4..d7f7b17c414e58602d0c8c79d69a852b74385bfa 100644 (file)
@@ -46,3 +46,9 @@ EXPORT_SYMBOL(__atomic_hash);
 
        /* physical memory */
 EXPORT_SYMBOL(memstart_addr);
+
+       /* string / mem functions */
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(memchr);
index 2fb7f6092aae5f99ff888340251dffed1bb0c8a9..2fce1398aa246b83901014767fbf5200bbaafdfe 100644 (file)
@@ -1,4 +1,5 @@
 lib-y          := bitops.o delay.o                                     \
                   strncpy_from_user.o strnlen_user.o clear_user.o      \
                   copy_from_user.o copy_to_user.o copy_in_user.o       \
-                  copy_page.o clear_page.o
+                  copy_page.o clear_page.o                             \
+                  memchr.o memcpy.o memmove.o memset.o
diff --git a/arch/arm64/lib/memchr.S b/arch/arm64/lib/memchr.S
new file mode 100644 (file)
index 0000000..8636b75
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Based on arch/arm/lib/memchr.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Find a character in an area of memory.
+ *
+ * Parameters:
+ *     x0 - buf
+ *     x1 - c
+ *     x2 - n
+ * Returns:
+ *     x0 - address of first occurrence of 'c' or 0
+ */
+ENTRY(memchr)
+       and     w1, w1, #0xff
+1:     subs    x2, x2, #1
+       b.mi    2f
+       ldrb    w3, [x0], #1
+       cmp     w3, w1
+       b.ne    1b
+       sub     x0, x0, #1
+       ret
+2:     mov     x0, #0
+       ret
+ENDPROC(memchr)
diff --git a/arch/arm64/lib/memcpy.S b/arch/arm64/lib/memcpy.S
new file mode 100644 (file)
index 0000000..27b5003
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Copy a buffer from src to dest (alignment handled by the hardware)
+ *
+ * Parameters:
+ *     x0 - dest
+ *     x1 - src
+ *     x2 - n
+ * Returns:
+ *     x0 - dest
+ */
+ENTRY(memcpy)
+       mov     x4, x0
+       subs    x2, x2, #8
+       b.mi    2f
+1:     ldr     x3, [x1], #8
+       subs    x2, x2, #8
+       str     x3, [x4], #8
+       b.pl    1b
+2:     adds    x2, x2, #4
+       b.mi    3f
+       ldr     w3, [x1], #4
+       sub     x2, x2, #4
+       str     w3, [x4], #4
+3:     adds    x2, x2, #2
+       b.mi    4f
+       ldrh    w3, [x1], #2
+       sub     x2, x2, #2
+       strh    w3, [x4], #2
+4:     adds    x2, x2, #1
+       b.mi    5f
+       ldrb    w3, [x1]
+       strb    w3, [x4]
+5:     ret
+ENDPROC(memcpy)
diff --git a/arch/arm64/lib/memmove.S b/arch/arm64/lib/memmove.S
new file mode 100644 (file)
index 0000000..b79fdfa
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Move a buffer from src to test (alignment handled by the hardware).
+ * If dest <= src, call memcpy, otherwise copy in reverse order.
+ *
+ * Parameters:
+ *     x0 - dest
+ *     x1 - src
+ *     x2 - n
+ * Returns:
+ *     x0 - dest
+ */
+ENTRY(memmove)
+       cmp     x0, x1
+       b.ls    memcpy
+       add     x4, x0, x2
+       add     x1, x1, x2
+       subs    x2, x2, #8
+       b.mi    2f
+1:     ldr     x3, [x1, #-8]!
+       subs    x2, x2, #8
+       str     x3, [x4, #-8]!
+       b.pl    1b
+2:     adds    x2, x2, #4
+       b.mi    3f
+       ldr     w3, [x1, #-4]!
+       sub     x2, x2, #4
+       str     w3, [x4, #-4]!
+3:     adds    x2, x2, #2
+       b.mi    4f
+       ldrh    w3, [x1, #-2]!
+       sub     x2, x2, #2
+       strh    w3, [x4, #-2]!
+4:     adds    x2, x2, #1
+       b.mi    5f
+       ldrb    w3, [x1, #-1]
+       strb    w3, [x4, #-1]
+5:     ret
+ENDPROC(memmove)
diff --git a/arch/arm64/lib/memset.S b/arch/arm64/lib/memset.S
new file mode 100644 (file)
index 0000000..87e4a68
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Fill in the buffer with character c (alignment handled by the hardware)
+ *
+ * Parameters:
+ *     x0 - buf
+ *     x1 - c
+ *     x2 - n
+ * Returns:
+ *     x0 - buf
+ */
+ENTRY(memset)
+       mov     x4, x0
+       and     w1, w1, #0xff
+       orr     w1, w1, w1, lsl #8
+       orr     w1, w1, w1, lsl #16
+       orr     x1, x1, x1, lsl #32
+       subs    x2, x2, #8
+       b.mi    2f
+1:     str     x1, [x4], #8
+       subs    x2, x2, #8
+       b.pl    1b
+2:     adds    x2, x2, #4
+       b.mi    3f
+       sub     x2, x2, #4
+       str     w1, [x4], #4
+3:     adds    x2, x2, #2
+       b.mi    4f
+       sub     x2, x2, #2
+       strh    w1, [x4], #2
+4:     adds    x2, x2, #1
+       b.mi    5f
+       strb    w1, [x4]
+5:     ret
+ENDPROC(memset)