1 /* $OpenBSD: locore.S,v 1.18 1998/09/15 10:58:53 pefo Exp $ */
3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved.
6 * This code is derived from software contributed to Berkeley by
7 * Digital Equipment Corporation and Ralph Campbell.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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
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.
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)
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
54 * Contains code that is the first executed at boot time plus
55 * assembly language support routines.
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>
68 .set noreorder # Noreorder is default style!
70 #define SAVE_U_PCB_REG(reg, offs, base) \
71 REG_S reg, U_PCB_REGS + (SZREG * offs) (base)
73 #define RESTORE_U_PCB_REG(reg, offs, base) \
74 REG_L reg, U_PCB_REGS + (SZREG * offs) (base)
76 #define SAVE_U_PCB_FPREG(reg, offs, base) \
77 FP_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
79 #define RESTORE_U_PCB_FPREG(reg, offs, base) \
80 FP_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
82 #define SAVE_U_PCB_FPSR(reg, offs, base) \
83 REG_S reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
85 #define RESTORE_U_PCB_FPSR(reg, offs, base) \
86 REG_L reg, U_PCB_FPREGS + (SZFPREG * offs) (base)
88 #define SAVE_U_PCB_CONTEXT(reg, offs, base) \
89 REG_S reg, U_PCB_CONTEXT + (SZREG * offs) (base)
91 #define RESTORE_U_PCB_CONTEXT(reg, offs, base) \
92 REG_L reg, U_PCB_CONTEXT + (SZREG * offs) (base)
95 * Setup for and return to user.
100 jal _C_LABEL(fork_exit)
105 mfc0 v0, MIPS_COP_0_STATUS
106 and v0, ~(MIPS_SR_INT_IE)
107 mtc0 v0, MIPS_COP_0_STATUS # disable interrupts
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.
116 PTR_L k1, PC_CURPCB(k1)
118 RESTORE_U_PCB_REG(t0, MULLO, k1)
119 RESTORE_U_PCB_REG(t1, MULHI, k1)
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
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
157 mfc0 k1, MIPS_COP_0_STATUS
158 and k1, k1, MIPS_SR_INT_MASK
160 mtc0 k0, MIPS_COP_0_STATUS # switch to user mode (when eret...)
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.
172 * savectx(struct pcb *pcbp);
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)
190 move v0, ra /* save 'ra' before we trash it */
194 SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0)
195 move ra, v0 /* restore 'ra' before returning */
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.
206 NON_LEAF(cpu_throw, CALLFRAME_SIZ, ra)
207 mfc0 t0, MIPS_COP_0_STATUS # t0 = saved status register
210 and a3, t0, ~(MIPS_SR_INT_IE)
211 mtc0 a3, MIPS_COP_0_STATUS # Disable all interrupts
213 j mips_sw1 # We're not interested in old
214 # thread's context, so jump
220 * cpu_switch(struct thread *old, struct thread *new, struct mutex *mtx);
224 * Find the highest priority process and resume it.
226 NON_LEAF(cpu_switch, CALLFRAME_SIZ, ra)
227 mfc0 t0, MIPS_COP_0_STATUS # t0 = saved status register
230 and a3, t0, ~(MIPS_SR_INT_IE)
231 mtc0 a3, MIPS_COP_0_STATUS # Disable all interrupts
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)
255 SAVE_U_PCB_CONTEXT(ra, PREG_PC, a0) # save return address
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.
262 PTR_S a2, TD_LOCK(a3) # Switchout td_lock
265 #if defined(SMP) && defined(SCHED_ULE)
266 PTR_LA t0, _C_LABEL(blocked_lock)
268 PTR_L t1, TD_LOCK(a1)
269 beq t0, t1, blocked_loop
272 move s7, a1 # Store newthread
274 * Switch to new context.
277 PTR_S a1, PC_CURTHREAD(a3)
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
284 PTR_LI s0, MIPS_KSEG2_START # If Uarea addr is below kseg2,
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
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.
296 MTC0 v0, MIPS_COP_0_TLB_HI # VPN = va
300 mfc0 s0, MIPS_COP_0_TLB_INDEX
303 PTR_LI t1, MIPS_KSEG0_START # invalidate tlb entry
306 sll s0, PAGE_SHIFT + 1
308 MTC0 t1, MIPS_COP_0_TLB_HI
309 mtc0 zero, MIPS_COP_0_TLB_LO0
310 mtc0 zero, MIPS_COP_0_TLB_LO1
314 MTC0 v0, MIPS_COP_0_TLB_HI # set VPN again
317 /* SMP!! - Works only for unshared TLB case - i.e. no v-cpus */
318 mtc0 zero, MIPS_COP_0_TLB_INDEX # TLB entry #0
320 mtc0 a1, MIPS_COP_0_TLB_LO0 # upte[0]
322 mtc0 a2, MIPS_COP_0_TLB_LO1 # upte[1]
324 tlbwi # set TLB entry #0
327 * Now running on new u struct.
330 PTR_LA t1, _C_LABEL(pmap_activate) # s7 = new proc pointer
331 jalr t1 # s7 = new proc pointer
334 * Restore registers and return.
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)
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.
355 mfc0 t0, MIPS_COP_0_STATUS
356 and t0, t0, MIPS_SR_INT_MASK
357 and v0, v0, ~MIPS_SR_INT_MASK
359 mtc0 v0, MIPS_COP_0_STATUS
366 /*----------------------------------------------------------------------------
368 * MipsSwitchFPState --
370 * Save the current state into 'from' and restore it from 'to'.
372 * MipsSwitchFPState(from, to)
373 * struct thread *from;
374 * struct trapframe *to;
382 *----------------------------------------------------------------------------
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
390 beq a0, zero, 1f # skip save if NULL pointer
393 * First read out the status register to make sure that all FP operations
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
405 * Save the floating point registers.
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)
442 * Restore the floating point registers.
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)
478 and t0, t0, ~MIPS_FPU_EXCEPTION_BITS
479 ctc1 t0, MIPS_FPU_CSR
482 mtc0 t1, MIPS_COP_0_STATUS # Restore the status register.
486 END(MipsSwitchFPState)
488 /*----------------------------------------------------------------------------
490 * MipsSaveCurFPState --
492 * Save the current floating point coprocessor state.
494 * MipsSaveCurFPState(td)
501 * machFPCurProcPtr is cleared.
503 *----------------------------------------------------------------------------
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
512 PTR_S zero, PC_FPCURTHREAD(a1) # indicate state has been saved
514 * First read out the status register to make sure that all FP operations
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
525 * Save the floating point registers.
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)
560 mtc0 t1, MIPS_COP_0_STATUS # Restore the status register.
564 END(MipsSaveCurFPState)
567 * When starting init, call this to configure the process for user
568 * mode. This will be inherited by other processes.
570 LEAF_NOPROFILE(prepare_usermode)
573 END(prepare_usermode)
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.
581 .globl _C_LABEL(sigcode)
583 PTR_ADDU a0, sp, SIGF_UC # address of ucontext
587 break 0 # just in case sigreturn fails
588 .globl _C_LABEL(esigcode)
594 .long esigcode-sigcode