summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2005-10-03 14:12:10 +0000
committercognet <cognet@FreeBSD.org>2005-10-03 14:12:10 +0000
commit4cd1fe1a5957a5b4e0e5ecf92d732467a7eb3220 (patch)
tree381689ae767052268ea7e1437386d4af61b5ae53 /sys
parentb528a2341702ba37400bf7f647766b0ee6983f4b (diff)
downloadFreeBSD-src-4cd1fe1a5957a5b4e0e5ecf92d732467a7eb3220.zip
FreeBSD-src-4cd1fe1a5957a5b4e0e5ecf92d732467a7eb3220.tar.gz
Add a new API to let platform-specific ports provide functions for big
copy/zeroing.
Diffstat (limited to 'sys')
-rw-r--r--sys/arm/arm/bcopyinout.S47
-rw-r--r--sys/arm/arm/bcopyinout_xscale.S44
-rw-r--r--sys/arm/arm/support.S58
-rw-r--r--sys/arm/include/md_var.h10
4 files changed, 159 insertions, 0 deletions
diff --git a/sys/arm/arm/bcopyinout.S b/sys/arm/arm/bcopyinout.S
index fdd57d6..632b000 100644
--- a/sys/arm/arm/bcopyinout.S
+++ b/sys/arm/arm/bcopyinout.S
@@ -40,6 +40,11 @@
#include <machine/asm.h>
+.L_arm_memcpy:
+ .word _C_LABEL(_arm_memcpy)
+.L_min_memcpy_size:
+ .word _C_LABEL(_min_memcpy_size)
+
__FBSDID("$FreeBSD$");
#ifdef __XSCALE__
#include <arm/arm/bcopyinout_xscale.S>
@@ -82,6 +87,27 @@ ENTRY(copyin)
moveq r0, #0
RETeq
+ ldr r3, .L_arm_memcpy
+ ldr r3, [r3]
+ cmp r3, #0
+ beq .Lnormal
+ ldr r3, .L_min_memcpy_size
+ ldr r3, [r3]
+ cmp r2, r3
+ blt .Lnormal
+ stmfd sp!, {r0-r2, r4, lr}
+ mov r3, r0
+ mov r0, r1
+ mov r1, r3
+ mov r3, #2 /* SRC_IS_USER */
+ ldr r4, .L_arm_memcpy
+ mov lr, pc
+ ldr pc, [r4]
+ cmp r0, #0
+ ldmfd sp!, {r0-r2, r4, lr}
+ moveq r0, #0
+ RETeq
+
SAVE_REGS
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
@@ -306,6 +332,27 @@ ENTRY(copyout)
moveq r0, #0
RETeq
+ ldr r3, .L_arm_memcpy
+ ldr r3, [r3]
+ cmp r3, #0
+ beq .Lnormale
+ ldr r3, .L_min_memcpy_size
+ ldr r3, [r3]
+ cmp r2, r3
+ blt .Lnormale
+ stmfd sp!, {r0-r2, r4, lr}
+ mov r3, r0
+ mov r0, r1
+ mov r1, r3
+ mov r3, #1 /* DST_IS_USER */
+ ldr r4, .L_arm_memcpy
+ mov lr, pc
+ ldr pc, [r4]
+ cmp r0, #0
+ ldmfd sp!, {r0-r2, r4, lr}
+ moveq r0, #0
+ RETeq
+
SAVE_REGS
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */
diff --git a/sys/arm/arm/bcopyinout_xscale.S b/sys/arm/arm/bcopyinout_xscale.S
index bb785f8..94846dc 100644
--- a/sys/arm/arm/bcopyinout_xscale.S
+++ b/sys/arm/arm/bcopyinout_xscale.S
@@ -61,6 +61,28 @@ ENTRY(copyin)
movle r0, #0x00
movle pc, lr /* Bail early if length is <= 0 */
+ ldr r3, .L_arm_memcpy
+ ldr r3, [r3]
+ cmp r3, #0
+ beq .Lnormal
+ ldr r3, .L_min_memcpy_size
+ ldr r3, [r3]
+ cmp r2, r3
+ blt .Lnormal
+ stmfd sp!, {r0-r2, r4, lr}
+ mov r3, r0
+ mov r0, r1
+ mov r1, r3
+ mov r3, #2 /* SRC_IS_USER */
+ ldr r4, .L_arm_memcpy
+ mov lr, pc
+ ldr pc, [r4]
+ cmp r0, #0
+ ldmfd sp!, {r0-r2, r4, lr}
+ moveq r0, #0
+ RETeq
+
+.Lnormal:
stmfd sp!, {r10-r11, lr}
#ifdef MULTIPROCESSOR
@@ -491,6 +513,28 @@ ENTRY(copyout)
movle r0, #0x00
movle pc, lr /* Bail early if length is <= 0 */
+ ldr r3, .L_arm_memcpy
+ ldr r3, [r3]
+ cmp r3, #0
+ beq .Lnormale
+ ldr r3, .L_min_memcpy_size
+ ldr r3, [r3]
+ cmp r2, r3
+ blt .Lnormale
+ stmfd sp!, {r0-r2, r4, lr}
+ mov r3, r0
+ mov r0, r1
+ mov r1, r3
+ mov r3, #1 /* DST_IS_USER */
+ ldr r4, .L_arm_memcpy
+ mov lr, pc
+ ldr pc, [r4]
+ cmp r0, #0
+ ldmfd sp!, {r0-r2, r4, lr}
+ moveq r0, #0
+ RETeq
+
+.Lnormale:
stmfd sp!, {r10-r11, lr}
#ifdef MULTIPROCESSOR
diff --git a/sys/arm/arm/support.S b/sys/arm/arm/support.S
index 242ece2..2e7d2a8 100644
--- a/sys/arm/arm/support.S
+++ b/sys/arm/arm/support.S
@@ -30,6 +30,14 @@ __FBSDID("$FreeBSD$");
#include "assym.s"
+.L_arm_memcpy:
+ .word _C_LABEL(_arm_memcpy)
+.L_arm_bzero:
+ .word _C_LABEL(_arm_bzero)
+.L_min_memcpy_size:
+ .word _C_LABEL(_min_memcpy_size)
+.L_min_bzero_size:
+ .word _C_LABEL(_min_bzero_size)
/*
* memset: Sets a block of memory to the specified value
*
@@ -43,6 +51,22 @@ __FBSDID("$FreeBSD$");
*/
/* LINTSTUB: Func: void bzero(void *, size_t) */
ENTRY(bzero)
+ ldr r3, .L_arm_bzero
+ ldr r3, [r3]
+ cmp r3, #0
+ beq .Lnormal0
+ ldr r2, .L_min_bzero_size
+ ldr r2, [r2]
+ cmp r1, r2
+ blt .Lnormal0
+ stmfd sp!, {r0, r1, lr}
+ mov r2, #0
+ mov lr, pc
+ mov pc, r3
+ cmp r0, #0
+ ldmfd sp!, {r0, r1, lr}
+ RETeq
+.Lnormal0:
mov r3, #0x00
b do_memset
@@ -847,6 +871,23 @@ ENTRY(memmove)
#if !defined(__XSCALE__)
ENTRY(memcpy)
/* save leaf functions having to store this away */
+ ldr r3, .L_arm_memcpy
+ ldr r3, [r3]
+ cmp r3, #0
+ beq .Lnormal
+ ldr r3, .L_min_memcpy_size
+ ldr r3, [r3]
+ cmp r2, r3
+ blt .Lnormal
+ stmfd sp!, {r0-r2, r4, lr}
+ mov r3, #0
+ ldr r4, .L_arm_memcpy
+ mov lr, pc
+ ldr pc, [r4]
+ cmp r0, #0
+ ldmfd sp!, {r0-r2, r4, lr}
+ RETeq
+
stmdb sp!, {r0, lr} /* memcpy() returns dest addr */
subs r2, r2, #4
@@ -1054,6 +1095,23 @@ ENTRY(memcpy)
pld [r1]
cmp r2, #0x0c
ble .Lmemcpy_short /* <= 12 bytes */
+ ldr r3, .L_arm_memcpy
+ ldr r3, [r3]
+ cmp r3, #0
+ beq .Lnormal
+ ldr r3, .L_min_memcpy_size
+ ldr r3, [r3]
+ cmp r2, r3
+ blt .Lnormal
+ stmfd sp!, {r0-r2, r4, lr}
+ mov r3, #0
+ ldr r4, .L_arm_memcpy
+ mov lr, pc
+ ldr pc, [r4]
+ cmp r0, #0
+ ldmfd sp!, {r0-r2, r4, lr}
+ RETeq
+.Lnormal:
mov r3, r0 /* We must not clobber r0 */
/* Word-align the destination buffer */
diff --git a/sys/arm/include/md_var.h b/sys/arm/include/md_var.h
index 14dc2e4..868b5bc 100644
--- a/sys/arm/include/md_var.h
+++ b/sys/arm/include/md_var.h
@@ -36,4 +36,14 @@
extern char sigcode[];
extern int szsigcode;
+extern int (*_arm_memcpy)(void *, void *, int, int);
+extern int (*_arm_bzero)(void *, int, int);
+
+extern int _min_memcpy_size;
+extern int _min_bzero_size;
+
+#define DST_IS_USER 0x1
+#define SRC_IS_USER 0x2
+#define IS_PHYSICAL 0x4
+
#endif /* !_MACHINE_MD_VAR_H_ */
OpenPOWER on IntegriCloud