Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Dec 2009 20:28:29 +0000 (UTC)
From:      John Baldwin <jhb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r200687 - in stable/7/sys/boot/i386: libi386 loader
Message-ID:  <200912182028.nBIKSTkA007724@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jhb
Date: Fri Dec 18 20:28:28 2009
New Revision: 200687
URL: http://svn.freebsd.org/changeset/base/200687

Log:
  MFC 200216,200219:
  - Various small whitespace and style fixes.
  - Improve the algorithm the loader uses to choose a memory range for its
    heap when using a range above 1MB.

Modified:
  stable/7/sys/boot/i386/libi386/biosmem.c
  stable/7/sys/boot/i386/libi386/libi386.h
  stable/7/sys/boot/i386/loader/main.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/boot/i386/libi386/biosmem.c
==============================================================================
--- stable/7/sys/boot/i386/libi386/biosmem.c	Fri Dec 18 20:28:04 2009	(r200686)
+++ stable/7/sys/boot/i386/libi386/biosmem.c	Fri Dec 18 20:28:28 2009	(r200687)
@@ -35,14 +35,20 @@ __FBSDID("$FreeBSD$");
 #include "libi386.h"
 #include "btxv86.h"
 
-vm_offset_t	memtop, memtop_copyin;
-u_int32_t	bios_basemem, bios_extmem;
+vm_offset_t	memtop, memtop_copyin, high_heap_base;
+uint32_t	bios_basemem, bios_extmem, high_heap_size;
 
 static struct bios_smap smap;
 
+/*
+ * The minimum amount of memory to reserve in bios_extmem for the heap.
+ */
+#define	HEAP_MIN	(3 * 1024 * 1024)
+
 void
 bios_getmem(void)
 {
+    uint64_t size;
 
     /* Parse system memory map */
     v86.ebx = 0;
@@ -65,6 +71,26 @@ bios_getmem(void)
 	if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base == 0x100000)) {
 	    bios_extmem = smap.length;
 	}
+
+	/*
+	 * Look for the largest segment in 'extended' memory beyond
+	 * 1MB but below 4GB.
+	 */
+	if ((smap.type == SMAP_TYPE_MEMORY) && (smap.base > 0x100000) &&
+	    (smap.base < 0x100000000ull)) {
+	    size = smap.length;
+
+	    /*
+	     * If this segment crosses the 4GB boundary, truncate it.
+	     */
+	    if (smap.base + size > 0x100000000ull)
+		size = 0x100000000ull - smap.base;
+
+	    if (size > high_heap_size) {
+		high_heap_size = size;
+		high_heap_base = smap.base;
+	    }
+	}
     } while (v86.ebx != 0);
 
     /* Fall back to the old compatibility function for base memory */
@@ -97,5 +123,13 @@ bios_getmem(void)
     /* Set memtop to actual top of memory */
     memtop = memtop_copyin = 0x100000 + bios_extmem;
 
+    /*
+     * If we have extended memory and did not find a suitable heap
+     * region in the SMAP, use the last 3MB of 'extended' memory as a
+     * high heap candidate.
+     */
+    if (bios_extmem >= HEAP_MIN && high_heap_size < HEAP_MIN) {
+	high_heap_size = HEAP_MIN;
+	high_heap_base = memtop - HEAP_MIN;
+    }
 }    
-

Modified: stable/7/sys/boot/i386/libi386/libi386.h
==============================================================================
--- stable/7/sys/boot/i386/libi386/libi386.h	Fri Dec 18 20:28:04 2009	(r200686)
+++ stable/7/sys/boot/i386/libi386/libi386.h	Fri Dec 18 20:28:28 2009	(r200687)
@@ -78,9 +78,9 @@ int	bc_add(int biosdev);		/* Register CD
 int	bc_getdev(struct i386_devdesc *dev);	/* return dev_t for (dev) */
 int	bc_bios2unit(int biosdev);	/* xlate BIOS device -> bioscd unit */
 int	bc_unit2bios(int unit);		/* xlate bioscd unit -> BIOS device */
-u_int32_t	bd_getbigeom(int bunit);	/* return geometry in bootinfo format */
-int	bd_bios2unit(int biosdev);		/* xlate BIOS device -> biosdisk unit */
-int	bd_unit2bios(int unit);			/* xlate biosdisk unit -> BIOS device */
+uint32_t bd_getbigeom(int bunit);	/* return geometry in bootinfo format */
+int	bd_bios2unit(int biosdev);	/* xlate BIOS device -> biosdisk unit */
+int	bd_unit2bios(int unit);		/* xlate biosdisk unit -> BIOS device */
 int	bd_getdev(struct i386_devdesc *dev);	/* return dev_t for (dev) */
 
 ssize_t	i386_copyin(const void *src, vm_offset_t dest, const size_t len);
@@ -92,12 +92,15 @@ void	bios_addsmapdata(struct preloaded_f
 void	bios_getsmap(void);
 
 void	bios_getmem(void);
-extern u_int32_t	bios_basemem;				/* base memory in bytes */
-extern u_int32_t	bios_extmem;				/* extended memory in bytes */
+extern uint32_t		bios_basemem;	/* base memory in bytes */
+extern uint32_t		bios_extmem;	/* extended memory in bytes */
 extern vm_offset_t	memtop;		/* last address of physical memory + 1 */
 extern vm_offset_t	memtop_copyin;	/* memtop less heap size for the cases */
-					/*  when heap is at the top of extended memory */
-					/*  for other cases - just the same as memtop */
+					/*  when heap is at the top of         */
+					/*  extended memory; for other cases   */
+					/*  just the same as memtop            */
+extern uint32_t		high_heap_size;	/* extended memory region available */
+extern vm_offset_t	high_heap_base;	/* for use as the heap */
 
 int biospci_find_devclass(uint32_t class, int index, uint32_t *locator);
 int biospci_write_config(uint32_t locator, int offset, int width, uint32_t val);

Modified: stable/7/sys/boot/i386/loader/main.c
==============================================================================
--- stable/7/sys/boot/i386/loader/main.c	Fri Dec 18 20:28:04 2009	(r200686)
+++ stable/7/sys/boot/i386/loader/main.c	Fri Dec 18 20:28:28 2009	(r200687)
@@ -102,14 +102,19 @@ main(void)
      */
     bios_getmem();
 
-#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
-    heap_top = PTOV(memtop_copyin);
-    memtop_copyin -= 0x300000;
-    heap_bottom = PTOV(memtop_copyin);
-#else
-    heap_top = (void *)bios_basemem;
-    heap_bottom = (void *)end;
+#if defined(LOADER_BZIP2_SUPPORT) || defined(LOADER_FIREWIRE_SUPPORT) || \
+    defined(LOADER_GPT_SUPPORT) || defined(LOADER_ZFS_SUPPORT)
+    if (high_heap_size > 0) {
+	heap_top = PTOV(high_heap_base + high_heap_size);
+	heap_bottom = PTOV(high_heap_base);
+	if (high_heap_base < memtop_copyin)
+	    memtop_copyin = high_heap_base;
+    } else
 #endif
+    {
+	heap_top = (void *)PTOV(bios_basemem);
+	heap_bottom = (void *)end;
+    }
     setheap(heap_bottom, heap_top);
 
     /* 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200912182028.nBIKSTkA007724>