mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-26 23:24:03 +02:00
Fix the runtime memory map change issue
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2357 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
9821fa9a8f
commit
78bd039b86
@ -1,6 +1,6 @@
|
|||||||
/*++
|
/*++
|
||||||
|
|
||||||
Copyright (c) 2006, Intel Corporation
|
Copyright (c) 2007, Intel Corporation
|
||||||
All rights reserved. This program and the accompanying materials
|
All rights reserved. This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
are licensed and made available under the terms and conditions of the BSD License
|
||||||
which accompanies this distribution. The full text of the license may be found at
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -50,7 +50,10 @@ UINTN mMemoryMapKey = 0;
|
|||||||
UINTN mMapDepth = 0;
|
UINTN mMapDepth = 0;
|
||||||
MEMORY_MAP mMapStack[MAX_MAP_DEPTH];
|
MEMORY_MAP mMapStack[MAX_MAP_DEPTH];
|
||||||
UINTN mFreeMapStack = 0;
|
UINTN mFreeMapStack = 0;
|
||||||
|
//
|
||||||
|
// This list maintain the free memory map list
|
||||||
|
//
|
||||||
|
LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList);
|
||||||
BOOLEAN mMemoryTypeInformationInitialized = FALSE;
|
BOOLEAN mMemoryTypeInformationInitialized = FALSE;
|
||||||
|
|
||||||
EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {
|
EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {
|
||||||
@ -128,7 +131,12 @@ VOID
|
|||||||
RemoveMemoryMapEntry (
|
RemoveMemoryMapEntry (
|
||||||
MEMORY_MAP *Entry
|
MEMORY_MAP *Entry
|
||||||
);
|
);
|
||||||
|
|
||||||
|
STATIC
|
||||||
|
MEMORY_MAP *
|
||||||
|
AllocateMemoryMapEntry (
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
CoreAcquireMemoryLock (
|
CoreAcquireMemoryLock (
|
||||||
VOID
|
VOID
|
||||||
@ -509,7 +517,7 @@ Returns:
|
|||||||
//
|
//
|
||||||
|
|
||||||
mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;
|
mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;
|
||||||
mMapStack[mMapDepth].FromPool = FALSE;
|
mMapStack[mMapDepth].FromPages = FALSE;
|
||||||
mMapStack[mMapDepth].Type = Type;
|
mMapStack[mMapDepth].Type = Type;
|
||||||
mMapStack[mMapDepth].Start = Start;
|
mMapStack[mMapDepth].Start = Start;
|
||||||
mMapStack[mMapDepth].End = End;
|
mMapStack[mMapDepth].End = End;
|
||||||
@ -564,11 +572,10 @@ Returns:
|
|||||||
mFreeMapStack += 1;
|
mFreeMapStack += 1;
|
||||||
|
|
||||||
while (mMapDepth) {
|
while (mMapDepth) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Allocate memory for a entry
|
// Deque an memory map entry from mFreeMemoryMapEntryList
|
||||||
//
|
//
|
||||||
Entry = CoreAllocatePoolI (EfiRuntimeServicesData, sizeof(MEMORY_MAP));
|
Entry = AllocateMemoryMapEntry ();
|
||||||
|
|
||||||
ASSERT (Entry);
|
ASSERT (Entry);
|
||||||
|
|
||||||
@ -580,20 +587,20 @@ Returns:
|
|||||||
if (mMapStack[mMapDepth].Link.ForwardLink != NULL) {
|
if (mMapStack[mMapDepth].Link.ForwardLink != NULL) {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Move this entry to general pool
|
// Move this entry to general memory
|
||||||
//
|
//
|
||||||
RemoveEntryList (&mMapStack[mMapDepth].Link);
|
RemoveEntryList (&mMapStack[mMapDepth].Link);
|
||||||
mMapStack[mMapDepth].Link.ForwardLink = NULL;
|
mMapStack[mMapDepth].Link.ForwardLink = NULL;
|
||||||
|
|
||||||
CopyMem (Entry , &mMapStack[mMapDepth], sizeof (MEMORY_MAP));
|
CopyMem (Entry , &mMapStack[mMapDepth], sizeof (MEMORY_MAP));
|
||||||
Entry->FromPool = TRUE;
|
Entry->FromPages = TRUE;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find insertion location
|
// Find insertion location
|
||||||
//
|
//
|
||||||
for (Link2 = gMemoryMap.ForwardLink; Link2 != &gMemoryMap; Link2 = Link2->ForwardLink) {
|
for (Link2 = gMemoryMap.ForwardLink; Link2 != &gMemoryMap; Link2 = Link2->ForwardLink) {
|
||||||
Entry2 = CR (Link2, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
|
Entry2 = CR (Link2, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
|
||||||
if (Entry2->FromPool && Entry2->Start > Entry->Start) {
|
if (Entry2->FromPages && Entry2->Start > Entry->Start) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -601,12 +608,11 @@ Returns:
|
|||||||
InsertTailList (Link2, &Entry->Link);
|
InsertTailList (Link2, &Entry->Link);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
//
|
||||||
|
// This item of mMapStack[mMapDepth] has already been dequeued from gMemoryMap list,
|
||||||
|
// so here no need to move it to memory.
|
||||||
//
|
//
|
||||||
// It was removed, don't move it
|
InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);
|
||||||
//
|
|
||||||
CoreFreePoolI (Entry);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,11 +643,68 @@ Returns:
|
|||||||
RemoveEntryList (&Entry->Link);
|
RemoveEntryList (&Entry->Link);
|
||||||
Entry->Link.ForwardLink = NULL;
|
Entry->Link.ForwardLink = NULL;
|
||||||
|
|
||||||
if (Entry->FromPool) {
|
if (Entry->FromPages) {
|
||||||
CoreFreePoolI (Entry);
|
//
|
||||||
|
// Insert the free memory map descriptor to the end of mFreeMemoryMapEntryList
|
||||||
|
//
|
||||||
|
InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MEMORY_MAP *
|
||||||
|
AllocateMemoryMapEntry (
|
||||||
|
)
|
||||||
|
/*++
|
||||||
|
|
||||||
|
Routine Description:
|
||||||
|
|
||||||
|
Internal function. Deque a descriptor entry from the mFreeMemoryMapEntryList.
|
||||||
|
If the list is emtry, then allocate a new page to refuel the list.
|
||||||
|
Please Note this algorithm to allocate the memory map descriptor has a property
|
||||||
|
that the memory allocated for memory entries always grows, and will never really be freed
|
||||||
|
For example, if the current boot uses 2000 memory map entries at the maximum point, but
|
||||||
|
ends up with only 50 at the time the OS is booted, then the memory associated with the 1950
|
||||||
|
memory map entries is still allocated from EfiBootServicesMemory.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
NONE
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
The Memory map descriptor dequed from the mFreeMemoryMapEntryList
|
||||||
|
|
||||||
|
--*/
|
||||||
|
{
|
||||||
|
MEMORY_MAP* FreeDescriptorEntries;
|
||||||
|
MEMORY_MAP* Entry;
|
||||||
|
UINTN Index;
|
||||||
|
|
||||||
|
if (IsListEmpty (&mFreeMemoryMapEntryList)) {
|
||||||
|
//
|
||||||
|
// The list is empty, to allocate one page to refuel the list
|
||||||
|
//
|
||||||
|
FreeDescriptorEntries = CoreAllocatePoolPages (EfiBootServicesData, 1, DEFAULT_PAGE_ALLOCATION);
|
||||||
|
if(FreeDescriptorEntries != NULL) {
|
||||||
|
//
|
||||||
|
// Enque the free memmory map entries into the list
|
||||||
|
//
|
||||||
|
for (Index = 0; Index< DEFAULT_PAGE_ALLOCATION / sizeof(MEMORY_MAP); Index++) {
|
||||||
|
FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE;
|
||||||
|
InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// dequeue the first descriptor from the list
|
||||||
|
//
|
||||||
|
Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
|
||||||
|
RemoveEntryList (&Entry->Link);
|
||||||
|
|
||||||
|
return Entry;
|
||||||
|
}
|
||||||
|
|
||||||
STATIC
|
STATIC
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
@ -790,7 +853,7 @@ Returns:
|
|||||||
// Add a new one
|
// Add a new one
|
||||||
//
|
//
|
||||||
mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;
|
mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;
|
||||||
mMapStack[mMapDepth].FromPool = FALSE;
|
mMapStack[mMapDepth].FromPages = FALSE;
|
||||||
mMapStack[mMapDepth].Type = Entry->Type;
|
mMapStack[mMapDepth].Type = Entry->Type;
|
||||||
mMapStack[mMapDepth].Start = RangeEnd+1;
|
mMapStack[mMapDepth].Start = RangeEnd+1;
|
||||||
mMapStack[mMapDepth].End = Entry->End;
|
mMapStack[mMapDepth].End = Entry->End;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user