diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arm/arm/bcopyinout.S | 47 | ||||
-rw-r--r-- | sys/arm/arm/bcopyinout_xscale.S | 44 | ||||
-rw-r--r-- | sys/arm/arm/support.S | 58 | ||||
-rw-r--r-- | sys/arm/include/md_var.h | 10 |
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_ */ |