From 27f761d0a3689d254136193932fb11f0944491c7 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 6 Feb 2017 03:14:14 +0000 Subject: [PATCH] [BOOTLIB]: Clarify that BlMemoryReserved == BlMemoryBelow1MB [BOOTLIB]: Implement EfiAllocatePages, EfiFreePages for Protected Mode. [BOOTLIB]: Fix a "Todo" in MmFwGetMemoryMap: We now free the EFI buffer used for the memory map itself, and unmap it from the memory map (which would show it as 'in-use' while we're dumping it). svn path=/trunk/; revision=73722 --- reactos/boot/environ/app/bootmgr/bootmgr.c | 4 +- reactos/boot/environ/include/bl.h | 11 ++- .../boot/environ/lib/firmware/efi/firmware.c | 87 ++++++++++++++++--- reactos/boot/environ/lib/mm/descriptor.c | 2 +- reactos/boot/environ/lib/mm/mm.c | 1 - reactos/boot/environ/lib/mm/pagealloc.c | 2 +- 6 files changed, 87 insertions(+), 20 deletions(-) diff --git a/reactos/boot/environ/app/bootmgr/bootmgr.c b/reactos/boot/environ/app/bootmgr/bootmgr.c index b1f22a8a332..e8647e5f5c3 100644 --- a/reactos/boot/environ/app/bootmgr/bootmgr.c +++ b/reactos/boot/environ/app/bootmgr/bootmgr.c @@ -1035,11 +1035,11 @@ BmFwMemoryInitialize ( AddressRange.Maximum = 0xFFFFF; AddressRange.Minimum = 0; - /* Allocate one reserved page with the "reserved" attribute */ + /* Allocate one reserved page with the "below 1MB" attribute */ Status = MmPapAllocatePhysicalPagesInRange(&PhysicalAddress, BlApplicationReserved, 1, - BlMemoryReserved, + BlMemoryBelow1MB, 0, &MmMdlUnmappedAllocated, &AddressRange, diff --git a/reactos/boot/environ/include/bl.h b/reactos/boot/environ/include/bl.h index 7401e642620..0b046c57c37 100644 --- a/reactos/boot/environ/include/bl.h +++ b/reactos/boot/environ/include/bl.h @@ -364,8 +364,8 @@ typedef enum _BL_MEMORY_ATTR BlMemoryUnknown = 0x00010000, BlMemoryNonFixed = 0x00020000, BlMemoryFixed = 0x00040000, - BlMemoryReserved = 0x00080000, - BlMemoryValidAllocationAttributes = BlMemoryNonFixed | BlMemoryFixed | BlMemoryReserved | BlMemoryUnknown, + BlMemoryBelow1MB = 0x00080000, + BlMemoryValidAllocationAttributes = BlMemoryNonFixed | BlMemoryFixed | BlMemoryBelow1MB | BlMemoryUnknown, BlMemoryValidAllocationAttributeMask = 0x00FF0000, // @@ -2010,6 +2010,13 @@ MmMdFindDescriptor ( _In_ ULONGLONG Page ); +PBL_MEMORY_DESCRIPTOR +MmMdFindDescriptorFromMdl ( + _In_ PBL_MEMORY_DESCRIPTOR_LIST MdList, + _In_ ULONG Flags, + _In_ ULONGLONG Page + ); + NTSTATUS MmMdCopyList ( _In_ PBL_MEMORY_DESCRIPTOR_LIST DestinationList, diff --git a/reactos/boot/environ/lib/firmware/efi/firmware.c b/reactos/boot/environ/lib/firmware/efi/firmware.c index 48cdffb0793..e26ef18eb62 100644 --- a/reactos/boot/environ/lib/firmware/efi/firmware.c +++ b/reactos/boot/environ/lib/firmware/efi/firmware.c @@ -617,8 +617,8 @@ EfiFreePages ( OldMode = CurrentExecutionContext->Mode; if (OldMode != BlRealMode) { - /* FIXME: Not yet implemented */ - return STATUS_NOT_IMPLEMENTED; + /* Switch to real mode */ + BlpArchSwitchContext(BlProtectedMode); } /* Make the EFI call */ @@ -1118,13 +1118,18 @@ EfiAllocatePages ( { BL_ARCH_MODE OldMode; EFI_STATUS EfiStatus; + PHYSICAL_ADDRESS MemoryPhysical; /* Are we in protected mode? */ OldMode = CurrentExecutionContext->Mode; if (OldMode != BlRealMode) { - /* FIXME: Not yet implemented */ - return STATUS_NOT_IMPLEMENTED; + /* Translate output address */ + BlMmTranslateVirtualAddress(Memory, &MemoryPhysical); + Memory = (EFI_PHYSICAL_ADDRESS*)MemoryPhysical.LowPart; + + /* Switch to real mode */ + BlpArchSwitchContext(BlProtectedMode); } /* Make the EFI call */ @@ -1387,7 +1392,7 @@ MmFwGetMemoryMap ( BL_LIBRARY_PARAMETERS LibraryParameters = BlpLibraryParameters; BOOLEAN UseEfiBuffer, HaveRamDisk; NTSTATUS Status; - ULONGLONG Pages, StartPage, EndPage; + ULONGLONG Pages, StartPage, EndPage, EfiBufferPage; UINTN EfiMemoryMapSize, MapKey, DescriptorSize, DescriptorVersion; EFI_PHYSICAL_ADDRESS EfiBuffer = 0; EFI_MEMORY_DESCRIPTOR* EfiMemoryMap; @@ -1650,9 +1655,8 @@ MmFwGetMemoryMap ( /* Check if this region is currently free RAM */ if (Descriptor->Type == BlConventionalMemory) { - /* Set the reserved flag on the descriptor */ - EfiPrintf(L"Adding magic flag\r\n"); - Descriptor->Flags |= BlMemoryReserved; + /* Set the appropriate flag on the descriptor */ + Descriptor->Flags |= BlMemoryBelow1MB; } /* Add this descriptor into the list */ @@ -1695,9 +1699,8 @@ MmFwGetMemoryMap ( /* Check if this region is currently free RAM below 1MB */ if ((Descriptor->Type == BlConventionalMemory) && (EndPage <= 0x100)) { - /* Set the reserved flag on the descriptor */ - EfiPrintf(L"Adding magic flag\r\n"); - Descriptor->Flags |= BlMemoryReserved; + /* Set the appropriate flag on the descriptor */ + Descriptor->Flags |= BlMemoryBelow1MB; } /* Add the descriptor to the list, requesting coalescing as asked */ @@ -1718,8 +1721,66 @@ LoopAgain: EfiMemoryMap = (PVOID)((ULONG_PTR)EfiMemoryMap + DescriptorSize); } - /* FIXME: @TODO: Mark the EfiBuffer as free, since we're about to free it */ - /* For now, just "leak" the 1-2 pages... */ + /* Check if we are using the local UEFI buffer */ + if (!UseEfiBuffer) + { + goto Quickie; + } + + /* Free the EFI buffer */ + Status = EfiFreePages(Pages, EfiBuffer); + if (!NT_SUCCESS(Status)) + { + /* Keep the pages marked 'in use' and fake success */ + Status = STATUS_SUCCESS; + goto Quickie; + } + + /* Get the base page of the EFI buffer */ + EfiBufferPage = EfiBuffer >> PAGE_SHIFT; + Pages = (EfiBufferPage + Pages) - EfiBufferPage; + + /* Don't try freeing below */ + EfiBuffer = 0; + + /* Find the current descriptor for the allocation */ + Descriptor = MmMdFindDescriptorFromMdl(MemoryMap, + BL_MM_REMOVE_PHYSICAL_REGION_FLAG, + EfiBufferPage); + if (!Descriptor) + { + Status = STATUS_UNSUCCESSFUL; + goto Quickie; + } + + /* Convert it to a free descriptor */ + Descriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags, + BlConventionalMemory, + EfiBufferPage, + 0, + Pages); + if (!Descriptor) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto Quickie; + } + + /* Remove the region from the memory map */ + Status = MmMdRemoveRegionFromMdlEx(MemoryMap, + BL_MM_REMOVE_PHYSICAL_REGION_FLAG, + EfiBufferPage, + Pages, + NULL); + if (!NT_SUCCESS(Status)) + { + MmMdFreeDescriptor(Descriptor); + goto Quickie; + } + + /* Add it back as free memory */ + Status = MmMdAddDescriptorToList(MemoryMap, + Descriptor, + BL_MM_ADD_DESCRIPTOR_COALESCE_FLAG); Quickie: /* Free the EFI buffer, if we had one */ diff --git a/reactos/boot/environ/lib/mm/descriptor.c b/reactos/boot/environ/lib/mm/descriptor.c index c2522bc1687..bfb8c374651 100644 --- a/reactos/boot/environ/lib/mm/descriptor.c +++ b/reactos/boot/environ/lib/mm/descriptor.c @@ -1073,7 +1073,7 @@ MmMdFindSatisfyingRegion ( } /* Bail out if the allocation flags don't match */ - if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryReserved | BlMemoryUnknown))) + if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryBelow1MB | BlMemoryUnknown))) { //EfiPrintf(L"Incorrect memory allocation flags\r\n"); return FALSE; diff --git a/reactos/boot/environ/lib/mm/mm.c b/reactos/boot/environ/lib/mm/mm.c index e10444167d5..d0dbe991c49 100644 --- a/reactos/boot/environ/lib/mm/mm.c +++ b/reactos/boot/environ/lib/mm/mm.c @@ -348,7 +348,6 @@ BlpMmInitialize ( LibraryParameters->MinimumAllocationCount); if (!NT_SUCCESS(Status)) { - EfiPrintf(L"PA Mm init failed: %lx\r\n", Status); goto Quickie; } diff --git a/reactos/boot/environ/lib/mm/pagealloc.c b/reactos/boot/environ/lib/mm/pagealloc.c index 22b926af6d4..1ca2652da27 100644 --- a/reactos/boot/environ/lib/mm/pagealloc.c +++ b/reactos/boot/environ/lib/mm/pagealloc.c @@ -543,7 +543,7 @@ MmPaInitialize ( { /* Remove this region from our free memory MDL */ Status = MmMdRemoveRegionFromMdlEx(&MmMdlUnmappedUnallocated, - 0x40000000, + BL_MM_REMOVE_PHYSICAL_REGION_FLAG, Descriptor->BasePage, Descriptor->PageCount, NULL);