ia64/xen-unstable

view xen/arch/ia64/vmx_entry.S @ 5797:ca44d2dbb273

Intel's pre-bk->hg transition patches
Signed-off-by Eddie Dong <Eddie.dong@intel.com>
Signed-off-by Anthony Xu <Anthony.xu@intel.com>
Signed-off-by Kevin Tian <Kevin.tian@intel.com>
author djm@kirby.fc.hp.com
date Sat Jul 09 07:58:56 2005 -0700 (2005-07-09)
parents c91f74efda05
children a83ac0806d6b
line source
1 /* -*- Mode:C; c-basic-offset:4; tab-width:4; indent-tabs-mode:nil -*- */
2 /*
3 * vmx_entry.S:
4 * Copyright (c) 2005, Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place - Suite 330, Boston, MA 02111-1307 USA.
18 *
19 * Xuefei Xu (Anthony Xu) (anthony.xu@intel.com)
20 * Kun Tian (Kevin Tian) (kevin.tian@intel.com)
21 */
23 #ifndef VCPU_TLB_SHIFT
24 #define VCPU_TLB_SHIFT 22
25 #endif
26 #include <linux/config.h>
27 #include <asm/asmmacro.h>
28 #include <asm/cache.h>
29 #include <asm/kregs.h>
30 #include <asm/offsets.h>
31 #include <asm/pgtable.h>
32 #include <asm/percpu.h>
33 #include <asm/processor.h>
34 #include <asm/thread_info.h>
35 #include <asm/unistd.h>
37 #include "vmx_minstate.h"
39 /*
40 * prev_task <- vmx_ia64_switch_to(struct task_struct *next)
41 * With Ingo's new scheduler, interrupts are disabled when this routine gets
42 * called. The code starting at .map relies on this. The rest of the code
43 * doesn't care about the interrupt masking status.
44 *
45 * Since we allocate domain stack in xenheap, there's no need to map new
46 * domain's stack since all xenheap is mapped by TR. Another different task
47 * for vmx_ia64_switch_to is to switch to bank0 and change current pointer.
48 */
49 GLOBAL_ENTRY(vmx_ia64_switch_to)
50 .prologue
51 alloc r16=ar.pfs,1,0,0,0
52 DO_SAVE_SWITCH_STACK
53 .body
55 bsw.0 // Switch to bank0, because bank0 r21 is current pointer
56 ;;
57 adds r22=IA64_TASK_THREAD_KSP_OFFSET,r13
58 movl r25=init_task
59 adds r26=IA64_TASK_THREAD_KSP_OFFSET,in0
60 ;;
61 st8 [r22]=sp // save kernel stack pointer of old task
62 ;;
63 /*
64 * TR always mapped this task's page, we can skip doing it again.
65 */
66 ld8 sp=[r26] // load kernel stack pointer of new task
67 mov r21=in0 // update "current" application register
68 mov r8=r13 // return pointer to previously running task
69 mov r13=in0 // set "current" pointer
70 ;;
71 bsw.1
72 ;;
73 DO_LOAD_SWITCH_STACK
75 #ifdef CONFIG_SMP
76 sync.i // ensure "fc"s done by this CPU are visible on other CPUs
77 #endif
78 br.ret.sptk.many rp // boogie on out in new context
79 END(vmx_ia64_switch_to)
81 GLOBAL_ENTRY(ia64_leave_nested)
82 rsm psr.i
83 ;;
84 adds r21=PT(PR)+16,r12
85 ;;
87 lfetch [r21],PT(CR_IPSR)-PT(PR)
88 adds r2=PT(B6)+16,r12
89 adds r3=PT(R16)+16,r12
90 ;;
91 lfetch [r21]
92 ld8 r28=[r2],8 // load b6
93 adds r29=PT(R24)+16,r12
95 ld8.fill r16=[r3]
96 adds r3=PT(AR_CSD)-PT(R16),r3
97 adds r30=PT(AR_CCV)+16,r12
98 ;;
99 ld8.fill r24=[r29]
100 ld8 r15=[r30] // load ar.ccv
101 ;;
102 ld8 r29=[r2],16 // load b7
103 ld8 r30=[r3],16 // load ar.csd
104 ;;
105 ld8 r31=[r2],16 // load ar.ssd
106 ld8.fill r8=[r3],16
107 ;;
108 ld8.fill r9=[r2],16
109 ld8.fill r10=[r3],PT(R17)-PT(R10)
110 ;;
111 ld8.fill r11=[r2],PT(R18)-PT(R11)
112 ld8.fill r17=[r3],16
113 ;;
114 ld8.fill r18=[r2],16
115 ld8.fill r19=[r3],16
116 ;;
117 ld8.fill r20=[r2],16
118 ld8.fill r21=[r3],16
119 mov ar.csd=r30
120 mov ar.ssd=r31
121 ;;
122 rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection
123 invala // invalidate ALAT
124 ;;
125 ld8.fill r22=[r2],24
126 ld8.fill r23=[r3],24
127 mov b6=r28
128 ;;
129 ld8.fill r25=[r2],16
130 ld8.fill r26=[r3],16
131 mov b7=r29
132 ;;
133 ld8.fill r27=[r2],16
134 ld8.fill r28=[r3],16
135 ;;
136 ld8.fill r29=[r2],16
137 ld8.fill r30=[r3],24
138 ;;
139 ld8.fill r31=[r2],PT(F9)-PT(R31)
140 adds r3=PT(F10)-PT(F6),r3
141 ;;
142 ldf.fill f9=[r2],PT(F6)-PT(F9)
143 ldf.fill f10=[r3],PT(F8)-PT(F10)
144 ;;
145 ldf.fill f6=[r2],PT(F7)-PT(F6)
146 ;;
147 ldf.fill f7=[r2],PT(F11)-PT(F7)
148 ldf.fill f8=[r3],32
149 ;;
150 srlz.i // ensure interruption collection is off
151 mov ar.ccv=r15
152 ;;
153 bsw.0 // switch back to bank 0 (no stop bit required beforehand...)
154 ;;
155 ldf.fill f11=[r2]
156 // mov r18=r13
157 // mov r21=r13
158 adds r16=PT(CR_IPSR)+16,r12
159 adds r17=PT(CR_IIP)+16,r12
160 ;;
161 ld8 r29=[r16],16 // load cr.ipsr
162 ld8 r28=[r17],16 // load cr.iip
163 ;;
164 ld8 r30=[r16],16 // load cr.ifs
165 ld8 r25=[r17],16 // load ar.unat
166 ;;
167 ld8 r26=[r16],16 // load ar.pfs
168 ld8 r27=[r17],16 // load ar.rsc
169 cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs
170 ;;
171 ld8 r24=[r16],16 // load ar.rnat (may be garbage)
172 ld8 r23=[r17],16// load ar.bspstore (may be garbage)
173 ;;
174 ld8 r31=[r16],16 // load predicates
175 ld8 r22=[r17],16 // load b0
176 ;;
177 ld8 r19=[r16],16 // load ar.rsc value for "loadrs"
178 ld8.fill r1=[r17],16 // load r1
179 ;;
180 ld8.fill r12=[r16],16
181 ld8.fill r13=[r17],16
182 ;;
183 ld8 r20=[r16],16 // ar.fpsr
184 ld8.fill r15=[r17],16
185 ;;
186 ld8.fill r14=[r16],16
187 ld8.fill r2=[r17]
188 ;;
189 ld8.fill r3=[r16]
190 ;;
191 mov r16=ar.bsp // get existing backing store pointer
192 ;;
193 mov b0=r22
194 mov ar.pfs=r26
195 mov cr.ifs=r30
196 mov cr.ipsr=r29
197 mov ar.fpsr=r20
198 mov cr.iip=r28
199 ;;
200 mov ar.rsc=r27
201 mov ar.unat=r25
202 mov pr=r31,-1
203 rfi
204 END(ia64_leave_nested)
208 GLOBAL_ENTRY(ia64_leave_hypervisor)
209 PT_REGS_UNWIND_INFO(0)
210 /*
211 * work.need_resched etc. mustn't get changed by this CPU before it returns to
212 ;;
213 * user- or fsys-mode, hence we disable interrupts early on:
214 */
215 rsm psr.i
216 ;;
217 alloc loc0=ar.pfs,0,1,1,0
218 adds out0=16,r12
219 ;;
220 br.call.sptk.many b0=leave_hypervisor_tail
221 mov ar.pfs=loc0
222 adds r8=IA64_VPD_BASE_OFFSET,r13
223 ;;
224 ld8 r8=[r8]
225 ;;
226 adds r9=VPD(VPSR),r8
227 ;;
228 ld8 r9=[r9]
229 ;;
230 tbit.z pBN0,pBN1=r9,IA64_PSR_BN_BIT
231 ;;
232 (pBN0) add r7=VPD(VBNAT),r8;
233 (pBN1) add r7=VPD(VNAT),r8;
234 ;;
235 ld8 r7=[r7]
236 ;;
237 mov ar.unat=r7
238 (pBN0) add r4=VPD(VBGR),r8;
239 (pBN1) add r4=VPD(VGR),r8;
240 (pBN0) add r5=VPD(VBGR)+0x8,r8;
241 (pBN1) add r5=VPD(VGR)+0x8,r8;
242 ;;
243 ld8.fill r16=[r4],16
244 ld8.fill r17=[r5],16
245 ;;
246 ld8.fill r18=[r4],16
247 ld8.fill r19=[r5],16
248 ;;
249 ld8.fill r20=[r4],16
250 ld8.fill r21=[r5],16
251 ;;
252 ld8.fill r22=[r4],16
253 ld8.fill r23=[r5],16
254 ;;
255 ld8.fill r24=[r4],16
256 ld8.fill r25=[r5],16
257 ;;
258 ld8.fill r26=[r4],16
259 ld8.fill r27=[r5],16
260 ;;
261 ld8.fill r28=[r4],16
262 ld8.fill r29=[r5],16
263 ;;
264 ld8.fill r30=[r4],16
265 ld8.fill r31=[r5],16
266 ;;
267 bsw.0
268 ;;
269 mov r18=r8 //vpd
270 mov r19=r9 //vpsr
271 adds r20=PT(PR)+16,r12
272 ;;
273 lfetch [r20],PT(CR_IPSR)-PT(PR)
274 adds r16=PT(B6)+16,r12
275 adds r17=PT(B7)+16,r12
276 ;;
277 lfetch [r20]
278 mov r21=r13 // get current
279 ;;
280 ld8 r30=[r16],16 // load b6
281 ld8 r31=[r17],16 // load b7
282 add r20=PT(EML_UNAT)+16,r12
283 ;;
284 ld8 r29=[r20] //load ar_unat
285 mov b6=r30
286 mov b7=r31
287 ld8 r30=[r16],16 //load ar_csd
288 ld8 r31=[r17],16 //load ar_ssd
289 ;;
290 mov ar.unat=r29
291 mov ar.csd=r30
292 mov ar.ssd=r31
293 ;;
294 ld8.fill r8=[r16],16 //load r8
295 ld8.fill r9=[r17],16 //load r9
296 ;;
297 ld8.fill r10=[r16],PT(R1)-PT(R10) //load r10
298 ld8.fill r11=[r17],PT(R12)-PT(R11) //load r11
299 ;;
300 ld8.fill r1=[r16],16 //load r1
301 ld8.fill r12=[r17],16 //load r12
302 ;;
303 ld8.fill r13=[r16],16 //load r13
304 ld8 r30=[r17],16 //load ar_fpsr
305 ;;
306 ld8.fill r15=[r16],16 //load r15
307 ld8.fill r14=[r17],16 //load r14
308 mov ar.fpsr=r30
309 ;;
310 ld8.fill r2=[r16],16 //load r2
311 ld8.fill r3=[r17],16 //load r3
312 ;;
313 /*
314 (pEml) ld8.fill r4=[r16],16 //load r4
315 (pEml) ld8.fill r5=[r17],16 //load r5
316 ;;
317 (pEml) ld8.fill r6=[r16],PT(AR_CCV)-PT(R6) //load r6
318 (pEml) ld8.fill r7=[r17],PT(F7)-PT(R7) //load r7
319 ;;
320 (pNonEml) adds r16=PT(AR_CCV)-PT(R4),r16
321 (pNonEml) adds r17=PT(F7)-PT(R5),r17
322 ;;
323 */
324 ld8.fill r4=[r16],16 //load r4
325 ld8.fill r5=[r17],16 //load r5
326 ;;
327 ld8.fill r6=[r16],PT(AR_CCV)-PT(R6) //load r6
328 ld8.fill r7=[r17],PT(F7)-PT(R7) //load r7
329 ;;
331 ld8 r30=[r16],PT(F6)-PT(AR_CCV)
332 rsm psr.i | psr.ic // initiate turning off of interrupt and interruption collection
333 ;;
334 srlz.i // ensure interruption collection is off
335 ;;
336 invala // invalidate ALAT
337 ;;
338 ldf.fill f6=[r16],32
339 ldf.fill f7=[r17],32
340 ;;
341 ldf.fill f8=[r16],32
342 ldf.fill f9=[r17],32
343 ;;
344 ldf.fill f10=[r16]
345 ldf.fill f11=[r17]
346 ;;
347 mov ar.ccv=r30
348 adds r16=PT(CR_IPSR)-PT(F10),r16
349 adds r17=PT(CR_IIP)-PT(F11),r17
350 ;;
351 ld8 r31=[r16],16 // load cr.ipsr
352 ld8 r30=[r17],16 // load cr.iip
353 ;;
354 ld8 r29=[r16],16 // load cr.ifs
355 ld8 r28=[r17],16 // load ar.unat
356 ;;
357 ld8 r27=[r16],16 // load ar.pfs
358 ld8 r26=[r17],16 // load ar.rsc
359 ;;
360 ld8 r25=[r16],16 // load ar.rnat (may be garbage)
361 ld8 r24=[r17],16// load ar.bspstore (may be garbage)
362 ;;
363 ld8 r23=[r16],16 // load predicates
364 ld8 r22=[r17],PT(RFI_PFS)-PT(B0) // load b0
365 ;;
366 ld8 r20=[r16],16 // load ar.rsc value for "loadrs"
367 ;;
368 //rbs_switch
369 // loadrs has already been shifted
370 alloc r16=ar.pfs,0,0,0,0 // drop current register frame
371 ;;
372 mov ar.rsc=r20
373 ;;
374 loadrs
375 ;;
376 mov ar.bspstore=r24
377 ;;
378 ld8 r24=[r17] //load rfi_pfs
379 mov ar.unat=r28
380 mov ar.rnat=r25
381 mov ar.rsc=r26
382 ;;
383 mov cr.ipsr=r31
384 mov cr.iip=r30
385 mov cr.ifs=r29
386 cmp.ne p6,p0=r24,r0
387 (p6)br.sptk vmx_dorfirfi
388 ;;
389 vmx_dorfirfi_back:
390 mov ar.pfs=r27
392 //vsa_sync_write_start
393 movl r20=__vsa_base
394 ;;
395 ld8 r20=[r20] // read entry point
396 mov r25=r18
397 ;;
398 add r16=PAL_VPS_SYNC_WRITE,r20
399 movl r24=switch_rr7 // calculate return address
400 ;;
401 mov b0=r16
402 br.cond.sptk b0 // call the service
403 ;;
404 // switch rr7 and rr5
405 switch_rr7:
406 adds r24=SWITCH_MRR5_OFFSET, r21
407 adds r26=SWITCH_MRR6_OFFSET, r21
408 adds r16=SWITCH_MRR7_OFFSET ,r21
409 movl r25=(5<<61)
410 movl r27=(6<<61)
411 movl r17=(7<<61)
412 ;;
413 ld8 r24=[r24]
414 ld8 r26=[r26]
415 ld8 r16=[r16]
416 ;;
417 mov rr[r25]=r24
418 mov rr[r27]=r26
419 mov rr[r17]=r16
420 ;;
421 srlz.i
422 ;;
423 add r24=SWITCH_MPTA_OFFSET, r21
424 ;;
425 ld8 r24=[r24]
426 ;;
427 mov cr.pta=r24
428 ;;
429 srlz.i
430 ;;
431 // fall through
432 GLOBAL_ENTRY(ia64_vmm_entry)
433 /*
434 * must be at bank 0
435 * parameter:
436 * r18:vpd
437 * r19:vpsr
438 * r20:__vsa_base
439 * r22:b0
440 * r23:predicate
441 */
442 mov r24=r22
443 mov r25=r18
444 tbit.nz p1,p2 = r19,IA64_PSR_IC_BIT // p1=vpsr.ic
445 ;;
446 (p1) add r29=PAL_VPS_RESUME_NORMAL,r20
447 (p2) add r29=PAL_VPS_RESUME_HANDLER,r20
448 ;;
449 mov pr=r23,-2
450 mov b0=r29
451 ;;
452 br.cond.sptk b0 // call pal service
453 END(ia64_leave_hypervisor)
455 //r24 rfi_pfs
456 //r17 address of rfi_pfs
457 GLOBAL_ENTRY(vmx_dorfirfi)
458 mov r16=ar.ec
459 movl r20 = vmx_dorfirfi_back
460 ;;
461 // clean rfi_pfs
462 st8 [r17]=r0
463 mov b0=r20
464 // pfs.pec=ar.ec
465 dep r24 = r16, r24, 52, 6
466 ;;
467 mov ar.pfs=r24
468 ;;
469 br.ret.sptk b0
470 ;;
471 END(vmx_dorfirfi)
474 #define VMX_PURGE_RR7 0
475 #define VMX_INSERT_RR7 1
476 /*
477 * in0: old rr7
478 * in1: virtual address of xen image
479 * in2: virtual address of vhpt table
480 */
481 GLOBAL_ENTRY(vmx_purge_double_mapping)
482 alloc loc1 = ar.pfs,5,9,0,0
483 mov loc0 = rp
484 movl r8 = 1f
485 ;;
486 movl loc4 = KERNEL_TR_PAGE_SHIFT
487 movl loc5 = VCPU_TLB_SHIFT
488 mov loc6 = psr
489 movl loc7 = XEN_RR7_SWITCH_STUB
490 mov loc8 = (1<<VMX_PURGE_RR7)
491 ;;
492 srlz.i
493 ;;
494 rsm psr.i | psr.ic
495 ;;
496 srlz.i
497 ;;
498 mov ar.rsc = 0
499 mov b6 = loc7
500 mov rp = r8
501 ;;
502 br.sptk b6
503 1:
504 mov ar.rsc = 3
505 mov rp = loc0
506 ;;
507 mov psr.l = loc6
508 ;;
509 srlz.i
510 ;;
511 br.ret.sptk rp
512 END(vmx_purge_double_mapping)
514 /*
515 * in0: new rr7
516 * in1: virtual address of xen image
517 * in2: virtual address of vhpt table
518 * in3: pte entry of xen image
519 * in4: pte entry of vhpt table
520 */
521 GLOBAL_ENTRY(vmx_insert_double_mapping)
522 alloc loc1 = ar.pfs,5,9,0,0
523 mov loc0 = rp
524 movl loc2 = IA64_TR_XEN_IN_DOM // TR number for xen image
525 ;;
526 movl loc3 = IA64_TR_VHPT_IN_DOM // TR number for vhpt table
527 movl r8 = 1f
528 movl loc4 = KERNEL_TR_PAGE_SHIFT
529 ;;
530 movl loc5 = VCPU_TLB_SHIFT
531 mov loc6 = psr
532 movl loc7 = XEN_RR7_SWITCH_STUB
533 ;;
534 srlz.i
535 ;;
536 rsm psr.i | psr.ic
537 mov loc8 = (1<<VMX_INSERT_RR7)
538 ;;
539 srlz.i
540 ;;
541 mov ar.rsc = 0
542 mov b6 = loc7
543 mov rp = r8
544 ;;
545 br.sptk b6
546 1:
547 mov ar.rsc = 3
548 mov rp = loc0
549 ;;
550 mov psr.l = loc6
551 ;;
552 srlz.i
553 ;;
554 br.ret.sptk rp
555 END(vmx_insert_double_mapping)
557 .align PAGE_SIZE
558 /*
559 * Stub to add double mapping for new domain, which shouldn't
560 * access any memory when active. Before reaching this point,
561 * both psr.i/ic is cleared and rse is set in lazy mode.
562 *
563 * in0: new rr7
564 * in1: virtual address of xen image
565 * in2: virtual address of vhpt table
566 * in3: pte entry of xen image
567 * in4: pte entry of vhpt table
568 * loc2: TR number for xen image
569 * loc3: TR number for vhpt table
570 * loc4: page size for xen image
571 * loc5: page size of vhpt table
572 * loc7: free to use
573 * loc8: purge or insert
574 * r8: will contain old rid value
575 */
576 GLOBAL_ENTRY(vmx_switch_rr7)
577 movl loc7 = (7<<61)
578 dep.z loc4 = loc4, 2, 6
579 dep.z loc5 = loc5, 2, 6
580 ;;
581 tbit.nz p6,p7=loc8, VMX_INSERT_RR7
582 mov r8 = rr[loc7]
583 ;;
584 mov rr[loc7] = in0
585 (p6)mov cr.ifa = in1
586 (p6)mov cr.itir = loc4
587 ;;
588 srlz.i
589 ;;
590 (p6)itr.i itr[loc2] = in3
591 (p7)ptr.i in1, loc4
592 ;;
593 (p6)itr.d dtr[loc2] = in3
594 (p7)ptr.d in1, loc4
595 ;;
596 srlz.i
597 ;;
598 (p6)mov cr.ifa = in2
599 (p6)mov cr.itir = loc5
600 ;;
601 (p6)itr.d dtr[loc3] = in4
602 (p7)ptr.d in2, loc5
603 ;;
604 srlz.i
605 ;;
606 mov rr[loc7] = r8
607 ;;
608 srlz.i
609 br.sptk rp
610 END(vmx_switch_rr7)
611 .align PAGE_SIZE