parisc: flush pages through tmpalias space
[linux-flexiantxendom0-3.2.10.git] / arch / parisc / kernel / entry.S
index cec6532..e8c119b 100644 (file)
 #include <linux/linkage.h>
 
 #ifdef CONFIG_64BIT
-#define CMPIB           cmpib,*
-#define CMPB            cmpb,*
-#define COND(x)                *x
-
        .level 2.0w
 #else
-#define CMPIB           cmpib,
-#define CMPB            cmpb,
-#define COND(x)                x
-
        .level 2.0
 #endif
 
@@ -98,7 +90,6 @@
         * The "get_stack" macros are responsible for determining the
         * kernel stack value.
         *
-        * For Faults:
         *      If sr7 == 0
         *          Already using a kernel stack, so call the
         *          get_stack_use_r30 macro to push a pt_regs structure
         *          task pointer pointed to by cr30. Set the stack
         *          pointer to point to the end of the task structure.
         *
-        * For Interrupts:
-        *      If sr7 == 0
-        *          Already using a kernel stack, check to see if r30
-        *          is already pointing to the per processor interrupt
-        *          stack. If it is, call the get_stack_use_r30 macro
-        *          to push a pt_regs structure on the stack, and store
-        *          registers there. Otherwise, call get_stack_use_cr31
-        *          to get a pointer to the base of the interrupt stack
-        *          and push a pt_regs structure on that stack.
-        *      else
-        *          Need to set up a kernel stack, so call the
-        *          get_stack_use_cr30 macro to set up a pointer
-        *          to the pt_regs structure contained within the
-        *          task pointer pointed to by cr30. Set the stack
-        *          pointer to point to the end of the task structure.
-        *          N.B: We don't use the interrupt stack for the
-        *          first interrupt from userland, because signals/
-        *          resched's are processed when returning to userland,
-        *          and we can sleep in those cases.
-        *
         * Note that we use shadowed registers for temps until
         * we can save %r26 and %r29. %r26 is used to preserve
         * %r8 (a shadowed register) which temporarily contained
 #ifndef CONFIG_64BIT
        /*
         * naitlb miss interruption handler (parisc 1.1 - 32 bit)
-        *
-        * Note: naitlb misses will be treated
-        * as an ordinary itlb miss for now.
-        * However, note that naitlb misses
-        * have the faulting address in the
-        * IOR/ISR.
         */
 
        .macro  naitlb_11 code
 
        mfctl   %isr,spc
-       b       itlb_miss_11
+       b       naitlb_miss_11
        mfctl   %ior,va
-       /* FIXME: If user causes a naitlb miss, the priv level may not be in
-        * lower bits of va, where the itlb miss handler is expecting them
-        */
 
        .align          32
        .endm
        
        /*
         * naitlb miss interruption handler (parisc 2.0)
-        *
-        * Note: naitlb misses will be treated
-        * as an ordinary itlb miss for now.
-        * However, note that naitlb misses
-        * have the faulting address in the
-        * IOR/ISR.
         */
 
        .macro  naitlb_20 code
 
        mfctl   %isr,spc
 #ifdef CONFIG_64BIT
-       b       itlb_miss_20w
+       b       naitlb_miss_20w
 #else
-       b       itlb_miss_20
+       b       naitlb_miss_20
 #endif
        mfctl   %ior,va
-       /* FIXME: If user causes a naitlb miss, the priv level may not be in
-        * lower bits of va, where the itlb miss handler is expecting them
-        */
 
        .align          32
        .endm
        .align          32
        .endm
 
