ia64/xen-unstable

view xen/arch/ia64/linux-xen/pal.S @ 9770:ced37bea0647

[IA64] FPH enabling + cleanup

Move contents of switch_to macro from xensystem.h to context_switch function.
Initialize FPU on all processors. FPH is always enabled in Xen.
Speed up context-switch (a little bit!) by not enabling/disabling FPH.
Cleanup (unused function/variablesi/fields, debug printf...)
vmx_ia64_switch_to removed (was unused).

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
author awilliam@xenbuild.aw
date Tue Apr 25 22:35:41 2006 -0600 (2006-04-25)
parents 9312a3e8a6f8
children b235b68a0f4f
line source
1 /*
2 * PAL Firmware support
3 * IA-64 Processor Programmers Reference Vol 2
4 *
5 * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
6 * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
7 * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
8 * David Mosberger <davidm@hpl.hp.com>
9 * Stephane Eranian <eranian@hpl.hp.com>
10 *
11 * 05/22/2000 eranian Added support for stacked register calls
12 * 05/24/2000 eranian Added support for physical mode static calls
13 */
15 #include <asm/asmmacro.h>
16 #include <asm/processor.h>
18 .data
19 pal_entry_point:
20 data8 ia64_pal_default_handler
21 .text
23 /*
24 * Set the PAL entry point address. This could be written in C code, but we do it here
25 * to keep it all in one module (besides, it's so trivial that it's
26 * not a big deal).
27 *
28 * in0 Address of the PAL entry point (text address, NOT a function descriptor).
29 */
30 GLOBAL_ENTRY(ia64_pal_handler_init)
31 alloc r3=ar.pfs,1,0,0,0
32 movl r2=pal_entry_point
33 ;;
34 st8 [r2]=in0
35 br.ret.sptk.many rp
36 END(ia64_pal_handler_init)
38 /*
39 * Default PAL call handler. This needs to be coded in assembly because it uses
40 * the static calling convention, i.e., the RSE may not be used and calls are
41 * done via "br.cond" (not "br.call").
42 */
43 GLOBAL_ENTRY(ia64_pal_default_handler)
44 mov r8=-1
45 br.cond.sptk.many rp
46 END(ia64_pal_default_handler)
48 /*
49 * Make a PAL call using the static calling convention.
50 *
51 * in0 Index of PAL service
52 * in1 - in3 Remaining PAL arguments
53 * in4 1 ==> clear psr.ic, 0 ==> don't clear psr.ic
54 *
55 */
56 GLOBAL_ENTRY(ia64_pal_call_static)
57 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
58 alloc loc1 = ar.pfs,5,5,0,0
59 movl loc2 = pal_entry_point
60 1: {
61 mov r28 = in0
62 mov r29 = in1
63 mov r8 = ip
64 }
65 ;;
66 ld8 loc2 = [loc2] // loc2 <- entry point
67 tbit.nz p6,p7 = in4, 0
68 adds r8 = 1f-1b,r8
69 mov loc4=ar.rsc // save RSE configuration
70 ;;
71 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
72 mov loc3 = psr
73 mov loc0 = rp
74 .body
75 mov r30 = in2
77 (p6) rsm psr.i | psr.ic
78 mov r31 = in3
79 mov b7 = loc2
81 (p7) rsm psr.i
82 ;;
83 (p6) srlz.i
84 mov rp = r8
85 br.cond.sptk.many b7
86 1: mov psr.l = loc3
87 mov ar.rsc = loc4 // restore RSE configuration
88 mov ar.pfs = loc1
89 mov rp = loc0
90 ;;
91 srlz.d // seralize restoration of psr.l
92 br.ret.sptk.many b0
93 END(ia64_pal_call_static)
95 /*
96 * Make a PAL call using the stacked registers calling convention.
97 *
98 * Inputs:
99 * in0 Index of PAL service
100 * in2 - in3 Remaning PAL arguments
101 */
102 GLOBAL_ENTRY(ia64_pal_call_stacked)
103 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
104 alloc loc1 = ar.pfs,4,4,4,0
105 movl loc2 = pal_entry_point
107 mov r28 = in0 // Index MUST be copied to r28
108 mov out0 = in0 // AND in0 of PAL function
109 mov loc0 = rp
110 .body
111 ;;
112 ld8 loc2 = [loc2] // loc2 <- entry point
113 mov out1 = in1
114 mov out2 = in2
115 mov out3 = in3
116 mov loc3 = psr
117 ;;
118 rsm psr.i
119 mov b7 = loc2
120 ;;
121 br.call.sptk.many rp=b7 // now make the call
122 .ret0: mov psr.l = loc3
123 mov ar.pfs = loc1
124 mov rp = loc0
125 ;;
126 srlz.d // serialize restoration of psr.l
127 br.ret.sptk.many b0
128 END(ia64_pal_call_stacked)
130 /*
131 * Make a physical mode PAL call using the static registers calling convention.
132 *
133 * Inputs:
134 * in0 Index of PAL service
135 * in2 - in3 Remaning PAL arguments
136 *
137 * PSR_LP, PSR_TB, PSR_ID, PSR_DA are never set by the kernel.
138 * So we don't need to clear them.
139 */
140 #define PAL_PSR_BITS_TO_CLEAR \
141 (IA64_PSR_I | IA64_PSR_IT | IA64_PSR_DT | IA64_PSR_DB | IA64_PSR_RT | \
142 IA64_PSR_DD | IA64_PSR_SS | IA64_PSR_RI | IA64_PSR_ED | \
143 IA64_PSR_DFL | IA64_PSR_DFH)
145 #define PAL_PSR_BITS_TO_SET \
146 (IA64_PSR_BN)
149 GLOBAL_ENTRY(ia64_pal_call_phys_static)
150 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(4)
151 alloc loc1 = ar.pfs,4,7,0,0
152 movl loc2 = pal_entry_point
153 1: {
154 mov r28 = in0 // copy procedure index
155 mov r8 = ip // save ip to compute branch
156 mov loc0 = rp // save rp
157 }
158 .body
159 ;;
160 ld8 loc2 = [loc2] // loc2 <- entry point
161 mov r29 = in1 // first argument
162 mov r30 = in2 // copy arg2
163 mov r31 = in3 // copy arg3
164 ;;
165 mov loc3 = psr // save psr
166 adds r8 = 1f-1b,r8 // calculate return address for call
167 ;;
168 mov loc4=ar.rsc // save RSE configuration
169 #ifdef XEN
170 dep.z loc2=loc2,0,60 // convert pal entry point to physical
171 #else // XEN
172 dep.z loc2=loc2,0,61 // convert pal entry point to physical
173 #endif // XEN
174 tpa r8=r8 // convert rp to physical
175 ;;
176 mov b7 = loc2 // install target to branch reg
177 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
178 movl r16=PAL_PSR_BITS_TO_CLEAR
179 movl r17=PAL_PSR_BITS_TO_SET
180 ;;
181 or loc3=loc3,r17 // add in psr the bits to set
182 ;;
183 andcm r16=loc3,r16 // removes bits to clear from psr
184 br.call.sptk.many rp=ia64_switch_mode_phys
185 .ret1: mov rp = r8 // install return address (physical)
186 mov loc5 = r19
187 mov loc6 = r20
188 br.cond.sptk.many b7
189 1:
190 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
191 mov r16=loc3 // r16= original psr
192 mov r19=loc5
193 mov r20=loc6
194 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
195 .ret2:
196 mov psr.l = loc3 // restore init PSR
198 mov ar.pfs = loc1
199 mov rp = loc0
200 ;;
201 mov ar.rsc=loc4 // restore RSE configuration
202 srlz.d // seralize restoration of psr.l
203 br.ret.sptk.many b0
204 END(ia64_pal_call_phys_static)
206 /*
207 * Make a PAL call using the stacked registers in physical mode.
208 *
209 * Inputs:
210 * in0 Index of PAL service
211 * in2 - in3 Remaning PAL arguments
212 */
213 GLOBAL_ENTRY(ia64_pal_call_phys_stacked)
214 .prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(5)
215 alloc loc1 = ar.pfs,5,7,4,0
216 movl loc2 = pal_entry_point
217 1: {
218 mov r28 = in0 // copy procedure index
219 mov loc0 = rp // save rp
220 }
221 .body
222 ;;
223 ld8 loc2 = [loc2] // loc2 <- entry point
224 mov out0 = in0 // first argument
225 mov out1 = in1 // copy arg2
226 mov out2 = in2 // copy arg3
227 mov out3 = in3 // copy arg3
228 ;;
229 mov loc3 = psr // save psr
230 ;;
231 mov loc4=ar.rsc // save RSE configuration
232 #ifdef XEN
233 dep.z loc2=loc2,0,60 // convert pal entry point to physical
234 #else // XEN
235 dep.z loc2=loc2,0,61 // convert pal entry point to physical
236 #endif // XEN
237 ;;
238 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
239 movl r16=PAL_PSR_BITS_TO_CLEAR
240 movl r17=PAL_PSR_BITS_TO_SET
241 ;;
242 or loc3=loc3,r17 // add in psr the bits to set
243 mov b7 = loc2 // install target to branch reg
244 ;;
245 andcm r16=loc3,r16 // removes bits to clear from psr
246 br.call.sptk.many rp=ia64_switch_mode_phys
247 .ret6:
248 mov loc5 = r19
249 mov loc6 = r20
250 br.call.sptk.many rp=b7 // now make the call
251 .ret7:
252 mov ar.rsc=0 // put RSE in enforced lazy, LE mode
253 mov r16=loc3 // r16= original psr
254 mov r19=loc5
255 mov r20=loc6
256 br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
258 .ret8: mov psr.l = loc3 // restore init PSR
259 mov ar.pfs = loc1
260 mov rp = loc0
261 ;;
262 mov ar.rsc=loc4 // restore RSE configuration
263 srlz.d // seralize restoration of psr.l
264 br.ret.sptk.many b0
265 END(ia64_pal_call_phys_stacked)
267 /*
268 * Save scratch fp scratch regs which aren't saved in pt_regs already (fp10-fp15).
269 *
270 * NOTE: We need to do this since firmware (SAL and PAL) may use any of the scratch
271 * regs fp-low partition.
272 *
273 * Inputs:
274 * in0 Address of stack storage for fp regs
275 */
276 GLOBAL_ENTRY(ia64_save_scratch_fpregs)
277 alloc r3=ar.pfs,1,0,0,0
278 add r2=16,in0
279 ;;
280 stf.spill [in0] = f10,32
281 stf.spill [r2] = f11,32
282 ;;
283 stf.spill [in0] = f12,32
284 stf.spill [r2] = f13,32
285 ;;
286 stf.spill [in0] = f14,32
287 stf.spill [r2] = f15,32
288 br.ret.sptk.many rp
289 END(ia64_save_scratch_fpregs)
291 /*
292 * Load scratch fp scratch regs (fp10-fp15)
293 *
294 * Inputs:
295 * in0 Address of stack storage for fp regs
296 */
297 GLOBAL_ENTRY(ia64_load_scratch_fpregs)
298 alloc r3=ar.pfs,1,0,0,0
299 add r2=16,in0
300 ;;
301 ldf.fill f10 = [in0],32
302 ldf.fill f11 = [r2],32
303 ;;
304 ldf.fill f12 = [in0],32
305 ldf.fill f13 = [r2],32
306 ;;
307 ldf.fill f14 = [in0],32
308 ldf.fill f15 = [r2],32
309 br.ret.sptk.many rp
310 END(ia64_load_scratch_fpregs)