mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 01:15:09 +00:00
[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
This commit is contained in:
parent
e25a440db4
commit
4ea30042a6
6 changed files with 511 additions and 10 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue