vserver 1.9.5.x5
[linux-2.6.git] / arch / ia64 / kernel / mca_asm.S
index b5026aa..cf3f801 100644 (file)
@@ -13,6 +13,9 @@
 //                2. Restore current thread pointer to kr6
 //                3. Move stack ptr 16 bytes to conform to C calling convention
 //
+// 04/11/12 Russ Anderson <rja@sgi.com>
+//                Added per cpu MCA/INIT stack save areas.
+//
 #include <linux/config.h>
 #include <linux/threads.h>
 
        ld8     tmp=[sal_to_os_handoff];;                               \
        st8     [os_to_sal_handoff]=tmp;;
 
+#define GET_IA64_MCA_DATA(reg)                                         \
+       GET_THIS_PADDR(reg, ia64_mca_data)                              \
+       ;;                                                              \
+       ld8 reg=[reg]
+
        .global ia64_os_mca_dispatch
        .global ia64_os_mca_dispatch_end
        .global ia64_sal_to_os_handoff_state
        .global ia64_os_to_sal_handoff_state
-       .global ia64_mca_proc_state_dump
-       .global ia64_mca_stack
-       .global ia64_mca_stackframe
-       .global ia64_mca_bspstore
-       .global ia64_init_stack
 
        .text
        .align 16
@@ -146,36 +149,26 @@ ia64_os_mca_done_dump:
        // The following code purges TC and TR entries. Then reload all TC entries.
        // Purge percpu data TC entries.
 begin_tlb_purge_and_reload:
-       mov r16=cr.lid
-       LOAD_PHYSICAL(p0,r17,ia64_mca_tlb_list) // Physical address of ia64_mca_tlb_list
-       mov r19=0
-       mov r20=NR_CPUS
-       ;;
-1:     cmp.eq p6,p7=r19,r20
-(p6)   br.spnt.few err
-       ld8 r18=[r17],IA64_MCA_TLB_INFO_SIZE
-       ;;
-       add r19=1,r19
-       cmp.eq p6,p7=r18,r16
-(p7)   br.sptk.few 1b
-       ;;
-       adds r17=-IA64_MCA_TLB_INFO_SIZE,r17
-       ;;
-       mov r23=r17             // save current ia64_mca_percpu_info addr pointer.
-       adds r17=16,r17
+
+#define O(member)      IA64_CPUINFO_##member##_OFFSET
+
+       GET_THIS_PADDR(r2, cpu_info)    // load phys addr of cpu_info into r2
        ;;
-       ld8 r18=[r17],8         // r18=ptce_base
-       ;;
-       ld4 r19=[r17],4         // r19=ptce_count[0]
+       addl r17=O(PTCE_STRIDE),r2
+       addl r2=O(PTCE_BASE),r2
        ;;
-       ld4 r20=[r17],4         // r20=ptce_count[1]
+       ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));;     // r18=ptce_base
+       ld4 r19=[r2],4                                  // r19=ptce_count[0]
+       ld4 r21=[r17],4                                 // r21=ptce_stride[0]
        ;;
-       ld4 r21=[r17],4         // r21=ptce_stride[0]
+       ld4 r20=[r2]                                    // r20=ptce_count[1]
+       ld4 r22=[r17]                                   // r22=ptce_stride[1]
        mov r24=0
        ;;
-       ld4 r22=[r17],4         // r22=ptce_stride[1]
        adds r20=-1,r20
        ;;
+#undef O
+
 2:
        cmp.ltu p6,p7=r24,r19
 (p7)   br.cond.dpnt.few 4f
@@ -215,9 +208,9 @@ begin_tlb_purge_and_reload:
        srlz.d
        ;;
        // 3. Purge ITR for PAL code.
-       adds r17=48,r23
+       GET_THIS_PADDR(r2, ia64_mca_pal_base)
        ;;
-       ld8 r16=[r17]
+       ld8 r16=[r2]
        mov r18=IA64_GRANULE_SHIFT<<2
        ;;
        ptr.i r16,r18
@@ -260,14 +253,15 @@ begin_tlb_purge_and_reload:
        srlz.d
        ;;
        // 2. Reload DTR register for PERCPU data.
-       adds r17=8,r23
+       GET_THIS_PADDR(r2, ia64_mca_per_cpu_pte)
+       ;;
        movl r16=PERCPU_ADDR            // vaddr
        movl r18=PERCPU_PAGE_SHIFT<<2
        ;;
        mov cr.itir=r18
        mov cr.ifa=r16
        ;;
-       ld8 r18=[r17]                   // pte
+       ld8 r18=[r2]                    // load per-CPU PTE
        mov r16=IA64_TR_PERCPU_DATA;
        ;;
        itr.d dtr[r16]=r18
