diff options
author | Ilya Yanok <yanok@emcraft.com> | 2008-12-10 20:55:41 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-12-28 17:53:25 -0500 |
commit | ca9153a3a2a7556d091dfe080e42b0e67881fff6 (patch) | |
tree | 35b5ce24f190690cf7a726cbb97980da51704855 /arch/powerpc/kernel | |
parent | 6ca4f7494bde078b2b730e28e4ea1dc36a772f70 (diff) |
powerpc/44x: Support 16K/64K base page sizes on 44x
This adds support for 16k and 64k page sizes on PowerPC 44x processors.
The PGDIR table is much smaller than a page when using 16k or 64k
pages (512 and 32 bytes respectively) so we allocate the PGDIR with
kzalloc() instead of __get_free_pages().
One PTE table covers rather a large memory area when using 16k or 64k
pages (32MB or 512MB respectively), so we can easily put FIXMAP and
PKMAP in the area covered by one PTE table.
Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
Signed-off-by: Vladimir Panfilov <pvr@emcraft.com>
Signed-off-by: Ilya Yanok <yanok@emcraft.com>
Acked-by: Josh Boyer <jwboyer@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r-- | arch/powerpc/kernel/asm-offsets.c | 4 | ||||
-rw-r--r-- | arch/powerpc/kernel/head_44x.S | 23 | ||||
-rw-r--r-- | arch/powerpc/kernel/misc_32.S | 12 |
3 files changed, 24 insertions, 15 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index c05ab1d3e620..661d07d2146b 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -380,6 +380,10 @@ int main(void) | |||
380 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); | 380 | DEFINE(VCPU_FAULT_DEAR, offsetof(struct kvm_vcpu, arch.fault_dear)); |
381 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); | 381 | DEFINE(VCPU_FAULT_ESR, offsetof(struct kvm_vcpu, arch.fault_esr)); |
382 | #endif | 382 | #endif |
383 | #ifdef CONFIG_44x | ||
384 | DEFINE(PGD_T_LOG2, PGD_T_LOG2); | ||
385 | DEFINE(PTE_T_LOG2, PTE_T_LOG2); | ||
386 | #endif | ||
383 | 387 | ||
384 | return 0; | 388 | return 0; |
385 | } | 389 | } |
diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index bd4fe9e7278b..b56fecc93a16 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S | |||
@@ -402,12 +402,14 @@ interrupt_base: | |||
402 | rlwimi r13,r12,10,30,30 | 402 | rlwimi r13,r12,10,30,30 |
403 | 403 | ||
404 | /* Load the PTE */ | 404 | /* Load the PTE */ |
405 | rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ | 405 | /* Compute pgdir/pmd offset */ |
406 | rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 | ||
406 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ | 407 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ |
407 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ | 408 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ |
408 | beq 2f /* Bail if no table */ | 409 | beq 2f /* Bail if no table */ |
409 | 410 | ||
410 | rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ | 411 | /* Compute pte address */ |
412 | rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 | ||
411 | lwz r11, 0(r12) /* Get high word of pte entry */ | 413 | lwz r11, 0(r12) /* Get high word of pte entry */ |
412 | lwz r12, 4(r12) /* Get low word of pte entry */ | 414 | lwz r12, 4(r12) /* Get low word of pte entry */ |
413 | 415 | ||
@@ -496,12 +498,14 @@ tlb_44x_patch_hwater_D: | |||
496 | /* Make up the required permissions */ | 498 | /* Make up the required permissions */ |
497 | li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC | 499 | li r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC |
498 | 500 | ||
499 | rlwinm r12, r10, 13, 19, 29 /* Compute pgdir/pmd offset */ | 501 | /* Compute pgdir/pmd offset */ |
502 | rlwinm r12, r10, PPC44x_PGD_OFF_SHIFT, PPC44x_PGD_OFF_MASK_BIT, 29 | ||
500 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ | 503 | lwzx r11, r12, r11 /* Get pgd/pmd entry */ |
501 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ | 504 | rlwinm. r12, r11, 0, 0, 20 /* Extract pt base address */ |
502 | beq 2f /* Bail if no table */ | 505 | beq 2f /* Bail if no table */ |
503 | 506 | ||
504 | rlwimi r12, r10, 23, 20, 28 /* Compute pte address */ | 507 | /* Compute pte address */ |
508 | rlwimi r12, r10, PPC44x_PTE_ADD_SHIFT, PPC44x_PTE_ADD_MASK_BIT, 28 | ||
505 | lwz r11, 0(r12) /* Get high word of pte entry */ | 509 | lwz r11, 0(r12) /* Get high word of pte entry */ |
506 | lwz r12, 4(r12) /* Get low word of pte entry */ | 510 | lwz r12, 4(r12) /* Get low word of pte entry */ |
507 | 511 | ||
@@ -565,15 +569,16 @@ tlb_44x_patch_hwater_I: | |||
565 | */ | 569 | */ |
566 | finish_tlb_load: | 570 | finish_tlb_load: |
567 | /* Combine RPN & ERPN an write WS 0 */ | 571 | /* Combine RPN & ERPN an write WS 0 */ |
568 | rlwimi r11,r12,0,0,19 | 572 | rlwimi r11,r12,0,0,31-PAGE_SHIFT |
569 | tlbwe r11,r13,PPC44x_TLB_XLAT | 573 | tlbwe r11,r13,PPC44x_TLB_XLAT |
570 | 574 | ||
571 | /* | 575 | /* |
572 | * Create WS1. This is the faulting address (EPN), | 576 | * Create WS1. This is the faulting address (EPN), |
573 | * page size, and valid flag. | 577 | * page size, and valid flag. |
574 | */ | 578 | */ |
575 | li r11,PPC44x_TLB_VALID | PPC44x_TLB_4K | 579 | li r11,PPC44x_TLB_VALID | PPC44x_TLBE_SIZE |
576 | rlwimi r10,r11,0,20,31 /* Insert valid and page size*/ | 580 | /* Insert valid and page size */ |
581 | rlwimi r10,r11,0,PPC44x_PTE_ADD_MASK_BIT,31 | ||
577 | tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ | 582 | tlbwe r10,r13,PPC44x_TLB_PAGEID /* Write PAGEID */ |
578 | 583 | ||
579 | /* And WS 2 */ | 584 | /* And WS 2 */ |
@@ -645,12 +650,12 @@ _GLOBAL(set_context) | |||
645 | * goes at the beginning of the data segment, which is page-aligned. | 650 | * goes at the beginning of the data segment, which is page-aligned. |
646 | */ | 651 | */ |
647 | .data | 652 | .data |
648 | .align 12 | 653 | .align PAGE_SHIFT |
649 | .globl sdata | 654 | .globl sdata |
650 | sdata: | 655 | sdata: |
651 | .globl empty_zero_page | 656 | .globl empty_zero_page |
652 | empty_zero_page: | 657 | empty_zero_page: |
653 | .space 4096 | 658 | .space PAGE_SIZE |
654 | 659 | ||
655 | /* | 660 | /* |
656 | * To support >32-bit physical addresses, we use an 8KB pgdir. | 661 | * To support >32-bit physical addresses, we use an 8KB pgdir. |
diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index ae0d084b6a24..15f28e0de78d 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S | |||
@@ -426,8 +426,8 @@ _GLOBAL(__flush_dcache_icache) | |||
426 | BEGIN_FTR_SECTION | 426 | BEGIN_FTR_SECTION |
427 | blr | 427 | blr |
428 | END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | 428 | END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) |
429 | rlwinm r3,r3,0,0,19 /* Get page base address */ | 429 | rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ |
430 | li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ | 430 | li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ |
431 | mtctr r4 | 431 | mtctr r4 |
432 | mr r6,r3 | 432 | mr r6,r3 |
433 | 0: dcbst 0,r3 /* Write line to ram */ | 433 | 0: dcbst 0,r3 /* Write line to ram */ |
@@ -467,8 +467,8 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | |||
467 | rlwinm r0,r10,0,28,26 /* clear DR */ | 467 | rlwinm r0,r10,0,28,26 /* clear DR */ |
468 | mtmsr r0 | 468 | mtmsr r0 |
469 | isync | 469 | isync |
470 | rlwinm r3,r3,0,0,19 /* Get page base address */ | 470 | rlwinm r3,r3,0,0,31-PAGE_SHIFT /* Get page base address */ |
471 | li r4,4096/L1_CACHE_BYTES /* Number of lines in a page */ | 471 | li r4,PAGE_SIZE/L1_CACHE_BYTES /* Number of lines in a page */ |
472 | mtctr r4 | 472 | mtctr r4 |
473 | mr r6,r3 | 473 | mr r6,r3 |
474 | 0: dcbst 0,r3 /* Write line to ram */ | 474 | 0: dcbst 0,r3 /* Write line to ram */ |
@@ -492,7 +492,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) | |||
492 | * void clear_pages(void *page, int order) ; | 492 | * void clear_pages(void *page, int order) ; |
493 | */ | 493 | */ |
494 | _GLOBAL(clear_pages) | 494 | _GLOBAL(clear_pages) |
495 | li r0,4096/L1_CACHE_BYTES | 495 | li r0,PAGE_SIZE/L1_CACHE_BYTES |
496 | slw r0,r0,r4 | 496 | slw r0,r0,r4 |
497 | mtctr r0 | 497 | mtctr r0 |
498 | #ifdef CONFIG_8xx | 498 | #ifdef CONFIG_8xx |
@@ -550,7 +550,7 @@ _GLOBAL(copy_page) | |||
550 | dcbt r5,r4 | 550 | dcbt r5,r4 |
551 | li r11,L1_CACHE_BYTES+4 | 551 | li r11,L1_CACHE_BYTES+4 |
552 | #endif /* MAX_COPY_PREFETCH */ | 552 | #endif /* MAX_COPY_PREFETCH */ |
553 | li r0,4096/L1_CACHE_BYTES - MAX_COPY_PREFETCH | 553 | li r0,PAGE_SIZE/L1_CACHE_BYTES - MAX_COPY_PREFETCH |
554 | crclr 4*cr0+eq | 554 | crclr 4*cr0+eq |
555 | 2: | 555 | 2: |
556 | mtctr r0 | 556 | mtctr r0 |