[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.4.10.1

1.4.10.1! matt        1: /*     $NetBSD: copy.S,v 1.5 2007/05/17 14:51:13 yamt 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/param.h>
                     44: #include <machine/asm.h>
                     45:
1.4.10.1! matt       46: #define GET_CURPCB(reg)        \
        !            47:        movq    CPUVAR(CURLWP), reg; \
        !            48:        movq    L_ADDR(reg), reg
        !            49:
1.1       fvdl       50: /*
                     51:  * Copy routines from and to userland, plus a few more. See the
                     52:  * section 9 manpages for info. Some cases can be optimized more.
                     53:  *
                     54:  * I wonder if it's worthwhile to make these use SSE2 registers.
                     55:  */
                     56:
                     57: /*
                     58:  * XXXfvdl appears only to be used by pccons.
                     59:  *
1.4       christos   60:  * fillw(short pattern, void *addr, size_t len);
1.1       fvdl       61:  * Write len copies of pattern at addr.
                     62:  * appears to be used by pccons.
                     63:  */
                     64: ENTRY(fillw)
                     65:        movl    %edi,%eax
                     66:        movq    %rsi,%rdi
                     67:        movw    %ax,%cx
                     68:        rorl    $16,%eax
                     69:        movw    %cx,%ax
                     70:        cld
                     71:        movq    %rdx,%rcx
                     72:        shrq    %rcx
                     73:        rep
                     74:        stosl
                     75:        movq    %rdx,%rcx
                     76:        andq    $1,%rcx
                     77:        rep
                     78:        stosw
                     79:        ret
                     80:
                     81: ENTRY(kcopy)
1.4.10.1! matt       82:        GET_CURPCB(%rax)
1.1       fvdl       83:        pushq   PCB_ONFAULT(%rax)
                     84:        leaq    _C_LABEL(copy_fault)(%rip),%r11
                     85:        movq    %r11, PCB_ONFAULT(%rax)
                     86:
                     87:        xchgq   %rdi,%rsi
                     88:        movq    %rdx,%rcx
                     89:
                     90:        movq    %rdi,%rax
                     91:        subq    %rsi,%rax
                     92:        cmpq    %rcx,%rax               # overlapping?
                     93:        jb      1f
                     94:        cld                             # nope, copy forward
                     95:        shrq    $3,%rcx                 # copy by 64-bit words
                     96:        rep
                     97:        movsq
                     98:
                     99:        movq    %rdx,%rcx
                    100:        andl    $7,%ecx                 # any bytes left?
                    101:        rep
                    102:        movsb
                    103:
1.4.10.1! matt      104:        GET_CURPCB(%rdx)
1.1       fvdl      105:        popq    PCB_ONFAULT(%rdx)
                    106:        xorq    %rax,%rax
                    107:        ret
                    108:
                    109: 1:     addq    %rcx,%rdi               # copy backward
                    110:        addq    %rcx,%rsi
                    111:        std
                    112:        andq    $7,%rcx                 # any fractional bytes?
                    113:        decq    %rdi
                    114:        decq    %rsi
                    115:        rep
                    116:        movsb
                    117:        movq    %rdx,%rcx               # copy remainder by 64-bit words
                    118:        shrq    $3,%rcx
                    119:        subq    $7,%rsi
                    120:        subq    $7,%rdi
                    121:        rep
                    122:        movsq
                    123:        cld
                    124:
1.4.10.1! matt      125:        GET_CURPCB(%rdx)
1.1       fvdl      126:        popq    PCB_ONFAULT(%rdx)
                    127:        xorq    %rax,%rax
                    128:        ret
                    129:
                    130: ENTRY(copyout)
                    131:        pushq   $0
                    132:
                    133:        xchgq   %rdi,%rsi
                    134:        movq    %rdx,%rax
                    135:
                    136:        movq    %rdi,%rdx
                    137:        addq    %rax,%rdx
                    138:        jc      _C_LABEL(copy_efault)
                    139:        movq    $VM_MAXUSER_ADDRESS,%r8
                    140:        cmpq    %r8,%rdx
                    141:        ja      _C_LABEL(copy_efault)
                    142:
1.4.10.1! matt      143:        GET_CURPCB(%rdx)
1.1       fvdl      144:        leaq    _C_LABEL(copy_fault)(%rip),%r11
                    145:        movq    %r11,PCB_ONFAULT(%rdx)
                    146:
                    147:        cld
                    148:        movq    %rax,%rcx
                    149:        shrq    $3,%rcx
                    150:        rep
                    151:        movsq
                    152:        movb    %al,%cl
                    153:        andb    $7,%cl
                    154:        rep
                    155:        movsb
                    156:
                    157:        popq    PCB_ONFAULT(%rdx)
                    158:        xorl    %eax,%eax
                    159:        ret
                    160:
                    161: ENTRY(copyin)
1.4.10.1! matt      162:        GET_CURPCB(%rax)
1.1       fvdl      163:        pushq   $0
                    164:        leaq    _C_LABEL(copy_fault)(%rip),%r11
                    165:        movq    %r11,PCB_ONFAULT(%rax)
                    166:
                    167:        xchgq   %rdi,%rsi
                    168:        movq    %rdx,%rax
                    169:
                    170:        movq    %rsi,%rdx
                    171:        addq    %rax,%rdx
                    172:        jc      _C_LABEL(copy_efault)
                    173:        movq    $VM_MAXUSER_ADDRESS,%r8
                    174:        cmpq    %r8,%rdx
                    175:        ja      _C_LABEL(copy_efault)
                    176:
                    177: 3:     /* bcopy(%rsi, %rdi, %rax); */
                    178:        cld
                    179:        movq    %rax,%rcx
                    180:        shrq    $3,%rcx
                    181:        rep
                    182:        movsq
                    183:        movb    %al,%cl
                    184:        andb    $7,%cl
                    185:        rep
                    186:        movsb
                    187:
1.4.10.1! matt      188:        GET_CURPCB(%rdx)
1.1       fvdl      189:        popq    PCB_ONFAULT(%rdx)
                    190:        xorl    %eax,%eax
                    191:        ret
                    192:
                    193: NENTRY(copy_efault)
                    194:        movq    $EFAULT,%rax
                    195:
                    196: NENTRY(copy_fault)
1.4.10.1! matt      197:        GET_CURPCB(%rdx)
1.1       fvdl      198:        popq    PCB_ONFAULT(%rdx)
                    199:        ret
                    200:
                    201: ENTRY(copyoutstr)
                    202:        xchgq   %rdi,%rsi
                    203:        movq    %rdx,%r8
                    204:        movq    %rcx,%r9
                    205:
1.4.10.1! matt      206: 5:     GET_CURPCB(%rax)
1.1       fvdl      207:        leaq    _C_LABEL(copystr_fault)(%rip),%r11
                    208:        movq    %r11,PCB_ONFAULT(%rax)
                    209:        /*
                    210:         * Get min(%rdx, VM_MAXUSER_ADDRESS-%rdi).
                    211:         */
                    212:        movq    $VM_MAXUSER_ADDRESS,%rax
                    213:        subq    %rdi,%rax
1.2       fvdl      214:        jc      _C_LABEL(copystr_efault)
1.1       fvdl      215:        cmpq    %rdx,%rax
                    216:        jae     1f
                    217:        movq    %rax,%rdx
                    218:        movq    %rax,%r8
                    219:
                    220: 1:     incq    %rdx
                    221:        cld
                    222:
                    223: 1:     decq    %rdx
                    224:        jz      2f
                    225:        lodsb
                    226:        stosb
                    227:        testb   %al,%al
                    228:        jnz     1b
                    229:
                    230:        /* Success -- 0 byte reached. */
                    231:        decq    %rdx
                    232:        xorq    %rax,%rax
                    233:        jmp     copystr_return
                    234:
                    235: 2:     /* rdx is zero -- return EFAULT or ENAMETOOLONG. */
                    236:        movq    $VM_MAXUSER_ADDRESS,%r11
                    237:        cmpq    %r11,%rdi
                    238:        jae     _C_LABEL(copystr_efault)
                    239:        movq    $ENAMETOOLONG,%rax
                    240:        jmp     copystr_return
                    241:
                    242: ENTRY(copyinstr)
                    243:        xchgq   %rdi,%rsi
                    244:        movq    %rdx,%r8
                    245:        movq    %rcx,%r9
                    246:
1.4.10.1! matt      247:        GET_CURPCB(%rcx)
1.1       fvdl      248:        leaq    _C_LABEL(copystr_fault)(%rip),%r11
                    249:        movq    %r11,PCB_ONFAULT(%rcx)
                    250:
                    251:        /*
                    252:         * Get min(%rdx, VM_MAXUSER_ADDRESS-%rsi).
                    253:         */
                    254:        movq    $VM_MAXUSER_ADDRESS,%rax
                    255:        subq    %rsi,%rax
1.2       fvdl      256:        jc      _C_LABEL(copystr_efault)
1.1       fvdl      257:        cmpq    %rdx,%rax
                    258:        jae     1f
                    259:        movq    %rax,%rdx
                    260:        movq    %rax,%r8
                    261:
                    262: 1:     incq    %rdx
                    263:        cld
                    264:
                    265: 1:     decq    %rdx
                    266:        jz      2f
                    267:        lodsb
                    268:        stosb
                    269:        testb   %al,%al
                    270:        jnz     1b
                    271:
                    272:        /* Success -- 0 byte reached. */
                    273:        decq    %rdx
                    274:        xorq    %rax,%rax
                    275:        jmp     copystr_return
                    276:
                    277: 2:     /* edx is zero -- return EFAULT or ENAMETOOLONG. */
                    278:        movq    $VM_MAXUSER_ADDRESS,%r11
                    279:        cmpq    %r11,%rsi
                    280:        jae     _C_LABEL(copystr_efault)
                    281:        movq    $ENAMETOOLONG,%rax
                    282:        jmp     copystr_return
                    283:
                    284: ENTRY(copystr_efault)
                    285:        movl    $EFAULT,%eax
                    286:
                    287: ENTRY(copystr_fault)
                    288: copystr_return:
                    289:        /* Set *lencopied and return %eax. */
1.4.10.1! matt      290:        GET_CURPCB(%rcx)
1.1       fvdl      291:        movq    $0,PCB_ONFAULT(%rcx)
                    292:        testq   %r9,%r9
                    293:        jz      8f
                    294:        subq    %rdx,%r8
                    295:        movq    %r8,(%r9)
                    296:
                    297: 8:     ret
                    298:
                    299: ENTRY(copystr)
                    300:        xchgq   %rdi,%rsi
                    301:        movq    %rdx,%r8
                    302:
                    303:        incq    %rdx
                    304:        cld
                    305:
                    306: 1:     decq    %rdx
                    307:        jz      4f
                    308:        lodsb
                    309:        stosb
                    310:        testb   %al,%al
                    311:        jnz     1b
                    312:
                    313:        /* Success -- 0 byte reached. */
                    314:        decq    %rdx
                    315:        xorl    %eax,%eax
                    316:        jmp     6f
                    317:
                    318: 4:     /* edx is zero -- return ENAMETOOLONG. */
                    319:        movl    $ENAMETOOLONG,%eax
                    320:
                    321: 6:     /* Set *lencopied and return %eax. */
                    322:        testq   %rcx,%rcx
                    323:        jz      7f
                    324:        subq    %rdx,%r8
                    325:        movq    %r8,(%rcx)
                    326:
                    327: 7:     ret
                    328:
                    329: ENTRY(fuword)
                    330:        movq    $VM_MAXUSER_ADDRESS-4,%r11
                    331:        cmpq    %r11,%rdi
                    332:        ja      _C_LABEL(fusuaddrfault)
1.4.10.1! matt      333:        GET_CURPCB(%rcx)
1.1       fvdl      334:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    335:        movq    %r11,PCB_ONFAULT(%rcx)
                    336:        movl    (%rdi),%eax
                    337:        movq    $0,PCB_ONFAULT(%rcx)
                    338:        ret
                    339:
                    340: ENTRY(fusword)
                    341:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    342:        cmpq    %r11,%rdi
                    343:        ja      _C_LABEL(fusuaddrfault)
1.4.10.1! matt      344:        GET_CURPCB(%rcx)
1.1       fvdl      345:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    346:        movq    %r11,PCB_ONFAULT(%rcx)
                    347:        movzwl  (%rdi),%eax
                    348:        movq    $0,PCB_ONFAULT(%rcx)
                    349:        ret
                    350:
                    351: ENTRY(fuswintr)
                    352:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    353:        cmpq    %r11,%rdi
                    354:        ja      _C_LABEL(fusuaddrfault)
1.4.10.1! matt      355:        GET_CURPCB(%rcx)
1.1       fvdl      356:        leaq    _C_LABEL(fusuintrfailure)(%rip),%r11
                    357:        movq    %r11,PCB_ONFAULT(%rcx)
                    358:        movzwl  (%rdi),%eax
                    359:        movq    $0,PCB_ONFAULT(%rcx)
                    360:        ret
                    361:
                    362: ENTRY(fubyte)
                    363:        movq    $VM_MAXUSER_ADDRESS-1,%r11
                    364:        cmpq    %r11,%rdi
                    365:        ja      _C_LABEL(fusuaddrfault)
1.4.10.1! matt      366:        GET_CURPCB(%rcx)
1.1       fvdl      367:        leaq    _C_LABEL(fusuintrfailure)(%rip),%r11
                    368:        movq    %r11,PCB_ONFAULT(%rcx)
                    369:        movzbl  (%rdi),%eax
                    370:        movq    $0,PCB_ONFAULT(%rcx)
                    371:        ret
                    372:
                    373: /*
                    374:  * These are the same, but must reside at different addresses,
                    375:  * because trap.c checks for them.
                    376:  */
                    377: ENTRY(fusuintrfailure)
                    378:        movq    $0,PCB_ONFAULT(%rcx)
                    379:        movl    $-1,%eax
                    380:        ret
                    381:
                    382: ENTRY(fusufailure)
                    383:        movq    $0,PCB_ONFAULT(%rcx)
                    384:        movl    $-1,%eax
                    385:        ret
                    386:
                    387: ENTRY(fusuaddrfault)
                    388:        movl    $-1,%eax
                    389:        ret
                    390:
                    391: ENTRY(suword)
                    392:        movq    $VM_MAXUSER_ADDRESS-4,%r11
                    393:        cmpq    %r11,%rdi
                    394:        ja      _C_LABEL(fusuaddrfault)
                    395:
1.4.10.1! matt      396:        GET_CURPCB(%rcx)
1.1       fvdl      397:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    398:        movq    %r11,PCB_ONFAULT(%rcx)
                    399:
                    400:        movq    %rsi,(%rdi)
                    401:        xorq    %rax,%rax
                    402:        movq    %rax,PCB_ONFAULT(%rcx)
                    403:        ret
                    404:
                    405: ENTRY(susword)
                    406:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    407:        cmpq    %r11,%rdi
                    408:        ja      _C_LABEL(fusuaddrfault)
                    409:
1.4.10.1! matt      410:        GET_CURPCB(%rcx)
1.1       fvdl      411:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    412:        movq    %r11,PCB_ONFAULT(%rcx)
                    413:
                    414:        movw    %si,(%rdi)
                    415:        xorq    %rax,%rax
                    416:        movq    %rax,PCB_ONFAULT(%rcx)
                    417:        ret
                    418:
                    419: ENTRY(suswintr)
                    420:        movq    $VM_MAXUSER_ADDRESS-2,%r11
                    421:        cmpq    %r11,%rdi
                    422:        ja      _C_LABEL(fusuaddrfault)
1.4.10.1! matt      423:        GET_CURPCB(%rcx)
1.1       fvdl      424:        leaq    _C_LABEL(fusuintrfailure)(%rip),%r11
                    425:        movq    %r11,PCB_ONFAULT(%rcx)
                    426:
                    427:        movw    %si,(%rdi)
                    428:        xorq    %rax,%rax
                    429:        movq    %rax,PCB_ONFAULT(%rcx)
                    430:        ret
                    431:
                    432: ENTRY(subyte)
                    433:        movq    $VM_MAXUSER_ADDRESS-1,%r11
                    434:        cmpq    %r11,%rdi
                    435:        ja      _C_LABEL(fusuaddrfault)
                    436:
1.4.10.1! matt      437:        GET_CURPCB(%rcx)
1.1       fvdl      438:        leaq    _C_LABEL(fusufailure)(%rip),%r11
                    439:        movq    %r11,PCB_ONFAULT(%rcx)
                    440:
                    441:        movb    %sil,(%rdi)
                    442:        xorq    %rax,%rax
                    443:        movq    %rax,PCB_ONFAULT(%rcx)
                    444:        ret

CVSweb <webmaster@jp.NetBSD.org>