X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxe%2FMisc%2FDebugImageInfo.c;h=a75d4158280b9597e5d265d8ce6fecdeeb49598c;hp=295f32f43e8eee0b2c71335f43504973f26033d6;hb=9d510e61fceee7b92955ef9a3c20343752d8ce3f;hpb=ec90508b3d3ff22a698a0446cb09d551d7466045
diff --git a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
index 295f32f43e..a75d415828 100644
--- a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
+++ b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
@@ -2,14 +2,8 @@
Support functions for managing debug image info table when loading and unloading
images.
-Copyright (c) 2006 - 2008, Intel Corporation.
-All rights reserved. This program and the accompanying materials
-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
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -22,9 +16,9 @@ EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
};
-EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
+UINTN mMaxTableEntries = 0;
-#define FOUR_MEG_ALIGNMENT 0x400000
+EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))
@@ -38,17 +32,98 @@ CoreInitializeDebugImageInfoTable (
VOID
)
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Memory;
+ UINTN AlignedMemory;
+ UINTN AlignmentMask;
+ UINTN UnalignedPages;
+ UINTN RealPages;
//
// Allocate 4M aligned page for the structure and fill in the data.
// Ideally we would update the CRC now as well, but the service may not yet be available.
// See comments in the CoreUpdateDebugTableCrc32() function below for details.
//
- mDebugTable = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER)), FOUR_MEG_ALIGNMENT);
- mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
+ Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER));
+ AlignmentMask = SIZE_4MB - 1;
+ RealPages = Pages + EFI_SIZE_TO_PAGES (SIZE_4MB);
+
+ //
+ // Attempt to allocate memory below PcdMaxEfiSystemTablePointerAddress
+ // If PcdMaxEfiSystemTablePointerAddress is 0, then allocate memory below
+ // MAX_ADDRESS
+ //
+ Memory = PcdGet64 (PcdMaxEfiSystemTablePointerAddress);
+ if (Memory == 0) {
+ Memory = MAX_ADDRESS;
+ }
+ Status = CoreAllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ RealPages,
+ &Memory
+ );
+ if (EFI_ERROR (Status)) {
+ if (PcdGet64 (PcdMaxEfiSystemTablePointerAddress) != 0) {
+ DEBUG ((EFI_D_INFO, "Allocate memory for EFI_SYSTEM_TABLE_POINTER below PcdMaxEfiSystemTablePointerAddress failed. \
+ Retry to allocate memroy as close to the top of memory as feasible.\n"));
+ }
+ //
+ // If the initial memory allocation fails, then reattempt allocation
+ // as close to the top of memory as feasible.
+ //
+ Status = CoreAllocatePages (
+ AllocateAnyPages,
+ EfiBootServicesData,
+ RealPages,
+ &Memory
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ }
+
+ //
+ // Free overallocated pages
+ //
+ AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
+ UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
+ if (UnalignedPages > 0) {
+ //
+ // Free first unaligned page(s).
+ //
+ Status = CoreFreePages (Memory, UnalignedPages);
+ ASSERT_EFI_ERROR (Status);
+ }
+ Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
+ UnalignedPages = RealPages - Pages - UnalignedPages;
+ if (UnalignedPages > 0) {
+ //
+ // Free last unaligned page(s).
+ //
+ Status = CoreFreePages (Memory, UnalignedPages);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Set mDebugTable to the 4MB aligned allocated pages
+ //
+ mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(AlignedMemory);
+ ASSERT (mDebugTable != NULL);
+
+ //
+ // Initialize EFI_SYSTEM_TABLE_POINTER structure
+ //
+ mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST;
- mDebugTable->Crc32 = 0;
+ mDebugTable->Crc32 = 0;
+
+ //
+ // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System
+ // Configuration Table
+ //
Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);
ASSERT_EFI_ERROR (Status);
}
@@ -93,7 +168,6 @@ CoreNewDebugImageInfoEntry (
EFI_DEBUG_IMAGE_INFO *Table;
EFI_DEBUG_IMAGE_INFO *NewTable;
UINTN Index;
- UINTN MaxTableIndex;
UINTN TableSize;
//
@@ -102,21 +176,24 @@ CoreNewDebugImageInfoEntry (
mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
- MaxTableIndex = mDebugInfoTableHeader.TableSize;
- for (Index = 0; Index < MaxTableIndex; Index++) {
- if (Table[Index].NormalImage == NULL) {
- //
- // We have found a free entry so exit the loop
- //
- break;
+ if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) {
+ //
+ // We still have empty entires in the Table, find the first empty entry.
+ //
+ Index = 0;
+ while (Table[Index].NormalImage != NULL) {
+ Index++;
}
- }
- if (Index == MaxTableIndex) {
+ //
+ // There must be an empty entry in the in the table.
+ //
+ ASSERT (Index < mMaxTableEntries);
+ } else {
//
// Table is full, so re-allocate another page for a larger table...
//
- TableSize = MaxTableIndex * EFI_DEBUG_TABLE_ENTRY_SIZE;
+ TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE;
NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE);
if (NewTable == NULL) {
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
@@ -135,8 +212,14 @@ CoreNewDebugImageInfoEntry (
//
Table = NewTable;
mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
- mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
+ //
+ // Enlarge the max table entries and set the first empty entry index to
+ // be the original max table entries.
+ //
+ Index = mMaxTableEntries;
+ mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
}
+
//
// Allocate data for new entry
//
@@ -148,6 +231,11 @@ CoreNewDebugImageInfoEntry (
Table[Index].NormalImage->ImageInfoType = (UINT32) ImageInfoType;
Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;
Table[Index].NormalImage->ImageHandle = ImageHandle;
+ //
+ // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
+ //
+ mDebugInfoTableHeader.TableSize++;
+ mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
}
mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
}
@@ -172,7 +260,7 @@ CoreRemoveDebugImageInfoEntry (
Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
- for (Index = 0; Index < mDebugInfoTableHeader.TableSize; Index++) {
+ for (Index = 0; Index < mMaxTableEntries; Index++) {
if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {
//
// Found a match. Free up the record, then NULL the pointer to indicate the slot
@@ -180,6 +268,11 @@ CoreRemoveDebugImageInfoEntry (
//
CoreFreePool (Table[Index].NormalImage);
Table[Index].NormalImage = NULL;
+ //
+ // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
+ //
+ mDebugInfoTableHeader.TableSize--;
+ mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
break;
}
}