[IA64] Implement hyper_get_psr
authorawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>
Fri, 12 Jan 2007 20:01:25 +0000 (13:01 -0700)
committerawilliam@xenbuild2.aw <awilliam@xenbuild2.aw>
Fri, 12 Jan 2007 20:01:25 +0000 (13:01 -0700)
Mov from psr is used frequently by xeno.

Signed-of-by: Anthony Xu <anthony.xu@intel.com>
linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S
linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S
linux-2.6-xen-sparse/arch/ia64/xen/xenpal.S
linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h
xen/arch/ia64/asm-xsi-offsets.c
xen/arch/ia64/xen/hyperprivop.S

index 07399d30c83719a10a6f473787e776169786c682..be2cb570b7916b22260ff4366b30a07dc118de44 100644 (file)
@@ -8,6 +8,19 @@
 #include <asm/processor.h>
 #include <asm/asmmacro.h>
 
+GLOBAL_ENTRY(xen_get_psr)
+       movl r8=running_on_xen;;
+       ld4 r8=[r8];;
+       cmp.eq p7,p0=r8,r0;;
+(p7)   mov r8=psr;;
+(p7)   br.ret.sptk.many rp
+       ;;
+       XEN_HYPER_GET_PSR
+       ;;
+       br.ret.sptk.many rp
+       ;;
+END(xen_get_psr)
+
 GLOBAL_ENTRY(xen_get_ivr)
        movl r8=running_on_xen;;
        ld4 r8=[r8];;
