blob: 1e92ed0783790ce143b7c6e4e1009b2fc19e0964 [file] [log] [blame]
Isaku Yamahatad65b5032008-10-17 11:18:01 +09001/******************************************************************************
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
Isaku Yamahata21820cc2008-10-17 11:18:02 +090025#define DO_SAVE_MIN XEN_DO_SAVE_MIN
26
Isaku Yamahatad65b5032008-10-17 11:18:01 +090027#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