|
@@ -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
|