patch-2.3.99-pre2 linux/arch/sparc/mm/init.c

Next file: linux/arch/sparc64/config.in
Previous file: linux/arch/sparc/lib/muldi3.S
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.99-pre1/linux/arch/sparc/mm/init.c linux/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 @@
 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 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 @@
 	/* 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 @@
 	/* 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 @@
 			     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 @@
 	}
 	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;
@@ -445,6 +472,22 @@
 	}
 	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)
 {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)