This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / arch / ia64 / xen / hypercall.S
1 /*
2  * Support routines for Xen hypercalls
3  *
4  * Copyright (C) 2005 Dan Magenheimer <dan.magenheimer@hp.com>
5  */
6
7 #include <asm/processor.h>
8 #include <asm/asmmacro.h>
9
10 /* To clear vpsr.ic, vpsr.i needs to be cleared first */
11 #define XEN_CLEAR_PSR_IC                                \
12         mov r14=1;                                      \
13         movl r15=XSI_PSR_I_ADDR;                        \
14         movl r2=XSI_PSR_IC;                             \
15         ;;                                              \
16         ld8 r15=[r15];                                  \
17         ld4 r3=[r2];                                    \
18         ;;                                              \
19         ld1 r16=[r15];                                  \
20         ;;                                              \
21         st1 [r15]=r14;                                  \
22         st4 [r2]=r0;                                    \
23         ;;
24
25 /* First restore vpsr.ic, and then vpsr.i */
26 #define XEN_RESTORE_PSR_IC                              \
27         st4 [r2]=r3;                                    \
28         st1 [r15]=r16;                                  \
29         ;;
30
31 GLOBAL_ENTRY(xen_get_ivr)
32         movl r8=running_on_xen;;
33         ld4 r8=[r8];;
34         cmp.eq p7,p0=r8,r0;;
35 (p7)    mov r8=cr.ivr;;
36 (p7)    br.ret.sptk.many rp
37         ;;
38         XEN_CLEAR_PSR_IC
39         ;;
40         XEN_HYPER_GET_IVR
41         ;;
42         XEN_RESTORE_PSR_IC
43         ;;
44         br.ret.sptk.many rp
45         ;;
46 END(xen_get_ivr)
47
48 GLOBAL_ENTRY(xen_get_tpr)
49         movl r8=running_on_xen;;
50         ld4 r8=[r8];;
51         cmp.eq p7,p0=r8,r0;;
52 (p7)    mov r8=cr.tpr;;
53 (p7)    br.ret.sptk.many rp
54         ;;
55         XEN_CLEAR_PSR_IC
56         ;;
57         XEN_HYPER_GET_TPR
58         ;;
59         XEN_RESTORE_PSR_IC
60         ;;
61         br.ret.sptk.many rp
62         ;;
63 END(xen_get_tpr)
64
65 GLOBAL_ENTRY(xen_set_tpr)
66         movl r8=running_on_xen;;
67         ld4 r8=[r8];;
68         cmp.eq p7,p0=r8,r0;;
69 (p7)    mov cr.tpr=r32;;
70 (p7)    br.ret.sptk.many rp
71         ;;
72         mov r8=r32
73         ;;
74         XEN_CLEAR_PSR_IC
75         ;;
76         XEN_HYPER_SET_TPR
77         ;;
78         XEN_RESTORE_PSR_IC
79         ;;
80         br.ret.sptk.many rp
81         ;;
82 END(xen_set_tpr)
83
84 GLOBAL_ENTRY(xen_eoi)
85         movl r8=running_on_xen;;
86         ld4 r8=[r8];;
87         cmp.eq p7,p0=r8,r0;;
88 (p7)    mov cr.eoi=r0;;
89 (p7)    br.ret.sptk.many rp
90         ;;
91         mov r8=r32
92         ;;
93         XEN_CLEAR_PSR_IC
94         ;;
95         XEN_HYPER_EOI
96         ;;
97         XEN_RESTORE_PSR_IC
98         ;;
99         br.ret.sptk.many rp
100         ;;
101 END(xen_eoi)
102
103 GLOBAL_ENTRY(xen_thash)
104         movl r8=running_on_xen;;
105         ld4 r8=[r8];;
106         cmp.eq p7,p0=r8,r0;;
107 (p7)    thash r8=r32;;
108 (p7)    br.ret.sptk.many rp
109         ;;
110         mov r8=r32
111         ;;
112         XEN_CLEAR_PSR_IC
113         ;;
114         XEN_HYPER_THASH
115         ;;
116         XEN_RESTORE_PSR_IC
117         ;;
118         br.ret.sptk.many rp
119         ;;
120 END(xen_thash)
121
122 GLOBAL_ENTRY(xen_set_itm)
123         movl r8=running_on_xen;;
124         ld4 r8=[r8];;
125         cmp.eq p7,p0=r8,r0;;
126 (p7)    mov cr.itm=r32;;
127 (p7)    br.ret.sptk.many rp
128         ;;
129         mov r8=r32
130         ;;
131         XEN_CLEAR_PSR_IC
132         ;;
133         XEN_HYPER_SET_ITM
134         ;;
135         XEN_RESTORE_PSR_IC
136         ;;
137         br.ret.sptk.many rp
138         ;;
139 END(xen_set_itm)
140
141 GLOBAL_ENTRY(xen_ptcga)
142         movl r8=running_on_xen;;
143         ld4 r8=[r8];;
144         cmp.eq p7,p0=r8,r0;;
145 (p7)    ptc.ga r32,r33;;
146 (p7)    br.ret.sptk.many rp
147         ;;
148         mov r8=r32
149         mov r9=r33
150         ;;
151         XEN_CLEAR_PSR_IC
152         ;;
153         XEN_HYPER_PTC_GA
154         ;;
155         XEN_RESTORE_PSR_IC
156         ;;
157         br.ret.sptk.many rp
158         ;;
159 END(xen_ptcga)
160
161 GLOBAL_ENTRY(xen_get_rr)
162         movl r8=running_on_xen;;
163         ld4 r8=[r8];;
164         cmp.eq p7,p0=r8,r0;;
165 (p7)    mov r8=rr[r32];;
166 (p7)    br.ret.sptk.many rp
167         ;;
168         mov r8=r32
169         ;;
170         XEN_CLEAR_PSR_IC
171         ;;
172         XEN_HYPER_GET_RR
173         ;;
174         XEN_RESTORE_PSR_IC
175         ;;
176         br.ret.sptk.many rp
177         ;;
178 END(xen_get_rr)
179
180 GLOBAL_ENTRY(xen_set_rr)
181         movl r8=running_on_xen;;
182         ld4 r8=[r8];;
183         cmp.eq p7,p0=r8,r0;;
184 (p7)    mov rr[r32]=r33;;
185 (p7)    br.ret.sptk.many rp
186         ;;
187         mov r8=r32
188         mov r9=r33
189         ;;
190         XEN_CLEAR_PSR_IC
191         ;;
192         XEN_HYPER_SET_RR
193         ;;
194         XEN_RESTORE_PSR_IC
195         ;;
196         br.ret.sptk.many rp
197         ;;
198 END(xen_set_rr)
199
200 GLOBAL_ENTRY(xen_set_kr)
201         movl r8=running_on_xen;;
202         ld4 r8=[r8];;
203         cmp.ne p7,p0=r8,r0;;
204 (p7)    br.cond.spnt.few 1f;
205         ;;
206         cmp.eq p7,p0=r8,r0
207         adds r8=-1,r8;;
208 (p7)    mov ar0=r9
209 (p7)    br.ret.sptk.many rp;;
210         cmp.eq p7,p0=r8,r0
211         adds r8=-1,r8;;
212 (p7)    mov ar1=r9
213 (p7)    br.ret.sptk.many rp;;
214         cmp.eq p7,p0=r8,r0
215         adds r8=-1,r8;;
216 (p7)    mov ar2=r9
217 (p7)    br.ret.sptk.many rp;;
218         cmp.eq p7,p0=r8,r0
219         adds r8=-1,r8;;
220 (p7)    mov ar3=r9
221 (p7)    br.ret.sptk.many rp;;
222         cmp.eq p7,p0=r8,r0
223         adds r8=-1,r8;;
224 (p7)    mov ar4=r9
225 (p7)    br.ret.sptk.many rp;;
226         cmp.eq p7,p0=r8,r0
227         adds r8=-1,r8;;
228 (p7)    mov ar5=r9
229 (p7)    br.ret.sptk.many rp;;
230         cmp.eq p7,p0=r8,r0
231         adds r8=-1,r8;;
232 (p7)    mov ar6=r9
233 (p7)    br.ret.sptk.many rp;;
234         cmp.eq p7,p0=r8,r0
235         adds r8=-1,r8;;
236 (p7)    mov ar7=r9
237 (p7)    br.ret.sptk.many rp;;
238
239 1:      mov r8=r32
240         mov r9=r33
241         ;;
242         XEN_CLEAR_PSR_IC
243         ;;
244         XEN_HYPER_SET_KR
245         ;;
246         XEN_RESTORE_PSR_IC
247         ;;
248         br.ret.sptk.many rp
249 END(xen_set_kr)
250
251 GLOBAL_ENTRY(xen_fc)
252         movl r8=running_on_xen;;
253         ld4 r8=[r8];;
254         cmp.eq p7,p0=r8,r0;;
255 (p7)    fc r32;;
256 (p7)    br.ret.sptk.many rp
257         ;;
258         mov r8=r32
259         ;;
260         XEN_CLEAR_PSR_IC
261         ;;
262         XEN_HYPER_FC
263         ;;
264         XEN_RESTORE_PSR_IC
265         ;;
266         br.ret.sptk.many rp
267 END(xen_fc)
268
269 GLOBAL_ENTRY(xen_get_cpuid)
270         movl r8=running_on_xen;;
271         ld4 r8=[r8];;
272         cmp.eq p7,p0=r8,r0;;
273 (p7)    mov r8=cpuid[r32];;
274 (p7)    br.ret.sptk.many rp
275         ;;
276         mov r8=r32
277         ;;
278         XEN_CLEAR_PSR_IC
279         ;;
280         XEN_HYPER_GET_CPUID
281         ;;
282         XEN_RESTORE_PSR_IC
283         ;;
284         br.ret.sptk.many rp
285 END(xen_get_cpuid)
286
287 GLOBAL_ENTRY(xen_get_pmd)
288         movl r8=running_on_xen;;
289         ld4 r8=[r8];;
290         cmp.eq p7,p0=r8,r0;;
291 (p7)    mov r8=pmd[r32];;
292 (p7)    br.ret.sptk.many rp
293         ;;
294         mov r8=r32
295         ;;
296         XEN_CLEAR_PSR_IC
297         ;;
298         XEN_HYPER_GET_PMD
299         ;;
300         XEN_RESTORE_PSR_IC
301         ;;
302         br.ret.sptk.many rp
303 END(xen_get_pmd)
304
305 #ifdef CONFIG_IA32_SUPPORT
306 GLOBAL_ENTRY(xen_get_eflag)
307         movl r8=running_on_xen;;
308         ld4 r8=[r8];;
309         cmp.eq p7,p0=r8,r0;;
310 (p7)    mov r8=ar24;;
311 (p7)    br.ret.sptk.many rp
312         ;;
313         mov r8=r32
314         ;;
315         XEN_CLEAR_PSR_IC
316         ;;
317         XEN_HYPER_GET_EFLAG
318         ;;
319         XEN_RESTORE_PSR_IC
320         ;;
321         br.ret.sptk.many rp
322 END(xen_get_eflag)
323         
324 // some bits aren't set if pl!=0, see SDM vol1 3.1.8
325 GLOBAL_ENTRY(xen_set_eflag)
326         movl r8=running_on_xen;;
327         ld4 r8=[r8];;
328         cmp.eq p7,p0=r8,r0;;
329 (p7)    mov ar24=r32
330 (p7)    br.ret.sptk.many rp
331         ;;
332         mov r8=r32
333         ;;
334         XEN_CLEAR_PSR_IC
335         ;;
336         XEN_HYPER_SET_EFLAG
337         ;;
338         XEN_RESTORE_PSR_IC
339         ;;
340         br.ret.sptk.many rp
341 END(xen_set_eflag)
342 #endif
343
344 GLOBAL_ENTRY(xen_send_ipi)
345         mov r14=r32
346         mov r15=r33
347         mov r2=0x400
348         break 0x1000
349         ;;
350         br.ret.sptk.many rp
351         ;;
352 END(xen_send_ipi)
353
354 #ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT
355 // Those are vdso specialized.
356 // In fsys mode, call, ret can't be used.
357 GLOBAL_ENTRY(xen_rsm_be_i)
358         ld8 r22=[r22]
359         ;; 
360         st1 [r22]=r20
361         st4 [r23]=r0
362         XEN_HYPER_RSM_BE
363         st4 [r23]=r20
364         brl.cond.sptk   .vdso_rsm_be_i_ret
365         ;; 
366 END(xen_rsm_be_i)
367
368 GLOBAL_ENTRY(xen_get_psr)
369         mov r31=r8
370         mov r25=IA64_PSR_IC
371         st4 [r23]=r0
372         XEN_HYPER_GET_PSR
373         ;; 
374         st4 [r23]=r20
375         or r29=r8,r25 // vpsr.ic was cleared for hyperprivop
376         mov r8=r31
377         brl.cond.sptk   .vdso_get_psr_ret
378         ;; 
379 END(xen_get_psr)
380
381         // see xen_ssm_i() in privop.h
382         // r22 = &vcpu->evtchn_mask
383         // r23 = &vpsr.ic
384         // r24 = &vcpu->pending_interruption
385         // r25 = tmp
386         // r31 = tmp
387         // p11 = tmp
388         // p14 = tmp
389 #define XEN_SET_PSR_I                   \
390         ld4 r31=[r22];                  \
391         ld4 r25=[r24];                  \
392         ;;                              \
393         st4 [r22]=r0;                   \
394         cmp.ne.unc p14,p0=r0,r31;       \
395         ;;                              \
396 (p14)   cmp.ne.unc p11,p0=r0,r25;       \
397         ;;                              \
398 (p11)   st4 [r22]=r20;                  \
399 (p11)   st4 [r23]=r0;                   \
400 (p11)   XEN_HYPER_SSM_I;
401                 
402 GLOBAL_ENTRY(xen_ssm_i_0)
403         XEN_SET_PSR_I
404         brl.cond.sptk   .vdso_ssm_i_0_ret
405         ;; 
406 END(xen_ssm_i_0)
407
408 GLOBAL_ENTRY(xen_ssm_i_1)
409         XEN_SET_PSR_I
410         brl.cond.sptk   .vdso_ssm_i_1_ret
411         ;; 
412 END(xen_ssm_i_1)
413 #endif