aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mm/mmu.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-11-28 10:39:02 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-11-28 10:39:02 -0500
commit7ef4de17cc55a3c3b8d093743b1e3b845d8eba47 (patch)
treeadf87c996affbb6c42850d55cb34c0e5a2f6d340 /arch/arm/mm/mmu.c
parentf412b09f4ed7c57f5b8935ed7d6fc786f402a629 (diff)
parentb5ee9002583fc14e6d45a04c18f208987a8fbced (diff)
Merge branch 'highmem' into devel
Conflicts: arch/arm/mach-clps7500/include/mach/memory.h
Diffstat (limited to 'arch/arm/mm/mmu.c')
-rw-r--r--arch/arm/mm/mmu.c114
1 files changed, 66 insertions, 48 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index f24803c1fb0b..c0b9a78d7b87 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -646,61 +646,79 @@ static void __init early_vmalloc(char **arg)
646 "vmalloc area too small, limiting to %luMB\n", 646 "vmalloc area too small, limiting to %luMB\n",
647 vmalloc_reserve >> 20); 647 vmalloc_reserve >> 20);
648 } 648 }
649
650 if (vmalloc_reserve > VMALLOC_END - (PAGE_OFFSET + SZ_32M)) {
651 vmalloc_reserve = VMALLOC_END - (PAGE_OFFSET + SZ_32M);
652 printk(KERN_WARNING
653 "vmalloc area is too big, limiting to %luMB\n",
654 vmalloc_reserve >> 20);
655 }
649} 656}
650__early_param("vmalloc=", early_vmalloc); 657__early_param("vmalloc=", early_vmalloc);
651 658
652#define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve) 659#define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve)
653 660
654static int __init check_membank_valid(struct membank *mb) 661static void __init sanity_check_meminfo(void)
655{ 662{
656 /* 663 int i, j;
657 * Check whether this memory region has non-zero size or
658 * invalid node number.
659 */
660 if (mb->size == 0 || mb->node >= MAX_NUMNODES)
661 return 0;
662
663 /*
664 * Check whether this memory region would entirely overlap
665 * the vmalloc area.
666 */
667 if (phys_to_virt(mb->start) >= VMALLOC_MIN) {
668 printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
669 "(vmalloc region overlap).\n",
670 mb->start, mb->start + mb->size - 1);
671 return 0;
672 }
673
674 /*
675 * Check whether this memory region would partially overlap
676 * the vmalloc area.
677 */
678 if (phys_to_virt(mb->start + mb->size) < phys_to_virt(mb->start) ||
679 phys_to_virt(mb->start + mb->size) > VMALLOC_MIN) {
680 unsigned long newsize = VMALLOC_MIN - phys_to_virt(mb->start);
681
682 printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
683 "to -%.8lx (vmalloc region overlap).\n",
684 mb->start, mb->start + mb->size - 1,
685 mb->start + newsize - 1);
686 mb->size = newsize;
687 }
688 664
689 return 1; 665 for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
690} 666 struct membank *bank = &meminfo.bank[j];
667 *bank = meminfo.bank[i];
691 668
692static void __init sanity_check_meminfo(struct meminfo *mi) 669#ifdef CONFIG_HIGHMEM
693{ 670 /*
694 int i, j; 671 * Split those memory banks which are partially overlapping
672 * the vmalloc area greatly simplifying things later.
673 */
674 if (__va(bank->start) < VMALLOC_MIN &&
675 bank->size > VMALLOC_MIN - __va(bank->start)) {
676 if (meminfo.nr_banks >= NR_BANKS) {
677 printk(KERN_CRIT "NR_BANKS too low, "
678 "ignoring high memory\n");
679 } else {
680 memmove(bank + 1, bank,
681 (meminfo.nr_banks - i) * sizeof(*bank));
682 meminfo.nr_banks++;
683 i++;
684 bank[1].size -= VMALLOC_MIN - __va(bank->start);
685 bank[1].start = __pa(VMALLOC_MIN - 1) + 1;
686 j++;
687 }
688 bank->size = VMALLOC_MIN - __va(bank->start);
689 }
690#else
691 /*
692 * Check whether this memory bank would entirely overlap
693 * the vmalloc area.
694 */
695 if (__va(bank->start) >= VMALLOC_MIN) {
696 printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
697 "(vmalloc region overlap).\n",
698 bank->start, bank->start + bank->size - 1);
699 continue;
700 }
695 701
696 for (i = 0, j = 0; i < mi->nr_banks; i++) { 702 /*
697 if (check_membank_valid(&mi->bank[i])) 703 * Check whether this memory bank would partially overlap
698 mi->bank[j++] = mi->bank[i]; 704 * the vmalloc area.
705 */
706 if (__va(bank->start + bank->size) > VMALLOC_MIN ||
707 __va(bank->start + bank->size) < __va(bank->start)) {
708 unsigned long newsize = VMALLOC_MIN - __va(bank->start);
709 printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
710 "to -%.8lx (vmalloc region overlap).\n",
711 bank->start, bank->start + bank->size - 1,
712 bank->start + newsize - 1);
713 bank->size = newsize;
714 }
715#endif
716 j++;
699 } 717 }
700 mi->nr_banks = j; 718 meminfo.nr_banks = j;
701} 719}
702 720
703static inline void prepare_page_table(struct meminfo *mi) 721static inline void prepare_page_table(void)
704{ 722{
705 unsigned long addr; 723 unsigned long addr;
706 724
@@ -721,7 +739,7 @@ static inline void prepare_page_table(struct meminfo *mi)
721 * Clear out all the kernel space mappings, except for the first 739 * Clear out all the kernel space mappings, except for the first
722 * memory bank, up to the end of the vmalloc region. 740 * memory bank, up to the end of the vmalloc region.
723 */ 741 */
724 for (addr = __phys_to_virt(mi->bank[0].start + mi->bank[0].size); 742 for (addr = __phys_to_virt(bank_phys_end(&meminfo.bank[0]));
725 addr < VMALLOC_END; addr += PGDIR_SIZE) 743 addr < VMALLOC_END; addr += PGDIR_SIZE)
726 pmd_clear(pmd_off_k(addr)); 744 pmd_clear(pmd_off_k(addr));
727} 745}
@@ -880,14 +898,14 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
880 * paging_init() sets up the page tables, initialises the zone memory 898 * paging_init() sets up the page tables, initialises the zone memory
881 * maps, and sets up the zero page, bad page and bad page tables. 899 * maps, and sets up the zero page, bad page and bad page tables.
882 */ 900 */
883void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) 901void __init paging_init(struct machine_desc *mdesc)
884{ 902{
885 void *zero_page; 903 void *zero_page;
886 904
887 build_mem_type_table(); 905 build_mem_type_table();
888 sanity_check_meminfo(mi); 906 sanity_check_meminfo();
889 prepare_page_table(mi); 907 prepare_page_table();
890 bootmem_init(mi); 908 bootmem_init();
891 devicemaps_init(mdesc); 909 devicemaps_init(mdesc);
892 910
893 top_pmd = pmd_off_k(0xffff0000); 911 top_pmd = pmd_off_k(0xffff0000);