diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /Core/CORE_DXE/DebugImageInfo.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'Core/CORE_DXE/DebugImageInfo.c')
-rw-r--r-- | Core/CORE_DXE/DebugImageInfo.c | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/Core/CORE_DXE/DebugImageInfo.c b/Core/CORE_DXE/DebugImageInfo.c new file mode 100644 index 0000000..c1a81a3 --- /dev/null +++ b/Core/CORE_DXE/DebugImageInfo.c @@ -0,0 +1,262 @@ +/*++ + +Copyright (c) 2004 - 2007, 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. + +Module Name: + + DebugImageInfo.c + +Abstract: + + Support functions for managing debug image info table when loading and unloading + images. + +--*/ + +#include "Tiano.h" +#include "DxeCore.h" +#include "DebugImageInfo.h" + + +static 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; + + +VOID +CoreInitializeDebugImageInfoTable ( + VOID + ) +/*++ + +Routine Description: + + Creates and initializes the DebugImageInfo Table. Also creates the configuration + table and registers it into the system table. + +Arguments: + None + +Returns: + NA + +Notes: + 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. + +--*/ +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Mem; + UINTN NumberOfPages; + + // + // 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. + // + NumberOfPages = FOUR_MEG_PAGES + EFI_SIZE_TO_PAGES(sizeof (EFI_SYSTEM_TABLE_POINTER)); + + 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; + } + // + // Now get a 4M aligned address within the memory range we were given. + // Then allocate memory at that address + // + 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; + } + // + // 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. + // + mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(UINTN)Mem; + mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE; + mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gST; + mDebugTable->Crc32 = 0; + Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader); + ASSERT_EFI_ERROR (Status); +} + +VOID +CoreUpdateDebugTableCrc32 ( + VOID + ) +/*++ + +Routine Description: + + 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. + +Arguments: + None + +Returns: + NA + +--*/ +{ + ASSERT(mDebugTable != NULL); + mDebugTable->Crc32 = 0; + gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32); +} + +VOID +CoreNewDebugImageInfoEntry ( + IN UINT32 ImageInfoType, + IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, + IN EFI_HANDLE ImageHandle + ) +/*++ + +Routine Description: + + Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates + the table if it's not large enough to accomidate another entry. + +Arguments: + + ImageInfoType - type of debug image information + LoadedImage - pointer to the loaded image protocol for the image being loaded + ImageHandle - image handle for the image being loaded + +Returns: + NA + +--*/ +{ + EFI_DEBUG_IMAGE_INFO *Table; + EFI_DEBUG_IMAGE_INFO *NewTable; + UINTN Index; + UINTN MaxTableIndex; + 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; + 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 (Index == MaxTableIndex) { + // + // 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); + if (NewTable == NULL) { + mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + return; + } + // + // Copy the old table into the new one + // + EfiCommonLibCopyMem (NewTable, Table, TableSize); + // + // Free the old table + // + CoreFreePool (Table); + // + // Update the table header + // + Table = NewTable; + mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable; + mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE; + } + // + // Allocate data for new entry + // + Table[Index].NormalImage = CoreAllocateZeroBootServicesPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL)); + if (Table[Index].NormalImage != NULL) { + // + // Update the entry + // + Table[Index].NormalImage->ImageInfoType = ImageInfoType; + Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage; + Table[Index].NormalImage->ImageHandle = ImageHandle; + } + mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; +} + + +VOID +CoreRemoveDebugImageInfoEntry ( + EFI_HANDLE ImageHandle + ) +/*++ + +Routine Description: + + Removes and frees an entry from the DebugImageInfo Table. + +Arguments: + + ImageHandle - image handle for the image being unloaded + +Returns: + + NA + +--*/ +{ + EFI_DEBUG_IMAGE_INFO *Table; + UINTN Index; + + mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; + + Table = mDebugInfoTableHeader.EfiDebugImageInfoTable; + + for (Index = 0; Index < mDebugInfoTableHeader.TableSize; 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; + break; + } + } + mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS; +} + |