Author: ion
Date: Sun May 14 00:11:48 2017
New Revision: 74541
URL:
http://svn.reactos.org/svn/reactos?rev=74541&view=rev
Log:
[BOOTLIB]: Complete implementation of MmMdRemoveRegionFromMdlEx
Modified:
trunk/reactos/boot/environ/lib/mm/descriptor.c
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 May 14 00:11:48 2017
@@ -390,6 +390,7 @@
if (MmGlobalMemoryDescriptorsUsed >= MmGlobalMemoryDescriptorCount)
{
EfiPrintf(L"Out of descriptors!\r\n");
+ EfiStall(1000000);
return NULL;
}
@@ -409,9 +410,9 @@
BOOLEAN
MmMdpTruncateDescriptor (
- __in PBL_MEMORY_DESCRIPTOR_LIST MdList,
- __in PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
- __in ULONG Flags
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
+ _In_ ULONG Flags
)
{
PBL_MEMORY_DESCRIPTOR NextDescriptor, PreviousDescriptor;
@@ -435,12 +436,14 @@
if ((PreviousEntry != MdList->First) && (MemoryDescriptor->BasePage
< PreviousEndPage))
{
EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64
platforms\r\n");
+ EfiStall(1000000);
}
/* Check for forward overlap */
if ((NextEntry != MdList->First) && (NextDescriptor->BasePage <
EndPage))
{
EfiPrintf(L"Overlap detected -- this is unexpected on x86/x64
platforms\r\n");
+ EfiStall(1000000);
}
/* Nothing to do */
@@ -449,9 +452,9 @@
BOOLEAN
MmMdpCoalesceDescriptor (
- __in PBL_MEMORY_DESCRIPTOR_LIST MdList,
- __in PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
- __in ULONG Flags
+ _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList,
+ _In_ PBL_MEMORY_DESCRIPTOR MemoryDescriptor,
+ _In_ ULONG Flags
)
{
PBL_MEMORY_DESCRIPTOR NextDescriptor, PreviousDescriptor;
@@ -623,28 +626,25 @@
BOOLEAN HaveNewList, UseVirtualPage;
NTSTATUS Status;
PLIST_ENTRY ListHead, NextEntry;
- PBL_MEMORY_DESCRIPTOR Descriptor;
- //BL_MEMORY_DESCRIPTOR NewDescriptor;
+ PBL_MEMORY_DESCRIPTOR Descriptor, NewDescriptor, ListDescriptor;
+ BL_MEMORY_DESCRIPTOR OldDescriptor;
ULONGLONG RegionSize;
- ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage;
+ ULONGLONG FoundBasePage, FoundEndPage, FoundPageCount, EndPage, VirtualPage;
/* Set initial status */
Status = STATUS_SUCCESS;
+ ListDescriptor = NULL;
+ NewDescriptor = NULL;
+ HaveNewList = FALSE;
/* Check if removed descriptors should go into a new list */
if (NewMdList != NULL)
{
/* Initialize it */
- MmMdInitializeListHead(NewMdList);
- NewMdList->Type = MdList->Type;
+ MmMdInitializeList(NewMdList, MdList->Type, NULL);
/* Remember for later */
HaveNewList = TRUE;
- }
- else
- {
- /* For later */
- HaveNewList = FALSE;
}
/* Is the region being removed physical? */
@@ -684,7 +684,7 @@
EndPage = PageCount + BasePage;
/* Make a copy of the original descriptor */
- //NewDescriptor = *Descriptor; // FIXME: Need to use this somewhere...
+ OldDescriptor = *Descriptor;
/* Check if the region to be removed starts after the found region starts */
if ((BasePage > FoundBasePage) || (FoundBasePage >= EndPage))
@@ -695,13 +695,14 @@
/* Check if the found region starts after the region or ends before the
region */
if ((FoundBasePage >= BasePage) || (EndPage >= FoundEndPage))
{
- /* This descriptor doesn't cover any part of the range -- nothing
to do */
- NOTHING;
+ /* This is a fully-mapped descriptor -- change nothing */
+ OldDescriptor.PageCount = 0;
}
else
{
/* This descriptor fully covers the entire allocation */
FoundBasePage = Descriptor->BasePage;
+ VirtualPage = Descriptor->VirtualPage;
FoundPageCount = BasePage - FoundBasePage;
/* This is how many pages we will eat away from the descriptor */
@@ -710,29 +711,40 @@
/* Update the descriptor to account for the consumed pages */
Descriptor->BasePage += RegionSize;
Descriptor->PageCount -= RegionSize;
- if (Descriptor->VirtualPage)
+ if (VirtualPage)
{
Descriptor->VirtualPage += RegionSize;
}
/* Initialize a descriptor for the start of the region */
- Descriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
- Descriptor->Type,
- FoundBasePage,
-
Descriptor->VirtualPage,
- FoundPageCount);
- if (!Descriptor)
+ NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
+ Descriptor->Type,
+ FoundBasePage,
+ VirtualPage,
+ FoundPageCount);
+ if (!NewDescriptor)
{
Status = STATUS_NO_MEMORY;
goto Quickie;
}
/* Add it into the list */
- Status = MmMdAddDescriptorToList(MdList, Descriptor, Flags);
+ Status = MmMdAddDescriptorToList(MdList, NewDescriptor, Flags);
if (!NT_SUCCESS(Status))
{
Status = STATUS_NO_MEMORY;
goto Quickie;
+ }
+
+ /* Don't free it on exit path */
+ NewDescriptor = NULL;
+
+ /* Adjust the leftover descriptor */
+ OldDescriptor.BasePage += FoundPageCount;
+ OldDescriptor.PageCount = PageCount;
+ if (OldDescriptor.VirtualPage)
+ {
+ OldDescriptor.VirtualPage += FoundPageCount;
}
}
}
@@ -741,9 +753,17 @@
/* This descriptor contains the entire allocation */
RegionSize = FoundEndPage - BasePage;
Descriptor->PageCount -= RegionSize;
+
+ /* Adjust the leftover descriptor */
+ OldDescriptor.BasePage += Descriptor->PageCount;
+ OldDescriptor.PageCount = RegionSize;
+ if (OldDescriptor.VirtualPage)
+ {
+ OldDescriptor.VirtualPage += FoundPageCount;
+ }
}
- /* Keep going */
+ /* Go to the next entry */
NextEntry = NextEntry->Flink;
}
else
@@ -764,14 +784,14 @@
}
/* This is how many pages we will eat away from the descriptor */
- RegionSize = FoundEndPage - FoundBasePage;
+ FoundPageCount = FoundEndPage - FoundBasePage;
/* Update the descriptor to account for the consumed pages */
- Descriptor->BasePage += RegionSize;
- Descriptor->PageCount -= RegionSize;
+ Descriptor->BasePage += FoundPageCount;
+ Descriptor->PageCount -= FoundPageCount;
if (Descriptor->VirtualPage)
{
- Descriptor->VirtualPage += RegionSize;
+ Descriptor->VirtualPage += FoundPageCount;
}
/* Go to the next entry */
@@ -782,15 +802,53 @@
{
/* Remove it */
MmMdRemoveDescriptorFromList(MdList, Descriptor);
- MmMdFreeDescriptor(Descriptor);
/* Check if we're supposed to insert it into a new list */
if (HaveNewList)
{
- EfiPrintf(L"Not yet implemented\r\n");
- Status = STATUS_NOT_IMPLEMENTED;
+ /* This is the one to add */
+ ListDescriptor = Descriptor;
+ }
+ else
+ {
+ /* Nope -- just get rid of it */
+ MmMdFreeDescriptor(Descriptor);
+ }
+ }
+ }
+
+ /* Is there a remainder descriptor, and do we have a list for it */
+ if ((OldDescriptor.PageCount) && (HaveNewList))
+ {
+ /* Did we already chop off the descriptor? */
+ if (ListDescriptor)
+ {
+ /* Use what we previously chopped */
+ *ListDescriptor = OldDescriptor;
+ }
+ else
+ {
+ /* First time, so build a descriptor to describe the leftover */
+ ListDescriptor = MmMdInitByteGranularDescriptor(OldDescriptor.Flags,
+ OldDescriptor.Type,
+ OldDescriptor.BasePage,
+
OldDescriptor.VirtualPage,
+
OldDescriptor.PageCount);
+ if (!ListDescriptor)
+ {
+ Status = STATUS_NO_MEMORY;
goto Quickie;
}
+
+ /* Add it into the list */
+ Status = MmMdAddDescriptorToList(NewMdList, ListDescriptor, 0);
+ if (!NT_SUCCESS(Status))
+ {
+ goto Quickie;
+ }
+
+ /* Don't free on exit path */
+ ListDescriptor = NULL;
}
}
}
@@ -804,11 +862,23 @@
{
/* Free and re-initialize it */
MmMdFreeList(NewMdList);
- MmMdInitializeListHead(NewMdList);
- NewMdList->Type = MdList->Type;
- }
- }
-
+ MmMdInitializeList(NewMdList, MdList->Type, NULL);
+ }
+
+ /* Check if we had a list descriptor, and free it */
+ if (ListDescriptor)
+ {
+ MmMdFreeDescriptor(ListDescriptor);
+ }
+
+ /* Check if we had a new descriptor, and free it */
+ if (NewDescriptor)
+ {
+ MmMdFreeDescriptor(NewDescriptor);
+ }
+ }
+
+ /* All done */
return Status;
}