Author: ion Date: Sun Feb 5 21:50:14 2017 New Revision: 73716
URL: http://svn.reactos.org/svn/reactos?rev=73716&view=rev Log: [BOOTMGR]: Fix bug in test. [BOOTLIB]: Fix bug in MmMdFindDescriptorFromMdl. [BOOTLIB]: Implement MmFwFreePages. [BOOTLIB]: Implement most of MmPapFreePhysicalPages. The rest is coming next. [BOOTMGR]: Add test for alloc/free.
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.c trunk/reactos/boot/environ/include/bl.h trunk/reactos/boot/environ/lib/firmware/fwutil.c trunk/reactos/boot/environ/lib/mm/descriptor.c trunk/reactos/boot/environ/lib/mm/pagealloc.c
Modified: trunk/reactos/boot/environ/app/bootmgr/bootmgr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/app/bootmgr/bo... ============================================================================== --- trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/app/bootmgr/bootmgr.c [iso-8859-1] Sun Feb 5 21:50:14 2017 @@ -2902,12 +2902,6 @@ 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; @@ -2915,8 +2909,11 @@ 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); + Found = MmMdFindDescriptor(BL_MM_INCLUDE_UNMAPPED_ALLOCATED, 0, PhysicalAddress.QuadPart >> PAGE_SHIFT); EfiPrintf(L"Found descriptor: %p %llx\r\n", Found, Found->BasePage); + + Status = BlMmFreePhysicalPages(PhysicalAddress); + EfiPrintf(L"Memory free status: %lx\r\n", Status); }
Modified: trunk/reactos/boot/environ/include/bl.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/include/bl.h?r... ============================================================================== --- trunk/reactos/boot/environ/include/bl.h [iso-8859-1] (original) +++ trunk/reactos/boot/environ/include/bl.h [iso-8859-1] Sun Feb 5 21:50:14 2017 @@ -122,6 +122,7 @@ #define BL_MM_REQUEST_DEFAULT_TYPE 1 #define BL_MM_REQUEST_TOP_DOWN_TYPE 2
+#define BL_MM_REMOVE_PHYSICAL_REGION_FLAG 0x40000000 #define BL_MM_REMOVE_VIRTUAL_REGION_FLAG 0x80000000
#define BL_LIBRARY_FLAG_NO_DISPLAY 0x01 @@ -374,9 +375,10 @@ BlMemoryCoalesced = 0x02000000, BlMemoryUpdate = 0x04000000, BlMemoryNonFirmware = 0x08000000, + BlMemoryPersistent = 0x10000000, BlMemorySpecial = 0x20000000, BlMemoryFirmware = 0x80000000, - BlMemoryValidTypeAttributes = BlMemoryRuntime | BlMemoryCoalesced | BlMemoryUpdate | BlMemoryNonFirmware | BlMemorySpecial | BlMemoryFirmware, + BlMemoryValidTypeAttributes = BlMemoryRuntime | BlMemoryCoalesced | BlMemoryUpdate | BlMemoryNonFirmware | BlMemoryPersistent | BlMemorySpecial | BlMemoryFirmware, BlMemoryValidTypeAttributeMask = 0xFF000000, } BL_MEMORY_ATTR;
@@ -1541,6 +1543,12 @@ _Out_ PPHYSICAL_ADDRESS FoundRsdt );
+NTSTATUS +EfiFreePages ( + _In_ ULONG Pages, + _In_ EFI_PHYSICAL_ADDRESS PhysicalAddress + ); + /* PLATFORM TIMER ROUTINES ***************************************************/
NTSTATUS @@ -1709,6 +1717,12 @@ VOID BlFwReboot ( VOID + ); + +NTSTATUS +MmFwFreePages ( + _In_ ULONG BasePage, + _In_ ULONG PageCount );
PGUID @@ -1987,6 +2001,13 @@ _In_ PBL_MEMORY_DESCRIPTOR_LIST DescriptorList, _In_ ULONG Type, _In_ PLIST_ENTRY ListHead + ); + +PBL_MEMORY_DESCRIPTOR +MmMdFindDescriptor ( + _In_ ULONG WhichList, + _In_ ULONG Flags, + _In_ ULONGLONG Page );
NTSTATUS
Modified: trunk/reactos/boot/environ/lib/firmware/fwutil.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/firmware/f... ============================================================================== --- trunk/reactos/boot/environ/lib/firmware/fwutil.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/firmware/fwutil.c [iso-8859-1] Sun Feb 5 21:50:14 2017 @@ -24,3 +24,12 @@ EfiResetSystem(EfiResetCold); }
+NTSTATUS +MmFwFreePages ( + _In_ ULONG BasePage, + _In_ ULONG PageCount + ) +{ + /* Free the pages */ + return EfiFreePages(PageCount, BasePage << PAGE_SHIFT); +}
Modified: trunk/reactos/boot/environ/lib/mm/descriptor.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/descrip... ============================================================================== --- trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/mm/descriptor.c [iso-8859-1] Sun Feb 5 21:50:14 2017 @@ -857,7 +857,7 @@ (Page < (BasePage + Current->PageCount))) { /* The descriptor fits the page being requested */ - break; + return Current; }
/* Try the next one */
Modified: trunk/reactos/boot/environ/lib/mm/pagealloc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/environ/lib/mm/pageall... ============================================================================== --- trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] (original) +++ trunk/reactos/boot/environ/lib/mm/pagealloc.c [iso-8859-1] Sun Feb 5 21:50:14 2017 @@ -616,6 +616,130 @@ _In_ PHYSICAL_ADDRESS Address ) { + PBL_MEMORY_DESCRIPTOR Descriptor; + ULONGLONG Page; + ULONG DescriptorFlags, Flags; + BOOLEAN DontFree, HasPageData; + BL_LIBRARY_PARAMETERS LibraryParameters; + NTSTATUS Status; + + /* Set some defaults */ + Flags = BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG; + DontFree = FALSE; + HasPageData = FALSE; + + /* Only page-aligned addresses a re accepted */ + if (Address.QuadPart & (PAGE_SIZE - 1)) + { + EfiPrintf(L"free mem fail 1\r\n"); + return STATUS_INVALID_PARAMETER; + } + + /* Try to find the descriptor containing this address */ + Page = Address.QuadPart >> PAGE_SHIFT; + Descriptor = MmMdFindDescriptor(WhichList, + BL_MM_REMOVE_PHYSICAL_REGION_FLAG, + Page); + if (!Descriptor) + { + EfiPrintf(L"free mem fail 2\r\n"); + return STATUS_INVALID_PARAMETER; + } + + /* If a page count was given, it must match, unless it's coalesced */ + DescriptorFlags = Descriptor->Flags; + if (!(DescriptorFlags & BlMemoryCoalesced) && + (PageCount) && (PageCount != Descriptor->PageCount)) + { + EfiPrintf(L"free mem fail 3\r\n"); + return STATUS_INVALID_PARAMETER; + } + + /* Check if this is persistent memory in teardown status */ + if ((PapInitializationStatus == 2) && + (DescriptorFlags & BlMemoryPersistent)) + { + /* Then we should keep it */ + DontFree = TRUE; + } + else + { + /* Mark it as non-persistent, since we're freeing it */ + Descriptor->Flags &= ~BlMemoryPersistent; + } + + /* Check if this memory contains paging data */ + if ((Descriptor->Type == BlLoaderPageDirectory) || + (Descriptor->Type == BlLoaderReferencePage)) + { + HasPageData = TRUE; + } + + /* Check if a page count was given */ + if (PageCount) + { + /* The pages must fit within the descriptor */ + if ((PageCount + Page - Descriptor->BasePage) > Descriptor->PageCount) + { + EfiPrintf(L"free mem fail 4\r\n"); + return STATUS_INVALID_PARAMETER; + } + } + else + { + /* No page count given, so the address must be at the beginning then */ + if (Descriptor->BasePage != Page) + { + EfiPrintf(L"free mem fail 5\r\n"); + return STATUS_INVALID_PARAMETER; + } + + /* And we'll use the page count in the descriptor */ + PageCount = Descriptor->PageCount; + } + + /* Copy library parameters since we will read them */ + RtlCopyMemory(&LibraryParameters, + &BlpLibraryParameters, + sizeof(LibraryParameters)); + + /* Check if this is teardown */ + if (PapInitializationStatus == 2) + { + EfiPrintf(L"Case 2 not yet handled!\r\n"); + return STATUS_NOT_SUPPORTED; + } + else if (!DontFree) + { + /* Caller wants memory to be freed -- should we zero it? */ + if (!(HasPageData) & + (LibraryParameters.LibraryFlags & + BL_LIBRARY_FLAG_ZERO_HEAP_ALLOCATIONS_ON_FREE)) + { + EfiPrintf(L"Freeing zero data not yet handled!\r\n"); + return STATUS_NOT_SUPPORTED; + } + } + + /* Now call into firmware to actually free the physical pages */ + Status = MmFwFreePages(Page, PageCount); + if (!NT_SUCCESS(Status)) + { + EfiPrintf(L"free mem fail 6\r\n"); + return Status; + } + + /* Remove the firmware flags */ + Descriptor->Flags &= ~(BlMemoryNonFirmware | + BlMemoryFirmware | + BlMemoryPersistent); + + /* If we're not actually freeing, don't coalesce with anyone nearby */ + if (DontFree) + { + Flags |= BL_MM_ADD_DESCRIPTOR_NEVER_COALESCE_FLAG; + } + /* TBD */ EfiPrintf(L"Leaking memory: %p!\r\n", Address.QuadPart); return STATUS_SUCCESS;