Author: ion
Date: Sun Sep 6 06:15:08 2015
New Revision: 69047
URL:
http://svn.reactos.org/svn/reactos?rev=69047&view=rev
Log:
[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.
Modified:
trunk/reactos/boot/environ/app/bootmgr/efiemu.c
trunk/reactos/boot/environ/include/bl.h
trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
trunk/reactos/boot/environ/lib/mm/descriptor.c
trunk/reactos/boot/environ/lib/mm/mm.c
trunk/reactos/boot/environ/lib/mm/pagealloc.c
Modified: trunk/reactos/boot/environ/app/bootmgr/efiemu.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/e…
==============================================================================
--- trunk/reactos/boot/environ/app/bootmgr/efiemu.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/app/bootmgr/efiemu.c [iso-8859-1] Sun Sep 6 06:15:08 2015
@@ -930,10 +930,10 @@
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;
Modified: trunk/reactos/boot/environ/include/bl.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?…
==============================================================================
--- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sun Sep 6 06:15:08 2015
@@ -53,11 +53,22 @@
#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 **************************************************************/
@@ -222,7 +233,7 @@
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 @@
_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
Modified: trunk/reactos/boot/environ/lib/firmware/efi/firmware.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/firmware/…
==============================================================================
--- trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/firmware/efi/firmware.c [iso-8859-1] Sun Sep 6
06:15:08 2015
@@ -371,7 +371,7 @@
)
{
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 @@
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 @@
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,17 +572,136 @@
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);
+ /* 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 */
-LoopAgain:
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 */
Modified: trunk/reactos/boot/environ/lib/mm/descriptor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/descri…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] Sun Sep 6 06:15:08 2015
@@ -19,7 +19,130 @@
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 (
@@ -113,6 +236,157 @@
}
}
+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,
Modified: trunk/reactos/boot/environ/lib/mm/mm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/mm.c?r…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/mm.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/mm.c [iso-8859-1] Sun Sep 6 06:15:08 2015
@@ -31,7 +31,8 @@
VOID
)
{
- return STATUS_NOT_IMPLEMENTED;
+ /* FIXME: Read BCD option to see what bad memory to remove */
+ return STATUS_SUCCESS;
}
NTSTATUS
Modified: trunk/reactos/boot/environ/lib/mm/pagealloc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/pageal…
==============================================================================
--- trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] (original)
+++ trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] Sun Sep 6 06:15:08 2015
@@ -16,6 +16,8 @@
ULONG PapMinimumAllocationCount;
+BOOLEAN PapInitializationStatus;
+
BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated;
BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated;
BL_MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker;
@@ -32,12 +34,23 @@
/* FUNCTIONS *****************************************************************/
NTSTATUS
+BlpMmInitializeConstraints (
+ VOID
+ )
+{
+ /* FIXME: Read BCD option 'avoidlowmemory' and 'truncatememory' */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
MmPaInitialize (
__in PBL_MEMORY_DATA BootMemoryData,
__in ULONG MinimumAllocationCount
)
{
NTSTATUS Status;
+ ULONG ExistingDescriptors, FinalOffset;
+ PBL_MEMORY_DESCRIPTOR Descriptor;
/* Initialize physical allocator variables */
PapMaximumPhysicalPage = 0xFFFFFFFFFFFFF;
@@ -59,10 +72,56 @@
/* 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 */