summaryrefslogtreecommitdiffstats
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 15:36:45 +0000
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 6870805c31d..ab511d94d91 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -651,44 +651,62 @@ __early_param("vmalloc=", early_vmalloc);
#define VMALLOC_MIN (void *)(VMALLOC_END - vmalloc_reserve)
-static int __init check_membank_valid(struct membank *mb)
-{
- /*
- * Check whether this memory region would entirely overlap
- * the vmalloc area.
- */
- if (phys_to_virt(mb->start) >= VMALLOC_MIN) {
- printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
- "(vmalloc region overlap).\n",
- mb->start, mb->start + mb->size - 1);
- return 0;
- }
-
- /*
- * Check whether this memory region would partially overlap
- * the vmalloc area.
- */
- if (phys_to_virt(mb->start + mb->size) < phys_to_virt(mb->start) ||
- phys_to_virt(mb->start + mb->size) > VMALLOC_MIN) {
- unsigned long newsize = VMALLOC_MIN - phys_to_virt(mb->start);
-
- printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
- "to -%.8lx (vmalloc region overlap).\n",
- mb->start, mb->start + mb->size - 1,
- mb->start + newsize - 1);
- mb->size = newsize;
- }
-
- return 1;
-}
-
static void __init sanity_check_meminfo(void)
{
int i, j;
for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
- if (check_membank_valid(&meminfo.bank[i]))
- meminfo.bank[j++] = meminfo.bank[i];
+ struct membank *bank = &meminfo.bank[j];
+ *bank = meminfo.bank[i];
+
+#ifdef CONFIG_HIGHMEM
+ /*
+ * Split those memory banks which are partially overlapping
+ * the vmalloc area greatly simplifying things later.
+ */
+ if (__va(bank->start) < VMALLOC_MIN &&
+ bank->size > VMALLOC_MIN - __va(bank->start)) {
+ if (meminfo.nr_banks >= NR_BANKS) {
+ printk(KERN_CRIT "NR_BANKS too low, "
+ "ignoring high memory\n");
+ } else {
+ memmove(bank + 1, bank,
+ (meminfo.nr_banks - i) * sizeof(*bank));
+ meminfo.nr_banks++;
+ i++;
+ bank[1].size -= VMALLOC_MIN - __va(bank->start);
+ bank[1].start = __pa(VMALLOC_MIN - 1) + 1;
+ j++;
+ }
+ bank->size = VMALLOC_MIN - __va(bank->start);
+ }
+#else
+ /*
+ * Check whether this memory bank would entirely overlap
+ * the vmalloc area.
+ */
+ if (__va(bank->start) >= VMALLOC_MIN) {
+ printk(KERN_NOTICE "Ignoring RAM at %.8lx-%.8lx "
+ "(vmalloc region overlap).\n",
+ bank->start, bank->start + bank->size - 1);
+ continue;
+ }
+
+ /*
+ * Check whether this memory bank would partially overlap
+ * the vmalloc area.
+ */
+ if (__va(bank->start + bank->size) > VMALLOC_MIN ||
+ __va(bank->start + bank->size) < __va(bank->start)) {
+ unsigned long newsize = VMALLOC_MIN - __va(bank->start);
+ printk(KERN_NOTICE "Truncating RAM at %.8lx-%.8lx "
+ "to -%.8lx (vmalloc region overlap).\n",
+ bank->start, bank->start + bank->size - 1,
+ bank->start + newsize - 1);
+ bank->size = newsize;
+ }
+#endif
+ j++;
}
meminfo.nr_banks = j;
}