[FREELDR]
[reactos.git] / reactos / boot / freeldr / freeldr / mm / meminit.c
index bb7efae..b9e8877 100644 (file)
@@ -26,250 +26,199 @@ DBG_DEFAULT_CHANNEL(MEMORY);
 #if DBG
 typedef struct
 {
-    MEMORY_TYPE Type;
+    TYPE_OF_MEMORY Type;
     PCSTR TypeString;
 } FREELDR_MEMORY_TYPE, *PFREELDR_MEMORY_TYPE;
 
 FREELDR_MEMORY_TYPE MemoryTypeArray[] =
 {
-    { MemoryMaximum, "Unknown memory" },
-    { MemoryExceptionBlock, "Exception block" },
-    { MemorySystemBlock, "System block" },
-    { MemoryFree, "Free memory" },
-    { MemoryBad, "Bad memory" },
-    { MemoryLoadedProgram, "Loaded program" },
-    { MemoryFirmwareTemporary, "Firmware temporary" },
-    { MemoryFirmwarePermanent, "Firmware permanent" },
-    { MemoryFreeContiguous, "Free contiguous memory" },
-    { MemorySpecialMemory, "Special memory" },
+    { LoaderMaximum, "Unknown memory" },
+    { LoaderFree, "Free memory" },
+    { LoaderBad, "Bad memory" },
+    { LoaderLoadedProgram, "LoadedProgram" },
+    { LoaderFirmwareTemporary, "FirmwareTemporary" },
+    { LoaderFirmwarePermanent, "FirmwarePermanent" },
+    { LoaderOsloaderHeap, "OsloaderHeap" },
+    { LoaderOsloaderStack, "OsloaderStack" },
+    { LoaderSystemCode, "SystemCode" },
+    { LoaderHalCode, "HalCode" },
+    { LoaderBootDriver, "BootDriver" },
+    { LoaderRegistryData, "RegistryData" },
+    { LoaderMemoryData, "MemoryData" },
+    { LoaderNlsData, "NlsData" },
+    { LoaderSpecialMemory, "SpecialMemory" },
+    { LoaderReserve, "Reserve" },
 };
 ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
 #endif
 
 PVOID  PageLookupTableAddress = NULL;
-ULONG          TotalPagesInLookupTable = 0;
-ULONG          FreePagesInLookupTable = 0;
-ULONG          LastFreePageHint = 0;
-ULONG MmLowestPhysicalPage = 0xFFFFFFFF;
-ULONG MmHighestPhysicalPage = 0;
+PFN_NUMBER TotalPagesInLookupTable = 0;
+PFN_NUMBER FreePagesInLookupTable = 0;
+PFN_NUMBER LastFreePageHint = 0;
+PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF;
+PFN_NUMBER MmHighestPhysicalPage = 0;
+
+PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
+ULONG BiosMemoryMapEntryCount;
 
 extern ULONG_PTR       MmHeapPointer;
 extern ULONG_PTR       MmHeapStart;
 
