[BACK]Return to copy.S CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / amd64 / amd64

Annotation of src/sys/arch/amd64/amd64/copy.S, Revision 1.7.2.1

1.7.2.1 ! mjf         1: /*     $NetBSD: copy.S,v 1.8 2007/11/12 18:42:00 ad Exp $      */
1.1       fvdl        2:
                      3: /*
                      4:  * Copyright (c) 2001 Wasabi Systems, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * Written by Frank van der Linden for Wasabi Systems, Inc.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed for the NetBSD Project by
                     20:  *      Wasabi Systems, Inc.
                     21:  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
                     22:  *    or promote products derived from this software without specific prior
                     23:  *    written permission.
                     24:  *
                     25:  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
                     26:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     27:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     28:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
                     29:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     30:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     31:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     32:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     33:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     34:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     35:  * POSSIBILITY OF SUCH DAMAGE.
                     36:  */
                     37:
                     38: #include "assym.h"
                     39:
                     40: #include <sys/errno.h>
                     41: #include <sys/syscall.h>
                     42:
                     43: #include <machine/asm.h>
1.7       yamt       44: #include <machine/frameasm.h>
1.1       fvdl       45:
1.5       yamt       46: #define GET_CURPCB(reg)        \
                     47:        movq    CPUVAR(CURLWP), reg; \
                     48:        movq    L_ADDR(reg), reg
                     49:
1.7       yamt       50: ENTRY(do_pmap_load)
                     51: #if 1
                     52:        pushq   %rbp
                     53:        movq    %rsp,%rbp
                     54: #endif
                     55:        pushq   %rdi
                     56:        pushq   %rsi
                     57:        pushq   %rdx
                     58:        pushq   %rcx
                     59:        call    _C_LABEL(pmap_load)
                     60:        popq    %rcx
                     61:        popq    %rdx
                     62:        popq    %rsi
                     63:        popq    %rdi
                     64: #if 1
                     65:        leaveq
                     66: #endif
                     67:        ret
                     68:
1.1       fvdl       69: /*
                     70:  * Copy routines from and to userland, plus a few more. See the
                     71:  * section 9 manpages for info. Some cases can be optimized more.
                     72:  *
                     73:  * I wonder if it's worthwhile to make these use SSE2 registers.
                     74:  */
                     75:
                     76: /*
                     77:  * XXXfvdl appears only to be used by pccons.
                     78:  *
1.4       christos   79:  * fillw(short pattern, void *addr, size_t len);
1.1       fvdl       80:  * Write len copies of pattern at addr.
                     81:  * appears to be used by pccons.
                     82:  */
                     83: ENTRY(fillw)
                     84:        movl    %edi,%eax
                     85:        movq    %rsi,%rdi
                     86:        movw    %ax,%cx
                     87:        rorl    $16,%eax
                     88:        movw    %cx,%ax
                     89:        movq    %rdx,%rcx
                     90:        shrq    %rcx
                     91:        rep
                     92:        stosl
                     93:        movq    %rdx,%rcx
                     94:        andq    $1,%rcx
                     95:        rep
                     96:        stosw
                     97:        ret
                     98:
                     99: ENTRY(kcopy)
1.5       yamt      100:        GET_CURPCB(%rax)
1.1       fvdl      101:        pushq   PCB_ONFAULT(%rax)
1.7       yamt      102:        leaq    _C_LABEL(kcopy_fault)(%rip),%r11
1.1       fvdl      103:        movq    %r11, PCB_ONFAULT(%rax)
                    104:
                    105:        xchgq   %rdi,%rsi
                    106:        movq    %rdx,%rcx
                    107:
                    108:        movq    %rdi,%rax
                    109:        subq    %rsi,%rax
                    110:        cmpq    %rcx,%rax               # overlapping?
                    111:        jb      1f
1.7.2.1 ! mjf       112:        # nope, copy forward
1.1       fvdl      113:        shrq    $3,%rcx                 # copy by 64-bit words
                    114:        rep
                    115:        movsq
                    116:
                    117:        movq    %rdx,%rcx
                    118:        andl    $7,%ecx                 # any bytes left?
                    119:        rep
                    120:        movsb
                    121:
