164 lines
3.7 KiB
C
164 lines
3.7 KiB
C
/*++
|
|
|
|
Copyright (c) 2024, Quinn Stephens.
|
|
Provided under the BSD 3-Clause license.
|
|
|
|
Module Name:
|
|
|
|
mmpa.c
|
|
|
|
Abstract:
|
|
|
|
Provides memory manager page routines.
|
|
|
|
--*/
|
|
|
|
#include "bootlib.h"
|
|
#include "mm.h"
|
|
|
|
ULONG PapMinimumAllocationCount;
|
|
ULONGLONG PapMinimumPhysicalPage;
|
|
ULONGLONG PapMaximumPhysicalPage;
|
|
|
|
MEMORY_DESCRIPTOR_LIST MmMdlFwAllocationTracker;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlBadMemory;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlTruncatedMemory;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlPersistentMemory;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlReservedAllocated;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlMappedAllocated;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlMappedUnallocated;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlUnmappedAllocated;
|
|
MEMORY_DESCRIPTOR_LIST MmMdlUnmappedUnallocated;
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
InitializeMdl (
|
|
IN PMEMORY_DESCRIPTOR_LIST Mdl
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes a MDL.
|
|
|
|
Arguments:
|
|
|
|
Mdl - Pointer to the MDL.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
Mdl->Head = NULL;
|
|
Mdl->Current = NULL;
|
|
Mdl->Type = MDL_TYPE_PHYSICAL;
|
|
}
|
|
|
|
NTSTATUS
|
|
MmPaInitialize (
|
|
IN PBOOT_MEMORY_INFO MemoryInfo,
|
|
IN ULONG MinimumAllocation
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Initializes the page allocator.
|
|
|
|
Arguments:
|
|
|
|
MemoryInfo - Pointer to the memory info structure.
|
|
|
|
MinimumAllocation - Minimum amount of pages to grow the pool by at a time.
|
|
|
|
Return Value:
|
|
|
|
STATUS_SUCCESS if successful,
|
|
STATUS_INVALID_PARAMETER if regions in MemoryInfo could not be removed.
|
|
STATUS_NO_MEMORY if a new descriptor cannot be allocated.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
PMEMORY_DESCRIPTOR Descriptor, NewDescriptor;
|
|
|
|
PapMinimumAllocationCount = MinimumAllocation;
|
|
PapMinimumPhysicalPage = 1;
|
|
PapMaximumPhysicalPage = MAXULONGLONG >> PAGE_SHIFT;
|
|
|
|
//
|
|
// Initialize Memory Descriptor Lists
|
|
//
|
|
InitializeMdl(&MmMdlFwAllocationTracker);
|
|
InitializeMdl(&MmMdlBadMemory);
|
|
InitializeMdl(&MmMdlTruncatedMemory);
|
|
InitializeMdl(&MmMdlPersistentMemory);
|
|
InitializeMdl(&MmMdlReservedAllocated);
|
|
InitializeMdl(&MmMdlMappedAllocated);
|
|
InitializeMdl(&MmMdlMappedUnallocated);
|
|
InitializeMdl(&MmMdlUnmappedAllocated);
|
|
InitializeMdl(&MmMdlUnmappedUnallocated);
|
|
|
|
Status = MmFwGetMemoryMap(&MmMdlUnmappedUnallocated, 0x03);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
//
|
|
// Remove regions described in MemoryInfo from the
|
|
// MDL the memory manager will use for allocation.
|
|
//
|
|
Descriptor = (PMEMORY_DESCRIPTOR)((PUCHAR)MemoryInfo + MemoryInfo->MdlOffset);
|
|
for (ULONG DescriptorCount = MemoryInfo->DescriptorCount;
|
|
DescriptorCount > 0;
|
|
DescriptorCount--) {
|
|
//
|
|
// Remove from the usable MDL.
|
|
//
|
|
Status = MmMdRemoveRegionFromMdl(
|
|
&MmMdlUnmappedUnallocated,
|
|
Descriptor->FirstPage,
|
|
Descriptor->PageCount,
|
|
MDL_OPERATION_FLAGS_PHYSICAL
|
|
);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
//
|
|
// ... and add to the reserved MDL.
|
|
//
|
|
NewDescriptor = MmMdInitDescriptor(
|
|
Descriptor->FirstPage,
|
|
Descriptor->MappedFirstPage,
|
|
Descriptor->PageCount,
|
|
Descriptor->Attributes,
|
|
Descriptor->Type
|
|
);
|
|
if (NewDescriptor == NULL) {
|
|
return STATUS_NO_MEMORY;
|
|
}
|
|
|
|
Status = MmMdAddDescriptorToList(&MmMdlReservedAllocated, NewDescriptor, 0);
|
|
if (!NT_SUCCESS(Status)) {
|
|
MmMdFreeDescriptor(NewDescriptor);
|
|
return Status;
|
|
}
|
|
|
|
Descriptor = (PMEMORY_DESCRIPTOR)((PUCHAR)Descriptor + MemoryInfo->DescriptorSize);
|
|
}
|
|
|
|
Status = BlpMmInitializeConstraints();
|
|
if (!NT_SUCCESS(Status)) {
|
|
return Status;
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|