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/b…
==============================================================================
--- 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?…
==============================================================================
--- 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/…
==============================================================================
--- 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/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 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/pageal…
==============================================================================
--- 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;