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-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 /*      $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/10.2/sys/mips/mips/swtch.S 249901 2013-04-25 17:23:54Z imp $
   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_compat.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 #include <machine/pcb.h>
   66 
   67 #include "assym.s"
   68 
   69         .set    noreorder                       # Noreorder is default style!
   70 
   71 #define SAVE_U_PCB_REG(reg, offs, base) \
   72         REG_S   reg, U_PCB_REGS + (SZREG * offs) (base)
   73 
   74 #define RESTORE_U_PCB_REG(reg, offs, base) \
   75         REG_L   reg, U_PCB_REGS + (SZREG * offs) (base)
   76 
   77 #define SAVE_U_PCB_FPREG(reg, offs, base) \
   78         FP_S    reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   79 
   80 #define RESTORE_U_PCB_FPREG(reg, offs, base) \
   81         FP_L    reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   82 
   83 #define SAVE_U_PCB_FPSR(reg, offs, base) \
   84         REG_S   reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   85 
   86 #define RESTORE_U_PCB_FPSR(reg, offs, base) \
   87         REG_L   reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
   88 
   89 #define SAVE_U_PCB_CONTEXT(reg, offs, base) \
   90         REG_S   reg, U_PCB_CONTEXT + (SZREG * offs) (base)
   91 
   92 #define RESTORE_U_PCB_CONTEXT(reg, offs, base) \
   93         REG_L   reg, U_PCB_CONTEXT + (SZREG * offs) (base)
   94 
   95 
   96 /*
   97  * Setup for and return to user.
   98  */
   99 LEAF(fork_trampoline)
  100         move    a0,s0
  101         move    a1,s1
  102         jal     _C_LABEL(fork_exit)
  103         move    a2,s2                     #BDSlot
  104 
  105         DO_AST
  106 
  107         mfc0    v0, MIPS_COP_0_STATUS
  108         and     v0, ~(MIPS_SR_INT_IE)
  109         mtc0    v0, MIPS_COP_0_STATUS   # disable interrupts
  110         COP0_SYNC
  111 /*
  112  * The use of k1 for storing the PCB pointer must be done only
  113  * after interrupts are disabled.  Otherwise it will get overwritten
  114  * by the interrupt code.
  115  */
  116         .set    noat
  117         GET_CPU_PCPU(k1)
  118         PTR_L   k1, PC_CURPCB(k1)
  119 
  120         RESTORE_U_PCB_REG(t0, MULLO, k1)
  121         RESTORE_U_PCB_REG(t1, MULHI, k1)
  122         mtlo    t0
  123         mthi    t1
  124         RESTORE_U_PCB_REG(a0, PC, k1)
  125         RESTORE_U_PCB_REG(AT, AST, k1)
  126         RESTORE_U_PCB_REG(v0, V0, k1)
  127         MTC0    a0, MIPS_COP_0_EXC_PC   # set return address
  128 
  129         RESTORE_U_PCB_REG(v1, V1, k1)
  130         RESTORE_U_PCB_REG(a0, A0, k1)
  131         RESTORE_U_PCB_REG(a1, A1, k1)
  132         RESTORE_U_PCB_REG(a2, A2, k1)
  133         RESTORE_U_PCB_REG(a3, A3, k1)
  134         RESTORE_U_PCB_REG(t0, T0, k1)
  135         RESTORE_U_PCB_REG(t1, T1, k1)
  136         RESTORE_U_PCB_REG(t2, T2, k1)
  137         RESTORE_U_PCB_REG(t3, T3, k1)
  138         RESTORE_U_PCB_REG(ta0, TA0, k1)
  139         RESTORE_U_PCB_REG(ta1, TA1, k1)
  140         RESTORE_U_PCB_REG(ta2, TA2, k1)
  141         RESTORE_U_PCB_REG(ta3, TA3, k1)
  142         RESTORE_U_PCB_REG(s0, S0, k1)
  143         RESTORE_U_PCB_REG(s1, S1, k1)
  144         RESTORE_U_PCB_REG(s2, S2, k1)
  145         RESTORE_U_PCB_REG(s3, S3, k1)
  146         RESTORE_U_PCB_REG(s4, S4, k1)
  147         RESTORE_U_PCB_REG(s5, S5, k1)
  148         RESTORE_U_PCB_REG(s6, S6, k1)
  149         RESTORE_U_PCB_REG(s7, S7, k1)
  150         RESTORE_U_PCB_REG(t8, T8, k1)
  151         RESTORE_U_PCB_REG(t9, T9, k1)
  152         RESTORE_U_PCB_REG(k0, SR, k1)
  153         RESTORE_U_PCB_REG(gp, GP, k1)
  154         RESTORE_U_PCB_REG(s8, S8, k1)
  155         RESTORE_U_PCB_REG(ra, RA, k1)
  156         RESTORE_U_PCB_REG(sp, SP, k1)
  157         li      k1, ~MIPS_SR_INT_MASK
  158         and     k0, k0, k1
  159         mfc0    k1, MIPS_COP_0_STATUS
  160         and     k1, k1, MIPS_SR_INT_MASK
  161         or      k0, k0, k1
  162         mtc0    k0, MIPS_COP_0_STATUS   # switch to user mode (when eret...)
  163         HAZARD_DELAY
  164         sync
  165         eret
  166         .set    at
  167 END(fork_trampoline)
  168 
  169 /*
  170  * Update pcb, saving current processor state.
  171  * Note: this only works if pcbp != curproc's pcb since
  172  * cpu_switch() will copy over pcb_context.
  173  *
  174  *      savectx(struct pcb *pcbp);
  175  */
  176 LEAF(savectx)
  177         SAVE_U_PCB_CONTEXT(s0, PCB_REG_S0, a0)
  178         SAVE_U_PCB_CONTEXT(s1, PCB_REG_S1, a0)
  179         SAVE_U_PCB_CONTEXT(s2, PCB_REG_S2, a0)
  180         SAVE_U_PCB_CONTEXT(s3, PCB_REG_S3, a0)
  181         mfc0    v0, MIPS_COP_0_STATUS
  182         SAVE_U_PCB_CONTEXT(s4, PCB_REG_S4, a0)
  183         SAVE_U_PCB_CONTEXT(s5, PCB_REG_S5, a0)
  184         SAVE_U_PCB_CONTEXT(s6, PCB_REG_S6, a0)
  185         SAVE_U_PCB_CONTEXT(s7, PCB_REG_S7, a0)
  186         SAVE_U_PCB_CONTEXT(sp, PCB_REG_SP, a0)
  187         SAVE_U_PCB_CONTEXT(s8, PCB_REG_S8, a0)
  188         SAVE_U_PCB_CONTEXT(ra, PCB_REG_RA, a0)
  189         SAVE_U_PCB_CONTEXT(v0, PCB_REG_SR, a0)
  190         SAVE_U_PCB_CONTEXT(gp, PCB_REG_GP, a0)
  191 
  192         move    v0, ra                  /* save 'ra' before we trash it */
  193         jal     1f
  194         nop
  195 1:
  196         SAVE_U_PCB_CONTEXT(ra, PCB_REG_PC, a0)
  197         move    ra, v0                  /* restore 'ra' before returning */
  198 
  199         j       ra
  200         move    v0, zero
  201 END(savectx)
  202 
  203 NON_LEAF(cpu_throw, CALLFRAME_SIZ, ra)
  204         mfc0    t0, MIPS_COP_0_STATUS           # t0 = saved status register
  205         nop
  206         nop
  207         and     a3, t0, ~(MIPS_SR_INT_IE)
  208         mtc0    a3, MIPS_COP_0_STATUS           # Disable all interrupts
  209         ITLBNOPFIX
  210         j       mips_sw1                        # We're not interested in old 
  211                                                 # thread's context, so jump 
  212                                                 # right to action
  213         nop                                     # BDSLOT
  214 END(cpu_throw)
  215 
  216 /*
  217  * cpu_switch(struct thread *old, struct thread *new, struct mutex *mtx);
  218  *      a0 - old
  219  *      a1 - new
  220  *      a2 - mtx
  221  * Find the highest priority process and resume it.
  222  */
  223 NON_LEAF(cpu_switch, CALLFRAME_SIZ, ra)
  224         mfc0    t0, MIPS_COP_0_STATUS           # t0 = saved status register
  225         nop
  226         nop
  227         and     a3, t0, ~(MIPS_SR_INT_IE)       
  228         mtc0    a3, MIPS_COP_0_STATUS           # Disable all interrupts
  229         ITLBNOPFIX
  230         beqz    a0, mips_sw1
  231         move    a3, a0
  232         PTR_L   a0, TD_PCB(a0)          # load PCB addr of curproc
  233         SAVE_U_PCB_CONTEXT(sp, PCB_REG_SP, a0)          # save old sp
  234         PTR_SUBU        sp, sp, CALLFRAME_SIZ
  235         REG_S   ra, CALLFRAME_RA(sp)
  236         .mask   0x80000000, (CALLFRAME_RA - CALLFRAME_SIZ)
  237         SAVE_U_PCB_CONTEXT(s0, PCB_REG_S0, a0)          # do a 'savectx()'
  238         SAVE_U_PCB_CONTEXT(s1, PCB_REG_S1, a0)
  239         SAVE_U_PCB_CONTEXT(s2, PCB_REG_S2, a0)
  240         SAVE_U_PCB_CONTEXT(s3, PCB_REG_S3, a0)
  241         SAVE_U_PCB_CONTEXT(s4, PCB_REG_S4, a0)
  242         SAVE_U_PCB_CONTEXT(s5, PCB_REG_S5, a0)
  243         SAVE_U_PCB_CONTEXT(s6, PCB_REG_S6, a0)
  244         SAVE_U_PCB_CONTEXT(s7, PCB_REG_S7, a0)
  245         SAVE_U_PCB_CONTEXT(s8, PCB_REG_S8, a0)
  246         SAVE_U_PCB_CONTEXT(ra, PCB_REG_RA, a0)          # save return address
  247         SAVE_U_PCB_CONTEXT(t0, PCB_REG_SR, a0)          # save status register
  248         SAVE_U_PCB_CONTEXT(gp, PCB_REG_GP, a0)
  249         jal     getpc
  250         nop
  251 getpc:
  252         SAVE_U_PCB_CONTEXT(ra, PCB_REG_PC, a0)          # save return address
  253 
  254 #ifdef CPU_CNMIPS
  255 
  256         lw      t2, TD_MDFLAGS(a3)              # get md_flags
  257         and     t1, t2, MDTD_COP2USED
  258         beqz    t1, cop2_untouched
  259         nop
  260 
  261         /* Clear cop2used flag */
  262         and     t2, t2, ~MDTD_COP2USED
  263         sw      t2, TD_MDFLAGS(a3)
  264 
  265         and     t2, t0, ~MIPS_SR_COP_2_BIT      # clear COP_2 enable bit
  266         SAVE_U_PCB_CONTEXT(t2, PCB_REG_SR, a0)  # save status register
  267 
  268         RESTORE_U_PCB_REG(t0, PS, a0)           # get CPU status register
  269         and     t2, t0, ~MIPS_SR_COP_2_BIT      # clear COP_2 enable bit
  270         SAVE_U_PCB_REG(t2, PS, a0)              # save stratus register
  271 
  272         /* preserve a0..a3 */
  273         move    s0, a0
  274         move    s1, a1
  275         move    s2, a2
  276         move    s3, a3
  277 
  278         /* does kernel own COP2 context? */
  279         lw      t1, TD_COP2OWNER(a3)            # get md_cop2owner
  280         beqz    t1, userland_cop2               # 0 - it's userland context
  281         nop
  282 
  283         PTR_L   a0, TD_COP2(a3)
  284         beqz    a0, no_cop2_context
  285         nop
  286 
  287         j       do_cop2_save
  288         nop
  289 
  290 userland_cop2:
  291 
  292         PTR_L   a0, TD_UCOP2(a3)
  293         beqz    a0, no_cop2_context
  294         nop
  295 
  296 do_cop2_save:
  297         jal     octeon_cop2_save
  298         nop
  299 
  300 no_cop2_context:
  301         move    a3, s3
  302         move    a2, s2
  303         move    a1, s1
  304         move    a0, s0
  305 
  306 cop2_untouched:
  307 #endif
  308 
  309         PTR_S   a2, TD_LOCK(a3)                 # Switchout td_lock 
  310 
  311 mips_sw1:
  312 #if defined(SMP) && defined(SCHED_ULE)
  313         PTR_LA  t0, _C_LABEL(blocked_lock)
  314 blocked_loop:
  315         PTR_L   t1, TD_LOCK(a1)
  316         beq     t0, t1, blocked_loop
  317         nop
  318 #endif
  319         move    s7, a1  # Store newthread
  320 /*
  321  * Switch to new context.
  322  */
  323         GET_CPU_PCPU(a3)
  324         PTR_S   a1, PC_CURTHREAD(a3)
  325         PTR_L   a2, TD_PCB(a1)
  326         PTR_S   a2, PC_CURPCB(a3)
  327         PTR_L   v0, TD_KSTACK(a1)
  328 #if defined(__mips_n64)
  329         PTR_LI  s0, MIPS_XKSEG_START
  330 #else
  331         PTR_LI  s0, MIPS_KSEG2_START            # If Uarea addr is below kseg2,
  332 #endif
  333         bltu    v0, s0, sw2                     # no need to insert in TLB.
  334         PTE_L   a1, TD_UPTE + 0(s7)             # a1 = u. pte #0
  335         PTE_L   a2, TD_UPTE + PTESIZE(s7)       # a2 = u. pte #1
  336 /*
  337  * Wiredown the USPACE of newproc in TLB entry#0.  Check whether target
  338  * USPACE is already in another place of TLB before that, and if so
  339  * invalidate that TLB entry.
  340  * NOTE: This is hard coded to UPAGES == 2.
  341  * Also, there should be no TLB faults at this point.
  342  */
  343         MTC0    v0, MIPS_COP_0_TLB_HI           # VPN = va
  344         HAZARD_DELAY
  345         tlbp                                    # probe VPN
  346         HAZARD_DELAY
  347         mfc0    s0, MIPS_COP_0_TLB_INDEX
  348         HAZARD_DELAY
  349 
  350         PTR_LI  t1, MIPS_KSEG0_START            # invalidate tlb entry
  351         bltz    s0, entry0set
  352         nop
  353         sll     s0, PAGE_SHIFT + 1
  354         addu    t1, s0
  355         MTC0    t1, MIPS_COP_0_TLB_HI
  356         PTE_MTC0        zero, MIPS_COP_0_TLB_LO0
  357         PTE_MTC0        zero, MIPS_COP_0_TLB_LO1
  358         HAZARD_DELAY
  359         tlbwi
  360         HAZARD_DELAY
  361         MTC0    v0, MIPS_COP_0_TLB_HI           # set VPN again
  362 
  363 entry0set:
  364 /* SMP!! - Works only for  unshared TLB case - i.e. no v-cpus */
  365         mtc0    zero, MIPS_COP_0_TLB_INDEX              # TLB entry #0
  366         HAZARD_DELAY
  367         PTE_MTC0        a1, MIPS_COP_0_TLB_LO0          # upte[0]
  368         HAZARD_DELAY
  369         PTE_MTC0        a2, MIPS_COP_0_TLB_LO1          # upte[1]
  370         HAZARD_DELAY
  371         tlbwi                                   # set TLB entry #0
  372         HAZARD_DELAY
  373 /*
  374  * Now running on new u struct.
  375  */
  376 sw2:
  377         PTR_L   s0, TD_PCB(s7)
  378         RESTORE_U_PCB_CONTEXT(sp, PCB_REG_SP, s0)
  379         PTR_LA  t1, _C_LABEL(pmap_activate)     # s7 = new proc pointer
  380         jalr    t1                              # s7 = new proc pointer
  381         move    a0, s7                          # BDSLOT
  382 /*
  383  * Restore registers and return.
  384  */
  385         move    a0, s0
  386         RESTORE_U_PCB_CONTEXT(gp, PCB_REG_GP, a0)
  387         RESTORE_U_PCB_CONTEXT(v0, PCB_REG_SR, a0)       # restore kernel context
  388         RESTORE_U_PCB_CONTEXT(ra, PCB_REG_RA, a0)
  389         RESTORE_U_PCB_CONTEXT(s0, PCB_REG_S0, a0)
  390         RESTORE_U_PCB_CONTEXT(s1, PCB_REG_S1, a0)
  391         RESTORE_U_PCB_CONTEXT(s2, PCB_REG_S2, a0)
  392         RESTORE_U_PCB_CONTEXT(s3, PCB_REG_S3, a0)
  393         RESTORE_U_PCB_CONTEXT(s4, PCB_REG_S4, a0)
  394         RESTORE_U_PCB_CONTEXT(s5, PCB_REG_S5, a0)
  395         RESTORE_U_PCB_CONTEXT(s6, PCB_REG_S6, a0)
  396         RESTORE_U_PCB_CONTEXT(s7, PCB_REG_S7, a0)
  397         RESTORE_U_PCB_CONTEXT(s8, PCB_REG_S8, a0)
  398 
  399         mfc0    t0, MIPS_COP_0_STATUS
  400         and     t0, t0, MIPS_SR_INT_MASK
  401         and     v0, v0, ~MIPS_SR_INT_MASK
  402         or      v0, v0, t0
  403         mtc0    v0, MIPS_COP_0_STATUS
  404         ITLBNOPFIX
  405 
  406         j       ra
  407         nop
  408 END(cpu_switch)
  409 
  410 /*----------------------------------------------------------------------------
  411  *
  412  * MipsSwitchFPState --
  413  *
  414  *      Save the current state into 'from' and restore it from 'to'.
  415  *
  416  *      MipsSwitchFPState(from, to)
  417  *              struct thread *from;
  418  *              struct trapframe *to;
  419  *
  420  * Results:
  421  *      None.
  422  *
  423  * Side effects:
  424  *      None.
  425  *
  426  *----------------------------------------------------------------------------
  427  */
  428 LEAF(MipsSwitchFPState)
  429         mfc0    t1, MIPS_COP_0_STATUS   # Save old SR
  430         li      t0, MIPS_SR_COP_1_BIT   # enable the coprocessor
  431         mtc0    t0, MIPS_COP_0_STATUS
  432         ITLBNOPFIX
  433 
  434         beq     a0, zero, 1f            # skip save if NULL pointer
  435         nop
  436 /*
  437  * First read out the status register to make sure that all FP operations
  438  * have completed.
  439  */
  440         PTR_L   a0, TD_PCB(a0)                  # get pointer to pcb for proc
  441         cfc1    t0, MIPS_FPU_CSR                # stall til FP done
  442         cfc1    t0, MIPS_FPU_CSR                # now get status
  443         li      t3, ~MIPS_SR_COP_1_BIT
  444         RESTORE_U_PCB_REG(t2, PS, a0)           # get CPU status register
  445         SAVE_U_PCB_FPSR(t0, FSR_NUM, a0)        # save FP status
  446         and     t2, t2, t3                      # clear COP_1 enable bit
  447         SAVE_U_PCB_REG(t2, PS, a0)              # save new status register
  448 /*
  449  * Save the floating point registers.
  450  */
  451         SAVE_U_PCB_FPREG($f0, F0_NUM, a0)
  452         SAVE_U_PCB_FPREG($f1, F1_NUM, a0)
  453         SAVE_U_PCB_FPREG($f2, F2_NUM, a0)
  454         SAVE_U_PCB_FPREG($f3, F3_NUM, a0)
  455         SAVE_U_PCB_FPREG($f4, F4_NUM, a0)
  456         SAVE_U_PCB_FPREG($f5, F5_NUM, a0)
  457         SAVE_U_PCB_FPREG($f6, F6_NUM, a0)
  458         SAVE_U_PCB_FPREG($f7, F7_NUM, a0)
  459         SAVE_U_PCB_FPREG($f8, F8_NUM, a0)
  460         SAVE_U_PCB_FPREG($f9, F9_NUM, a0)
  461         SAVE_U_PCB_FPREG($f10, F10_NUM, a0)
  462         SAVE_U_PCB_FPREG($f11, F11_NUM, a0)
  463         SAVE_U_PCB_FPREG($f12, F12_NUM, a0)
  464         SAVE_U_PCB_FPREG($f13, F13_NUM, a0)
  465         SAVE_U_PCB_FPREG($f14, F14_NUM, a0)
  466         SAVE_U_PCB_FPREG($f15, F15_NUM, a0)
  467         SAVE_U_PCB_FPREG($f16, F16_NUM, a0)
  468         SAVE_U_PCB_FPREG($f17, F17_NUM, a0)
  469         SAVE_U_PCB_FPREG($f18, F18_NUM, a0)
  470         SAVE_U_PCB_FPREG($f19, F19_NUM, a0)
  471         SAVE_U_PCB_FPREG($f20, F20_NUM, a0)
  472         SAVE_U_PCB_FPREG($f21, F21_NUM, a0)
  473         SAVE_U_PCB_FPREG($f22, F22_NUM, a0)
  474         SAVE_U_PCB_FPREG($f23, F23_NUM, a0)
  475         SAVE_U_PCB_FPREG($f24, F24_NUM, a0)
  476         SAVE_U_PCB_FPREG($f25, F25_NUM, a0)
  477         SAVE_U_PCB_FPREG($f26, F26_NUM, a0)
  478         SAVE_U_PCB_FPREG($f27, F27_NUM, a0)
  479         SAVE_U_PCB_FPREG($f28, F28_NUM, a0)
  480         SAVE_U_PCB_FPREG($f29, F29_NUM, a0)
  481         SAVE_U_PCB_FPREG($f30, F30_NUM, a0)
  482         SAVE_U_PCB_FPREG($f31, F31_NUM, a0)
  483 
  484 1:
  485 /*
  486  *  Restore the floating point registers.
  487  */
  488         RESTORE_U_PCB_FPSR(t0, FSR_NUM, a1)     # get status register
  489         RESTORE_U_PCB_FPREG($f0, F0_NUM, a1)
  490         RESTORE_U_PCB_FPREG($f1, F1_NUM, a1)
  491         RESTORE_U_PCB_FPREG($f2, F2_NUM, a1)
  492         RESTORE_U_PCB_FPREG($f3, F3_NUM, a1)
  493         RESTORE_U_PCB_FPREG($f4, F4_NUM, a1)
  494         RESTORE_U_PCB_FPREG($f5, F5_NUM, a1)
  495         RESTORE_U_PCB_FPREG($f6, F6_NUM, a1)
  496         RESTORE_U_PCB_FPREG($f7, F7_NUM, a1)
  497         RESTORE_U_PCB_FPREG($f8, F8_NUM, a1)
  498         RESTORE_U_PCB_FPREG($f9, F9_NUM, a1)
  499         RESTORE_U_PCB_FPREG($f10, F10_NUM, a1)
  500         RESTORE_U_PCB_FPREG($f11, F11_NUM, a1)
  501         RESTORE_U_PCB_FPREG($f12, F12_NUM, a1)
  502         RESTORE_U_PCB_FPREG($f13, F13_NUM, a1)
  503         RESTORE_U_PCB_FPREG($f14, F14_NUM, a1)
  504         RESTORE_U_PCB_FPREG($f15, F15_NUM, a1)
  505         RESTORE_U_PCB_FPREG($f16, F16_NUM, a1)
  506         RESTORE_U_PCB_FPREG($f17, F17_NUM, a1)
  507         RESTORE_U_PCB_FPREG($f18, F18_NUM, a1)
  508         RESTORE_U_PCB_FPREG($f19, F19_NUM, a1)
  509         RESTORE_U_PCB_FPREG($f20, F20_NUM, a1)
  510         RESTORE_U_PCB_FPREG($f21, F21_NUM, a1)
  511         RESTORE_U_PCB_FPREG($f22, F22_NUM, a1)
  512         RESTORE_U_PCB_FPREG($f23, F23_NUM, a1)
  513         RESTORE_U_PCB_FPREG($f24, F24_NUM, a1)
  514         RESTORE_U_PCB_FPREG($f25, F25_NUM, a1)
  515         RESTORE_U_PCB_FPREG($f26, F26_NUM, a1)
  516         RESTORE_U_PCB_FPREG($f27, F27_NUM, a1)
  517         RESTORE_U_PCB_FPREG($f28, F28_NUM, a1)
  518         RESTORE_U_PCB_FPREG($f29, F29_NUM, a1)
  519         RESTORE_U_PCB_FPREG($f30, F30_NUM, a1)
  520         RESTORE_U_PCB_FPREG($f31, F31_NUM, a1)
  521 
  522         and     t0, t0, ~MIPS_FPU_EXCEPTION_BITS
  523         ctc1    t0, MIPS_FPU_CSR
  524         nop
  525 
  526         mtc0    t1, MIPS_COP_0_STATUS           # Restore the status register.
  527         ITLBNOPFIX
  528         j       ra
  529         nop
  530 END(MipsSwitchFPState)
  531 
  532 /*----------------------------------------------------------------------------
  533  *
  534  * MipsSaveCurFPState --
  535  *
  536  *      Save the current floating point coprocessor state.
  537  *
  538  *      MipsSaveCurFPState(td)
  539  *              struct thread *td;
  540  *
  541  * Results:
  542  *      None.
  543  *
  544  * Side effects:
  545  *      machFPCurProcPtr is cleared.
  546  *
  547  *----------------------------------------------------------------------------
  548  */
  549 LEAF(MipsSaveCurFPState)
  550         PTR_L   a0, TD_PCB(a0)                  # get pointer to pcb for thread
  551         mfc0    t1, MIPS_COP_0_STATUS           # Disable interrupts and
  552         li      t0, MIPS_SR_COP_1_BIT           #  enable the coprocessor
  553         mtc0    t0, MIPS_COP_0_STATUS
  554         ITLBNOPFIX
  555         GET_CPU_PCPU(a1)
  556         PTR_S   zero, PC_FPCURTHREAD(a1)        # indicate state has been saved
  557 /*
  558  * First read out the status register to make sure that all FP operations
  559  * have completed.
  560  */
  561         RESTORE_U_PCB_REG(t2, PS, a0)           # get CPU status register
  562         li      t3, ~MIPS_SR_COP_1_BIT
  563         and     t2, t2, t3                      # clear COP_1 enable bit
  564         cfc1    t0, MIPS_FPU_CSR                # stall til FP done
  565         cfc1    t0, MIPS_FPU_CSR                # now get status
  566         SAVE_U_PCB_REG(t2, PS, a0)              # save new status register
  567         SAVE_U_PCB_FPSR(t0, FSR_NUM, a0)        # save FP status
  568 /*
  569  * Save the floating point registers.
  570  */
  571         SAVE_U_PCB_FPREG($f0, F0_NUM, a0)
  572         SAVE_U_PCB_FPREG($f1, F1_NUM, a0)
  573         SAVE_U_PCB_FPREG($f2, F2_NUM, a0)
  574         SAVE_U_PCB_FPREG($f3, F3_NUM, a0)
  575         SAVE_U_PCB_FPREG($f4, F4_NUM, a0)
  576         SAVE_U_PCB_FPREG($f5, F5_NUM, a0)
  577         SAVE_U_PCB_FPREG($f6, F6_NUM, a0)
  578         SAVE_U_PCB_FPREG($f7, F7_NUM, a0)
  579         SAVE_U_PCB_FPREG($f8, F8_NUM, a0)
  580         SAVE_U_PCB_FPREG($f9, F9_NUM, a0)
  581         SAVE_U_PCB_FPREG($f10, F10_NUM, a0)
  582         SAVE_U_PCB_FPREG($f11, F11_NUM, a0)
  583         SAVE_U_PCB_FPREG($f12, F12_NUM, a0)
  584         SAVE_U_PCB_FPREG($f13, F13_NUM, a0)
  585         SAVE_U_PCB_FPREG($f14, F14_NUM, a0)
  586         SAVE_U_PCB_FPREG($f15, F15_NUM, a0)
  587         SAVE_U_PCB_FPREG($f16, F16_NUM, a0)
  588         SAVE_U_PCB_FPREG($f17, F17_NUM, a0)
  589         SAVE_U_PCB_FPREG($f18, F18_NUM, a0)
  590         SAVE_U_PCB_FPREG($f19, F19_NUM, a0)
  591         SAVE_U_PCB_FPREG($f20, F20_NUM, a0)
  592         SAVE_U_PCB_FPREG($f21, F21_NUM, a0)
  593         SAVE_U_PCB_FPREG($f22, F22_NUM, a0)
  594         SAVE_U_PCB_FPREG($f23, F23_NUM, a0)
  595         SAVE_U_PCB_FPREG($f24, F24_NUM, a0)
  596         SAVE_U_PCB_FPREG($f25, F25_NUM, a0)
  597         SAVE_U_PCB_FPREG($f26, F26_NUM, a0)
  598         SAVE_U_PCB_FPREG($f27, F27_NUM, a0)
  599         SAVE_U_PCB_FPREG($f28, F28_NUM, a0)
  600         SAVE_U_PCB_FPREG($f29, F29_NUM, a0)
  601         SAVE_U_PCB_FPREG($f30, F30_NUM, a0)
  602         SAVE_U_PCB_FPREG($f31, F31_NUM, a0)
  603 
  604         mtc0    t1, MIPS_COP_0_STATUS           # Restore the status register.
  605         ITLBNOPFIX
  606         j       ra
  607         nop
  608 END(MipsSaveCurFPState)
  609 
  610 /*
  611  * This code is copied the user's stack for returning from signal handlers
  612  * (see sendsig() and sigreturn()). We have to compute the address
  613  * of the sigcontext struct for the sigreturn call.
  614  */
  615         .globl  _C_LABEL(sigcode)
  616 _C_LABEL(sigcode):
  617         PTR_ADDU        a0, sp, SIGF_UC         # address of ucontext
  618         li              v0, SYS_sigreturn
  619 # sigreturn (ucp)
  620         syscall
  621         break   0                               # just in case sigreturn fails
  622         .globl  _C_LABEL(esigcode)
  623 _C_LABEL(esigcode):
  624 
  625         .data
  626         .globl  szsigcode
  627 szsigcode:
  628         .long   esigcode-sigcode
  629         .text
  630 
  631 #if (defined(__mips_n32) || defined(__mips_n64)) && defined(COMPAT_FREEBSD32)
  632         .globl  _C_LABEL(sigcode32)
  633 _C_LABEL(sigcode32):
  634         addu            a0, sp, SIGF32_UC       # address of ucontext
  635         li              v0, SYS_sigreturn
  636 # sigreturn (ucp)
  637         syscall
  638         break   0                               # just in case sigreturn fails
  639         .globl  _C_LABEL(esigcode32)
  640 _C_LABEL(esigcode32):
  641 
  642         .data
  643         .globl  szsigcode32
  644 szsigcode32:
  645         .long   esigcode32-sigcode32
  646         .text
  647 #endif

Cache object: 9001ab70c3ef7588a3d34efe10e76ef5


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