aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mm/mmu.c')
-rw-r--r--arch/arm/mm/mmu.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index ff7b43b5885a..6cf76b3b68d1 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -533,7 +533,7 @@ static void __init *early_alloc(unsigned long sz)
533static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot) 533static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr, unsigned long prot)
534{ 534{
535 if (pmd_none(*pmd)) { 535 if (pmd_none(*pmd)) {
536 pte_t *pte = early_alloc(2 * PTRS_PER_PTE * sizeof(pte_t)); 536 pte_t *pte = early_alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
537 __pmd_populate(pmd, __pa(pte), prot); 537 __pmd_populate(pmd, __pa(pte), prot);
538 } 538 }
539 BUG_ON(pmd_bad(*pmd)); 539 BUG_ON(pmd_bad(*pmd));
@@ -551,11 +551,11 @@ static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
551 } while (pte++, addr += PAGE_SIZE, addr != end); 551 } while (pte++, addr += PAGE_SIZE, addr != end);
552} 552}
553 553
554static void __init alloc_init_section(pgd_t *pgd, unsigned long addr, 554static void __init alloc_init_section(pud_t *pud, unsigned long addr,
555 unsigned long end, phys_addr_t phys, 555 unsigned long end, phys_addr_t phys,
556 const struct mem_type *type) 556 const struct mem_type *type)
557{ 557{
558 pmd_t *pmd = pmd_offset(pgd, addr); 558 pmd_t *pmd = pmd_offset(pud, addr);
559 559
560 /* 560 /*
561 * Try a section mapping - end, addr and phys must all be aligned 561 * Try a section mapping - end, addr and phys must all be aligned
@@ -584,6 +584,19 @@ static void __init alloc_init_section(pgd_t *pgd, unsigned long addr,
584 } 584 }
585} 585}
586 586
587static void alloc_init_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
588 unsigned long phys, const struct mem_type *type)
589{
590 pud_t *pud = pud_offset(pgd, addr);
591 unsigned long next;
592
593 do {
594 next = pud_addr_end(addr, end);
595 alloc_init_section(pud, addr, next, phys, type);
596 phys += next - addr;
597 } while (pud++, addr = next, addr != end);
598}
599
587static void __init create_36bit_mapping(struct map_desc *md, 600static void __init create_36bit_mapping(struct map_desc *md,
588 const struct mem_type *type) 601 const struct mem_type *type)
589{ 602{
@@ -592,13 +605,13 @@ static void __init create_36bit_mapping(struct map_desc *md,
592 pgd_t *pgd; 605 pgd_t *pgd;
593 606
594 addr = md->virtual; 607 addr = md->virtual;
595 phys = (unsigned long)__pfn_to_phys(md->pfn); 608 phys = __pfn_to_phys(md->pfn);
596 length = PAGE_ALIGN(md->length); 609 length = PAGE_ALIGN(md->length);
597 610
598 if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { 611 if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
599 printk(KERN_ERR "MM: CPU does not support supersection " 612 printk(KERN_ERR "MM: CPU does not support supersection "
600 "mapping for 0x%08llx at 0x%08lx\n", 613 "mapping for 0x%08llx at 0x%08lx\n",
601 __pfn_to_phys((u64)md->pfn), addr); 614 (long long)__pfn_to_phys((u64)md->pfn), addr);
602 return; 615 return;
603 } 616 }
604 617
@@ -611,14 +624,14 @@ static void __init create_36bit_mapping(struct map_desc *md,
611 if (type->domain) { 624 if (type->domain) {
612 printk(KERN_ERR "MM: invalid domain in supersection " 625 printk(KERN_ERR "MM: invalid domain in supersection "
613 "mapping for 0x%08llx at 0x%08lx\n", 626 "mapping for 0x%08llx at 0x%08lx\n",
614 __pfn_to_phys((u64)md->pfn), addr); 627 (long long)__pfn_to_phys((u64)md->pfn), addr);
615 return; 628 return;
616 } 629 }
617 630
618 if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { 631 if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
619 printk(KERN_ERR "MM: cannot create mapping for " 632 printk(KERN_ERR "MM: cannot create mapping for 0x%08llx"
620 "0x%08llx at 0x%08lx invalid alignment\n", 633 " at 0x%08lx invalid alignment\n",
621 __pfn_to_phys((u64)md->pfn), addr); 634 (long long)__pfn_to_phys((u64)md->pfn), addr);
622 return; 635 return;
623 } 636 }
624 637
@@ -631,7 +644,8 @@ static void __init create_36bit_mapping(struct map_desc *md,
631 pgd = pgd_offset_k(addr); 644 pgd = pgd_offset_k(addr);
632 end = addr + length; 645 end = addr + length;
633 do { 646 do {
634 pmd_t *pmd = pmd_offset(pgd, addr); 647 pud_t *pud = pud_offset(pgd, addr);
648 pmd_t *pmd = pmd_offset(pud, addr);
635 int i; 649 int i;
636 650
637 for (i = 0; i < 16; i++) 651 for (i = 0; i < 16; i++)
@@ -652,22 +666,23 @@ static void __init create_36bit_mapping(struct map_desc *md,
652 */ 666 */
653static void __init create_mapping(struct map_desc *md) 667static void __init create_mapping(struct map_desc *md)
654{ 668{
655 unsigned long phys, addr, length, end; 669 unsigned long addr, length, end;
670 phys_addr_t phys;
656 const struct mem_type *type; 671 const struct mem_type *type;
657 pgd_t *pgd; 672 pgd_t *pgd;
658 673
659 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) { 674 if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
660 printk(KERN_WARNING "BUG: not creating mapping for " 675 printk(KERN_WARNING "BUG: not creating mapping for 0x%08llx"
661 "0x%08llx at 0x%08lx in user region\n", 676 " at 0x%08lx in user region\n",
662 __pfn_to_phys((u64)md->pfn), md->virtual); 677 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
663 return; 678 return;
664 } 679 }
665 680
666 if ((md->type == MT_DEVICE || md->type == MT_ROM) && 681 if ((md->type == MT_DEVICE || md->type == MT_ROM) &&
667 md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { 682 md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) {
668 printk(KERN_WARNING "BUG: mapping for 0x%08llx at 0x%08lx " 683 printk(KERN_WARNING "BUG: mapping for 0x%08llx"
669 "overlaps vmalloc space\n", 684 " at 0x%08lx overlaps vmalloc space\n",
670 __pfn_to_phys((u64)md->pfn), md->virtual); 685 (long long)__pfn_to_phys((u64)md->pfn), md->virtual);
671 } 686 }
672 687
673 type = &mem_types[md->type]; 688 type = &mem_types[md->type];
@@ -681,13 +696,13 @@ static void __init create_mapping(struct map_desc *md)
681 } 696 }
682 697
683 addr = md->virtual & PAGE_MASK; 698 addr = md->virtual & PAGE_MASK;
684 phys = (unsigned long)__pfn_to_phys(md->pfn); 699 phys = __pfn_to_phys(md->pfn);
685 length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); 700 length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
686 701
687 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) { 702 if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
688 printk(KERN_WARNING "BUG: map for 0x%08lx at 0x%08lx can not " 703 printk(KERN_WARNING "BUG: map for 0x%08llx at 0x%08lx can not "
689 "be mapped using pages, ignoring.\n", 704 "be mapped using pages, ignoring.\n",
690 __pfn_to_phys(md->pfn), addr); 705 (long long)__pfn_to_phys(md->pfn), addr);
691 return; 706 return;
692 } 707 }
693 708
@@ -696,7 +711,7 @@ static void __init create_mapping(struct map_desc *md)
696 do { 711 do {
697 unsigned long next = pgd_addr_end(addr, end); 712 unsigned long next = pgd_addr_end(addr, end);
698 713
699 alloc_init_section(pgd, addr, next, phys, type); 714 alloc_init_pud(pgd, addr, next, phys, type);
700 715
701 phys += next - addr; 716 phys += next - addr;
702 addr = next; 717 addr = next;
@@ -794,9 +809,10 @@ static void __init sanity_check_meminfo(void)
794 */ 809 */
795 if (__va(bank->start) >= vmalloc_min || 810 if (__va(bank->start) >= vmalloc_min ||
796 __va(bank->start) < (void *)PAGE_OFFSET) { 811 __va(bank->start) < (void *)PAGE_OFFSET) {
797 printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx " 812 printk(KERN_NOTICE "Ignoring RAM at %.8llx-%.8llx "
798 "(vmalloc region overlap).\n", 813 "(vmalloc region overlap).\n",
799 bank->start, bank->start + bank->size - 1); 814 (unsigned long long)bank->start,
815 (unsigned long long)bank->start + bank->size - 1);
800 continue; 816 continue;
801 } 817 }
802 818
@@ -807,10 +823,11 @@ static void __init sanity_check_meminfo(void)
807 if (__va(bank->start + bank->size) > vmalloc_min || 823 if (__va(bank->start + bank->size) > vmalloc_min ||
808 __va(bank->start + bank->size) < __va(bank->start)) { 824 __va(bank->start + bank->size) < __va(bank->start)) {
809 unsigned long newsize = vmalloc_min - __va(bank->start); 825 unsigned long newsize = vmalloc_min - __va(bank->start);
810 printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx " 826 printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "
811 "to -%.8lx (vmalloc region overlap).\n", 827 "to -%.8llx (vmalloc region overlap).\n",
812 bank->start, bank->start + bank->size - 1, 828 (unsigned long long)bank->start,
813 bank->start + newsize - 1); 829 (unsigned long long)bank->start + bank->size - 1,
830 (unsigned long long)bank->start + newsize - 1);
814 bank->size = newsize; 831 bank->size = newsize;
815 } 832 }
816#endif 833#endif