1 | /* |
---|
2 | * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation |
---|
3 | * |
---|
4 | * This program is free software; you can redistribute it and/or modify |
---|
5 | * it under the terms of the GNU General Public License as published by |
---|
6 | * the Free Software Foundation; either version 2 of the License, or |
---|
7 | * (at your option) any later version. |
---|
8 | * |
---|
9 | * This program is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
12 | * GNU General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU General Public License |
---|
15 | * along with this program; if not, write to the Free Software |
---|
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
17 | */ |
---|
18 | |
---|
19 | #include <asm/config.h> |
---|
20 | #include <asm/asm-offsets.h> |
---|
21 | #include <asm/reg_defs.h> |
---|
22 | #include <asm/msr.h> |
---|
23 | #include <asm/processor.h> |
---|
24 | |
---|
25 | #ifdef HAS_FLOAT |
---|
26 | save_fp: |
---|
27 | addi r4, r3, VCPU_fprs - FPR_WIDTH |
---|
28 | stfdu fr0,FPR_WIDTH(r4) |
---|
29 | stfdu fr1,FPR_WIDTH(r4) |
---|
30 | stfdu fr2,FPR_WIDTH(r4) |
---|
31 | stfdu fr3,FPR_WIDTH(r4) |
---|
32 | stfdu fr4,FPR_WIDTH(r4) |
---|
33 | stfdu fr5,FPR_WIDTH(r4) |
---|
34 | stfdu fr6,FPR_WIDTH(r4) |
---|
35 | stfdu fr7,FPR_WIDTH(r4) |
---|
36 | stfdu fr8,FPR_WIDTH(r4) |
---|
37 | stfdu fr9,FPR_WIDTH(r4) |
---|
38 | stfdu fr10,FPR_WIDTH(r4) |
---|
39 | stfdu fr11,FPR_WIDTH(r4) |
---|
40 | stfdu fr12,FPR_WIDTH(r4) |
---|
41 | stfdu fr13,FPR_WIDTH(r4) |
---|
42 | stfdu fr14,FPR_WIDTH(r4) |
---|
43 | stfdu fr15,FPR_WIDTH(r4) |
---|
44 | stfdu fr16,FPR_WIDTH(r4) |
---|
45 | stfdu fr17,FPR_WIDTH(r4) |
---|
46 | stfdu fr18,FPR_WIDTH(r4) |
---|
47 | stfdu fr19,FPR_WIDTH(r4) |
---|
48 | stfdu fr20,FPR_WIDTH(r4) |
---|
49 | stfdu fr21,FPR_WIDTH(r4) |
---|
50 | stfdu fr22,FPR_WIDTH(r4) |
---|
51 | stfdu fr23,FPR_WIDTH(r4) |
---|
52 | stfdu fr24,FPR_WIDTH(r4) |
---|
53 | stfdu fr25,FPR_WIDTH(r4) |
---|
54 | stfdu fr26,FPR_WIDTH(r4) |
---|
55 | stfdu fr27,FPR_WIDTH(r4) |
---|
56 | stfdu fr28,FPR_WIDTH(r4) |
---|
57 | stfdu fr29,FPR_WIDTH(r4) |
---|
58 | stfdu fr30,FPR_WIDTH(r4) |
---|
59 | stfdu fr31,FPR_WIDTH(r4) |
---|
60 | mffs fr0 |
---|
61 | stfd fr0,VCPU_fpscr(r3) |
---|
62 | blr |
---|
63 | |
---|
64 | load_fp: |
---|
65 | lfd fr0,VCPU_fpscr(r3) |
---|
66 | mtfsf 0xff,fr0 |
---|
67 | |
---|
68 | addi r4, r3, VCPU_fprs - FPR_WIDTH |
---|
69 | lfdu fr0,FPR_WIDTH(r4) |
---|
70 | lfdu fr1,FPR_WIDTH(r4) |
---|
71 | lfdu fr2,FPR_WIDTH(r4) |
---|
72 | lfdu fr3,FPR_WIDTH(r4) |
---|
73 | lfdu fr4,FPR_WIDTH(r4) |
---|
74 | lfdu fr5,FPR_WIDTH(r4) |
---|
75 | lfdu fr6,FPR_WIDTH(r4) |
---|
76 | lfdu fr7,FPR_WIDTH(r4) |
---|
77 | lfdu fr8,FPR_WIDTH(r4) |
---|
78 | lfdu fr9,FPR_WIDTH(r4) |
---|
79 | lfdu fr10,FPR_WIDTH(r4) |
---|
80 | lfdu fr11,FPR_WIDTH(r4) |
---|
81 | lfdu fr12,FPR_WIDTH(r4) |
---|
82 | lfdu fr13,FPR_WIDTH(r4) |
---|
83 | lfdu fr14,FPR_WIDTH(r4) |
---|
84 | lfdu fr15,FPR_WIDTH(r4) |
---|
85 | lfdu fr16,FPR_WIDTH(r4) |
---|
86 | lfdu fr17,FPR_WIDTH(r4) |
---|
87 | lfdu fr18,FPR_WIDTH(r4) |
---|
88 | lfdu fr19,FPR_WIDTH(r4) |
---|
89 | lfdu fr20,FPR_WIDTH(r4) |
---|
90 | lfdu fr21,FPR_WIDTH(r4) |
---|
91 | lfdu fr22,FPR_WIDTH(r4) |
---|
92 | lfdu fr23,FPR_WIDTH(r4) |
---|
93 | lfdu fr24,FPR_WIDTH(r4) |
---|
94 | lfdu fr25,FPR_WIDTH(r4) |
---|
95 | lfdu fr26,FPR_WIDTH(r4) |
---|
96 | lfdu fr27,FPR_WIDTH(r4) |
---|
97 | lfdu fr28,FPR_WIDTH(r4) |
---|
98 | lfdu fr29,FPR_WIDTH(r4) |
---|
99 | lfdu fr30,FPR_WIDTH(r4) |
---|
100 | lfdu fr31,FPR_WIDTH(r4) |
---|
101 | blr |
---|
102 | #endif /* HAS_FLOAT */ |
---|
103 | |
---|
104 | #ifdef HAS_VMX |
---|
105 | |
---|
106 | #define VCPU_vr(n) (VCPU_vrs + ((n) * 16)) |
---|
107 | |
---|
108 | /* |
---|
109 | * We cannot rely on the domain to correctly use VRSAVE |
---|
110 | * so it is required that all VMX registers are saved and restored. |
---|
111 | */ |
---|
112 | save_vmx: |
---|
113 | mfspr r0,SPRN_VRSAVE |
---|
114 | stw r0,VCPU_vrsave(r3) |
---|
115 | |
---|
116 | addi r0,r3,VCPU_vr(0); stvxl vr0,0,r0 |
---|
117 | addi r0,r3,VCPU_vr(1); stvxl vr1,0,r0 |
---|
118 | addi r0,r3,VCPU_vr(2); stvxl vr2,0,r0 |
---|
119 | addi r0,r3,VCPU_vr(3); stvxl vr3,0,r0 |
---|
120 | addi r0,r3,VCPU_vr(4); stvxl vr4,0,r0 |
---|
121 | addi r0,r3,VCPU_vr(5); stvxl vr5,0,r0 |
---|
122 | addi r0,r3,VCPU_vr(6); stvxl vr6,0,r0 |
---|
123 | addi r0,r3,VCPU_vr(7); stvxl vr7,0,r0 |
---|
124 | addi r0,r3,VCPU_vr(8); stvxl vr8,0,r0 |
---|
125 | |
---|
126 | /* |
---|
127 | * By now vr0 should be pushed out so now is a good time to |
---|
128 | * get the VRSCR which can take a long time and has no dependcies |
---|
129 | * on the following operations. |
---|
130 | */ |
---|
131 | mfvscr vr0 |
---|
132 | addi r0,r3,VCPU_vscr ; stvxl vr0,0,r0 |
---|
133 | |
---|
134 | addi r0,r3,VCPU_vr(9); stvxl vr9,0,r0 |
---|
135 | addi r0,r3,VCPU_vr(10); stvxl vr10,0,r0 |
---|
136 | addi r0,r3,VCPU_vr(11); stvxl vr11,0,r0 |
---|
137 | addi r0,r3,VCPU_vr(12); stvxl vr12,0,r0 |
---|
138 | addi r0,r3,VCPU_vr(13); stvxl vr13,0,r0 |
---|
139 | addi r0,r3,VCPU_vr(14); stvxl vr14,0,r0 |
---|
140 | addi r0,r3,VCPU_vr(15); stvxl vr15,0,r0 |
---|
141 | addi r0,r3,VCPU_vr(16); stvxl vr16,0,r0 |
---|
142 | addi r0,r3,VCPU_vr(17); stvxl vr17,0,r0 |
---|
143 | addi r0,r3,VCPU_vr(18); stvxl vr18,0,r0 |
---|
144 | addi r0,r3,VCPU_vr(19); stvxl vr19,0,r0 |
---|
145 | addi r0,r3,VCPU_vr(20); stvxl vr20,0,r0 |
---|
146 | addi r0,r3,VCPU_vr(21); stvxl vr21,0,r0 |
---|
147 | addi r0,r3,VCPU_vr(22); stvxl vr22,0,r0 |
---|
148 | addi r0,r3,VCPU_vr(23); stvxl vr23,0,r0 |
---|
149 | addi r0,r3,VCPU_vr(24); stvxl vr24,0,r0 |
---|
150 | addi r0,r3,VCPU_vr(25); stvxl vr25,0,r0 |
---|
151 | addi r0,r3,VCPU_vr(26); stvxl vr26,0,r0 |
---|
152 | addi r0,r3,VCPU_vr(27); stvxl vr27,0,r0 |
---|
153 | addi r0,r3,VCPU_vr(28); stvxl vr28,0,r0 |
---|
154 | addi r0,r3,VCPU_vr(29); stvxl vr29,0,r0 |
---|
155 | addi r0,r3,VCPU_vr(30); stvxl vr30,0,r0 |
---|
156 | addi r0,r3,VCPU_vr(31); stvxl vr31,0,r0 |
---|
157 | blr |
---|
158 | |
---|
159 | load_vmx: |
---|
160 | lwz r0,VCPU_vrsave(r3) |
---|
161 | mtspr SPRN_VRSAVE,r0 |
---|
162 | |
---|
163 | /* |
---|
164 | * This operation can take a long time so we use vr31 to |
---|
165 | * eliminate the depency on r0 for the next load |
---|
166 | */ |
---|
167 | addi r0,r3,VCPU_vscr ; lvxl vr31,0,r0 |
---|
168 | mtvscr vr31 |
---|
169 | |
---|
170 | addi r0,r3,VCPU_vr(0); lvxl vr0,0,r0 |
---|
171 | addi r0,r3,VCPU_vr(1); lvxl vr1,0,r0 |
---|
172 | addi r0,r3,VCPU_vr(2); lvxl vr2,0,r0 |
---|
173 | addi r0,r3,VCPU_vr(3); lvxl vr3,0,r0 |
---|
174 | addi r0,r3,VCPU_vr(4); lvxl vr4,0,r0 |
---|
175 | addi r0,r3,VCPU_vr(5); lvxl vr5,0,r0 |
---|
176 | addi r0,r3,VCPU_vr(6); lvxl vr6,0,r0 |
---|
177 | addi r0,r3,VCPU_vr(7); lvxl vr7,0,r0 |
---|
178 | addi r0,r3,VCPU_vr(8); lvxl vr8,0,r0 |
---|
179 | addi r0,r3,VCPU_vr(9); lvxl vr9,0,r0 |
---|
180 | addi r0,r3,VCPU_vr(10); lvxl vr10,0,r0 |
---|
181 | addi r0,r3,VCPU_vr(11); lvxl vr11,0,r0 |
---|
182 | addi r0,r3,VCPU_vr(12); lvxl vr12,0,r0 |
---|
183 | addi r0,r3,VCPU_vr(13); lvxl vr13,0,r0 |
---|
184 | addi r0,r3,VCPU_vr(14); lvxl vr14,0,r0 |
---|
185 | addi r0,r3,VCPU_vr(15); lvxl vr15,0,r0 |
---|
186 | addi r0,r3,VCPU_vr(16); lvxl vr16,0,r0 |
---|
187 | addi r0,r3,VCPU_vr(17); lvxl vr17,0,r0 |
---|
188 | addi r0,r3,VCPU_vr(18); lvxl vr18,0,r0 |
---|
189 | addi r0,r3,VCPU_vr(19); lvxl vr19,0,r0 |
---|
190 | addi r0,r3,VCPU_vr(20); lvxl vr20,0,r0 |
---|
191 | addi r0,r3,VCPU_vr(21); lvxl vr21,0,r0 |
---|
192 | addi r0,r3,VCPU_vr(22); lvxl vr22,0,r0 |
---|
193 | addi r0,r3,VCPU_vr(23); lvxl vr23,0,r0 |
---|
194 | addi r0,r3,VCPU_vr(24); lvxl vr24,0,r0 |
---|
195 | addi r0,r3,VCPU_vr(25); lvxl vr25,0,r0 |
---|
196 | addi r0,r3,VCPU_vr(26); lvxl vr26,0,r0 |
---|
197 | addi r0,r3,VCPU_vr(27); lvxl vr27,0,r0 |
---|
198 | addi r0,r3,VCPU_vr(28); lvxl vr28,0,r0 |
---|
199 | addi r0,r3,VCPU_vr(29); lvxl vr29,0,r0 |
---|
200 | addi r0,r3,VCPU_vr(30); lvxl vr30,0,r0 |
---|
201 | addi r0,r3,VCPU_vr(31); lvxl vr31,0,r0 |
---|
202 | blr |
---|
203 | #endif /* HAS_VMX */ |
---|
204 | |
---|
205 | /* void save_float(struct exec_domain *ed) */ |
---|
206 | _GLOBAL(save_float) |
---|
207 | mflr r8 |
---|
208 | #ifdef HAS_FLOAT |
---|
209 | mfmsr r9 # save msr |
---|
210 | ori r0,r9,MSR_FP # turn on FPU |
---|
211 | mtmsr r0 |
---|
212 | bl save_fp # uses r3, r4 |
---|
213 | mtmsr r9 # restore msr |
---|
214 | #endif /* HAS_FLOAT */ |
---|
215 | #ifdef HAS_VMX |
---|
216 | mfmsr r9 # save msr |
---|
217 | oris r0,r9,MSR_VMX@h # turn on VMX |
---|
218 | mtmsr r0 |
---|
219 | bl save_vmx # uses r3 |
---|
220 | mtmsr r9 # restore msr |
---|
221 | #endif /* HAS_VMX */ |
---|
222 | mtlr r8 |
---|
223 | blr |
---|
224 | |
---|
225 | /* void load_float(struct exec_domain *ed) */ |
---|
226 | _GLOBAL(load_float) |
---|
227 | mflr r8 |
---|
228 | #ifdef HAS_FLOAT |
---|
229 | mfmsr r9 # save msr |
---|
230 | ori r0,r9,MSR_FP # turn on FPU |
---|
231 | mtmsr r0 |
---|
232 | bl load_fp # uses r3, r4 |
---|
233 | mtmsr r9 # restore msr |
---|
234 | #endif /* HAS_FLOAT */ |
---|
235 | #ifdef HAS_VMX |
---|
236 | mfmsr r9 # save msr |
---|
237 | oris r0,r9,MSR_VMX@h # turn on VMX |
---|
238 | mtmsr r0 |
---|
239 | bl load_vmx # uses r3 |
---|
240 | mtmsr r9 # restore msr |
---|
241 | #endif /* HAS_VMX */ |
---|
242 | mtlr r8 |
---|
243 | blr |
---|