[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] MCA support - Add percpu data physical addr mca_asm.S



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 2afdc0066df69cf8f1fb4eb1881ae2e9b1c63164
# Parent  dc4a352d2143ba18fbadf8330005fd1fe3700973
[IA64] MCA support - Add percpu data physical addr mca_asm.S

Signed-off-by: Yutaka Ezaki <yutaka.ezaki@xxxxxxxxxxxxxx>
Signed-off-by: Masaki Kanno <kanno.masaki@xxxxxxxxxxxxxx>
Signed-off-by: Kazuhiro Suzuki <kaz@xxxxxxxxxxxxxx>
---
 xen/arch/ia64/linux-xen/mca_asm.S |  152 +++++++++++++++++++++++++++++++++++---
 1 files changed, 142 insertions(+), 10 deletions(-)

diff -r dc4a352d2143 -r 2afdc0066df6 xen/arch/ia64/linux-xen/mca_asm.S
--- a/xen/arch/ia64/linux-xen/mca_asm.S Sun Oct 29 09:27:10 2006 -0700
+++ b/xen/arch/ia64/linux-xen/mca_asm.S Sun Oct 29 09:27:11 2006 -0700
@@ -24,6 +24,9 @@
 #include <asm/processor.h>
 #include <asm/mca_asm.h>
 #include <asm/mca.h>
+#ifdef XEN
+#include <asm/vhpt.h>
+#endif
 
 /*
  * When we get a machine check, the kernel stack pointer is no longer
@@ -50,8 +53,7 @@
  */
 #ifdef XEN
 #define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)         \
-       movl    _tmp=THIS_CPU(ia64_sal_to_os_handoff_state_addr);;      \
-       tpa     _tmp=_tmp;;                             \
+       GET_THIS_PADDR(_tmp, ia64_sal_to_os_handoff_state_addr);;       \
        ld8     _tmp=[_tmp];;                           \
        st8     [_tmp]=r1,0x08;;                        \
        st8     [_tmp]=r8,0x08;;                        \
@@ -72,6 +74,7 @@
        st8     [_tmp]=r12,0x08;;                       \
        st8     [_tmp]=r17,0x08;;                       \
        st8     [_tmp]=r18,0x08
+#endif /* XEN */
 
 /*
  * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
@@ -101,6 +104,24 @@
  *     imots_sal_check_ra=Return address to location within SAL_CHECK
  *
  */
+#ifdef XEN
+#define COLD_BOOT_HANDOFF_STATE(sal_to_os_handoff,os_to_sal_handoff,tmp)\
+       movl    tmp=IA64_MCA_COLD_BOOT;                                 \
+       GET_THIS_PADDR(r2,ia64_sal_to_os_handoff_state_addr);;          \
+       ld8     sal_to_os_handoff=[sal_to_os_handoff];;                 \
+       movl    os_to_sal_handoff=ia64_os_to_sal_handoff_state;;        \
+       dep     os_to_sal_handoff = 0, os_to_sal_handoff, 60, 4;;       \
+       /*DATA_VA_TO_PA(os_to_sal_handoff);;*/                          \
+       st8     [os_to_sal_handoff]=tmp,8;;                             \
+       ld8     tmp=[sal_to_os_handoff],48;;                            \
+       st8     [os_to_sal_handoff]=tmp,8;;                             \
+       movl    tmp=IA64_MCA_SAME_CONTEXT;;                             \
+       st8     [os_to_sal_handoff]=tmp,8;;                             \
+       ld8     tmp=[sal_to_os_handoff],-8;;                            \
+       st8     [os_to_sal_handoff]=tmp,8;;                             \
+       ld8     tmp=[sal_to_os_handoff];;                               \
+       st8     [os_to_sal_handoff]=tmp;;
+#else  /* XEN */
 #define COLD_BOOT_HANDOFF_STATE(sal_to_os_handoff,os_to_sal_handoff,tmp)\
        movl    tmp=IA64_MCA_COLD_BOOT;                                 \
        movl    sal_to_os_handoff=__pa(ia64_sal_to_os_handoff_state);   \
