From 6eb6728488367c042071ffc459dc3c4de3e8e6a0 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 5 Feb 2017 19:55:49 +0000 Subject: [PATCH] [BOOTMGR]: Add the basics of some memory allocator/descriptor tests. [BOOTLIB]: Implement MmMdFindDescriptorFromMdl (broken?) [BOOTLIB]: Implement MmMdFindDescriptor. [BOOTLIB]: Implement BlMmFreePhysicalPages. [BOOTLIB]: Implement MmPapFreePages for physical memory translation scenario only. svn path=/trunk/; revision=73712 --- reactos/boot/environ/app/bootmgr/bootmgr.c | 25 +++ reactos/boot/environ/include/bl.h | 1 - reactos/boot/environ/lib/mm/descriptor.c | 198 +++++++++++++++++++++ reactos/boot/environ/lib/mm/pagealloc.c | 36 +++- 4 files changed, 254 insertions(+), 6 deletions(-) diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.c b/reactos/boot/environ/app/bootmgr/bootmgr.c index 0fb3c6b6d8e..8da61c7d7bb 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.c +++ b/reactos/boot/environ/app/bootmgr/bootmgr.c @@ -2895,6 +2895,31 @@ BmMain ( } } + + /* TEST MODE */ + EfiPrintf(L"Performing memory allocator tests...\r\n"); + { + NTSTATUS Status; + PHYSICAL_ADDRESS PhysicalAddress; + PBL_MEMORY_DESCRIPTOR Found; + PBL_MEMORY_DESCRIPTOR + MmMdFindDescriptor ( + _In_ ULONG WhichList, + _In_ ULONG Flags, + _In_ ULONGLONG Page + ); + + /* Allocate 1 physical page */ + PhysicalAddress.QuadPart = 0; + Status = BlMmAllocatePhysicalPages(&PhysicalAddress, BlLoaderData, 1, 0, 1); + EfiPrintf(L"Allocation status: %lx at address: %llx\r\n", Status, PhysicalAddress.QuadPart); + EfiStall(10000); + + Found = MmMdFindDescriptor(BL_MM_INCLUDE_UNMAPPED_ALLOCATED, 0, PhysicalAddress.QuadPart); + EfiPrintf(L"Found descriptor: %p %llx\r\n", Found, Found->BasePage); + } + + /* Write out the first XML tag */ BlXmiWrite(L""); diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index db9e053d07d..6ade600762e 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -670,7 +670,6 @@ NTSTATUS VOID ); - /* DATA STRUCTURES ***********************************************************/ typedef struct _BL_LIBRARY_PARAMETERS diff --git a/reactos/boot/environ/lib/mm/descriptor.c b/reactos/boot/environ/lib/mm/descriptor.c index e7e6759ee6f..808be81b28f 100644 --- a/reactos/boot/environ/lib/mm/descriptor.c +++ b/reactos/boot/environ/lib/mm/descriptor.c @@ -779,6 +779,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 */ + break; + } + + /* 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, diff --git a/reactos/boot/environ/lib/mm/pagealloc.c b/reactos/boot/environ/lib/mm/pagealloc.c index e83452d942a..0444ba91273 100644 --- a/reactos/boot/environ/lib/mm/pagealloc.c +++ b/reactos/boot/environ/lib/mm/pagealloc.c @@ -609,15 +609,25 @@ BlMmAllocatePhysicalPages( 0); } +NTSTATUS +MmPapFreePhysicalPages ( + _In_ ULONG WhichList, + _In_ ULONGLONG PageCount, + _In_ PHYSICAL_ADDRESS Address + ) +{ + /* TBD */ + EfiPrintf(L"Leaking memory: %p!\r\n", Address.QuadPart); + return STATUS_SUCCESS; +} + NTSTATUS BlMmFreePhysicalPages ( _In_ PHYSICAL_ADDRESS Address ) { /* Call the physical allocator */ - EfiPrintf(L"Leaking memory: %p!\r\n", Address.QuadPart); - return STATUS_SUCCESS; - //return MmPapFreePhysicalPages(4, 0, Address); + return MmPapFreePhysicalPages(BL_MM_INCLUDE_UNMAPPED_ALLOCATED, 0, Address); } NTSTATUS @@ -626,8 +636,24 @@ MmPapFreePages ( _In_ ULONG WhichList ) { - EfiPrintf(L"Leaking memory: %p!\r\n", Address); - return STATUS_SUCCESS; + PHYSICAL_ADDRESS PhysicalAddress; + + /* Handle virtual memory scenario */ + if (MmTranslationType != BlNone) + { + EfiPrintf(L"Unimplemented virtual path\r\n"); + return STATUS_SUCCESS; + } + + /* Physical memory should be in the unmapped allocated list */ + if (WhichList != BL_MM_INCLUDE_PERSISTENT_MEMORY) + { + WhichList = BL_MM_INCLUDE_UNMAPPED_ALLOCATED; + } + + /* Free it from there */ + PhysicalAddress.QuadPart = (ULONGLONG)Address; + return MmPapFreePhysicalPages(WhichList, 0, PhysicalAddress); } NTSTATUS