From 4ea30042a67b7e87bac3588e8acc8038dcb59202 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 6 Sep 2015 06:15:08 +0000 Subject: [PATCH] [BOOTMGFW]: - Cleanup some bugs/issues in the memory map parsing code. - Implement creation of BL/NT-compatible memory descriptors based on UEFI descriptors. - Implement other remaining parts of the page allocator initialization routine. - Last part missing is to implement routines for removing from a memory list, and for handling the boot manager's own descriptor. svn path=/trunk/; revision=69047 --- reactos/boot/environ/app/bootmgr/efiemu.c | 4 +- reactos/boot/environ/include/bl.h | 32 +- .../boot/environ/lib/firmware/efi/firmware.c | 145 ++++++++- reactos/boot/environ/lib/mm/descriptor.c | 274 ++++++++++++++++++ reactos/boot/environ/lib/mm/mm.c | 3 +- reactos/boot/environ/lib/mm/pagealloc.c | 63 +++- 6 files changed, 511 insertions(+), 10 deletions(-) diff --git a/reactos/boot/environ/app/bootmgr/efiemu.c b/reactos/boot/environ/app/bootmgr/efiemu.c index 35f48f8dcf2..1c700dddb8e 100644 --- a/reactos/boot/environ/app/bootmgr/efiemu.c +++ b/reactos/boot/environ/app/bootmgr/efiemu.c @@ -930,10 +930,10 @@ EfiInitCreateInputParametersEx ( EfiInitScratch.MemoryDataOffset; EfiInitScratch.BootMemoryData.DescriptorSize = sizeof(BL_MEMORY_DESCRIPTOR); EfiInitScratch.BootMemoryData.DescriptorCount = 1; - EfiInitScratch.BootMemoryData.Unknown = 8; + EfiInitScratch.BootMemoryData.DescriptorOffset = FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage); /* Build the memory entry descriptor for this image itself */ - EfiInitScratch.MemEntry.Flags = 8; + EfiInitScratch.MemEntry.Flags = BlMemoryWriteBack; EfiInitScratch.MemEntry.Type = BlLoaderMemory; EfiInitScratch.MemEntry.BasePage = EfiInitScratch.ImageBase >> PAGE_SHIFT; EfiInitScratch.MemEntry.PageCount = ALIGN_UP_BY(EfiInitScratch.ImageSize, PAGE_SIZE) >> PAGE_SHIFT; diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index cf5d6244ac0..088d1233568 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -53,12 +53,23 @@ EarlyPrint(_In_ PWCHAR Format, ...); #define BL_CONTEXT_INTERRUPTS_ON 2 #define BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS 0x01 -#define BL_MM_FLAG_UNKNOWN 0x02 +#define BL_MM_FLAG_REQUEST_COALESCING 0x02 + +#define BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG 0x01 +#define BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG 0x02 +#define BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG 0x10 +#define BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG 0x20 +#define BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG 0x2000 + +#define BL_MM_DESCRIPTOR_REQUIRES_COALESCING_FLAG 0x2000000 +#define BL_MM_DESCRIPTOR_REQUIRES_UPDATING_FLAG 0x4000000 #define BL_LIBRARY_FLAG_REINITIALIZE 0x02 #define BL_LIBRARY_FLAG_REINITIALIZE_ALL 0x04 #define BL_LIBRARY_FLAG_INITIALIZATION_COMPLETED 0x20 +#define BL_MEMORY_CLASS_SHIFT 28 + /* ENUMERATIONS **************************************************************/ typedef enum _BL_TRANSLATION_TYPE @@ -222,7 +233,7 @@ typedef struct _BL_MEMORY_DATA ULONG MdListOffset; ULONG DescriptorCount; ULONG DescriptorSize; - ULONG Unknown; + ULONG DescriptorOffset; } BL_MEMORY_DATA, *PBL_MEMORY_DATA; typedef struct _BL_FIRMWARE_DESCRIPTOR @@ -518,10 +529,27 @@ MmMdFreeList( _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList ); +PBL_MEMORY_DESCRIPTOR +MmMdInitByteGranularDescriptor ( + _In_ ULONG Flags, + _In_ BL_MEMORY_TYPE Type, + _In_ ULONGLONG BasePage, + _In_ ULONGLONG VirtualPage, + _In_ ULONGLONG PageCount + ); + +NTSTATUS +MmMdAddDescriptorToList ( + _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, + _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor, + _In_ ULONG Flags + ); + extern ULONG MmDescriptorCallTreeCount; extern ULONG BlpApplicationFlags; extern BL_LIBRARY_PARAMETERS BlpLibraryParameters; extern BL_TRANSLATION_TYPE MmTranslationType; extern PBL_ARCH_CONTEXT CurrentExecutionContext; +extern PBL_DEVICE_DESCRIPTOR BlpBootDevice; #endif diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index f29bee7a8a5..b8758483d5b 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -371,7 +371,7 @@ MmFwGetMemoryMap ( ) { BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters; - BOOLEAN UseEfiBuffer; + BOOLEAN UseEfiBuffer, HaveRamDisk; NTSTATUS Status; ULONGLONG Pages, StartPage, EndPage; UINTN EfiMemoryMapSize, MapKey, DescriptorSize, DescriptorVersion; @@ -381,6 +381,11 @@ MmFwGetMemoryMap ( BL_ARCH_MODE OldMode; EFI_MEMORY_DESCRIPTOR EfiDescriptor; BL_MEMORY_TYPE MemoryType; + PBL_MEMORY_DESCRIPTOR Descriptor; + BL_MEMORY_ATTR Attribute; + + /* Initialize EFI memory map attributes */ + EfiMemoryMapSize = MapKey = DescriptorSize = DescriptorVersion = 0; /* Increment the nesting depth */ MmDescriptorCallTreeCount++; @@ -509,6 +514,21 @@ MmFwGetMemoryMap ( goto Quickie; } + /* Did we boot from a RAM disk? */ + if ((BlpBootDevice->DeviceType == LocalDevice) && + (BlpBootDevice->Local.Type == RamDiskDevice)) + { + /* We don't handle this yet */ + EarlyPrint(L"RAM boot not supported\n"); + Status = STATUS_NOT_IMPLEMENTED; + goto Quickie; + } + else + { + /* We didn't, so there won't be any need to find the memory descriptor */ + HaveRamDisk = FALSE; + } + /* Loop the EFI memory map */ EarlyPrint(L"UEFI MEMORY MAP\n\n"); EarlyPrint(L"TYPE START END ATTRIBUTES\n"); @@ -552,18 +572,137 @@ MmFwGetMemoryMap ( goto LoopAgain; } - EarlyPrint(L"%08X 0x%016I64X-0x%016I64X 0x%X\n", + EarlyPrint(L"%08X 0x%016I64X-0x%016I64X 0x%I64X\n", MemoryType, StartPage << PAGE_SHIFT, EndPage << PAGE_SHIFT, EfiDescriptor.Attribute); - /* Consume this descriptor, and move to the next one */ + /* Check for any range of memory below 1MB */ + if (StartPage < 0x100) + { + /* Does this range actually contain NULL? */ + if (StartPage == 0) + { + /* Manually create a reserved descriptof for this page */ + Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute); + Descriptor = MmMdInitByteGranularDescriptor(Attribute, + BlReservedMemory, + 0, + 0, + 1); + if (!Descriptor) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + /* Add this descriptor into the list */ + Status = MmMdAddDescriptorToList(MemoryMap, + Descriptor, + BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG); + if (!NT_SUCCESS(Status)) + { + EarlyPrint(L"Failed to add zero page descriptor: %lx\n", Status); + break; + } + + /* Now handle the rest of the range, unless this was it */ + StartPage = 1; + if (EndPage == 1) + { + goto LoopAgain; + } + } + + /* Does the range go beyond 1MB? */ + if (EndPage > 0x100) + { + /* Then create the descriptor for everything up until the megabyte */ + Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute); + Descriptor = MmMdInitByteGranularDescriptor(Attribute, + MemoryType, + StartPage, + 0, + 0x100 - StartPage); + if (!Descriptor) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + /* Check if this region is currently free RAM */ + if (Descriptor->Type == BlConventionalMemory) + { + /* Set an unknown flag on the descriptor */ + Descriptor->Flags |= 0x80000; + } + + /* Add this descriptor into the list */ + Status = MmMdAddDescriptorToList(MemoryMap, + Descriptor, + BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG); + if (!NT_SUCCESS(Status)) + { + EarlyPrint(L"Failed to add 1MB descriptor: %lx\n", Status); + break; + } + + /* Now handle the rest of the range above 1MB */ + StartPage = 0x100; + } + } + + /* Check if we loaded from a RAM disk */ + if (HaveRamDisk) + { + /* We don't handle this yet */ + EarlyPrint(L"RAM boot not supported\n"); + Status = STATUS_NOT_IMPLEMENTED; + goto Quickie; + } + + /* Create a descriptor for the current range */ + Attribute = MmFwpGetOsAttributeType(EfiDescriptor.Attribute); + Descriptor = MmMdInitByteGranularDescriptor(Attribute, + MemoryType, + StartPage, + 0, + EndPage - StartPage); + if (!Descriptor) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + break; + } + + /* Check if this region is currently free RAM below 1MB */ + if ((Descriptor->Type == BlConventionalMemory) && (EndPage <= 0x100)) + { + /* Set an unknown flag on the descriptor */ + Descriptor->Flags |= 0x80000; + } + + /* Add the descriptor to the list, requesting coalescing as asked */ + Status = MmMdAddDescriptorToList(MemoryMap, + Descriptor, + BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG | + (Flags & BL_MM_FLAG_REQUEST_COALESCING) ? + BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG : 0); + if (!NT_SUCCESS(Status)) + { + EarlyPrint(L"Failed to add full descriptor: %lx\n", Status); + break; + } + LoopAgain: + /* Consume this descriptor, and move to the next one */ EfiMemoryMapSize -= DescriptorSize; EfiMemoryMap = (PVOID)((ULONG_PTR)EfiMemoryMap + DescriptorSize); } + /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */ + /* For now, just "leak" the 1-2 pages... */ + Quickie: /* Free the EFI buffer, if we had one */ if (EfiBuffer != 0) diff --git a/reactos/boot/environ/lib/mm/descriptor.c b/reactos/boot/environ/lib/mm/descriptor.c index df59102f589..b3d4883cddf 100644 --- a/reactos/boot/environ/lib/mm/descriptor.c +++ b/reactos/boot/environ/lib/mm/descriptor.c @@ -19,8 +19,131 @@ BOOLEAN MmGlobalMemoryDescriptorsUsed; PBL_MEMORY_DESCRIPTOR MmDynamicMemoryDescriptors; ULONG MmDynamicMemoryDescriptorCount; +BL_MEMORY_TYPE MmPlatformMemoryTypePrecedence[] = +{ + BlReservedMemory, + BlUnusableMemory, + BlDeviceIoMemory, + BlDevicePortMemory, + BlPalMemory, + BlEfiRuntimeMemory, + BlAcpiNvsMemory, + BlAcpiReclaimMemory, + BlEfiBootMemory +}; + /* FUNCTIONS *****************************************************************/ +/* The order is Conventional > Other > System > Loader > Application */ +BOOLEAN +MmMdpHasPrecedence ( + _In_ BL_MEMORY_TYPE Type1, + _In_ BL_MEMORY_TYPE Type2 + ) +{ + BL_MEMORY_CLASS Class1, Class2; + ULONG i, j; + + /* Descriptor is free RAM -- it preceeds */ + if (Type1 == BlConventionalMemory) + { + return TRUE; + } + + /* It isn't free RAM, but the comparator is -- it suceeds it */ + if (Type2 == BlConventionalMemory) + { + return FALSE; + } + + /* Descriptor is not system, application, or loader class -- it preceeds */ + Class1 = Type1 >> BL_MEMORY_CLASS_SHIFT; + if ((Class1 != BlSystemClass) && + (Class1 != BlApplicationClass) && + (Class1 != BlLoaderClass)) + { + return TRUE; + } + + /* It isn't one of those classes, but the comparator it -- it suceeds it */ + Class2 = Type2 >> BL_MEMORY_CLASS_SHIFT; + if ((Class2 != BlSystemClass) && + (Class2 != BlApplicationClass) && + (Class2 != BlLoaderClass)) + { + return FALSE; + } + + /* Descriptor is system class */ + if (Class1 == BlSystemClass) + { + /* And so is the other guy... */ + if (Class2 == BlSystemClass) + { + i = 0; + j = 0; + + /* Scan for the descriptor's system precedence index */ + do + { + if (MmPlatformMemoryTypePrecedence[j] == Type1) + { + break; + } + } while (++j < RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence)); + + /* Use an invalid index if one wasn't found */ + if (j == RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence)) + { + j = 0xFFFFFFFF; + } + + /* Now scan for the comparator's system precedence index */ + while (MmPlatformMemoryTypePrecedence[i] != Type2) + { + /* Use an invalid index if one wasn't found */ + if (++i >= RTL_NUMBER_OF(MmPlatformMemoryTypePrecedence)) + { + i = 0xFFFFFFFF; + break; + } + } + + /* Does the current have a valid index? */ + if (j != 0xFFFFFFFF) + { + /* Yes, what about the comparator? */ + if (i != 0xFFFFFFFF) + { + /* Let the indexes fight! */ + return i >= j; + } + + /* Succeed the comparator, its index is unknown */ + return FALSE; + } + } + + /* The comparator isn't system, so it preceeds it */ + return TRUE; + } + + /* Descriptor is not system class, but comparator is -- it suceeds it */ + if (Class2 == BlSystemClass) + { + return FALSE; + } + + /* Descriptor is loader class -- it preceeds */ + if (Class1 == BlLoaderClass) + { + return TRUE; + } + + /* It isn't loader class -- if the other guy is, suceed it */ + return Class2 != BlLoaderClass; +} + VOID MmMdpSwitchToDynamicDescriptors ( _In_ ULONG Count @@ -113,6 +236,157 @@ MmMdFreeList( } } +PBL_MEMORY_DESCRIPTOR +MmMdInitByteGranularDescriptor ( + _In_ ULONG Flags, + _In_ BL_MEMORY_TYPE Type, + _In_ ULONGLONG BasePage, + _In_ ULONGLONG VirtualPage, + _In_ ULONGLONG PageCount + ) +{ + PBL_MEMORY_DESCRIPTOR MemoryDescriptor; + + /* If we're out of descriptors, bail out */ + if (MmGlobalMemoryDescriptorsUsed >= MmGlobalMemoryDescriptorCount) + { + EarlyPrint(L"Out of descriptors!\n"); + return NULL; + } + + /* Take one of the available descriptors and fill it out */ + MemoryDescriptor = &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorsUsed]; + MemoryDescriptor->BaseAddress = BasePage; + MemoryDescriptor->VirtualPage = VirtualPage; + MemoryDescriptor->PageCount = PageCount; + MemoryDescriptor->Flags = Flags; + MemoryDescriptor->Type = Type; + InitializeListHead(&MemoryDescriptor->ListEntry); + + /* Increment the count and return the descriptor */ + MmGlobalMemoryDescriptorsUsed++; + return MemoryDescriptor; +} + +NTSTATUS +MmMdAddDescriptorToList ( + _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, + _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor, + _In_ ULONG Flags + ) +{ + PLIST_ENTRY ThisEntry, FirstEntry; + PBL_MEMORY_DESCRIPTOR ThisDescriptor; + + /* Arguments must be present */ + if (!(MdList) || !(MemoryDescriptor)) + { + return STATUS_INVALID_PARAMETER; + } + + /* Check if coalescing is forcefully disabled */ + if (Flags & BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG) + { + /* Then we won't be coalescing */ + Flags &= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG; + } + else + { + /* Coalesce if the descriptor requires it */ + if (MemoryDescriptor->Flags & BL_MM_DESCRIPTOR_REQUIRES_COALESCING_FLAG) + { + Flags |= BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG; + } + } + + /* Check if truncation is forcefully disabled */ + if (Flags & BL_MM_ADD_DESCRIPTOR_NEVER_TRUNCATE_FLAG) + { + Flags &= ~BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG; + } + + /* Update the current list pointer if the descriptor requires it */ + if (MemoryDescriptor->Flags & BL_MM_DESCRIPTOR_REQUIRES_UPDATING_FLAG) + { + Flags |= BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG; + } + + /* Get the current descriptor */ + ThisEntry = MdList->This; + ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry); + + /* Also get the first descriptor */ + FirstEntry = MdList->First; + + /* Check if there's no current pointer, or if it's higher than the new one */ + if (!(ThisEntry) || + (MemoryDescriptor->BaseAddress <= ThisDescriptor->BaseAddress)) + { + /* Start at the first descriptor instead, since current is past us */ + ThisEntry = FirstEntry->Flink; + ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry); + } + + /* Loop until we find the right location to insert */ + while (1) + { + /* Have we gotten back to the first entry? */ + if (ThisEntry == FirstEntry) + { + /* Then we didn't find a good match, so insert it right here */ + InsertTailList(FirstEntry, &MemoryDescriptor->ListEntry); + + /* Do we have to truncate? */ + if (Flags & BL_MM_ADD_DESCRIPTOR_TRUNCATE_FLAG) + { + /* Do it and then exit */ +#if 0 + if (MmMdpTruncateDescriptor(MdList, Flags)) + { + return STATUS_SUCCESS; + } +#endif + } + + /* Do we have to coalesce? */ + if (Flags & BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG) + { + /* Do it and then exit */ +#if 0 + if (MmMdpCoalesceDescriptor(MdList)) + { + return STATUS_SUCCESS; + } +#endif + } + + /* Do we have to update the current pointer? */ + if (Flags & BL_MM_ADD_DESCRIPTOR_UPDATE_LIST_POINTER_FLAG) + { + /* Do it */ + MmMdpSaveCurrentListPointer(MdList, &MemoryDescriptor->ListEntry); + } + + /* We're done */ + return STATUS_SUCCESS; + } + + /* Is the new descriptor below this address, and has precedence over it? */ + if ((MemoryDescriptor->BaseAddress < ThisDescriptor->BaseAddress) && + (MmMdpHasPrecedence(MemoryDescriptor->Type, ThisDescriptor->Type))) + { + /* Then insert right here */ + InsertTailList(ThisEntry, &MemoryDescriptor->ListEntry); + return STATUS_SUCCESS; + } + + /* Try the next descriptor */ + ThisEntry = ThisEntry->Flink; + ThisDescriptor = CONTAINING_RECORD(ThisEntry, BL_MEMORY_DESCRIPTOR, ListEntry); + } +} + + VOID MmMdInitialize ( _In_ ULONG Phase, diff --git a/reactos/boot/environ/lib/mm/mm.c b/reactos/boot/environ/lib/mm/mm.c index 0c475523c62..20c8a46d5ef 100644 --- a/reactos/boot/environ/lib/mm/mm.c +++ b/reactos/boot/environ/lib/mm/mm.c @@ -31,7 +31,8 @@ BlMmRemoveBadMemory ( VOID ) { - return STATUS_NOT_IMPLEMENTED; + /* FIXME: Read BCD option to see what bad memory to remove */ + return STATUS_SUCCESS; } NTSTATUS diff --git a/reactos/boot/environ/lib/mm/pagealloc.c b/reactos/boot/environ/lib/mm/pagealloc.c index 42dd47557fe..6d79553c4c1 100644 --- a/reactos/boot/environ/lib/mm/pagealloc.c +++ b/reactos/boot/environ/lib/mm/pagealloc.c @@ -16,6 +16,8 @@ ULONGLONG PapMaximumPhysicalPage, PapMinimumPhysicalPage; ULONG PapMinimumAllocationCount; +BOOLEAN PapInitializationStatus; + BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated; BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated; BL_MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker; @@ -31,6 +33,15 @@ BL_MEMORY_DESCRIPTOR_LIST MmMdlMappingTrackers; /* FUNCTIONS *****************************************************************/ +NTSTATUS +BlpMmInitializeConstraints ( + VOID + ) +{ + /* FIXME: Read BCD option 'avoidlowmemory' and 'truncatememory' */ + return STATUS_SUCCESS; +} + NTSTATUS MmPaInitialize ( __in PBL_MEMORY_DATA BootMemoryData, @@ -38,6 +49,8 @@ MmPaInitialize ( ) { NTSTATUS Status; + ULONG ExistingDescriptors, FinalOffset; + PBL_MEMORY_DESCRIPTOR Descriptor; /* Initialize physical allocator variables */ PapMaximumPhysicalPage = 0xFFFFFFFFFFFFF; @@ -59,10 +72,56 @@ MmPaInitialize ( /* Get the BIOS memory map */ Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS | - BL_MM_FLAG_UNKNOWN); + BL_MM_FLAG_REQUEST_COALESCING); if (NT_SUCCESS(Status)) { - Status = STATUS_NOT_IMPLEMENTED; + PLIST_ENTRY listHead, nextEntry; + + /* Loop the NT firmware memory list */ + EarlyPrint(L"NT MEMORY MAP\n\n"); + listHead = &MmMdlUnmappedUnallocated.ListHead; + nextEntry = listHead->Flink; + while (listHead != nextEntry) + { + Descriptor = CONTAINING_RECORD(nextEntry, BL_MEMORY_DESCRIPTOR, ListEntry); + + EarlyPrint(L"Type: %lX Flags: %lX Start: 0x%I64X End: 0x%I64X\n", + Descriptor->Type, + Descriptor->Flags, + Descriptor->BasePage << PAGE_SHIFT, + (Descriptor->BasePage + Descriptor->PageCount) << PAGE_SHIFT); + + nextEntry = nextEntry->Flink; + } + + /* + * Because BL supports cross x86-x64 application launches and a LIST_ENTRY + * is of variable size, care must be taken here to ensure that we see a + * consistent view of descriptors. BL uses some offset magic to figure out + * where the data actually starts, since everything is ULONGLONG past the + * LIST_ENTRY itself + */ + FinalOffset = BootMemoryData->MdListOffset + BootMemoryData->DescriptorOffset; + Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)BootMemoryData + FinalOffset - + FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage)); + + /* Scan all of them */ + ExistingDescriptors = BootMemoryData->DescriptorCount; + while (ExistingDescriptors != 0) + { + EarlyPrint(L"Existing migration of memory not supported\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + } + + /* We are done, so check for any RAM constraints which will make us truncate memory */ + Status = BlpMmInitializeConstraints(); + if (NT_SUCCESS(Status)) + { + /* The Page Allocator has initialized */ + PapInitializationStatus = TRUE; + Status = STATUS_SUCCESS; + } } /* Return status */