]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/ia64/kernel/ivt.S
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[linux-2.6-omap-h63xx.git] / arch / ia64 / kernel / ivt.S
index 829a43cab79705e998e7aff8f6d577b2e7cede50..6678c49daba3c40fcf9972c572ad6087e4690ce5 100644 (file)
@@ -38,7 +38,6 @@
  * Table is based upon EAS2.6 (Oct 1999)
  */
 
-#include <linux/config.h>
 
 #include <asm/asmmacro.h>
 #include <asm/break.h>
@@ -375,6 +374,7 @@ ENTRY(alt_dtlb_miss)
        movl r19=(((1 << IA64_MAX_PHYS_BITS) - 1) & ~0xfff)
        mov r21=cr.ipsr
        mov r31=pr
+       mov r24=PERCPU_ADDR
        ;;
 #ifdef CONFIG_DISABLE_VHPT
        shr.u r22=r16,61                        // get the region number into r21
@@ -387,22 +387,30 @@ ENTRY(alt_dtlb_miss)
 (p8)   mov r29=b0                              // save b0
 (p8)   br.cond.dptk dtlb_fault
 #endif
+       cmp.ge p10,p11=r16,r24                  // access to per_cpu_data?
+       tbit.z p12,p0=r16,61                    // access to region 6?
+       mov r25=PERCPU_PAGE_SHIFT << 2
+       mov r26=PERCPU_PAGE_SIZE
+       nop.m 0
+       nop.b 0
+       ;;
+(p10)  mov r19=IA64_KR(PER_CPU_DATA)
+(p11)  and r19=r19,r16                         // clear non-ppn fields
        extr.u r23=r21,IA64_PSR_CPL0_BIT,2      // extract psr.cpl
        and r22=IA64_ISR_CODE_MASK,r20          // get the isr.code field
        tbit.nz p6,p7=r20,IA64_ISR_SP_BIT       // is speculation bit on?
-       shr.u r18=r16,57                        // move address bit 61 to bit 4
-       and r19=r19,r16                         // clear ed, reserved bits, and PTE control bits
        tbit.nz p9,p0=r20,IA64_ISR_NA_BIT       // is non-access bit on?
        ;;
-       andcm r18=0x10,r18      // bit 4=~address-bit(61)
+(p10)  sub r19=r19,r26
+(p10)  mov cr.itir=r25
        cmp.ne p8,p0=r0,r23
 (p9)   cmp.eq.or.andcm p6,p7=IA64_ISR_CODE_LFETCH,r22  // check isr.code field
+(p12)  dep r17=-1,r17,4,1                      // set ma=UC for region 6 addr
 (p8)   br.cond.spnt page_fault
 
        dep r21=-1,r21,IA64_PSR_ED_BIT,1
-       or r19=r19,r17          // insert PTE control bits into r19
        ;;
-       or r19=r19,r18          // set bit 4 (uncached) if the access was to region 6
+       or r19=r19,r17          // insert PTE control bits into r19
 (p6)   mov cr.ipsr=r21
        ;;
 (p7)   itc.d r19               // insert the TLB entry
@@ -797,8 +805,13 @@ ENTRY(break_fault)
 
 (p8)   adds r28=16,r28                         // A    switch cr.iip to next bundle
 (p9)   adds r8=1,r8                            // A    increment ei to next slot
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       ;;
+       mov b6=r30                              // I0   setup syscall handler branch reg early
+#else
        nop.i 0
        ;;
+#endif
 
        mov.m r25=ar.unat                       // M2 (5 cyc)
        dep r29=r8,r29,41,2                     // I0   insert new ei into cr.ipsr
@@ -809,7 +822,11 @@ ENTRY(break_fault)
        //
 ///////////////////////////////////////////////////////////////////////
        st1 [r16]=r0                            // M2|3 clear current->thread.on_ustack flag
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       mov.m r30=ar.itc                        // M    get cycle for accounting
+#else
        mov b6=r30                              // I0   setup syscall handler branch reg early
+#endif
        cmp.eq pKStk,pUStk=r0,r17               // A    were we on kernel stacks already?
 
        and r9=_TIF_SYSCALL_TRACEAUDIT,r9       // A    mask trace or audit
@@ -821,6 +838,30 @@ ENTRY(break_fault)
        cmp.eq p14,p0=r9,r0                     // A    are syscalls being traced/audited?
        br.call.sptk.many b7=ia64_syscall_setup // B
 1:
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       // mov.m r30=ar.itc is called in advance, and r13 is current
+       add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13  // A
+       add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13  // A
+(pKStk)        br.cond.spnt .skip_accounting           // B    unlikely skip
+       ;;
+       ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP   // M  get last stamp
+       ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE   // M  time at leave
+       ;;
+       ld8 r20=[r16],TI_AC_STAMP-TI_AC_STIME   // M  cumulated stime
+       ld8 r21=[r17]                           // M  cumulated utime
+       sub r22=r19,r18                         // A  stime before leave
+       ;;
+       st8 [r16]=r30,TI_AC_STIME-TI_AC_STAMP   // M  update stamp
+       sub r18=r30,r19                         // A  elapsed time in user
+       ;;
+       add r20=r20,r22                         // A  sum stime
+       add r21=r21,r18                         // A  sum utime
+       ;;
+       st8 [r16]=r20                           // M  update stime
+       st8 [r17]=r21                           // M  update utime
+       ;;
+.skip_accounting:
+#endif
        mov ar.rsc=0x3                          // M2   set eager mode, pl 0, LE, loadrs=0
        nop 0
        bsw.1                                   // B (6 cyc) regs are saved, switch to bank 1
@@ -920,6 +961,7 @@ END(interrupt)
         *      - r27: saved ar.rsc
         *      - r28: saved cr.iip
         *      - r29: saved cr.ipsr
+        *      - r30: ar.itc for accounting (don't touch)
         *      - r31: saved pr
         *      -  b0: original contents (to be saved)
         * On exit:
@@ -1082,6 +1124,41 @@ END(dispatch_illegal_op_fault)
        DBG_FAULT(16)
        FAULT(16)
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       /*
+        * There is no particular reason for this code to be here, other than
+        * that there happens to be space here that would go unused otherwise.
+        * If this fault ever gets "unreserved", simply moved the following
+        * code to a more suitable spot...
+        *
+        * account_sys_enter is called from SAVE_MIN* macros if accounting is
+        * enabled and if the macro is entered from user mode.
+        */
+ENTRY(account_sys_enter)
+       // mov.m r20=ar.itc is called in advance, and r13 is current
+       add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13
+       add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13
+       ;;
+       ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP   // time at last check in kernel
+       ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE   // time at left from kernel
+        ;;
+       ld8 r23=[r16],TI_AC_STAMP-TI_AC_STIME   // cumulated stime
+       ld8 r21=[r17]                           // cumulated utime
+       sub r22=r19,r18                         // stime before leave kernel
+       ;;
+       st8 [r16]=r20,TI_AC_STIME-TI_AC_STAMP   // update stamp
+       sub r18=r20,r19                         // elapsed time in user mode
+       ;;
+       add r23=r23,r22                         // sum stime
+       add r21=r21,r18                         // sum utime
+       ;;
+       st8 [r16]=r23                           // update stime
+       st8 [r17]=r21                           // update utime
+       ;;
+       br.ret.sptk.many rp
+END(account_sys_enter)
+#endif
+
        .org ia64_ivt+0x4400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4400 Entry 17 (size 64 bundles) Reserved