Merge branch 'x86-cpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[sfrench/cifs-2.6.git] / arch / powerpc / kernel / head_8xx.S
index 7ee876d2adb57c6cc1e78d1d3204ab240238c02d..fafff8dbd5d990175874d9ca09e40a44085be525 100644 (file)
@@ -104,12 +104,15 @@ turn_on_mmu:
  * task's thread_struct.
  */
 #define EXCEPTION_PROLOG       \
-       mtspr   SPRN_SPRG_SCRATCH0,r10; \
-       mtspr   SPRN_SPRG_SCRATCH1,r11; \
-       mfcr    r10;            \
+       EXCEPTION_PROLOG_0;     \
        EXCEPTION_PROLOG_1;     \
        EXCEPTION_PROLOG_2
 
+#define EXCEPTION_PROLOG_0     \
+       mtspr   SPRN_SPRG_SCRATCH0,r10; \
+       mtspr   SPRN_SPRG_SCRATCH1,r11; \
+       mfcr    r10
+
 #define EXCEPTION_PROLOG_1     \
        mfspr   r11,SPRN_SRR1;          /* check whether user or kernel */ \
        andi.   r11,r11,MSR_PR; \
@@ -144,6 +147,14 @@ turn_on_mmu:
        SAVE_4GPRS(3, r11);     \
        SAVE_2GPRS(7, r11)
 
+/*
+ * Exception exit code.
+ */
+#define EXCEPTION_EPILOG_0     \
+       mtcr    r10;            \
+       mfspr   r10,SPRN_SPRG_SCRATCH0; \
+       mfspr   r11,SPRN_SPRG_SCRATCH1
+
 /*
  * Note: code which follows this uses cr0.eq (set if from kernel),
  * r11, r12 (SRR0), and r9 (SRR1).
@@ -293,16 +304,8 @@ InstructionTLBMiss:
 #ifdef CONFIG_8xx_CPU6
        stw     r3, 8(r0)
 #endif
-       DO_8xx_CPU6(0x3f80, r3)
-       mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
-       mfcr    r10
-#ifdef CONFIG_8xx_CPU6
-       stw     r10, 0(r0)
-       stw     r11, 4(r0)
-#else
-       mtspr   SPRN_DAR, r10
-       mtspr   SPRN_SPRG2, r11
-#endif
+       EXCEPTION_PROLOG_0
+       mtspr   SPRN_SPRG_SCRATCH2, r10
        mfspr   r10, SPRN_SRR0  /* Get effective address of fault */
 #ifdef CONFIG_8xx_CPU15
        addi    r11, r10, 0x1000
@@ -359,18 +362,11 @@ InstructionTLBMiss:
        mtspr   SPRN_MI_RPN, r10        /* Update TLB entry */
 
        /* Restore registers */
-#ifndef CONFIG_8xx_CPU6
-       mfspr   r10, SPRN_DAR
-       mtcr    r10
-       mtspr   SPRN_DAR, r11   /* Tag DAR */
-       mfspr   r11, SPRN_SPRG2
-#else
-       lwz     r11, 0(r0)
-       mtcr    r11
-       lwz     r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
        lwz     r3, 8(r0)
 #endif
-       mfspr   r10, SPRN_M_TW
+       mfspr   r10, SPRN_SPRG_SCRATCH2
+       EXCEPTION_EPILOG_0
        rfi
 2:
        mfspr   r11, SPRN_SRR1
@@ -381,19 +377,11 @@ InstructionTLBMiss:
        mtspr   SPRN_SRR1, r11
 
        /* Restore registers */
-#ifndef CONFIG_8xx_CPU6
-       mfspr   r10, SPRN_DAR
-       mtcr    r10
-       li      r11, 0x00f0
-       mtspr   SPRN_DAR, r11   /* Tag DAR */
-       mfspr   r11, SPRN_SPRG2
-#else
-       lwz     r11, 0(r0)
-       mtcr    r11
-       lwz     r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
        lwz     r3, 8(r0)
 #endif
-       mfspr   r10, SPRN_M_TW
+       mfspr   r10, SPRN_SPRG_SCRATCH2
+       EXCEPTION_EPILOG_0
        b       InstructionAccess
 
        . = 0x1200
