• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * arch/ia64/kvm/optvfault.S
3 * optimize virtualization fault handler
4 *
5 * Copyright (C) 2006 Intel Co
6 *	Xuefei Xu (Anthony Xu) <anthony.xu@intel.com>
7 * Copyright (C) 2008 Intel Co
8 *      Add the support for Tukwila processors.
9 *	Xiantao Zhang <xiantao.zhang@intel.com>
10 */
11
12#include <asm/asmmacro.h>
13#include <asm/processor.h>
14#include <asm/kvm_host.h>
15
16#include "vti.h"
17#include "asm-offsets.h"
18
19#define ACCE_MOV_FROM_AR
20#define ACCE_MOV_FROM_RR
21#define ACCE_MOV_TO_RR
22#define ACCE_RSM
23#define ACCE_SSM
24#define ACCE_MOV_TO_PSR
25#define ACCE_THASH
26
27#define VMX_VPS_SYNC_READ			\
28	add r16=VMM_VPD_BASE_OFFSET,r21;	\
29	mov r17 = b0;				\
30	mov r18 = r24;				\
31	mov r19 = r25;				\
32	mov r20 = r31;				\
33	;;					\
34{.mii;						\
35	ld8 r16 = [r16];			\
36	nop 0x0;				\
37	mov r24 = ip;				\
38	;;					\
39};						\
40{.mmb;						\
41	add r24=0x20, r24;			\
42	mov r25 =r16;				\
43	br.sptk.many kvm_vps_sync_read;		\
44};						\
45	mov b0 = r17;				\
46	mov r24 = r18;				\
47	mov r25 = r19;				\
48	mov r31 = r20
49
50ENTRY(kvm_vps_entry)
51	adds r29 = VMM_VCPU_VSA_BASE_OFFSET,r21
52	;;
53	ld8 r29 = [r29]
54	;;
55	add r29 = r29, r30
56	;;
57	mov b0 = r29
58	br.sptk.many b0
59END(kvm_vps_entry)
60
61/*
62 *	Inputs:
63 *	r24 : return address
64 *  	r25 : vpd
65 *	r29 : scratch
66 *
67 */
68GLOBAL_ENTRY(kvm_vps_sync_read)
69	movl r30 = PAL_VPS_SYNC_READ
70	;;
71	br.sptk.many kvm_vps_entry
72END(kvm_vps_sync_read)
73
74/*
75 *	Inputs:
76 *	r24 : return address
77 *  	r25 : vpd
78 *	r29 : scratch
79 *
80 */
81GLOBAL_ENTRY(kvm_vps_sync_write)
82	movl r30 = PAL_VPS_SYNC_WRITE
83	;;
84	br.sptk.many kvm_vps_entry
85END(kvm_vps_sync_write)
86
87/*
88 *	Inputs:
89 *	r23 : pr
90 *	r24 : guest b0
91 *  	r25 : vpd
92 *
93 */
94GLOBAL_ENTRY(kvm_vps_resume_normal)
95	movl r30 = PAL_VPS_RESUME_NORMAL
96	;;
97	mov pr=r23,-2
98	br.sptk.many kvm_vps_entry
99END(kvm_vps_resume_normal)
100
101/*
102 *	Inputs:
103 *	r23 : pr
104 *	r24 : guest b0
105 *  	r25 : vpd
106 *	r17 : isr
107 */
108GLOBAL_ENTRY(kvm_vps_resume_handler)
109	movl r30 = PAL_VPS_RESUME_HANDLER
110	;;
111	ld8 r26=[r25]
112	shr r17=r17,IA64_ISR_IR_BIT
113	;;
114	dep r26=r17,r26,63,1   // bit 63 of r26 indicate whether enable CFLE
115	mov pr=r23,-2
116	br.sptk.many kvm_vps_entry
117END(kvm_vps_resume_handler)
118
119//mov r1=ar3
120GLOBAL_ENTRY(kvm_asm_mov_from_ar)
121#ifndef ACCE_MOV_FROM_AR
122	br.many kvm_virtualization_fault_back
123#endif
124	add r18=VMM_VCPU_ITC_OFS_OFFSET, r21
125	add r16=VMM_VCPU_LAST_ITC_OFFSET,r21
126	extr.u r17=r25,6,7
127	;;
128	ld8 r18=[r18]
129	mov r19=ar.itc
130	mov r24=b0
131	;;
132	add r19=r19,r18
133	addl r20=@gprel(asm_mov_to_reg),gp
134	;;
135	st8 [r16] = r19
136	adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20
137	shladd r17=r17,4,r20
138	;;
139	mov b0=r17
140	br.sptk.few b0
141	;;
142END(kvm_asm_mov_from_ar)
143
144/*
145 * Special SGI SN2 optimized version of mov_from_ar using the SN2 RTC
146 * clock as it's source for emulating the ITC. This version will be
147 * copied on top of the original version if the host is determined to
148 * be an SN2.
149 */
150GLOBAL_ENTRY(kvm_asm_mov_from_ar_sn2)
151	add r18=VMM_VCPU_ITC_OFS_OFFSET, r21
152	movl r19 = (KVM_VMM_BASE+(1<<KVM_VMM_SHIFT))
153
154	add r16=VMM_VCPU_LAST_ITC_OFFSET,r21
155	extr.u r17=r25,6,7
156	mov r24=b0
157	;;
158	ld8 r18=[r18]
159	ld8 r19=[r19]
160	addl r20=@gprel(asm_mov_to_reg),gp
161	;;
162	add r19=r19,r18
163	shladd r17=r17,4,r20
164	;;
165	adds r30=kvm_resume_to_guest-asm_mov_to_reg,r20
166	st8 [r16] = r19
167	mov b0=r17
168	br.sptk.few b0
169	;;
170END(kvm_asm_mov_from_ar_sn2)
171
172
173
174// mov r1=rr[r3]
175GLOBAL_ENTRY(kvm_asm_mov_from_rr)
176#ifndef ACCE_MOV_FROM_RR
177	br.many kvm_virtualization_fault_back
178#endif
179	extr.u r16=r25,20,7
180	extr.u r17=r25,6,7
181	addl r20=@gprel(asm_mov_from_reg),gp
182	;;
183	adds r30=kvm_asm_mov_from_rr_back_1-asm_mov_from_reg,r20
184	shladd r16=r16,4,r20
185	mov r24=b0
186	;;
187	add r27=VMM_VCPU_VRR0_OFFSET,r21
188	mov b0=r16
189	br.many b0
190	;;
191kvm_asm_mov_from_rr_back_1:
192	adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20
193	adds r22=asm_mov_to_reg-asm_mov_from_reg,r20
194	shr.u r26=r19,61
195	;;
196	shladd r17=r17,4,r22
197	shladd r27=r26,3,r27
198	;;
199	ld8 r19=[r27]
200	mov b0=r17
201	br.many b0
202END(kvm_asm_mov_from_rr)
203
204
205// mov rr[r3]=r2
206GLOBAL_ENTRY(kvm_asm_mov_to_rr)
207#ifndef ACCE_MOV_TO_RR
208	br.many kvm_virtualization_fault_back
209#endif
210	extr.u r16=r25,20,7
211	extr.u r17=r25,13,7
212	addl r20=@gprel(asm_mov_from_reg),gp
213	;;
214	adds r30=kvm_asm_mov_to_rr_back_1-asm_mov_from_reg,r20
215	shladd r16=r16,4,r20
216	mov r22=b0
217	;;
218	add r27=VMM_VCPU_VRR0_OFFSET,r21
219	mov b0=r16
220	br.many b0
221	;;
222kvm_asm_mov_to_rr_back_1:
223	adds r30=kvm_asm_mov_to_rr_back_2-asm_mov_from_reg,r20
224	shr.u r23=r19,61
225	shladd r17=r17,4,r20
226	;;
227	//if rr6, go back
228	cmp.eq p6,p0=6,r23
229	mov b0=r22
230	(p6) br.cond.dpnt.many kvm_virtualization_fault_back
231	;;
232	mov r28=r19
233	mov b0=r17
234	br.many b0
235kvm_asm_mov_to_rr_back_2:
236	adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20
237	shladd r27=r23,3,r27
238	;; // vrr.rid<<4 |0xe
239	st8 [r27]=r19
240	mov b0=r30
241	;;
242	extr.u r16=r19,8,26
243	extr.u r18 =r19,2,6
244	mov r17 =0xe
245	;;
246	shladd r16 = r16, 4, r17
247	extr.u r19 =r19,0,8
248	;;
249	shl r16 = r16,8
250	;;
251	add r19 = r19, r16
252	;; //set ve 1
253	dep r19=-1,r19,0,1
254	cmp.lt p6,p0=14,r18
255	;;
256	(p6) mov r18=14
257	;;
258	(p6) dep r19=r18,r19,2,6
259	;;
260	cmp.eq p6,p0=0,r23
261	;;
262	cmp.eq.or p6,p0=4,r23
263	;;
264	adds r16=VMM_VCPU_MODE_FLAGS_OFFSET,r21
265	(p6) adds r17=VMM_VCPU_META_SAVED_RR0_OFFSET,r21
266	;;
267	ld4 r16=[r16]
268	cmp.eq p7,p0=r0,r0
269	(p6) shladd r17=r23,1,r17
270	;;
271	(p6) st8 [r17]=r19
272	(p6) tbit.nz p6,p7=r16,0
273	;;
274	(p7) mov rr[r28]=r19
275	mov r24=r22
276	br.many b0
277END(kvm_asm_mov_to_rr)
278
279
280//rsm
281GLOBAL_ENTRY(kvm_asm_rsm)
282#ifndef ACCE_RSM
283	br.many kvm_virtualization_fault_back
284#endif
285	VMX_VPS_SYNC_READ
286	;;
287	extr.u r26=r25,6,21
288	extr.u r27=r25,31,2
289	;;
290	extr.u r28=r25,36,1
291	dep r26=r27,r26,21,2
292	;;
293	add r17=VPD_VPSR_START_OFFSET,r16
294	add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21
295	//r26 is imm24
296	dep r26=r28,r26,23,1
297	;;
298	ld8 r18=[r17]
299	movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI
300	ld4 r23=[r22]
301	sub r27=-1,r26
302	mov r24=b0
303	;;
304	mov r20=cr.ipsr
305	or r28=r27,r28
306	and r19=r18,r27
307	;;
308	st8 [r17]=r19
309	and r20=r20,r28
310	/* Comment it out due to short of fp lazy alorgithm support
311	adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
312	;;
313	ld8 r27=[r27]
314	;;
315	tbit.nz p8,p0= r27,IA64_PSR_DFH_BIT
316	;;
317	(p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
318	*/
319	;;
320	mov cr.ipsr=r20
321	tbit.nz p6,p0=r23,0
322	;;
323	tbit.z.or p6,p0=r26,IA64_PSR_DT_BIT
324	(p6) br.dptk kvm_resume_to_guest_with_sync
325	;;
326	add r26=VMM_VCPU_META_RR0_OFFSET,r21
327	add r27=VMM_VCPU_META_RR0_OFFSET+8,r21
328	dep r23=-1,r23,0,1
329	;;
330	ld8 r26=[r26]
331	ld8 r27=[r27]
332	st4 [r22]=r23
333	dep.z r28=4,61,3
334	;;
335	mov rr[r0]=r26
336	;;
337	mov rr[r28]=r27
338	;;
339	srlz.d
340	br.many kvm_resume_to_guest_with_sync
341END(kvm_asm_rsm)
342
343
344//ssm
345GLOBAL_ENTRY(kvm_asm_ssm)
346#ifndef ACCE_SSM
347	br.many kvm_virtualization_fault_back
348#endif
349	VMX_VPS_SYNC_READ
350	;;
351	extr.u r26=r25,6,21
352	extr.u r27=r25,31,2
353	;;
354	extr.u r28=r25,36,1
355	dep r26=r27,r26,21,2
356	;;  //r26 is imm24
357	add r27=VPD_VPSR_START_OFFSET,r16
358	dep r26=r28,r26,23,1
359	;;  //r19 vpsr
360	ld8 r29=[r27]
361	mov r24=b0
362	;;
363	add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21
364	mov r20=cr.ipsr
365	or r19=r29,r26
366	;;
367	ld4 r23=[r22]
368	st8 [r27]=r19
369	or r20=r20,r26
370	;;
371	mov cr.ipsr=r20
372	movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT
373	;;
374	and r19=r28,r19
375	tbit.z p6,p0=r23,0
376	;;
377	cmp.ne.or p6,p0=r28,r19
378	(p6) br.dptk kvm_asm_ssm_1
379	;;
380	add r26=VMM_VCPU_META_SAVED_RR0_OFFSET,r21
381	add r27=VMM_VCPU_META_SAVED_RR0_OFFSET+8,r21
382	dep r23=0,r23,0,1
383	;;
384	ld8 r26=[r26]
385	ld8 r27=[r27]
386	st4 [r22]=r23
387	dep.z r28=4,61,3
388	;;
389	mov rr[r0]=r26
390	;;
391	mov rr[r28]=r27
392	;;
393	srlz.d
394	;;
395kvm_asm_ssm_1:
396	tbit.nz p6,p0=r29,IA64_PSR_I_BIT
397	;;
398	tbit.z.or p6,p0=r19,IA64_PSR_I_BIT
399	(p6) br.dptk kvm_resume_to_guest_with_sync
400	;;
401	add r29=VPD_VTPR_START_OFFSET,r16
402	add r30=VPD_VHPI_START_OFFSET,r16
403	;;
404	ld8 r29=[r29]
405	ld8 r30=[r30]
406	;;
407	extr.u r17=r29,4,4
408	extr.u r18=r29,16,1
409	;;
410	dep r17=r18,r17,4,1
411	;;
412	cmp.gt p6,p0=r30,r17
413	(p6) br.dpnt.few kvm_asm_dispatch_vexirq
414	br.many kvm_resume_to_guest_with_sync
415END(kvm_asm_ssm)
416
417
418//mov psr.l=r2
419GLOBAL_ENTRY(kvm_asm_mov_to_psr)
420#ifndef ACCE_MOV_TO_PSR
421	br.many kvm_virtualization_fault_back
422#endif
423	VMX_VPS_SYNC_READ
424	;;
425	extr.u r26=r25,13,7 //r2
426	addl r20=@gprel(asm_mov_from_reg),gp
427	;;
428	adds r30=kvm_asm_mov_to_psr_back-asm_mov_from_reg,r20
429	shladd r26=r26,4,r20
430	mov r24=b0
431	;;
432	add r27=VPD_VPSR_START_OFFSET,r16
433	mov b0=r26
434	br.many b0
435	;;
436kvm_asm_mov_to_psr_back:
437	ld8 r17=[r27]
438	add r22=VMM_VCPU_MODE_FLAGS_OFFSET,r21
439	dep r19=0,r19,32,32
440	;;
441	ld4 r23=[r22]
442	dep r18=0,r17,0,32
443	;;
444	add r30=r18,r19
445	movl r28=IA64_PSR_DT+IA64_PSR_RT+IA64_PSR_IT
446	;;
447	st8 [r27]=r30
448	and r27=r28,r30
449	and r29=r28,r17
450	;;
451	cmp.eq p5,p0=r29,r27
452	cmp.eq p6,p7=r28,r27
453	(p5) br.many kvm_asm_mov_to_psr_1
454	;;
455	//virtual to physical
456	(p7) add r26=VMM_VCPU_META_RR0_OFFSET,r21
457	(p7) add r27=VMM_VCPU_META_RR0_OFFSET+8,r21
458	(p7) dep r23=-1,r23,0,1
459	;;
460	//physical to virtual
461	(p6) add r26=VMM_VCPU_META_SAVED_RR0_OFFSET,r21
462	(p6) add r27=VMM_VCPU_META_SAVED_RR0_OFFSET+8,r21
463	(p6) dep r23=0,r23,0,1
464	;;
465	ld8 r26=[r26]
466	ld8 r27=[r27]
467	st4 [r22]=r23
468	dep.z r28=4,61,3
469	;;
470	mov rr[r0]=r26
471	;;
472	mov rr[r28]=r27
473	;;
474	srlz.d
475	;;
476kvm_asm_mov_to_psr_1:
477	mov r20=cr.ipsr
478	movl r28=IA64_PSR_IC+IA64_PSR_I+IA64_PSR_DT+IA64_PSR_SI+IA64_PSR_RT
479	;;
480	or r19=r19,r28
481	dep r20=0,r20,0,32
482	;;
483	add r20=r19,r20
484	mov b0=r24
485	;;
486	/* Comment it out due to short of fp lazy algorithm support
487	adds r27=IA64_VCPU_FP_PSR_OFFSET,r21
488	;;
489	ld8 r27=[r27]
490	;;
491	tbit.nz p8,p0=r27,IA64_PSR_DFH_BIT
492	;;
493	(p8) dep r20=-1,r20,IA64_PSR_DFH_BIT,1
494	;;
495	*/
496	mov cr.ipsr=r20
497	cmp.ne p6,p0=r0,r0
498	;;
499	tbit.nz.or p6,p0=r17,IA64_PSR_I_BIT
500	tbit.z.or p6,p0=r30,IA64_PSR_I_BIT
501	(p6) br.dpnt.few kvm_resume_to_guest_with_sync
502	;;
503	add r29=VPD_VTPR_START_OFFSET,r16
504	add r30=VPD_VHPI_START_OFFSET,r16
505	;;
506	ld8 r29=[r29]
507	ld8 r30=[r30]
508	;;
509	extr.u r17=r29,4,4
510	extr.u r18=r29,16,1
511	;;
512	dep r17=r18,r17,4,1
513	;;
514	cmp.gt p6,p0=r30,r17
515	(p6) br.dpnt.few kvm_asm_dispatch_vexirq
516	br.many kvm_resume_to_guest_with_sync
517END(kvm_asm_mov_to_psr)
518
519
520ENTRY(kvm_asm_dispatch_vexirq)
521//increment iip
522	mov r17 = b0
523	mov r18 = r31
524{.mii
525	add r25=VMM_VPD_BASE_OFFSET,r21
526	nop 0x0
527	mov r24 = ip
528	;;
529}
530{.mmb
531	add r24 = 0x20, r24
532	ld8 r25 = [r25]
533	br.sptk.many kvm_vps_sync_write
534}
535	mov b0 =r17
536	mov r16=cr.ipsr
537	mov r31 = r18
538	mov r19 = 37
539	;;
540	extr.u r17=r16,IA64_PSR_RI_BIT,2
541	tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1
542	;;
543	(p6) mov r18=cr.iip
544	(p6) mov r17=r0
545	(p7) add r17=1,r17
546	;;
547	(p6) add r18=0x10,r18
548	dep r16=r17,r16,IA64_PSR_RI_BIT,2
549	;;
550	(p6) mov cr.iip=r18
551	mov cr.ipsr=r16
552	mov r30 =1
553	br.many kvm_dispatch_vexirq
554END(kvm_asm_dispatch_vexirq)
555
556// thash
557// TODO: add support when pta.vf = 1
558GLOBAL_ENTRY(kvm_asm_thash)
559#ifndef ACCE_THASH
560	br.many kvm_virtualization_fault_back
561#endif
562	extr.u r17=r25,20,7		// get r3 from opcode in r25
563	extr.u r18=r25,6,7		// get r1 from opcode in r25
564	addl r20=@gprel(asm_mov_from_reg),gp
565	;;
566	adds r30=kvm_asm_thash_back1-asm_mov_from_reg,r20
567	shladd r17=r17,4,r20	// get addr of MOVE_FROM_REG(r17)
568	adds r16=VMM_VPD_BASE_OFFSET,r21	// get vcpu.arch.priveregs
569	;;
570	mov r24=b0
571	;;
572	ld8 r16=[r16]		// get VPD addr
573	mov b0=r17
574	br.many b0			// r19 return value
575	;;
576kvm_asm_thash_back1:
577	shr.u r23=r19,61		// get RR number
578	adds r28=VMM_VCPU_VRR0_OFFSET,r21	// get vcpu->arch.vrr[0]'s addr
579	adds r16=VMM_VPD_VPTA_OFFSET,r16	// get vpta
580	;;
581	shladd r27=r23,3,r28	// get vcpu->arch.vrr[r23]'s addr
582	ld8 r17=[r16]		// get PTA
583	mov r26=1
584	;;
585	extr.u r29=r17,2,6	// get pta.size
586	ld8 r28=[r27]		// get vcpu->arch.vrr[r23]'s value
587	;;
588	mov b0=r24
589	//Fallback to C if pta.vf is set
590	tbit.nz p6,p0=r17, 8
591	;;
592	(p6) mov r24=EVENT_THASH
593	(p6) br.cond.dpnt.many kvm_virtualization_fault_back
594	extr.u r28=r28,2,6	// get rr.ps
595	shl r22=r26,r29		// 1UL << pta.size
596	;;
597	shr.u r23=r19,r28	// vaddr >> rr.ps
598	adds r26=3,r29		// pta.size + 3
599	shl r27=r17,3		// pta << 3
600	;;
601	shl r23=r23,3		// (vaddr >> rr.ps) << 3
602	shr.u r27=r27,r26	// (pta << 3) >> (pta.size+3)
603	movl r16=7<<61
604	;;
605	adds r22=-1,r22		// (1UL << pta.size) - 1
606	shl r27=r27,r29		// ((pta<<3)>>(pta.size+3))<<pta.size
607	and r19=r19,r16		// vaddr & VRN_MASK
608	;;
609	and r22=r22,r23		// vhpt_offset
610	or r19=r19,r27 // (vadr&VRN_MASK)|(((pta<<3)>>(pta.size + 3))<<pta.size)
611	adds r26=asm_mov_to_reg-asm_mov_from_reg,r20
612	;;
613	or r19=r19,r22		// calc pval
614	shladd r17=r18,4,r26
615	adds r30=kvm_resume_to_guest-asm_mov_from_reg,r20
616	;;
617	mov b0=r17
618	br.many b0
619END(kvm_asm_thash)
620
621#define MOV_TO_REG0	\
622{;			\
623	nop.b 0x0;		\
624	nop.b 0x0;		\
625	nop.b 0x0;		\
626	;;			\
627};
628
629
630#define MOV_TO_REG(n)	\
631{;			\
632	mov r##n##=r19;	\
633	mov b0=r30;	\
634	br.sptk.many b0;	\
635	;;			\
636};
637
638
639#define MOV_FROM_REG(n)	\
640{;				\
641	mov r19=r##n##;		\
642	mov b0=r30;		\
643	br.sptk.many b0;		\
644	;;				\
645};
646
647
648#define MOV_TO_BANK0_REG(n)			\
649ENTRY_MIN_ALIGN(asm_mov_to_bank0_reg##n##);	\
650{;						\
651	mov r26=r2;				\
652	mov r2=r19;				\
653	bsw.1;					\
654	;;						\
655};						\
656{;						\
657	mov r##n##=r2;				\
658	nop.b 0x0;					\
659	bsw.0;					\
660	;;						\
661};						\
662{;						\
663	mov r2=r26;				\
664	mov b0=r30;				\
665	br.sptk.many b0;				\
666	;;						\
667};						\
668END(asm_mov_to_bank0_reg##n##)
669
670
671#define MOV_FROM_BANK0_REG(n)			\
672ENTRY_MIN_ALIGN(asm_mov_from_bank0_reg##n##);	\
673{;						\
674	mov r26=r2;				\
675	nop.b 0x0;					\
676	bsw.1;					\
677	;;						\
678};						\
679{;						\
680	mov r2=r##n##;				\
681	nop.b 0x0;					\
682	bsw.0;					\
683	;;						\
684};						\
685{;						\
686	mov r19=r2;				\
687	mov r2=r26;				\
688	mov b0=r30;				\
689};						\
690{;						\
691	nop.b 0x0;					\
692	nop.b 0x0;					\
693	br.sptk.many b0;				\
694	;;						\
695};						\
696END(asm_mov_from_bank0_reg##n##)
697
698
699#define JMP_TO_MOV_TO_BANK0_REG(n)		\
700{;						\
701	nop.b 0x0;					\
702	nop.b 0x0;					\
703	br.sptk.many asm_mov_to_bank0_reg##n##;	\
704	;;						\
705}
706
707
708#define JMP_TO_MOV_FROM_BANK0_REG(n)		\
709{;						\
710	nop.b 0x0;					\
711	nop.b 0x0;					\
712	br.sptk.many asm_mov_from_bank0_reg##n##;	\
713	;;						\
714}
715
716
717MOV_FROM_BANK0_REG(16)
718MOV_FROM_BANK0_REG(17)
719MOV_FROM_BANK0_REG(18)
720MOV_FROM_BANK0_REG(19)
721MOV_FROM_BANK0_REG(20)
722MOV_FROM_BANK0_REG(21)
723MOV_FROM_BANK0_REG(22)
724MOV_FROM_BANK0_REG(23)
725MOV_FROM_BANK0_REG(24)
726MOV_FROM_BANK0_REG(25)
727MOV_FROM_BANK0_REG(26)
728MOV_FROM_BANK0_REG(27)
729MOV_FROM_BANK0_REG(28)
730MOV_FROM_BANK0_REG(29)
731MOV_FROM_BANK0_REG(30)
732MOV_FROM_BANK0_REG(31)
733
734
735// mov from reg table
736ENTRY(asm_mov_from_reg)
737	MOV_FROM_REG(0)
738	MOV_FROM_REG(1)
739	MOV_FROM_REG(2)
740	MOV_FROM_REG(3)
741	MOV_FROM_REG(4)
742	MOV_FROM_REG(5)
743	MOV_FROM_REG(6)
744	MOV_FROM_REG(7)
745	MOV_FROM_REG(8)
746	MOV_FROM_REG(9)
747	MOV_FROM_REG(10)
748	MOV_FROM_REG(11)
749	MOV_FROM_REG(12)
750	MOV_FROM_REG(13)
751	MOV_FROM_REG(14)
752	MOV_FROM_REG(15)
753	JMP_TO_MOV_FROM_BANK0_REG(16)
754	JMP_TO_MOV_FROM_BANK0_REG(17)
755	JMP_TO_MOV_FROM_BANK0_REG(18)
756	JMP_TO_MOV_FROM_BANK0_REG(19)
757	JMP_TO_MOV_FROM_BANK0_REG(20)
758	JMP_TO_MOV_FROM_BANK0_REG(21)
759	JMP_TO_MOV_FROM_BANK0_REG(22)
760	JMP_TO_MOV_FROM_BANK0_REG(23)
761	JMP_TO_MOV_FROM_BANK0_REG(24)
762	JMP_TO_MOV_FROM_BANK0_REG(25)
763	JMP_TO_MOV_FROM_BANK0_REG(26)
764	JMP_TO_MOV_FROM_BANK0_REG(27)
765	JMP_TO_MOV_FROM_BANK0_REG(28)
766	JMP_TO_MOV_FROM_BANK0_REG(29)
767	JMP_TO_MOV_FROM_BANK0_REG(30)
768	JMP_TO_MOV_FROM_BANK0_REG(31)
769	MOV_FROM_REG(32)
770	MOV_FROM_REG(33)
771	MOV_FROM_REG(34)
772	MOV_FROM_REG(35)
773	MOV_FROM_REG(36)
774	MOV_FROM_REG(37)
775	MOV_FROM_REG(38)
776	MOV_FROM_REG(39)
777	MOV_FROM_REG(40)
778	MOV_FROM_REG(41)
779	MOV_FROM_REG(42)
780	MOV_FROM_REG(43)
781	MOV_FROM_REG(44)
782	MOV_FROM_REG(45)
783	MOV_FROM_REG(46)
784	MOV_FROM_REG(47)
785	MOV_FROM_REG(48)
786	MOV_FROM_REG(49)
787	MOV_FROM_REG(50)
788	MOV_FROM_REG(51)
789	MOV_FROM_REG(52)
790	MOV_FROM_REG(53)
791	MOV_FROM_REG(54)
792	MOV_FROM_REG(55)
793	MOV_FROM_REG(56)
794	MOV_FROM_REG(57)
795	MOV_FROM_REG(58)
796	MOV_FROM_REG(59)
797	MOV_FROM_REG(60)
798	MOV_FROM_REG(61)
799	MOV_FROM_REG(62)
800	MOV_FROM_REG(63)
801	MOV_FROM_REG(64)
802	MOV_FROM_REG(65)
803	MOV_FROM_REG(66)
804	MOV_FROM_REG(67)
805	MOV_FROM_REG(68)
806	MOV_FROM_REG(69)
807	MOV_FROM_REG(70)
808	MOV_FROM_REG(71)
809	MOV_FROM_REG(72)
810	MOV_FROM_REG(73)
811	MOV_FROM_REG(74)
812	MOV_FROM_REG(75)
813	MOV_FROM_REG(76)
814	MOV_FROM_REG(77)
815	MOV_FROM_REG(78)
816	MOV_FROM_REG(79)
817	MOV_FROM_REG(80)
818	MOV_FROM_REG(81)
819	MOV_FROM_REG(82)
820	MOV_FROM_REG(83)
821	MOV_FROM_REG(84)
822	MOV_FROM_REG(85)
823	MOV_FROM_REG(86)
824	MOV_FROM_REG(87)
825	MOV_FROM_REG(88)
826	MOV_FROM_REG(89)
827	MOV_FROM_REG(90)
828	MOV_FROM_REG(91)
829	MOV_FROM_REG(92)
830	MOV_FROM_REG(93)
831	MOV_FROM_REG(94)
832	MOV_FROM_REG(95)
833	MOV_FROM_REG(96)
834	MOV_FROM_REG(97)
835	MOV_FROM_REG(98)
836	MOV_FROM_REG(99)
837	MOV_FROM_REG(100)
838	MOV_FROM_REG(101)
839	MOV_FROM_REG(102)
840	MOV_FROM_REG(103)
841	MOV_FROM_REG(104)
842	MOV_FROM_REG(105)
843	MOV_FROM_REG(106)
844	MOV_FROM_REG(107)
845	MOV_FROM_REG(108)
846	MOV_FROM_REG(109)
847	MOV_FROM_REG(110)
848	MOV_FROM_REG(111)
849	MOV_FROM_REG(112)
850	MOV_FROM_REG(113)
851	MOV_FROM_REG(114)
852	MOV_FROM_REG(115)
853	MOV_FROM_REG(116)
854	MOV_FROM_REG(117)
855	MOV_FROM_REG(118)
856	MOV_FROM_REG(119)
857	MOV_FROM_REG(120)
858	MOV_FROM_REG(121)
859	MOV_FROM_REG(122)
860	MOV_FROM_REG(123)
861	MOV_FROM_REG(124)
862	MOV_FROM_REG(125)
863	MOV_FROM_REG(126)
864	MOV_FROM_REG(127)
865END(asm_mov_from_reg)
866
867
868/* must be in bank 0
869 * parameter:
870 * r31: pr
871 * r24: b0
872 */
873ENTRY(kvm_resume_to_guest_with_sync)
874	adds r19=VMM_VPD_BASE_OFFSET,r21
875	mov r16 = r31
876	mov r17 = r24
877	;;
878{.mii
879	ld8 r25 =[r19]
880	nop 0x0
881	mov r24 = ip
882	;;
883}
884{.mmb
885	add r24 =0x20, r24
886	nop 0x0
887	br.sptk.many kvm_vps_sync_write
888}
889
890	mov r31 = r16
891	mov r24 =r17
892	;;
893	br.sptk.many kvm_resume_to_guest
894END(kvm_resume_to_guest_with_sync)
895
896ENTRY(kvm_resume_to_guest)
897	adds r16 = VMM_VCPU_SAVED_GP_OFFSET,r21
898	;;
899	ld8 r1 =[r16]
900	adds r20 = VMM_VCPU_VSA_BASE_OFFSET,r21
901	;;
902	mov r16=cr.ipsr
903	;;
904	ld8 r20 = [r20]
905	adds r19=VMM_VPD_BASE_OFFSET,r21
906	;;
907	ld8 r25=[r19]
908	extr.u r17=r16,IA64_PSR_RI_BIT,2
909	tbit.nz p6,p7=r16,IA64_PSR_RI_BIT+1
910	;;
911	(p6) mov r18=cr.iip
912	(p6) mov r17=r0
913	;;
914	(p6) add r18=0x10,r18
915	(p7) add r17=1,r17
916	;;
917	(p6) mov cr.iip=r18
918	dep r16=r17,r16,IA64_PSR_RI_BIT,2
919	;;
920	mov cr.ipsr=r16
921	adds r19= VPD_VPSR_START_OFFSET,r25
922	add r28=PAL_VPS_RESUME_NORMAL,r20
923	add r29=PAL_VPS_RESUME_HANDLER,r20
924	;;
925	ld8 r19=[r19]
926	mov b0=r29
927	mov r27=cr.isr
928	;;
929	tbit.z p6,p7 = r19,IA64_PSR_IC_BIT		// p7=vpsr.ic
930	shr r27=r27,IA64_ISR_IR_BIT
931	;;
932	(p6) ld8 r26=[r25]
933	(p7) mov b0=r28
934	;;
935	(p6) dep r26=r27,r26,63,1
936	mov pr=r31,-2
937	br.sptk.many b0             // call pal service
938	;;
939END(kvm_resume_to_guest)
940
941
942MOV_TO_BANK0_REG(16)
943MOV_TO_BANK0_REG(17)
944MOV_TO_BANK0_REG(18)
945MOV_TO_BANK0_REG(19)
946MOV_TO_BANK0_REG(20)
947MOV_TO_BANK0_REG(21)
948MOV_TO_BANK0_REG(22)
949MOV_TO_BANK0_REG(23)
950MOV_TO_BANK0_REG(24)
951MOV_TO_BANK0_REG(25)
952MOV_TO_BANK0_REG(26)
953MOV_TO_BANK0_REG(27)
954MOV_TO_BANK0_REG(28)
955MOV_TO_BANK0_REG(29)
956MOV_TO_BANK0_REG(30)
957MOV_TO_BANK0_REG(31)
958
959
960// mov to reg table
961ENTRY(asm_mov_to_reg)
962	MOV_TO_REG0
963	MOV_TO_REG(1)
964	MOV_TO_REG(2)
965	MOV_TO_REG(3)
966	MOV_TO_REG(4)
967	MOV_TO_REG(5)
968	MOV_TO_REG(6)
969	MOV_TO_REG(7)
970	MOV_TO_REG(8)
971	MOV_TO_REG(9)
972	MOV_TO_REG(10)
973	MOV_TO_REG(11)
974	MOV_TO_REG(12)
975	MOV_TO_REG(13)
976	MOV_TO_REG(14)
977	MOV_TO_REG(15)
978	JMP_TO_MOV_TO_BANK0_REG(16)
979	JMP_TO_MOV_TO_BANK0_REG(17)
980	JMP_TO_MOV_TO_BANK0_REG(18)
981	JMP_TO_MOV_TO_BANK0_REG(19)
982	JMP_TO_MOV_TO_BANK0_REG(20)
983	JMP_TO_MOV_TO_BANK0_REG(21)
984	JMP_TO_MOV_TO_BANK0_REG(22)
985	JMP_TO_MOV_TO_BANK0_REG(23)
986	JMP_TO_MOV_TO_BANK0_REG(24)
987	JMP_TO_MOV_TO_BANK0_REG(25)
988	JMP_TO_MOV_TO_BANK0_REG(26)
989	JMP_TO_MOV_TO_BANK0_REG(27)
990	JMP_TO_MOV_TO_BANK0_REG(28)
991	JMP_TO_MOV_TO_BANK0_REG(29)
992	JMP_TO_MOV_TO_BANK0_REG(30)
993	JMP_TO_MOV_TO_BANK0_REG(31)
994	MOV_TO_REG(32)
995	MOV_TO_REG(33)
996	MOV_TO_REG(34)
997	MOV_TO_REG(35)
998	MOV_TO_REG(36)
999	MOV_TO_REG(37)
1000	MOV_TO_REG(38)
1001	MOV_TO_REG(39)
1002	MOV_TO_REG(40)
1003	MOV_TO_REG(41)
1004	MOV_TO_REG(42)
1005	MOV_TO_REG(43)
1006	MOV_TO_REG(44)
1007	MOV_TO_REG(45)
1008	MOV_TO_REG(46)
1009	MOV_TO_REG(47)
1010	MOV_TO_REG(48)
1011	MOV_TO_REG(49)
1012	MOV_TO_REG(50)
1013	MOV_TO_REG(51)
1014	MOV_TO_REG(52)
1015	MOV_TO_REG(53)
1016	MOV_TO_REG(54)
1017	MOV_TO_REG(55)
1018	MOV_TO_REG(56)
1019	MOV_TO_REG(57)
1020	MOV_TO_REG(58)
1021	MOV_TO_REG(59)
1022	MOV_TO_REG(60)
1023	MOV_TO_REG(61)
1024	MOV_TO_REG(62)
1025	MOV_TO_REG(63)
1026	MOV_TO_REG(64)
1027	MOV_TO_REG(65)
1028	MOV_TO_REG(66)
1029	MOV_TO_REG(67)
1030	MOV_TO_REG(68)
1031	MOV_TO_REG(69)
1032	MOV_TO_REG(70)
1033	MOV_TO_REG(71)
1034	MOV_TO_REG(72)
1035	MOV_TO_REG(73)
1036	MOV_TO_REG(74)
1037	MOV_TO_REG(75)
1038	MOV_TO_REG(76)
1039	MOV_TO_REG(77)
1040	MOV_TO_REG(78)
1041	MOV_TO_REG(79)
1042	MOV_TO_REG(80)
1043	MOV_TO_REG(81)
1044	MOV_TO_REG(82)
1045	MOV_TO_REG(83)
1046	MOV_TO_REG(84)
1047	MOV_TO_REG(85)
1048	MOV_TO_REG(86)
1049	MOV_TO_REG(87)
1050	MOV_TO_REG(88)
1051	MOV_TO_REG(89)
1052	MOV_TO_REG(90)
1053	MOV_TO_REG(91)
1054	MOV_TO_REG(92)
1055	MOV_TO_REG(93)
1056	MOV_TO_REG(94)
1057	MOV_TO_REG(95)
1058	MOV_TO_REG(96)
1059	MOV_TO_REG(97)
1060	MOV_TO_REG(98)
1061	MOV_TO_REG(99)
1062	MOV_TO_REG(100)
1063	MOV_TO_REG(101)
1064	MOV_TO_REG(102)
1065	MOV_TO_REG(103)
1066	MOV_TO_REG(104)
1067	MOV_TO_REG(105)
1068	MOV_TO_REG(106)
1069	MOV_TO_REG(107)
1070	MOV_TO_REG(108)
1071	MOV_TO_REG(109)
1072	MOV_TO_REG(110)
1073	MOV_TO_REG(111)
1074	MOV_TO_REG(112)
1075	MOV_TO_REG(113)
1076	MOV_TO_REG(114)
1077	MOV_TO_REG(115)
1078	MOV_TO_REG(116)
1079	MOV_TO_REG(117)
1080	MOV_TO_REG(118)
1081	MOV_TO_REG(119)
1082	MOV_TO_REG(120)
1083	MOV_TO_REG(121)
1084	MOV_TO_REG(122)
1085	MOV_TO_REG(123)
1086	MOV_TO_REG(124)
1087	MOV_TO_REG(125)
1088	MOV_TO_REG(126)
1089	MOV_TO_REG(127)
1090END(asm_mov_to_reg)
1091