Subject: port-i386/13399: Bugs in post-1.5 memory probe
To: None <gnats-bugs@gnats.netbsd.org>
From: None <entropy@tappedin.com>
List: netbsd-bugs
Date: 07/07/2001 00:25:03
>Number:         13399
>Category:       port-i386
>Synopsis:       Bugs in post-1.5 memory probe
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jul 06 21:23:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        <NetBSD-current source date>20010706
>Organization:
entropy -- it's not just a good idea, it's the second law.
>Environment:
	
System: NetBSD tardis.local 1.5W NetBSD 1.5W (TARDIS) #8: Sat Jul 7 00:04:13 EDT 2001 entropy@zippy.local:/usr/src/sys/arch/i386/compile/TARDIS i386
Architecture: i386
Machine: i386
>Description:
	

When booting post-1.5 kernels on an old machine, I got crashes immediately
after startup.  The following warnings were printed:

>How-To-Repeat:
	

Try to boot -current on a DECpc XL 590.

>Fix:
	

The following patch fixes several bugs in the post-1.5 BIOS memory probes.

- If the BIOS reports the same memory cluster multiple times, only allocate
  the extent once.

- If we fail to allocate an extent, don't add it to mem_clusters and don't
  increment mem_cluster_cnt.

- When loading the physical extents, make sure we don't try to add an
  extent with zero length (seg_start == tmp)


Index: machdep.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/machdep.c,v
retrieving revision 1.446
diff -u -u -r1.446 machdep.c
--- machdep.c	2001/06/19 15:54:48	1.446
+++ machdep.c	2001/07/07 04:03:48
@@ -2144,6 +2144,7 @@
 	u_int32_t type;
 {
 	extern struct extent *iomem_ex;
+	int i;
 
 	if (seg_end > 0x100000000ULL) {
 		printf("WARNING: skipping large "
@@ -2165,6 +2166,17 @@
 	if (seg_end <= seg_start)
 		return;
 
+	for (i = 0; i < mem_cluster_cnt; i++) {
+		if ((mem_clusters[i].start == round_page(seg_start))
+		    && (mem_clusters[i].size
+			    == trunc_page(seg_end) - mem_clusters[i].start)) {
+#ifdef DEBUG_MEMLOAD
+			printf("WARNING: skipping duplicate segment entry\n");
+#endif
+			return;
+		}
+	}
+
 	/*
 	 * Allocate the physical addresses used by RAM
 	 * from the iomem extent map.  This is done before
@@ -2179,6 +2191,7 @@
 		    "(0x%qx/0x%qx/0x%x) FROM "
 		    "IOMEM EXTENT MAP!\n",
 		    seg_start, seg_end - seg_start, type);
+		return;
 	}
 
 	/*
@@ -2331,6 +2344,10 @@
 	}
 #endif /* ! REALBASEMEM && ! REALEXTMEM */
 
+#ifdef DEBUG_MEMLOAD
+	printf("mem_cluster_count: %d\n", mem_cluster_cnt);
+#endif
+
 	/*
 	 * If the loop above didn't find any valid segment, fall back to
 	 * former code.
@@ -2449,14 +2466,17 @@
 					tmp = (16 * 1024 * 1024);
 				else
 					tmp = seg_end;
+
+				if (tmp != seg_start) {
 #if DEBUG_MEMLOAD
-				printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
+				  printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
 				    seg_start, tmp,
 				    atop(seg_start), atop(tmp));
 #endif
-				uvm_page_physload(atop(seg_start),
+				  uvm_page_physload(atop(seg_start),
 				    atop(tmp), atop(seg_start),
 				    atop(tmp), first16q);
+				}
 				seg_start = tmp;
 			}
 
@@ -2482,14 +2502,16 @@
 					tmp = (16 * 1024 * 1024);
 				else
 					tmp = seg_end1;
+				if (tmp != seg_start1) {
 #if DEBUG_MEMLOAD
-				printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
+				  printf("loading 0x%qx-0x%qx (0x%lx-0x%lx)\n",
 				    seg_start1, tmp,
 				    atop(seg_start1), atop(tmp));
 #endif
-				uvm_page_physload(atop(seg_start1),
+				  uvm_page_physload(atop(seg_start1),
 				    atop(tmp), atop(seg_start1),
 				    atop(tmp), first16q);
+				}
 				seg_start1 = tmp;
 			}
 
>Release-Note:
>Audit-Trail:
>Unformatted:
 >> NetBSD/i386 BIOS Boot, Revision 2.10
 >> (entropy@zippy.local, Thu Jul  5 05:13:48 EDT 2001)
 >> Memory: 635/48128 k
 Press return to boot now, any other key for boot menu
 booting fd0a:netbsd - starting in 0
 type "?" or "help" for help.
 > boot hd0a:netbsd -s
 booting hd0a:netbsd (howto 0x2)
 4532951+83004+324460 [65+263168+216671]=0x52c6f0
 WARNING: CAN'T ALLOCATE MEMORY SEGMENT (0x100000/0xf00000/0x1) FROM IOMEM EXTENT MAP!
 WARNING: CAN'T ALLOCATE MEMORY SEGMENT (0x1000000/0x2000000/0x1) FROM IOMEM EXTENT MAP!
 (At this point the system resets immediately).
 
 The machine is a DECpc XL 590 with 48M memory.