[FREELDR] Fix memory initialization on Xbox
authorStanislav Motylkov <x86corez@gmail.com>
Mon, 15 Jul 2019 21:36:54 +0000 (00:36 +0300)
committerHermès BÉLUSCA - MAÏTO <hermes.belusca-maito@reactos.org>
Thu, 18 Jul 2019 20:49:51 +0000 (22:49 +0200)
- Refactor and use PC memory map init functions
- This fixes filesystem detection and probably some other problems

Based on a patch by Matt Borgerson.

CORE-16204 CORE-16206

Co-authored-by: Matt Borgerson <contact@mborgerson.com>
boot/freeldr/freeldr/arch/i386/pcmem.c
boot/freeldr/freeldr/arch/i386/xboxmem.c

index 21647d4..2add4d9 100644 (file)
@@ -480,6 +480,7 @@ nextRange:
 
 VOID
 ReserveMemory(
+    PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
     ULONG_PTR BaseAddress,
     SIZE_T Size,
     TYPE_OF_MEMORY MemoryType,
@@ -494,11 +495,11 @@ ReserveMemory(
     for (i = 0; i < PcMapCount; i++)
     {
         /* Check for conflicting descriptor */
-        if ((PcMemoryMap[i].BasePage < BasePage + PageCount) &&
-            (PcMemoryMap[i].BasePage + PcMemoryMap[i].PageCount > BasePage))
+        if ((MemoryMap[i].BasePage < BasePage + PageCount) &&
+            (MemoryMap[i].BasePage + MemoryMap[i].PageCount > BasePage))
         {
             /* Check if the memory is free */
-            if (PcMemoryMap[i].MemoryType != LoaderFree)
+            if (MemoryMap[i].MemoryType != LoaderFree)
             {
                 FrLdrBugCheckWithMessage(
                     MEMORY_INIT_FAILURE,
@@ -513,7 +514,7 @@ ReserveMemory(
     }
 
     /* Add the memory descriptor */
-    PcMapCount = AddMemoryDescriptor(PcMemoryMap,
+    PcMapCount = AddMemoryDescriptor(MemoryMap,
                                      MAX_BIOS_DESCRIPTORS,
                                      BasePage,
                                      PageCount,
@@ -522,6 +523,7 @@ ReserveMemory(
 
 VOID
 SetMemory(
+    PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
     ULONG_PTR BaseAddress,
     SIZE_T Size,
     TYPE_OF_MEMORY MemoryType)
@@ -532,17 +534,67 @@ SetMemory(
     PageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(BaseAddress, Size);
 
     /* Add the memory descriptor */
-    PcMapCount = AddMemoryDescriptor(PcMemoryMap,
+    PcMapCount = AddMemoryDescriptor(MemoryMap,
                                      MAX_BIOS_DESCRIPTORS,
                                      BasePage,
                                      PageCount,
                                      MemoryType);
 }
 
+ULONG
+PcMemFinalizeMemoryMap(
+    PFREELDR_MEMORY_DESCRIPTOR MemoryMap)
+{
+    ULONG i;
+
+    /* Reserve some static ranges for freeldr */
+    ReserveMemory(MemoryMap, 0x1000, STACKLOW - 0x1000, LoaderFirmwareTemporary, "BIOS area");
+    ReserveMemory(MemoryMap, STACKLOW, STACKADDR - STACKLOW, LoaderOsloaderStack, "FreeLdr stack");
+    ReserveMemory(MemoryMap, FREELDR_BASE, FrLdrImageSize, LoaderLoadedProgram, "FreeLdr image");
+
+    /* Default to 1 page above freeldr for the disk read buffer */
+    DiskReadBuffer = (PUCHAR)ALIGN_UP_BY(FREELDR_BASE + FrLdrImageSize, PAGE_SIZE);
+    DiskReadBufferSize = PAGE_SIZE;
+
+    /* Scan for free range above freeldr image */
+    for (i = 0; i < PcMapCount; i++)
+    {
+        if ((MemoryMap[i].BasePage > (FREELDR_BASE / PAGE_SIZE)) &&
+            (MemoryMap[i].MemoryType == LoaderFree))
+        {
+            /* Use this range for the disk read buffer */
+            DiskReadBuffer = (PVOID)(MemoryMap[i].BasePage * PAGE_SIZE);
+            DiskReadBufferSize = min(MemoryMap[i].PageCount * PAGE_SIZE,
+                                     MAX_DISKREADBUFFER_SIZE);
+            break;
+        }
+    }
+
+    TRACE("DiskReadBuffer=0x%p, DiskReadBufferSize=0x%lx\n",
+          DiskReadBuffer, DiskReadBufferSize);
+
+    /* Now reserve the range for the disk read buffer */
+    ReserveMemory(MemoryMap,
+                  (ULONG_PTR)DiskReadBuffer,
+                  DiskReadBufferSize,
+                  LoaderFirmwareTemporary,
+                  "Disk read buffer");
+
+    TRACE("Dumping resulting memory map:\n");
+    for (i = 0; i < PcMapCount; i++)
+    {
+        TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n",
+              MemoryMap[i].BasePage,
+              MemoryMap[i].PageCount,
+              MmGetSystemMemoryMapTypeString(MemoryMap[i].MemoryType));
+    }
+    return PcMapCount;
+}
+
 PFREELDR_MEMORY_DESCRIPTOR
 PcMemGetMemoryMap(ULONG *MemoryMapSize)
 {
-    ULONG i, EntryCount;
+    ULONG EntryCount;
     ULONG ExtendedMemorySizeAtOneMB;
     ULONG ExtendedMemorySizeAtSixteenMB;
     ULONG EbdaBase, EbdaSize;
@@ -596,53 +648,12 @@ PcMemGetMemoryMap(ULONG *MemoryMapSize)
     }
 
     /* Setup some protected ranges */
-    SetMemory(0x000000, 0x01000, LoaderFirmwarePermanent); // Realmode IVT / BDA
-    SetMemory(0x0A0000, 0x50000, LoaderFirmwarePermanent); // Video memory
-    SetMemory(0x0F0000, 0x10000, LoaderSpecialMemory); // ROM
-    SetMemory(0xFFF000, 0x01000, LoaderSpecialMemory); // unusable memory (do we really need this?)
-
-    /* Reserve some static ranges for freeldr */
-    ReserveMemory(0x1000, STACKLOW - 0x1000, LoaderFirmwareTemporary, "BIOS area");
-    ReserveMemory(STACKLOW, STACKADDR - STACKLOW, LoaderOsloaderStack, "FreeLdr stack");
-    ReserveMemory(FREELDR_BASE, FrLdrImageSize, LoaderLoadedProgram, "FreeLdr image");
-
-    /* Default to 1 page above freeldr for the disk read buffer */
-    DiskReadBuffer = (PUCHAR)ALIGN_UP_BY(FREELDR_BASE + FrLdrImageSize, PAGE_SIZE);
-    DiskReadBufferSize = PAGE_SIZE;
-
-    /* Scan for free range above freeldr image */
-    for (i = 0; i < PcMapCount; i++)
-    {
-        if ((PcMemoryMap[i].BasePage > (FREELDR_BASE / PAGE_SIZE)) &&
-            (PcMemoryMap[i].MemoryType == LoaderFree))
-        {
-            /* Use this range for the disk read buffer */
-            DiskReadBuffer = (PVOID)(PcMemoryMap[i].BasePage * PAGE_SIZE);
-            DiskReadBufferSize = min(PcMemoryMap[i].PageCount * PAGE_SIZE,
-                                     MAX_DISKREADBUFFER_SIZE);
-            break;
-        }
-    }
-
-    TRACE("DiskReadBuffer=0x%p, DiskReadBufferSize=0x%lx\n",
-          DiskReadBuffer, DiskReadBufferSize);
-
-    /* Now reserve the range for the disk read buffer */
-    ReserveMemory((ULONG_PTR)DiskReadBuffer,
-                  DiskReadBufferSize,
-                  LoaderFirmwareTemporary,
-                  "Disk read buffer");
-
-    TRACE("Dumping resulting memory map:\n");
-    for (i = 0; i < PcMapCount; i++)
-    {
-        TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n",
-              PcMemoryMap[i].BasePage,
-              PcMemoryMap[i].PageCount,
-              MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType));
-    }
+    SetMemory(PcMemoryMap, 0x000000, 0x01000, LoaderFirmwarePermanent); // Realmode IVT / BDA
+    SetMemory(PcMemoryMap, 0x0A0000, 0x50000, LoaderFirmwarePermanent); // Video memory
+    SetMemory(PcMemoryMap, 0x0F0000, 0x10000, LoaderSpecialMemory); // ROM
+    SetMemory(PcMemoryMap, 0xFFF000, 0x01000, LoaderSpecialMemory); // unusable memory (do we really need this?)
 
-    *MemoryMapSize = PcMapCount;
+    *MemoryMapSize = PcMemFinalizeMemoryMap(PcMemoryMap);
     return PcMemoryMap;
 }
 
index 2e763bb..ee5da0f 100644 (file)
@@ -20,6 +20,9 @@
  */
 
 #include <freeldr.h>
+#include <debug.h>
+
+DBG_DEFAULT_CHANNEL(MEMORY);
 
 static ULONG InstalledMemoryMb = 0;
 static ULONG AvailableMemoryMb = 0;
@@ -28,6 +31,17 @@ static ULONG AvailableMemoryMb = 0;
 #define TEST_PATTERN1 0xAA
 #define TEST_PATTERN2 0x55
 
+extern VOID
+SetMemory(
+    PFREELDR_MEMORY_DESCRIPTOR MemoryMap,
+    ULONG_PTR BaseAddress,
+    SIZE_T Size,
+    TYPE_OF_MEMORY MemoryType);
+
+extern ULONG
+PcMemFinalizeMemoryMap(
+    PFREELDR_MEMORY_DESCRIPTOR MemoryMap);
+
 VOID
 XboxMemInit(VOID)
 {
@@ -71,6 +85,7 @@ XboxMemInit(VOID)
     WRITE_PORT_ULONG((ULONG*) 0xcf8, CONFIG_CMD(0, 0, 0x84));
     WRITE_PORT_ULONG((ULONG*) 0xcfc, InstalledMemoryMb * 1024 * 1024 - 1);
 
+    /* 4 MB video framebuffer is reserved later using XboxMemReserveMemory() */
     AvailableMemoryMb = InstalledMemoryMb;
 }
 
@@ -79,25 +94,31 @@ FREELDR_MEMORY_DESCRIPTOR XboxMemoryMap[2];
 PFREELDR_MEMORY_DESCRIPTOR
 XboxMemGetMemoryMap(ULONG *MemoryMapSize)
 {
+    TRACE("XboxMemGetMemoryMap()\n");
+
     /* Synthesize memory map */
 
     /* Available RAM block */
-    XboxMemoryMap[0].BasePage = 0;
-    XboxMemoryMap[0].PageCount = AvailableMemoryMb * 1024 * 1024 / MM_PAGE_SIZE;
-    XboxMemoryMap[0].MemoryType = LoaderFree;
+    SetMemory(XboxMemoryMap,
+              0,
+              AvailableMemoryMb * 1024 * 1024,
+              LoaderFree);
 
     /* Video memory */
-    XboxMemoryMap[1].BasePage = AvailableMemoryMb * 1024 * 1024 / MM_PAGE_SIZE;
-    XboxMemoryMap[1].PageCount = (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024 / MM_PAGE_SIZE;
-    XboxMemoryMap[1].MemoryType = LoaderFirmwarePermanent;
+    SetMemory(XboxMemoryMap,
+              AvailableMemoryMb * 1024 * 1024,
+              (InstalledMemoryMb - AvailableMemoryMb) * 1024 * 1024,
+              LoaderFirmwarePermanent);
 
-    *MemoryMapSize = 2;
+    *MemoryMapSize = PcMemFinalizeMemoryMap(XboxMemoryMap);
     return XboxMemoryMap;
 }
 
 PVOID
 XboxMemReserveMemory(ULONG MbToReserve)
 {
+    /* This function is used to reserve video framebuffer in XboxVideoInit() */
+
     if (InstalledMemoryMb == 0)
     {
         /* Hmm, seems we're not initialized yet */