aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2008-09-02 11:44:21 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-11-28 10:36:45 -0500
commita1bbaec0cd2a59d4bb09b72e4541a8a12e480d5d (patch)
treec574a8fb0078ea5931264bbac8ee6dfc5e3bc6e5
parent4b5f32cee0cce7b9783ced5cbeabd17aa53c51fb (diff)
[ARM] split highmem into its own memory bank
Doing so will greatly simplify the bootmem initialization code as each bank is therefore entirely lowmem or highmem with no crossing between those zones. Signed-off-by: Nicolas Pitre <nico@marvell.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mm/mmu.c84
1 files changed, 51 insertions, 33 deletions
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 6870805c31dd..ab511d94d917 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -651,44 +651,62 @@ __early_param("vmalloc=", early_vmalloc);
651 651
652#define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve) 652#define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve)
653 653
654static int __init check_membank_valid(struct membank *mb)
655{
656 /*
657 * Check whether this memory region would entirely overlap
658 * the vmalloc area.
659 */
660 if (phys_to_virt(mb->start) >= VMALLOC_MIN) {
661 printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
662 "(vmalloc region overlap).\n",
663 mb->start, mb->start + mb->size - 1);
664 return 0;
665 }
666
667 /*
668 * Check whether this memory region would partially overlap
669 * the vmalloc area.
670 */
671 if (phys_to_virt(mb->start + mb->size) < phys_to_virt(mb->start) ||
672 phys_to_virt(mb->start + mb->size) > VMALLOC_MIN) {
673 unsigned long newsize = VMALLOC_MIN - phys_to_virt(mb->start);
674
675 printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
676 "to -%.8lx (vmalloc region overlap).\n",
677 mb->start, mb->start + mb->size - 1,
678 mb->start + newsize - 1);
679 mb->size = newsize;
680 }
681
682 return 1;
683}
684
685static void __init sanity_check_meminfo(void) 654static void __init sanity_check_meminfo(void)
686{ 655{
687 int i, j; 656 int i, j;
688 657
689 for (i = 0, j = 0; i < meminfo.nr_banks; i++) { 658 for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
690 if (check_membank_valid(&meminfo.bank[i])) 659 struct membank *bank = &meminfo.bank[j];
691 meminfo.bank[j++] = meminfo.bank[i]; 660 *bank = meminfo.bank[i];
661
662#ifdef CONFIG_HIGHMEM
663 /*
664 * Split those memory banks which are partially overlapping
665 * the vmalloc area greatly simplifying things later.
666 */
667 if (__va(bank->start) < VMALLOC_MIN &&
668 bank->size > VMALLOC_MIN - __va(bank->start)) {
669 if (meminfo.nr_banks >= NR_BANKS) {
670 printk(KERN_CRIT "NR_BANKS too low, "
671 "ignoring high memory\n");
672 } else {
673 memmove(bank + 1, bank,
674 (meminfo.nr_banks - i) * sizeof(*bank));
675 meminfo.nr_banks++;
676 i++;
677 bank[1].size -= VMALLOC_MIN - __va(bank->start);
678 bank[1].start = __pa(VMALLOC_MIN - 1) + 1;
679 j++;
680 }
681 bank->size = VMALLOC_MIN - __va(bank->start);
682 }
683#else
684 /*
685 * Check whether this memory bank would entirely overlap
686 * the vmalloc area.
687 */
688 if (__va(bank->start) >= VMALLOC_MIN) {
689 printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
690 "(vmalloc region overlap).\n",
691 bank->start, bank->start + bank->size - 1);
692 continue;
693 }
694
695 /*
696 * Check whether this memory bank would partially overlap
697 * the vmalloc area.
698 */
699 if (__va(bank->start + bank->size) > VMALLOC_MIN ||
700 __va(bank->start + bank->size) < __va(bank->start)) {
701 unsigned long newsize = VMALLOC_MIN - __va(bank->start);
702 printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
703 "to -%.8lx (vmalloc region overlap).\n",
704 bank->start, bank->start + bank->size - 1,
705 bank->start + newsize - 1);
706 bank->size = newsize;
707 }
708#endif
709 j++;
692 } 710 }
693 meminfo.nr_banks = j; 711 meminfo.nr_banks = j;
694} 712}