-       /* The following are simple 32 vs 64 bit instruction
-        * abstractions for the macros */
-       .macro          EXTR    reg1,start,length,reg2
-#ifdef CONFIG_64BIT
-       extrd,u         \reg1,32+\start,\length,\reg2
-#else
-       extrw,u         \reg1,\start,\length,\reg2
-#endif
-       .endm
-
-       .macro          DEP     reg1,start,length,reg2
-#ifdef CONFIG_64BIT
-       depd            \reg1,32+\start,\length,\reg2
-#else
-       depw            \reg1,\start,\length,\reg2
-#endif
-       .endm
-
-       .macro          DEPI    val,start,length,reg
-#ifdef CONFIG_64BIT
-       depdi           \val,32+\start,\length,\reg
-#else
-       depwi           \val,\start,\length,\reg
-#endif
-       .endm
-
        /* In LP64, the space contains part of the upper 32 bits of the
         * fault.  We have to extract this and place it in the va,
         * zeroing the corresponding bits in the space register */
         */
        .macro          L2_ptep pmd,pte,index,va,fault
 #if PT_NLEVELS == 3
-       EXTR            \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
+       extru           \va,31-ASM_PMD_SHIFT,ASM_BITS_PER_PMD,\index
 #else
-       EXTR            \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
+       extru           \va,31-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index
 #endif
-       DEP             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
+       dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
        copy            %r0,\pte
        ldw,s           \index(\pmd),\pmd
        bb,>=,n         \pmd,_PxD_PRESENT_BIT,\fault
-       DEP             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
+       dep             %r0,31,PxD_FLAG_SHIFT,\pmd /* clear flags */
        copy            \pmd,%r9
        SHLREG          %r9,PxD_VALUE_SHIFT,\pmd
-       EXTR            \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
-       DEP             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
+       extru           \va,31-PAGE_SHIFT,ASM_BITS_PER_PTE,\index
+       dep             %r0,31,PAGE_SHIFT,\pmd  /* clear offset */
        shladd          \index,BITS_PER_PTE_ENTRY,\pmd,\pmd
        LDREG           %r0(\pmd),\pte          /* pmd is now pte */
        bb,>=,n         \pte,_PAGE_PRESENT_BIT,\fault
        STREG           \pte,0(\ptep)
        .endm
 
+       /* bitshift difference between a PFN (based on kernel's PAGE_SIZE)
+        * to a CPU TLB 4k PFN (4k => 12 bits to shift) */
+       #define PAGE_ADD_SHIFT  (PAGE_SHIFT-12)
+
+       /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
+       .macro          convert_for_tlb_insert20 pte
+       extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58)+PAGE_ADD_SHIFT,\
+                               64-PAGE_SHIFT-PAGE_ADD_SHIFT,\pte
+       depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,\
+                               (63-58)+PAGE_ADD_SHIFT,\pte
+       .endm
+
        /* Convert the pte and prot to tlb insertion values.  How
         * this happens is quite subtle, read below */
        .macro          make_insert_tlb spc,pte,prot
         * on most of those machines only handles cache transactions.
         */
        extrd,u,*=      \pte,_PAGE_NO_CACHE_BIT+32,1,%r0
-       depi            1,12,1,\prot
+       depdi           1,12,1,\prot
 
        /* Drop prot bits and convert to page addr for iitlbt and idtlbt */
-       extrd,u         \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte
-       depdi           _PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte
+       convert_for_tlb_insert20 \pte
        .endm
 
        /* Identical macro to make_insert_tlb above, except it
 
        /* Get rid of prot bits and convert to page addr for iitlba */
 
-       depi            _PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte
-       extru           \pte,24,25,\pte
+       depi            0,31,ASM_PFN_PTE_SHIFT,\pte
+       SHRREG          \pte,(ASM_PFN_PTE_SHIFT-(31-26)),\pte
        .endm
 
        /* This is for ILP32 PA2.0 only.  The TLB insertion needs
        depdi           0,31,32,\tmp
 #endif
        copy            \va,\tmp1
-       DEPI            0,31,23,\tmp1
+       depi            0,31,23,\tmp1
        cmpb,COND(<>),n \tmp,\tmp1,\fault
-       ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),\prot
+       mfctl           %cr19,\tmp      /* iir */
+       /* get the opcode (first six bits) into \tmp */
+       extrw,u         \tmp,5,6,\tmp
+       /*
+        * Only setting the T bit prevents data cache movein
+        * Setting access rights to zero prevents instruction cache movein
+        *
+        * Note subtlety here: _PAGE_GATEWAY, _PAGE_EXEC and _PAGE_WRITE go
+        * to type field and _PAGE_READ goes to top bit of PL1
+        */
+       ldi             (_PAGE_REFTRAP|_PAGE_READ|_PAGE_WRITE),\prot
+       /*
+        * so if the opcode is one (i.e. this is a memory management
+        * instruction) nullify the next load so \prot is only T.
+        * Otherwise this is a normal data operation
+        */
+       cmpiclr,=       0x01,\tmp,%r0
+       ldi             (_PAGE_DIRTY|_PAGE_READ|_PAGE_WRITE),\prot
        depd,z          \prot,8,7,\prot
        /*
         * OK, it is in the temp alias region, check whether "from" or "to".
 
        .text
 
-       .align 4096
+       .align  PAGE_SIZE
 
 ENTRY(fault_vector_20)
        /* First vector is invalid (0) */