1.5       yamt      122:        GET_CURPCB(%rdx)
1.1       fvdl      123:        popq    PCB_ONFAULT(%rdx)
                    124:        xorq    %rax,%rax
                    125:        ret
                    126:
                    127: 1:     addq    %rcx,%rdi               # copy backward
                    128:        addq    %rcx,%rsi
                    129:        std
                    130:        andq    $7,%rcx                 # any fractional bytes?
                    131:        decq    %rdi
                    132:        decq    %rsi
                    133:        rep
                    134:        movsb
                    135:        movq    %rdx,%rcx               # copy remainder by 64-bit words
                    136:        shrq    $3,%rcx
                    137:        subq    $7,%rsi
                    138:        subq    $7,%rdi
                    139:        rep
                    140:        movsq
                    141:        cld
                    142:
1.5       yamt      143:        GET_CURPCB(%rdx)
1.1       fvdl      144:        popq    PCB_ONFAULT(%rdx)
                    145:        xorq    %rax,%rax
                    146:        ret
                    147:
                    148: ENTRY(copyout)
1.7       yamt      149:        DO_DEFERRED_SWITCH
1.1       fvdl      150:        pushq   $0
                    151:
                    152:        xchgq   %rdi,%rsi
                    153:        movq    %rdx,%rax
                    154:
                    155:        movq    %rdi,%rdx
                    156:        addq    %rax,%rdx
                    157:        jc      _C_LABEL(copy_efault)
                    158:        movq    $VM_MAXUSER_ADDRESS,%r8
                    159:        cmpq    %r8,%rdx
                    160:        ja      _C_LABEL(copy_efault)
                    161:
1.5       yamt      162:        GET_CURPCB(%rdx)
1.1       fvdl      163:        leaq    _C_LABEL(copy_fault)(%rip),%r11
                    164:        movq    %r11,PCB_ONFAULT(%rdx)
                    165:
                    166:        movq    %rax,%rcx
                    167:        shrq    $3,%rcx
                    168:        rep
                    169:        movsq
                    170:        movb    %al,%cl
                    171:        andb    $7,%cl
                    172:        rep
                    173:        movsb
                    174:
                    175:        popq    PCB_ONFAULT(%rdx)
                    176:        xorl    %eax,%eax
                    177:        ret
                    178:
                    179: ENTRY(copyin)
1.7       yamt      180:        DO_DEFERRED_SWITCH
1.5       yamt      181:        GET_CURPCB(%rax)
1.1       fvdl      182:        pushq   $0
                    183:        leaq    _C_LABEL(copy_fault)(%rip),%r11
                    184:        movq    %r11,PCB_ONFAULT(%rax)
                    185:
                    186:        xchgq   %rdi,%rsi
                    187:        movq    %rdx,%rax
                    188:
                    189:        movq    %rsi,%rdx
                    190:        addq    %rax,%rdx
                    191:        jc      _C_LABEL(copy_efault)
                    192:        movq    $VM_MAXUSER_ADDRESS,%r8
                    193:        cmpq    %r8,%rdx
                    194:        ja      _C_LABEL(copy_efault)
                    195:
                    196: 3:     /* bcopy(%rsi, %rdi, %rax); */
                    197:        movq    %rax,%rcx
                    198:        shrq    $3,%rcx
                    199:        rep
                    200:        movsq
                    201:        movb    %al,%cl
                    202:        andb    $7,%cl
                    203:        rep
                    204:        movsb
                    205:
1.5       yamt      206:        GET_CURPCB(%rdx)
1.1       fvdl      207:        popq    PCB_ONFAULT(%rdx)
                    208:        xorl    %eax,%eax
                    209:        ret
                    210:
                    211: NENTRY(copy_efault)
                    212:        movq    $EFAULT,%rax
                    213:
