[ros-diffs] [tkreuzer] 53796: [FREELDR] Patch by Brian Palmer: Properly handle a memory hole below 16MB, which some machines have.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Wed Sep 21 21:48:45 UTC 2011


Author: tkreuzer
Date: Wed Sep 21 21:48:44 2011
New Revision: 53796

URL: http://svn.reactos.org/svn/reactos?rev=53796&view=rev
Log:
[FREELDR]
Patch by Brian Palmer:
Properly handle a memory hole below 16MB, which some machines have.

Modified:
    trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c?rev=53796&r1=53795&r2=53796&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/pcmem.c [iso-8859-1] Wed Sep 21 21:48:44 2011
@@ -27,95 +27,100 @@
 
 DBG_DEFAULT_CHANNEL(MEMORY);
 
-static ULONG
-PcMemGetExtendedMemorySize(VOID)
-{
-  REGS RegsIn;
-  REGS RegsOut;
-  ULONG MemorySize;
-
-  TRACE("GetExtendedMemorySize()\n");
-
-  /* Int 15h AX=E801h
-   * Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
-   *
-   * AX = E801h
-   * Return:
-   * CF clear if successful
-   * AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
-   * BX = extended memory above 16M, in 64K blocks
-   * CX = configured memory 1M to 16M, in K
-   * DX = configured memory above 16M, in 64K blocks
-   * CF set on error
-   */
-  RegsIn.w.ax = 0xE801;
-  Int386(0x15, &RegsIn, &RegsOut);
-
-  TRACE("Int15h AX=E801h\n");
-  TRACE("AX = 0x%x\n", RegsOut.w.ax);
-  TRACE("BX = 0x%x\n", RegsOut.w.bx);
-  TRACE("CX = 0x%x\n", RegsOut.w.cx);
-  TRACE("DX = 0x%x\n", RegsOut.w.dx);
-  TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
-
-  if (INT386_SUCCESS(RegsOut))
-    {
-      /* If AX=BX=0000h the use CX and DX */
-      if (RegsOut.w.ax == 0)
-        {
-          /* Return extended memory size in K */
-          MemorySize = RegsOut.w.dx * 64;
-          MemorySize += RegsOut.w.cx;
-          return MemorySize;
-        }
-      else
-        {
-          /* Return extended memory size in K */
-          MemorySize = RegsOut.w.bx * 64;
-          MemorySize += RegsOut.w.ax;
-          return MemorySize;
-        }
-    }
-
-  /* If we get here then Int15 Func E801h didn't work */
-  /* So try Int15 Func 88h */
-
-  /* Int 15h AH=88h
-   * SYSTEM - GET EXTENDED MEMORY SIZE (286+)
-   *
-   * AH = 88h
-   * Return:
-   * CF clear if successful
-   * AX = number of contiguous KB starting at absolute address 100000h
-   * CF set on error
-   * AH = status
-   * 80h invalid command (PC,PCjr)
-   * 86h unsupported function (XT,PS30)
-   */
-  RegsIn.b.ah = 0x88;
-  Int386(0x15, &RegsIn, &RegsOut);
-
-  TRACE("Int15h AH=88h\n");
-  TRACE("AX = 0x%x\n", RegsOut.w.ax);
-  TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
-
-  if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
-    {
-      MemorySize = RegsOut.w.ax;
-      return MemorySize;
-    }
-
-  /* If we get here then Int15 Func 88h didn't work */
-  /* So try reading the CMOS */
-  WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
-  MemorySize = READ_PORT_UCHAR((PUCHAR)0x71);
-  MemorySize = (MemorySize & 0xFFFF);
-  MemorySize = (MemorySize << 8);
-
-  TRACE("Int15h Failed\n");
-  TRACE("CMOS reports: 0x%x\n", MemorySize);
-
-  return MemorySize;
+static
+BOOLEAN
+GetExtendedMemoryConfiguration(ULONG* pMemoryAtOneMB /* in KB */, ULONG* pMemoryAtSixteenMB /* in 64KB */)
+{
+    REGS     RegsIn;
+    REGS     RegsOut;
+
+    TRACE("GetExtendedMemoryConfiguration()\n");
+
+    *pMemoryAtOneMB = 0;
+    *pMemoryAtSixteenMB = 0;
+
+    // Int 15h AX=E801h
+    // Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS
+    //
+    // AX = E801h
+    // Return:
+    // CF clear if successful
+    // AX = extended memory between 1M and 16M, in K (max 3C00h = 15MB)
+    // BX = extended memory above 16M, in 64K blocks
+    // CX = configured memory 1M to 16M, in K
+    // DX = configured memory above 16M, in 64K blocks
+    // CF set on error
+    RegsIn.w.ax = 0xE801;
+    Int386(0x15, &RegsIn, &RegsOut);
+
+    TRACE("Int15h AX=E801h\n");
+    TRACE("AX = 0x%x\n", RegsOut.w.ax);
+    TRACE("BX = 0x%x\n", RegsOut.w.bx);
+    TRACE("CX = 0x%x\n", RegsOut.w.cx);
+    TRACE("DX = 0x%x\n", RegsOut.w.dx);
+    TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
+
+    if (INT386_SUCCESS(RegsOut))
+    {
+        // If AX=BX=0000h the use CX and DX
+        if (RegsOut.w.ax == 0)
+        {
+            // Return extended memory size in K
+            *pMemoryAtSixteenMB = RegsOut.w.dx;
+            *pMemoryAtOneMB = RegsOut.w.cx;
+            return TRUE;
+        }
+        else
+        {
+            // Return extended memory size in K
+            *pMemoryAtSixteenMB = RegsOut.w.bx;
+            *pMemoryAtOneMB = RegsOut.w.ax;
+            return TRUE;
+        }
+    }
+
+    // If we get here then Int15 Func E801h didn't work
+    // So try Int15 Func 88h
+    // Int 15h AH=88h
+    // SYSTEM - GET EXTENDED MEMORY SIZE (286+)
+    //
+    // AH = 88h
+    // Return:
+    // CF clear if successful
+    // AX = number of contiguous KB starting at absolute address 100000h
+    // CF set on error
+    // AH = status
+    // 80h invalid command (PC,PCjr)
+    // 86h unsupported function (XT,PS30)
+    RegsIn.b.ah = 0x88;
+    Int386(0x15, &RegsIn, &RegsOut);
+
+    TRACE("Int15h AH=88h\n");
+    TRACE("AX = 0x%x\n", RegsOut.w.ax);
+    TRACE("CF set = %s\n\n", (RegsOut.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");
+
+    if (INT386_SUCCESS(RegsOut) && RegsOut.w.ax != 0)
+    {
+        *pMemoryAtOneMB = RegsOut.w.ax;
+        return TRUE;
+    }
+
+    // If we get here then Int15 Func 88h didn't work
+    // So try reading the CMOS
+    WRITE_PORT_UCHAR((PUCHAR)0x70, 0x31);
+    *pMemoryAtOneMB = READ_PORT_UCHAR((PUCHAR)0x71);
+    *pMemoryAtOneMB = (*pMemoryAtOneMB & 0xFFFF);
+    *pMemoryAtOneMB = (*pMemoryAtOneMB << 8);
+
+    TRACE("Int15h Failed\n");
+    TRACE("CMOS reports: 0x%x\n", *pMemoryAtOneMB);
+
+    if (*pMemoryAtOneMB != 0)
+    {
+        return TRUE;
+    }
+
+    return FALSE;
 }
 
 static ULONG
@@ -228,21 +233,36 @@
 PcMemGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
 {
   ULONG EntryCount;
+  ULONG ExtendedMemorySizeAtOneMB;
+  ULONG ExtendedMemorySizeAtSixteenMB;
 
   EntryCount = PcMemGetBiosMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
 
   /* If the BIOS didn't provide a memory map, synthesize one */
-  if (0 == EntryCount && 2 <= MaxMemoryMapSize)
-    {
-      /* Conventional memory */
-      BiosMemoryMap[0].BaseAddress = 0;
-      BiosMemoryMap[0].Length = PcMemGetConventionalMemorySize() * 1024;
-      BiosMemoryMap[0].Type = BiosMemoryUsable;
-      /* Extended memory */
-      BiosMemoryMap[1].BaseAddress = 1024 * 1024;
-      BiosMemoryMap[1].Length = PcMemGetExtendedMemorySize() * 1024;
-      BiosMemoryMap[1].Type = BiosMemoryUsable;
-      EntryCount = 2;
+  if (0 == EntryCount && 3 <= MaxMemoryMapSize)
+    {
+      GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB, &ExtendedMemorySizeAtSixteenMB);
+
+                                  /* Conventional memory */
+      BiosMemoryMap[EntryCount].BaseAddress = 0;
+      BiosMemoryMap[EntryCount].Length = PcMemGetConventionalMemorySize() * 1024;
+      BiosMemoryMap[EntryCount].Type = BiosMemoryUsable;
+      EntryCount++;
+
+      /* Extended memory at 1MB */
+      BiosMemoryMap[EntryCount].BaseAddress = 1024 * 1024;
+      BiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtOneMB * 1024;
+      BiosMemoryMap[EntryCount].Type = BiosMemoryUsable;
+      EntryCount++;
+
+      if (ExtendedMemorySizeAtSixteenMB != 0)
+      {
+        /* Extended memory at 16MB */
+        BiosMemoryMap[EntryCount].BaseAddress = 0x1000000;
+        BiosMemoryMap[EntryCount].Length = ExtendedMemorySizeAtSixteenMB * 64 * 1024;
+        BiosMemoryMap[EntryCount].Type = BiosMemoryUsable;
+        EntryCount++;
+      }
     }
 
   return EntryCount;




More information about the Ros-diffs mailing list