mirror of
https://github.com/reactos/reactos.git
synced 2024-09-19 17:21:14 +00:00
321bcc056d
svn path=/branches/GSoC_2016/AHCI/; revision=71203
624 lines
21 KiB
C
624 lines
21 KiB
C
/*
|
|
* COPYRIGHT: See COPYING.ARM in the top level directory
|
|
* PROJECT: ReactOS UEFI Boot Library
|
|
* FILE: boot/environ/lib/mm/pagealloc.c
|
|
* PURPOSE: Boot Library Memory Manager Page Allocator
|
|
* PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
|
|
*/
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
#include "bl.h"
|
|
#include "bcd.h"
|
|
|
|
typedef struct _BL_PA_REQUEST
|
|
{
|
|
BL_ADDRESS_RANGE BaseRange;
|
|
BL_ADDRESS_RANGE VirtualRange;
|
|
ULONG Type;
|
|
ULONGLONG Pages;
|
|
ULONG MemoryType;
|
|
ULONG Alignment;
|
|
ULONG Flags;
|
|
} BL_PA_REQUEST, *PBL_PA_REQUEST;
|
|
|
|
/* DATA VARIABLES ************************************************************/
|
|
|
|
ULONGLONG PapMaximumPhysicalPage, PapMinimumPhysicalPage;
|
|
|
|
ULONG PapMinimumAllocationCount;
|
|
|
|
BOOLEAN PapInitializationStatus;
|
|
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlBadMemory;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlCompleteBadMemory;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlFreeVirtual;
|
|
BL_MEMORY_DESCRIPTOR_LIST MmMdlMappingTrackers;
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
NTSTATUS
|
|
BlpMmInitializeConstraints (
|
|
VOID
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ULONGLONG LowestAddressValid, HighestAddressValid;
|
|
|
|
/* Check for LOWMEM */
|
|
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
|
|
BcdLibraryInteger_AvoidLowPhysicalMemory,
|
|
&LowestAddressValid);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
EfiPrintf(L"/LOWMEM not supported\r\n");
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/* Check for MAXMEM */
|
|
Status = BlGetBootOptionInteger(BlpApplicationEntry.BcdData,
|
|
BcdLibraryInteger_TruncatePhysicalMemory,
|
|
&HighestAddressValid);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
EfiPrintf(L"/MAXMEM not supported\r\n");
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/* Return back to the caller */
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
MmPapAllocateRegionFromMdl (
|
|
_In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
|
|
_Out_opt_ PBL_MEMORY_DESCRIPTOR Descriptor,
|
|
_In_ PBL_MEMORY_DESCRIPTOR_LIST CurrentList,
|
|
_In_ PBL_PA_REQUEST Request,
|
|
_In_ BL_MEMORY_TYPE Type
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
BL_MEMORY_DESCRIPTOR LocalDescriptor = {{0}};
|
|
PBL_MEMORY_DESCRIPTOR FoundDescriptor, TempDescriptor;
|
|
PLIST_ENTRY ListHead, NextEntry;
|
|
BOOLEAN TopDown, GotFwPages;
|
|
EFI_PHYSICAL_ADDRESS EfiAddress;
|
|
ULONGLONG LocalEndPage, FoundEndPage, LocalVirtualEndPage;
|
|
|
|
/* Check if any parameters were not passed in correctly */
|
|
if ( !(CurrentList) || !(Request) || (!(NewList) && !(Descriptor)))
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
/* Set failure by default */
|
|
Status = STATUS_NO_MEMORY;
|
|
|
|
/* Take the head and next entry in the list, as appropriate */
|
|
ListHead = CurrentList->First;
|
|
if (Request->Type & BL_MM_REQUEST_TOP_DOWN_TYPE)
|
|
{
|
|
NextEntry = ListHead->Blink;
|
|
TopDown = TRUE;
|
|
}
|
|
else
|
|
{
|
|
NextEntry = ListHead->Flink;
|
|
TopDown = FALSE;
|
|
}
|
|
|
|
/* Loop through the list */
|
|
GotFwPages = FALSE;
|
|
while (NextEntry != ListHead)
|
|
{
|
|
/* Grab a descriptor */
|
|
FoundDescriptor = CONTAINING_RECORD(NextEntry,
|
|
BL_MEMORY_DESCRIPTOR,
|
|
ListEntry);
|
|
|
|
/* See if it matches the request */
|
|
if (MmMdFindSatisfyingRegion(FoundDescriptor,
|
|
&LocalDescriptor,
|
|
Request->Pages,
|
|
&Request->BaseRange,
|
|
&Request->VirtualRange,
|
|
TopDown,
|
|
Request->MemoryType,
|
|
Request->Flags,
|
|
Request->Alignment))
|
|
{
|
|
/* It does, get out */
|
|
break;
|
|
}
|
|
|
|
/* It doesn't, move to the next appropriate entry */
|
|
if (TopDown)
|
|
{
|
|
NextEntry = NextEntry->Blink;
|
|
}
|
|
else
|
|
{
|
|
NextEntry = NextEntry->Flink;
|
|
}
|
|
}
|
|
|
|
/* Check if we exhausted the list */
|
|
if (NextEntry == ListHead)
|
|
{
|
|
EfiPrintf(L"No matching memory found\r\n");
|
|
return Status;
|
|
}
|
|
|
|
/* Copy all the flags that are not request flag */
|
|
LocalDescriptor.Flags = (Request->Flags & 0xFFFF0000) |
|
|
(LocalDescriptor.Flags & 0x0000FFFF);
|
|
|
|
/* Are we using the physical memory list, and are we OK with using firmware? */
|
|
if ((CurrentList == &MmMdlUnmappedUnallocated) &&
|
|
!((Request->Flags & BlMemoryNonFirmware) ||
|
|
(LocalDescriptor.Flags & BlMemoryNonFirmware)))
|
|
{
|
|
/* Allocate the requested address from EFI */
|
|
EfiAddress = LocalDescriptor.BasePage << PAGE_SHIFT;
|
|
Status = EfiAllocatePages(AllocateAddress,
|
|
(ULONG)LocalDescriptor.PageCount,
|
|
&EfiAddress);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
EfiPrintf(L"EFI memory allocation failure\r\n");
|
|
return Status;
|
|
}
|
|
|
|
/* Remember we got memory from EFI */
|
|
GotFwPages = TRUE;
|
|
}
|
|
|
|
/* Remove the descriptor from the original list it was on */
|
|
MmMdRemoveDescriptorFromList(CurrentList, FoundDescriptor);
|
|
|
|
/* Are we allocating from the virtual memory list? */
|
|
if (CurrentList == &MmMdlMappedUnallocated)
|
|
{
|
|
EfiPrintf(L"Virtual memory not yet supported\r\n");
|
|
return STATUS_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
/* Does the memory we received not exactly fall onto the beginning of its descriptor? */
|
|
if (LocalDescriptor.BasePage != FoundDescriptor->BasePage)
|
|
{
|
|
EfiPrintf(L"Local Page: %08I64X Found Page: %08I64X\r\n", LocalDescriptor.BasePage, FoundDescriptor->BasePage);
|
|
TempDescriptor = MmMdInitByteGranularDescriptor(FoundDescriptor->Flags,
|
|
FoundDescriptor->Type,
|
|
FoundDescriptor->BasePage,
|
|
FoundDescriptor->VirtualPage,
|
|
LocalDescriptor.BasePage -
|
|
FoundDescriptor->BasePage);
|
|
Status = MmMdAddDescriptorToList(CurrentList, TempDescriptor, 0);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
/* Does the memory we received not exactly fall onto the end of its descriptor? */
|
|
LocalEndPage = LocalDescriptor.PageCount + LocalDescriptor.BasePage;
|
|
FoundEndPage = FoundDescriptor->PageCount + FoundDescriptor->BasePage;
|
|
LocalVirtualEndPage = LocalDescriptor.VirtualPage ?
|
|
LocalDescriptor.VirtualPage + LocalDescriptor.PageCount : 0;
|
|
if (LocalEndPage != FoundEndPage)
|
|
{
|
|
EfiPrintf(L"Local Page: %08I64X Found Page: %08I64X\r\n", LocalEndPage, FoundEndPage);
|
|
TempDescriptor = MmMdInitByteGranularDescriptor(FoundDescriptor->Flags,
|
|
FoundDescriptor->Type,
|
|
LocalEndPage,
|
|
LocalVirtualEndPage,
|
|
FoundEndPage - LocalEndPage);
|
|
Status = MmMdAddDescriptorToList(CurrentList, TempDescriptor, 0);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return Status;
|
|
}
|
|
}
|
|
|
|
/* We got the memory we needed */
|
|
Status = STATUS_SUCCESS;
|
|
|
|
/* Are we supposed to insert it into a new list? */
|
|
if (NewList)
|
|
{
|
|
/* Copy the allocated region descriptor into the one we found */
|
|
FoundDescriptor->BaseAddress = LocalDescriptor.BaseAddress;
|
|
FoundDescriptor->VirtualPage = LocalDescriptor.VirtualPage;
|
|
FoundDescriptor->PageCount = LocalDescriptor.PageCount;
|
|
FoundDescriptor->Type = Type;
|
|
FoundDescriptor->Flags = LocalDescriptor.Flags;
|
|
|
|
/* Remember if it came from EFI */
|
|
if (GotFwPages)
|
|
{
|
|
FoundDescriptor->Flags |= BlMemoryFirmware;
|
|
}
|
|
|
|
/* Add the descriptor to the requested list */
|
|
Status = MmMdAddDescriptorToList(NewList, FoundDescriptor, 0);
|
|
}
|
|
else
|
|
{
|
|
/* Free the descriptor, nobody wants to know about it anymore */
|
|
MmMdFreeDescriptor(FoundDescriptor);
|
|
}
|
|
|
|
/* Return the allocation region back */
|
|
RtlCopyMemory(Descriptor, &LocalDescriptor, sizeof(LocalDescriptor));
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
MmPaAllocatePages (
|
|
_In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
|
|
_In_ PBL_MEMORY_DESCRIPTOR Descriptor,
|
|
_In_ PBL_MEMORY_DESCRIPTOR_LIST CurrentList,
|
|
_In_ PBL_PA_REQUEST Request,
|
|
_In_ BL_MEMORY_TYPE MemoryType
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
/* Heap and page directory/table pages have a special flag */
|
|
if ((MemoryType >= BlLoaderHeap) && (MemoryType <= BlLoaderReferencePage))
|
|
{
|
|
Request->Flags |= BlMemorySpecial;
|
|
}
|
|
|
|
/* Try to find a free region of RAM matching this range and request */
|
|
Request->MemoryType = BlConventionalMemory;
|
|
Status = MmPapAllocateRegionFromMdl(NewList,
|
|
Descriptor,
|
|
CurrentList,
|
|
Request,
|
|
MemoryType);
|
|
if (Status == STATUS_NOT_FOUND)
|
|
{
|
|
/* Need to re-synchronize the memory map and check other lists */
|
|
EfiPrintf(L"No RAM found -- backup plan not yet implemented\r\n");
|
|
}
|
|
|
|
/* Did we get the region we wanted? */
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
/* All good, return back */
|
|
return Status;
|
|
}
|
|
|
|
/* Nope, we have to hunt for it elsewhere */
|
|
EfiPrintf(L"TODO\r\n");
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
MmPapAllocatePhysicalPagesInRange (
|
|
_Inout_ PPHYSICAL_ADDRESS BaseAddress,
|
|
_In_ BL_MEMORY_TYPE MemoryType,
|
|
_In_ ULONGLONG Pages,
|
|
_In_ ULONG Attributes,
|
|
_In_ ULONG Alignment,
|
|
_In_ PBL_MEMORY_DESCRIPTOR_LIST NewList,
|
|
_In_opt_ PBL_ADDRESS_RANGE Range,
|
|
_In_ ULONG RangeType
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
BL_PA_REQUEST Request;
|
|
BL_MEMORY_DESCRIPTOR Descriptor;
|
|
|
|
/* Increase nesting depth */
|
|
++MmDescriptorCallTreeCount;
|
|
|
|
/* Bail out if no address was specified */
|
|
if (!BaseAddress)
|
|
{
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto Quickie;
|
|
}
|
|
|
|
/* Bail out if no page count was passed in, or a bad list was specified */
|
|
if (!(Pages) ||
|
|
((NewList != &MmMdlUnmappedAllocated) &&
|
|
(NewList != &MmMdlPersistentMemory)))
|
|
{
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto Quickie;
|
|
}
|
|
|
|
/* Bail out if the passed in range is invalid */
|
|
if ((Range) && (Range->Minimum >= Range->Maximum))
|
|
{
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto Quickie;
|
|
}
|
|
|
|
/* Adjust alignment as needed */
|
|
if (!Alignment)
|
|
{
|
|
Alignment = 1;
|
|
}
|
|
|
|
/* Clear the virtual range */
|
|
Request.VirtualRange.Minimum = 0;
|
|
Request.VirtualRange.Maximum = 0;
|
|
|
|
/* Check if a fixed allocation was requested*/
|
|
if (Attributes & BlMemoryFixed)
|
|
{
|
|
/* Force the only available range to be the passed in address */
|
|
Request.BaseRange.Minimum = BaseAddress->QuadPart >> PAGE_SHIFT;
|
|
Request.BaseRange.Maximum = Request.BaseRange.Minimum + Pages - 1;
|
|
}
|
|
else if (Range)
|
|
{
|
|
/* Otherwise, a manual range was specified, use it */
|
|
Request.BaseRange.Minimum = Range->Minimum >> PAGE_SHIFT;
|
|
Request.BaseRange.Maximum = Request.BaseRange.Minimum +
|
|
(Range->Maximum >> PAGE_SHIFT) - 1;
|
|
}
|
|
else
|
|
{
|
|
/* Otherwise, use any possible range of pages */
|
|
Request.BaseRange.Minimum = PapMinimumPhysicalPage;
|
|
Request.BaseRange.Maximum = MAXULONG >> PAGE_SHIFT;
|
|
}
|
|
|
|
/* Check if no type was specified, or if it was invalid */
|
|
if (!(RangeType) ||
|
|
(RangeType & ~(BL_MM_REQUEST_TOP_DOWN_TYPE | BL_MM_REQUEST_DEFAULT_TYPE)))
|
|
{
|
|
/* Use default type */
|
|
Request.Type = BL_MM_REQUEST_DEFAULT_TYPE;
|
|
}
|
|
else
|
|
{
|
|
/* Use the requested type */
|
|
Request.Type = RangeType;
|
|
}
|
|
|
|
/* Capture the other request parameters */
|
|
Request.Alignment = Alignment;
|
|
Request.Pages = Pages;
|
|
Request.Flags = Attributes;
|
|
Status = MmPaAllocatePages(NewList,
|
|
&Descriptor,
|
|
&MmMdlUnmappedUnallocated,
|
|
&Request,
|
|
MemoryType);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
/* We got a descriptor back, return its address */
|
|
BaseAddress->QuadPart = Descriptor.BasePage << PAGE_SHIFT;
|
|
}
|
|
|
|
Quickie:
|
|
/* Restore the nesting depth */
|
|
MmMdFreeGlobalDescriptors();
|
|
--MmDescriptorCallTreeCount;
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
MmPapAllocatePagesInRange (
|
|
_Inout_ PVOID* PhysicalAddress,
|
|
_In_ BL_MEMORY_TYPE MemoryType,
|
|
_In_ ULONGLONG Pages,
|
|
_In_ ULONG Attributes,
|
|
_In_ ULONG Alignment,
|
|
_In_opt_ PBL_ADDRESS_RANGE Range,
|
|
_In_ ULONG Type
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
PHYSICAL_ADDRESS BaseAddress;
|
|
|
|
/* Increment nesting depth */
|
|
++MmDescriptorCallTreeCount;
|
|
|
|
/* Check for missing parameters or invalid range */
|
|
if (!(PhysicalAddress) ||
|
|
!(Pages) ||
|
|
((Range) && (Range->Minimum >= Range->Maximum)))
|
|
{
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
goto Exit;
|
|
}
|
|
|
|
/* What translation mode are we using? */
|
|
if (MmTranslationType != BlNone)
|
|
{
|
|
/* We don't support virtual memory yet */
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
/* Check if this is a fixed allocation */
|
|
BaseAddress.QuadPart = (Attributes & BlMemoryFixed) ? (ULONG_PTR)*PhysicalAddress : 0;
|
|
|
|
/* Allocate the pages */
|
|
Status = MmPapAllocatePhysicalPagesInRange(&BaseAddress,
|
|
MemoryType,
|
|
Pages,
|
|
Attributes,
|
|
Alignment,
|
|
(&MmMdlMappedAllocated !=
|
|
&MmMdlPersistentMemory) ?
|
|
&MmMdlUnmappedAllocated :
|
|
&MmMdlMappedAllocated,
|
|
Range,
|
|
Type);
|
|
|
|
/* Return the allocated address */
|
|
*PhysicalAddress = (PVOID)BaseAddress.LowPart;
|
|
}
|
|
|
|
Exit:
|
|
/* Restore the nesting depth */
|
|
MmMdFreeGlobalDescriptors();
|
|
--MmDescriptorCallTreeCount;
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
MmPaInitialize (
|
|
__in PBL_MEMORY_DATA BootMemoryData,
|
|
__in ULONG MinimumAllocationCount
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG ExistingDescriptors, FinalOffset;
|
|
PBL_MEMORY_DESCRIPTOR Descriptor, NewDescriptor;
|
|
|
|
/* Initialize physical allocator variables */
|
|
PapMaximumPhysicalPage = 0xFFFFFFFFFFFFF;
|
|
PapMinimumAllocationCount = MinimumAllocationCount;
|
|
PapMinimumPhysicalPage = 0;
|
|
|
|
/* Initialize all the lists */
|
|
MmMdInitializeListHead(&MmMdlMappedAllocated);
|
|
MmMdInitializeListHead(&MmMdlMappedUnallocated);
|
|
MmMdInitializeListHead(&MmMdlFwAllocationTracker);
|
|
MmMdInitializeListHead(&MmMdlUnmappedAllocated);
|
|
MmMdInitializeListHead(&MmMdlReservedAllocated);
|
|
MmMdInitializeListHead(&MmMdlBadMemory);
|
|
MmMdInitializeListHead(&MmMdlTruncatedMemory);
|
|
MmMdInitializeListHead(&MmMdlPersistentMemory);
|
|
MmMdInitializeListHead(&MmMdlUnmappedUnallocated);
|
|
MmMdInitializeListHead(&MmMdlCompleteBadMemory);
|
|
|
|
/* Get the BIOS memory map */
|
|
Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated,
|
|
BL_MM_FLAG_USE_FIRMWARE_FOR_MEMORY_MAP_BUFFERS |
|
|
BL_MM_FLAG_REQUEST_COALESCING);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
#if 0
|
|
PLIST_ENTRY listHead, nextEntry;
|
|
|
|
/* Loop the NT firmware memory list */
|
|
EfiPrintf(L"NT MEMORY MAP\n\r\n");
|
|
listHead = &MmMdlUnmappedUnallocated.ListHead;
|
|
nextEntry = listHead->Flink;
|
|
while (listHead != nextEntry)
|
|
{
|
|
Descriptor = CONTAINING_RECORD(nextEntry, BL_MEMORY_DESCRIPTOR, ListEntry);
|
|
|
|
EfiPrintf(L"Type: %08lX Flags: %08lX Base: 0x%016I64X End: 0x%016I64X\r\n",
|
|
Descriptor->Type,
|
|
Descriptor->Flags,
|
|
Descriptor->BasePage << PAGE_SHIFT,
|
|
(Descriptor->BasePage + Descriptor->PageCount) << PAGE_SHIFT);
|
|
|
|
nextEntry = nextEntry->Flink;
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
* Because BL supports cross x86-x64 application launches and a LIST_ENTRY
|
|
* is of variable size, care must be taken here to ensure that we see a
|
|
* consistent view of descriptors. BL uses some offset magic to figure out
|
|
* where the data actually starts, since everything is ULONGLONG past the
|
|
* LIST_ENTRY itself
|
|
*/
|
|
FinalOffset = BootMemoryData->MdListOffset + BootMemoryData->DescriptorOffset;
|
|
Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)BootMemoryData + FinalOffset -
|
|
FIELD_OFFSET(BL_MEMORY_DESCRIPTOR, BasePage));
|
|
|
|
/* Scan all of them */
|
|
ExistingDescriptors = BootMemoryData->DescriptorCount;
|
|
while (ExistingDescriptors != 0)
|
|
{
|
|
/* Remove this region from our free memory MDL */
|
|
Status = MmMdRemoveRegionFromMdlEx(&MmMdlUnmappedUnallocated,
|
|
0x40000000,
|
|
Descriptor->BasePage,
|
|
Descriptor->PageCount,
|
|
NULL);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
/* Build a descriptor for it */
|
|
NewDescriptor = MmMdInitByteGranularDescriptor(Descriptor->Flags,
|
|
Descriptor->Type,
|
|
Descriptor->BasePage,
|
|
Descriptor->VirtualPage,
|
|
Descriptor->PageCount);
|
|
if (!NewDescriptor)
|
|
{
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
/* And add this region to the reserved & allocated MDL */
|
|
Status = MmMdAddDescriptorToList(&MmMdlReservedAllocated, NewDescriptor, 0);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return Status;
|
|
}
|
|
|
|
/* Move on to the next descriptor */
|
|
ExistingDescriptors--;
|
|
Descriptor = (PBL_MEMORY_DESCRIPTOR)((ULONG_PTR)Descriptor + BootMemoryData->DescriptorSize);
|
|
}
|
|
|
|
/* We are done, so check for any RAM constraints which will make us truncate memory */
|
|
Status = BlpMmInitializeConstraints();
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
/* The Page Allocator has initialized */
|
|
PapInitializationStatus = TRUE;
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
}
|
|
|
|
/* Return status */
|
|
return Status;
|
|
}
|
|
|
|
NTSTATUS
|
|
BlMmAllocatePhysicalPages(
|
|
_In_ PPHYSICAL_ADDRESS Address,
|
|
_In_ BL_MEMORY_TYPE MemoryType,
|
|
_In_ ULONGLONG PageCount,
|
|
_In_ ULONG Attributes,
|
|
_In_ ULONG Alignment
|
|
)
|
|
{
|
|
/* Call the physical allocator */
|
|
return MmPapAllocatePhysicalPagesInRange(Address,
|
|
MemoryType,
|
|
PageCount,
|
|
Attributes,
|
|
Alignment,
|
|
&MmMdlUnmappedAllocated,
|
|
NULL,
|
|
0);
|
|
}
|
|
|
|
NTSTATUS
|
|
BlMmFreePhysicalPages (
|
|
_In_ PHYSICAL_ADDRESS Address
|
|
)
|
|
{
|
|
/* Call the physical allocator */
|
|
EfiPrintf(L"Leaking memory!\r\n");
|
|
return STATUS_SUCCESS;
|
|
//return MmPapFreePhysicalPages(4, 0, Address);
|
|
}
|