Use memcpy() in kcopy(), copyin(), and copyout(). XXX This means we have
to burn 3 insns to swap the arguments. Need to change the interface to these routines to match memcpy(). G/C bcopy() from here. We'll let it be provided by libkern (which is what provides memcpy()) until bcopy() is exorcised completely.
This commit is contained in:
parent
ac8a2539c1
commit
d819792e68
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: locore.s,v 1.96 2001/05/30 15:24:27 lukem Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.97 2001/07/13 00:06:06 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
#include <machine/asm.h>
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.96 2001/05/30 15:24:27 lukem Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: locore.s,v 1.97 2001/07/13 00:06:06 thorpej Exp $");
|
||||
|
||||
#include "assym.h"
|
||||
|
||||
@ -1090,237 +1090,6 @@ NESTED(copyoutstr, 4, 16, ra, IM_RA|IM_S0, 0)
|
||||
RET /* v0 left over from copystr */
|
||||
END(copyoutstr)
|
||||
|
||||
/*
|
||||
* Copy a bytes within the kernel's address space.
|
||||
*
|
||||
* Although bcopy() is not specified to handle overlapping regions,
|
||||
* this version does do so.
|
||||
*
|
||||
* void bcopy(char *from, char *to, size_t len);
|
||||
*/
|
||||
LEAF(bcopy,3)
|
||||
|
||||
/* Check for negative length */
|
||||
ble a2,bcopy_done
|
||||
|
||||
/* Check for overlap */
|
||||
subq a1,a0,t5
|
||||
cmpult t5,a2,t5
|
||||
bne t5,bcopy_overlap
|
||||
|
||||
/* a3 = end address */
|
||||
addq a0,a2,a3
|
||||
|
||||
/* Get the first word */
|
||||
ldq_u t2,0(a0)
|
||||
|
||||
/* Do they have the same alignment? */
|
||||
xor a0,a1,t0
|
||||
and t0,7,t0
|
||||
and a1,7,t1
|
||||
bne t0,bcopy_different_alignment
|
||||
|
||||
/* src & dst have same alignment */
|
||||
beq t1,bcopy_all_aligned
|
||||
|
||||
ldq_u t3,0(a1)
|
||||
addq a2,t1,a2
|
||||
mskqh t2,a0,t2
|
||||
mskql t3,a0,t3
|
||||
or t2,t3,t2
|
||||
|
||||
/* Dst is 8-byte aligned */
|
||||
|
||||
bcopy_all_aligned:
|
||||
/* If less than 8 bytes,skip loop */
|
||||
subq a2,1,t0
|
||||
and a2,7,a2
|
||||
bic t0,7,t0
|
||||
beq t0,bcopy_samealign_lp_end
|
||||
|
||||
bcopy_samealign_lp:
|
||||
stq_u t2,0(a1)
|
||||
addq a1,8,a1
|
||||
ldq_u t2,8(a0)
|
||||
subq t0,8,t0
|
||||
addq a0,8,a0
|
||||
bne t0,bcopy_samealign_lp
|
||||
|
||||
bcopy_samealign_lp_end:
|
||||
/* If we're done, exit */
|
||||
bne a2,bcopy_small_left
|
||||
stq_u t2,0(a1)
|
||||
RET
|
||||
|
||||
bcopy_small_left:
|
||||
mskql t2,a2,t4
|
||||
ldq_u t3,0(a1)
|
||||
mskqh t3,a2,t3
|
||||
or t4,t3,t4
|
||||
stq_u t4,0(a1)
|
||||
RET
|
||||
|
||||
bcopy_different_alignment:
|
||||
/*
|
||||
* this is the fun part
|
||||
*/
|
||||
addq a0,a2,a3
|
||||
cmpule a2,8,t0
|
||||
bne t0,bcopy_da_finish
|
||||
|
||||
beq t1,bcopy_da_noentry
|
||||
|
||||
/* Do the initial partial word */
|
||||
subq zero,a1,t0
|
||||
and t0,7,t0
|
||||
ldq_u t3,7(a0)
|
||||
extql t2,a0,t2
|
||||
extqh t3,a0,t3
|
||||
or t2,t3,t5
|
||||
insql t5,a1,t5
|
||||
ldq_u t6,0(a1)
|
||||
mskql t6,a1,t6
|
||||
or t5,t6,t5
|
||||
stq_u t5,0(a1)
|
||||
addq a0,t0,a0
|
||||
addq a1,t0,a1
|
||||
subq a2,t0,a2
|
||||
ldq_u t2,0(a0)
|
||||
|
||||
bcopy_da_noentry:
|
||||
subq a2,1,t0
|
||||
bic t0,7,t0
|
||||
and a2,7,a2
|
||||
beq t0,bcopy_da_finish2
|
||||
|
||||
bcopy_da_lp:
|
||||
ldq_u t3,7(a0)
|
||||
addq a0,8,a0
|
||||
extql t2,a0,t4
|
||||
extqh t3,a0,t5
|
||||
subq t0,8,t0
|
||||
or t4,t5,t5
|
||||
stq t5,0(a1)
|
||||
addq a1,8,a1
|
||||
beq t0,bcopy_da_finish1
|
||||
ldq_u t2,7(a0)
|
||||
addq a0,8,a0
|
||||
extql t3,a0,t4
|
||||
extqh t2,a0,t5
|
||||
subq t0,8,t0
|
||||
or t4,t5,t5
|
||||
stq t5,0(a1)
|
||||
addq a1,8,a1
|
||||
bne t0,bcopy_da_lp
|
||||
|
||||
bcopy_da_finish2:
|
||||
/* Do the last new word */
|
||||
mov t2,t3
|
||||
|
||||
bcopy_da_finish1:
|
||||
/* Do the last partial word */
|
||||
ldq_u t2,-1(a3)
|
||||
extql t3,a0,t3
|
||||
extqh t2,a0,t2
|
||||
or t2,t3,t2
|
||||
br zero,bcopy_samealign_lp_end
|
||||
|
||||
bcopy_da_finish:
|
||||
/* Do the last word in the next source word */
|
||||
ldq_u t3,-1(a3)
|
||||
extql t2,a0,t2
|
||||
extqh t3,a0,t3
|
||||
or t2,t3,t2
|
||||
insqh t2,a1,t3
|
||||
insql t2,a1,t2
|
||||
lda t4,-1(zero)
|
||||
mskql t4,a2,t5
|
||||
cmovne t5,t5,t4
|
||||
insqh t4,a1,t5
|
||||
insql t4,a1,t4
|
||||
addq a1,a2,a4
|
||||
ldq_u t6,0(a1)
|
||||
ldq_u t7,-1(a4)
|
||||
bic t6,t4,t6
|
||||
bic t7,t5,t7
|
||||
and t2,t4,t2
|
||||
and t3,t5,t3
|
||||
or t2,t6,t2
|
||||
or t3,t7,t3
|
||||
stq_u t3,-1(a4)
|
||||
stq_u t2,0(a1)
|
||||
RET
|
||||
|
||||
bcopy_overlap:
|
||||
/*
|
||||
* Basically equivalent to previous case, only backwards.
|
||||
* Not quite as highly optimized
|
||||
*/
|
||||
addq a0,a2,a3
|
||||
addq a1,a2,a4
|
||||
|
||||
/* less than 8 bytes - don't worry about overlap */
|
||||
cmpule a2,8,t0
|
||||
bne t0,bcopy_ov_short
|
||||
|
||||
/* Possibly do a partial first word */
|
||||
and a4,7,t4
|
||||
beq t4,bcopy_ov_nostart2
|
||||
subq a3,t4,a3
|
||||
subq a4,t4,a4
|
||||
ldq_u t1,0(a3)
|
||||
subq a2,t4,a2
|
||||
ldq_u t2,7(a3)
|
||||
ldq t3,0(a4)
|
||||
extql t1,a3,t1
|
||||
extqh t2,a3,t2
|
||||
or t1,t2,t1
|
||||
mskqh t3,t4,t3
|
||||
mskql t1,t4,t1
|
||||
or t1,t3,t1
|
||||
stq t1,0(a4)
|
||||
|
||||
bcopy_ov_nostart2:
|
||||
bic a2,7,t4
|
||||
and a2,7,a2
|
||||
beq t4,bcopy_ov_lp_end
|
||||
|
||||
bcopy_ov_lp:
|
||||
/* This could be more pipelined, but it doesn't seem worth it */
|
||||
ldq_u t0,-8(a3)
|
||||
subq a4,8,a4
|
||||
ldq_u t1,-1(a3)
|
||||
subq a3,8,a3
|
||||
extql t0,a3,t0
|
||||
extqh t1,a3,t1
|
||||
subq t4,8,t4
|
||||
or t0,t1,t0
|
||||
stq t0,0(a4)
|
||||
bne t4,bcopy_ov_lp
|
||||
|
||||
bcopy_ov_lp_end:
|
||||
beq a2,bcopy_done
|
||||
|
||||
ldq_u t0,0(a0)
|
||||
ldq_u t1,7(a0)
|
||||
ldq_u t2,0(a1)
|
||||
extql t0,a0,t0
|
||||
extqh t1,a0,t1
|
||||
or t0,t1,t0
|
||||
insql t0,a1,t0
|
||||
mskql t2,a1,t2
|
||||
or t2,t0,t2
|
||||
stq_u t2,0(a1)
|
||||
|
||||
bcopy_done:
|
||||
RET
|
||||
|
||||
bcopy_ov_short:
|
||||
ldq_u t2,0(a0)
|
||||
br zero,bcopy_da_finish
|
||||
|
||||
END(bcopy)
|
||||
|
||||
/*
|
||||
* kcopy(const void *src, void *dst, size_t len);
|
||||
*
|
||||
@ -1337,6 +1106,10 @@ NESTED(kcopy, 3, 32, ra, IM_RA|IM_S0|IM_S1, 0)
|
||||
stq ra, (32-8)(sp) /* save ra */
|
||||
stq s0, (32-16)(sp) /* save s0 */
|
||||
stq s1, (32-24)(sp) /* save s1 */
|
||||
/* Swap a0, a1, for call to memcpy(). */
|
||||
mov a1, v0
|
||||
mov a0, a1
|
||||
mov v0, a0
|
||||
/* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
|
||||
GET_CURPROC
|
||||
ldq s1, 0(v0) /* s1 = curproc */
|
||||
@ -1346,7 +1119,7 @@ NESTED(kcopy, 3, 32, ra, IM_RA|IM_S0|IM_S1, 0)
|
||||
ldq s0, U_PCB_ONFAULT(at_reg) /* save old handler. */
|
||||
stq v0, U_PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
CALL(bcopy) /* do the copy. */
|
||||
CALL(memcpy) /* do the copy. */
|
||||
.set noat
|
||||
ldq at_reg, P_ADDR(s1) /* restore the old handler. */
|
||||
stq s0, U_PCB_ONFAULT(at_reg)
|
||||
@ -1381,6 +1154,10 @@ NESTED(copyin, 3, 16, ra, IM_RA|IM_S0, 0)
|
||||
ldiq t0, VM_MAX_ADDRESS /* make sure that src addr */
|
||||
cmpult a0, t0, t1 /* is in user space. */
|
||||
beq t1, copyerr /* if it's not, error out. */
|
||||
/* Swap a0, a1, for call to memcpy(). */
|
||||
mov a1, v0
|
||||
mov a0, a1
|
||||
mov v0, a0
|
||||
/* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
|
||||
GET_CURPROC
|
||||
ldq s0, 0(v0) /* s0 = curproc */
|
||||
@ -1389,7 +1166,7 @@ NESTED(copyin, 3, 16, ra, IM_RA|IM_S0, 0)
|
||||
ldq at_reg, P_ADDR(s0)
|
||||
stq v0, U_PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
CALL(bcopy) /* do the copy. */
|
||||
CALL(memcpy) /* do the copy. */
|
||||
.set noat
|
||||
ldq at_reg, P_ADDR(s0) /* kill the fault handler. */
|
||||
stq zero, U_PCB_ONFAULT(at_reg)
|
||||
@ -1409,6 +1186,10 @@ NESTED(copyout, 3, 16, ra, IM_RA|IM_S0, 0)
|
||||
ldiq t0, VM_MAX_ADDRESS /* make sure that dest addr */
|
||||
cmpult a1, t0, t1 /* is in user space. */
|
||||
beq t1, copyerr /* if it's not, error out. */
|
||||
/* Swap a0, a1, for call to memcpy(). */
|
||||
mov a1, v0
|
||||
mov a0, a1
|
||||
mov v0, a0
|
||||
/* Note: GET_CURPROC clobbers v0, t0, t8...t11. */
|
||||
GET_CURPROC
|
||||
ldq s0, 0(v0) /* s0 = curproc */
|
||||
@ -1417,7 +1198,7 @@ NESTED(copyout, 3, 16, ra, IM_RA|IM_S0, 0)
|
||||
ldq at_reg, P_ADDR(s0)
|
||||
stq v0, U_PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
CALL(bcopy) /* do the copy. */
|
||||
CALL(memcpy) /* do the copy. */
|
||||
.set noat
|
||||
ldq at_reg, P_ADDR(s0) /* kill the fault handler. */
|
||||
stq zero, U_PCB_ONFAULT(at_reg)
|
||||
|
Loading…
x
Reference in New Issue
Block a user