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/sparc64/sparc64/swtch.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) 2001 Jake Burkholder.
    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  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  */
   26 
   27 #include <machine/asm.h>
   28 __FBSDID("$FreeBSD: releng/5.2/sys/sparc64/sparc64/swtch.S 114188 2003-04-29 00:37:41Z jake $");
   29 
   30 #include <machine/asmacros.h>
   31 #include <machine/asi.h>
   32 #include <machine/ktr.h>
   33 #include <machine/tstate.h>
   34 
   35 #include "assym.s"
   36 
   37         .register       %g2, #ignore
   38         .register       %g3, #ignore
   39 
   40 /*
   41  * void cpu_throw(struct thread *old, struct thread *new)
   42  */
   43 ENTRY(cpu_throw)
   44         save    %sp, -CCFSZ, %sp
   45         flushw
   46         ba      %xcc, .Lsw1
   47          mov    %i1, %i0
   48 END(cpu_throw)
   49 
   50 /*
   51  * void cpu_switch(struct thread *old, struct thread *new)
   52  */
   53 ENTRY(cpu_switch)
   54         save    %sp, -CCFSZ, %sp
   55         mov     %i1, %i0
   56 
   57         /*
   58          * If the current thread was using floating point in the kernel, save
   59          * its context.  The userland floating point context has already been
   60          * saved in that case.
   61          */
   62         rd      %fprs, %l2
   63         andcc   %l2, FPRS_FEF, %g0
   64         bz,a,pt %xcc, 1f
   65          nop
   66         call    savefpctx
   67          add    PCB_REG, PCB_KFP, %o0
   68         ba,a    %xcc, 2f
   69          nop
   70 
   71         /*
   72          * If the current thread was using floating point in userland, save
   73          * its context.
   74          */
   75 1:      sub     PCB_REG, TF_SIZEOF, %l2
   76         ldx     [%l2 + TF_FPRS], %l3
   77         andcc   %l3, FPRS_FEF, %g0
   78         bz,a,pt %xcc, 2f
   79          nop
   80         call    savefpctx
   81          add    PCB_REG, PCB_UFP, %o0
   82         andn    %l3, FPRS_FEF, %l3
   83         stx     %l3, [%l2 + TF_FPRS]
   84 
   85         ldx     [PCB_REG + PCB_FLAGS], %l3
   86         or      %l3, PCB_FEF, %l3
   87         stx     %l3, [PCB_REG + PCB_FLAGS]
   88 
   89         /*
   90          * Flush the windows out to the stack and save the current frame
   91          * pointer and program counter.
   92          */
   93 2:      flushw
   94         wrpr    %g0, 0, %cleanwin
   95         stx     %fp, [PCB_REG + PCB_SP]
   96         stx     %i7, [PCB_REG + PCB_PC]
   97 
   98         /*
   99          * Load the new thread's frame pointer and program counter, and set
  100          * the current thread and pcb.
  101          */
  102 .Lsw1:
  103 #if KTR_COMPILE & KTR_PROC
  104         CATR(KTR_PROC, "cpu_switch: new td=%p pc=%#lx fp=%#lx"
  105             , %g1, %g2, %g3, 7, 8, 9)
  106         stx     %i0, [%g1 + KTR_PARM1]
  107         ldx     [%i0 + TD_PCB], %g2
  108         ldx     [%g2 + PCB_PC], %g3
  109         stx     %g3, [%g1 + KTR_PARM2]
  110         ldx     [%g2 + PCB_SP], %g3
  111         stx     %g3, [%g1 + KTR_PARM3]
  112 9:
  113 #endif
  114         ldx     [%i0 + TD_PCB], %i1
  115 
  116         stx     %i0, [PCPU(CURTHREAD)]
  117         stx     %i1, [PCPU(CURPCB)]
  118 
  119         wrpr    %g0, PSTATE_NORMAL, %pstate
  120         mov     %i1, PCB_REG
  121         wrpr    %g0, PSTATE_ALT, %pstate
  122         mov     %i1, PCB_REG
  123         wrpr    %g0, PSTATE_KERNEL, %pstate
  124 
  125         ldx     [PCB_REG + PCB_SP], %fp
  126         ldx     [PCB_REG + PCB_PC], %i7
  127         sub     %fp, CCFSZ, %sp
  128 
  129         /*
  130          * Point to the vmspaces of the new process, and of the last non-kernel
  131          * process to run.
  132          */
  133         ldx     [%i0 + TD_PROC], %i2
  134         ldx     [PCPU(VMSPACE)], %l2
  135         ldx     [%i2 + P_VMSPACE], %i2
  136 
  137 #if KTR_COMPILE & KTR_PROC
  138         CATR(KTR_PROC, "cpu_switch: new vm=%p old vm=%p"
  139             , %g1, %g2, %g3, 7, 8, 9)
  140         stx     %i2, [%g1 + KTR_PARM1]
  141         stx     %l2, [%g1 + KTR_PARM2]
  142 9:
  143 #endif
  144 
  145         /*
  146          * If they are the same we are done.
  147          */
  148         cmp     %l2, %i2
  149         be,a,pn %xcc, 5f
  150          nop
  151 
  152         /*
  153          * If the new process is a kernel thread we can just leave the old
  154          * context active and avoid recycling its context number.
  155          */
  156         SET(vmspace0, %i4, %i3)
  157         cmp     %i2, %i3
  158         be,a,pn %xcc, 5f
  159          nop
  160 
  161         /*
  162          * If there was no non-kernel vmspace, don't try to deactivate it.
  163          */
  164         brz,a,pn %l2, 3f
  165          nop
  166 
  167         /*
  168          * Mark the pmap of the last non-kernel vmspace to run as no longer
  169          * active on this cpu.
  170          */
  171         lduw    [%l2 + VM_PMAP + PM_ACTIVE], %l3
  172         lduw    [PCPU(CPUMASK)], %l4
  173         andn    %l3, %l4, %l3
  174         stw     %l3, [%l2 + VM_PMAP + PM_ACTIVE]
  175 
  176         /*
  177          * Take away its context number.
  178          */
  179         lduw    [PCPU(CPUID)], %l3
  180         sllx    %l3, INT_SHIFT, %l3
  181         add     %l2, VM_PMAP + PM_CONTEXT, %l4
  182         mov     -1, %l5
  183         stw     %l5, [%l3 + %l4]
  184 
  185         /*
  186          * Find a new tlb context.  If we've run out we have to flush all user
  187          * mappings from the tlb and reset the context numbers.
  188          */
  189 3:      lduw    [PCPU(TLB_CTX)], %i3
  190         lduw    [PCPU(TLB_CTX_MAX)], %i4
  191         cmp     %i3, %i4
  192         bne,a,pt %xcc, 4f
  193          nop
  194         SET(tlb_flush_user, %i5, %i4)
  195         ldx     [%i4], %i5
  196         call    %i5
  197          nop
  198         lduw    [PCPU(TLB_CTX_MIN)], %i3
  199 
  200         /*
  201          * Advance next free context.
  202          */
  203 4:      add     %i3, 1, %i4
  204         stw     %i4, [PCPU(TLB_CTX)]
  205 
  206         /*
  207          * Set the new context number in the pmap.
  208          */
  209         lduw    [PCPU(CPUID)], %i4
  210         sllx    %i4, INT_SHIFT, %i4
  211         add     %i2, VM_PMAP + PM_CONTEXT, %i5
  212         stw     %i3, [%i4 + %i5]
  213 
  214         /*
  215          * Mark the pmap as active on this cpu.
  216          */
  217         lduw    [%i2 + VM_PMAP + PM_ACTIVE], %i4
  218         lduw    [PCPU(CPUMASK)], %i5
  219         or      %i4, %i5, %i4
  220         stw     %i4, [%i2 + VM_PMAP + PM_ACTIVE]
  221 
  222         /*
  223          * Make note of the change in vmspace.
  224          */
  225         stx     %i2, [PCPU(VMSPACE)]
  226 
  227         /*
  228          * Fiddle the hardware bits.  Set the tsb registers and install the
  229          * new context number in the cpu.
  230          */
  231         ldx     [%i2 + VM_PMAP + PM_TSB], %i4
  232         mov     AA_DMMU_TSB, %i5
  233         stxa    %i4, [%i5] ASI_DMMU
  234         mov     AA_IMMU_TSB, %i5
  235         stxa    %i4, [%i5] ASI_IMMU
  236         mov     AA_DMMU_PCXR, %i5
  237         stxa    %i3, [%i5] ASI_DMMU
  238         membar  #Sync
  239 
  240         /*
  241          * Done.  Return and load the new process's window from the stack.
  242          */
  243 5:      ret
  244          restore
  245 END(cpu_switch)
  246 
  247 ENTRY(savectx)
  248         save    %sp, -CCFSZ, %sp
  249         flushw
  250         call    savefpctx
  251          add    %i0, PCB_UFP, %o0
  252         stx     %fp, [%i0 + PCB_SP]
  253         stx     %i7, [%i0 + PCB_PC]
  254         ret
  255          restore %g0, 0, %o0
  256 END(savectx)
  257 
  258 /*
  259  * void savefpctx(uint32_t *);
  260  */
  261 ENTRY(savefpctx)
  262         wr      %g0, FPRS_FEF, %fprs
  263         wr      %g0, ASI_BLK_S, %asi
  264         stda    %f0, [%o0 + (0 * 64)] %asi
  265         stda    %f16, [%o0 + (1 * 64)] %asi
  266         stda    %f32, [%o0 + (2 * 64)] %asi
  267         stda    %f48, [%o0 + (3 * 64)] %asi
  268         membar  #Sync
  269         retl
  270          wr     %g0, 0, %fprs
  271 END(savefpctx)

Cache object: 10f076591ddbf4e86492167a71033ffb


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