patch-2.3.32 linux/arch/arm/kernel/setup.c
Next file: linux/arch/arm/kernel/traps.c
Previous file: linux/arch/arm/kernel/ioport.c
Back to the patch index
Back to the overall index
- Lines: 193
- Date:
Mon Dec 13 16:26:27 1999
- Orig file:
v2.3.31/linux/arch/arm/kernel/setup.c
- Orig date:
Tue Dec 7 09:32:40 1999
diff -u --recursive --new-file v2.3.31/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
@@ -249,67 +249,132 @@
#endif
}
+#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define P_PFN_DOWN(x) O_PFN_DOWN((x) - PHYS_OFFSET)
+#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
+
+#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
+#define P_PFN_UP(x) O_PFN_UP((x) - PHYS_OFFSET)
+#define V_PFN_UP(x) O_PFN_UP(__pa(x))
+
+#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
+#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
+ (((unsigned long)(s)) & PAGE_MASK))
+
+#define free_bootmem(s,sz) free_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
+#define reserve_bootmem(s,sz) reserve_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
+
+static unsigned int __init find_bootmap_pfn(unsigned int bootmap_pages)
+{
+ unsigned int start_pfn, bank, bootmap_pfn;
+
+ start_pfn = V_PFN_UP(&_end);
+ bootmap_pfn = 0;
+
+ /*
+ * FIXME: We really want to avoid allocating the bootmap
+ * over the top of the initrd.
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ if (__pa(initrd_end) > (meminfo.end + PHYS_OFFSET)) {
+ printk ("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx) - disabling initrd\n",
+ __pa(initrd_end), meminfo.end + PHYS_OFFSET);
+ initrd_start = 0;
+ initrd_end = 0;
+ }
+ }
+#endif
+
+ for (bank = 0; bank < meminfo.nr_banks; bank ++) {
+ unsigned int start, end;
+
+ if (meminfo.bank[bank].size == 0)
+ continue;
+
+ start = O_PFN_UP(meminfo.bank[bank].start);
+ end = O_PFN_DOWN(meminfo.bank[bank].size +
+ meminfo.bank[bank].start);
+
+ if (end < start_pfn)
+ continue;
+
+ if (start < start_pfn)
+ start = start_pfn;
+
+ if (end <= start)
+ continue;
+
+ if (end - start >= bootmap_pages) {
+ bootmap_pfn = start;
+ break;
+ }
+ }
+
+ if (bootmap_pfn == 0)
+ BUG();
+
+ return bootmap_pfn;
+}
+
/*
- * Work out our memory regions. Note that "pfn" is the physical page number
- * relative to the first physical page, not the physical address itself.
+ * Initialise the bootmem allocator.
*/
static void __init setup_bootmem(void)
{
- unsigned int end_pfn, bootmem_end;
- int bank;
+ unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn;
+ unsigned int i;
/*
- * Calculate the end of memory.
+ * Calculate the physical address of the top of memory.
*/
- for (bank = 0; bank < meminfo.nr_banks; bank++) {
- if (meminfo.bank[bank].size) {
- unsigned long end;
+ meminfo.end = 0;
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ unsigned long end;
- end = meminfo.bank[bank].start +
- meminfo.bank[bank].size;
+ if (meminfo.bank[i].size != 0) {
+ end = meminfo.bank[i].start + meminfo.bank[i].size;
if (meminfo.end < end)
meminfo.end = end;
}
}
- bootmem_end = __pa(PAGE_ALIGN((unsigned long)&_end));
- end_pfn = meminfo.end >> PAGE_SHIFT;
+ start_pfn = O_PFN_UP(PHYS_OFFSET);
+ end_pfn = O_PFN_DOWN(meminfo.end);
+ bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
+ bootmap_pfn = find_bootmap_pfn(bootmap_pages);
/*
* Initialise the boot-time allocator
*/
- bootmem_end += init_bootmem(bootmem_end >> PAGE_SHIFT, end_pfn, PHYS_OFFSET);
+ init_bootmem_start(bootmap_pfn, start_pfn, end_pfn);
/*
* Register all available RAM with the bootmem allocator.
- * The address is relative to the start of physical memory.
*/
- for (bank = 0; bank < meminfo.nr_banks; bank ++)
- free_bootmem(meminfo.bank[bank].start, meminfo.bank[bank].size);
+ for (i = 0; i < meminfo.nr_banks; i++)
+ if (meminfo.bank[i].size)
+ free_bootmem(O_PFN_UP(meminfo.bank[i].start),
+ PFN_SIZE(meminfo.bank[i].size));
/*
- * reserve the following regions:
- * physical page 0 - it contains the exception vectors
- * kernel and the bootmem structure
- * swapper page directory (if any)
- * initrd (if any)
+ * Register the reserved regions with bootmem
*/
- reserve_bootmem(0, PAGE_SIZE);
+ reserve_bootmem(bootmap_pfn, bootmap_pages);
+ reserve_bootmem(V_PFN_DOWN(&_stext), PFN_RANGE(&_stext, &_end));
+
#ifdef CONFIG_CPU_32
- reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *));
+ /*
+ * Reserve the page tables. These are already in use.
+ */
+ reserve_bootmem(V_PFN_DOWN(swapper_pg_dir),
+ PFN_SIZE(PTRS_PER_PGD * sizeof(void *)));
#endif
- reserve_bootmem(__pa(&_stext), bootmem_end - __pa(&_stext));
#ifdef CONFIG_BLK_DEV_INITRD
- if (__pa(initrd_end) > (end_pfn << PAGE_SHIFT)) {
- printk ("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08x) - disabling initrd\n",
- __pa(initrd_end), end_pfn << PAGE_SHIFT);
- initrd_start = 0;
- }
-
if (initrd_start)
- reserve_bootmem(__pa(initrd_start),
- initrd_end - initrd_start);
+ reserve_bootmem(O_PFN_DOWN(initrd_start),
+ PFN_RANGE(initrd_start, initrd_end));
#endif
}
@@ -332,7 +397,7 @@
virt_start = __phys_to_virt(meminfo.bank[i].start);
virt_end = virt_start + meminfo.bank[i].size - 1;
- res = alloc_bootmem(sizeof(*res));
+ res = alloc_bootmem_low(sizeof(*res));
res->name = "System RAM";
res->start = __virt_to_bus(virt_start);
res->end = __virt_to_bus(virt_end);
@@ -400,7 +465,7 @@
}
for (i = 0; i < 4; i++) {
- meminfo.bank[i].start = i << 26;
+ meminfo.bank[i].start = PHYS_OFFSET + (i << 26);
meminfo.bank[i].size =
params->u1.s.pages_in_bank[i] *
params->u1.s.page_size;
@@ -627,7 +692,7 @@
if (meminfo.nr_banks == 0) {
meminfo.nr_banks = 1;
- meminfo.bank[0].start = 0;
+ meminfo.bank[0].start = PHYS_OFFSET;
if (params)
meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
else
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)