@@ -114,13 +135,13 @@
        st8     [os_to_sal_handoff]=tmp,8;;                             \
        ld8     tmp=[sal_to_os_handoff];;                               \
        st8     [os_to_sal_handoff]=tmp;;
+#endif /* XEN */
 
 #define GET_IA64_MCA_DATA(reg)                                         \
        GET_THIS_PADDR(reg, ia64_mca_data)                              \
        ;;                                                              \
        ld8 reg=[reg]
 
-#endif /* XEN */
        .global ia64_os_mca_dispatch
        .global ia64_os_mca_dispatch_end
 #ifndef XEN
@@ -132,7 +153,40 @@
        .text
        .align 16
 
-#ifndef XEN
+#ifdef XEN
+/*
+ * void set_per_cpu_data(void)
+ * {
+ *   int i;
+ *   for (i = 0; i < 64; i++) {
+ *     if (ia64_mca_tlb_list[i].cr_lid == ia64_getreg(_IA64_REG_CR_LID)) {
+ *       ia64_set_kr(IA64_KR_PER_CPU_DATA, ia64_mca_tlb_list[i].percpu_paddr);
+ *       return;
+ *     }
+ *   }
+ *   while(1); // Endless loop on error
+ * }
+ */
+#define SET_PER_CPU_DATA()                                     \
+       LOAD_PHYSICAL(p0,r2,ia64_mca_tlb_list);;                \
+       mov r7 = r0;                                            \
+       mov r6 = r0;;                                           \
+       adds r3 = IA64_MCA_PERCPU_OFFSET, r2;                   \
+1:     add r4 = r6, r2;                                        \
+       mov r5=cr.lid;;                                         \
+       adds r7 = 1, r7;                                        \
+       ld8 r4 = [r4];;                                         \
+       cmp.ne p6, p7 = r5, r4;                                 \
+       cmp4.lt p8, p9 = NR_CPUS-1, r7;                         \
+(p7)   br.cond.dpnt 3f;                                        \
+       adds r6 = 16, r6;                                       \
+(p9)   br.cond.sptk 1b;                                        \
+2:     br 2b;;                 /* Endless loop on error */     \
+3:     add r4 = r6, r3;;                                       \
+       ld8 r4 = [r4];;                                         \
+       mov ar.k3=r4
+#endif /* XEN */
+
 /*
  * Just the TLB purge part is moved to a separate function
  * so we can re-use the code for cpu hotplug code as well
@@ -221,6 +275,44 @@ 4:
        ;;
        srlz.i
        ;;
+#ifdef XEN
+       // 5. VHPT
+#if VHPT_ENABLED
+       // r25 = __va_ul(vcpu_vhpt_maddr(v));
+       GET_THIS_PADDR(r2,cpu_kr);;
+       add r2=IA64_KR_CURRENT_OFFSET,r2;;
+       ld8 r2=[r2];;
+#ifdef CONFIG_XEN_IA64_PERVCPU_VHPT
+#define HAS_PERVCPU_VHPT_MASK  0x2
+       dep r3=0,r2,60,4;;                      // virtual to physical
+       add r3=IA64_VCPU_DOMAIN_OFFSET,r3;;
+       ld8 r3=[r3];; 
+       dep r3=0,r3,60,4;;                      // virtual to physical
+       add r3=IA64_DOMAIN_FLAGS_OFFSET,r3;;
+       ld8 r3=[r3];; 
+       and r3=HAS_PERVCPU_VHPT_MASK,r3;;
+       cmp.eq p6,p0=r3,r0;;
+(p6)   br.cond.sptk    .not_pervcpu_vhpt
+       add r2=IA64_VCPU_VHPT_MADDR_OFFSET,r2;;
+       dep r2=0,r2,60,4;;                      // virtual to physical
+       ld8 r2=[r2];; 
+       dep r25=-1,r2,60,4;;                    // physical to virtual
+       br.sptk         .percpu_vhpt_done
+#endif
+.not_pervcpu_vhpt:
+       GET_THIS_PADDR(r2, vhpt_paddr);; 
+       ld8 r2=[r2];; 
+       dep r25=-1,r2,60,4;;                    // physical to virtual
+.percpu_vhpt_done:
+       dep r20=0,r25,0,IA64_GRANULE_SHIFT
+       mov r24=IA64_GRANULE_SHIFT<<2
+       ;;
+       ptr.d r20,r24
+       ;;
+       srlz.d
+       ;;
+#endif
+#endif
        // Now branch away to caller.
        br.sptk.many b1
        ;;
@@ -235,6 +327,9 @@ ia64_os_mca_spin:
        cmp.ne  p6,p0=r4,r0
 (p6)   br ia64_os_mca_spin
 
+#ifdef XEN
+       SET_PER_CPU_DATA();;
+#endif
        // Save the SAL to OS MCA handoff state as defined
        // by SAL SPEC 3.0
        // NOTE : The order in which the state gets saved
@@ -250,7 +345,19 @@ begin_os_mca_dump:
 
 ia64_os_mca_done_dump:
 
+#ifdef XEN
+       // Set current to ar.k6
+       GET_THIS_PADDR(r2,cpu_kr);;
+       add r2=IA64_KR_CURRENT_OFFSET,r2;;
+       ld8 r2=[r2];;
+       mov ar.k6=r2;;
+
+       GET_THIS_PADDR(r2,ia64_sal_to_os_handoff_state_addr);;
+       ld8 r2=[r2];;
+       adds r16=56,r2
+#else
        LOAD_PHYSICAL(p0,r16,ia64_sal_to_os_handoff_state+56)
+#endif
        ;;
        ld8 r18=[r16]           // Get processor state parameter on existing 
PALE_CHECK.
        ;;
@@ -342,6 +449,28 @@ ia64_reload_tr:
        ;;
        srlz.d
        ;;
+#ifdef XEN
+       // 5. VHPT
+#if VHPT_ENABLED
+       // r25 = __va_ul(vcpu_vhpt_maddr(v));
+       dep r20=0,r25,0,IA64_GRANULE_SHIFT
+       movl r26=PAGE_KERNEL
+       ;;
+       mov r21=IA64_TR_VHPT
+       dep r22=0,r20,60,4              // physical address of
+                                       // va_vhpt & ~(IA64_GRANULE_SIZE - 1)
+       mov r24=IA64_GRANULE_SHIFT<<2
+       ;;
+       or r23=r22,r26                  // construct PA | page properties
+       mov cr.itir=r24
+       mov cr.ifa=r20
+       ;;
+       itr.d dtr[r21]=r23              // wire in new mapping...
+       ;;
+       srlz.d
+       ;;
+#endif
+#endif
        br.sptk.many done_tlb_purge_and_reload
 err:
        COLD_BOOT_HANDOFF_STATE(r20,r21,r22)
@@ -874,12 +1003,6 @@ end_os_mca_restore:
        br      ia64_os_mca_done_restore;;
 
 //EndStub//////////////////////////////////////////////////////////////////////
-#else
-ia64_os_mca_dispatch:
-1:
-       br.sptk 1b
-ia64_os_mca_dispatch_end:
-#endif /* !XEN */
 
 
 // ok, the issue here is that we need to save state information so
@@ -911,6 +1034,15 @@ ia64_os_mca_dispatch_end:
 
 GLOBAL_ENTRY(ia64_monarch_init_handler)
        .prologue
+#ifdef XEN     /* Need in ia64_monarch_init_handler? */
+       SET_PER_CPU_DATA();;
+
+       // Set current to ar.k6
+       GET_THIS_PADDR(r2,cpu_kr);;
+       add r2=IA64_KR_CURRENT_OFFSET,r2;;
+       ld8 r2=[r2];;
+       mov ar.k6=r2;;
+#endif
        // stash the information the SAL passed to os
        SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
        ;;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.