powerpc/8xx: Use M_TW instead of M_TWB
authorLEROY Christophe <christophe.leroy@c-s.fr>
Fri, 19 Sep 2014 08:36:08 +0000 (10:36 +0200)
committerScott Wood <scottwood@freescale.com>
Sat, 8 Nov 2014 00:10:40 +0000 (18:10 -0600)
Use M_TW instead of M_TWB for storing Level 1 table address as M_TWB requires
4k aligned tables, which is only the case with 4k pages.
Consequently, we have to calculate the level 1 table index by ourselves.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Scott Wood <scottwood@freescale.com>
arch/powerpc/kernel/head_8xx.S

index c061bc8..c78f7fd 100644 (file)
@@ -278,8 +278,8 @@ SystemCall:
        . = 0x1100
 /*
  * For the MPC8xx, this is a software tablewalk to load the instruction
- * TLB.  It is modelled after the example in the Motorola manual.  The task
- * switch loads the M_TWB register with the pointer to the first level table.
+ * TLB.  The task switch loads the M_TW register with the pointer to the first
+ * level table.
  * If we discover there is no second level table (value is zero) or if there
  * is an invalid pte, we load that into the TLB, which causes another fault
  * into the TLB Error interrupt where we can handle such problems.
@@ -301,7 +301,6 @@ InstructionTLBMiss:
 #endif
        DO_8xx_CPU6(0x3780, r3)
        mtspr   SPRN_MD_EPN, r10        /* Have to use MD_EPN for walk, MI_EPN can't */
-       mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
 
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
@@ -309,14 +308,17 @@ InstructionTLBMiss:
 #ifdef CONFIG_MODULES
        /* Only modules will cause ITLB Misses as we always
         * pin the first 8MB of kernel memory */
-       andi.   r11, r10, 0x0800        /* Address >= 0x80000000 */
+       andis.  r11, r10, 0x8000        /* Address >= 0x80000000 */
+#endif
+       mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
+#ifdef CONFIG_MODULES
        beq     3f
-       lis     r11, swapper_pg_dir@h
-       ori     r11, r11, swapper_pg_dir@l
-       rlwimi  r10, r11, 0, 2, 19
+       lis     r11, (swapper_pg_dir-PAGE_OFFSET)@h
+       ori     r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
 3:
 #endif
-       lwz     r11, 0(r10)     /* Get the level 1 entry */
+       rlwinm  r10, r10, 12, 20, 29    /* Extract level 1 index */
+       lwzx    r11, r10, r11   /* Get the level 1 entry */
        rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
        beq     2f              /* If zero, don't try to find a pte */
 
@@ -377,18 +379,19 @@ DataStoreTLBMiss:
 #endif
        EXCEPTION_PROLOG_0
        mtspr   SPRN_SPRG_SCRATCH2, r10
-       mfspr   r10, SPRN_M_TWB /* Get level 1 table entry address */
+       mfspr   r10, SPRN_MD_EPN
 
        /* If we are faulting a kernel address, we have to use the
         * kernel page tables.
         */
-       andi.   r11, r10, 0x0800
+       andis.  r11, r10, 0x8000
+       mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
        beq     3f
-       lis     r11, swapper_pg_dir@h
-       ori     r11, r11, swapper_pg_dir@l
-       rlwimi  r10, r11, 0, 2, 19
+       lis     r11, (swapper_pg_dir-PAGE_OFFSET)@h
+       ori     r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
 3:
-       lwz     r11, 0(r10)     /* Get the level 1 entry */
+       rlwinm  r10, r10, 12, 20, 29    /* Extract level 1 index */
+       lwzx    r11, r10, r11   /* Get the level 1 entry */
        rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
        beq     2f              /* If zero, don't try to find a pte */
 
@@ -527,12 +530,12 @@ FixupDAR:/* Entry point for dcbx workaround. */
        andis.  r11, r10, 0x8000        /* Address >= 0x80000000 */
        DO_8xx_CPU6(0x3780, r3)
        mtspr   SPRN_MD_EPN, r10
-       mfspr   r11, SPRN_M_TWB /* Get level 1 table entry address */
+       mfspr   r11, SPRN_M_TW  /* Get level 1 table base address */
        beq-    3f              /* Branch if user space */
        lis     r11, (swapper_pg_dir-PAGE_OFFSET)@h
        ori     r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
-       rlwimi  r11, r10, 32-20, 0xffc /* r11 = r11&~0xffc|(r10>>20)&0xffc */
-3:     lwz     r11, 0(r11)     /* Get the level 1 entry */
+3:     rlwinm  r10, r10, 12, 20, 29    /* Extract level 1 index */
+       lwzx    r11, r10, r11   /* Get the level 1 entry */
        DO_8xx_CPU6(0x3b80, r3)
        mtspr   SPRN_MD_TWC, r11        /* Load pte table base address */
        mfspr   r11, SPRN_MD_TWC        /* ....and get the pte address */
@@ -541,6 +544,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
        lwz     r3, 8(r0)       /* restore r3 from memory */
 #endif
        /* concat physical page address(r11) and page offset(r10) */
+       mfspr   r10, SPRN_SRR0
        rlwimi  r11, r10, 0, 20, 31
        lwz     r11,0(r11)
 /* Check if it really is a dcbx instruction. */
@@ -696,11 +700,11 @@ start_here:
 #ifdef CONFIG_8xx_CPU6
        lis     r4, cpu6_errata_word@h
        ori     r4, r4, cpu6_errata_word@l
-       li      r3, 0x3980
+       li      r3, 0x3f80
        stw     r3, 12(r4)
        lwz     r3, 12(r4)
 #endif
-       mtspr   SPRN_M_TWB, r6
+       mtspr   SPRN_M_TW, r6
        lis     r4,2f@h
        ori     r4,r4,2f@l
        tophys(r4,r4)
@@ -874,10 +878,10 @@ _GLOBAL(set_context)
        lis     r6, cpu6_errata_word@h
        ori     r6, r6, cpu6_errata_word@l
        tophys  (r4, r4)
-       li      r7, 0x3980
+       li      r7, 0x3f80
        stw     r7, 12(r6)
        lwz     r7, 12(r6)
-        mtspr   SPRN_M_TWB, r4               /* Update MMU base address */
+        mtspr   SPRN_M_TW, r4               /* Update MMU base address */
        li      r7, 0x3380
        stw     r7, 12(r6)
        lwz     r7, 12(r6)
@@ -885,7 +889,7 @@ _GLOBAL(set_context)
 #else
         mtspr   SPRN_M_CASID,r3                /* Update context */
        tophys  (r4, r4)
-       mtspr   SPRN_M_TWB, r4          /* and pgd */
+       mtspr   SPRN_M_TW, r4           /* and pgd */
 #endif
        SYNC
        blr