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; } }