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/mips/mips/swtch.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 /*      $OpenBSD: locore.S,v 1.18 1998/09/15 10:58:53 pefo Exp $        */
    2 /*-
    3  * Copyright (c) 1992, 1993
    4  *      The Regents of the University of California.  All rights reserved.
    5  *
    6  * This code is derived from software contributed to Berkeley by
    7  * Digital Equipment Corporation and Ralph Campbell.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions and the following disclaimer.
   14  * 2. Redistributions in binary form must reproduce the above copyright
   15  *    notice, this list of conditions and the following disclaimer in the
   16  *    documentation and/or other materials provided with the distribution.
   17  * 4. Neither the name of the University nor the names of its contributors
   18  *    may be used to endorse or promote products derived from this software
   19  *    without specific prior written permission.
   20  *
   21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   31  * SUCH DAMAGE.
   32  *
   33  * Copyright (C) 1989 Digital Equipment Corporation.
   34  * Permission to use, copy, modify, and distribute this software and
   35  * its documentation for any purpose and without fee is hereby granted,
   36  * provided that the above copyright notice appears in all copies.
   37  * Digital Equipment Corporation makes no representations about the
   38  * suitability of this software for any purpose.  It is provided "as is"
   39  * without express or implied warranty.
   40  *
   41  * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/loMem.s,
   42  *      v 1.1 89/07/11 17:55:04 nelson Exp  SPRITE (DECWRL)
   43  * from: Header: /sprite/src/kernel/mach/ds3100.md/RCS/machAsm.s,
   44  *      v 9.2 90/01/29 18:00:39 shirriff Exp  SPRITE (DECWRL)
   45  * from: Header: /sprite/src/kernel/vm/ds3100.md/vmPmaxAsm.s,
   46  *      v 1.1 89/07/10 14:27:41 nelson Exp  SPRITE (DECWRL)
   47  *
   48  *      from: @(#)locore.s      8.5 (Berkeley) 1/4/94
   49  *      JNPR: swtch.S,v 1.6.2.1 2007/09/10 10:36:50 girish
   50  * $FreeBSD: releng/8.4/sys/mips/mips/swtch.S 215938 2010-11-27 12:26:40Z jchandra $
   51  */
   52 
   53 /*
   54  *      Contains code that is the first executed at boot time plus
   55  *      assembly language support routines.
   56  */
   57 
   58 #include "opt_cputype.h"
   59 #include <sys/syscall.h>
   60 #include <machine/asm.h>
   61 #include <machine/cpu.h>
   62 #include <machine/cpuregs.h>
   63 #include <machine/regnum.h>
   64 #include <machine/pte.h>
   65 
   66 #include "assym.s"
   67 
   68         .set    noreorder                       # Noreorder is default style!
   69 
   70 #define SAVE_U_PCB_REG(reg, offs, base) \
   71         REG_S   reg, U_PCB_REGS + (SZREG * offs) (base)
   72 
   73 #define RESTORE_U_PCB_REG(reg, offs, base) \
   74         REG_L   reg, U_PCB_REGS + (SZREG * offs) (base)
   75 
   76 #define SAVE_U_PCB_FPREG(reg, offs, base) \
   77         FP_S    reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   78 
   79 #define RESTORE_U_PCB_FPREG(reg, offs, base) \
   80         FP_L    reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   81 
   82 #define SAVE_U_PCB_FPSR(reg, offs, base) \
   83         REG_S   reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   84 
   85 #define RESTORE_U_PCB_FPSR(reg, offs, base) \
   86         REG_L   reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   87 
   88 #define SAVE_U_PCB_CONTEXT(reg, offs, base) \
   89         REG_S   reg, U_PCB_CONTEXT + (SZREG * offs) (base)
   90 
   91 #define RESTORE_U_PCB_CONTEXT(reg, offs, base) \
   92         REG_L   reg, U_PCB_CONTEXT + (SZREG * offs) (base)
   93 
   94 /*
   95  * Setup for and return to user.
   96  */
   97 LEAF(fork_trampoline)
   98         move    a0,s0
   99         move    a1,s1
  100         jal     _C_LABEL(fork_exit)
  101         move    a2,s2                     #BDSlot
  102 
  103         DO_AST
  104 
  105         mfc0    v0, MIPS_COP_0_STATUS
  106         and     v0, ~(MIPS_SR_INT_IE)
  107         mtc0    v0, MIPS_COP_0_STATUS   # disable interrupts
  108         COP0_SYNC
  109 /*
  110  * The use of k1 for storing the PCB pointer must be done only
  111  * after interrupts are disabled.  Otherwise it will get overwritten
  112  * by the interrupt code.
  113  */
  114         .set    noat
  115         GET_CPU_PCPU(k1)
  116         PTR_L   k1, PC_CURPCB(k1)
  117 
  118         RESTORE_U_PCB_REG(t0, MULLO, k1)
  119         RESTORE_U_PCB_REG(t1, MULHI, k1)
  120         mtlo    t0
  121         mthi    t1
  122         RESTORE_U_PCB_REG(a0, PC, k1)
  123         RESTORE_U_PCB_REG(AT, AST, k1)
  124         RESTORE_U_PCB_REG(v0, V0, k1)
  125         MTC0    a0, MIPS_COP_0_EXC_PC   # set return address
  126 
  127         RESTORE_U_PCB_REG(v1, V1, k1)
  128         RESTORE_U_PCB_REG(a0, A0, k1)
  129         RESTORE_U_PCB_REG(a1, A1, k1)
  130         RESTORE_U_PCB_REG(a2, A2, k1)
  131         RESTORE_U_PCB_REG(a3, A3, k1)
  132         RESTORE_U_PCB_REG(t0, T0, k1)
  133         RESTORE_U_PCB_REG(t1, T1, k1)
  134         RESTORE_U_PCB_REG(t2, T2, k1)
  135         RESTORE_U_PCB_REG(t3, T3, k1)
  136         RESTORE_U_PCB_REG(ta0, TA0, k1)
  137         RESTORE_U_PCB_REG(ta1, TA1, k1)
  138         RESTORE_U_PCB_REG(ta2, TA2, k1)
  139         RESTORE_U_PCB_REG(ta3, TA3, k1)
  140         RESTORE_U_PCB_REG(s0, S0, k1)
  141         RESTORE_U_PCB_REG(s1, S1, k1)
  142         RESTORE_U_PCB_REG(s2, S2, k1)
  143         RESTORE_U_PCB_REG(s3, S3, k1)
  144         RESTORE_U_PCB_REG(s4, S4, k1)
  145         RESTORE_U_PCB_REG(s5, S5, k1)
  146         RESTORE_U_PCB_REG(s6, S6, k1)
  147         RESTORE_U_PCB_REG(s7, S7, k1)
  148         RESTORE_U_PCB_REG(t8, T8, k1)
  149         RESTORE_U_PCB_REG(t9, T9, k1)
  150         RESTORE_U_PCB_REG(k0, SR, k1)
  151         RESTORE_U_PCB_REG(gp, GP, k1)
  152         RESTORE_U_PCB_REG(s8, S8, k1)
  153         RESTORE_U_PCB_REG(ra, RA, k1)
  154         RESTORE_U_PCB_REG(sp, SP, k1)
  155         li      k1, ~MIPS_SR_INT_MASK
  156         and     k0, k0, k1
  157         mfc0    k1, MIPS_COP_0_STATUS
  158         and     k1, k1, MIPS_SR_INT_MASK
  159         or      k0, k0, k1
  160         mtc0    k0, MIPS_COP_0_STATUS   # switch to user mode (when eret...)
  161         HAZARD_DELAY
  162         sync
  163         eret
  164         .set    at
  165 END(fork_trampoline)
  166 
  167 /*
  168  * Update pcb, saving current processor state.
  169  * Note: this only works if pcbp != curproc's pcb since
  170  * cpu_switch() will copy over pcb_context.
  171  *
  172  *      savectx(struct pcb *pcbp);
  173  */
  174 LEAF(savectx)
  175         SAVE_U_PCB_CONTEXT(s0, PREG_S0, a0)
  176         SAVE_U_PCB_CONTEXT(s1, PREG_S1, a0)
  177         SAVE_U_PCB_CONTEXT(s2, PREG_S2, a0)
  178         SAVE_U_PCB_CONTEXT(s3, PREG_S3, a0)
  179         mfc0    v0, MIPS_COP_0_STATUS
  180         SAVE_U_PCB_CONTEXT(s4, PREG_S4, a0)
  181         SAVE_U_PCB_CONTEXT(s5, PREG_S5, a0)
  182         SAVE_U_PCB_CONTEXT(s6, PREG_S6, a0)
  183         SAVE_U_PCB_CONTEXT(s7, PREG_S7, a0)
  184         SAVE_U_PCB_CONTEXT(sp, PREG_SP, a0)
  185         SAVE_U_PCB_CONTEXT(s8, PREG_S8, a0)
  186         SAVE_U_PCB_CONTEXT(ra, PREG_RA, a0)
  187         SAVE_U_PCB_CONTEXT(v0, PREG_SR, a0)
  188         SAVE_U_PCB_CONTEXT(gp, PREG_GP, a0)
  189 
  190         move    v0, ra                  /* save 'ra' before we trash it */
  191         jal     1f
  192         nop
  193 1:
  194         SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0)
  195         move    ra, v0                  /* restore 'ra' before returning */
  196 
  197         /*
  198          * FREEBSD_DEVELOPERS_FIXME:
  199          * In case there are CPU-specific registers that need
  200          * to be saved with the other registers do so here.
  201          */
  202         j       ra
  203         move    v0, zero
  204 END(savectx)
  205 
  206 NON_LEAF(cpu_throw, CALLFRAME_SIZ, ra)
  207         mfc0    t0, MIPS_COP_0_STATUS           # t0 = saved status register
  208         nop
  209         nop
  210         and     a3, t0, ~(MIPS_SR_INT_IE)
  211         mtc0    a3, MIPS_COP_0_STATUS           # Disable all interrupts
  212         ITLBNOPFIX
  213         j       mips_sw1                        # We're not interested in old 
  214                                                 # thread's context, so jump 
  215                                                 # right to action
  216         nop                                     # BDSLOT
  217 END(cpu_throw)
  218 
  219 /*
  220  * cpu_switch(struct thread *old, struct thread *new, struct mutex *mtx);
  221  *      a0 - old
  222  *      a1 - new
  223  *      a2 - mtx
  224  * Find the highest priority process and resume it.
  225  */
  226 NON_LEAF(cpu_switch, CALLFRAME_SIZ, ra)
  227         mfc0    t0, MIPS_COP_0_STATUS           # t0 = saved status register
  228         nop
  229         nop
  230         and     a3, t0, ~(MIPS_SR_INT_IE)       
  231         mtc0    a3, MIPS_COP_0_STATUS           # Disable all interrupts
  232         ITLBNOPFIX
  233         beqz    a0, mips_sw1
  234         move    a3, a0
  235         PTR_L   a0, TD_PCB(a0)          # load PCB addr of curproc
  236         SAVE_U_PCB_CONTEXT(sp, PREG_SP, a0)             # save old sp
  237         PTR_SUBU        sp, sp, CALLFRAME_SIZ
  238         REG_S   ra, CALLFRAME_RA(sp)
  239         .mask   0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
  240         SAVE_U_PCB_CONTEXT(s0, PREG_S0, a0)             # do a 'savectx()'
  241         SAVE_U_PCB_CONTEXT(s1, PREG_S1, a0)
  242         SAVE_U_PCB_CONTEXT(s2, PREG_S2, a0)
  243         SAVE_U_PCB_CONTEXT(s3, PREG_S3, a0)
  244         SAVE_U_PCB_CONTEXT(s4, PREG_S4, a0)
  245         SAVE_U_PCB_CONTEXT(s5, PREG_S5, a0)
  246         SAVE_U_PCB_CONTEXT(s6, PREG_S6, a0)
  247         SAVE_U_PCB_CONTEXT(s7, PREG_S7, a0)
  248         SAVE_U_PCB_CONTEXT(s8, PREG_S8, a0)
  249         SAVE_U_PCB_CONTEXT(ra, PREG_RA, a0)             # save return address
  250         SAVE_U_PCB_CONTEXT(t0, PREG_SR, a0)             # save status register
  251         SAVE_U_PCB_CONTEXT(gp, PREG_GP, a0)
  252         jal     getpc
  253         nop
  254 getpc:
  255         SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0)             # save return address
  256         /*
  257          * FREEBSD_DEVELOPERS_FIXME:
  258          * In case there are CPU-specific registers that need
  259          * to be saved with the other registers do so here.
  260          */
  261 
  262         PTR_S   a2, TD_LOCK(a3)                 # Switchout td_lock 
  263 
  264 mips_sw1:
  265 #if defined(SMP) && defined(SCHED_ULE)
  266         PTR_LA  t0, _C_LABEL(blocked_lock)
  267 blocked_loop:
  268         PTR_L   t1, TD_LOCK(a1)
  269         beq     t0, t1, blocked_loop
  270         nop
  271 #endif
  272         move    s7, a1  # Store newthread
  273 /*
  274  * Switch to new context.
  275  */
  276         GET_CPU_PCPU(a3)
  277         PTR_S   a1, PC_CURTHREAD(a3)
  278         PTR_L   a2, TD_PCB(a1)
  279         PTR_S   a2, PC_CURPCB(a3)
  280         PTR_L   v0, TD_KSTACK(a1)
  281 #if defined(__mips_n64)
  282         PTR_LI  s0, MIPS_XKSEG_START
  283 #else
  284         PTR_LI  s0, MIPS_KSEG2_START            # If Uarea addr is below kseg2,
  285 #endif
  286         bltu    v0, s0, sw2                     # no need to insert in TLB.
  287         lw      a1, TD_UPTE + 0(s7)             # a1 = u. pte #0
  288         lw      a2, TD_UPTE + 4(s7)             # a2 = u. pte #1
  289 /*
  290  * Wiredown the USPACE of newproc in TLB entry#0.  Check whether target
  291  * USPACE is already in another place of TLB before that, and if so
  292  * invalidate that TLB entry.
  293  * NOTE: This is hard coded to UPAGES == 2.
  294  * Also, there should be no TLB faults at this point.
  295  */
  296         MTC0    v0, MIPS_COP_0_TLB_HI           # VPN = va
  297         HAZARD_DELAY
  298         tlbp                                    # probe VPN
  299         HAZARD_DELAY
  300         mfc0    s0, MIPS_COP_0_TLB_INDEX
  301         HAZARD_DELAY
  302 
  303         PTR_LI  t1, MIPS_KSEG0_START            # invalidate tlb entry
  304         bltz    s0, entry0set
  305         nop
  306         sll     s0, PAGE_SHIFT + 1
  307         addu    t1, s0
  308         MTC0    t1, MIPS_COP_0_TLB_HI
  309         mtc0    zero, MIPS_COP_0_TLB_LO0
  310         mtc0    zero, MIPS_COP_0_TLB_LO1
  311         HAZARD_DELAY
  312         tlbwi
  313         HAZARD_DELAY
  314         MTC0    v0, MIPS_COP_0_TLB_HI           # set VPN again
  315 
  316 entry0set:
  317 /* SMP!! - Works only for  unshared TLB case - i.e. no v-cpus */
  318         mtc0    zero, MIPS_COP_0_TLB_INDEX              # TLB entry #0
  319         HAZARD_DELAY
  320         mtc0    a1, MIPS_COP_0_TLB_LO0          # upte[0]
  321         HAZARD_DELAY
  322         mtc0    a2, MIPS_COP_0_TLB_LO1          # upte[1]
  323         HAZARD_DELAY
  324         tlbwi                                   # set TLB entry #0
  325         HAZARD_DELAY
  326 /*
  327  * Now running on new u struct.
  328  */
  329 sw2:
  330         PTR_LA  t1, _C_LABEL(pmap_activate)     # s7 = new proc pointer
  331         jalr    t1                              # s7 = new proc pointer
  332         move    a0, s7                          # BDSLOT
  333 /*
  334  * Restore registers and return.
  335  */
  336         PTR_L   a0, TD_PCB(s7)
  337         RESTORE_U_PCB_CONTEXT(gp, PREG_GP, a0)
  338         RESTORE_U_PCB_CONTEXT(v0, PREG_SR, a0)  # restore kernel context
  339         RESTORE_U_PCB_CONTEXT(ra, PREG_RA, a0)
  340         RESTORE_U_PCB_CONTEXT(s0, PREG_S0, a0)
  341         RESTORE_U_PCB_CONTEXT(s1, PREG_S1, a0)
  342         RESTORE_U_PCB_CONTEXT(s2, PREG_S2, a0)
  343         RESTORE_U_PCB_CONTEXT(s3, PREG_S3, a0)
  344         RESTORE_U_PCB_CONTEXT(s4, PREG_S4, a0)
  345         RESTORE_U_PCB_CONTEXT(s5, PREG_S5, a0)
  346         RESTORE_U_PCB_CONTEXT(s6, PREG_S6, a0)
  347         RESTORE_U_PCB_CONTEXT(s7, PREG_S7, a0)
  348         RESTORE_U_PCB_CONTEXT(sp, PREG_SP, a0)
  349         RESTORE_U_PCB_CONTEXT(s8, PREG_S8, a0)
  350         /*
  351          * FREEBSD_DEVELOPERS_FIXME:
  352          * In case there are CPU-specific registers that need
  353          * to be restored with the other registers do so here.
  354          */
  355         mfc0    t0, MIPS_COP_0_STATUS
  356         and     t0, t0, MIPS_SR_INT_MASK
  357         and     v0, v0, ~MIPS_SR_INT_MASK
  358         or      v0, v0, t0
  359         mtc0    v0, MIPS_COP_0_STATUS
  360         ITLBNOPFIX
  361 
  362         j       ra
  363         nop
  364 END(cpu_switch)
  365 
  366 /*----------------------------------------------------------------------------
  367  *
  368  * MipsSwitchFPState --
  369  *
  370  *      Save the current state into 'from' and restore it from 'to'.
  371  *
  372  *      MipsSwitchFPState(from, to)
  373  *              struct thread *from;
  374  *              struct trapframe *to;
  375  *
  376  * Results:
  377  *      None.
  378  *
  379  * Side effects:
  380  *      None.
  381  *
  382  *----------------------------------------------------------------------------
  383  */
  384 LEAF(MipsSwitchFPState)
  385         mfc0    t1, MIPS_COP_0_STATUS   # Save old SR
  386         li      t0, MIPS_SR_COP_1_BIT   # enable the coprocessor
  387         mtc0    t0, MIPS_COP_0_STATUS
  388         ITLBNOPFIX
  389 
  390         beq     a0, zero, 1f            # skip save if NULL pointer
  391         nop
  392 /*
  393  * First read out the status register to make sure that all FP operations
  394  * have completed.
  395  */
  396         PTR_L   a0, TD_PCB(a0)                  # get pointer to pcb for proc
  397         cfc1    t0, MIPS_FPU_CSR                # stall til FP done
  398         cfc1    t0, MIPS_FPU_CSR                # now get status
  399         li      t3, ~MIPS_SR_COP_1_BIT
  400         RESTORE_U_PCB_REG(t2, PS, a0)           # get CPU status register
  401         SAVE_U_PCB_FPSR(t0, FSR_NUM, a0)        # save FP status
  402         and     t2, t2, t3                      # clear COP_1 enable bit
  403         SAVE_U_PCB_REG(t2, PS, a0)              # save new status register
  404 /*
  405  * Save the floating point registers.
  406  */
  407         SAVE_U_PCB_FPREG($f0, F0_NUM, a0)
  408         SAVE_U_PCB_FPREG($f1, F1_NUM, a0)
  409         SAVE_U_PCB_FPREG($f2, F2_NUM, a0)
  410         SAVE_U_PCB_FPREG($f3, F3_NUM, a0)
  411         SAVE_U_PCB_FPREG($f4, F4_NUM, a0)
  412         SAVE_U_PCB_FPREG($f5, F5_NUM, a0)
  413         SAVE_U_PCB_FPREG($f6, F6_NUM, a0)
  414         SAVE_U_PCB_FPREG($f7, F7_NUM, a0)
  415         SAVE_U_PCB_FPREG($f8, F8_NUM, a0)
  416         SAVE_U_PCB_FPREG($f9, F9_NUM, a0)
  417         SAVE_U_PCB_FPREG($f10, F10_NUM, a0)
  418         SAVE_U_PCB_FPREG($f11, F11_NUM, a0)
  419         SAVE_U_PCB_FPREG($f12, F12_NUM, a0)
  420         SAVE_U_PCB_FPREG($f13, F13_NUM, a0)
  421         SAVE_U_PCB_FPREG($f14, F14_NUM, a0)
  422         SAVE_U_PCB_FPREG($f15, F15_NUM, a0)
  423         SAVE_U_PCB_FPREG($f16, F16_NUM, a0)
  424         SAVE_U_PCB_FPREG($f17, F17_NUM, a0)
  425         SAVE_U_PCB_FPREG($f18, F18_NUM, a0)
  426         SAVE_U_PCB_FPREG($f19, F19_NUM, a0)
  427         SAVE_U_PCB_FPREG($f20, F20_NUM, a0)
  428         SAVE_U_PCB_FPREG($f21, F21_NUM, a0)
  429         SAVE_U_PCB_FPREG($f22, F22_NUM, a0)
  430         SAVE_U_PCB_FPREG($f23, F23_NUM, a0)
  431         SAVE_U_PCB_FPREG($f24, F24_NUM, a0)
  432         SAVE_U_PCB_FPREG($f25, F25_NUM, a0)
  433         SAVE_U_PCB_FPREG($f26, F26_NUM, a0)
  434         SAVE_U_PCB_FPREG($f27, F27_NUM, a0)
  435         SAVE_U_PCB_FPREG($f28, F28_NUM, a0)
  436         SAVE_U_PCB_FPREG($f29, F29_NUM, a0)
  437         SAVE_U_PCB_FPREG($f30, F30_NUM, a0)
  438         SAVE_U_PCB_FPREG($f31, F31_NUM, a0)
  439 
  440 1:
  441 /*
  442  *  Restore the floating point registers.
  443  */
  444         RESTORE_U_PCB_FPSR(t0, FSR_NUM, a1)     # get status register
  445         RESTORE_U_PCB_FPREG($f0, F0_NUM, a1)
  446         RESTORE_U_PCB_FPREG($f1, F1_NUM, a1)
  447         RESTORE_U_PCB_FPREG($f2, F2_NUM, a1)
  448         RESTORE_U_PCB_FPREG($f3, F3_NUM, a1)
  449         RESTORE_U_PCB_FPREG($f4, F4_NUM, a1)
  450         RESTORE_U_PCB_FPREG($f5, F5_NUM, a1)
  451         RESTORE_U_PCB_FPREG($f6, F6_NUM, a1)
  452         RESTORE_U_PCB_FPREG($f7, F7_NUM, a1)
  453         RESTORE_U_PCB_FPREG($f8, F8_NUM, a1)
  454         RESTORE_U_PCB_FPREG($f9, F9_NUM, a1)
  455         RESTORE_U_PCB_FPREG($f10, F10_NUM, a1)
  456         RESTORE_U_PCB_FPREG($f11, F11_NUM, a1)
  457         RESTORE_U_PCB_FPREG($f12, F12_NUM, a1)
  458         RESTORE_U_PCB_FPREG($f13, F13_NUM, a1)
  459         RESTORE_U_PCB_FPREG($f14, F14_NUM, a1)
  460         RESTORE_U_PCB_FPREG($f15, F15_NUM, a1)
  461         RESTORE_U_PCB_FPREG($f16, F16_NUM, a1)
  462         RESTORE_U_PCB_FPREG($f17, F17_NUM, a1)
  463         RESTORE_U_PCB_FPREG($f18, F18_NUM, a1)
  464         RESTORE_U_PCB_FPREG($f19, F19_NUM, a1)
  465         RESTORE_U_PCB_FPREG($f20, F20_NUM, a1)
  466         RESTORE_U_PCB_FPREG($f21, F21_NUM, a1)
  467         RESTORE_U_PCB_FPREG($f22, F22_NUM, a1)
  468         RESTORE_U_PCB_FPREG($f23, F23_NUM, a1)
  469         RESTORE_U_PCB_FPREG($f24, F24_NUM, a1)
  470         RESTORE_U_PCB_FPREG($f25, F25_NUM, a1)
  471         RESTORE_U_PCB_FPREG($f26, F26_NUM, a1)
  472         RESTORE_U_PCB_FPREG($f27, F27_NUM, a1)
  473         RESTORE_U_PCB_FPREG($f28, F28_NUM, a1)
  474         RESTORE_U_PCB_FPREG($f29, F29_NUM, a1)
  475         RESTORE_U_PCB_FPREG($f30, F30_NUM, a1)
  476         RESTORE_U_PCB_FPREG($f31, F31_NUM, a1)
  477 
  478         and     t0, t0, ~MIPS_FPU_EXCEPTION_BITS
  479         ctc1    t0, MIPS_FPU_CSR
  480         nop
  481 
  482         mtc0    t1, MIPS_COP_0_STATUS           # Restore the status register.
  483         ITLBNOPFIX
  484         j       ra
  485         nop
  486 END(MipsSwitchFPState)
  487 
  488 /*----------------------------------------------------------------------------
  489  *
  490  * MipsSaveCurFPState --
  491  *
  492  *      Save the current floating point coprocessor state.
  493  *
  494  *      MipsSaveCurFPState(td)
  495  *              struct thread *td;
  496  *
  497  * Results:
  498  *      None.
  499  *
  500  * Side effects:
  501  *      machFPCurProcPtr is cleared.
  502  *
  503  *----------------------------------------------------------------------------
  504  */
  505 LEAF(MipsSaveCurFPState)
  506         PTR_L   a0, TD_PCB(a0)                  # get pointer to pcb for thread
  507         mfc0    t1, MIPS_COP_0_STATUS           # Disable interrupts and
  508         li      t0, MIPS_SR_COP_1_BIT           #  enable the coprocessor
  509         mtc0    t0, MIPS_COP_0_STATUS
  510         ITLBNOPFIX
  511         GET_CPU_PCPU(a1)
  512         PTR_S   zero, PC_FPCURTHREAD(a1)        # indicate state has been saved
  513 /*
  514  * First read out the status register to make sure that all FP operations
  515  * have completed.
  516  */
  517         RESTORE_U_PCB_REG(t2, PS, a0)           # get CPU status register
  518         li      t3, ~MIPS_SR_COP_1_BIT
  519         and     t2, t2, t3                      # clear COP_1 enable bit
  520         cfc1    t0, MIPS_FPU_CSR                # stall til FP done
  521         cfc1    t0, MIPS_FPU_CSR                # now get status
  522         SAVE_U_PCB_REG(t2, PS, a0)              # save new status register
  523         SAVE_U_PCB_FPSR(t0, FSR_NUM, a0)        # save FP status
  524 /*
  525  * Save the floating point registers.
  526  */
  527         SAVE_U_PCB_FPREG($f0, F0_NUM, a0)
  528         SAVE_U_PCB_FPREG($f1, F1_NUM, a0)
  529         SAVE_U_PCB_FPREG($f2, F2_NUM, a0)
  530         SAVE_U_PCB_FPREG($f3, F3_NUM, a0)
  531         SAVE_U_PCB_FPREG($f4, F4_NUM, a0)
  532         SAVE_U_PCB_FPREG($f5, F5_NUM, a0)
  533         SAVE_U_PCB_FPREG($f6, F6_NUM, a0)
  534         SAVE_U_PCB_FPREG($f7, F7_NUM, a0)
  535         SAVE_U_PCB_FPREG($f8, F8_NUM, a0)
  536         SAVE_U_PCB_FPREG($f9, F9_NUM, a0)
  537         SAVE_U_PCB_FPREG($f10, F10_NUM, a0)
  538         SAVE_U_PCB_FPREG($f11, F11_NUM, a0)
  539         SAVE_U_PCB_FPREG($f12, F12_NUM, a0)
  540         SAVE_U_PCB_FPREG($f13, F13_NUM, a0)
  541         SAVE_U_PCB_FPREG($f14, F14_NUM, a0)
  542         SAVE_U_PCB_FPREG($f15, F15_NUM, a0)
  543         SAVE_U_PCB_FPREG($f16, F16_NUM, a0)
  544         SAVE_U_PCB_FPREG($f17, F17_NUM, a0)
  545         SAVE_U_PCB_FPREG($f18, F18_NUM, a0)
  546         SAVE_U_PCB_FPREG($f19, F19_NUM, a0)
  547         SAVE_U_PCB_FPREG($f20, F20_NUM, a0)
  548         SAVE_U_PCB_FPREG($f21, F21_NUM, a0)
  549         SAVE_U_PCB_FPREG($f22, F22_NUM, a0)
  550         SAVE_U_PCB_FPREG($f23, F23_NUM, a0)
  551         SAVE_U_PCB_FPREG($f24, F24_NUM, a0)
  552         SAVE_U_PCB_FPREG($f25, F25_NUM, a0)
  553         SAVE_U_PCB_FPREG($f26, F26_NUM, a0)
  554         SAVE_U_PCB_FPREG($f27, F27_NUM, a0)
  555         SAVE_U_PCB_FPREG($f28, F28_NUM, a0)
  556         SAVE_U_PCB_FPREG($f29, F29_NUM, a0)
  557         SAVE_U_PCB_FPREG($f30, F30_NUM, a0)
  558         SAVE_U_PCB_FPREG($f31, F31_NUM, a0)
  559 
  560         mtc0    t1, MIPS_COP_0_STATUS           # Restore the status register.
  561         ITLBNOPFIX
  562         j       ra
  563         nop
  564 END(MipsSaveCurFPState)
  565 
  566 /*
  567  * When starting init, call this to configure the process for user
  568  * mode.  This will be inherited by other processes.
  569  */
  570 LEAF_NOPROFILE(prepare_usermode)
  571         j       ra
  572         nop
  573 END(prepare_usermode)
  574 
  575 
  576 /*
  577  * This code is copied the user's stack for returning from signal handlers
  578  * (see sendsig() and sigreturn()). We have to compute the address
  579  * of the sigcontext struct for the sigreturn call.
  580  */
  581         .globl  _C_LABEL(sigcode)
  582 _C_LABEL(sigcode):
  583         PTR_ADDU        a0, sp, SIGF_UC         # address of ucontext
  584         li              v0, SYS_sigreturn
  585 # sigreturn (ucp)
  586         syscall
  587         break   0                               # just in case sigreturn fails
  588         .globl  _C_LABEL(esigcode)
  589 _C_LABEL(esigcode):
  590 
  591         .data
  592         .globl  szsigcode
  593 szsigcode:
  594         .long   esigcode-sigcode
  595         .text

Cache object: 88bb3e1d3d7e98570460524e7610b8d9


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