-typedef struct
-{
-    MEMORY_DESCRIPTOR m;
-    ULONG Index;
-    BOOLEAN GeneratedDescriptor;
-} MEMORY_DESCRIPTOR_INT;
-static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] =
+ULONG
+AddMemoryDescriptor(
+    IN OUT PFREELDR_MEMORY_DESCRIPTOR List,
+    IN ULONG MaxCount,
+    IN PFN_NUMBER BasePage,
+    IN PFN_NUMBER PageCount,
+    IN TYPE_OF_MEMORY MemoryType)
 {
-#if defined (__i386__) || defined (_M_AMD64)
-    { { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors
-    { { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline
-    { { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
-    { { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER
-    { { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER
-    { { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER
-    { { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video
-    { { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory
-#elif __arm__ // This needs to be done per-platform specific way
+    ULONG i, c;
+    PFN_NUMBER NextBase;
+    TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
+          BasePage, BasePage + PageCount, PageCount);
 
-#endif
-};
+    /* Scan through all existing descriptors */
+    for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++)
+    {
+        /* Count entries completely below the new range */
+        if (List[i].BasePage + List[i].PageCount <= BasePage) i++;
+    }
 
-static
-VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount)
-{
-       int             Index;
-       int             Index2;
-       ULONGLONG BaseAddressOffset;
+    /* Check if the list is full */
+    if (c >= MaxCount) return c;
 
-       // Loop through each entry in the array
-       for (Index=0; Index<*MapCount; Index++)
-       {
-               // Correct all the addresses to be aligned on page boundaries
-               BaseAddressOffset = ROUND_UP(BiosMemoryMap[Index].BaseAddress, MM_PAGE_SIZE) - BiosMemoryMap[Index].BaseAddress;
-               BiosMemoryMap[Index].BaseAddress += BaseAddressOffset;
-               if (BiosMemoryMap[Index].Length < BaseAddressOffset)
-               {
-                       BiosMemoryMap[Index].Length = 0;
-               }
-               else
-               {
-                       BiosMemoryMap[Index].Length -= BaseAddressOffset;
-               }
-               BiosMemoryMap[Index].Length = ROUND_DOWN(BiosMemoryMap[Index].Length, MM_PAGE_SIZE);
-
-               // If the entry type isn't usable then remove
-               // it from the memory map (this will help reduce
-               // the size of our lookup table)
-               // If the length is less than a full page then
-               // get rid of it also.
-               if (BiosMemoryMap[Index].Type != BiosMemoryUsable ||
-                       BiosMemoryMap[Index].Length < MM_PAGE_SIZE)
-               {
-                       // Slide every entry after this down one
-                       for (Index2=Index; Index2<(*MapCount - 1); Index2++)
-                       {
-                               BiosMemoryMap[Index2] = BiosMemoryMap[Index2 + 1];
-                       }
-                       (*MapCount)--;
-                       Index--;
-               }
-       }
-}
+    /* Is there an existing descriptor starting before the new range */
+    while ((i < c) && (List[i].BasePage <= BasePage))
+    {
+        /* The end of the existing one is the minimum for the new range */
+        NextBase = List[i].BasePage + List[i].PageCount;
 
-const MEMORY_DESCRIPTOR*
-ArcGetMemoryDescriptor(const MEMORY_DESCRIPTOR* Current)
-{
-    MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
-    PBIOS_MEMORY_MAP BiosMemoryMap;
-    static ULONG BiosMemoryMapEntryCount;
-    static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
-    static BOOLEAN MemoryMapInitialized = FALSE;
-    ULONG i, j;
+        /* Bail out, if everything is trimmed away */
+        if ((BasePage + PageCount) <= NextBase) return c;
 
-    //
-    // Check if it is the first time we're called
-    //
-    if (!MemoryMapInitialized)
+        /* Trim the naew range at the lower end */
+        PageCount -= (NextBase - BasePage);
+        BasePage = NextBase;
+
+        /* Go to the next entry and repeat */
+        i++;
+    }
+
+    ASSERT(PageCount > 0);
+
+    /* Are there still entries above? */
+    if (i < c)
     {
-        //
-        // Get the machine generated memory map
-        //
-        BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);
+        /* Shift the following entries one up */
+        RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0]));
 
-        //
-        // Fix entries that are not page aligned
-        //
-        MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
+        /* Insert the new range */
+        List[i].BasePage = BasePage;
+        List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage);
+        List[i].MemoryType = MemoryType;
+        c++;
 
-        //
-        // Copy the entries to our structure
-        //
-        for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
-        {
-            //
-            // Is it suitable memory?
-            //
-            if (BiosMemoryMap[i].Type != BiosMemoryUsable)
-            {
-                //
-                // No. Process next descriptor
-                //
-                continue;
-            }
+        TRACE("Inserting at i=%ld: (0x%lx:0x%lx)\n",
+              i, List[i].BasePage, List[i].PageCount);
 
-            //
-            // Copy this memory descriptor
-            //
-            BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
-            BiosMemoryDescriptors[j].m.BasePage = (ULONG)(BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE);
-            BiosMemoryDescriptors[j].m.PageCount = (ULONG)(BiosMemoryMap[i].Length / MM_PAGE_SIZE);
-            BiosMemoryDescriptors[j].Index = j;
-            BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
-            j++;
+        /* Check if the range was trimmed */
+        if (PageCount > List[i].PageCount)
+        {
+            /* Recursively process the trimmed part */
+            c = AddMemoryDescriptor(List,
+                                    MaxCount,
+                                    BasePage + List[i].PageCount,
+                                    PageCount - List[i].PageCount,
+                                    MemoryType);
         }
+    }
+    else
+    {
+        /* We can simply add the range here */
+        TRACE("Adding i=%ld: (0x%lx:0x%lx)\n", i, BasePage, PageCount);
+        List[i].BasePage = BasePage;
+        List[i].PageCount = PageCount;
+        List[i].MemoryType = MemoryType;
+        c++;
+    }
 
-        //
-        // Remember how much descriptors we found
-        //
-        BiosMemoryMapEntryCount = j;
+    /* Return the new count */
+    return c;
+}
 
-        //
-        // Mark memory map as already retrieved and initialized
-        //
-        MemoryMapInitialized = TRUE;
+const FREELDR_MEMORY_DESCRIPTOR*
+ArcGetMemoryDescriptor(const FREELDR_MEMORY_DESCRIPTOR* Current)
+{
+    if (Current == NULL)
+    {
+        return BiosMemoryMap;
     }
+    else
+    {
+        Current++;
+        if (Current->PageCount == 0) return NULL;
+        return Current;
+    }
+}
 
-    CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
 
-    if (Current == NULL)
+BOOLEAN
+MmCheckFreeldrImageFile()
+{
+    PIMAGE_NT_HEADERS NtHeaders;
+    PIMAGE_FILE_HEADER FileHeader;
+    PIMAGE_OPTIONAL_HEADER OptionalHeader;
+
+    /* Get the NT headers */
+    NtHeaders = RtlImageNtHeader(&__ImageBase);
+    if (!NtHeaders)
     {
-        //
-        // First descriptor requested
-        //
-        if (BiosMemoryMapEntryCount > 0)
-        {
-            //
-            // Return first generated memory descriptor
-            //
-            return &BiosMemoryDescriptors[0].m;
-        }
-        else if (sizeof(MemoryDescriptors) > 0)
-        {
-            //
-            // Return first fixed memory descriptor
-            //
-            return &MemoryDescriptors[0].m;
-        }
-        else
-        {
-            //
-            // Strange case, we have no memory descriptor
-            //
-            return NULL;
-        }
+        ERR("Coult not get NtHeaders!\n");
+        return FALSE;
     }
-    else if (CurrentDescriptor->GeneratedDescriptor)
+
+    /* Check the file header */
+    FileHeader = &NtHeaders->FileHeader;
+    if ((FileHeader->Machine != IMAGE_FILE_MACHINE_NATIVE) ||
+        (FileHeader->NumberOfSections != FREELDR_SECTION_COUNT) ||
+        (FileHeader->PointerToSymbolTable != 0) ||
+        (FileHeader->NumberOfSymbols != 0) ||
+        (FileHeader->SizeOfOptionalHeader != 0xE0))
     {
-        //
-        // Current entry is a generated descriptor
-        //
-        if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
-        {
-            //
-            // Return next generated descriptor
-            //
-            return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
-        }
-        else if (sizeof(MemoryDescriptors) > 0)
-        {
-            //
-            // Return first fixed memory descriptor
-            //
-            return &MemoryDescriptors[0].m;
-        }
-        else
-        {
-            //
-            // No fixed memory descriptor; end of memory map
-            //
-            return NULL;
-        }
+        return FALSE;
     }
-    else
+
+    /* Check the optional header */
+    OptionalHeader = &NtHeaders->OptionalHeader;
+    if ((OptionalHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) ||
+        (OptionalHeader->Subsystem != 1) || // native
+        (OptionalHeader->ImageBase != FREELDR_PE_BASE) ||
+        (OptionalHeader->SizeOfImage > MAX_FREELDR_PE_SIZE) ||
+        (OptionalHeader->SectionAlignment != OptionalHeader->FileAlignment))
     {
-        //
-        // Current entry is a fixed descriptor
-        //
-        if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
-        {
-            //
-            // Return next fixed descriptor
-            //
-            return &MemoryDescriptors[CurrentDescriptor->Index + 1].m;
-        }
-        else
-        {
-            //
-            // No more fixed memory descriptor; end of memory map
-            //
-            return NULL;
-        }
+        return FALSE;
     }
-}
 
+    return TRUE;
+}
 
 BOOLEAN MmInitializeMemoryManager(VOID)
 {
 #if DBG
-       const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+       const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
 #endif
 
        TRACE("Initializing Memory Manager.\n");
 
+       /* Check the freeldr binary */
+       if (!MmCheckFreeldrImageFile())
+       {
+               FrLdrBugCheck(FREELDR_IMAGE_CORRUPTION);
+       }
+
+    BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);
+
 #if DBG
        // Dump the system memory map
        TRACE("System Memory Map (Base Address, Length, Type):\n");
@@ -298,18 +247,22 @@ BOOLEAN MmInitializeMemoryManager(VOID)
 
        // Initialize the page lookup table
        MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
+
        MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);
 
-       FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
+       FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress,
+                                                        TotalPagesInLookupTable);
 
        MmInitializeHeap(PageLookupTableAddress);
 
-       TRACE("Memory Manager initialized. %d pages available.\n", FreePagesInLookupTable);
+       TRACE("Memory Manager initialized. 0x%x pages available.\n", FreePagesInLookupTable);
+
+
        return TRUE;
 }
 
 #if DBG
-PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type)
+PCSTR MmGetSystemMemoryMapTypeString(TYPE_OF_MEMORY Type)
 {
        ULONG           Index;
 
@@ -325,15 +278,15 @@ PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type)
 }
 #endif
 
-ULONG MmGetPageNumberFromAddress(PVOID Address)
+PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
 {
        return ((ULONG_PTR)Address) / MM_PAGE_SIZE;
 }
 
-ULONG MmGetAddressablePageCountIncludingHoles(VOID)
+PFN_NUMBER MmGetAddressablePageCountIncludingHoles(VOID)
 {
-    const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
-    ULONG PageCount;
+    const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+    PFN_NUMBER PageCount;
 
     //
     // Go through the whole memory map to get max address
@@ -348,7 +301,8 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
             //
             // Yes, remember it if this is real memory
             //
-            if (MemoryDescriptor->MemoryType == MemoryFree) MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
+            if (MemoryDescriptor->MemoryType == LoaderFree)
+                MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
         }
 
         //
@@ -359,82 +313,44 @@ ULONG MmGetAddressablePageCountIncludingHoles(VOID)
             //
             // Yes, remember it if this is real memory
             //
-            if (MemoryDescriptor->MemoryType == MemoryFree) MmLowestPhysicalPage = MemoryDescriptor->BasePage;
+            MmLowestPhysicalPage = MemoryDescriptor->BasePage;
         }
     }
 
-    TRACE("lo/hi %lx %lxn", MmLowestPhysicalPage, MmHighestPhysicalPage);
+    TRACE("lo/hi %lx %lx\n", MmLowestPhysicalPage, MmHighestPhysicalPage);
     PageCount = MmHighestPhysicalPage - MmLowestPhysicalPage;
     TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);
     return PageCount;
 }
 
-PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount)
+PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
 {
-    const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
-    ULONG PageLookupTableSize;
-    ULONG PageLookupTablePages;
-    ULONG PageLookupTableStartPage = 0;
+    const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+    SIZE_T PageLookupTableSize;
+    PFN_NUMBER PageLookupTablePages;
+    PFN_NUMBER PageLookupTableStartPage = 0;
     PVOID PageLookupTableMemAddress = NULL;
 
-    //
     // Calculate how much pages we need to keep the page lookup table
-    //
     PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
     PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE;
 
-    //
     // Search the highest memory block big enough to contain lookup table
-    //
     while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
     {
-        //
-        // Is it suitable memory?
-        //
-        if (MemoryDescriptor->MemoryType != MemoryFree)
-        {
-            //
-            // No. Process next descriptor
-            //
-            continue;
-        }
+        // Continue, if memory is not free
+        if (MemoryDescriptor->MemoryType != LoaderFree) continue;
 
-        //
-        // Is the block big enough?
-        //
-        if (MemoryDescriptor->PageCount < PageLookupTablePages)
-        {
-            //
-            // No. Process next descriptor
-            //
-            continue;
-        }
+        // Continue, if the block is not big enough?
+        if (MemoryDescriptor->PageCount < PageLookupTablePages) continue;
 
-        //
-        // Is it at a higher address than previous suitable address?
-        //
-        if (MemoryDescriptor->BasePage < PageLookupTableStartPage)
-        {
-            //
-            // No. Process next descriptor
-            //
-            continue;
-        }
+        // Continue, if it is not at a higher address than previous address
+        if (MemoryDescriptor->BasePage < PageLookupTableStartPage) continue;
 
-        //
-        // Can we use this address?
-        //
-        if (MemoryDescriptor->BasePage >= MM_MAX_PAGE)
-        {
-            //
-            // No. Process next descriptor
-            //
-            continue;
-        }
+        // Continue, if the address is too high
+        if (MemoryDescriptor->BasePage >= MM_MAX_PAGE) continue;
 
-        //
         // Memory block is more suitable than the previous one
-        //
         PageLookupTableStartPage = MemoryDescriptor->BasePage;
         PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
             (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE
@@ -446,111 +362,71 @@ PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount)
     return PageLookupTableMemAddress;
 }
 
-VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
+VOID MmInitPageLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
 {
-    const MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
-    TYPE_OF_MEMORY MemoryMapPageAllocated;
-    ULONG PageLookupTableStartPage;
-    ULONG PageLookupTablePageCount;
+    const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+    PFN_NUMBER PageLookupTableStartPage;
+    PFN_NUMBER PageLookupTablePageCount;
 
     TRACE("MmInitPageLookupTable()\n");
 
-    //
     // Mark every page as allocated initially
     // We will go through and mark pages again according to the memory map
     // But this will mark any holes not described in the map as allocated
-    //
     MmMarkPagesInLookupTable(PageLookupTable, MmLowestPhysicalPage, TotalPageCount, LoaderFirmwarePermanent);
 
-    //
     // Parse the whole memory map
-    //
     while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
     {
-        //
-        // Convert ARC memory type to loader memory type
-        //
-        switch (MemoryDescriptor->MemoryType)
+        // Mark used pages in the lookup table
+
+        if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount <= TotalPageCount)
         {
-            case MemoryFree:
-            {
-                //
-                // Allocatable memory
-                //
-                MemoryMapPageAllocated = LoaderFree;
-                break;
-            }
-            case MemoryFirmwarePermanent:
-            {
-                //
-                // Firmware permanent memory
-                //
-                MemoryMapPageAllocated = LoaderFirmwarePermanent;
-                break;
-            }
-            case MemoryFirmwareTemporary:
-            {
-                //
-                // Firmware temporary memory
-                //
-                MemoryMapPageAllocated = LoaderFirmwareTemporary;
-                break;
-            }
-            case MemoryLoadedProgram:
-            {
-                //
-                // Bootloader code
-                //
-                MemoryMapPageAllocated = LoaderLoadedProgram;
-                break;
-            }
-            case MemorySpecialMemory:
-            {
-                //
-                // OS Loader Stack
-                //
-                MemoryMapPageAllocated = LoaderOsloaderStack;
-                break;
-            }
-            default:
-            {
-                //
-                // Put something sensible here, which won't be overwritten
-                //
-                MemoryMapPageAllocated = LoaderSpecialMemory;
-                break;
-            }
+            TRACE("Marking pages 0x%lx-0x%lx as type %s\n",
+                  MemoryDescriptor->BasePage,
+                  MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
+                  MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
+            MmMarkPagesInLookupTable(PageLookupTable,
+                                     MemoryDescriptor->BasePage,
+                                     MemoryDescriptor->PageCount,
+                                     MemoryDescriptor->MemoryType);
         }
-
-        //
-        // Mark used pages in the lookup table
-        //
-        TRACE("Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount);
-        MmMarkPagesInLookupTable(PageLookupTable, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount, MemoryMapPageAllocated);
+        else
+            TRACE("Ignoring pages 0x%lx-0x%lx (%s)\n",
+                  MemoryDescriptor->BasePage,
+                  MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
+                  MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
     }
 
-    //
     // Mark the pages that the lookup table occupies as reserved
-    //
     PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
     PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
-    TRACE("Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount);
+    TRACE("Marking the page lookup table pages as reserved StartPage: 0x%x PageCount: 0x%x\n", PageLookupTableStartPage, PageLookupTablePageCount);
     MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
 }
 
-VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated)
+VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY PageAllocated)
 {
-       PPAGE_LOOKUP_TABLE_ITEM         RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
-       ULONG                                                   Index;
+       PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
+       PFN_NUMBER Index;
        TRACE("MmMarkPagesInLookupTable()\n");
 
+    /* Validate the range */
+    if ((StartPage < MmLowestPhysicalPage) ||
+        ((StartPage + PageCount - 1) > MmHighestPhysicalPage))
+    {
+        ERR("Memory (0x%lx:0x%lx) outside of lookup table! Valid range: 0x%lx-0x%lx.\n",
+            StartPage, PageCount, MmLowestPhysicalPage, MmHighestPhysicalPage);
+        return;
+    }
+
     StartPage -= MmLowestPhysicalPage;
        for (Index=StartPage; Index<(StartPage+PageCount); Index++)
        {
 #if 0
                if ((Index <= (StartPage + 16)) || (Index >= (StartPage+PageCount-16)))
                {
-                       TRACE("Index = %d StartPage = %d PageCount = %d\n", Index, StartPage, PageCount);
+                       TRACE("Index = 0x%x StartPage = 0x%x PageCount = 0x%x\n", Index, StartPage, PageCount);
                }
 #endif
                RealPageLookupTable[Index].PageAllocated = PageAllocated;
@@ -559,10 +435,10 @@ VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG Page
        TRACE("MmMarkPagesInLookupTable() Done\n");
 }
 
-VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType)
+VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY MemoryType)
 {
        PPAGE_LOOKUP_TABLE_ITEM         RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
-       ULONG                                                   Index;
+       PFN_NUMBER                                      Index;
 
     StartPage -= MmLowestPhysicalPage;
        for (Index=StartPage; Index<(StartPage+PageCount); Index++)
@@ -572,11 +448,11 @@ VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG
        }
 }
 
-ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
+PFN_NUMBER MmCountFreePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
 {
        PPAGE_LOOKUP_TABLE_ITEM         RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
-       ULONG                                                   Index;
-       ULONG                                                   FreePageCount;
+       PFN_NUMBER                                                      Index;
+       PFN_NUMBER                                                      FreePageCount;
 
        FreePageCount = 0;
        for (Index=0; Index<TotalPageCount; Index++)
@@ -590,11 +466,11 @@ ULONG MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
        return FreePageCount;
 }
 
-ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd)
+PFN_NUMBER MmFindAvailablePages(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, BOOLEAN FromEnd)
 {
-       PPAGE_LOOKUP_TABLE_ITEM         RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
-       ULONG                                                   AvailablePagesSoFar;
-       ULONG                                                   Index;
+       PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
+       PFN_NUMBER AvailablePagesSoFar;
+       PFN_NUMBER Index;
 
        if (LastFreePageHint > TotalPageCount)
        {
@@ -625,7 +501,7 @@ ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG Pa
        }
        else
        {
-               TRACE("Alloc low memory, LastFreePageHint %d, TPC %d\n", LastFreePageHint, TotalPageCount);
+               TRACE("Alloc low memory, LastFreePageHint 0x%x, TPC 0x%x\n", LastFreePageHint, TotalPageCount);
                /* Allocate "low" pages */
                for (Index=1; Index < LastFreePageHint; Index++)
                {
@@ -649,11 +525,11 @@ ULONG MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG Pa
        return 0;
 }
 
-ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage)
+PFN_NUMBER MmFindAvailablePagesBeforePage(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, PFN_NUMBER LastPage)
 {
        PPAGE_LOOKUP_TABLE_ITEM         RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
-       ULONG                                                   AvailablePagesSoFar;
-       ULONG                                                   Index;
+       PFN_NUMBER                                      AvailablePagesSoFar;
+       PFN_NUMBER                                      Index;
 
        if (LastPage > TotalPageCount)
        {
@@ -682,10 +558,10 @@ ULONG MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount
        return 0;
 }
 
-VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
+VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
 {
        PPAGE_LOOKUP_TABLE_ITEM         RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
-       ULONG                                                   Index;
+       PFN_NUMBER                                                      Index;
 
        for (Index=TotalPageCount-1; Index>0; Index--)
        {
@@ -697,13 +573,16 @@ VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
        }
 }
 
-BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount)
+BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PVOID PageAddress, PFN_NUMBER PageCount)
 {
        PPAGE_LOOKUP_TABLE_ITEM         RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
-       ULONG                                                   StartPage;
-       ULONG                                                   Index;
+       PFN_NUMBER                                                      StartPage;
+       PFN_NUMBER                                                      Index;
 
        StartPage = MmGetPageNumberFromAddress(PageAddress);
+
+       if (StartPage < MmLowestPhysicalPage) return FALSE;
+
     StartPage -= MmLowestPhysicalPage;
 
        // Make sure they aren't trying to go past the
@@ -713,7 +592,7 @@ BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, P
                return FALSE;
        }
 
-       for (Index=StartPage; Index<(StartPage + PageCount); Index++)
+       for (Index = StartPage; Index < (StartPage + PageCount); Index++)
        {
                // If this page is allocated then there obviously isn't
                // memory availabe so return FALSE