[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
This commit is contained in:
Alex Ionescu 2017-02-06 03:14:14 +00:00
parent 88dcf31856
commit 27f761d0a3
6 changed files with 87 additions and 20 deletions

View file

@ -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,

View file

@ -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,

View file

@ -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 */

View file

@ -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;

View file

@ -348,7 +348,6 @@ BlpMmInitialize (
LibraryParameters->MinimumAllocationCount);
if (!NT_SUCCESS(Status))
{
EfiPrintf(L"PA Mm init failed: %lx\r\n", Status);
goto Quickie;
}

View file

@ -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);