@@ -675,11 +630,7 @@ ENTRY(fault_vector_20)
        def             13
        def             14
        dtlb_20         15
-#if 0
        naitlb_20       16
-#else
-       def             16
-#endif
        nadtlb_20       17
        def             18
        def             19
@@ -722,11 +673,7 @@ ENTRY(fault_vector_11)
        def             13
        def             14
        dtlb_11         15
-#if 0
        naitlb_11       16
-#else
-       def             16
-#endif
        nadtlb_11       17
        def             18
        def             19
@@ -904,7 +851,7 @@ ENDPROC(_switch_to)
         *
         */
 
-       .align 4096
+       .align  PAGE_SIZE
 
 ENTRY(syscall_exit_rfi)
        mfctl   %cr30,%r16
@@ -954,21 +901,6 @@ intr_return:
        /* NOTE: Need to enable interrupts incase we schedule. */
        ssm     PSW_SM_I, %r0
 
-       /* Check for software interrupts */
-
-       .import irq_stat,data
-
-       load32  irq_stat,%r19
-#ifdef CONFIG_SMP
-       mfctl   %cr30,%r1
-       ldw     TI_CPU(%r1),%r1 /* get cpu # - int */
-       /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) amount
-       ** irq_stat[] is defined using ____cacheline_aligned.
-       */
-       SHLREG  %r1,L1_CACHE_SHIFT,%r20
-       add     %r19,%r20,%r19  /* now have &irq_stat[smp_processor_id()] */
-#endif /* CONFIG_SMP */
-
 intr_check_resched:
 
        /* check for reschedule */
@@ -981,7 +913,7 @@ intr_check_sig:
        /* As above */
        mfctl   %cr30,%r1
        LDREG   TI_FLAGS(%r1),%r19
