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/6.0/sys/sparc64/sparc64/swtch.S 129749 2004-05-26 12:06:52Z tmm $");
   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 pmaps of the new process, and of the last non-kernel
  131          * process to run.
  132          */
  133         ldx     [%i0 + TD_PROC], %i2
  134         ldx     [PCPU(PMAP)], %l2
  135         ldx     [%i2 + P_VMSPACE], %i5
  136         add     %i5, VM_PMAP, %i2
  137 
  138 #if KTR_COMPILE & KTR_PROC
  139         CATR(KTR_PROC, "cpu_switch: new pmap=%p old pmap=%p"
  140             , %g1, %g2, %g3, 7, 8, 9)
  141         stx     %i2, [%g1 + KTR_PARM1]
  142         stx     %l2, [%g1 + KTR_PARM2]
  143 9:
  144 #endif
  145 
  146         /*
  147          * If they are the same we are done.
  148          */
  149         cmp     %l2, %i2
  150         be,a,pn %xcc, 5f
  151          nop
  152 
  153         /*
  154          * If the new process is a kernel thread we can just leave the old
  155          * context active and avoid recycling its context number.
  156          */
  157         SET(vmspace0, %i4, %i3)
  158         cmp     %i5, %i3
  159         be,a,pn %xcc, 5f
  160          nop
  161 
  162         /*
  163          * If there was no non-kernel pmap, don't try to deactivate it.
  164          */
  165         brz,a,pn %l2, 3f
  166          nop
  167 
  168         /*
  169          * Mark the pmap of the last non-kernel vmspace to run as no longer
  170          * active on this cpu.
  171          */
  172         lduw    [%l2 + PM_ACTIVE], %l3
  173         lduw    [PCPU(CPUMASK)], %l4
  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         /*
  187          * Find a new tlb context.  If we've run out we have to flush all user
  188          * mappings from the tlb and reset the context numbers.
  189          */
  190 3:      lduw    [PCPU(TLB_CTX)], %i3
  191         lduw    [PCPU(TLB_CTX_MAX)], %i4
  192         cmp     %i3, %i4
  193         bne,a,pt %xcc, 4f
  194          nop
  195         SET(tlb_flush_user, %i5, %i4)
  196         ldx     [%i4], %i5
  197         call    %i5
  198          nop
  199         lduw    [PCPU(TLB_CTX_MIN)], %i3
  200 
  201         /*
  202          * Advance next free context.
  203          */
  204 4:      add     %i3, 1, %i4
  205         stw     %i4, [PCPU(TLB_CTX)]
  206 
  207         /*
  208          * Set the new context number in the pmap.
  209          */
  210         lduw    [PCPU(CPUID)], %i4
  211         sllx    %i4, INT_SHIFT, %i4
  212         add     %i2, PM_CONTEXT, %i5
  213         stw     %i3, [%i4 + %i5]
  214 
  215         /*
  216          * Mark the pmap as active on this cpu.
  217          */
  218         lduw    [%i2 + PM_ACTIVE], %i4
  219         lduw    [PCPU(CPUMASK)], %i5
  220         or      %i4, %i5, %i4
  221         stw     %i4, [%i2 + PM_ACTIVE]
  222 
  223         /*
  224          * Make note of the change in pmap.
  225          */
  226         stx     %i2, [PCPU(PMAP)]
  227 
  228         /*
  229          * Fiddle the hardware bits.  Set the tsb registers and install the
  230          * new context number in the cpu.
  231          */
  232         ldx     [%i2 + PM_TSB], %i4
  233         mov     AA_DMMU_TSB, %i5
  234         stxa    %i4, [%i5] ASI_DMMU
  235         mov     AA_IMMU_TSB, %i5
  236         stxa    %i4, [%i5] ASI_IMMU
  237         mov     AA_DMMU_PCXR, %i5
  238         stxa    %i3, [%i5] ASI_DMMU
  239         membar  #Sync
  240 
  241         /*
  242          * Done.  Return and load the new process's window from the stack.
  243          */
  244 5:      ret
  245          restore
  246 END(cpu_switch)
  247 
  248 ENTRY(savectx)
  249         save    %sp, -CCFSZ, %sp
  250         flushw
  251         call    savefpctx
  252          add    %i0, PCB_UFP, %o0
  253         stx     %fp, [%i0 + PCB_SP]
  254         stx     %i7, [%i0 + PCB_PC]
  255         ret
  256          restore %g0, 0, %o0
  257 END(savectx)
  258 
  259 /*
  260  * void savefpctx(uint32_t *);
  261  */
  262 ENTRY(savefpctx)
  263         wr      %g0, FPRS_FEF, %fprs
  264         wr      %g0, ASI_BLK_S, %asi
  265         stda    %f0, [%o0 + (0 * 64)] %asi
  266         stda    %f16, [%o0 + (1 * 64)] %asi
  267         stda    %f32, [%o0 + (2 * 64)] %asi
  268         stda    %f48, [%o0 + (3 * 64)] %asi
  269         membar  #Sync
  270         retl
  271          wr     %g0, 0, %fprs
  272 END(savefpctx)

Cache object: 1a438dba4f7fd29e031fdbe25d6ab39c


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