diff options
author | LEROY Christophe <christophe.leroy@c-s.fr> | 2014-09-19 04:36:08 -0400 |
---|---|---|
committer | Scott Wood <scottwood@freescale.com> | 2014-11-07 19:10:40 -0500 |
commit | cbc130f120d5e180a70a0fa4a8b4191e44548a87 (patch) | |
tree | e69a89701ad7ce65c1abff8760f4af5d19235660 /arch/powerpc/kernel/head_8xx.S | |
parent | 6cde2b6f399e7d68a4b482680850a077104f9068 (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.S | 48 |
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 | ||
317 | 3: | 318 | 3: |
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 | ||
390 | 3: | 392 | 3: |
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 */ | 537 | 3: rlwinm r10, r10, 12, 20, 29 /* Extract level 1 index */ |
535 | 3: 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 |