aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/head_8xx.S
diff options
context:
space:
mode:
authorLEROY Christophe <christophe.leroy@c-s.fr>2014-09-19 04:36:08 -0400
committerScott Wood <scottwood@freescale.com>2014-11-07 19:10:40 -0500
commitcbc130f120d5e180a70a0fa4a8b4191e44548a87 (patch)
treee69a89701ad7ce65c1abff8760f4af5d19235660 /arch/powerpc/kernel/head_8xx.S
parent6cde2b6f399e7d68a4b482680850a077104f9068 (diff)
powerpc/8xx: Use M_TW instead of M_TWB
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>
Diffstat (limited to 'arch/powerpc/kernel/head_8xx.S')
-rw-r--r--arch/powerpc/kernel/head_8xx.S48
1 files changed, 26 insertions, 22 deletions
diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index c061bc8d9045..c78f7fd342cb 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -278,8 +278,8 @@ SystemCall:
278 . = 0x1100 278 . = 0x1100
279/* 279/*
280 * For the MPC8xx, this is a software tablewalk to load the instruction 280 * For the MPC8xx, this is a software tablewalk to load the instruction
281 * TLB. It is modelled after the example in the Motorola manual. The task 281 * TLB. The task switch loads the M_TW register with the pointer to the first
282 * switch loads the M_TWB register with the pointer to the first level table. 282 * level table.
283 * If we discover there is no second level table (value is zero) or if there 283 * If we discover there is no second level table (value is zero) or if there
284 * is an invalid pte, we load that into the TLB, which causes another fault 284 * is an invalid pte, we load that into the TLB, which causes another fault
285 * into the TLB Error interrupt where we can handle such problems. 285 * into the TLB Error interrupt where we can handle such problems.
@@ -301,7 +301,6 @@ InstructionTLBMiss:
301#endif 301#endif
302 DO_8xx_CPU6(0x3780, r3) 302 DO_8xx_CPU6(0x3780, r3)
303 mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */ 303 mtspr SPRN_MD_EPN, r10 /* Have to use MD_EPN for walk, MI_EPN can't */
304 mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */
305 304
306 /* If we are faulting a kernel address, we have to use the 305 /* If we are faulting a kernel address, we have to use the
307 * kernel page tables. 306 * kernel page tables.
@@ -309,14 +308,17 @@ InstructionTLBMiss:
309#ifdef CONFIG_MODULES 308#ifdef CONFIG_MODULES
310 /* Only modules will cause ITLB Misses as we always 309 /* Only modules will cause ITLB Misses as we always
311 * pin the first 8MB of kernel memory */ 310 * pin the first 8MB of kernel memory */
312 andi. r11, r10, 0x0800 /* Address >= 0x80000000 */ 311 andis. r11, r10, 0x8000 /* Address >= 0x80000000 */
312#endif
313 mfspr r11, SPRN_M_TW /* Get level 1 table base address */
314#ifdef CONFIG_MODULES
313 beq 3f 315 beq 3f
314 lis r11, swapper_pg_dir@h 316 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
315 ori r11, r11, swapper_pg_dir@l 317 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
316 rlwimi r10, r11, 0, 2, 19
3173: 3183:
318#endif 319#endif
319 lwz r11, 0(r10) /* Get the level 1 entry */ 320 rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */
321 lwzx r11, r10, r11 /* Get the level 1 entry */
320 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ 322 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
321 beq 2f /* If zero, don't try to find a pte */ 323 beq 2f /* If zero, don't try to find a pte */
322 324
@@ -377,18 +379,19 @@ DataStoreTLBMiss:
377#endif 379#endif
378 EXCEPTION_PROLOG_0 380 EXCEPTION_PROLOG_0
379 mtspr SPRN_SPRG_SCRATCH2, r10 381 mtspr SPRN_SPRG_SCRATCH2, r10
380 mfspr r10, SPRN_M_TWB /* Get level 1 table entry address */ 382 mfspr r10, SPRN_MD_EPN
381 383
382 /* If we are faulting a kernel address, we have to use the 384 /* If we are faulting a kernel address, we have to use the
383 * kernel page tables. 385 * kernel page tables.
384 */ 386 */
385 andi. r11, r10, 0x0800 387 andis. r11, r10, 0x8000
388 mfspr r11, SPRN_M_TW /* Get level 1 table base address */
386 beq 3f 389 beq 3f
387 lis r11, swapper_pg_dir@h 390 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
388 ori r11, r11, swapper_pg_dir@l 391 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
389 rlwimi r10, r11, 0, 2, 19
3903: 3923:
391 lwz r11, 0(r10) /* Get the level 1 entry */ 393 rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */
394 lwzx r11, r10, r11 /* Get the level 1 entry */
392 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */ 395 rlwinm. r10, r11,0,0,19 /* Extract page descriptor page address */
393 beq 2f /* If zero, don't try to find a pte */ 396 beq 2f /* If zero, don't try to find a pte */
394 397
@@ -527,12 +530,12 @@ FixupDAR:/* Entry point for dcbx workaround. */
527 andis. r11, r10, 0x8000 /* Address >= 0x80000000 */ 530 andis. r11, r10, 0x8000 /* Address >= 0x80000000 */
528 DO_8xx_CPU6(0x3780, r3) 531 DO_8xx_CPU6(0x3780, r3)
529 mtspr SPRN_MD_EPN, r10 532 mtspr SPRN_MD_EPN, r10
530 mfspr r11, SPRN_M_TWB /* Get level 1 table entry address */ 533 mfspr r11, SPRN_M_TW /* Get level 1 table base address */
531 beq- 3f /* Branch if user space */ 534 beq- 3f /* Branch if user space */
532 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h 535 lis r11, (swapper_pg_dir-PAGE_OFFSET)@h
533 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l 536 ori r11, r11, (swapper_pg_dir-PAGE_OFFSET)@l
534 rlwimi r11, r10, 32-20, 0xffc /* r11 = r11&~0xffc|(r10>>20)&0xffc */ 5373: rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */
5353: lwz r11, 0(r11) /* Get the level 1 entry */ 538 lwzx r11, r10, r11 /* Get the level 1 entry */
536 DO_8xx_CPU6(0x3b80, r3) 539 DO_8xx_CPU6(0x3b80, r3)
537 mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ 540 mtspr SPRN_MD_TWC, r11 /* Load pte table base address */
538 mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ 541 mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
@@ -541,6 +544,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
541 lwz r3, 8(r0) /* restore r3 from memory */ 544 lwz r3, 8(r0) /* restore r3 from memory */
542#endif 545#endif
543 /* concat physical page address(r11) and page offset(r10) */ 546 /* concat physical page address(r11) and page offset(r10) */
547 mfspr r10, SPRN_SRR0
544 rlwimi r11, r10, 0, 20, 31 548 rlwimi r11, r10, 0, 20, 31
545 lwz r11,0(r11) 549 lwz r11,0(r11)
546/* Check if it really is a dcbx instruction. */ 550/* Check if it really is a dcbx instruction. */
@@ -696,11 +700,11 @@ start_here:
696#ifdef CONFIG_8xx_CPU6 700#ifdef CONFIG_8xx_CPU6
697 lis r4, cpu6_errata_word@h 701 lis r4, cpu6_errata_word@h
698 ori r4, r4, cpu6_errata_word@l 702 ori r4, r4, cpu6_errata_word@l
699 li r3, 0x3980 703 li r3, 0x3f80
700 stw r3, 12(r4) 704 stw r3, 12(r4)
701 lwz r3, 12(r4) 705 lwz r3, 12(r4)
702#endif 706#endif
703 mtspr SPRN_M_TWB, r6 707 mtspr SPRN_M_TW, r6
704 lis r4,2f@h 708 lis r4,2f@h
705 ori r4,r4,2f@l 709 ori r4,r4,2f@l
706 tophys(r4,r4) 710 tophys(r4,r4)
@@ -874,10 +878,10 @@ _GLOBAL(set_context)
874 lis r6, cpu6_errata_word@h 878 lis r6, cpu6_errata_word@h
875 ori r6, r6, cpu6_errata_word@l 879 ori r6, r6, cpu6_errata_word@l
876 tophys (r4, r4) 880 tophys (r4, r4)
877 li r7, 0x3980 881 li r7, 0x3f80
878 stw r7, 12(r6) 882 stw r7, 12(r6)
879 lwz r7, 12(r6) 883 lwz r7, 12(r6)
880 mtspr SPRN_M_TWB, r4 /* Update MMU base address */ 884 mtspr SPRN_M_TW, r4 /* Update MMU base address */
881 li r7, 0x3380 885 li r7, 0x3380
882 stw r7, 12(r6) 886 stw r7, 12(r6)
883 lwz r7, 12(r6) 887 lwz r7, 12(r6)
@@ -885,7 +889,7 @@ _GLOBAL(set_context)
885#else 889#else
886 mtspr SPRN_M_CASID,r3 /* Update context */ 890 mtspr SPRN_M_CASID,r3 /* Update context */
887 tophys (r4, r4) 891 tophys (r4, r4)
888 mtspr SPRN_M_TWB, r4 /* and pgd */ 892 mtspr SPRN_M_TW, r4 /* and pgd */
889#endif 893#endif
890 SYNC 894 SYNC
891 blr 895 blr