[BOOTLIB]: Clarify some attributes now that their meaning is clearer.
[reactos.git] / reactos / boot / environ / lib / mm / descriptor.c
index 2c7d859..705ba1d 100644 (file)
@@ -253,7 +253,6 @@ MmMdCopyList (
 {
     NTSTATUS Status;
     PULONG Used;
-    BOOLEAN Finished;
     PLIST_ENTRY First, NextEntry;
     PBL_MEMORY_DESCRIPTOR Descriptor;
 
@@ -290,45 +289,33 @@ MmMdCopyList (
     /* Iterate through the list */
     First = SourceList->First;
     NextEntry = First->Flink;
-    if (First->Flink != First)
+    while ((NextEntry != First) && (NT_SUCCESS(Status)))
     {
-        /* As long as we have success */
-        while (NT_SUCCESS(Status))
+        /* Make sure there's still space */
+        if (Count <= *Used)
         {
-            /* Check if there's still space */
-            if (Count <= *Used)
-            {
-                Status = STATUS_NO_MEMORY;
-                break;
-            }
-
-            /* Get the current descriptor */
-            Descriptor = CONTAINING_RECORD(NextEntry,
-                                           BL_MEMORY_DESCRIPTOR,
-                                           ListEntry);
-
-            /* Copy it into one of the descriptors we have */
-            RtlCopyMemory(&ListDescriptor[*Used],
-                          Descriptor,
-                          sizeof(*Descriptor));
+            Status = STATUS_NO_MEMORY;
+            break;
+        }
 
-            /* Add it to the list we have */
-            Status = MmMdAddDescriptorToList(DestinationList,
-                                             &ListDescriptor[*Used],
-                                             Flags);
-            ++*Used;
+        /* Get the current descriptor */
+        Descriptor = CONTAINING_RECORD(NextEntry,
+                                       BL_MEMORY_DESCRIPTOR,
+                                       ListEntry);
 
-            /* Before moving on, check if we're done */
-            Finished = NextEntry->Flink == SourceList->First;
+        /* Copy it into one of the descriptors we have */
+        RtlCopyMemory(&ListDescriptor[*Used],
+                      Descriptor,
+                      sizeof(*Descriptor));
 
-            /* Move to the next entry */
-            NextEntry = NextEntry->Flink;
+        /* Add it to the list we have */
+        Status = MmMdAddDescriptorToList(DestinationList,
+                                         &ListDescriptor[*Used],
+                                         Flags);
+        ++*Used;
 
-            if (Finished)
-            {
-                break;
-            }
-        }
+        /* Move to the next entry */
+        NextEntry = NextEntry->Flink;
     }
 
     /* Check if the global descriptors were used */
@@ -693,7 +680,6 @@ MmMdRemoveRegionFromMdlEx (
         FoundPageCount = Descriptor->PageCount;
         FoundEndPage = FoundBasePage + FoundPageCount;
         EndPage = PageCount + BasePage;
-        //EarlyPrint(L"Looking for Region 0x%08I64X-0x%08I64X in 0x%08I64X-0x%08I64X\r\n", BasePage, EndPage, FoundBasePage, FoundEndPage);
 
         /* Make a copy of the original descriptor */
         RtlCopyMemory(&NewDescriptor, NextEntry, sizeof(NewDescriptor));
@@ -707,19 +693,52 @@ MmMdRemoveRegionFromMdlEx (
                 /* 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 */
-                    //EarlyPrint(L"No part of this descriptor contains the region\r\n");
+                    /* This descriptor doesn't cover any part of the range -- nothing to do */
+                    NOTHING;
                 }
                 else
                 {
-                    /* This descriptor covers the head of the allocation */
-                    //EarlyPrint(L"Descriptor covers the head of the region\r\n");
+                    /* This descriptor fully covers the entire allocation */
+                    FoundBasePage = Descriptor->BasePage;
+                    FoundPageCount = BasePage - FoundBasePage;
+
+                    /* This is how many pages we will eat away from the descriptor */
+                    RegionSize = FoundPageCount + PageCount;
+
+                    /* Update the descriptor to account for the consumed pages */
+                    Descriptor->BasePage += RegionSize;
+                    Descriptor->PageCount -= RegionSize;
+                    if (Descriptor->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)
+                    {
+                        Status = STATUS_NO_MEMORY;
+                        goto Quickie;
+                    }
+
+                    /* Add it into the list */
+                    Status = MmMdAddDescriptorToList(MdList, Descriptor, Flags);
+                    if (!NT_SUCCESS(Status))
+                    {
+                        Status = STATUS_NO_MEMORY;
+                        goto Quickie;
+                    }
                 }
             }
             else
             {
                 /* This descriptor contains the entire allocation */
-                //EarlyPrint(L"Descriptor contains the entire region\r\n");
+                RegionSize = FoundEndPage - BasePage;
+                Descriptor->PageCount -= RegionSize;
             }
 
             /* Keep going */
@@ -736,14 +755,14 @@ MmMdRemoveRegionFromMdlEx (
              *
              * So first, figure out if we cover the entire end or not
              */
-            if (EndPage > FoundEndPage)
+            if (EndPage < FoundEndPage)
             {
                 /* The allocation goes past the end of this descriptor */
-                EndPage = FoundEndPage;
+                FoundEndPage = EndPage;
             }
 
             /* This is how many pages we will eat away from the descriptor */
-            RegionSize = EndPage - FoundBasePage;
+            RegionSize = FoundEndPage - FoundBasePage;
 
             /* Update the descriptor to account for the consumed pages */
             Descriptor->BasePage += RegionSize;
@@ -760,7 +779,6 @@ MmMdRemoveRegionFromMdlEx (
             if (!Descriptor->PageCount)
             {
                 /* Remove it */
-                //EarlyPrint(L"Entire descriptor consumed\r\n");
                 MmMdRemoveDescriptorFromList(MdList, Descriptor);
                 MmMdFreeDescriptor(Descriptor);
 
@@ -792,6 +810,204 @@ Quickie:
     return Status;
 }
 
+PBL_MEMORY_DESCRIPTOR
+MmMdFindDescriptorFromMdl (
+    _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, 
+    _In_ ULONG Flags, 
+    _In_ ULONGLONG Page
+    )
+{
+    BOOLEAN IsVirtual;
+    PLIST_ENTRY NextEntry, ListHead;
+    PBL_MEMORY_DESCRIPTOR Current;
+    ULONGLONG BasePage;
+
+    /* Assume physical */
+    IsVirtual = FALSE;
+
+    /* Check if the caller wants physical memory */
+    if (!(Flags & BL_MM_REMOVE_VIRTUAL_REGION_FLAG))
+    {
+        /* Check if this is a virtual memory list */
+        if (MdList->Type == BlMdVirtual)
+        {
+            /* We won't find anything */
+            return NULL;
+        }
+    }
+    else if (MdList->Type == BlMdPhysical)
+    {
+        /* Otherwise, caller wants virtual, but this is a physical list */
+        IsVirtual = TRUE;
+        NextEntry = MdList->First->Flink;
+    }
+    
+    /* Check if this is a physical search */
+    if (!IsVirtual)
+    {
+        /* Check if we can use the current pointer */
+        NextEntry = MdList->This;
+        if (!NextEntry)
+        {
+            /* We can't -- start at the beginning */
+            NextEntry = MdList->First->Flink;
+        }
+        else
+        {
+            /* If the page is below the current pointer, restart */
+            Current = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
+            if (Page < Current->BasePage)
+            {
+                NextEntry = MdList->First->Flink;
+            }
+        }
+    }
+
+    /* Loop the list of descriptors */
+    ListHead = MdList->First;
+    while (NextEntry != ListHead)
+    {
+        /* Get the current one */
+        Current = CONTAINING_RECORD(NextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
+
+        /* Check if we are looking for virtual memory */
+        if (IsVirtual)
+        {
+            /* Use the base address */
+            BasePage = Current->VirtualPage;
+        }
+        else
+        {
+            /* Use the page */
+            BasePage = Current->BasePage;
+        }
+
+        /* If this is a virtual descriptor, make sure it has a base address */
+        if ((!(IsVirtual) || (BasePage)) &&
+            (BasePage <= Page) &&
+            (Page < (BasePage + Current->PageCount)))
+        {
+            /* The descriptor fits the page being requested */
+            return Current;
+        }
+
+        /* Try the next one */
+        NextEntry = NextEntry->Flink;
+    }
+
+    /* Nothing found if we're here */
+    return NULL;
+}
+
+PBL_MEMORY_DESCRIPTOR
+MmMdFindDescriptor (
+    _In_ ULONG WhichList, 
+    _In_ ULONG Flags,
+    _In_ ULONGLONG Page
+    )
+{
+    PBL_MEMORY_DESCRIPTOR FoundDescriptor;
+
+    /* Check if the caller is looking for mapped, allocated memory */
+    if (WhichList & BL_MM_INCLUDE_MAPPED_ALLOCATED)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlMappedAllocated, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Check if the caller is looking for mapped, unallocated memory */
+    if (WhichList & BL_MM_INCLUDE_MAPPED_UNALLOCATED)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlMappedUnallocated, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Check if the caller is looking for unmapped, allocated memory */
+    if (WhichList & BL_MM_INCLUDE_UNMAPPED_ALLOCATED)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlUnmappedAllocated, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Check if the caller is looking for unmapped, unallocated memory */
+    if (WhichList & BL_MM_INCLUDE_UNMAPPED_UNALLOCATED)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlUnmappedUnallocated, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Check if the caller is looking for reserved, allocated memory */
+    if (WhichList & BL_MM_INCLUDE_RESERVED_ALLOCATED)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlReservedAllocated, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Check if the caller is looking for bad memory */
+    if (WhichList & BL_MM_INCLUDE_BAD_MEMORY)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlBadMemory, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Check if the caller is looking for truncated memory */
+    if (WhichList & BL_MM_INCLUDE_TRUNCATED_MEMORY)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlTruncatedMemory, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Check if the caller is looking for persistent memory */
+    if (WhichList & BL_MM_INCLUDE_PERSISTENT_MEMORY)
+    {
+        /* Find a descriptor in that list */
+        FoundDescriptor = MmMdFindDescriptorFromMdl(&MmMdlPersistentMemory, Flags, Page);
+        if (FoundDescriptor)
+        {
+            /* Got it */
+            return FoundDescriptor;
+        }
+    }
+
+    /* Nothing if we got here */
+    return NULL;
+}
+
 BOOLEAN
 MmMdFindSatisfyingRegion (
     _In_ PBL_MEMORY_DESCRIPTOR Descriptor,
@@ -888,7 +1104,7 @@ MmMdFindSatisfyingRegion (
     }
 
     /* Bail out if the allocation flags don't match */
-    if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryReserved | BlMemoryUnknown)))
+    if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryBelow1MB | BlMemoryLargePages)))
     {
         //EfiPrintf(L"Incorrect memory allocation flags\r\n");
         return FALSE;