-       ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20
+       ldi     (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20
        and,COND(<>)    %r19, %r20, %r0
        b,n     intr_restore    /* skip past if we've nothing to do */
 
@@ -993,9 +925,9 @@ intr_check_sig:
         * Only do signals if we are returning to user space
         */
        LDREG   PT_IASQ0(%r16), %r20
-       CMPIB=,n 0,%r20,intr_restore /* backward */
+       cmpib,COND(=),n 0,%r20,intr_restore /* backward */
        LDREG   PT_IASQ1(%r16), %r20
-       CMPIB=,n 0,%r20,intr_restore /* backward */
+       cmpib,COND(=),n 0,%r20,intr_restore /* backward */
 
        copy    %r0, %r25                       /* long in_syscall = 0 */
 #ifdef CONFIG_64BIT
@@ -1030,13 +962,6 @@ intr_restore:
 
        rfi
        nop
-       nop
-       nop
-       nop
-       nop
-       nop
-       nop
-       nop
 
 #ifndef CONFIG_PREEMPT
 # define intr_do_preempt       intr_restore
@@ -1049,10 +974,10 @@ intr_do_resched:
         * we jump back to intr_restore.
         */
        LDREG   PT_IASQ0(%r16), %r20
-       CMPIB=  0, %r20, intr_do_preempt
+       cmpib,COND(=)   0, %r20, intr_do_preempt
        nop
        LDREG   PT_IASQ1(%r16), %r20
-       CMPIB=  0, %r20, intr_do_preempt
+       cmpib,COND(=)   0, %r20, intr_do_preempt
        nop
 
 #ifdef CONFIG_64BIT
@@ -1081,7 +1006,7 @@ intr_do_preempt:
        /* current_thread_info()->preempt_count */
        mfctl   %cr30, %r1
        LDREG   TI_PRE_COUNT(%r1), %r19
-       CMPIB<> 0, %r19, intr_restore   /* if preempt_count > 0 */
+       cmpib,COND(<>)  0, %r19, intr_restore   /* if preempt_count > 0 */
        nop                             /* prev insn branched backwards */
 
        /* check if we interrupted a critical path */
@@ -1100,24 +1025,14 @@ intr_do_preempt:
         */
 
 intr_extint:
-       CMPIB=,n 0,%r16,1f
+       cmpib,COND(=),n 0,%r16,1f
+
        get_stack_use_cr30
-       b,n 3f
+       b,n 2f
 
 1:
-#if 0  /* Interrupt Stack support not working yet! */
-       mfctl   %cr31,%r1
-       copy    %r30,%r17
-       /* FIXME! depi below has hardcoded idea of interrupt stack size (32k)*/
-       DEPI    0,31,15,%r17
-       CMPB=,n %r1,%r17,2f
-       get_stack_use_cr31
-       b,n 3f
-#endif
-2:
        get_stack_use_r30
-
-3:
+2:
        save_specials   %r29
        virt_map
        save_general    %r29
@@ -1145,7 +1060,7 @@ ENDPROC(syscall_exit_rfi)
 
 ENTRY(intr_save)               /* for os_hpmc */
        mfsp    %sr7,%r16
-       CMPIB=,n 0,%r16,1f
+       cmpib,COND(=),n 0,%r16,1f
        get_stack_use_cr30
        b       2f
        copy    %r8,%r26
@@ -1167,7 +1082,7 @@ ENTRY(intr_save)          /* for os_hpmc */
         *           adjust isr/ior below.
         */
 
-       CMPIB=,n        6,%r26,skip_save_ior
+       cmpib,COND(=),n        6,%r26,skip_save_ior
 
 
        mfctl           %cr20, %r16 /* isr */
@@ -1279,7 +1194,7 @@ nadtlb_miss_20w:
        get_pgd         spc,ptp
        space_check     spc,t0,nadtlb_fault
 
-       L3_ptep         ptp,pte,t0,va,nadtlb_check_flush_20w
+       L3_ptep         ptp,pte,t0,va,nadtlb_check_alias_20w
 
        update_ptep     ptp,pte,t0,t1
 
@@ -1290,6 +1205,14 @@ nadtlb_miss_20w:
        rfir
        nop
 
+nadtlb_check_alias_20w:
+       do_alias        spc,t0,t1,va,pte,prot,nadtlb_check_flush_20w
+
+       idtlbt          pte,prot
+
+       rfir
+       nop
+
 nadtlb_check_flush_20w:
        bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
 
@@ -1298,10 +1221,9 @@ nadtlb_check_flush_20w:
        depdi,z         7,7,3,prot
        depdi           1,10,1,prot
 
-       /* Get rid of prot bits and convert to page addr for idtlbt */
+       /* Drop prot bits from pte and convert to page addr for idtlbt */
+       convert_for_tlb_insert20 pte
 
-       depdi           0,63,12,pte
-       extrd,u         pte,56,52,pte
        idtlbt          pte,prot
 
        rfir
@@ -1332,25 +1254,7 @@ dtlb_miss_11:
        nop
 
 dtlb_check_alias_11:
-
-       /* Check to see if fault is in the temporary alias region */
-
-       cmpib,<>,n      0,spc,dtlb_fault /* forward */
-       ldil            L%(TMPALIAS_MAP_START),t0
-       copy            va,t1
-       depwi           0,31,23,t1
-       cmpb,<>,n       t0,t1,dtlb_fault /* forward */
-       ldi             (_PAGE_DIRTY|_PAGE_WRITE|_PAGE_READ),prot
-       depw,z          prot,8,7,prot
-
-       /*
-        * OK, it is in the temp alias region, check whether "from" or "to".
-        * Check "subtle" note in pacache.S re: r23/r26.
-        */
-
-       extrw,u,=       va,9,1,r0
-       or,tr           %r23,%r0,pte    /* If "from" use "from" page */
-       or              %r26,%r0,pte    /* else "to", use "to" page  */
+       do_alias        spc,t0,t1,va,pte,prot,dtlb_fault
 
        idtlba          pte,(va)
        idtlbp          prot,(va)
@@ -1363,7 +1267,7 @@ nadtlb_miss_11:
 
        space_check     spc,t0,nadtlb_fault
 
-       L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_11
+       L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_11
 
        update_ptep     ptp,pte,t0,t1
 
@@ -1381,6 +1285,15 @@ nadtlb_miss_11:
        rfir
        nop
 
+nadtlb_check_alias_11:
+       do_alias        spc,t0,t1,va,pte,prot,nadtlb_check_flush_11
+
+       idtlba          pte,(va)
+       idtlbp          prot,(va)
+
+       rfir
+       nop
+
 nadtlb_check_flush_11:
        bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
 
@@ -1391,8 +1304,8 @@ nadtlb_check_flush_11:
 
        /* Get rid of prot bits and convert to page addr for idtlba */
 
-       depi            0,31,12,pte
-       extru           pte,24,25,pte
+       depi            0,31,ASM_PFN_PTE_SHIFT,pte
+       SHRREG          pte,(ASM_PFN_PTE_SHIFT-(31-26)),pte
 
        mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
        mtsp            spc,%sr1
@@ -1436,7 +1349,7 @@ nadtlb_miss_20:
 
        space_check     spc,t0,nadtlb_fault
 
-       L2_ptep         ptp,pte,t0,va,nadtlb_check_flush_20
+       L2_ptep         ptp,pte,t0,va,nadtlb_check_alias_20
 
        update_ptep     ptp,pte,t0,t1
 
@@ -1449,6 +1362,14 @@ nadtlb_miss_20:
        rfir
        nop
 
+nadtlb_check_alias_20:
+       do_alias        spc,t0,t1,va,pte,prot,nadtlb_check_flush_20
+
+       idtlbt          pte,prot
+
+       rfir
+       nop
+
 nadtlb_check_flush_20:
        bb,>=,n          pte,_PAGE_FLUSH_BIT,nadtlb_emulate
 
@@ -1457,10 +1378,9 @@ nadtlb_check_flush_20:
        depdi,z         7,7,3,prot
        depdi           1,10,1,prot
 
-       /* Get rid of prot bits and convert to page addr for idtlbt */
+       /* Drop prot bits from pte and convert to page addr for idtlbt */
+       convert_for_tlb_insert20 pte
 
-       depdi           0,63,12,pte
-       extrd,u         pte,56,32,pte
        idtlbt          pte,prot
 
        rfir
@@ -1496,11 +1416,11 @@ nadtlb_emulate:
        bb,>=,n         %r9,26,nadtlb_nullify  /* m bit not set, just nullify */
        BL              get_register,%r25
        extrw,u         %r9,15,5,%r8           /* Get index register # */
-       CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
+       cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
        copy            %r1,%r24
        BL              get_register,%r25
        extrw,u         %r9,10,5,%r8           /* Get base register # */
-       CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
+       cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
        BL              set_register,%r25
        add,l           %r1,%r24,%r1           /* doesn't affect c/b bits */
 
@@ -1532,7 +1452,7 @@ nadtlb_probe_check:
        cmpb,<>,n       %r16,%r17,nadtlb_fault /* Must be probe,[rw]*/
        BL              get_register,%r25      /* Find the target register */
        extrw,u         %r9,31,5,%r8           /* Get target register */
-       CMPIB=,n        -1,%r1,nadtlb_fault    /* have to use slow path */
+       cmpib,COND(=),n        -1,%r1,nadtlb_fault    /* have to use slow path */
        BL              set_register,%r25
        copy            %r0,%r1                /* Write zero to target register */
        b nadtlb_nullify                       /* Nullify return insn */
@@ -1562,6 +1482,36 @@ itlb_miss_20w:
        rfir
        nop
 
+naitlb_miss_20w:
+
+       /*
+        * I miss is a little different, since we allow users to fault
+        * on the gateway page which is in the kernel address space.
+        */
+
+       space_adjust    spc,va,t0
+       get_pgd         spc,ptp
+       space_check     spc,t0,naitlb_fault
+
+       L3_ptep         ptp,pte,t0,va,naitlb_check_alias_20w
+
+       update_ptep     ptp,pte,t0,t1
+
+       make_insert_tlb spc,pte,prot
+
+       iitlbt          pte,prot
+
+       rfir
+       nop
+
+naitlb_check_alias_20w:
+       do_alias        spc,t0,t1,va,pte,prot,naitlb_fault
+
+       iitlbt          pte,prot
+
+       rfir
+       nop
+
 #else
 
 itlb_miss_11:
@@ -1586,6 +1536,38 @@ itlb_miss_11:
        rfir
        nop
 
+naitlb_miss_11:
+       get_pgd         spc,ptp
+
+       space_check     spc,t0,naitlb_fault
+
+       L2_ptep         ptp,pte,t0,va,naitlb_check_alias_11
+
+       update_ptep     ptp,pte,t0,t1
+
+       make_insert_tlb_11      spc,pte,prot
+
+       mfsp            %sr1,t0  /* Save sr1 so we can use it in tlb inserts */
+       mtsp            spc,%sr1
+
+       iitlba          pte,(%sr1,va)
+       iitlbp          prot,(%sr1,va)
+
+       mtsp            t0, %sr1        /* Restore sr1 */
+
+       rfir
+       nop
+
+naitlb_check_alias_11:
+       do_alias        spc,t0,t1,va,pte,prot,itlb_fault
+
+       iitlba          pte,(%sr0, va)
+       iitlbp          prot,(%sr0, va)
+
+       rfir
+       nop
+
+
 itlb_miss_20:
        get_pgd         spc,ptp
 
@@ -1604,6 +1586,32 @@ itlb_miss_20:
        rfir
        nop
 
+naitlb_miss_20:
+       get_pgd         spc,ptp
+
+       space_check     spc,t0,naitlb_fault
+
+       L2_ptep         ptp,pte,t0,va,naitlb_check_alias_20
+
+       update_ptep     ptp,pte,t0,t1
+
+       make_insert_tlb spc,pte,prot
+
+       f_extend        pte,t0
+
+       iitlbt          pte,prot
+
+       rfir
+       nop
+
+naitlb_check_alias_20:
+       do_alias        spc,t0,t1,va,pte,prot,naitlb_fault
+
+       iitlbt          pte,prot
+
+       rfir
+       nop
+
 #endif
 
 #ifdef CONFIG_64BIT
@@ -1616,12 +1624,12 @@ dbit_trap_20w:
        L3_ptep         ptp,pte,t0,va,dbit_fault
 
 #ifdef CONFIG_SMP
-       CMPIB=,n        0,spc,dbit_nolock_20w
+       cmpib,COND(=),n        0,spc,dbit_nolock_20w
        load32          PA(pa_dbit_lock),t0
 
 dbit_spin_20w:
        LDCW            0(t0),t1
-       cmpib,=         0,t1,dbit_spin_20w
+       cmpib,COND(=)         0,t1,dbit_spin_20w
        nop
 
 dbit_nolock_20w:
@@ -1632,7 +1640,7 @@ dbit_nolock_20w:
                
        idtlbt          pte,prot
 #ifdef CONFIG_SMP
-       CMPIB=,n        0,spc,dbit_nounlock_20w
+       cmpib,COND(=),n        0,spc,dbit_nounlock_20w
        ldi             1,t1
        stw             t1,0(t0)
 
@@ -1652,7 +1660,7 @@ dbit_trap_11:
        L2_ptep         ptp,pte,t0,va,dbit_fault
 
 #ifdef CONFIG_SMP
-       CMPIB=,n        0,spc,dbit_nolock_11
+       cmpib,COND(=),n        0,spc,dbit_nolock_11
        load32          PA(pa_dbit_lock),t0
 
 dbit_spin_11:
@@ -1674,7 +1682,7 @@ dbit_nolock_11:
 
        mtsp            t1, %sr1     /* Restore sr1 */
 #ifdef CONFIG_SMP
-       CMPIB=,n        0,spc,dbit_nounlock_11
+       cmpib,COND(=),n        0,spc,dbit_nounlock_11
        ldi             1,t1
        stw             t1,0(t0)
 
@@ -1692,7 +1700,7 @@ dbit_trap_20:
        L2_ptep         ptp,pte,t0,va,dbit_fault
 
 #ifdef CONFIG_SMP
-       CMPIB=,n        0,spc,dbit_nolock_20
+       cmpib,COND(=),n        0,spc,dbit_nolock_20
        load32          PA(pa_dbit_lock),t0
 
 dbit_spin_20:
@@ -1711,7 +1719,7 @@ dbit_nolock_20:
         idtlbt          pte,prot
 
 #ifdef CONFIG_SMP
-       CMPIB=,n        0,spc,dbit_nounlock_20
+       cmpib,COND(=),n        0,spc,dbit_nounlock_20
        ldi             1,t1
        stw             t1,0(t0)
 
@@ -1740,6 +1748,10 @@ nadtlb_fault:
        b               intr_save
        ldi             17,%r8
 
+naitlb_fault:
+       b               intr_save
+       ldi             16,%r8
+
 dtlb_fault:
        b               intr_save
        ldi             15,%r8
@@ -2034,14 +2046,13 @@ ENTRY(syscall_exit)
        STREG     %r28,TASK_PT_GR28(%r1)
 
 #ifdef CONFIG_HPUX
-
 /* <linux/personality.h> cannot be easily included */
 #define PER_HPUX 0x10
-       LDREG     TASK_PERSONALITY(%r1),%r19
+       ldw     TASK_PERSONALITY(%r1),%r19
 
        /* We can't use "CMPIB<> PER_HPUX" since "im5" field is sign extended */
        ldo       -PER_HPUX(%r19), %r19
-       CMPIB<>,n 0,%r19,1f
+       cmpib,COND(<>),n 0,%r19,1f
 
        /* Save other hpux returns if personality is PER_HPUX */
        STREG     %r22,TASK_PT_GR22(%r1)
@@ -2055,24 +2066,6 @@ ENTRY(syscall_exit)
         */
        loadgp
 
-syscall_check_bh:
-
-       /* Check for software interrupts */
-
-       .import irq_stat,data
-
-       load32  irq_stat,%r19
-
-#ifdef CONFIG_SMP
-       /* sched.h: int processor */
-       /* %r26 is used as scratch register to index into irq_stat[] */
-       ldw     TI_CPU-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r26 /* cpu # */
-
-       /* shift left ____cacheline_aligned (aka L1_CACHE_BYTES) bits */
-       SHLREG  %r26,L1_CACHE_SHIFT,%r20
-       add     %r19,%r20,%r19  /* now have &irq_stat[smp_processor_id()] */
-#endif /* CONFIG_SMP */
-
 syscall_check_resched:
 
        /* check for reschedule */
@@ -2111,12 +2104,13 @@ syscall_do_signal:
        b,n     syscall_check_sig
 
 syscall_restore:
-       /* Are we being ptraced? */
        LDREG   TI_TASK-THREAD_SZ_ALGN-FRAME_SIZE(%r30),%r1
 
-       LDREG   TASK_PTRACE(%r1), %r19
-       bb,<    %r19,31,syscall_restore_rfi
-       nop
+       /* Are we being ptraced? */
+       ldw     TASK_FLAGS(%r1),%r19
+       ldi     (_TIF_SINGLESTEP|_TIF_BLOCKSTEP),%r2
+       and,COND(=)     %r19,%r2,%r0
+       b,n     syscall_restore_rfi
 
        ldo     TASK_PT_FR31(%r1),%r19             /* reload fpregs */
        rest_fp %r19
@@ -2139,9 +2133,10 @@ syscall_restore:
        LDREG   TASK_PT_GR31(%r1),%r31     /* restore syscall rp */
 
        /* NOTE: We use rsm/ssm pair to make this operation atomic */
+       LDREG   TASK_PT_GR30(%r1),%r1              /* Get user sp */
        rsm     PSW_SM_I, %r0
-       LDREG   TASK_PT_GR30(%r1),%r30             /* restore user sp */
-       mfsp    %sr3,%r1                           /* Get users space id */
+       copy    %r1,%r30                           /* Restore user sp */
+       mfsp    %sr3,%r1                           /* Get user space id */
        mtsp    %r1,%sr7                           /* Restore sr7 */
        ssm     PSW_SM_I, %r0
 
@@ -2177,16 +2172,16 @@ syscall_restore_rfi:
        ldi     0x0b,%r20                          /* Create new PSW */
        depi    -1,13,1,%r20                       /* C, Q, D, and I bits */
 
-       /* The values of PA_SINGLESTEP_BIT and PA_BLOCKSTEP_BIT are
-        * set in include/linux/ptrace.h and converted to PA bitmap
+       /* The values of SINGLESTEP_BIT and BLOCKSTEP_BIT are
+        * set in thread_info.h and converted to PA bitmap
         * numbers in asm-offsets.c */
 
-       /* if ((%r19.PA_SINGLESTEP_BIT)) { %r20.27=1} */
-       extru,= %r19,PA_SINGLESTEP_BIT,1,%r0
+       /* if ((%r19.SINGLESTEP_BIT)) { %r20.27=1} */
+       extru,= %r19,TIF_SINGLESTEP_PA_BIT,1,%r0
        depi    -1,27,1,%r20                       /* R bit */
 
-       /* if ((%r19.PA_BLOCKSTEP_BIT)) { %r20.7=1} */
-       extru,= %r19,PA_BLOCKSTEP_BIT,1,%r0
+       /* if ((%r19.BLOCKSTEP_BIT)) { %r20.7=1} */
+       extru,= %r19,TIF_BLOCKSTEP_PA_BIT,1,%r0
        depi    -1,7,1,%r20                        /* T bit */
 
        STREG   %r20,TASK_PT_PSW(%r1)
@@ -2244,12 +2239,39 @@ syscall_do_resched:
 #else
        nop
 #endif
-       b       syscall_check_bh  /* if resched, we start over again */
+       b       syscall_check_resched   /* if resched, we start over again */
        nop
 ENDPROC(syscall_exit)
 
 
-ENTRY(get_register)
+#ifdef CONFIG_FUNCTION_TRACER
+       .import ftrace_function_trampoline,code
+ENTRY(_mcount)
+       copy    %r3, %arg2
+       b       ftrace_function_trampoline
+       nop
+ENDPROC(_mcount)
+
+ENTRY(return_to_handler)
+       load32  return_trampoline, %rp
+       copy    %ret0, %arg0
+       copy    %ret1, %arg1
+       b       ftrace_return_to_handler
+       nop
+return_trampoline:
+       copy    %ret0, %rp
+       copy    %r23, %ret0
+       copy    %r24, %ret1
+
+.globl ftrace_stub
+ftrace_stub:
+       bv      %r0(%rp)
+       nop
+ENDPROC(return_to_handler)
+#endif /* CONFIG_FUNCTION_TRACER */
+
+
+get_register:
        /*
         * get_register is used by the non access tlb miss handlers to
         * copy the value of the general register specified in r8 into
@@ -2326,10 +2348,9 @@ ENTRY(get_register)
        copy    %r30,%r1
        bv      %r0(%r25)    /* r31 */
        copy    %r31,%r1
-ENDPROC(get_register)
 
 
-ENTRY(set_register)
+set_register:
        /*
         * set_register is used by the non access tlb miss handlers to
         * copy the value of r1 into the general register specified in
@@ -2401,5 +2422,4 @@ ENTRY(set_register)
        copy    %r1,%r30
        bv      %r0(%r25)    /* r31 */
        copy    %r1,%r31
-ENDPROC(set_register)