1.7       yamt      214: /*
                    215:  * kcopy_fault is used by kcopy and copy_fault is used by copyin/out.
                    216:  *
                    217:  * they're distinguished for lazy pmap switching.  see trap().
                    218:  */
                    219:
                    220: NENTRY(kcopy_fault)
                    221:        GET_CURPCB(%rdx)
                    222:        popq    PCB_ONFAULT(%rdx)
                    223:        ret
                    224:
1.1       fvdl      225: NENTRY(copy_fault)
1.5       yamt      226:        GET_CURPCB(%rdx)
1.1       fvdl      227:        popq    PCB_ONFAULT(%rdx)
                    228:        ret
                    229:
                    230: ENTRY(copyoutstr)
1.7       yamt      231:        DO_DEFERRED_SWITCH
1.1       fvdl      232:        xchgq   %rdi,%rsi
                    233:        movq    %rdx,%r8
                    234:        movq    %rcx,%r9
                    235:
1.5       yamt      236: 5:     GET_CURPCB(%rax)
1.1       fvdl      237:        leaq    _C_LABEL(copystr_fault)(%rip),%r11
                    238:        movq    %r11,PCB_ONFAULT(%rax)
                    239:        /*
                    240:         * Get min(%rdx, VM_MAXUSER_ADDRESS-%rdi).
                    241:         */
                    242:        movq    $VM_MAXUSER_ADDRESS,%rax
                    243:        subq    %rdi,%rax
1.2       fvdl      244:        jc      _C_LABEL(copystr_efault)
1.1       fvdl      245:        cmpq    %rdx,%rax
                    246:        jae     1f
                    247:        movq    %rax,%rdx
                    248:        movq    %rax,%r8
                    249:
                    250: 1:     incq    %rdx
                    251:
                    252: 1:     decq    %rdx
                    253:        jz      2f
                    254:        lodsb
                    255:        stosb
                    256:        testb   %al,%al
                    257:        jnz     1b
                    258:
                    259:        /* Success -- 0 byte reached. */
                    260:        decq    %rdx
                    261:        xorq    %rax,%rax
                    262:        jmp     copystr_return
                    263:
                    264: 2:     /* rdx is zero -- return EFAULT or ENAMETOOLONG. */
                    265:        movq    $VM_MAXUSER_ADDRESS,%r11
                    266:        cmpq    %r11,%rdi
                    267:        jae     _C_LABEL(copystr_efault)
                    268:        movq    $ENAMETOOLONG,%rax
                    269:        jmp     copystr_return
                    270:
                    271: ENTRY(copyinstr)
1.7       yamt      272:        DO_DEFERRED_SWITCH
1.1       fvdl      273:        xchgq   %rdi,%rsi
                    274:        movq    %rdx,%r8
                    275:        movq    %rcx,%r9
                    276:
1.5       yamt      277:        GET_CURPCB(%rcx)
1.1       fvdl      278:        leaq    _C_LABEL(copystr_fault)(%rip),%r11
                    279:        movq    %r11,PCB_ONFAULT(%rcx)
                    280:
                    281:        /*
                    282:         * Get min(%rdx, VM_MAXUSER_ADDRESS-%rsi).
                    283:         */
                    284:        movq    $VM_MAXUSER_ADDRESS,%rax
                    285:        subq    %rsi,%rax
1.2       fvdl      286:        jc      _C_LABEL(copystr_efault)
1.1       fvdl      287:        cmpq    %rdx,%rax
                    288:        jae     1f
                    289:        movq    %rax,%rdx
                    290:        movq    %rax,%r8
                    291:
                    292: 1:     incq    %rdx
                    293:
                    294: 1:     decq    %rdx
                    295:        jz      2f
                    296:        lodsb
                    297:        stosb
                    298:        testb   %al,%al
                    299:        jnz     1b
                    300:
                    301:        /* Success -- 0 byte reached. */
                    302:        decq    %rdx
                    303:        xorq    %rax,%rax
                    304:        jmp     copystr_return
                    305:
                    306: 2:     /* edx is zero -- return EFAULT or ENAMETOOLONG. */
                    307:        movq    $VM_MAXUSER_ADDRESS,%r11
                    308:        cmpq    %r11,%rsi
                    309:        jae     _C_LABEL(copystr_efault)
                    310:        movq    $ENAMETOOLONG,%rax
                    311:        jmp     copystr_return
                    312:
                    313: ENTRY(copystr_efault)
                    314:        movl    $EFAULT,%eax
                    315:
                    316: ENTRY(copystr_fault)
                    317: copystr_return:
                    318:        /* Set *lencopied and return %eax. */
