aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorIlya Yanok <yanok@emcraft.com>2008-12-10 20:55:41 -0500
committerPaul Mackerras <paulus@samba.org>2008-12-28 17:53:25 -0500
commitca9153a3a2a7556d091dfe080e42b0e67881fff6 (patch)
tree35b5ce24f190690cf7a726cbb97980da51704855 /arch/powerpc/kernel
parent6ca4f7494bde078b2b730e28e4ea1dc36a772f70 (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.c4
-rw-r--r--arch/powerpc/kernel/head_44x.S23
-rw-r--r--arch/powerpc/kernel/misc_32.S12
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 */
566finish_tlb_load: 570finish_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
650sdata: 655sdata:
651 .globl empty_zero_page 656 .globl empty_zero_page
652empty_zero_page: 657empty_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)
426BEGIN_FTR_SECTION 426BEGIN_FTR_SECTION
427 blr 427 blr
428END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) 428END_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
4330: dcbst 0,r3 /* Write line to ram */ 4330: 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
4740: dcbst 0,r3 /* Write line to ram */ 4740: 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
5552: 5552:
556 mtctr r0 556 mtctr r0