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$");
   29 
   30 #include <machine/asmacros.h>
   31 #include <machine/asi.h>
   32 #include <machine/fsr.h>
   33 #include <machine/ktr.h>
   34 #include <machine/pcb.h>
   35 #include <machine/tstate.h>
   36 
   37 #include "assym.s"
   38 
   39         .register       %g2, #ignore
   40         .register       %g3, #ignore
   41 
   42 /*
   43  * void cpu_throw(struct thread *old, struct thread *new)
   44  */
   45 ENTRY(cpu_throw)
   46         save    %sp, -CCFSZ, %sp
   47         flushw
   48         ba      %xcc, .Lsw1
   49          mov    %g0, %i2
   50 END(cpu_throw)
   51 
   52 /*
   53  * void cpu_switch(struct thread *old, struct thread *new, struct mtx *mtx)
   54  */
   55 ENTRY(cpu_switch)
   56         save    %sp, -CCFSZ, %sp
   57 
   58         /*
   59          * If the current thread was using floating point in the kernel, save
   60          * its context.  The userland floating point context has already been
   61          * saved in that case.
   62          */
   63         rd      %fprs, %l2
   64         andcc   %l2, FPRS_FEF, %g0
   65         bz,a,pt %xcc, 1f
   66          nop
   67         call    savefpctx
   68          add    PCB_REG, PCB_KFP, %o0
   69         ba,a    %xcc, 2f
   70          nop
   71 
   72         /*
   73          * If the current thread was using floating point in userland, save
   74          * its context.
   75          */
   76 1:      sub     PCB_REG, TF_SIZEOF, %l2
   77         ldx     [%l2 + TF_FPRS], %l3
   78         andcc   %l3, FPRS_FEF, %g0
   79         bz,a,pt %xcc, 2f
   80          nop
   81         call    savefpctx
   82          add    PCB_REG, PCB_UFP, %o0
   83         andn    %l3, FPRS_FEF, %l3
   84         stx     %l3, [%l2 + TF_FPRS]
   85 
   86         ldx     [PCB_REG + PCB_FLAGS], %l3
   87         or      %l3, PCB_FEF, %l3
   88         stx     %l3, [PCB_REG + PCB_FLAGS]
   89 
   90         /*
   91          * Flush the windows out to the stack and save the current frame
   92          * pointer and program counter.
   93          */
   94 2:      flushw
   95         wrpr    %g0, 0, %cleanwin
   96         stx     %fp, [PCB_REG + PCB_SP]
   97         stx     %i7, [PCB_REG + PCB_PC]
   98 
   99         /*
  100          * Load the new thread's frame pointer and program counter, and set
  101          * the current thread and pcb.
  102          */
  103 .Lsw1:
  104 #if KTR_COMPILE & KTR_PROC
  105         CATR(KTR_PROC, "cpu_switch: new td=%p pc=%#lx fp=%#lx"
  106             , %g1, %g2, %g3, 8, 9, 10)
  107         stx     %i1, [%g1 + KTR_PARM1]
  108         ldx     [%i1 + TD_PCB], %g2
  109         ldx     [%g2 + PCB_PC], %g3
  110         stx     %g3, [%g1 + KTR_PARM2]
  111         ldx     [%g2 + PCB_SP], %g3
  112         stx     %g3, [%g1 + KTR_PARM3]
  113 10:
  114 #endif
  115         ldx     [%i1 + TD_PCB], %l0
  116 
  117         stx     %i1, [PCPU(CURTHREAD)]
  118         stx     %l0, [PCPU(CURPCB)]
  119 
  120         wrpr    %g0, PSTATE_NORMAL, %pstate
  121         mov     %l0, PCB_REG
  122         wrpr    %g0, PSTATE_ALT, %pstate
  123         mov     %l0, PCB_REG
  124         wrpr    %g0, PSTATE_KERNEL, %pstate
  125 
  126         ldx     [PCB_REG + PCB_SP], %fp
  127         ldx     [PCB_REG + PCB_PC], %i7
  128         sub     %fp, CCFSZ, %sp
  129 
  130         /*
  131          * Point to the pmaps of the new process, and of the last non-kernel
  132          * process to run.
  133          */
  134         ldx     [%i1 + TD_PROC], %l1
  135         ldx     [PCPU(PMAP)], %l2
  136         ldx     [%l1 + P_VMSPACE], %i5
  137         add     %i5, VM_PMAP, %l1
  138 
  139 #if KTR_COMPILE & KTR_PROC
  140         CATR(KTR_PROC, "cpu_switch: new pmap=%p old pmap=%p"
  141             , %g1, %g2, %g3, 8, 9, 10)
  142         stx     %l1, [%g1 + KTR_PARM1]
  143         stx     %l2, [%g1 + KTR_PARM2]
  144 10:
  145 #endif
  146 
  147         /*
  148          * If they are the same we are done.
  149          */
  150         cmp     %l2, %l1
  151         be,a,pn %xcc, 7f
  152          nop
  153 
  154         /*
  155          * If the new process is a kernel thread we can just leave the old
  156          * context active and avoid recycling its context number.
  157          */
  158         SET(vmspace0, %i4, %i3)
  159         cmp     %i5, %i3
  160         be,a,pn %xcc, 7f
  161          nop
  162 
  163         /*
  164          * If there was no non-kernel pmap, don't try to deactivate it.
  165          */
  166         brz,pn  %l2, 3f
  167          lduw   [PCPU(CPUMASK)], %l4
  168 
  169         /*
  170          * Mark the pmap of the last non-kernel vmspace to run as no longer
  171          * active on this CPU.
  172          */
  173         lduw    [%l2 + PM_ACTIVE], %l3
  174         andn    %l3, %l4, %l3
  175         stw     %l3, [%l2 + PM_ACTIVE]
  176 
  177         /*
  178          * Take away its context number.
  179          */
  180         lduw    [PCPU(CPUID)], %l3
  181         sllx    %l3, INT_SHIFT, %l3
  182         add     %l2, PM_CONTEXT, %l4
  183         mov     -1, %l5
  184         stw     %l5, [%l3 + %l4]
  185 
  186 3:      cmp     %i2, %g0
  187         be,pn   %xcc, 4f
  188          lduw   [PCPU(TLB_CTX_MAX)], %i4
  189         stx     %i2, [%i0 + TD_LOCK]
  190 
  191         /*
  192          * Find a new TLB context.  If we've run out we have to flush all
  193          * user mappings from the TLB and reset the context numbers.
  194          */
  195 4:      lduw    [PCPU(TLB_CTX)], %i3
  196         cmp     %i3, %i4
  197         bne,a,pt %xcc, 5f
  198          nop
  199         SET(tlb_flush_user, %i5, %i4)
  200         ldx     [%i4], %i5
  201         call    %i5
  202          lduw   [PCPU(TLB_CTX_MIN)], %i3
  203 
  204         /*
  205          * Advance next free context.
  206          */
  207 5:      add     %i3, 1, %i4
  208         stw     %i4, [PCPU(TLB_CTX)]
  209 
  210         /*
  211          * Set the new context number in the pmap.
  212          */
  213         lduw    [PCPU(CPUID)], %i4
  214         sllx    %i4, INT_SHIFT, %i4
  215         add     %l1, PM_CONTEXT, %i5
  216         stw     %i3, [%i4 + %i5]
  217 
  218         /*
  219          * Mark the pmap as active on this CPU.
  220          */
  221         lduw    [%l1 + PM_ACTIVE], %i4
  222         lduw    [PCPU(CPUMASK)], %i5
  223         or      %i4, %i5, %i4
  224         stw     %i4, [%l1 + PM_ACTIVE]
  225 
  226         /*
  227          * Make note of the change in pmap.
  228          */
  229         stx     %l1, [PCPU(PMAP)]
  230 
  231         /*
  232          * Fiddle the hardware bits.  Set the TSB registers and install the
  233          * new context number in the CPU.
  234          */
  235         ldx     [%l1 + PM_TSB], %i4
  236         mov     AA_DMMU_TSB, %i5
  237         stxa    %i4, [%i5] ASI_DMMU
  238         mov     AA_IMMU_TSB, %i5
  239         stxa    %i4, [%i5] ASI_IMMU
  240         setx    TLB_CXR_PGSZ_MASK, %i5, %i4
  241         mov     AA_DMMU_PCXR, %i5
  242         ldxa    [%i5] ASI_DMMU, %l1
  243         and     %l1, %i4, %l1
  244         or      %i3, %l1, %i3
  245         sethi   %hi(KERNBASE), %i4
  246         stxa    %i3, [%i5] ASI_DMMU
  247         flush   %i4
  248 
  249         /*
  250          * Done, return and load the new process's window from the stack.
  251          */
  252 
  253 6:      ret
  254          restore
  255 
  256 7:      cmp     %i2, %g0
  257         be,a,pn %xcc, 6b
  258          nop
  259         stx     %i2, [%i0 + TD_LOCK]
  260         ret
  261          restore
  262 END(cpu_switch)
  263 
  264 ENTRY(savectx)
  265         save    %sp, -CCFSZ, %sp
  266         flushw
  267         call    savefpctx
  268          add    %i0, PCB_UFP, %o0
  269         stx     %fp, [%i0 + PCB_SP]
  270         stx     %i7, [%i0 + PCB_PC]
  271         ret
  272          restore %g0, 0, %o0
  273 END(savectx)
  274 
  275 /*
  276  * void savefpctx(uint32_t *);
  277  */
  278 ENTRY(savefpctx)
  279         wr      %g0, FPRS_FEF, %fprs
  280         wr      %g0, ASI_BLK_S, %asi
  281         stda    %f0, [%o0 + (0 * 64)] %asi
  282         stda    %f16, [%o0 + (1 * 64)] %asi
  283         stda    %f32, [%o0 + (2 * 64)] %asi
  284         stda    %f48, [%o0 + (3 * 64)] %asi
  285         membar  #Sync
  286         retl
  287          wr     %g0, 0, %fprs
  288 END(savefpctx)

Cache object: fbc0242f80273c67987d56557f73f77c


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