X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FCore%2FDxe%2FMisc%2FDebugImageInfo.c;h=47660729ba79fff8906e413d81ab5a3d47ccbcbf;hb=6dee8f78f2ac07d7de99b13630a0aa0613d888de;hp=e318b4239f4f9e5f9dc4debd13cc02cbd9984b42;hpb=162ed594438ab8d39f89b43e6d645ca24e1e1e65;p=mirror_edk2.git
diff --git a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
index e318b4239f..47660729ba 100644
--- a/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
+++ b/MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
@@ -1,90 +1,135 @@
-/** @file
-
+/** @file
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 - 2010, 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.
**/
-#include
+#include "DxeMain.h"
-static EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
+EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
0, // volatile UINT32 UpdateStatus;
0, // UINT32 TableSize;
NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
};
-static EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
+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.
- Note:
- This function allocates memory, frees it, and then allocates memory at an
- address within the initial allocation. Since this function is called early
- in DXE core initialization (before drivers are dispatched), this should not
- be a problem.
-
**/
VOID
CoreInitializeDebugImageInfoTable (
VOID
)
-{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Mem;
- UINTN NumberOfPages;
+{
+ EFI_STATUS Status;
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Memory;
+ UINTN AlignedMemory;
+ UINTN AlignmentMask;
+ UINTN UnalignedPages;
+ UINTN RealPages;
//
- // Allocate boot services memory for the structure. It's required to be aligned on
- // a 4M boundary, so allocate a 4M block (plus what we require), free it up, calculate
- // a 4M aligned address within the memory we just freed, and then allocate memory at that
- // address for our initial structure.
+ // 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.
//
- NumberOfPages = FOUR_MEG_PAGES + EFI_SIZE_TO_PAGES(sizeof (EFI_SYSTEM_TABLE_POINTER));
+ Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER));
+ AlignmentMask = SIZE_4MB - 1;
+ RealPages = Pages + EFI_SIZE_TO_PAGES (SIZE_4MB);
- Status = CoreAllocatePages (AllocateAnyPages, EfiBootServicesData, NumberOfPages , &Mem);
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR(Status)) {
- return;
- }
- Status = CoreFreePages (Mem, NumberOfPages);
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR(Status)) {
- return;
+ //
+ // 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;
+ }
+ }
+
//
- // Now get a 4M aligned address within the memory range we were given.
- // Then allocate memory at that address
+ // Free overallocated pages
//
- Mem = (Mem + FOUR_MEG_MASK) & (~FOUR_MEG_MASK);
-
- Status = CoreAllocatePages (AllocateAddress, EfiBootServicesData, NumberOfPages - FOUR_MEG_PAGES, &Mem);
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR(Status)) {
- return;
+ 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 = (EFI_PHYSICAL_ADDRESS)(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);
}
+
//
- // We now have a 4M aligned page allocated, so fill in the data structure.
- // 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.
+ // Set mDebugTable to the 4MB aligned allocated pages
+ //
+ mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(AlignedMemory);
+ ASSERT (mDebugTable != NULL);
+
//
- mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(UINTN)Mem;
- mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
+ // 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);
}
@@ -105,7 +150,7 @@ CoreUpdateDebugTableCrc32 (
{
ASSERT(mDebugTable != NULL);
mDebugTable->Crc32 = 0;
- gDxeCoreBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
+ gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
}
@@ -113,9 +158,9 @@ CoreUpdateDebugTableCrc32 (
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 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
**/
@@ -125,11 +170,10 @@ CoreNewDebugImageInfoEntry (
IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
IN EFI_HANDLE ImageHandle
)
-{
+{
EFI_DEBUG_IMAGE_INFO *Table;
EFI_DEBUG_IMAGE_INFO *NewTable;
UINTN Index;
- UINTN MaxTableIndex;
UINTN TableSize;
//
@@ -138,22 +182,25 @@ 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;
- NewTable = CoreAllocateZeroBootServicesPool (TableSize + EFI_PAGE_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;
return;
@@ -171,12 +218,18 @@ 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
//
- Table[Index].NormalImage = CoreAllocateZeroBootServicesPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
+ Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
if (Table[Index].NormalImage != NULL) {
//
// Update the entry
@@ -184,6 +237,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;
}
@@ -200,7 +258,7 @@ VOID
CoreRemoveDebugImageInfoEntry (
EFI_HANDLE ImageHandle
)
-{
+{
EFI_DEBUG_IMAGE_INFO *Table;
UINTN Index;
@@ -208,7 +266,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
@@ -216,6 +274,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;
}
}