The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/i386/i386/support.s

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1993 The Regents of the University of California.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 4. Neither the name of the University nor the names of its contributors
   14  *    may be used to endorse or promote products derived from this software
   15  *    without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * $FreeBSD: stable/9/sys/i386/i386/support.s 271072 2014-09-04 00:43:27Z pfg $
   30  */
   31 
   32 #include "opt_npx.h"
   33 
   34 #include <machine/asmacros.h>
   35 #include <machine/cputypes.h>
   36 #include <machine/intr_machdep.h>
   37 #include <machine/pmap.h>
   38 #include <machine/specialreg.h>
   39 
   40 #include "assym.s"
   41 
   42 #define IDXSHIFT        10
   43 
   44         .text
   45 
   46 /*
   47  * bcopy family
   48  * void bzero(void *buf, u_int len)
   49  */
   50 ENTRY(bzero)
   51         pushl   %edi
   52         movl    8(%esp),%edi
   53         movl    12(%esp),%ecx
   54         xorl    %eax,%eax
   55         shrl    $2,%ecx
   56         cld
   57         rep
   58         stosl
   59         movl    12(%esp),%ecx
   60         andl    $3,%ecx
   61         rep
   62         stosb
   63         popl    %edi
   64         ret
   65 END(bzero)
   66 
   67 ENTRY(sse2_pagezero)
   68         pushl   %ebx
   69         movl    8(%esp),%ecx
   70         movl    %ecx,%eax
   71         addl    $4096,%eax
   72         xor     %ebx,%ebx
   73 1:
   74         movnti  %ebx,(%ecx)
   75         addl    $4,%ecx
   76         cmpl    %ecx,%eax
   77         jne     1b
   78         sfence
   79         popl    %ebx
   80         ret
   81 END(sse2_pagezero)
   82 
   83 ENTRY(i686_pagezero)
   84         pushl   %edi
   85         pushl   %ebx
   86 
   87         movl    12(%esp),%edi
   88         movl    $1024,%ecx
   89         cld
   90 
   91         ALIGN_TEXT
   92 1:
   93         xorl    %eax,%eax
   94         repe
   95         scasl
   96         jnz     2f
   97 
   98         popl    %ebx
   99         popl    %edi
  100         ret
  101 
  102         ALIGN_TEXT
  103 
  104 2:
  105         incl    %ecx
  106         subl    $4,%edi
  107 
  108         movl    %ecx,%edx
  109         cmpl    $16,%ecx
  110 
  111         jge     3f
  112 
  113         movl    %edi,%ebx
  114         andl    $0x3f,%ebx
  115         shrl    %ebx
  116         shrl    %ebx
  117         movl    $16,%ecx
  118         subl    %ebx,%ecx
  119 
  120 3:
  121         subl    %ecx,%edx
  122         rep
  123         stosl
  124 
  125         movl    %edx,%ecx
  126         testl   %edx,%edx
  127         jnz     1b
  128 
  129         popl    %ebx
  130         popl    %edi
  131         ret
  132 END(i686_pagezero)
  133 
  134 /* fillw(pat, base, cnt) */
  135 ENTRY(fillw)
  136         pushl   %edi
  137         movl    8(%esp),%eax
  138         movl    12(%esp),%edi
  139         movl    16(%esp),%ecx
  140         cld
  141         rep
  142         stosw
  143         popl    %edi
  144         ret
  145 END(fillw)
  146 
  147 ENTRY(bcopyb)
  148         pushl   %esi
  149         pushl   %edi
  150         movl    12(%esp),%esi
  151         movl    16(%esp),%edi
  152         movl    20(%esp),%ecx
  153         movl    %edi,%eax
  154         subl    %esi,%eax
  155         cmpl    %ecx,%eax                       /* overlapping && src < dst? */
  156         jb      1f
  157         cld                                     /* nope, copy forwards */
  158         rep
  159         movsb
  160         popl    %edi
  161         popl    %esi
  162         ret
  163 
  164         ALIGN_TEXT
  165 1:
  166         addl    %ecx,%edi                       /* copy backwards. */
  167         addl    %ecx,%esi
  168         decl    %edi
  169         decl    %esi
  170         std
  171         rep
  172         movsb
  173         popl    %edi
  174         popl    %esi
  175         cld
  176         ret
  177 END(bcopyb)
  178 
  179 /*
  180  * bcopy(src, dst, cnt)
  181  *  ws@tools.de     (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
  182  */
  183 ENTRY(bcopy)
  184         pushl   %ebp
  185         movl    %esp,%ebp
  186         pushl   %esi
  187         pushl   %edi
  188         movl    8(%ebp),%esi
  189         movl    12(%ebp),%edi
  190         movl    16(%ebp),%ecx
  191 
  192         movl    %edi,%eax
  193         subl    %esi,%eax
  194         cmpl    %ecx,%eax                       /* overlapping && src < dst? */
  195         jb      1f
  196 
  197         shrl    $2,%ecx                         /* copy by 32-bit words */
  198         cld                                     /* nope, copy forwards */
  199         rep
  200         movsl
  201         movl    16(%ebp),%ecx
  202         andl    $3,%ecx                         /* any bytes left? */
  203         rep
  204         movsb
  205         popl    %edi
  206         popl    %esi
  207         popl    %ebp
  208         ret
  209 
  210         ALIGN_TEXT
  211 1:
  212         addl    %ecx,%edi                       /* copy backwards */
  213         addl    %ecx,%esi
  214         decl    %edi
  215         decl    %esi
  216         andl    $3,%ecx                         /* any fractional bytes? */
  217         std
  218         rep
  219         movsb
  220         movl    16(%ebp),%ecx                   /* copy remainder by 32-bit words */
  221         shrl    $2,%ecx
  222         subl    $3,%esi
  223         subl    $3,%edi
  224         rep
  225         movsl
  226         popl    %edi
  227         popl    %esi
  228         cld
  229         popl    %ebp
  230         ret
  231 END(bcopy)
  232 
  233 /*
  234  * Note: memcpy does not support overlapping copies
  235  */
  236 ENTRY(memcpy)
  237         pushl   %edi
  238         pushl   %esi
  239         movl    12(%esp),%edi
  240         movl    16(%esp),%esi
  241         movl    20(%esp),%ecx
  242         movl    %edi,%eax
  243         shrl    $2,%ecx                         /* copy by 32-bit words */
  244         cld                                     /* nope, copy forwards */
  245         rep
  246         movsl
  247         movl    20(%esp),%ecx
  248         andl    $3,%ecx                         /* any bytes left? */
  249         rep
  250         movsb
  251         popl    %esi
  252         popl    %edi
  253         ret
  254 END(memcpy)
  255 
  256 /*****************************************************************************/
  257 /* copyout and fubyte family                                                 */
  258 /*****************************************************************************/
  259 /*
  260  * Access user memory from inside the kernel. These routines and possibly
  261  * the math- and DOS emulators should be the only places that do this.
  262  *
  263  * We have to access the memory with user's permissions, so use a segment
  264  * selector with RPL 3. For writes to user space we have to additionally
  265  * check the PTE for write permission, because the 386 does not check
  266  * write permissions when we are executing with EPL 0. The 486 does check
  267  * this if the WP bit is set in CR0, so we can use a simpler version here.
  268  *
  269  * These routines set curpcb->pcb_onfault for the time they execute. When a
  270  * protection violation occurs inside the functions, the trap handler
  271  * returns to *curpcb->pcb_onfault instead of the function.
  272  */
  273 
  274 /*
  275  * copyout(from_kernel, to_user, len)  - MP SAFE
  276  */
  277 ENTRY(copyout)
  278         movl    PCPU(CURPCB),%eax
  279         movl    $copyout_fault,PCB_ONFAULT(%eax)
  280         pushl   %esi
  281         pushl   %edi
  282         pushl   %ebx
  283         movl    16(%esp),%esi
  284         movl    20(%esp),%edi
  285         movl    24(%esp),%ebx
  286         testl   %ebx,%ebx                       /* anything to do? */
  287         jz      done_copyout
  288 
  289         /*
  290          * Check explicitly for non-user addresses.  If 486 write protection
  291          * is being used, this check is essential because we are in kernel
  292          * mode so the h/w does not provide any protection against writing
  293          * kernel addresses.
  294          */
  295 
  296         /*
  297          * First, prevent address wrapping.
  298          */
  299         movl    %edi,%eax
  300         addl    %ebx,%eax
  301         jc      copyout_fault
  302 /*
  303  * XXX STOP USING VM_MAXUSER_ADDRESS.
  304  * It is an end address, not a max, so every time it is used correctly it
  305  * looks like there is an off by one error, and of course it caused an off
  306  * by one error in several places.
  307  */
  308         cmpl    $VM_MAXUSER_ADDRESS,%eax
  309         ja      copyout_fault
  310 
  311         /* bcopy(%esi, %edi, %ebx) */
  312         movl    %ebx,%ecx
  313 
  314         shrl    $2,%ecx
  315         cld
  316         rep
  317         movsl
  318         movb    %bl,%cl
  319         andb    $3,%cl
  320         rep
  321         movsb
  322 
  323 done_copyout:
  324         popl    %ebx
  325         popl    %edi
  326         popl    %esi
  327         xorl    %eax,%eax
  328         movl    PCPU(CURPCB),%edx
  329         movl    %eax,PCB_ONFAULT(%edx)
  330         ret
  331 END(copyout)
  332 
  333         ALIGN_TEXT
  334 copyout_fault:
  335         popl    %ebx
  336         popl    %edi
  337         popl    %esi
  338         movl    PCPU(CURPCB),%edx
  339         movl    $0,PCB_ONFAULT(%edx)
  340         movl    $EFAULT,%eax
  341         ret
  342 
  343 /*
  344  * copyin(from_user, to_kernel, len) - MP SAFE
  345  */
  346 ENTRY(copyin)
  347         movl    PCPU(CURPCB),%eax
  348         movl    $copyin_fault,PCB_ONFAULT(%eax)
  349         pushl   %esi
  350         pushl   %edi
  351         movl    12(%esp),%esi                   /* caddr_t from */
  352         movl    16(%esp),%edi                   /* caddr_t to */
  353         movl    20(%esp),%ecx                   /* size_t  len */
  354 
  355         /*
  356          * make sure address is valid
  357          */
  358         movl    %esi,%edx
  359         addl    %ecx,%edx
  360         jc      copyin_fault
  361         cmpl    $VM_MAXUSER_ADDRESS,%edx
  362         ja      copyin_fault
  363 
  364         movb    %cl,%al
  365         shrl    $2,%ecx                         /* copy longword-wise */
  366         cld
  367         rep
  368         movsl
  369         movb    %al,%cl
  370         andb    $3,%cl                          /* copy remaining bytes */
  371         rep
  372         movsb
  373 
  374         popl    %edi
  375         popl    %esi
  376         xorl    %eax,%eax
  377         movl    PCPU(CURPCB),%edx
  378         movl    %eax,PCB_ONFAULT(%edx)
  379         ret
  380 END(copyin)
  381 
  382         ALIGN_TEXT
  383 copyin_fault:
  384         popl    %edi
  385         popl    %esi
  386         movl    PCPU(CURPCB),%edx
  387         movl    $0,PCB_ONFAULT(%edx)
  388         movl    $EFAULT,%eax
  389         ret
  390 
  391 /*
  392  * casuword.  Compare and set user word.  Returns -1 or the current value.
  393  */
  394 
  395 ALTENTRY(casuword32)
  396 ENTRY(casuword)
  397         movl    PCPU(CURPCB),%ecx
  398         movl    $fusufault,PCB_ONFAULT(%ecx)
  399         movl    4(%esp),%edx                    /* dst */
  400         movl    8(%esp),%eax                    /* old */
  401         movl    12(%esp),%ecx                   /* new */
  402 
  403         cmpl    $VM_MAXUSER_ADDRESS-4,%edx      /* verify address is valid */
  404         ja      fusufault
  405 
  406 #ifdef SMP
  407         lock
  408 #endif
  409         cmpxchgl %ecx,(%edx)                    /* Compare and set. */
  410 
  411         /*
  412          * The old value is in %eax.  If the store succeeded it will be the
  413          * value we expected (old) from before the store, otherwise it will
  414          * be the current value.
  415          */
  416 
  417         movl    PCPU(CURPCB),%ecx
  418         movl    $0,PCB_ONFAULT(%ecx)
  419         ret
  420 END(casuword32)
  421 END(casuword)
  422 
  423 /*
  424  * Fetch (load) a 32-bit word, a 16-bit word, or an 8-bit byte from user
  425  * memory.  All these functions are MPSAFE.
  426  */
  427 
  428 ALTENTRY(fuword32)
  429 ENTRY(fuword)
  430         movl    PCPU(CURPCB),%ecx
  431         movl    $fusufault,PCB_ONFAULT(%ecx)
  432         movl    4(%esp),%edx                    /* from */
  433 
  434         cmpl    $VM_MAXUSER_ADDRESS-4,%edx      /* verify address is valid */
  435         ja      fusufault
  436 
  437         movl    (%edx),%eax
  438         movl    $0,PCB_ONFAULT(%ecx)
  439         ret
  440 END(fuword32)
  441 END(fuword)
  442 
  443 /*
  444  * fuswintr() and suswintr() are specialized variants of fuword16() and
  445  * suword16(), respectively.  They are called from the profiling code,
  446  * potentially at interrupt time.  If they fail, that's okay; good things
  447  * will happen later.  They always fail for now, until the trap code is
  448  * able to deal with this.
  449  */
  450 ALTENTRY(suswintr)
  451 ENTRY(fuswintr)
  452         movl    $-1,%eax
  453         ret
  454 END(suswintr)
  455 END(fuswintr)
  456 
  457 ENTRY(fuword16)
  458         movl    PCPU(CURPCB),%ecx
  459         movl    $fusufault,PCB_ONFAULT(%ecx)
  460         movl    4(%esp),%edx
  461 
  462         cmpl    $VM_MAXUSER_ADDRESS-2,%edx
  463         ja      fusufault
  464 
  465         movzwl  (%edx),%eax
  466         movl    $0,PCB_ONFAULT(%ecx)
  467         ret
  468 END(fuword16)
  469 
  470 ENTRY(fubyte)
  471         movl    PCPU(CURPCB),%ecx
  472         movl    $fusufault,PCB_ONFAULT(%ecx)
  473         movl    4(%esp),%edx
  474 
  475         cmpl    $VM_MAXUSER_ADDRESS-1,%edx
  476         ja      fusufault
  477 
  478         movzbl  (%edx),%eax
  479         movl    $0,PCB_ONFAULT(%ecx)
  480         ret
  481 END(fubyte)
  482 
  483         ALIGN_TEXT
  484 fusufault:
  485         movl    PCPU(CURPCB),%ecx
  486         xorl    %eax,%eax
  487         movl    %eax,PCB_ONFAULT(%ecx)
  488         decl    %eax
  489         ret
  490 
  491 /*
  492  * Store a 32-bit word, a 16-bit word, or an 8-bit byte to user memory.
  493  * All these functions are MPSAFE.
  494  */
  495 
  496 ALTENTRY(suword32)
  497 ENTRY(suword)
  498         movl    PCPU(CURPCB),%ecx
  499         movl    $fusufault,PCB_ONFAULT(%ecx)
  500         movl    4(%esp),%edx
  501 
  502         cmpl    $VM_MAXUSER_ADDRESS-4,%edx      /* verify address validity */
  503         ja      fusufault
  504 
  505         movl    8(%esp),%eax
  506         movl    %eax,(%edx)
  507         xorl    %eax,%eax
  508         movl    PCPU(CURPCB),%ecx
  509         movl    %eax,PCB_ONFAULT(%ecx)
  510         ret
  511 END(suword32)
  512 END(suword)
  513 
  514 ENTRY(suword16)
  515         movl    PCPU(CURPCB),%ecx
  516         movl    $fusufault,PCB_ONFAULT(%ecx)
  517         movl    4(%esp),%edx
  518 
  519         cmpl    $VM_MAXUSER_ADDRESS-2,%edx      /* verify address validity */
  520         ja      fusufault
  521 
  522         movw    8(%esp),%ax
  523         movw    %ax,(%edx)
  524         xorl    %eax,%eax
  525         movl    PCPU(CURPCB),%ecx               /* restore trashed register */
  526         movl    %eax,PCB_ONFAULT(%ecx)
  527         ret
  528 END(suword16)
  529 
  530 ENTRY(subyte)
  531         movl    PCPU(CURPCB),%ecx
  532         movl    $fusufault,PCB_ONFAULT(%ecx)
  533         movl    4(%esp),%edx
  534 
  535         cmpl    $VM_MAXUSER_ADDRESS-1,%edx      /* verify address validity */
  536         ja      fusufault
  537 
  538         movb    8(%esp),%al
  539         movb    %al,(%edx)
  540         xorl    %eax,%eax
  541         movl    PCPU(CURPCB),%ecx               /* restore trashed register */
  542         movl    %eax,PCB_ONFAULT(%ecx)
  543         ret
  544 END(subyte)
  545 
  546 /*
  547  * copyinstr(from, to, maxlen, int *lencopied) - MP SAFE
  548  *
  549  *      copy a string from from to to, stop when a 0 character is reached.
  550  *      return ENAMETOOLONG if string is longer than maxlen, and
  551  *      EFAULT on protection violations. If lencopied is non-zero,
  552  *      return the actual length in *lencopied.
  553  */
  554 ENTRY(copyinstr)
  555         pushl   %esi
  556         pushl   %edi
  557         movl    PCPU(CURPCB),%ecx
  558         movl    $cpystrflt,PCB_ONFAULT(%ecx)
  559 
  560         movl    12(%esp),%esi                   /* %esi = from */
  561         movl    16(%esp),%edi                   /* %edi = to */
  562         movl    20(%esp),%edx                   /* %edx = maxlen */
  563 
  564         movl    $VM_MAXUSER_ADDRESS,%eax
  565 
  566         /* make sure 'from' is within bounds */
  567         subl    %esi,%eax
  568         jbe     cpystrflt
  569 
  570         /* restrict maxlen to <= VM_MAXUSER_ADDRESS-from */
  571         cmpl    %edx,%eax
  572         jae     1f
  573         movl    %eax,%edx
  574         movl    %eax,20(%esp)
  575 1:
  576         incl    %edx
  577         cld
  578 
  579 2:
  580         decl    %edx
  581         jz      3f
  582 
  583         lodsb
  584         stosb
  585         orb     %al,%al
  586         jnz     2b
  587 
  588         /* Success -- 0 byte reached */
  589         decl    %edx
  590         xorl    %eax,%eax
  591         jmp     cpystrflt_x
  592 3:
  593         /* edx is zero - return ENAMETOOLONG or EFAULT */
  594         cmpl    $VM_MAXUSER_ADDRESS,%esi
  595         jae     cpystrflt
  596 4:
  597         movl    $ENAMETOOLONG,%eax
  598         jmp     cpystrflt_x
  599 
  600 cpystrflt:
  601         movl    $EFAULT,%eax
  602 
  603 cpystrflt_x:
  604         /* set *lencopied and return %eax */
  605         movl    PCPU(CURPCB),%ecx
  606         movl    $0,PCB_ONFAULT(%ecx)
  607         movl    20(%esp),%ecx
  608         subl    %edx,%ecx
  609         movl    24(%esp),%edx
  610         testl   %edx,%edx
  611         jz      1f
  612         movl    %ecx,(%edx)
  613 1:
  614         popl    %edi
  615         popl    %esi
  616         ret
  617 END(copyinstr)
  618 
  619 /*
  620  * copystr(from, to, maxlen, int *lencopied) - MP SAFE
  621  */
  622 ENTRY(copystr)
  623         pushl   %esi
  624         pushl   %edi
  625 
  626         movl    12(%esp),%esi                   /* %esi = from */
  627         movl    16(%esp),%edi                   /* %edi = to */
  628         movl    20(%esp),%edx                   /* %edx = maxlen */
  629         incl    %edx
  630         cld
  631 1:
  632         decl    %edx
  633         jz      4f
  634         lodsb
  635         stosb
  636         orb     %al,%al
  637         jnz     1b
  638 
  639         /* Success -- 0 byte reached */
  640         decl    %edx
  641         xorl    %eax,%eax
  642         jmp     6f
  643 4:
  644         /* edx is zero -- return ENAMETOOLONG */
  645         movl    $ENAMETOOLONG,%eax
  646 
  647 6:
  648         /* set *lencopied and return %eax */
  649         movl    20(%esp),%ecx
  650         subl    %edx,%ecx
  651         movl    24(%esp),%edx
  652         testl   %edx,%edx
  653         jz      7f
  654         movl    %ecx,(%edx)
  655 7:
  656         popl    %edi
  657         popl    %esi
  658         ret
  659 END(copystr)
  660 
  661 ENTRY(bcmp)
  662         pushl   %edi
  663         pushl   %esi
  664         movl    12(%esp),%edi
  665         movl    16(%esp),%esi
  666         movl    20(%esp),%edx
  667 
  668         movl    %edx,%ecx
  669         shrl    $2,%ecx
  670         cld                                     /* compare forwards */
  671         repe
  672         cmpsl
  673         jne     1f
  674 
  675         movl    %edx,%ecx
  676         andl    $3,%ecx
  677         repe
  678         cmpsb
  679 1:
  680         setne   %al
  681         movsbl  %al,%eax
  682         popl    %esi
  683         popl    %edi
  684         ret
  685 END(bcmp)
  686 
  687 /*
  688  * Handling of special 386 registers and descriptor tables etc
  689  */
  690 /* void lgdt(struct region_descriptor *rdp); */
  691 ENTRY(lgdt)
  692 #ifndef XEN
  693         /* reload the descriptor table */
  694         movl    4(%esp),%eax
  695         lgdt    (%eax)
  696 #endif
  697 
  698         /* flush the prefetch q */
  699         jmp     1f
  700         nop
  701 1:
  702         /* reload "stale" selectors */
  703         movl    $KDSEL,%eax
  704         movl    %eax,%ds
  705         movl    %eax,%es
  706         movl    %eax,%gs
  707         movl    %eax,%ss
  708         movl    $KPSEL,%eax
  709         movl    %eax,%fs
  710 
  711         /* reload code selector by turning return into intersegmental return */
  712         movl    (%esp),%eax
  713         pushl   %eax
  714         movl    $KCSEL,4(%esp)
  715         MEXITCOUNT
  716         lret
  717 END(lgdt)
  718 
  719 /* ssdtosd(*ssdp,*sdp) */
  720 ENTRY(ssdtosd)
  721         pushl   %ebx
  722         movl    8(%esp),%ecx
  723         movl    8(%ecx),%ebx
  724         shll    $16,%ebx
  725         movl    (%ecx),%edx
  726         roll    $16,%edx
  727         movb    %dh,%bl
  728         movb    %dl,%bh
  729         rorl    $8,%ebx
  730         movl    4(%ecx),%eax
  731         movw    %ax,%dx
  732         andl    $0xf0000,%eax
  733         orl     %eax,%ebx
  734         movl    12(%esp),%ecx
  735         movl    %edx,(%ecx)
  736         movl    %ebx,4(%ecx)
  737         popl    %ebx
  738         ret
  739 END(ssdtosd)
  740 
  741 /* void reset_dbregs() */
  742 ENTRY(reset_dbregs)
  743         movl    $0,%eax
  744         movl    %eax,%dr7       /* disable all breakpoints first */
  745         movl    %eax,%dr0
  746         movl    %eax,%dr1
  747         movl    %eax,%dr2
  748         movl    %eax,%dr3
  749         movl    %eax,%dr6
  750         ret
  751 END(reset_dbregs)
  752 
  753 /*****************************************************************************/
  754 /* setjump, longjump                                                         */
  755 /*****************************************************************************/
  756 
  757 ENTRY(setjmp)
  758         movl    4(%esp),%eax
  759         movl    %ebx,(%eax)                     /* save ebx */
  760         movl    %esp,4(%eax)                    /* save esp */
  761         movl    %ebp,8(%eax)                    /* save ebp */
  762         movl    %esi,12(%eax)                   /* save esi */
  763         movl    %edi,16(%eax)                   /* save edi */
  764         movl    (%esp),%edx                     /* get rta */
  765         movl    %edx,20(%eax)                   /* save eip */
  766         xorl    %eax,%eax                       /* return(0); */
  767         ret
  768 END(setjmp)
  769 
  770 ENTRY(longjmp)
  771         movl    4(%esp),%eax
  772         movl    (%eax),%ebx                     /* restore ebx */
  773         movl    4(%eax),%esp                    /* restore esp */
  774         movl    8(%eax),%ebp                    /* restore ebp */
  775         movl    12(%eax),%esi                   /* restore esi */
  776         movl    16(%eax),%edi                   /* restore edi */
  777         movl    20(%eax),%edx                   /* get rta */
  778         movl    %edx,(%esp)                     /* put in return frame */
  779         xorl    %eax,%eax                       /* return(1); */
  780         incl    %eax
  781         ret
  782 END(longjmp)
  783 
  784 /*
  785  * Support for reading MSRs in the safe manner.
  786  */
  787 ENTRY(rdmsr_safe)
  788 /* int rdmsr_safe(u_int msr, uint64_t *data) */
  789         movl    PCPU(CURPCB),%ecx
  790         movl    $msr_onfault,PCB_ONFAULT(%ecx)
  791 
  792         movl    4(%esp),%ecx
  793         rdmsr
  794         movl    8(%esp),%ecx
  795         movl    %eax,(%ecx)
  796         movl    %edx,4(%ecx)
  797         xorl    %eax,%eax
  798 
  799         movl    PCPU(CURPCB),%ecx
  800         movl    %eax,PCB_ONFAULT(%ecx)
  801 
  802         ret
  803 
  804 /*
  805  * Support for writing MSRs in the safe manner.
  806  */
  807 ENTRY(wrmsr_safe)
  808 /* int wrmsr_safe(u_int msr, uint64_t data) */
  809         movl    PCPU(CURPCB),%ecx
  810         movl    $msr_onfault,PCB_ONFAULT(%ecx)
  811 
  812         movl    4(%esp),%ecx
  813         movl    8(%esp),%eax
  814         movl    12(%esp),%edx
  815         wrmsr
  816         xorl    %eax,%eax
  817 
  818         movl    PCPU(CURPCB),%ecx
  819         movl    %eax,PCB_ONFAULT(%ecx)
  820 
  821         ret
  822 
  823 /*
  824  * MSR operations fault handler
  825  */
  826         ALIGN_TEXT
  827 msr_onfault:
  828         movl    PCPU(CURPCB),%ecx
  829         movl    $0,PCB_ONFAULT(%ecx)
  830         movl    $EFAULT,%eax
  831         ret

Cache object: 437625effaa8321667f801b2078bb4c9


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.