Import 2.3.9pre5
[davej-history.git] / arch / mips / kernel / r2300_switch.S
blob28252d3befc70745aebbdcf9b78c79a04cf1c7b4
1 /* $Id: r2300_switch.S,v 1.6 1999/06/13 16:30:32 ralf Exp $
2  *
3  * r2300_switch.S: R2300 specific task switching code.
4  *
5  * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle
6  * Copyright (C) 1994, 1995, 1996 by Andreas Busse
7  *
8  * Multi-cpu abstraction and macros for easier reading:
9  * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
10  *
11  * Further modifications to make this work:
12  * Copyright (c) 1998 Harald Koerfgen
13  */
14 #include <asm/asm.h>
15 #include <asm/bootinfo.h>
16 #include <asm/cachectl.h>
17 #include <asm/current.h>
18 #include <asm/fpregdef.h>
19 #include <asm/mipsconfig.h>
20 #include <asm/mipsregs.h>
21 #include <asm/offset.h>
22 #include <asm/page.h>
23 #include <asm/pgtable.h>
24 #include <asm/processor.h>
25 #include <asm/regdef.h>
26 #include <asm/stackframe.h>
28 #include <asm/asmmacro.h>
30         .set    mips1
31         .align  5
34  * task_struct *r4xx0_resume(task_struct *prev,
35  *                           task_struct *next)
36  */
37 LEAF(r2300_resume)
38         .set    reorder
39         mfc0    t1, CP0_STATUS
40         .set    noreorder
41         sw      t1, THREAD_STATUS(a0)
42         CPU_SAVE_NONSCRATCH(a0)
43         sw      ra, THREAD_REG31(a0)
45         /*
46          * The order of restoring the registers takes care of the race
47          * updating $28, $29 and kernelsp without disabling ints.
48          */
49         move    $28, a1
50         CPU_RESTORE_NONSCRATCH($28)
51         addiu   t0, $28, KERNEL_STACK_SIZE-32
52         sw      t0, kernelsp
53         mfc0    t1, CP0_STATUS          /* Do we really need this? */
54         li      a3, 0xff00
55         and     t1, a3
56         lw      a2, THREAD_STATUS($28)
57         nor     a3, $0, a3
58         and     a2, a3
59         lw      a3, TASK_MM($28)
60         or      a2, t1
61         lw      a3, MM_CONTEXT(a3)
62         mtc0    a2, CP0_STATUS
63         andi    a3, 0xfc0
64         mtc0    a3, CP0_ENTRYHI
65         jr      ra
66          move   v0, a0
67         END(r2300_resume)
70  * Do lazy fpu context switch.  Saves FPU context to the process in a0
71  * and loads the new context of the current process.
72  */
74 #define ST_OFF (KERNEL_STACK_SIZE - 32 - PT_SIZE + PT_STATUS)
76 LEAF(r2300_lazy_fpu_switch)
77         mfc0    t0, CP0_STATUS                  # enable cp1
78         li      t3, 0x20000000
79         or      t0, t3
80         mtc0    t0, CP0_STATUS
82         beqz    a0, 2f                          # Save floating point state
83          nor    t3, zero, t3
84         .set    reorder
85         lw      t1, ST_OFF(a0)                  # last thread looses fpu
86         .set    noreorder
87         and     t1, t3
88         sw      t1, ST_OFF(a0)
89         swc1    $f0, (THREAD_FPU + 0x00)(a0)
90         FPU_SAVE(a0, t1)                        # clobbers t1
93         lwc1    $f0, (THREAD_FPU + 0x00)($28)
94         .set    reorder
95         FPU_RESTORE($28, t0)            # clobbers t0
96         jr      ra
97         END(r2300_lazy_fpu_switch)
100  * Save a thread's fp context.
101  */
102         .set    noreorder
103 LEAF(r2300_save_fp)
104         FPU_SAVE(a0, t1)                        # clobbers t1
105         jr      ra
106          swc1   $f0, (THREAD_FPU + 0x00)(a0)
107         END(r2300_save_fp)
110  * Load the FPU with signalling NANS.  This bit pattern we're using has
111  * the property that no matter wether considered as single or as double
112  * precission represents signaling NANS.
114  * We initialize fcr31 to rounding to nearest, no exceptions.
115  */
117 #define FPU_DEFAULT  0x00000000
119 LEAF(r2300_init_fpu)
120         mfc0    t0, CP0_STATUS
121         li      t1, 0x20000000
122         or      t0, t1
123         mtc0    t0, CP0_STATUS
125         li      t1, FPU_DEFAULT
126         ctc1    t1, fcr31
128         li      t0, -1
130         mtc1    t0, $f0
131         mtc1    t0, $f1
132         mtc1    t0, $f2
133         mtc1    t0, $f3
134         mtc1    t0, $f4
135         mtc1    t0, $f5
136         mtc1    t0, $f6
137         mtc1    t0, $f7
138         mtc1    t0, $f8
139         mtc1    t0, $f9
140         mtc1    t0, $f10
141         mtc1    t0, $f11
142         mtc1    t0, $f12
143         mtc1    t0, $f13
144         mtc1    t0, $f14
145         mtc1    t0, $f15
146         mtc1    t0, $f16
147         mtc1    t0, $f17
148         mtc1    t0, $f18
149         mtc1    t0, $f19
150         mtc1    t0, $f20
151         mtc1    t0, $f21
152         mtc1    t0, $f22
153         mtc1    t0, $f23
154         mtc1    t0, $f24
155         mtc1    t0, $f25
156         mtc1    t0, $f26
157         mtc1    t0, $f27
158         mtc1    t0, $f28
159         mtc1    t0, $f29
160         mtc1    t0, $f30
161         jr      ra
162          mtc1   t0, $f31
163         END(r2300_init_fpu)