@@ -401,16 +389,8 @@ DataStoreTLBMiss:
 #ifdef CONFIG_8xx_CPU6
        stw     r3, 8(r0)
 #endif
-       DO_8xx_CPU6(0x3f80, r3)
-       mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
-       mfcr    r10
-#ifdef CONFIG_8xx_CPU6
-       stw     r10, 0(r0)
-       stw     r11, 4(r0)
-#else
-       mtspr   SPRN_DAR, r10
-       mtspr   SPRN_SPRG2, r11
-#endif
+       EXCEPTION_PROLOG_0
+       mtspr   SPRN_SPRG_SCRATCH2, r10
        mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
 
        /* If we are faulting a kernel address, we have to use the
@@ -483,19 +463,12 @@ DataStoreTLBMiss:
        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 
        /* Restore registers */
-#ifndef CONFIG_8xx_CPU6
-       mfspr   r10, SPRN_DAR
-       mtcr    r10
-       mtspr   SPRN_DAR, r11   /* Tag DAR */
-       mfspr   r11, SPRN_SPRG2
-#else
-       mtspr   SPRN_DAR, r11   /* Tag DAR */
-       lwz     r11, 0(r0)
-       mtcr    r11
-       lwz     r11, 4(r0)
+#ifdef CONFIG_8xx_CPU6
        lwz     r3, 8(r0)
 #endif
-       mfspr   r10, SPRN_M_TW
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r10, SPRN_SPRG_SCRATCH2
+       EXCEPTION_EPILOG_0
        rfi
 
 /* This is an instruction TLB error on the MPC8xx.  This could be due
@@ -507,35 +480,18 @@ InstructionTLBError:
        b       InstructionAccess
 
 /* This is the data TLB error on the MPC8xx.  This could be due to
- * many reasons, including a dirty update to a pte.  We can catch that
- * one here, but anything else is an error.  First, we track down the
- * Linux pte.  If it is valid, write access is allowed, but the
- * page dirty bit is not set, we will set it and reload the TLB.  For
- * any other case, we bail out to a higher level function that can
- * handle it.
+ * many reasons, including a dirty update to a pte.  We bail out to
+ * a higher level function that can handle it.
  */
        . = 0x1400
 DataTLBError:
-#ifdef CONFIG_8xx_CPU6
-       stw     r3, 8(r0)
-#endif
-       DO_8xx_CPU6(0x3f80, r3)
-       mtspr   SPRN_M_TW, r10  /* Save a couple of working registers */
-       mfcr    r10
-       stw     r10, 0(r0)
-       stw     r11, 4(r0)
+       EXCEPTION_PROLOG_0
 
-       mfspr   r10, SPRN_DAR
-       cmpwi   cr0, r10, 0x00f0
+       mfspr   r11, SPRN_DAR
+       cmpwi   cr0, r11, 0x00f0
        beq-    FixupDAR        /* must be a buggy dcbX, icbi insn. */
-DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR */
-       mfspr   r10, SPRN_M_TW  /* Restore registers */
-       lwz     r11, 0(r0)
-       mtcr    r11
-       lwz     r11, 4(r0)
-#ifdef CONFIG_8xx_CPU6
-       lwz     r3, 8(r0)
-#endif
+DARFixed:/* Return from dcbx instruction bug workaround */
+       EXCEPTION_EPILOG_0
        b       DataAccess
 
        EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
@@ -559,11 +515,15 @@ DARFixed:/* Return from dcbx instruction bug workaround, r10 holds value of DAR
 
 /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
  * by decoding the registers used by the dcbx instruction and adding them.
- * DAR is set to the calculated address and r10 also holds the EA on exit.
+ * DAR is set to the calculated address.
  */
  /* define if you don't want to use self modifying code */
 #define NO_SELF_MODIFYING_CODE
 FixupDAR:/* Entry point for dcbx workaround. */
+#ifdef CONFIG_8xx_CPU6
+       stw     r3, 8(r0)
+#endif
+       mtspr   SPRN_SPRG_SCRATCH2, r10
        /* fetch instruction from memory. */
        mfspr   r10, SPRN_SRR0
        andis.  r11, r10, 0x8000        /* Address >= 0x80000000 */
