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