Major overhaul. Rewritten most of this file to optimise copyin() and

copyout() for 32 bit aligned addresses. Also copyin() and copyout() now
share the same actual copying code.
Use the same copying code to implement kcopy().
This commit is contained in:
mark 1998-06-17 20:13:38 +00:00
parent 138ccaa418
commit 2aab040047
1 changed files with 70 additions and 93 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: bcopyinout.S,v 1.11 1998/06/02 19:14:44 mark Exp $ */
/* $NetBSD: bcopyinout.S,v 1.12 1998/06/17 20:13:38 mark Exp $ */
/*
* Copyright (c) 1995 Mark Brinicombe.
* Copyright (c) 1995-1998 Mark Brinicombe.
* Copyright (c) 1995 Brini.
* All rights reserved.
*
@ -17,54 +17,49 @@
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Brini.
* This product includes software developed by Mark Brinicombe.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* RiscBSD kernel project
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
*
* bcopyinout.S
*
* optimized and fault protected copyinout function
* optimized and fault protected byte copy functions
*
* Created : 16/05/95
*/
#include "opt_uvm.h"
#include "assym.h"
#include <machine/asm.h>
#include <sys/errno.h>
/*
* USE_BCOPY - Use bcopy() for the actual copy.
*
* USE WITH CAUTION. A number of contraints are imposed on the
* bcopy() function used due to the onfault handler used by
* copyin() / copyout() which means that on a fault execution
* will be passed directly to a copyin/copyout fault handler.
* These are
* The stack pointer must not be changed
* Only registers r0-r3 & r12 may be corrupted
*/
.text
.text
.align 0
Lcurpcb:
.word _curpcb
Lcurproc:
.word _curproc
Lvm_min_address:
.word VM_MIN_ADDRESS
Lvm_maxuser_address:
.word VM_MAXUSER_ADDRESS
Lvm_maxkern_address:
.word VM_MAXKERN_ADDRESS
#if defined(UVM)
ENTRY(kcopy)
b do_copyinout
#endif
/*
* r0 = user space address
@ -75,12 +70,7 @@ Lcurproc:
*/
ENTRY(copyin)
teq r2, #0x00000000
moveq r0, #0x000000000
moveq pc, lr
/* Validate addresses */
/* Validate user and kernel addresses */
ldr r3, Lvm_min_address
cmp r0, r3
bcc Lbadaddress
@ -93,34 +83,8 @@ ENTRY(copyin)
cmp r1, r3
bcs Lbadaddress
stmfd sp!, {r4}
ldr r4, Lcurpcb
ldr r4, [r4]
#ifdef DIAGNOSTIC
teq r4, #0x00000000
beq Lcopyinoutpcbfault
#endif /* DIAGNOSTIC */
add r3, pc, #Lcopyinoutfault - . - 8
str r3, [r4, #PCB_ONFAULT]
#ifdef USE_BCOPY
stmfd sp!, {lr}
bl _bcopy
ldmfd sp!, {lr}
#else /* USE_BCOPY */
Lcopyin_loop:
ldrb r3, [r0], #0x0001
strb r3, [r1], #0x0001
subs r2, r2, #0x00000001
bne Lcopyin_loop
#endif /* USE_BCOPY */
mov r0, #0x00000000
str r0, [r4, #PCB_ONFAULT]
ldmfd sp!, {r4}
mov pc, lr
/* Do the actual copy */
b do_copyinout
/*
* r0 = kernel space address
@ -131,12 +95,7 @@ Lcopyin_loop:
*/
ENTRY(copyout)
teq r2, #0x00000000
moveq r0, #0x000000000
moveq pc, lr
/* Validate addresses */
/* Validate user and kernel addresses */
ldr r3, Lvm_min_address
cmp r1, r3
bcc Lbadaddress
@ -149,6 +108,14 @@ ENTRY(copyout)
cmp r0, r3
bcs Lbadaddress
/* Do the actual copy */
do_copyinout:
/* Quick exit if legnth is zero */
teq r2, #0x00000000
moveq r0, #0x000000000
moveq pc, lr
stmfd sp!, {r4}
ldr r4, Lcurpcb
ldr r4, [r4]
@ -161,38 +128,50 @@ ENTRY(copyout)
add r3, pc, #Lcopyinoutfault - . - 8
str r3, [r4, #PCB_ONFAULT]
#ifdef USE_BCOPY
stmfd sp!, {lr}
bl _bcopy
ldmfd sp!, {lr}
#else /* USE_BCOPY */
Lcopyout_loop:
/*
* If less than 4 bytes or the source or destination address is
* not 32 bit aligned then copy it slowly, byte at a time.
* Otherwise copy it 32 bites at a time.
*/
sub r2, r2, #4
bmi Lslow_copyinout
tst r0, #3
tsteq r1, #3
bne Lslow_copyinout
Lcopyinout_loop:
ldr r3, [r0], #0x0004
str r3, [r1], #0x0004
subs r2, r2, #0x00000004
bpl Lcopyinout_loop
tst r2, #3
beq Lcopyinout_exit
Lslow_copyinout:
add r2, r2, #4
Lslow_copyinout_loop:
ldrb r3, [r0], #0x0001
strb r3, [r1], #0x0001
subs r2, r2, #0x00000001
bne Lcopyout_loop
#endif /* USE_BCOPY */
bne Lslow_copyinout_loop
Lcopyinout_exit:
mov r0, #0x00000000
str r0, [r4, #PCB_ONFAULT]
ldmfd sp!, {r4}
mov pc, lr
Lvm_min_address:
.word VM_MIN_ADDRESS
Lvm_maxuser_address:
.word VM_MAXUSER_ADDRESS
Lvm_maxkern_address:
.word VM_MAXKERN_ADDRESS
/* A fault occurred during the copy */
Lcopyinoutfault:
#ifdef USE_BCOPY
ldmfd sp!, {lr}
#endif /* USE_BCOPY */
mov r0, #0x00000000
str r0, [r4, #PCB_ONFAULT]
ldmfd sp!, {r4}
/* FALLTHROUGH */
/* Source or Destination address was bad so fail */
Lbadaddress:
mov r0, #EFAULT
mov pc, lr
@ -201,12 +180,10 @@ Lbadaddress:
Lcopyinoutpcbfault:
mov r2, r1
mov r1, r0
ldr r3, Lcurproc
ldr r3, [r3]
add r0, pc, #Lcopyinouttext - . - 8
b _panic
Lcopyinouttext:
.asciz "Yikes - No valid PCB during copyinout() addr1=%08x addr2=%08x curproc=%08x\n"
.asciz "No valid PCB during copyinout() addr1=%08x addr2=%08x\n"
.align 0
#endif /* DIAGNOSTIC */