[BOOT:MM] Big work on MM :)
This commit is contained in:
@@ -32,11 +32,11 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
MemoryInfo - pointer to the memory info structure.
|
||||
MemoryInfo - Pointer to the memory info.
|
||||
|
||||
TranslationType - the current translation type being used.
|
||||
TranslationType - The current translation type.
|
||||
|
||||
LibraryParameters - pointer to the library parameters structure.
|
||||
LibraryParameters - Pointer to the library parameters.
|
||||
|
||||
Return Value:
|
||||
|
||||
|
@@ -22,10 +22,316 @@ Abstract:
|
||||
MEMORY_DESCRIPTOR MmStaticMemoryDescriptors[MAX_STATIC_DESCRIPTOR_COUNT];
|
||||
|
||||
PMEMORY_DESCRIPTOR MmGlobalMemoryDescriptors;
|
||||
ULONG MmGlobalMemoryDescriptorCount;
|
||||
ULONG MmGlobalMemoryDescriptorCount, MmGlobalMemoryDescriptorsUsed;
|
||||
|
||||
PMEMORY_DESCRIPTOR MmDynamicMemoryDescriptors;
|
||||
ULONG MmDynamicMemoryDescriptorCount;
|
||||
ULONG MmDynamicMemoryDescriptorCount, MmDynamicMemoryDescriptorsUsed;
|
||||
|
||||
BOOLEAN
|
||||
MmMdpHasPrecedence (
|
||||
IN MEMORY_TYPE A,
|
||||
IN MEMORY_TYPE B
|
||||
)
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Compares two memory types to determine which has precedence.
|
||||
|
||||
Arguments:
|
||||
|
||||
A - memory type A.
|
||||
|
||||
B - memory type B.
|
||||
|
||||
Return Value:
|
||||
|
||||
TRUE if A has precedence over B, or if neither has precedence.
|
||||
FALSE if B has precedence over A.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
ULONG ClassA, ClassB;
|
||||
|
||||
ClassA = A >> 28;
|
||||
ClassB = B >> 28;
|
||||
|
||||
if (B == MEMORY_TYPE_FREE) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (A == MEMORY_TYPE_FREE) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ClassA > 0x0F) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (ClassB > 0x0F) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ClassA != 0x0F) {
|
||||
return (ClassB != 0x0F && (ClassA == 0x0D || ClassB != 0x0D)) ? TRUE:FALSE;
|
||||
}
|
||||
|
||||
if (ClassB != 0x0F) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// TODO: Incomplete.
|
||||
//
|
||||
ConsolePrint(L"MmMdpHasPrecedence() is incomplete\r\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
--*/
|
||||
|
||||
{
|
||||
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) {
|
||||
MmMdAddDescriptorToList(Mdl, NewDescriptor, Flags);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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) {
|
||||
MmMdAddDescriptorToList(Mdl, NewDescriptor, Flags);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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) {
|
||||
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 (
|
||||
@@ -55,10 +361,6 @@ Return Value:
|
||||
PLIST_ENTRY Blink;
|
||||
|
||||
Blink = Descriptor->ListEntry.Blink;
|
||||
|
||||
//
|
||||
// Remove the descriptor from the MDL.
|
||||
//
|
||||
RemoveEntryList(&Descriptor->ListEntry);
|
||||
|
||||
//
|
||||
@@ -129,7 +431,7 @@ Return Value:
|
||||
// Free the descriptor from the heap.
|
||||
// TODO: Use BlMmFreeHeap()
|
||||
//
|
||||
ConsolePrint(L"Cannot free memory descriptor: BlMmFreeHeap() is not implemented\r\n");
|
||||
ConsolePrint(L"MmMdFreeDescriptor(): need BlMmFreeHeap() to free descriptor\r\n");
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
// return BlMmFreeHeap(Descriptor);
|
||||
}
|
||||
@@ -147,7 +449,7 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Mdl - the MDL to free.
|
||||
Mdl - the MDL.
|
||||
|
||||
Return Value:
|
||||
|
||||
@@ -166,6 +468,56 @@ Return Value:
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
VOID
|
||||
MmMdInitialize (
|
||||
IN ULONG Unused,
|
||||
@@ -201,6 +553,7 @@ Return Value:
|
||||
//
|
||||
MmGlobalMemoryDescriptors = &MmStaticMemoryDescriptors[0];
|
||||
MmGlobalMemoryDescriptorCount = MAX_STATIC_DESCRIPTOR_COUNT;
|
||||
MmGlobalMemoryDescriptorsUsed = 0;
|
||||
RtlZeroMemory(MmGlobalMemoryDescriptors, MAX_STATIC_DESCRIPTOR_COUNT * sizeof(MEMORY_DESCRIPTOR));
|
||||
DebugPrintf(L"Global memory descriptor count: %x\r\n", MmGlobalMemoryDescriptorCount);
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
Mdl - the MDL to initialize.
|
||||
Mdl - Pointer to the MDL.
|
||||
|
||||
Return Value:
|
||||
|
||||
@@ -72,9 +72,9 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
MemoryInfo - pointer to the memory info structure.
|
||||
MemoryInfo - Pointer to the memory info structure.
|
||||
|
||||
MinimumAllocation - minimum amount of pages to grow the pool by at a time.
|
||||
MinimumAllocation - Minimum amount of pages to grow the pool by at a time.
|
||||
|
||||
Return Value:
|
||||
|
||||
|
Reference in New Issue
Block a user