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