1.5       yamt      319:        GET_CURPCB(%rcx)
1.1       fvdl      320:        movq    $0,PCB_ONFAULT(%rcx)
                    321:        testq   %r9,%r9
                    322:        jz      8f
                    323:        subq    %rdx,%r8
                    324:        movq    %r8,(%r9)
                    325:
                    326: 8:     ret
                    327:
                    328: ENTRY(copystr)
                    329:        xchgq   %rdi,%rsi
                    330:        movq    %rdx,%r8
                    331:
                    332:        incq    %rdx
                    333:
                    334: 1:     decq    %rdx
                    335:        jz      4f
                    336:        lodsb
                    337:        stosb
                    338:        testb   %al,%al
                    339:        jnz     1b
                    340:
                    341:        /* Success -- 0 byte reached. */
                    342:        decq    %rdx
                    343:        xorl    %eax,%eax
                    344:        jmp     6f
                    345:
                    346: 4:     /* edx is zero -- return ENAMETOOLONG. */
                    347:        movl    $ENAMETOOLONG,%eax
                    348:
                    349: 6:     /* Set *lencopied and return %eax. */
                    350:        testq   %rcx,%rcx
                    351:        jz      7f
                    352:        subq    %rdx,%r8
                    353:        movq    %r8,(%rcx)
                    354:
                    355: 7:     ret
                    356:
                    357: ENTRY(fuword)
1.7       yamt      358:        DO_DEFERRED_SWITCH
1.1       fvdl      359:        movq    $VM_MAXUSER_ADDRESS-4,%r11
                    360:        cmpq    %r11,%rdi
                    361:        ja      _C_LABEL(fusuaddrfault)
1.5       yamt      362:        GET_CURPCB(%rcx)
1.1       fvdl      363:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    364:        movq    %r11,PCB_ONFAULT(%rcx)
                    365:        movl    (%rdi),%eax
                    366:        movq    $0,PCB_ONFAULT(%rcx)
                    367:        ret
                    368:
                    369: ENTRY(fusword)
1.7       yamt      370:        DO_DEFERRED_SWITCH
1.1       fvdl      371:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    372:        cmpq    %r11,%rdi
                    373:        ja      _C_LABEL(fusuaddrfault)
1.5       yamt      374:        GET_CURPCB(%rcx)
1.1       fvdl      375:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    376:        movq    %r11,PCB_ONFAULT(%rcx)
                    377:        movzwl  (%rdi),%eax
                    378:        movq    $0,PCB_ONFAULT(%rcx)
                    379:        ret
                    380:
                    381: ENTRY(fuswintr)
1.7       yamt      382:        cmpq    $TLBSTATE_VALID, CPUVAR(TLBSTATE)
                    383:        jnz     _C_LABEL(fusuaddrfault)
1.1       fvdl      384:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    385:        cmpq    %r11,%rdi
                    386:        ja      _C_LABEL(fusuaddrfault)
1.5       yamt      387:        GET_CURPCB(%rcx)
1.1       fvdl      388:        leaq    _C_LABEL(fusuintrfailure)(%rip),%r11
                    389:        movq    %r11,PCB_ONFAULT(%rcx)
                    390:        movzwl  (%rdi),%eax
                    391:        movq    $0,PCB_ONFAULT(%rcx)
                    392:        ret
                    393:
                    394: ENTRY(fubyte)
1.7       yamt      395:        DO_DEFERRED_SWITCH
1.1       fvdl      396:        movq    $VM_MAXUSER_ADDRESS-1,%r11
                    397:        cmpq    %r11,%rdi
                    398:        ja      _C_LABEL(fusuaddrfault)
