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

Cache object: 3c497b2488dbc2a2f31a635407cc8b11


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