index 4d468c70f91f4be54345acf6b72f685d6ac808ae..f0a75468fa2af1d8b96d4e4a7b6944683647c6ef 100644 (file)
@@ -412,7 +412,16 @@ ENTRY(ia64_leave_syscall)
 (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
        ;;
        ld8 r26=[r2],PT(B0)-PT(AR_PFS)  // M0|1 load ar.pfs
+#ifdef CONFIG_XEN
+(pKStk)        mov r21=r8
+(pKStk)        XEN_HYPER_GET_PSR
+       ;;
+(pKStk)        mov r22=r8
+(pKStk)        mov r8=r21
+       ;;
+#else    
 (pKStk)        mov r22=psr                     // M2   read PSR now that interrupts are disabled
+#endif
        nop 0
        ;;
        ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0
@@ -642,7 +651,16 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        adds r16=PT(CR_IPSR)+16,r12
        adds r17=PT(CR_IIP)+16,r12
 
+#ifdef CONFIG_XEN    
+(pKStk)        mov r29=r8
+(pKStk)        XEN_HYPER_GET_PSR
+       ;;
+(pKStk)        mov r22=r8
+(pKStk)        mov r8=r29
+       ;;
+#else
 (pKStk)        mov r22=psr             // M2 read PSR now that interrupts are disabled
+#endif
        nop.i 0
        nop.i 0
        ;;
index 5208a3d9d0cd474270dc8b41584ddb1577697abb..d8ebfb994a7c65d920e545a39e51d2ced815269c 100644 (file)
@@ -33,7 +33,16 @@ GLOBAL_ENTRY(xen_pal_call_static)
        mov loc4=ar.rsc                 // save RSE configuration
        ;;
        mov ar.rsc=0                    // put RSE in enforced lazy, LE mode
+#ifdef CONFIG_XEN
+       mov r9 = r8
+       XEN_HYPER_GET_PSR
+       ;;
+       mov loc3 = r8
+       mov r8 = r9
+       ;;
+#else    
        mov loc3 = psr
+#endif    
        mov loc0 = rp
        .body
        mov r30 = in2
index 4270894a1e56cbf99951bfdd49ab3256eacb9a14..19624f5ba31ff80fb8ceff3a9111fcf166271602 100644 (file)
@@ -182,6 +182,7 @@ extern void xen_set_eflag(unsigned long);   /* see xen_ia64_setreg */
  * be properly handled by Xen, some are frequent enough that we use
  * hyperprivops for performance. */
 
+extern unsigned long xen_get_psr(void);
 extern unsigned long xen_get_ivr(void);
 extern unsigned long xen_get_tpr(void);
 extern void xen_set_itm(unsigned long);
@@ -201,6 +202,11 @@ extern void xen_ptcga(unsigned long addr, unsigned long size);
        __u64 ia64_intri_res;                                           \
                                                                        \
        switch(regnum) {                                                \
+       case _IA64_REG_PSR:                                             \
+               ia64_intri_res = (is_running_on_xen()) ?                        \
+                       xen_get_psr() :                                 \
+                       __ia64_getreg(regnum);                          \
+               break;                                                  \
        case _IA64_REG_CR_IVR:                                          \
                ia64_intri_res = (is_running_on_xen()) ?                        \
                        xen_get_ivr() :                                 \
index f9d22358f2ebefd61df8b5ba60739ddf4361f3f1..e3696909da6ded71e2d4af2d07a59b931c5c0a32 100755 (executable)
@@ -62,6 +62,7 @@ void foo(void)
        DEFINE_MAPPED_REG_OFS(XSI_ITV_OFS, itv);
        DEFINE_MAPPED_REG_OFS(XSI_PTA_OFS, pta);
        DEFINE_MAPPED_REG_OFS(XSI_PSR_IC_OFS, interrupt_collection_enabled);
+       DEFINE_MAPPED_REG_OFS(XSI_VPSR_PP_OFS, vpsr_pp);
        DEFINE_MAPPED_REG_OFS(XSI_METAPHYS_OFS, metaphysical_mode);
        DEFINE_MAPPED_REG_OFS(XSI_BANKNUM_OFS, banknum);
        DEFINE_MAPPED_REG_OFS(XSI_BANK0_R16_OFS, bank0_regs[0]);
index ca86b0432a6f6146c1a892ad3c123834edbf58de..06f154366483b0c101eed26e349355dbca38e2af 100644 (file)
@@ -140,6 +140,11 @@ GLOBAL_ENTRY(fast_hyperprivop)
 (p7)   br.sptk.many hyper_get_rr
        ;;
 
+       // HYPERPRIVOP_GET_PSR?
+       cmp.eq p7,p6=HYPERPRIVOP_GET_PSR,r17
+(p7)   br.sptk.many hyper_get_psr
+       ;;
+
        // HYPERPRIVOP_PTC_GA?
        cmp.eq p7,p6=HYPERPRIVOP_PTC_GA,r17
 (p7)   br.sptk.many hyper_ptc_ga
@@ -1460,6 +1465,53 @@ ENTRY(hyper_set_itm)
        ;;
 END(hyper_set_itm)
 
+ENTRY(hyper_get_psr)
+#ifdef FAST_HYPERPRIVOP_CNT
+       movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_GET_PSR);;
+       ld4 r21=[r20];;
+       adds r21=1,r21;;
+       st4 [r20]=r21;;
+#endif
+       mov r24=cr.ipsr
+       movl r8=0x18ffffffff;;
+       // only return PSR{36:35,31:0}
+       and r8=r8,r24
+       // set vpsr.ic
+       ld4 r21=[r18];;
+       dep r8=r21,r8,IA64_PSR_IC_BIT,1
+       // set vpsr.pp
+       adds r20=XSI_VPSR_PP_OFS-XSI_PSR_IC_OFS,r18 ;;
+       ld1 r21=[r20];;
+       dep r8=r21,r8,IA64_PSR_PP_BIT,1
+       // set vpsr.dt
+       adds r20=XSI_METAPHYS_OFS-XSI_PSR_IC_OFS,r18 ;;
+       ld4 r21=[r20];;
+       cmp.ne p6,p0=r21,r0
+       ;;
+(p6)   dep.z r8=r8,IA64_PSR_DT_BIT,1
+       // set vpsr.i
+       adds r20=XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS,r18 ;;
+       ld8 r20=[r20];;
+       ld1 r21=[r20];;
+       dep r8=r21,r8,IA64_PSR_I_BIT,1
+       ;;
+       mov r25=cr.iip
+       extr.u r26=r24,41,2 ;;
+       cmp.eq p6,p7=2,r26 ;;
+(p6)   mov r26=0
+(p6)   adds r25=16,r25
+(p7)   adds r26=1,r26
+       ;;
+       dep r24=r26,r24,41,2
+       ;;
+       mov cr.ipsr=r24
+       mov cr.iip=r25
+       mov pr=r31,-1 ;;
+       rfi
+       ;;
+END(hyper_get_psr)
+
+    
 ENTRY(hyper_get_rr)
 #ifdef FAST_HYPERPRIVOP_CNT
        movl r20=FAST_HYPERPRIVOP_PERFC(HYPERPRIVOP_GET_RR);;