Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 26 Aug 2009 16:10:37 -0500
From:      "James R. Van Artsdalen" <james-freebsd-current@jrv.org>
To:        FreeBSD Current <freebsd-current@freebsd.org>
Subject:   [patch] FreeBSD/amd64 can't see all system memory
Message-ID:  <4A95A4CD.1020600@jrv.org>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------010108050102020003040005
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

This fixes two bugs on amd64 only:

1. FreeBSD erroneously assumes that the BIOS E820 system memory map data
is non-descending.  The Zotac GF9300-D-E is an example of a system where
this is not true.

2. There is a typo in code that detects overlaps in regions reported by
E820.  No action is in fact taken right now on amd64.

i386 may have bug #1 but not #2.

With this patch "available memory" goes from 2689 MB to 7605 MB on the
Zotac GF9300-D-E.



--------------010108050102020003040005
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
 name="smap.pat"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="smap.pat"

Index: sys/amd64/amd64/machdep.c
===================================================================
--- sys/amd64/amd64/machdep.c	(revision 196500)
+++ sys/amd64/amd64/machdep.c	(working copy)
@@ -1236,6 +1236,19 @@
 	smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
 
 	for (smap = smapbase; smap < smapend; smap++) {
+		struct bios_smap *sp, *low = smap;
+
+		for (sp = smap + 1; sp < smapend; sp++)
+			if (low->base > sp->base)
+				low = sp;
+		if (low != smap) {
+			struct bios_smap ts;
+
+			ts = *smap;
+			*smap = *low;
+			*low = ts;
+		}
+
 		if (boothowto & RB_VERBOSE)
 			printf("SMAP type=%02x base=%016lx len=%016lx\n",
 			    smap->type, smap->base, smap->length);
@@ -1250,10 +1263,12 @@
 			if (smap->base < physmap[i + 1]) {
 				if (boothowto & RB_VERBOSE)
 					printf(
-	"Overlapping or non-monotonic memory region, ignoring second region\n");
-				continue;
+	"Overlapping memory region, ignoring second region\n");
+				break;
 			}
 		}
+		if (i <= physmap_idx)
+		  continue;
 
 		if (smap->base == physmap[physmap_idx + 1]) {
 			physmap[physmap_idx + 1] += smap->length;

--------------010108050102020003040005--



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