alcyone/BOOT/ENVIRON/LIB/MM/mmmd.c
Kaimakan71 2472e39635 [BOOT:LIB] More initialization and cleanup
Started BlpMmDestroy(), MmMdDestroy(), MmPaDestroy(),
EfiSetWatchdogTimer(), EfiOpenProtocol(), EfiConInExSetState(), and
BlDestroyLibrary().
Completed BlpFwInitialize().
Improved InitializeLibrary().
2024-10-06 13:50:21 -04:00

960 lines
23 KiB
C

/*++
Copyright (c) 2024, Quinn Stephens.
Provided under the BSD 3-Clause license.
Module Name:
mmmd.c
Abstract:
Provides memory descriptor routines.
--*/
#include <ntrtl.h>
#include "bootlib.h"
#include "mm.h"
#define MAX_STATIC_DESCRIPTOR_COUNT 1024
MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT];
PMEMORY_DESCRIPTOR MmGlobalMemoryDescriptors;
ULONG MmGlobalMemoryDescriptorCount, MmGlobalMemoryDescriptorsUsed;
PMEMORY_DESCRIPTOR MmDynamicMemoryDescriptors;
ULONG MmDynamicMemoryDescriptorCount, MmDynamicMemoryDescriptorsUsed;
#define MAX_PRECEDENCE_INDEX sizeof(MmPlatformMemoryTypePrecedence) / sizeof(MmPlatformMemoryTypePrecedence[0])
MEMORY_TYPE MmPlatformMemoryTypePrecedence[] = {
MEMORY_TYPE_RESERVED,
MEMORY_TYPE_UNUSABLE,
MEMORY_TYPE_MMIO,
MEMORY_TYPE_MMIO_PORT_SPACE,
MEMORY_TYPE_PAL_CODE,
MEMORY_TYPE_RUNTIME_SERVICES_CODE,
MEMORY_TYPE_RUNTIME_SERVICES_DATA,
MEMORY_TYPE_ACPI_NVS,
MEMORY_TYPE_ACPI_RECLAIM,
MEMORY_TYPE_PERSISTENT,
MEMORY_TYPE_BOOT_APPLICATION_2,
MEMORY_TYPE_BOOT_SERVICES,
MEMORY_TYPE_FREE,
MEMORY_TYPE_FREE_ZEROED
};
ULONG
GetPrecedenceIndex (
IN MEMORY_TYPE Type
)
/*++
Routine Description:
Finds the index into MmPlatformMemoryTypePrecedence for Type.
Arguments:
Type - The memory type.
Return Value:
The precedence index if found.
MAX_PRECEDENCE_INDEX if not found.
--*/
{
for (ULONG Index = 0;
Index < MAX_PRECEDENCE_INDEX;
Index++) {
if (MmPlatformMemoryTypePrecedence[Index] == Type) {
return Index;
}
}
return MAX_PRECEDENCE_INDEX;
}
BOOLEAN
MmMdpHasPrecedence (
IN MEMORY_TYPE TypeA,
IN MEMORY_TYPE TypeB
)
/*++
Routine Description:
Compares two memory types to determine which has precedence.
Arguments:
TypeA - Memory type A.
TypeB - Memory type B.
Return Value:
TRUE if TypeA has precedence over TypeB, or if neither has precedence.
FALSE if TypeB has precedence over TypeA.
--*/
{
ULONG ClassA, ClassB;
ULONG PrecedenceIndexA, PrecedenceIndexB;
if (TypeB == MEMORY_TYPE_FREE_ZEROED) {
return TRUE;
} else if (TypeA == MEMORY_TYPE_FREE_ZEROED) {
return FALSE;
} else if (TypeB == MEMORY_TYPE_FREE) {
return TRUE;
} else if (TypeA == MEMORY_TYPE_FREE) {
return FALSE;
}
ClassA = TypeA >> 28;
ClassB = TypeB >> 28;
if (ClassA != MEMORY_CLASS_APPLICATION
&& ClassA != MEMORY_CLASS_LIBRARY
&& ClassA != MEMORY_CLASS_SYSTEM) {
return TRUE;
} else if (ClassB != MEMORY_CLASS_APPLICATION
&& ClassB != MEMORY_CLASS_LIBRARY
&& ClassB != MEMORY_CLASS_SYSTEM) {
return FALSE;
}
if (ClassA != MEMORY_CLASS_SYSTEM) {
return (ClassB != MEMORY_CLASS_SYSTEM
&& (ClassA == MEMORY_CLASS_APPLICATION
|| ClassB != MEMORY_CLASS_APPLICATION)) ? TRUE:FALSE;
} else if (ClassB != MEMORY_CLASS_SYSTEM) {
return TRUE;
}
PrecedenceIndexA = GetPrecedenceIndex(TypeA);
if (PrecedenceIndexA == MAX_PRECEDENCE_INDEX) {
return TRUE;
}
PrecedenceIndexB = GetPrecedenceIndex(TypeB);
if (PrecedenceIndexB == MAX_PRECEDENCE_INDEX) {
return FALSE;
}
return PrecedenceIndexA <= PrecedenceIndexB ? TRUE:FALSE;
}
BOOLEAN
MmMdpTruncateDescriptor (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN PMEMORY_DESCRIPTOR Descriptor,
IN ULONG Flags
)
/*++
Routine Description:
Trunactes a memory descriptor that overlaps
with adjacent descriptors.
Arguments:
Mdl - The MDL containing Descriptor.
Descriptor - The descriptor to truncate.
Return Value:
TRUE if Descriptor was deleted from Mdl.
--*/
{
NTSTATUS Status;
PMEMORY_DESCRIPTOR PrevDescriptor, NextDescriptor, NewDescriptor;
ULONGLONG DescriptorEnd, PrevDescriptorEnd, NextDescriptorEnd;
ULONGLONG MappedFirstPage;
ULONGLONG Change;
PrevDescriptor = (PMEMORY_DESCRIPTOR)Descriptor->ListEntry.Blink;
NextDescriptor = (PMEMORY_DESCRIPTOR)Descriptor->ListEntry.Flink;
DescriptorEnd = Descriptor->FirstPage + Descriptor->PageCount;
PrevDescriptorEnd = PrevDescriptor->FirstPage + PrevDescriptor->PageCount;
NextDescriptorEnd = NextDescriptor->FirstPage + NextDescriptor->PageCount;
//
// Check if overlapping with previous descriptor.
//
if (Descriptor->ListEntry.Blink != Mdl->Head && Descriptor->FirstPage < PrevDescriptorEnd) {
if (MmMdpHasPrecedence(Descriptor->Type, PrevDescriptor->Type)) {
PrevDescriptor->PageCount = Descriptor->FirstPage - PrevDescriptor->FirstPage;
if (DescriptorEnd < PrevDescriptorEnd) {
if (PrevDescriptor->MappedFirstPage) {
MappedFirstPage = PrevDescriptor->MappedFirstPage + DescriptorEnd - PrevDescriptor->FirstPage;
} else {
MappedFirstPage = 0;
}
NewDescriptor = MmMdInitDescriptor(
DescriptorEnd,
MappedFirstPage,
PrevDescriptorEnd - DescriptorEnd,
PrevDescriptor->Attributes,
PrevDescriptor->Type
);
if (NewDescriptor != NULL) {
Status = MmMdAddDescriptorToList(Mdl, NewDescriptor, Flags);
if (!NT_SUCCESS(Status)) {
MmMdFreeDescriptor(NewDescriptor);
}
}
}
//
// Delete and free the previous
// descriptor if it is now empty.
//
if (PrevDescriptor->PageCount == 0) {
MmMdRemoveDescriptorFromList(Mdl, PrevDescriptor);
MmMdFreeDescriptor(PrevDescriptor);
}
} else {
//
// Remove if completely overlapping.
//
if (DescriptorEnd <= PrevDescriptorEnd) {
MmMdRemoveDescriptorFromList(Mdl, Descriptor);
MmMdFreeDescriptor(Descriptor);
return TRUE;
}
//
// Otherwise, move the descriptor.
//
Change = PrevDescriptorEnd - Descriptor->FirstPage;
Descriptor->FirstPage += Change;
Descriptor->PageCount -= Change;
if (Descriptor->MappedFirstPage) {
Descriptor->MappedFirstPage += Change;
}
}
}
//
// Check if overlapping with next descriptor.
//
if (Descriptor->ListEntry.Flink != Mdl->Head && NextDescriptor->FirstPage < DescriptorEnd) {
if (MmMdpHasPrecedence(NextDescriptor->Type, Descriptor->Type)) {
Descriptor->PageCount = NextDescriptor->FirstPage - Descriptor->FirstPage;
if (NextDescriptorEnd < DescriptorEnd) {
if (Descriptor->MappedFirstPage) {
MappedFirstPage = Descriptor->MappedFirstPage + NextDescriptorEnd - Descriptor->FirstPage;
} else {
MappedFirstPage = 0;
}
NewDescriptor = MmMdInitDescriptor(
NextDescriptorEnd,
MappedFirstPage,
DescriptorEnd - NextDescriptorEnd,
Descriptor->Attributes,
Descriptor->Type
);
if (NewDescriptor != NULL) {
Status = MmMdAddDescriptorToList(Mdl, NewDescriptor, Flags);
if (!NT_SUCCESS(Status)) {
MmMdFreeDescriptor(NewDescriptor);
}
}
}
//
// Delete and free the previous
// descriptor if it is now empty.
//
if (Descriptor->PageCount == 0) {
MmMdRemoveDescriptorFromList(Mdl, Descriptor);
MmMdFreeDescriptor(Descriptor);
}
} else {
//
// Remove if completely overlapping.
//
if (NextDescriptorEnd <= DescriptorEnd) {
MmMdRemoveDescriptorFromList(Mdl, NextDescriptor);
MmMdFreeDescriptor(NextDescriptor);
return TRUE;
}
//
// Otherwise, move the next descriptor.
//
Change = DescriptorEnd - NextDescriptor->FirstPage;
NextDescriptor->FirstPage += Change;
NextDescriptor->PageCount -= Change;
if (NextDescriptor->MappedFirstPage) {
NextDescriptor->MappedFirstPage += Change;
}
}
}
return FALSE;
}
NTSTATUS
MmMdAddDescriptorToList (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN PMEMORY_DESCRIPTOR Descriptor,
IN ULONG Flags
)
/*++
Routine Description:
Adds a descriptor to a MDL.
Arguments:
Mdl - the MDL to add Descriptor to.
Descriptor - the descriptor to add to Mdl.
Return Value:
STATUS_SUCCESS if successful,
STATUS_INVALID_PARAMETER if Mdl or Descriptor are invalid.
--*/
{
PLIST_ENTRY Entry;
PMEMORY_DESCRIPTOR CurrentDescriptor;
if (Mdl == NULL || Descriptor == NULL) {
DebugPrint(L"MmMdAddDescriptorToList(): Mdl and/or Descriptor are NULL\r\n");
return STATUS_INVALID_PARAMETER;
}
if (Mdl->Current) {
if (Descriptor->FirstPage < ((PMEMORY_DESCRIPTOR)Mdl->Current)->FirstPage) {
Entry = Mdl->Head->Flink;
} else {
Entry = Mdl->Current;
}
} else {
Entry = Mdl->Head->Flink;
}
//
// Search for an existing descriptor for this region.
//
while (Entry != Mdl->Head) {
CurrentDescriptor = (PMEMORY_DESCRIPTOR)Entry;
if (
Descriptor->FirstPage >= CurrentDescriptor->FirstPage && (Descriptor->FirstPage != CurrentDescriptor->FirstPage
|| !MmMdpHasPrecedence(Descriptor->Type, CurrentDescriptor->Type))
) {
Entry = Entry->Flink;
continue;
}
//
// Insert descriptor into the list
// right before the current entry.
//
Descriptor->ListEntry.Blink = Entry->Blink;
Descriptor->ListEntry.Flink = Entry;
Entry->Blink->Flink = &Descriptor->ListEntry;
Entry->Blink = &Descriptor->ListEntry;
//
// Truncate overlapping descriptors
// into one larger descriptor.
//
if (Flags & MDL_OPERATION_FLAGS_TRUNCATE) {
MmMdpTruncateDescriptor(Mdl, Descriptor, Flags);
}
return STATUS_SUCCESS;
}
//
// If there are no existing descriptors for this region
// (or the list is empty), insert and truncate the descriptor.
//
InsertTailList(Mdl->Head, &Descriptor->ListEntry);
if (Flags & MDL_OPERATION_FLAGS_TRUNCATE) {
MmMdpTruncateDescriptor(Mdl, Descriptor, Flags);
}
return STATUS_SUCCESS;
}
VOID
MmMdRemoveDescriptorFromList (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN PMEMORY_DESCRIPTOR Descriptor
)
/*++
Routine Description:
Removes a descriptor from a MDL.
Arguments:
Mdl - MDL to remove Descriptor from.
Descriptor - Descriptor to remove from Mdl.
Return Value:
None.
--*/
{
PLIST_ENTRY Blink;
Blink = Descriptor->ListEntry.Blink;
RemoveEntryList(&Descriptor->ListEntry);
//
// Check if the removed descriptor was cached.
//
if (Mdl->Current != &Descriptor->ListEntry) {
return;
}
//
// Cache the previous descriptor if possible.
//
if (
(
(ULONG_PTR)Blink < (ULONG_PTR)MmGlobalMemoryDescriptors
|| (ULONG_PTR)Blink >= (ULONG_PTR)&MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorCount]
)
&& Blink != Mdl->Head
) {
Mdl->Current = Blink;
} else {
Mdl->Current = NULL;
}
}
PMEMORY_DESCRIPTOR
MmMdFindDescriptorFromMdl (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN ULONGLONG Page,
IN ULONG Flags
)
/*++
Routine Description:
Searches an MDL for the descriptor containing a page.
Arguments:
Mdl - The MDL to search.
Page - The page to search for.
Flags - MDL_OPERATION_FLAGS_*
MDL_OPERATION_FLAGS_PHYSICAL if Page is physical.
MDL_OPERATION_FLAGS_VIRTUAL if Page is virtual.
Return Value:
Pointer to the descriptor if successful.
NULL if an error occurs.
--*/
{
BOOLEAN Mapped;
PMEMORY_DESCRIPTOR Descriptor;
PLIST_ENTRY ListEntry;
ULONGLONG FirstPage;
Mapped = FALSE;
if (Flags & MDL_OPERATION_FLAGS_VIRTUAL) {
if (Mdl->Type == MDL_TYPE_PHYSICAL) {
Mapped = TRUE;
}
} else {
//
// If the MDL is virtual, the
// virtual flag must be set.
//
if (Mdl->Type == MDL_TYPE_VIRTUAL) {
DebugPrint(L"MmMdFindDescriptorFromMdl(): Flags is invalid\r\n");
return NULL;
}
}
//
// Check if the cached descriptor is in range.
//
if (!Mapped && Mdl->Current != NULL) {
Descriptor = (PMEMORY_DESCRIPTOR)Mdl->Current;
if (Page < Descriptor->FirstPage) {
ListEntry = Mdl->Head->Flink;
} else {
ListEntry = Mdl->Current;
}
} else {
ListEntry = Mdl->Head->Flink;
}
while (ListEntry != Mdl->Head) {
Descriptor = (PMEMORY_DESCRIPTOR)ListEntry;
if (Mapped) {
FirstPage = Descriptor->MappedFirstPage;
} else {
FirstPage = Descriptor->FirstPage;
}
//
// Check if this descriptor contains Page.
//
if ((!Mapped || FirstPage)
&& Page >= FirstPage
&& Page < FirstPage + Descriptor->PageCount) {
return Descriptor;
}
ListEntry = ListEntry->Flink;
}
return NULL;
}
NTSTATUS
MmMdRemoveRegionFromMdlEx (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN ULONGLONG RemoveStart,
IN ULONGLONG PageCount,
IN ULONG Flags,
OUT PMEMORY_DESCRIPTOR_LIST Unused
)
/*++
Routine Description:
Removes a region from a MDL.
Arguments:
Mdl - MDL to remove the region from.
RemoveStart - The first page in the region.
PageCount - The number of pages in the region.
Flags - MDL_OPERATION_FLAGS_*.
MDL_OPERATION_FLAGS_PHYSICAL if the region is physical.
MDL_OPERATION_FLAGS_VIRTUAL if the region is virtual.
Unused - Unused.
Return Value:
STATUS_SUCCESS if successful,
STATUS_INVALID_PARAMETER if Flags value is invalid.
--*/
{
NTSTATUS Status;
ULONG Offset;
BOOLEAN Mapped;
ULONGLONG RemoveEnd;
PLIST_ENTRY ListEntry;
ULONGLONG DescriptorStart, DescriptorEnd;
PMEMORY_DESCRIPTOR Descriptor, NewDescriptor;
(VOID)Unused;
Mapped = FALSE;
if (Flags & MDL_OPERATION_FLAGS_VIRTUAL) {
if (Mdl->Type == MDL_TYPE_PHYSICAL) {
Mapped = TRUE;
}
} else {
//
// If the MDL is virtual, the
// virtual flag must be set.
//
if (Mdl->Type == MDL_TYPE_VIRTUAL) {
DebugPrint(L"MmMdRemoveRegionFromMdlEx(): Flags is invalid\r\n");
return STATUS_INVALID_PARAMETER;
}
}
RemoveEnd = RemoveStart + PageCount;
ListEntry = Mdl->Head->Flink;
while (ListEntry != Mdl->Head) {
Descriptor = (PMEMORY_DESCRIPTOR)ListEntry;
if (Mapped) {
DescriptorStart = Descriptor->MappedFirstPage;
} else {
DescriptorStart = Descriptor->FirstPage;
}
DescriptorEnd = DescriptorStart + Descriptor->PageCount;
//
// Check if the region to be removed
// is inside the current descriptor.
//
if (RemoveStart <= DescriptorStart && RemoveEnd > DescriptorStart) {
//
// The region is around the start of the descriptor, or
// they have identical locations and sizes.
// | RemoveStart | DescriptorStart | RemoveEnd | DescriptorEnd |
// | Lower address ............................ Higher address |
//
if (RemoveEnd < DescriptorEnd) {
Offset = RemoveEnd - DescriptorStart;
} else {
Offset = DescriptorEnd - DescriptorStart;
}
//
// Shrink the descriptor.
//
Descriptor->FirstPage += Offset;
Descriptor->PageCount -= Offset;
if (Descriptor->MappedFirstPage) {
Descriptor->MappedFirstPage += Offset;
}
//
// Remove descriptor if now empty.
//
if (Descriptor->PageCount == 0) {
MmMdRemoveDescriptorFromList(Mdl, Descriptor);
MmMdFreeDescriptor(Descriptor);
}
} else if (RemoveStart < DescriptorEnd && RemoveEnd >= DescriptorEnd) {
//
// The region is around the end of the descriptor.
// | DescriptorStart | RemoveStart | DescriptorEnd | RemoveEnd |
// | Lower address ............................ Higher address |
//
//
// Simply shrink the descriptor.
//
Descriptor->PageCount -= DescriptorEnd - RemoveStart;
} else if (RemoveStart > DescriptorStart && RemoveEnd < DescriptorEnd) {
//
// The region is completely inside the descriptor.
// In this case, the descriptor must be split in two.
// | DescriptorStart | RemoveStart | RemoveEnd | DescriptorEnd |
// | Lower address ............................ Higher address |
//
//
// Create a new descriptor before the removed region.
//
NewDescriptor = MmMdInitDescriptor(
Descriptor->FirstPage,
Descriptor->MappedFirstPage,
RemoveStart - DescriptorStart,
Descriptor->Attributes,
Descriptor->Type
);
//
// Shrink and move the current descriptor.
//
Offset = NewDescriptor->PageCount + PageCount;
Descriptor->FirstPage += Offset;
Descriptor->PageCount -= Offset;
if (Descriptor->MappedFirstPage) {
Descriptor->MappedFirstPage += Offset;
}
//
// Now check if MmMdInitDescriptor() actually worked.
//
if (NewDescriptor == NULL) {
return STATUS_NO_MEMORY;
}
Status = MmMdAddDescriptorToList(Mdl, NewDescriptor, Flags);
if (!NT_SUCCESS(Status)) {
MmMdFreeDescriptor(NewDescriptor);
return Status;
}
}
ListEntry = ListEntry->Flink;
}
return Status;
}
NTSTATUS
MmMdRemoveRegionFromMdl (
IN PMEMORY_DESCRIPTOR_LIST Mdl,
IN ULONGLONG RemoveStart,
IN ULONGLONG PageCount,
IN ULONG Flags
)
/*++
Routine Description:
Removes a region from a MDL.
Wrapper around MmMdRemoveRegionFromMdlEx().
Arguments:
Same as MmMdRemoveRegionFromMdlEx(), except for Unused.
Return Value:
Any status code returned by MmMdRemoveRegionFromMdlEx().
--*/
{
return MmMdRemoveRegionFromMdlEx(
Mdl,
RemoveStart,
PageCount,
Flags,
NULL
);
}
NTSTATUS
MmMdFreeDescriptor (
IN PMEMORY_DESCRIPTOR Descriptor
)
/*++
Routine Description:
Frees a memory descriptor.
Arguments:
Descriptor - the descriptor to free.
Return Value:
STATUS_SUCCESS if successful,
other NTSTATUS value if an error occurs.
--*/
{
if (
(
MmDynamicMemoryDescriptors != NULL
&& (ULONG_PTR)Descriptor >= (ULONG_PTR)MmDynamicMemoryDescriptors
&& (ULONG_PTR)Descriptor <= (ULONG_PTR)&MmDynamicMemoryDescriptors[MmDynamicMemoryDescriptorCount]
)
|| (
(ULONG_PTR)Descriptor >= (ULONG_PTR)MmStaticMemoryDescriptors
&& (ULONG_PTR)Descriptor <= (ULONG_PTR)&MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT]
)
) {
//
// Clear the descriptor from static/dynamic MDL.
//
RtlZeroMemory(Descriptor, sizeof(MEMORY_DESCRIPTOR));
return STATUS_SUCCESS;
}
//
// TODO: Free the descriptor from the heap.
// Need BlMmFreeHeap().
//
DebugPrint(L"MmMdFreeDescriptor(): Heap not available\r\n");
return STATUS_NOT_IMPLEMENTED;
// return BlMmFreeHeap(Descriptor);
}
VOID
MmMdFreeList (
IN PMEMORY_DESCRIPTOR_LIST Mdl
)
/*++
Routine Description:
Frees a memory descriptor list (MDL).
Arguments:
Mdl - the MDL.
Return Value:
None.
--*/
{
PLIST_ENTRY Entry;
Entry = Mdl->Head->Flink;
while (Entry != Mdl->Head) {
MmMdRemoveDescriptorFromList(Mdl, (PMEMORY_DESCRIPTOR)Entry);
MmMdFreeDescriptor((PMEMORY_DESCRIPTOR)Entry);
Entry = Entry->Flink;
}
}
PMEMORY_DESCRIPTOR
MmMdInitDescriptor (
IN ULONGLONG FirstPage,
IN ULONGLONG MappedFirstPage,
IN ULONGLONG PageCount,
IN ULONG Attributes,
IN MEMORY_TYPE Type
)
/*++
Routine Description:
Initializes a memory descriptor.
Arguments:
FirstPage - The first page in the region.
MappedFirstPage - The first page in the mapping.
Attributes - Memory attributes of the region.
Type - Memory type of the region.
Return Value:
Pointer to the memory descriptor,
NULL if an error occurs.
--*/
{
PMEMORY_DESCRIPTOR Descriptor;
if (MmGlobalMemoryDescriptorsUsed >= MmGlobalMemoryDescriptorCount) {
DebugPrint(L"MmMdInitDescriptor(): No free descriptors available\r\n");
return NULL;
}
Descriptor = &MmGlobalMemoryDescriptors[MmGlobalMemoryDescriptorsUsed++];
Descriptor->FirstPage = FirstPage;
Descriptor->MappedFirstPage = MappedFirstPage;
Descriptor->PageCount = PageCount;
Descriptor->Attributes = Attributes;
Descriptor->Type = Type;
InitializeListHead(&Descriptor->ListEntry);
return Descriptor;
}
NTSTATUS
MmMdDestroy (
)
/*++
Routine Description:
Cleans up after any actions performed by the memory descriptor manager.
After calling this, the memory descriptor manager can no longer be used.
Arguments:
None.
Return Value:
STATUS_SUCCESS.
--*/
{
//
// TODO: Implement this routine.
//
return STATUS_SUCCESS;
}
VOID
MmMdInitialize (
IN ULONG Stage,
IN PBOOT_LIBRARY_PARAMETERS LibraryParameters
)
/*++
Routine Description:
Initializes the memory descriptor manager.
Arguments:
Stage - Which stage of initialization to perform.
Stage 0: Initializes the static memory descriptor pool.
LibraryParameters - Pointer to the library parameters structure.
Return Value:
None.
--*/
{
(VOID)LibraryParameters;
if (Stage == 0) {
//
// Initialize static memory descriptor pool.
//
MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0];
MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT;
MmGlobalMemoryDescriptorsUsed = 0;
RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(MEMORY_DESCRIPTOR));
}
//
// TODO: Implement stage 1 initialization.
//
}