1e92ed0783790ce143b7c6e4e1009b2fc19e0964
[linux-2.6.git] / arch / ia64 / include / asm / xen / inst.h
1 /******************************************************************************
2  * arch/ia64/include/asm/xen/inst.h
3  *
4  * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp>
5  *                    VA Linux Systems Japan K.K.
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22
23 #include <asm/xen/privop.h>
24
25 #define DO_SAVE_MIN                             XEN_DO_SAVE_MIN
26
27 #define MOV_FROM_IFA(reg)       \
28         movl reg = XSI_IFA;     \
29         ;;                      \
30         ld8 reg = [reg]
31
32 #define MOV_FROM_ITIR(reg)      \
33         movl reg = XSI_ITIR;    \
34         ;;                      \
35         ld8 reg = [reg]
36
37 #define MOV_FROM_ISR(reg)       \
38         movl reg = XSI_ISR;     \
39         ;;                      \
40         ld8 reg = [reg]
41
42 #define MOV_FROM_IHA(reg)       \
43         movl reg = XSI_IHA;     \
44         ;;                      \
45         ld8 reg = [reg]
46
47 #define MOV_FROM_IPSR(pred, reg)        \
48 (pred)  movl reg = XSI_IPSR;            \
49         ;;                              \
50 (pred)  ld8 reg = [reg]
51
52 #define MOV_FROM_IIM(reg)       \
53         movl reg = XSI_IIM;     \
54         ;;                      \
55         ld8 reg = [reg]
56
57 #define MOV_FROM_IIP(reg)       \
58         movl reg = XSI_IIP;     \
59         ;;                      \
60         ld8 reg = [reg]
61
62 .macro __MOV_FROM_IVR reg, clob
63         .ifc "\reg", "r8"
64                 XEN_HYPER_GET_IVR
65                 .exitm
66         .endif
67         .ifc "\clob", "r8"
68                 XEN_HYPER_GET_IVR
69                 ;;
70                 mov \reg = r8
71                 .exitm
72         .endif
73
74         mov \clob = r8
75         ;;
76         XEN_HYPER_GET_IVR
77         ;;
78         mov \reg = r8
79         ;;
80         mov r8 = \clob
81 .endm
82 #define MOV_FROM_IVR(reg, clob) __MOV_FROM_IVR reg, clob
83
84 .macro __MOV_FROM_PSR pred, reg, clob
85         .ifc "\reg", "r8"
86                 (\pred) XEN_HYPER_GET_PSR;
87                 .exitm
88         .endif
89         .ifc "\clob", "r8"
90                 (\pred) XEN_HYPER_GET_PSR
91                 ;;
92                 (\pred) mov \reg = r8
93                 .exitm
94         .endif
95
96         (\pred) mov \clob = r8
97         (\pred) XEN_HYPER_GET_PSR
98         ;;
99         (\pred) mov \reg = r8
100         (\pred) mov r8 = \clob
101 .endm
102 #define MOV_FROM_PSR(pred, reg, clob)   __MOV_FROM_PSR pred, reg, clob
103
104
105 #define MOV_TO_IFA(reg, clob)   \
106         movl clob = XSI_IFA;    \
107         ;;                      \
108         st8 [clob] = reg        \
109
110 #define MOV_TO_ITIR(pred, reg, clob)    \
111 (pred)  movl clob = XSI_ITIR;           \
112         ;;                              \
113 (pred)  st8 [clob] = reg
114
115 #define MOV_TO_IHA(pred, reg, clob)     \
116 (pred)  movl clob = XSI_IHA;            \
117         ;;                              \
118 (pred)  st8 [clob] = reg
119
120 #define MOV_TO_IPSR(pred, reg, clob)    \
121 (pred)  movl clob = XSI_IPSR;           \
122         ;;                              \
123 (pred)  st8 [clob] = reg;               \
124         ;;
125
126 #define MOV_TO_IFS(pred, reg, clob)     \
127 (pred)  movl clob = XSI_IFS;            \
128         ;;                              \
129 (pred)  st8 [clob] = reg;               \
130         ;;
131
132 #define MOV_TO_IIP(reg, clob)   \
133         movl clob = XSI_IIP;    \
134         ;;                      \
135         st8 [clob] = reg
136
137 .macro ____MOV_TO_KR kr, reg, clob0, clob1
138         .ifc "\clob0", "r9"
139                 .error "clob0 \clob0 must not be r9"
140         .endif
141         .ifc "\clob1", "r8"
142                 .error "clob1 \clob1 must not be r8"
143         .endif
144
145         .ifnc "\reg", "r9"
146                 .ifnc "\clob1", "r9"
147                         mov \clob1 = r9
148                 .endif
149                 mov r9 = \reg
150         .endif
151         .ifnc "\clob0", "r8"
152                 mov \clob0 = r8
153         .endif
154         mov r8 = \kr
155         ;;
156         XEN_HYPER_SET_KR
157
158         .ifnc "\reg", "r9"
159                 .ifnc "\clob1", "r9"
160                         mov r9 = \clob1
161                 .endif
162         .endif
163         .ifnc "\clob0", "r8"
164                 mov r8 = \clob0
165         .endif
166 .endm
167
168 .macro __MOV_TO_KR kr, reg, clob0, clob1
169         .ifc "\clob0", "r9"
170                 ____MOV_TO_KR \kr, \reg, \clob1, \clob0
171                 .exitm
172         .endif
173         .ifc "\clob1", "r8"
174                 ____MOV_TO_KR \kr, \reg, \clob1, \clob0
175                 .exitm
176         .endif
177
178         ____MOV_TO_KR \kr, \reg, \clob0, \clob1
179 .endm
180
181 #define MOV_TO_KR(kr, reg, clob0, clob1) \
182         __MOV_TO_KR IA64_KR_ ## kr, reg, clob0, clob1
183
184
185 .macro __ITC_I pred, reg, clob
186         .ifc "\reg", "r8"
187                 (\pred) XEN_HYPER_ITC_I
188                 .exitm
189         .endif
190         .ifc "\clob", "r8"
191                 (\pred) mov r8 = \reg
192                 ;;
193                 (\pred) XEN_HYPER_ITC_I
194                 .exitm
195         .endif
196
197         (\pred) mov \clob = r8
198         (\pred) mov r8 = \reg
199         ;;
200         (\pred) XEN_HYPER_ITC_I
201         ;;
202         (\pred) mov r8 = \clob
203         ;;
204 .endm
205 #define ITC_I(pred, reg, clob)  __ITC_I pred, reg, clob
206
207 .macro __ITC_D pred, reg, clob
208         .ifc "\reg", "r8"
209                 (\pred) XEN_HYPER_ITC_D
210                 ;;
211                 .exitm
212         .endif
213         .ifc "\clob", "r8"
214                 (\pred) mov r8 = \reg
215                 ;;
216                 (\pred) XEN_HYPER_ITC_D
217                 ;;
218                 .exitm
219         .endif
220
221         (\pred) mov \clob = r8
222         (\pred) mov r8 = \reg
223         ;;
224         (\pred) XEN_HYPER_ITC_D
225         ;;
226         (\pred) mov r8 = \clob
227         ;;
228 .endm
229 #define ITC_D(pred, reg, clob)  __ITC_D pred, reg, clob
230
231 .macro __ITC_I_AND_D pred_i, pred_d, reg, clob
232         .ifc "\reg", "r8"
233                 (\pred_i)XEN_HYPER_ITC_I
234                 ;;
235                 (\pred_d)XEN_HYPER_ITC_D
236                 ;;
237                 .exitm
238         .endif
239         .ifc "\clob", "r8"
240                 mov r8 = \reg
241                 ;;
242                 (\pred_i)XEN_HYPER_ITC_I
243                 ;;
244                 (\pred_d)XEN_HYPER_ITC_D
245                 ;;
246                 .exitm
247         .endif
248
249         mov \clob = r8
250         mov r8 = \reg
251         ;;
252         (\pred_i)XEN_HYPER_ITC_I
253         ;;
254         (\pred_d)XEN_HYPER_ITC_D
255         ;;
256         mov r8 = \clob
257         ;;
258 .endm
259 #define ITC_I_AND_D(pred_i, pred_d, reg, clob) \
260         __ITC_I_AND_D pred_i, pred_d, reg, clob
261
262 .macro __THASH pred, reg0, reg1, clob
263         .ifc "\reg0", "r8"
264                 (\pred) mov r8 = \reg1
265                 (\pred) XEN_HYPER_THASH
266                 .exitm
267         .endc
268         .ifc "\reg1", "r8"
269                 (\pred) XEN_HYPER_THASH
270                 ;;
271                 (\pred) mov \reg0 = r8
272                 ;;
273                 .exitm
274         .endif
275         .ifc "\clob", "r8"
276                 (\pred) mov r8 = \reg1
277                 (\pred) XEN_HYPER_THASH
278                 ;;
279                 (\pred) mov \reg0 = r8
280                 ;;
281                 .exitm
282         .endif
283
284         (\pred) mov \clob = r8
285         (\pred) mov r8 = \reg1
286         (\pred) XEN_HYPER_THASH
287         ;;
288         (\pred) mov \reg0 = r8
289         (\pred) mov r8 = \clob
290         ;;
291 .endm
292 #define THASH(pred, reg0, reg1, clob) __THASH pred, reg0, reg1, clob
293
294 #define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1)    \
295         mov clob0 = 1;                                          \
296         movl clob1 = XSI_PSR_IC;                                \
297         ;;                                                      \
298         st4 [clob1] = clob0                                     \
299         ;;
300
301 #define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1)     \
302         ;;                                      \
303         srlz.d;                                 \
304         mov clob1 = 1;                          \
305         movl clob0 = XSI_PSR_IC;                \
306         ;;                                      \
307         st4 [clob0] = clob1
308
309 #define RSM_PSR_IC(clob)        \
310         movl clob = XSI_PSR_IC; \
311         ;;                      \
312         st4 [clob] = r0;        \
313         ;;
314
315 /* pred will be clobbered */
316 #define MASK_TO_PEND_OFS    (-1)
317 #define SSM_PSR_I(pred, pred_clob, clob)                                \
318 (pred)  movl clob = XSI_PSR_I_ADDR                                      \
319         ;;                                                              \
320 (pred)  ld8 clob = [clob]                                               \
321         ;;                                                              \
322         /* if (pred) vpsr.i = 1 */                                      \
323         /* if (pred) (vcpu->vcpu_info->evtchn_upcall_mask)=0 */         \
324 (pred)  st1 [clob] = r0, MASK_TO_PEND_OFS                               \
325         ;;                                                              \
326         /* if (vcpu->vcpu_info->evtchn_upcall_pending) */               \
327 (pred)  ld1 clob = [clob]                                               \
328         ;;                                                              \
329 (pred)  cmp.ne.unc pred_clob, p0 = clob, r0                             \
330         ;;                                                              \
331 (pred_clob)XEN_HYPER_SSM_I      /* do areal ssm psr.i */
332
333 #define RSM_PSR_I(pred, clob0, clob1)   \
334         movl clob0 = XSI_PSR_I_ADDR;    \
335         mov clob1 = 1;                  \
336         ;;                              \
337         ld8 clob0 = [clob0];            \
338         ;;                              \
339 (pred)  st1 [clob0] = clob1
340
341 #define RSM_PSR_I_IC(clob0, clob1, clob2)               \
342         movl clob0 = XSI_PSR_I_ADDR;                    \
343         movl clob1 = XSI_PSR_IC;                        \
344         ;;                                              \
345         ld8 clob0 = [clob0];                            \
346         mov clob2 = 1;                                  \
347         ;;                                              \
348         /* note: clears both vpsr.i and vpsr.ic! */     \
349         st1 [clob0] = clob2;                            \
350         st4 [clob1] = r0;                               \
351         ;;
352
353 #define RSM_PSR_DT              \
354         XEN_HYPER_RSM_PSR_DT
355
356 #define SSM_PSR_DT_AND_SRLZ_I   \
357         XEN_HYPER_SSM_PSR_DT
358
359 #define BSW_0(clob0, clob1, clob2)                      \
360         ;;                                              \
361         /* r16-r31 all now hold bank1 values */         \
362         mov clob2 = ar.unat;                            \
363         movl clob0 = XSI_BANK1_R16;                     \
364         movl clob1 = XSI_BANK1_R16 + 8;                 \
365         ;;                                              \
366 .mem.offset 0, 0; st8.spill [clob0] = r16, 16;          \
367 .mem.offset 8, 0; st8.spill [clob1] = r17, 16;          \
368         ;;                                              \
369 .mem.offset 0, 0; st8.spill [clob0] = r18, 16;          \
370 .mem.offset 8, 0; st8.spill [clob1] = r19, 16;          \
371         ;;                                              \
372 .mem.offset 0, 0; st8.spill [clob0] = r20, 16;          \
373 .mem.offset 8, 0; st8.spill [clob1] = r21, 16;          \
374         ;;                                              \
375 .mem.offset 0, 0; st8.spill [clob0] = r22, 16;          \
376 .mem.offset 8, 0; st8.spill [clob1] = r23, 16;          \
377         ;;                                              \
378 .mem.offset 0, 0; st8.spill [clob0] = r24, 16;          \
379 .mem.offset 8, 0; st8.spill [clob1] = r25, 16;          \
380         ;;                                              \
381 .mem.offset 0, 0; st8.spill [clob0] = r26, 16;          \
382 .mem.offset 8, 0; st8.spill [clob1] = r27, 16;          \
383         ;;                                              \
384 .mem.offset 0, 0; st8.spill [clob0] = r28, 16;          \
385 .mem.offset 8, 0; st8.spill [clob1] = r29, 16;          \
386         ;;                                              \
387 .mem.offset 0, 0; st8.spill [clob0] = r30, 16;          \
388 .mem.offset 8, 0; st8.spill [clob1] = r31, 16;          \
389         ;;                                              \
390         mov clob1 = ar.unat;                            \
391         movl clob0 = XSI_B1NAT;                         \
392         ;;                                              \
393         st8 [clob0] = clob1;                            \
394         mov ar.unat = clob2;                            \
395         movl clob0 = XSI_BANKNUM;                       \
396         ;;                                              \
397         st4 [clob0] = r0
398
399
400         /* FIXME: THIS CODE IS NOT NaT SAFE! */
401 #define XEN_BSW_1(clob)                 \
402         mov clob = ar.unat;             \
403         movl r30 = XSI_B1NAT;           \
404         ;;                              \
405         ld8 r30 = [r30];                \
406         mov r31 = 1;                    \
407         ;;                              \
408         mov ar.unat = r30;              \
409         movl r30 = XSI_BANKNUM;         \
410         ;;                              \
411         st4 [r30] = r31;                \
412         movl r30 = XSI_BANK1_R16;       \
413         movl r31 = XSI_BANK1_R16+8;     \
414         ;;                              \
415         ld8.fill r16 = [r30], 16;       \
416         ld8.fill r17 = [r31], 16;       \
417         ;;                              \
418         ld8.fill r18 = [r30], 16;       \
419         ld8.fill r19 = [r31], 16;       \
420         ;;                              \
421         ld8.fill r20 = [r30], 16;       \
422         ld8.fill r21 = [r31], 16;       \
423         ;;                              \
424         ld8.fill r22 = [r30], 16;       \
425         ld8.fill r23 = [r31], 16;       \
426         ;;                              \
427         ld8.fill r24 = [r30], 16;       \
428         ld8.fill r25 = [r31], 16;       \
429         ;;                              \
430         ld8.fill r26 = [r30], 16;       \
431         ld8.fill r27 = [r31], 16;       \
432         ;;                              \
433         ld8.fill r28 = [r30], 16;       \
434         ld8.fill r29 = [r31], 16;       \
435         ;;                              \
436         ld8.fill r30 = [r30];           \
437         ld8.fill r31 = [r31];           \
438         ;;                              \
439         mov ar.unat = clob
440
441 #define BSW_1(clob0, clob1)     XEN_BSW_1(clob1)
442
443
444 #define COVER   \
445         XEN_HYPER_COVER
446
447 #define RFI                     \
448         XEN_HYPER_RFI;          \
449         dv_serialize_data