[BOOT:MM] Finish MmFwGetMemoryMap()

Added stub for MmMdFindDescriptorFromMdl().
This commit is contained in:
Quinn Stephens 2024-09-01 10:38:28 -04:00
parent a32d72be1e
commit 4c32340803
3 changed files with 103 additions and 10 deletions

View File

@ -53,6 +53,13 @@ MmMdRemoveDescriptorFromList (
IN PMEMORY_DESCRIPTOR Descriptor
);
PMEMORY_DESCRIPTOR
MmMdFindDescriptorFromMdl (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN ULONGLONG Page,
IN ULONG Flags
);
NTSTATUS
MmMdRemoveRegionFromMdlEx (
IN PMEMORY_DESCRIPTOR_LIST Mdl,

View File

@ -302,17 +302,18 @@ Return Value:
{
NTSTATUS Status;
UINTN EfiMapSize;
UINTN EfiMapKey;
UINTN EfiDescriptorSize;
UINT32 EfiDescriptorVersion;
UINTN PageCount, EfiPageCount;
EFI_PHYSICAL_ADDRESS EfiBuffer;
EFI_MEMORY_DESCRIPTOR *EfiMap;
BOOLEAN IsRamdisk;
MEMORY_TYPE MemoryType;
UINTN EfiMapKey;
UINTN EfiMapSize, EfiDescriptorSize;
UINT32 EfiDescriptorVersion;
UINT64 EfiStartPage, EfiEndPage;
UINTN EfiPageCount;
ULONGLONG NtStartPage;
ULONG NtPageCount;
BOOLEAN IsRamdisk;
UINT64 EfiRamdiskStartPage, EfiRamdiskEndPage;
MEMORY_TYPE MemoryType;
PMEMORY_DESCRIPTOR NtDescriptor;
(VOID)Flags;
@ -347,8 +348,8 @@ Return Value:
}
EfiMapSize += 4 * EfiDescriptorSize;
PageCount = (ALIGN_UP(EfiMapSize, PAGE_SIZE) >> PAGE_SHIFT) + 1;
EfiPageCount = EFI_PAGE(PageCount);
NtPageCount = (ALIGN_UP(EfiMapSize, PAGE_SIZE) >> PAGE_SHIFT) + 1;
EfiPageCount = EFI_PAGE(NtPageCount);
Status = EfiAllocatePages(AllocateAnyPages, EfiLoaderData, EfiPageCount, &EfiBuffer);
if (!NT_SUCCESS(Status)) {
DebugPrint(L"MmFwGetMemoryMap(): EfiAllocatePages() failed\r\n");
@ -572,9 +573,55 @@ Return Value:
}
//
// TODO: Account for possible MDL changes due to freeing EfiBuffer.
// The following code is to free the buffer and
// also mark the freed memory as free in the MDL.
//
Status = EfiFreePages(EfiBuffer, EfiPageCount);
if (!NT_SUCCESS(Status)) {
Status = STATUS_SUCCESS;
goto exit;
}
EfiBuffer = 0;
EfiStartPage = EfiBuffer >> EFI_PAGE_SHIFT;
EfiEndPage = ALIGN_UP(EfiStartPage + EfiPageCount, EFI_PAGE(1));
NtStartPage = NT_PAGE(EfiStartPage);
NtPageCount = NT_PAGE(EfiEndPage) - NtStartPage;
//
// Find the current descriptor.
//
NtDescriptor = MmMdFindDescriptorFromMdl(Mdl, NtStartPage, MDL_OPERATION_FLAGS_PHYSICAL);
if (NtDescriptor == NULL) {
Status = STATUS_UNSUCCESSFUL;
goto exit;
}
//
// Create a new free descriptor, with the same
// attributes as the current one.
//
NtDescriptor = MmMdInitDescriptor(NtStartPage, 0, NtPageCount, NtDescriptor->Attributes, MEMORY_TYPE_FREE);
if (NtDescriptor == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto exit;
}
//
// Remove the current descriptor.
//
Status = MmMdRemoveRegionFromMdlEx(Mdl, NtStartPage, NtPageCount, MDL_OPERATION_FLAGS_PHYSICAL, 0);
if (!NT_SUCCESS(Status)) {
MmMdFreeDescriptor(NtDescriptor);
goto exit;
}
//
// Add the new descriptor to the MDL.
//
Status = MmMdAddDescriptorToList(Mdl, NtDescriptor, 0x01);
exit:
if (EfiBuffer) {
EfiFreePages(EfiBuffer, EfiPageCount);

View File

@ -386,6 +386,45 @@ Return Value:
}
}
PMEMORY_DESCRIPTOR
MmMdFindDescriptorFromMdl (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN ULONGLONG Page,
IN ULONG Flags
)
/*++
Routine Description:
Searches an MDL for the descriptor containing a page.
Arguments:
Mdl - The MDL to search.
Page - The page to search for.
Flags - MDL_OPERATION_FLAGS_*
MDL_OPERATION_FLAGS_PHYSICAL if Page is physical.
MDL_OPERATION_FLAGS_VIRTUAL if Page is virtual.
Return Value:
Pointer to the descriptor if successful.
NULL if an error occurs.
--*/
{
//
// TODO: Implement this routine.
//
return NULL;
}
NTSTATUS
MmMdRemoveRegionFromMdlEx (
IN PMEMORY_DESCRIPTOR_LIST Mdl,