> > -   vm86_intcall(0x12, &vmf);
> > -   basemem = vmf.vmf_ax;
> > +   if ((basemem = rtcin(RTC_BASELO) + (rtcin(RTC_BASEHI)<<8)) > 640)
> > +           basemem = 640;
> > +
> > +   if (basemem == 0) {
> > +           vm86_intcall(0x12, &vmf);
> > +           basemem = vmf.vmf_ax;
> > +   }
> > +
> >     if (basemem > 640) {
> >             printf("Preposterous BIOS basemem of %uK, truncating to 640K\n",
> >                     basemem);
> >
> 
> This would reintroduce a large bug.  The RTC gives the hardware memory
> size, but the interrupt gives the software memory size.  These differ
> for one of two machines under my desk (both have Award BIOSes).  The
> BIOS often steals some of the base memory.  It's hard to tell whether
> this memory will be used after FreeBSD determines the memory size.  It
> might be used for VM86 or (much more magically) for SMM.
> 
> Reading the memory size from BIOS RAM (offset 0x413) would be safer.
> I'm not sure how standard this is.  I thought that it is less standard
> than INT 0x12.

OK, RELENG_3 GENERIC kernel might have problems with base memory, RTC
was used there...

How about this?  It's my original idea.

Thanks

Index: machdep.c
===================================================================
RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v
retrieving revision 1.542
diff -u -r1.542 machdep.c
--- machdep.c   12 Oct 2002 05:32:23 -0000      1.542
+++ machdep.c   22 Oct 2002 03:04:15 -0000
@@ -1281,49 +1281,7 @@
 
        bzero(&vmf, sizeof(struct vm86frame));
        bzero(physmap, sizeof(physmap));
-
-       /*
-        * Perform "base memory" related probes & setup
-        */
-       vm86_intcall(0x12, &vmf);
-       basemem = vmf.vmf_ax;
-       if (basemem > 640) {
-               printf("Preposterous BIOS basemem of %uK, truncating to 640K\n",
-                       basemem);
-               basemem = 640;
-       }
-
-       /*
-        * XXX if biosbasemem is now < 640, there is a `hole'
-        * between the end of base memory and the start of
-        * ISA memory.  The hole may be empty or it may
-        * contain BIOS code or data.  Map it read/write so
-        * that the BIOS can write to it.  (Memory from 0 to
-        * the physical end of the kernel is mapped read-only
-        * to begin with and then parts of it are remapped.
-        * The parts that aren't remapped form holes that
-        * remain read-only and are unused by the kernel.
-        * The base memory area is below the physical end of
-        * the kernel and right now forms a read-only hole.
-        * The part of it from PAGE_SIZE to
-        * (trunc_page(biosbasemem * 1024) - 1) will be
-        * remapped and used by the kernel later.)
-        *
-        * This code is similar to the code used in
-        * pmap_mapdev, but since no memory needs to be
-        * allocated we simply change the mapping.
-        */
-       for (pa = trunc_page(basemem * 1024);
-            pa < ISA_HOLE_START; pa += PAGE_SIZE)
-               pmap_kenter(KERNBASE + pa, pa);
-
-       /*
-        * if basemem != 640, map pages r/w into vm86 page table so 
-        * that the bios can scribble on it.
-        */
-       pte = (pt_entry_t *)vm86paddr;
-       for (i = basemem / 4; i < 160; i++)
-               pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
+       basemem = 0;
 
        /*
         * map page 1 R/W into the kernel page table so we can use it
@@ -1391,6 +1349,60 @@
                physmap[physmap_idx + 1] = smap->base + smap->length;
 next_run: ;
        } while (vmf.vmf_ebx != 0);
+
+       /*
+        * Perform "base memory" related probes & setup
+        */
+       for (i = 0; i <= physmap_idx; i += 2) {
+               if (physmap[i] == 0x00000000) {
+                       basemem = physmap[i + 1] / 1024;
+                       break;
+               }
+       }
+
+       /* Fall back to the old compatibility function for base memory */
+       if (basemem == 0) {
+               vm86_intcall(0x12, &vmf);
+               basemem = vmf.vmf_ax;
+       }
+
+       if (basemem > 640) {
+               printf("Preposterous BIOS basemem of %uK, truncating to 640K\n",
+                       basemem);
+               basemem = 640;
+       }
+
+       /*
+        * XXX if biosbasemem is now < 640, there is a `hole'
+        * between the end of base memory and the start of
+        * ISA memory.  The hole may be empty or it may
+        * contain BIOS code or data.  Map it read/write so
+        * that the BIOS can write to it.  (Memory from 0 to
+        * the physical end of the kernel is mapped read-only
+        * to begin with and then parts of it are remapped.
+        * The parts that aren't remapped form holes that
+        * remain read-only and are unused by the kernel.
+        * The base memory area is below the physical end of
+        * the kernel and right now forms a read-only hole.
+        * The part of it from PAGE_SIZE to
+        * (trunc_page(biosbasemem * 1024) - 1) will be
+        * remapped and used by the kernel later.)
+        *
+        * This code is similar to the code used in
+        * pmap_mapdev, but since no memory needs to be
+        * allocated we simply change the mapping.
+        */
+       for (pa = trunc_page(basemem * 1024);
+            pa < ISA_HOLE_START; pa += PAGE_SIZE)
+               pmap_kenter(KERNBASE + pa, pa);
+
+       /*
+        * if basemem != 640, map pages r/w into vm86 page table so
+        * that the bios can scribble on it.
+        */
+       pte = (pt_entry_t *)vm86paddr;
+       for (i = basemem / 4; i < 160; i++)
+               pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
 
        if (physmap[1] != 0)
                goto physmap_done;

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message

Reply via email to