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