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/8.1/sys/mips/mips/swtch.S 178172 2008-04-13 07:27:37Z 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_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 #if defined(ISA_MIPS32)
   69 #undef WITH_64BIT_CP0
   70 #elif defined(ISA_MIPS64)
   71 #define WITH_64BIT_CP0
   72 #elif defined(ISA_MIPS3)
   73 #define WITH_64BIT_CP0
   74 #else
   75 #error "Please write the code for this ISA"
   76 #endif
   77 
   78 #ifdef WITH_64BIT_CP0
   79 #define _SLL    dsll
   80 #define _SRL    dsrl
   81 #define _MFC0   dmfc0
   82 #define _MTC0   dmtc0
   83 #define WIRED_SHIFT 34
   84 #define PAGE_SHIFT 34
   85 #else
   86 #define _SLL    sll
   87 #define _SRL    srl
   88 #define _MFC0   mfc0
   89 #define _MTC0   mtc0
   90 #define WIRED_SHIFT 2
   91 #define PAGE_SHIFT 2
   92 #endif
   93         .set    noreorder                       # Noreorder is default style!
   94 #if defined(ISA_MIPS32)
   95         .set    mips32
   96 #elif defined(ISA_MIPS64)
   97         .set    mips64
   98 #elif defined(ISA_MIPS3)
   99         .set    mips3
  100 #endif
  101 
  102 #if defined(ISA_MIPS32)
  103 #define STORE           sw              /* 32 bit mode regsave instruction */
  104 #define LOAD            lw              /* 32 bit mode regload instruction */
  105 #define RSIZE           4               /* 32 bit mode register size */
  106 #define STORE_FP        swc1            /* 32 bit mode fp regsave instruction */
  107 #define LOAD_FP         lwc1            /* 32 bit mode fp regload instruction */
  108 #define FP_RSIZE        4               /* 32 bit mode fp register size */
  109 #else
  110 #define STORE           sd              /* 64 bit mode regsave instruction */
  111 #define LOAD            ld              /* 64 bit mode regload instruction */
  112 #define RSIZE           8               /* 64 bit mode register size */
  113 #define STORE_FP        sdc1            /* 64 bit mode fp regsave instruction */
  114 #define LOAD_FP         ldc1            /* 64 bit mode fp regload instruction */
  115 #define FP_RSIZE        8               /* 64 bit mode fp register size */
  116 #endif
  117 
  118 /*
  119  * FREEBSD_DEVELOPERS_FIXME
  120  * Some MIPS CPU may need delays using nops between executing CP0 Instructions
  121  */
  122 
  123 #if 1
  124 #define HAZARD_DELAY                    nop ; nop ; nop ; nop
  125 #else
  126 #define HAZARD_DELAY
  127 #endif
  128 
  129 #define SAVE_U_PCB_REG(reg, offs, base) \
  130         STORE   reg, U_PCB_REGS + (RSIZE * offs) (base)
  131 
  132 #define RESTORE_U_PCB_REG(reg, offs, base) \
  133         LOAD    reg, U_PCB_REGS + (RSIZE * offs) (base)
  134 
  135 #define SAVE_U_PCB_FPREG(reg, offs, base) \
  136         STORE_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
  137 
  138 #define RESTORE_U_PCB_FPREG(reg, offs, base) \
  139         LOAD_FP reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
  140 
  141 #define SAVE_U_PCB_FPSR(reg, offs, base) \
  142         STORE   reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
  143 
  144 #define RESTORE_U_PCB_FPSR(reg, offs, base) \
  145         LOAD    reg, U_PCB_FPREGS + (FP_RSIZE * offs) (base)
  146 
  147 #define SAVE_U_PCB_CONTEXT(reg, offs, base) \
  148         STORE   reg, U_PCB_CONTEXT + (RSIZE * offs) (base)
  149 
  150 #define RESTORE_U_PCB_CONTEXT(reg, offs, base) \
  151         LOAD    reg, U_PCB_CONTEXT + (RSIZE * offs) (base)
  152 
  153 #define ITLBNOPFIX      nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;
  154 
  155 /*
  156  * Setup for and return to user.
  157  */
  158 LEAF(fork_trampoline)
  159         move    a0,s0
  160         move    a1,s1
  161         jal     _C_LABEL(fork_exit)
  162         move    a2,s2                     #BDSlot
  163 
  164         DO_AST
  165 
  166 /*
  167  * Since interrupts are enabled at this point, we use a1 instead of
  168  * k0 or k1 to store the PCB pointer.  This is because k0 and k1
  169  * are not preserved across interrupts.
  170  */
  171         GET_CPU_PCPU(a1)
  172         lw      a1, PC_CURPCB(a1)
  173 1:
  174 
  175         mfc0    v0, COP_0_STATUS_REG    # set exeption level bit.
  176         or      v0, SR_EXL
  177         and     v0, ~(SR_INT_ENAB)
  178         mtc0    v0, COP_0_STATUS_REG    # set exeption level bit.
  179         nop
  180         nop
  181         nop
  182         nop
  183         .set    noat
  184         move    k1, a1  
  185         RESTORE_U_PCB_REG(t0, MULLO, k1)
  186         RESTORE_U_PCB_REG(t1, MULHI, k1)
  187         mtlo    t0
  188         mthi    t1
  189         RESTORE_U_PCB_REG(a0, PC, k1)
  190         RESTORE_U_PCB_REG(AT, AST, k1)
  191         RESTORE_U_PCB_REG(v0, V0, k1)
  192         _MTC0   a0, COP_0_EXC_PC        # set return address
  193 
  194 /*
  195  * The use of k1 for storing the PCB pointer must be done only
  196  * after interrupts are disabled.  Otherwise it will get overwritten
  197  * by the interrupt code.
  198  */
  199         RESTORE_U_PCB_REG(v1, V1, k1)
  200         RESTORE_U_PCB_REG(a0, A0, k1)
  201         RESTORE_U_PCB_REG(a1, A1, k1)
  202         RESTORE_U_PCB_REG(a2, A2, k1)
  203         RESTORE_U_PCB_REG(a3, A3, k1)
  204         RESTORE_U_PCB_REG(t0, T0, k1)
  205         RESTORE_U_PCB_REG(t1, T1, k1)
  206         RESTORE_U_PCB_REG(t2, T2, k1)
  207         RESTORE_U_PCB_REG(t3, T3, k1)
  208         RESTORE_U_PCB_REG(t4, T4, k1)
  209         RESTORE_U_PCB_REG(t5, T5, k1)
  210         RESTORE_U_PCB_REG(t6, T6, k1)
  211         RESTORE_U_PCB_REG(t7, T7, k1)
  212         RESTORE_U_PCB_REG(s0, S0, k1)
  213         RESTORE_U_PCB_REG(s1, S1, k1)
  214         RESTORE_U_PCB_REG(s2, S2, k1)
  215         RESTORE_U_PCB_REG(s3, S3, k1)
  216         RESTORE_U_PCB_REG(s4, S4, k1)
  217         RESTORE_U_PCB_REG(s5, S5, k1)
  218         RESTORE_U_PCB_REG(s6, S6, k1)
  219         RESTORE_U_PCB_REG(s7, S7, k1)
  220         RESTORE_U_PCB_REG(t8, T8, k1)
  221         RESTORE_U_PCB_REG(t9, T9, k1)
  222         RESTORE_U_PCB_REG(k0, SR, k1)
  223         RESTORE_U_PCB_REG(gp, GP, k1)
  224         RESTORE_U_PCB_REG(s8, S8, k1)
  225         RESTORE_U_PCB_REG(ra, RA, k1)
  226         RESTORE_U_PCB_REG(sp, SP, k1)
  227         mtc0    k0, COP_0_STATUS_REG    # switch to user mode (when eret...)
  228         HAZARD_DELAY
  229         sync
  230         eret
  231         .set    at
  232 END(fork_trampoline)
  233 
  234 /*
  235  * Update pcb, saving current processor state.
  236  * Note: this only works if pcbp != curproc's pcb since
  237  * cpu_switch() will copy over pcb_context.
  238  *
  239  *      savectx(struct pcb *pcbp);
  240  */
  241 LEAF(savectx)
  242         SAVE_U_PCB_CONTEXT(s0, PREG_S0, a0)
  243         SAVE_U_PCB_CONTEXT(s1, PREG_S1, a0)
  244         SAVE_U_PCB_CONTEXT(s2, PREG_S2, a0)
  245         SAVE_U_PCB_CONTEXT(s3, PREG_S3, a0)
  246         mfc0    v0, COP_0_STATUS_REG
  247         SAVE_U_PCB_CONTEXT(s4, PREG_S4, a0)
  248         SAVE_U_PCB_CONTEXT(s5, PREG_S5, a0)
  249         SAVE_U_PCB_CONTEXT(s6, PREG_S6, a0)
  250         SAVE_U_PCB_CONTEXT(s7, PREG_S7, a0)
  251         SAVE_U_PCB_CONTEXT(sp, PREG_SP, a0)
  252         SAVE_U_PCB_CONTEXT(s8, PREG_S8, a0)
  253         SAVE_U_PCB_CONTEXT(ra, PREG_RA, a0)
  254         SAVE_U_PCB_CONTEXT(v0, PREG_SR, a0)
  255         SAVE_U_PCB_CONTEXT(gp, PREG_GP, a0)
  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         j       ra
  262         move    v0, zero
  263 END(savectx)
  264 
  265 
  266 KSEG0TEXT_START;
  267 
  268 NON_LEAF(mips_cpu_throw, STAND_FRAME_SIZE, ra)
  269         mfc0    t0, COP_0_STATUS_REG            # t0 = saved status register
  270         nop
  271         nop
  272         and     a3, t0, ~(SR_INT_ENAB)
  273         mtc0    a3, COP_0_STATUS_REG            # Disable all interrupts
  274         ITLBNOPFIX
  275         j       mips_sw1                        # We're not interested in old 
  276                                                 # thread's context, so jump 
  277                                                 # right to action
  278         nop                                     # BDSLOT
  279 END(mips_cpu_throw)
  280 
  281 /*
  282  *XXX Fixme:    should be written to new interface that requires lock
  283  *              storage.  We fake it for now.
  284  * cpu_switch(struct thread *old, struct thread *new);
  285  * Find the highest priority process and resume it.
  286  */
  287 NON_LEAF(cpu_switch, STAND_FRAME_SIZE, ra)
  288         mfc0    t0, COP_0_STATUS_REG            # t0 = saved status register
  289         nop
  290         nop
  291         and     a3, t0, ~(SR_INT_ENAB)  
  292         mtc0    a3, COP_0_STATUS_REG            # Disable all interrupts
  293         ITLBNOPFIX
  294         beqz    a0, mips_sw1
  295         move    a3, a0
  296         lw      a0, TD_PCB(a0)          # load PCB addr of curproc
  297         SAVE_U_PCB_CONTEXT(sp, PREG_SP, a0)             # save old sp
  298         subu    sp, sp, STAND_FRAME_SIZE
  299         sw      ra, STAND_RA_OFFSET(sp)
  300         .mask   0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
  301         SAVE_U_PCB_CONTEXT(s0, PREG_S0, a0)             # do a 'savectx()'
  302         SAVE_U_PCB_CONTEXT(s1, PREG_S1, a0)
  303         SAVE_U_PCB_CONTEXT(s2, PREG_S2, a0)
  304         SAVE_U_PCB_CONTEXT(s3, PREG_S3, a0)
  305         SAVE_U_PCB_CONTEXT(s4, PREG_S4, a0)
  306         SAVE_U_PCB_CONTEXT(s5, PREG_S5, a0)
  307         SAVE_U_PCB_CONTEXT(s6, PREG_S6, a0)
  308         SAVE_U_PCB_CONTEXT(s7, PREG_S7, a0)
  309         SAVE_U_PCB_CONTEXT(s8, PREG_S8, a0)
  310         SAVE_U_PCB_CONTEXT(ra, PREG_RA, a0)             # save return address
  311         SAVE_U_PCB_CONTEXT(t0, PREG_SR, a0)             # save status register
  312         SAVE_U_PCB_CONTEXT(gp, PREG_GP, a0)
  313         /*
  314          * FREEBSD_DEVELOPERS_FIXME:
  315          * In case there are CPU-specific registers that need
  316          * to be saved with the other registers do so here.
  317          */
  318 
  319         sw      a3, TD_LOCK(a0)                 # Switchout td_lock 
  320 
  321 mips_sw1:
  322 #if defined(SMP) && defined(SCHED_ULE)
  323         la      t0, _C_LABEL(blocked_lock)
  324 blocked_loop:
  325         lw      t1, TD_LOCK(a1)
  326         beq     t0, t1, blocked_loop
  327         nop
  328 #endif
  329         move    s7, a1  # Store newthread
  330 /*
  331  * Switch to new context.
  332  */
  333         GET_CPU_PCPU(a3)
  334         sw      a1, PC_CURTHREAD(a3)
  335         lw      a2, TD_PCB(a1)
  336         sw      a2, PC_CURPCB(a3)
  337         lw      v0, TD_REALKSTACK(a1)
  338         li      s0, (MIPS_KSEG2_START+VM_KERNEL_ALLOC_OFFSET)           # If Uarea addr is below kseg2,
  339         bltu    v0, s0, sw2                     # no need to insert in TLB.
  340         lw      a1, TD_UPTE+0(s7)               # t0 = first u. pte
  341         lw      a2, TD_UPTE+4(s7)               # t1 = 2nd u. pte
  342         and     s0, v0, PTE_ODDPG
  343         beq     s0, zero, entry0
  344         nop
  345 
  346         PANIC_KSEG0("USPACE sat on odd page boundary", t1)
  347 
  348 /*
  349  * Wiredown the USPACE of newproc in TLB entry#0.  Check whether target
  350  * USPACE is already in another place of TLB before that, and if so
  351  * invalidate that TLB entry.
  352  * NOTE: This is hard coded to UPAGES == 2.
  353  * Also, there should be no TLB faults at this point.
  354  */
  355 entry0:
  356         mtc0    v0, COP_0_TLB_HI                # VPN = va
  357         HAZARD_DELAY
  358         tlbp                                    # probe VPN
  359         HAZARD_DELAY
  360         mfc0    s0, COP_0_TLB_INDEX
  361         nop
  362 pgm:
  363         bltz    s0, entry0set
  364         li      t1, MIPS_KSEG0_START + 0x0fff0000       # invalidate tlb entry
  365         sll     s0, PAGE_SHIFT + 1
  366         addu    t1, s0
  367         mtc0    t1, COP_0_TLB_HI
  368         mtc0    zero, COP_0_TLB_LO0
  369         mtc0    zero, COP_0_TLB_LO1
  370         HAZARD_DELAY
  371         tlbwi
  372         HAZARD_DELAY
  373         mtc0    v0, COP_0_TLB_HI                # set VPN again
  374 entry0set:
  375 /* SMP!! - Works only for  unshared TLB case - i.e. no v-cpus */
  376         mtc0    zero, COP_0_TLB_INDEX           # TLB entry #0
  377 #       or      a1, PG_G
  378         mtc0    a1, COP_0_TLB_LO0               # upte[0]
  379 #       or      a2, PG_G
  380         mtc0    a2, COP_0_TLB_LO1               # upte[1]
  381         HAZARD_DELAY
  382         tlbwi                                   # set TLB entry #0
  383         HAZARD_DELAY
  384 /*
  385  * Now running on new u struct.
  386  */
  387 sw2:
  388         la      t1, _C_LABEL(pmap_activate)     # s7 = new proc pointer
  389         jalr    t1                              # s7 = new proc pointer
  390         move    a0, s7                          # BDSLOT
  391 /*
  392  * Restore registers and return.
  393  */
  394         lw      a0, TD_PCB(s7)
  395         RESTORE_U_PCB_CONTEXT(gp, PREG_GP, a0)
  396         RESTORE_U_PCB_CONTEXT(v0, PREG_SR, a0)  # restore kernel context
  397         RESTORE_U_PCB_CONTEXT(ra, PREG_RA, a0)
  398         RESTORE_U_PCB_CONTEXT(s0, PREG_S0, a0)
  399         RESTORE_U_PCB_CONTEXT(s1, PREG_S1, a0)
  400         RESTORE_U_PCB_CONTEXT(s2, PREG_S2, a0)
  401         RESTORE_U_PCB_CONTEXT(s3, PREG_S3, a0)
  402         RESTORE_U_PCB_CONTEXT(s4, PREG_S4, a0)
  403         RESTORE_U_PCB_CONTEXT(s5, PREG_S5, a0)
  404         RESTORE_U_PCB_CONTEXT(s6, PREG_S6, a0)
  405         RESTORE_U_PCB_CONTEXT(s7, PREG_S7, a0)
  406         RESTORE_U_PCB_CONTEXT(sp, PREG_SP, a0)
  407         RESTORE_U_PCB_CONTEXT(s8, PREG_S8, a0)
  408         /*
  409          * FREEBSD_DEVELOPERS_FIXME:
  410          * In case there are CPU-specific registers that need
  411          * to be restored with the other registers do so here.
  412          */
  413         mtc0    v0, COP_0_STATUS_REG
  414         ITLBNOPFIX
  415 
  416         j       ra
  417         nop
  418 END(cpu_switch)
  419 KSEG0TEXT_END;
  420 
  421 /*----------------------------------------------------------------------------
  422  *
  423  * MipsSwitchFPState --
  424  *
  425  *      Save the current state into 'from' and restore it from 'to'.
  426  *
  427  *      MipsSwitchFPState(from, to)
  428  *              struct thread *from;
  429  *              struct trapframe *to;
  430  *
  431  * Results:
  432  *      None.
  433  *
  434  * Side effects:
  435  *      None.
  436  *
  437  *----------------------------------------------------------------------------
  438  */
  439 LEAF(MipsSwitchFPState)
  440         mfc0    t1, COP_0_STATUS_REG    # Save old SR
  441         li      t0, SR_COP_1_BIT        # enable the coprocessor
  442         mtc0    t0, COP_0_STATUS_REG
  443         ITLBNOPFIX
  444 
  445         beq     a0, zero, 1f            # skip save if NULL pointer
  446         nop
  447 /*
  448  * First read out the status register to make sure that all FP operations
  449  * have completed.
  450  */
  451         lw      a0, TD_PCB(a0)                  # get pointer to pcb for proc
  452         cfc1    t0, FPC_CSR                     # stall til FP done
  453         cfc1    t0, FPC_CSR                     # now get status
  454         li      t3, ~SR_COP_1_BIT
  455         RESTORE_U_PCB_REG(t2, PS, a0)           # get CPU status register
  456         SAVE_U_PCB_FPSR(t0, FSR_NUM, a0)        # save FP status
  457         and     t2, t2, t3                      # clear COP_1 enable bit
  458         SAVE_U_PCB_REG(t2, PS, a0)              # save new status register
  459 /*
  460  * Save the floating point registers.
  461  */
  462         SAVE_U_PCB_FPREG($f0, F0_NUM, a0)
  463         SAVE_U_PCB_FPREG($f1, F1_NUM, a0)
  464         SAVE_U_PCB_FPREG($f2, F2_NUM, a0)
  465         SAVE_U_PCB_FPREG($f3, F3_NUM, a0)
  466         SAVE_U_PCB_FPREG($f4, F4_NUM, a0)
  467         SAVE_U_PCB_FPREG($f5, F5_NUM, a0)
  468         SAVE_U_PCB_FPREG($f6, F6_NUM, a0)
  469         SAVE_U_PCB_FPREG($f7, F7_NUM, a0)
  470         SAVE_U_PCB_FPREG($f8, F8_NUM, a0)
  471         SAVE_U_PCB_FPREG($f9, F9_NUM, a0)
  472         SAVE_U_PCB_FPREG($f10, F10_NUM, a0)
  473         SAVE_U_PCB_FPREG($f11, F11_NUM, a0)
  474         SAVE_U_PCB_FPREG($f12, F12_NUM, a0)
  475         SAVE_U_PCB_FPREG($f13, F13_NUM, a0)
  476         SAVE_U_PCB_FPREG($f14, F14_NUM, a0)
  477         SAVE_U_PCB_FPREG($f15, F15_NUM, a0)
  478         SAVE_U_PCB_FPREG($f16, F16_NUM, a0)
  479         SAVE_U_PCB_FPREG($f17, F17_NUM, a0)
  480         SAVE_U_PCB_FPREG($f18, F18_NUM, a0)
  481         SAVE_U_PCB_FPREG($f19, F19_NUM, a0)
  482         SAVE_U_PCB_FPREG($f20, F20_NUM, a0)
  483         SAVE_U_PCB_FPREG($f21, F21_NUM, a0)
  484         SAVE_U_PCB_FPREG($f22, F22_NUM, a0)
  485         SAVE_U_PCB_FPREG($f23, F23_NUM, a0)
  486         SAVE_U_PCB_FPREG($f24, F24_NUM, a0)
  487         SAVE_U_PCB_FPREG($f25, F25_NUM, a0)
  488         SAVE_U_PCB_FPREG($f26, F26_NUM, a0)
  489         SAVE_U_PCB_FPREG($f27, F27_NUM, a0)
  490         SAVE_U_PCB_FPREG($f28, F28_NUM, a0)
  491         SAVE_U_PCB_FPREG($f29, F29_NUM, a0)
  492         SAVE_U_PCB_FPREG($f30, F30_NUM, a0)
  493         SAVE_U_PCB_FPREG($f31, F31_NUM, a0)
  494 
  495 1:
  496 /*
  497  *  Restore the floating point registers.
  498  */
  499         RESTORE_U_PCB_FPSR(t0, FSR_NUM, a1)     # get status register
  500         RESTORE_U_PCB_FPREG($f0, F0_NUM, a1)
  501         RESTORE_U_PCB_FPREG($f1, F1_NUM, a1)
  502         RESTORE_U_PCB_FPREG($f2, F2_NUM, a1)
  503         RESTORE_U_PCB_FPREG($f3, F3_NUM, a1)
  504         RESTORE_U_PCB_FPREG($f4, F4_NUM, a1)
  505         RESTORE_U_PCB_FPREG($f5, F5_NUM, a1)
  506         RESTORE_U_PCB_FPREG($f6, F6_NUM, a1)
  507         RESTORE_U_PCB_FPREG($f7, F7_NUM, a1)
  508         RESTORE_U_PCB_FPREG($f8, F8_NUM, a1)
  509         RESTORE_U_PCB_FPREG($f9, F9_NUM, a1)
  510         RESTORE_U_PCB_FPREG($f10, F10_NUM, a1)
  511         RESTORE_U_PCB_FPREG($f11, F11_NUM, a1)
  512         RESTORE_U_PCB_FPREG($f12, F12_NUM, a1)
  513         RESTORE_U_PCB_FPREG($f13, F13_NUM, a1)
  514         RESTORE_U_PCB_FPREG($f14, F14_NUM, a1)
  515         RESTORE_U_PCB_FPREG($f15, F15_NUM, a1)
  516         RESTORE_U_PCB_FPREG($f16, F16_NUM, a1)
  517         RESTORE_U_PCB_FPREG($f17, F17_NUM, a1)
  518         RESTORE_U_PCB_FPREG($f18, F18_NUM, a1)
  519         RESTORE_U_PCB_FPREG($f19, F19_NUM, a1)
  520         RESTORE_U_PCB_FPREG($f20, F20_NUM, a1)
  521         RESTORE_U_PCB_FPREG($f21, F21_NUM, a1)
  522         RESTORE_U_PCB_FPREG($f22, F22_NUM, a1)
  523         RESTORE_U_PCB_FPREG($f23, F23_NUM, a1)
  524         RESTORE_U_PCB_FPREG($f24, F24_NUM, a1)
  525         RESTORE_U_PCB_FPREG($f25, F25_NUM, a1)
  526         RESTORE_U_PCB_FPREG($f26, F26_NUM, a1)
  527         RESTORE_U_PCB_FPREG($f27, F27_NUM, a1)
  528         RESTORE_U_PCB_FPREG($f28, F28_NUM, a1)
  529         RESTORE_U_PCB_FPREG($f29, F29_NUM, a1)
  530         RESTORE_U_PCB_FPREG($f30, F30_NUM, a1)
  531         RESTORE_U_PCB_FPREG($f31, F31_NUM, a1)
  532 
  533         and     t0, t0, ~FPC_EXCEPTION_BITS
  534         ctc1    t0, FPC_CSR
  535         nop
  536 
  537         mtc0    t1, COP_0_STATUS_REG            # Restore the status register.
  538         ITLBNOPFIX
  539         j       ra
  540         nop
  541 END(MipsSwitchFPState)
  542 
  543 /*----------------------------------------------------------------------------
  544  *
  545  * MipsSaveCurFPState --
  546  *
  547  *      Save the current floating point coprocessor state.
  548  *
  549  *      MipsSaveCurFPState(td)
  550  *              struct thread *td;
  551  *
  552  * Results:
  553  *      None.
  554  *
  555  * Side effects:
  556  *      machFPCurProcPtr is cleared.
  557  *
  558  *----------------------------------------------------------------------------
  559  */
  560 LEAF(MipsSaveCurFPState)
  561         lw      a0, TD_PCB(a0)                  # get pointer to pcb for thread
  562         mfc0    t1, COP_0_STATUS_REG            # Disable interrupts and
  563         li      t0, SR_COP_1_BIT                #  enable the coprocessor
  564         mtc0    t0, COP_0_STATUS_REG
  565         ITLBNOPFIX
  566         GET_CPU_PCPU(a1)
  567         sw      zero, PC_FPCURTHREAD(a1)        # indicate state has been saved
  568 /*
  569  * First read out the status register to make sure that all FP operations
  570  * have completed.
  571  */
  572         RESTORE_U_PCB_REG(t2, PS, a0)           # get CPU status register
  573         li      t3, ~SR_COP_1_BIT
  574         and     t2, t2, t3                      # clear COP_1 enable bit
  575         cfc1    t0, FPC_CSR                     # stall til FP done
  576         cfc1    t0, FPC_CSR                     # now get status
  577         SAVE_U_PCB_REG(t2, PS, a0)              # save new status register
  578         SAVE_U_PCB_FPSR(t0, FSR_NUM, a0)        # save FP status
  579 /*
  580  * Save the floating point registers.
  581  */
  582         SAVE_U_PCB_FPREG($f0, F0_NUM, a0)
  583         SAVE_U_PCB_FPREG($f1, F1_NUM, a0)
  584         SAVE_U_PCB_FPREG($f2, F2_NUM, a0)
  585         SAVE_U_PCB_FPREG($f3, F3_NUM, a0)
  586         SAVE_U_PCB_FPREG($f4, F4_NUM, a0)
  587         SAVE_U_PCB_FPREG($f5, F5_NUM, a0)
  588         SAVE_U_PCB_FPREG($f6, F6_NUM, a0)
  589         SAVE_U_PCB_FPREG($f7, F7_NUM, a0)
  590         SAVE_U_PCB_FPREG($f8, F8_NUM, a0)
  591         SAVE_U_PCB_FPREG($f9, F9_NUM, a0)
  592         SAVE_U_PCB_FPREG($f10, F10_NUM, a0)
  593         SAVE_U_PCB_FPREG($f11, F11_NUM, a0)
  594         SAVE_U_PCB_FPREG($f12, F12_NUM, a0)
  595         SAVE_U_PCB_FPREG($f13, F13_NUM, a0)
  596         SAVE_U_PCB_FPREG($f14, F14_NUM, a0)
  597         SAVE_U_PCB_FPREG($f15, F15_NUM, a0)
  598         SAVE_U_PCB_FPREG($f16, F16_NUM, a0)
  599         SAVE_U_PCB_FPREG($f17, F17_NUM, a0)
  600         SAVE_U_PCB_FPREG($f18, F18_NUM, a0)
  601         SAVE_U_PCB_FPREG($f19, F19_NUM, a0)
  602         SAVE_U_PCB_FPREG($f20, F20_NUM, a0)
  603         SAVE_U_PCB_FPREG($f21, F21_NUM, a0)
  604         SAVE_U_PCB_FPREG($f22, F22_NUM, a0)
  605         SAVE_U_PCB_FPREG($f23, F23_NUM, a0)
  606         SAVE_U_PCB_FPREG($f24, F24_NUM, a0)
  607         SAVE_U_PCB_FPREG($f25, F25_NUM, a0)
  608         SAVE_U_PCB_FPREG($f26, F26_NUM, a0)
  609         SAVE_U_PCB_FPREG($f27, F27_NUM, a0)
  610         SAVE_U_PCB_FPREG($f28, F28_NUM, a0)
  611         SAVE_U_PCB_FPREG($f29, F29_NUM, a0)
  612         SAVE_U_PCB_FPREG($f30, F30_NUM, a0)
  613         SAVE_U_PCB_FPREG($f31, F31_NUM, a0)
  614 
  615         mtc0    t1, COP_0_STATUS_REG            # Restore the status register.
  616         ITLBNOPFIX
  617         j       ra
  618         nop
  619 END(MipsSaveCurFPState)
  620 
  621 /*
  622  * When starting init, call this to configure the process for user
  623  * mode.  This will be inherited by other processes.
  624  */
  625 LEAF_NOPROFILE(prepare_usermode)
  626         j       ra
  627         nop
  628 END(prepare_usermode)
  629 
  630 
  631 /*
  632  * This code is copied the user's stack for returning from signal handlers
  633  * (see sendsig() and sigreturn()). We have to compute the address
  634  * of the sigcontext struct for the sigreturn call.
  635  */
  636         .globl  _C_LABEL(sigcode)
  637 _C_LABEL(sigcode):
  638         addu    a0, sp, SIGF_UC                 # address of ucontext
  639         li      v0, SYS_sigreturn
  640 # sigreturn (ucp)
  641         syscall
  642         break   0                               # just in case sigreturn fails
  643         .globl  _C_LABEL(esigcode)
  644 _C_LABEL(esigcode):
  645 
  646         .data
  647         .globl  szsigcode
  648 szsigcode:
  649         .long   esigcode-sigcode
  650         .text

Cache object: 0c56a8d006f71c049a36266098edb678


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