BL_MEMORY_TYPE MemoryType;
PBL_MEMORY_DESCRIPTOR Descriptor;
BL_MEMORY_ATTR Attribute;
+ PVOID LibraryBuffer;
/* Initialize EFI memory map attributes */
EfiMemoryMapSize = MapKey = DescriptorSize = DescriptorVersion = 0;
if (Status != STATUS_BUFFER_TOO_SMALL)
{
/* This should've failed because our buffer was too small, nothing else */
- EfiPrintf(L"Got strange EFI status for memory map: %lx\r\n", Status);
if (NT_SUCCESS(Status))
{
Status = STATUS_UNSUCCESSFUL;
}
else
{
- /* We don't support this path yet */
- Status = STATUS_NOT_IMPLEMENTED;
+ /* Round the map to pages */
+ Pages = BYTES_TO_PAGES(EfiMemoryMapSize);
+
+ /* Allocate a large enough buffer */
+ Status = MmPapAllocatePagesInRange(&LibraryBuffer,
+ BlLoaderData,
+ Pages,
+ 0,
+ 0,
+ 0,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ EfiPrintf(L"Failed to allocate mapped VM for EFI map: %lx\r\n", Status);
+ goto Quickie;
+ }
+
+ /* Call EFI to get the memory map */
+ EfiMemoryMap = LibraryBuffer;
+ Status = EfiGetMemoryMap(&EfiMemoryMapSize,
+ LibraryBuffer,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion);
}
/* So far so good? */
EfiFreePages(Pages, EfiBuffer);
}
+ /* Free the library-allocated buffer, if we had one */
+ if (LibraryBuffer != 0)
+ {
+ MmPapFreePages(LibraryBuffer, BL_MM_INCLUDE_MAPPED_ALLOCATED);
+ }
+
/* On failure, free the memory map if one was passed in */
if (!NT_SUCCESS(Status) && (MemoryMap != NULL))
{
ULONGLONG LocalEndPage, FoundEndPage, LocalVirtualEndPage;
/* Check if any parameters were not passed in correctly */
- if ( !(CurrentList) || !(Request) || (!(NewList) && !(Descriptor)))
+ if (!(CurrentList) || !(Request) || (!(NewList) && !(Descriptor)))
{
return STATUS_INVALID_PARAMETER;
}
return Status;
}
- /* Nope, we have to hunt for it elsewhere */
- EfiPrintf(L"TODO\r\n");
+ /* Are we failing due to some attributes? */
+ if (Request->Flags & BlMemoryValidAllocationAttributeMask)
+ {
+ EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+ EfiStall(1000000);
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* Nope, just fail the entire call */
return Status;
}
{
NTSTATUS Status;
PHYSICAL_ADDRESS BaseAddress;
+ BL_PA_REQUEST Request;
+ PBL_MEMORY_DESCRIPTOR_LIST List;
+ BL_MEMORY_DESCRIPTOR Descriptor;
/* Increment nesting depth */
++MmDescriptorCallTreeCount;
+ /* Default list */
+ List = &MmMdlMappedAllocated;
+
/* Check for missing parameters or invalid range */
if (!(PhysicalAddress) ||
!(Pages) ||
/* What translation mode are we using? */
if (MmTranslationType != BlNone)
{
- /* We don't support virtual memory yet @TODO */
- EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
- EfiStall(1000000);
- Status = STATUS_NOT_IMPLEMENTED;
- goto Exit;
+ /* Use 1 page alignment if none was requested */
+ if (!Alignment)
+ {
+ Alignment = 1;
+ }
+
+ /* Check if we got a range */
+ if (Range)
+ {
+ /* We don't support virtual memory yet @TODO */
+ EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+ EfiStall(1000000);
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Exit;
+ }
+ else
+ {
+ Request.BaseRange.Minimum = PapMinimumPhysicalPage;
+ Request.BaseRange.Maximum = (4 * 1024 * 1024) >> PAGE_SHIFT;
+ }
+
+ /* Check if a fixed allocation was requested */
+ if (Attributes & BlMemoryFixed)
+ {
+ /* We don't support virtual memory yet @TODO */
+ EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+ EfiStall(1000000);
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Exit;
+ }
+ else
+ {
+ /* Check if non-fixed was specifically requested */
+ if (Attributes & BlMemoryNonFixed)
+ {
+ /* We don't support virtual memory yet @TODO */
+ EfiPrintf(L"not yet implemented in %S\r\n", __FUNCTION__);
+ EfiStall(1000000);
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Exit;
+ }
+
+ /* Set the virtual address range */
+ Request.VirtualRange.Minimum = 0;
+ Request.VirtualRange.Maximum = (4 * 1024 * 1024) >> PAGE_SHIFT;
+ }
+
+ /* Check what type of allocation was requested */
+ if (Type)
+ {
+ /* Save it */
+ Request.Type = Type;
+
+ /* If it was invalid, set the default */
+ if (Type & ~(BL_MM_REQUEST_DEFAULT_TYPE | BL_MM_REQUEST_TOP_DOWN_TYPE))
+ {
+ Request.Type = BL_MM_REQUEST_DEFAULT_TYPE;
+ }
+ }
+ else
+ {
+ /* Set the default */
+ Request.Type = BL_MM_REQUEST_DEFAULT_TYPE;
+ }
+
+ /* Fill out the request of the request */
+ Request.Flags = Attributes;
+ Request.Alignment = Alignment;
+ Request.Pages = Pages;
+
+ /* Try to allocate the pages */
+ Status = MmPaAllocatePages(List,
+ &Descriptor,
+ &MmMdlMappedUnallocated,
+ &Request,
+ MemoryType);
+ if (!NT_SUCCESS(Status))
+ {
+ /* We don't support virtual memory yet @TODO */
+ EfiPrintf(L"Need to extend PA allocator\r\n");
+ EfiStall(1000000);
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Exit;
+ }
+
+ /* Return the allocated address */
+ *PhysicalAddress = (PVOID)((ULONG_PTR)Descriptor.VirtualPage << PAGE_SHIFT);
}
else
{