summaryrefslogtreecommitdiff
path: root/EDK/Foundation/Core/Dxe/Misc/DebugImageInfo.c
diff options
context:
space:
mode:
Diffstat (limited to 'EDK/Foundation/Core/Dxe/Misc/DebugImageInfo.c')
-rw-r--r--EDK/Foundation/Core/Dxe/Misc/DebugImageInfo.c262
1 files changed, 262 insertions, 0 deletions
diff --git a/EDK/Foundation/Core/Dxe/Misc/DebugImageInfo.c b/EDK/Foundation/Core/Dxe/Misc/DebugImageInfo.c
new file mode 100644
index 0000000..c1a81a3
--- /dev/null
+++ b/EDK/Foundation/Core/Dxe/Misc/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;
+}
+