mirror of https://github.com/acidanthera/audk.git
255 lines
7.7 KiB
C
255 lines
7.7 KiB
C
/** @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.
|
|
|
|
**/
|
|
|
|
#include <DxeMain.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) gDxeCoreST;
|
|
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;
|
|
gDxeCoreBS->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
|
|
//
|
|
CopyMem (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 = (UINT32) 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;
|
|
}
|
|
|