@@ -275,11 +269,13 @@ begin_tlb_purge_and_reload:
        srlz.d
        ;;
        // 3. Reload ITR for PAL code.
-       adds r17=40,r23
+       GET_THIS_PADDR(r2, ia64_mca_pal_pte)
+       ;;
+       ld8 r18=[r2]                    // load PAL PTE
        ;;
-       ld8 r18=[r17],8                 // pte
+       GET_THIS_PADDR(r2, ia64_mca_pal_base)
        ;;
-       ld8 r16=[r17]                   // vaddr
+       ld8 r16=[r2]                    // load PAL vaddr
        mov r19=IA64_GRANULE_SHIFT<<2
        ;;
        mov cr.itir=r19
@@ -318,17 +314,18 @@ err:
 done_tlb_purge_and_reload:
 
        // Setup new stack frame for OS_MCA handling
-       movl    r2=ia64_mca_bspstore;;  // local bspstore area location in r2
-       DATA_VA_TO_PA(r2);;
-       movl    r3=ia64_mca_stackframe;; // save stack frame to memory in r3
-       DATA_VA_TO_PA(r3);;
+       GET_IA64_MCA_DATA(r2)
+       ;;
+       add r3 = IA64_MCA_CPU_STACKFRAME_OFFSET, r2
+       add r2 = IA64_MCA_CPU_RBSTORE_OFFSET, r2
+       ;;
        rse_switch_context(r6,r3,r2);;  // RSC management in this new context
-       movl    r12=ia64_mca_stack
-       mov     r2=8*1024;;             // stack size must be same as C array
-       add     r12=r2,r12;;            // stack base @ bottom of array
-       adds    r12=-16,r12;;           // allow 16 bytes of scratch
-                                       // (C calling convention)
-       DATA_VA_TO_PA(r12);;
+
+       GET_IA64_MCA_DATA(r2)
+       ;;
+       add r2 = IA64_MCA_CPU_STACK_OFFSET+IA64_MCA_STACK_SIZE-16, r2
+       ;;
+       mov r12=r2              // establish new stack-pointer
 
         // Enter virtual mode from physical mode
        VIRTUAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_begin, r4)
@@ -344,9 +341,10 @@ ia64_os_mca_virtual_begin:
 ia64_os_mca_virtual_end:
 
        // restore the original stack frame here
-       movl    r2=ia64_mca_stackframe  // restore stack frame from memory at r2
+       GET_IA64_MCA_DATA(r2)
+       ;;
+       add r2 = IA64_MCA_CPU_STACKFRAME_OFFSET, r2
        ;;
-       DATA_VA_TO_PA(r2)
        movl    r4=IA64_PSR_MC
        ;;
        rse_return_context(r4,r3,r2)    // switch from interrupt context for RSE
@@ -387,8 +385,10 @@ ia64_os_mca_dispatch_end:
 ia64_os_mca_proc_state_dump:
 // Save bank 1 GRs 16-31 which will be used by c-language code when we switch
 //  to virtual addressing mode.
-       LOAD_PHYSICAL(p0,r2,ia64_mca_proc_state_dump)// convert OS state dump area to physical address
-
+       GET_IA64_MCA_DATA(r2)
+       ;;
+       add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2
+       ;;
 // save ar.NaT
        mov             r5=ar.unat                  // ar.unat
 
@@ -618,9 +618,9 @@ end_os_mca_dump:
 ia64_os_mca_proc_state_restore:
 
 // Restore bank1 GR16-31
-       movl            r2=ia64_mca_proc_state_dump     // Convert virtual address
-       ;;                                              // of OS state dump area
-       DATA_VA_TO_PA(r2)                               // to physical address
+       GET_IA64_MCA_DATA(r2)
+       ;;
+       add r2 = IA64_MCA_CPU_PROC_STATE_DUMP_OFFSET, r2
 
 restore_GRs:                                    // restore bank-1 GRs 16-31
        bsw.1;;
@@ -868,7 +868,7 @@ end_os_mca_restore:
 
 
 GLOBAL_ENTRY(ia64_monarch_init_handler)
-
+       .prologue
        // stash the information the SAL passed to os
        SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(r2)
        ;;
@@ -907,6 +907,7 @@ IVirtual_Switch:
        adds out0=16,sp                         // out0 = pointer to pt_regs
        ;;
        DO_SAVE_SWITCH_STACK
+       .body
        adds out1=16,sp                         // out0 = pointer to switch_stack
 
        br.call.sptk.many rp=ia64_init_handler