aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/edk2/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c')
-rw-r--r--roms/edk2/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c282
1 files changed, 282 insertions, 0 deletions
diff --git a/roms/edk2/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/roms/edk2/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
new file mode 100644
index 000000000..a75d41582
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
@@ -0,0 +1,282 @@
+/** @file
+ Support functions for managing debug image info table when loading and unloading
+ images.
+
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "DxeMain.h"
+
+
+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
+ 0, // volatile UINT32 UpdateStatus;
+ 0, // UINT32 TableSize;
+ NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
+};
+
+UINTN mMaxTableEntries = 0;
+
+EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
+
+#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))
+
+/**
+ Creates and initializes the DebugImageInfo Table. Also creates the configuration
+ table and registers it into the system table.
+
+**/
+VOID
+CoreInitializeDebugImageInfoTable (
+ VOID
+ )
+{
+ 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.
+ //
+ 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;
+
+ //
+ // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System
+ // Configuration Table
+ //
+ Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+/**
+ Update the CRC32 in the Debug Table.
+ Since the CRC32 service is made available by the Runtime driver, we have to
+ wait for the Runtime Driver to be installed before the CRC32 can be computed.
+ This function is called elsewhere by the core when the runtime architectural
+ protocol is produced.
+
+**/
+VOID
+CoreUpdateDebugTableCrc32 (
+ VOID
+ )
+{
+ ASSERT(mDebugTable != NULL);
+ mDebugTable->Crc32 = 0;
+ gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
+}
+
+
+/**
+ Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
+ the table if it's not large enough to accomidate another entry.
+
+ @param ImageInfoType type of debug image information
+ @param LoadedImage pointer to the loaded image protocol for the image being
+ loaded
+ @param ImageHandle image handle for the image being loaded
+
+**/
+VOID
+CoreNewDebugImageInfoEntry (
+ IN UINT32 ImageInfoType,
+ IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_DEBUG_IMAGE_INFO *Table;
+ EFI_DEBUG_IMAGE_INFO *NewTable;
+ UINTN Index;
+ UINTN TableSize;
+
+ //
+ // Set the flag indicating that we're in the process of updating the table.
+ //
+ mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
+
+ 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++;
+ }
+ //
+ // 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 = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE;
+ NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE);
+ if (NewTable == NULL) {
+ mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+ return;
+ }
+ //
+ // Copy the old table into the new one
+ //
+ CopyMem (NewTable, Table, TableSize);
+ //
+ // Free the old table
+ //
+ CoreFreePool (Table);
+ //
+ // Update the table header
+ //
+ Table = NewTable;
+ mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
+ //
+ // 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
+ //
+ Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
+ if (Table[Index].NormalImage != NULL) {
+ //
+ // Update the entry
+ //
+ 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;
+}
+
+
+
+/**
+ Removes and frees an entry from the DebugImageInfo Table.
+
+ @param ImageHandle image handle for the image being unloaded
+
+**/
+VOID
+CoreRemoveDebugImageInfoEntry (
+ EFI_HANDLE ImageHandle
+ )
+{
+ EFI_DEBUG_IMAGE_INFO *Table;
+ UINTN Index;
+
+ mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
+
+ 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
+ // is free.
+ //
+ 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;
+ }
+ }
+ mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+}
+
+