@@ -579,16 +539,17 @@ FixupDAR:/* Entry point for dcbx workaround. */
        mtspr   SPRN_MD_TWC, r11        /* Load pte table base address */
        mfspr   r11, SPRN_MD_TWC        /* ....and get the pte address */
        lwz     r11, 0(r11)     /* Get the pte */
+#ifdef CONFIG_8xx_CPU6
+       lwz     r3, 8(r0)       /* restore r3 from memory */
+#endif
        /* concat physical page address(r11) and page offset(r10) */
        rlwimi  r11, r10, 0, 20, 31
        lwz     r11,0(r11)
 /* Check if it really is a dcbx instruction. */
 /* dcbt and dcbtst does not generate DTLB Misses/Errors,
  * no need to include them here */
-       srwi    r10, r11, 26    /* check if major OP code is 31 */
-       cmpwi   cr0, r10, 31
-       bne-    141f
-       rlwinm  r10, r11, 0, 21, 30
+       xoris   r10, r11, 0x7c00        /* check if major OP code is 31 */
+       rlwinm  r10, r10, 0, 21, 5
        cmpwi   cr0, r10, 2028  /* Is dcbz? */
        beq+    142f
        cmpwi   cr0, r10, 940   /* Is dcbi? */
@@ -599,16 +560,13 @@ FixupDAR:/* Entry point for dcbx workaround. */
        beq+    142f
        cmpwi   cr0, r10, 1964  /* Is icbi? */
        beq+    142f
-141:   mfspr   r10, SPRN_DAR   /* r10 must hold DAR at exit */
+141:   mfspr   r10,SPRN_SPRG_SCRATCH2
        b       DARFixed        /* Nope, go back to normal TLB processing */
 
 144:   mfspr   r10, SPRN_DSISR
        rlwinm  r10, r10,0,7,5  /* Clear store bit for buggy dcbst insn */
        mtspr   SPRN_DSISR, r10
 142:   /* continue, it was a dcbx, dcbi instruction. */
-#ifdef CONFIG_8xx_CPU6
-       lwz     r3, 8(r0)       /* restore r3 from memory */
-#endif
 #ifndef NO_SELF_MODIFYING_CODE
        andis.  r10,r11,0x1f    /* test if reg RA is r0 */
        li      r10,modified_instr@l
@@ -619,14 +577,15 @@ FixupDAR:/* Entry point for dcbx workaround. */
        stw     r11,0(r10)      /* store add/and instruction */
        dcbf    0,r10           /* flush new instr. to memory. */
        icbi    0,r10           /* invalidate instr. cache line */
-       lwz     r11, 4(r0)      /* restore r11 from memory */
-       mfspr   r10, SPRN_M_TW  /* restore r10 from M_TW */
+       mfspr   r11, SPRN_SPRG_SCRATCH1 /* restore r11 */
+       mfspr   r10, SPRN_SPRG_SCRATCH0 /* restore r10 */
        isync                   /* Wait until new instr is loaded from memory */
 modified_instr:
        .space  4               /* this is where the add instr. is stored */
        bne+    143f
        subf    r10,r0,r10      /* r10=r10-r0, only if reg RA is r0 */
 143:   mtdar   r10             /* store faulting EA in DAR */
+       mfspr   r10,SPRN_SPRG_SCRATCH2
        b       DARFixed        /* Go back to normal TLB handling */
 #else
        mfctr   r10
@@ -680,13 +639,16 @@ modified_instr:
        mfdar   r11
        mtctr   r11                     /* restore ctr reg from DAR */
        mtdar   r10                     /* save fault EA to DAR */
+       mfspr   r10,SPRN_SPRG_SCRATCH2
        b       DARFixed                /* Go back to normal TLB handling */
 
        /* special handling for r10,r11 since these are modified already */
-153:   lwz     r11, 4(r0)      /* load r11 from memory */
-       b       155f
-154:   mfspr   r11, SPRN_M_TW  /* load r10 from M_TW */
-155:   add     r10, r10, r11   /* add it */
+153:   mfspr   r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */
+       add     r10, r10, r11   /* add it */
+       mfctr   r11             /* restore r11 */
+       b       151b
+154:   mfspr   r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */
+       add     r10, r10, r11   /* add it */
        mfctr   r11             /* restore r11 */
        b       151b
 #endif