summaryrefslogtreecommitdiffstats
path: root/arch/sparc/mm/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/mm/init.c')
-rw-r--r--arch/sparc/mm/init.c91
1 files changed, 67 insertions, 24 deletions
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index d92fbbb0b..2fa3a2c56 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.83 2000/03/07 23:12:35 anton Exp $
+/* $Id: init.c,v 1.84 2000/03/15 23:26:26 anton Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -43,7 +43,11 @@ unsigned long sparc_unmapped_base;
struct pgtable_cache_struct pgt_quicklists = { 0, 0, 0, 0, SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED };
/* References to section boundaries */
-extern char __init_begin, __init_end, _start, end, etext , edata;
+extern char __init_begin, __init_end, _start, _end, etext , edata;
+
+/* Initial ramdisk setup */
+extern unsigned int sparc_ramdisk_image;
+extern unsigned int sparc_ramdisk_size;
unsigned long totalram_pages = 0;
@@ -118,6 +122,7 @@ unsigned long __init bootmem_init(void)
{
unsigned long bootmap_size, start_pfn, end_pfn;
unsigned long end_of_phys_memory = 0UL;
+ unsigned long bootmap_pfn;
int i;
/* Limit maximum memory until we implement highmem for sparc */
@@ -160,7 +165,7 @@ unsigned long __init bootmem_init(void)
/* Start with page aligned address of last symbol in kernel
* image.
*/
- start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &end));
+ start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end));
/* Adjust up to the physical address where the kernel begins. */
start_pfn += phys_base;
@@ -168,14 +173,36 @@ unsigned long __init bootmem_init(void)
/* Now shift down to get the real physical page frame number. */
start_pfn >>= PAGE_SHIFT;
+ bootmap_pfn = start_pfn;
+
end_pfn = end_of_phys_memory >> PAGE_SHIFT;
+#ifdef CONFIG_BLK_DEV_INITRD
+ /* Now have to check initial ramdisk, so that bootmap does not overwrite it */
+ if (sparc_ramdisk_image) {
+ if (sparc_ramdisk_image >= (unsigned long)&_end - 2 * PAGE_SIZE)
+ sparc_ramdisk_image -= KERNBASE;
+ initrd_start = sparc_ramdisk_image + phys_base;
+ initrd_end = initrd_start + sparc_ramdisk_size;
+ if (initrd_end > end_of_phys_memory) {
+ printk(KERN_CRIT "initrd extends beyond end of memory "
+ "(0x%016lx > 0x%016lx)\ndisabling initrd\n",
+ initrd_end, end_of_phys_memory);
+ initrd_start = 0;
+ }
+ if (initrd_start) {
+ if (initrd_start >= (start_pfn << PAGE_SHIFT) &&
+ initrd_start < (start_pfn << PAGE_SHIFT) + 2 * PAGE_SIZE)
+ bootmap_pfn = PAGE_ALIGN (initrd_end) >> PAGE_SHIFT;
+ }
+ }
+#endif
/* Initialize the boot-time allocator. */
#ifdef DEBUG_BOOTMEM
- prom_printf("init_bootmem(spfn[%lx],epfn[%lx])\n",
- start_pfn, end_pfn);
+ prom_printf("init_bootmem(spfn[%lx],bpfn[%lx],epfn[%lx])\n",
+ start_pfn, bootmap_pfn, end_pfn);
#endif
- bootmap_size = init_bootmem(start_pfn, end_pfn);
+ bootmap_size = init_bootmem(bootmap_pfn, end_pfn);
/* Now register the available physical memory with the
* allocator.
@@ -190,15 +217,27 @@ unsigned long __init bootmem_init(void)
sp_banks[i].num_bytes);
}
- /* Reserve the kernel text/data/bss and the bootmem bitmap. */
+ /* Reserve the kernel text/data/bss, the bootmem bitmap and initrd. */
#ifdef DEBUG_BOOTMEM
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start)
+ prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
+ initrd_start, initrd_end - initrd_start);
+#endif
prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
- phys_base,
- (start_pfn << PAGE_SHIFT) +
- bootmap_size + PAGE_SIZE-1 - phys_base);
+ phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
+ prom_printf("reserve_bootmem: base[%lx] size[%lx]\n",
+ (bootmap_pfn << PAGE_SHIFT), bootmap_size);
#endif
- reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) +
- bootmap_size + PAGE_SIZE-1 - phys_base);
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ reserve_bootmem(initrd_start, initrd_end - initrd_start);
+ initrd_start += PAGE_OFFSET;
+ initrd_end += PAGE_OFFSET;
+ }
+#endif
+ reserve_bootmem(phys_base, (start_pfn << PAGE_SHIFT) - phys_base);
+ reserve_bootmem((bootmap_pfn << PAGE_SHIFT), bootmap_size);
#ifdef DEBUG_BOOTMEM
prom_printf("init_bootmem: return end_pfn[%lx]\n", end_pfn);
@@ -371,18 +410,6 @@ void __init mem_init(void)
}
memset(sparc_valid_addr_bitmap, 0, i << 2);
- /* fix this */
-#ifdef CONFIG_BLK_DEV_INITRD
- addr = __va(phys_base);
- last = PAGE_ALIGN((unsigned long)&end) + phys_base;
- while(addr < last) {
- if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end)
- mem_map[MAP_NR(addr)].flags &= ~(1<<PG_reserved);
- else
- addr += PAGE_SIZE;
- }
-#endif
-
taint_real_pages();
max_mapnr = last_valid_pfn;
@@ -446,6 +473,22 @@ void free_initmem (void)
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ if (start < end)
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+ for (; start < end; start += PAGE_SIZE) {
+ struct page *p = mem_map + MAP_NR(start);
+
+ ClearPageReserved(p);
+ set_page_count(p, 1);
+ __free_page(p);
+ num_physpages++;
+ }
+}
+#endif
+
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;