1.5       yamt      399:        GET_CURPCB(%rcx)
1.1       fvdl      400:        leaq    _C_LABEL(fusuintrfailure)(%rip),%r11
                    401:        movq    %r11,PCB_ONFAULT(%rcx)
                    402:        movzbl  (%rdi),%eax
                    403:        movq    $0,PCB_ONFAULT(%rcx)
                    404:        ret
                    405:
                    406: /*
                    407:  * These are the same, but must reside at different addresses,
                    408:  * because trap.c checks for them.
                    409:  */
                    410: ENTRY(fusuintrfailure)
                    411:        movq    $0,PCB_ONFAULT(%rcx)
                    412:        movl    $-1,%eax
                    413:        ret
                    414:
                    415: ENTRY(fusufailure)
                    416:        movq    $0,PCB_ONFAULT(%rcx)
                    417:        movl    $-1,%eax
                    418:        ret
                    419:
                    420: ENTRY(fusuaddrfault)
                    421:        movl    $-1,%eax
                    422:        ret
                    423:
                    424: ENTRY(suword)
1.7       yamt      425:        DO_DEFERRED_SWITCH
1.1       fvdl      426:        movq    $VM_MAXUSER_ADDRESS-4,%r11
                    427:        cmpq    %r11,%rdi
                    428:        ja      _C_LABEL(fusuaddrfault)
                    429:
1.5       yamt      430:        GET_CURPCB(%rcx)
1.1       fvdl      431:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    432:        movq    %r11,PCB_ONFAULT(%rcx)
                    433:
                    434:        movq    %rsi,(%rdi)
                    435:        xorq    %rax,%rax
                    436:        movq    %rax,PCB_ONFAULT(%rcx)
                    437:        ret
                    438:
                    439: ENTRY(susword)
1.7       yamt      440:        DO_DEFERRED_SWITCH
1.1       fvdl      441:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    442:        cmpq    %r11,%rdi
                    443:        ja      _C_LABEL(fusuaddrfault)
                    444:
1.5       yamt      445:        GET_CURPCB(%rcx)
1.1       fvdl      446:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    447:        movq    %r11,PCB_ONFAULT(%rcx)
                    448:
                    449:        movw    %si,(%rdi)
                    450:        xorq    %rax,%rax
                    451:        movq    %rax,PCB_ONFAULT(%rcx)
                    452:        ret
                    453:
                    454: ENTRY(suswintr)
1.7       yamt      455:        cmpq    $TLBSTATE_VALID, CPUVAR(TLBSTATE)
                    456:        jnz     _C_LABEL(fusuaddrfault)
1.1       fvdl      457:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    458:        cmpq    %r11,%rdi
                    459:        ja      _C_LABEL(fusuaddrfault)
1.5       yamt      460:        GET_CURPCB(%rcx)
1.1       fvdl      461:        leaq    _C_LABEL(fusuintrfailure)(%rip),%r11
                    462:        movq    %r11,PCB_ONFAULT(%rcx)
                    463:
                    464:        movw    %si,(%rdi)
                    465:        xorq    %rax,%rax
                    466:        movq    %rax,PCB_ONFAULT(%rcx)
                    467:        ret
                    468:
                    469: ENTRY(subyte)
1.7       yamt      470:        DO_DEFERRED_SWITCH
1.1       fvdl      471:        movq    $VM_MAXUSER_ADDRESS-1,%r11
                    472:        cmpq    %r11,%rdi
                    473:        ja      _C_LABEL(fusuaddrfault)
                    474:
1.5       yamt      475:        GET_CURPCB(%rcx)
1.1       fvdl      476:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    477:        movq    %r11,PCB_ONFAULT(%rcx)
                    478:
                    479:        movb    %sil,(%rdi)
                    480:        xorq    %rax,%rax
                    481:        movq    %rax,PCB_ONFAULT(%rcx)
                    482:        ret

CVSweb <webmaster@jp.NetBSD.org>