ShellPkg/Dp: Updated to dump perf log based on FPDT table
Cc: Liming Gao <liming.gao@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Ruiyu Ni <ruiyu.ni@intel.com> Cc: Jaben Carsey <jaben.carsey@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Dandan Bi <dandan.bi@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
@ -13,7 +13,7 @@
|
||||
Dp uses this information to group records in different ways. It also uses
|
||||
timer information to calculate elapsed time for each measurement.
|
||||
|
||||
Copyright (c) 2009 - 2017, Intel Corporation. All rights reserved.
|
||||
Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
|
||||
(C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
|
||||
This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
@ -24,13 +24,34 @@
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
**/
|
||||
|
||||
#include "PerformanceTokens.h"
|
||||
#include "Dp.h"
|
||||
#include "Literals.h"
|
||||
#include "DpInternal.h"
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct {
|
||||
EFI_ACPI_DESCRIPTION_HEADER Header;
|
||||
UINT32 Entry;
|
||||
} RSDT_TABLE;
|
||||
|
||||
typedef struct {
|
||||
EFI_ACPI_DESCRIPTION_HEADER Header;
|
||||
UINT64 Entry;
|
||||
} XSDT_TABLE;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
EFI_HANDLE mDpHiiHandle;
|
||||
|
||||
typedef struct {
|
||||
EFI_HANDLE Handle;
|
||||
EFI_GUID ModuleGuid;
|
||||
} HANDLE_GUID_MAP;
|
||||
|
||||
HANDLE_GUID_MAP *mCacheHandleGuidTable;
|
||||
UINTN mCachePairCount = 0;
|
||||
|
||||
//
|
||||
/// Module-Global Variables
|
||||
///@{
|
||||
@ -38,11 +59,14 @@ CHAR16 mGaugeString[DP_GAUGE_STRING_LENGTH + 1];
|
||||
CHAR16 mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];
|
||||
UINT64 mInterestThreshold;
|
||||
BOOLEAN mShowId = FALSE;
|
||||
UINT8 *mBootPerformanceTable;
|
||||
UINTN mBootPerformanceTableSize;
|
||||
BOOLEAN mPeiPhase = FALSE;
|
||||
BOOLEAN mDxePhase = FALSE;
|
||||
|
||||
PERF_SUMMARY_DATA SummaryData = { 0 }; ///< Create the SummaryData structure and init. to ZERO.
|
||||
|
||||
/// Timer Specific Information.
|
||||
TIMER_INFO TimerInfo;
|
||||
MEASUREMENT_RECORD *mMeasurementList = NULL;
|
||||
UINTN mMeasurementNum = 0;
|
||||
|
||||
/// Items for which to gather cumulative statistics.
|
||||
PERF_CUM_DATA CumData[] = {
|
||||
@ -99,6 +123,536 @@ DumpStatistics( void )
|
||||
SHELL_FREE_NON_NULL (StringPtrUnknown);
|
||||
}
|
||||
|
||||
/**
|
||||
This function scan ACPI table in RSDT.
|
||||
|
||||
@param Rsdt ACPI RSDT
|
||||
@param Signature ACPI table signature
|
||||
|
||||
@return ACPI table
|
||||
**/
|
||||
VOID *
|
||||
ScanTableInRSDT (
|
||||
IN RSDT_TABLE *Rsdt,
|
||||
IN UINT32 Signature
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT32 EntryCount;
|
||||
UINT32 *EntryPtr;
|
||||
EFI_ACPI_DESCRIPTION_HEADER *Table;
|
||||
|
||||
EntryCount = (Rsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32);
|
||||
|
||||
EntryPtr = &Rsdt->Entry;
|
||||
for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) {
|
||||
Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(*EntryPtr));
|
||||
if (Table->Signature == Signature) {
|
||||
return Table;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
This function scan ACPI table in XSDT.
|
||||
|
||||
@param Xsdt ACPI XSDT
|
||||
@param Signature ACPI table signature
|
||||
|
||||
@return ACPI table
|
||||
**/
|
||||
VOID *
|
||||
ScanTableInXSDT (
|
||||
IN XSDT_TABLE *Xsdt,
|
||||
IN UINT32 Signature
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
UINT32 EntryCount;
|
||||
UINT64 EntryPtr;
|
||||
UINTN BasePtr;
|
||||
EFI_ACPI_DESCRIPTION_HEADER *Table;
|
||||
|
||||
EntryCount = (Xsdt->Header.Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64);
|
||||
|
||||
BasePtr = (UINTN)(&(Xsdt->Entry));
|
||||
for (Index = 0; Index < EntryCount; Index ++) {
|
||||
CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64));
|
||||
Table = (EFI_ACPI_DESCRIPTION_HEADER*)((UINTN)(EntryPtr));
|
||||
if (Table->Signature == Signature) {
|
||||
return Table;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
This function scan ACPI table in RSDP.
|
||||
|
||||
@param Rsdp ACPI RSDP
|
||||
@param Signature ACPI table signature
|
||||
|
||||
@return ACPI table
|
||||
**/
|
||||
VOID *
|
||||
FindAcpiPtr (
|
||||
IN EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp,
|
||||
IN UINT32 Signature
|
||||
)
|
||||
{
|
||||
EFI_ACPI_DESCRIPTION_HEADER *AcpiTable;
|
||||
RSDT_TABLE *Rsdt;
|
||||
XSDT_TABLE *Xsdt;
|
||||
|
||||
AcpiTable = NULL;
|
||||
|
||||
//
|
||||
// Check ACPI2.0 table
|
||||
//
|
||||
Rsdt = (RSDT_TABLE *)(UINTN)Rsdp->RsdtAddress;
|
||||
Xsdt = NULL;
|
||||
if ((Rsdp->Revision >= 2) && (Rsdp->XsdtAddress < (UINT64)(UINTN)-1)) {
|
||||
Xsdt = (XSDT_TABLE *)(UINTN)Rsdp->XsdtAddress;
|
||||
}
|
||||
//
|
||||
// Check Xsdt
|
||||
//
|
||||
if (Xsdt != NULL) {
|
||||
AcpiTable = ScanTableInXSDT (Xsdt, Signature);
|
||||
}
|
||||
//
|
||||
// Check Rsdt
|
||||
//
|
||||
if ((AcpiTable == NULL) && (Rsdt != NULL)) {
|
||||
AcpiTable = ScanTableInRSDT (Rsdt, Signature);
|
||||
}
|
||||
|
||||
return AcpiTable;
|
||||
}
|
||||
|
||||
/**
|
||||
Get Boot performance table form Acpi table.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
GetBootPerformanceTable (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *AcpiTable;
|
||||
FIRMWARE_PERFORMANCE_TABLE *FirmwarePerformanceTable;
|
||||
|
||||
AcpiTable = NULL;
|
||||
|
||||
Status = EfiGetSystemConfigurationTable (
|
||||
&gEfiAcpi20TableGuid,
|
||||
&AcpiTable
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = EfiGetSystemConfigurationTable (
|
||||
&gEfiAcpi10TableGuid,
|
||||
&AcpiTable
|
||||
);
|
||||
}
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
FirmwarePerformanceTable = FindAcpiPtr (
|
||||
(EFI_ACPI_5_0_ROOT_SYSTEM_DESCRIPTION_POINTER *)AcpiTable,
|
||||
EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
|
||||
);
|
||||
if (FirmwarePerformanceTable == NULL) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
mBootPerformanceTable = (UINT8*) (UINTN)FirmwarePerformanceTable->BootPointerRecord.BootPerformanceTablePointer;
|
||||
mBootPerformanceTableSize = ((BOOT_PERFORMANCE_TABLE *) mBootPerformanceTable)->Header.Length;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Get Handle form Module Guid.
|
||||
|
||||
@param ModuleGuid Module Guid.
|
||||
@param Handle The handle to be returned.
|
||||
|
||||
**/
|
||||
VOID
|
||||
GetHandleFormModuleGuid (
|
||||
IN EFI_GUID *ModuleGuid,
|
||||
IN OUT EFI_HANDLE *Handle
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
|
||||
if (IsZeroGuid (ModuleGuid)) {
|
||||
*Handle = NULL;
|
||||
}
|
||||
//
|
||||
// Try to get the Handle form the caached array.
|
||||
//
|
||||
for (Index = 0; Index < mCachePairCount; Index++) {
|
||||
if (CompareGuid (ModuleGuid, &mCacheHandleGuidTable[Index].ModuleGuid)) {
|
||||
*Handle = mCacheHandleGuidTable[Index].Handle;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Index >= mCachePairCount) {
|
||||
*Handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Cache the GUID and handle mapping pairs. In order to save time for searching.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildCachedGuidHandleTable (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN HandleCount;
|
||||
UINTN Index;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
|
||||
EFI_GUID *TempGuid;
|
||||
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFilePath;
|
||||
|
||||
Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &HandleCount, &HandleBuffer);
|
||||
if (EFI_ERROR (Status)) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), mDpHiiHandle, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
mCacheHandleGuidTable = AllocateZeroPool (HandleCount * sizeof (HANDLE_GUID_MAP));
|
||||
if (mCacheHandleGuidTable == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < HandleCount; Index++) {
|
||||
//
|
||||
// Try Handle as ImageHandle.
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
(VOID**) &LoadedImage
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Try Handle as Controller Handle
|
||||
//
|
||||
Status = gBS->OpenProtocol (
|
||||
HandleBuffer[Index],
|
||||
&gEfiDriverBindingProtocolGuid,
|
||||
(VOID **) &DriverBinding,
|
||||
NULL,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Get Image protocol from ImageHandle
|
||||
//
|
||||
Status = gBS->HandleProtocol (
|
||||
DriverBinding->ImageHandle,
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
(VOID**) &LoadedImage
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status) && LoadedImage != NULL) {
|
||||
//
|
||||
// Get Module Guid from DevicePath.
|
||||
//
|
||||
if (LoadedImage->FilePath != NULL &&
|
||||
LoadedImage->FilePath->Type == MEDIA_DEVICE_PATH &&
|
||||
LoadedImage->FilePath->SubType == MEDIA_PIWG_FW_FILE_DP
|
||||
) {
|
||||
FvFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) LoadedImage->FilePath;
|
||||
TempGuid = &FvFilePath->FvFileName;
|
||||
|
||||
mCacheHandleGuidTable[mCachePairCount].Handle = HandleBuffer[Index];
|
||||
CopyGuid (&mCacheHandleGuidTable[mCachePairCount].ModuleGuid, TempGuid);
|
||||
mCachePairCount ++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool (HandleBuffer);
|
||||
HandleBuffer = NULL;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**
|
||||
Get Measurement form Fpdt records.
|
||||
|
||||
@param RecordHeader Pointer to the start record.
|
||||
@param IsStart Is start record or End record.
|
||||
@param Measurement Pointer to the measurement which need to be filled.
|
||||
|
||||
**/
|
||||
VOID
|
||||
GetMeasurementInfo (
|
||||
IN EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader,
|
||||
IN BOOLEAN IsStart,
|
||||
IN OUT MEASUREMENT_RECORD *Measurement
|
||||
)
|
||||
{
|
||||
VOID *ModuleGuid;
|
||||
EFI_HANDLE StartHandle;
|
||||
|
||||
switch (RecordHeader->Type) {
|
||||
case FPDT_GUID_EVENT_TYPE:
|
||||
ModuleGuid = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
|
||||
Measurement->Identifier = ((UINT32)((FPDT_GUID_EVENT_RECORD *)RecordHeader)->ProgressID);
|
||||
if (IsStart) {
|
||||
Measurement->StartTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
|
||||
} else {
|
||||
Measurement->EndTimeStamp = ((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Timestamp;
|
||||
}
|
||||
switch (Measurement->Identifier) {
|
||||
case MODULE_START_ID:
|
||||
case MODULE_END_ID:
|
||||
if (mPeiPhase) {
|
||||
Measurement->Token = ALit_PEIM;
|
||||
Measurement->Module = ALit_PEIM;
|
||||
} else if (mDxePhase) {
|
||||
Measurement->Token = ALit_START_IMAGE;
|
||||
Measurement->Module = ALit_START_IMAGE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
|
||||
if (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
|
||||
Measurement->Handle = &(((FPDT_GUID_EVENT_RECORD *)RecordHeader)->Guid);
|
||||
} else {
|
||||
GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
|
||||
Measurement->Handle = StartHandle;
|
||||
}
|
||||
break;
|
||||
|
||||
case FPDT_DYNAMIC_STRING_EVENT_TYPE:
|
||||
ModuleGuid = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
|
||||
Measurement->Identifier = ((UINT32)((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
|
||||
if (IsStart) {
|
||||
Measurement->StartTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
|
||||
} else {
|
||||
Measurement->EndTimeStamp = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
|
||||
}
|
||||
switch (Measurement->Identifier) {
|
||||
case MODULE_START_ID:
|
||||
case MODULE_END_ID:
|
||||
if (mPeiPhase) {
|
||||
Measurement->Token = ALit_PEIM;
|
||||
} else if (mDxePhase) {
|
||||
Measurement->Token = ALit_START_IMAGE;
|
||||
}
|
||||
break;
|
||||
|
||||
case MODULE_LOADIMAGE_START_ID:
|
||||
case MODULE_LOADIMAGE_END_ID:
|
||||
Measurement->Token = ALit_LOAD_IMAGE;
|
||||
break;
|
||||
|
||||
case MODULE_DB_START_ID:
|
||||
case MODULE_DB_END_ID:
|
||||
Measurement->Token = ALit_DB_START;
|
||||
break;
|
||||
|
||||
case MODULE_DB_SUPPORT_START_ID:
|
||||
case MODULE_DB_SUPPORT_END_ID:
|
||||
Measurement->Token = ALit_DB_SUPPORT;
|
||||
break;
|
||||
|
||||
case MODULE_DB_STOP_START_ID:
|
||||
case MODULE_DB_STOP_END_ID:
|
||||
Measurement->Token = ALit_DB_STOP;
|
||||
break;
|
||||
|
||||
default:
|
||||
Measurement->Token = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
|
||||
break;
|
||||
}
|
||||
|
||||
Measurement->Module = ((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->String;
|
||||
|
||||
if (AsciiStrCmp (Measurement->Token, ALit_PEIM) == 0) {
|
||||
Measurement->Handle = &(((FPDT_DYNAMIC_STRING_EVENT_RECORD *)RecordHeader)->Guid);
|
||||
} else {
|
||||
GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
|
||||
Measurement->Handle = StartHandle;
|
||||
}
|
||||
break;
|
||||
|
||||
case FPDT_GUID_QWORD_EVENT_TYPE:
|
||||
ModuleGuid = &(((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Guid);
|
||||
Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->ProgressID);
|
||||
if (IsStart) {
|
||||
Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
|
||||
} else {
|
||||
Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_EVENT_RECORD *)RecordHeader)->Timestamp;
|
||||
}
|
||||
switch (Measurement->Identifier) {
|
||||
case MODULE_DB_START_ID:
|
||||
Measurement->Token = ALit_DB_START;
|
||||
Measurement->Module = ALit_DB_START;
|
||||
break;
|
||||
|
||||
case MODULE_DB_SUPPORT_START_ID:
|
||||
case MODULE_DB_SUPPORT_END_ID:
|
||||
Measurement->Token = ALit_DB_SUPPORT;
|
||||
Measurement->Module = ALit_DB_SUPPORT;
|
||||
break;
|
||||
|
||||
case MODULE_DB_STOP_START_ID:
|
||||
case MODULE_DB_STOP_END_ID:
|
||||
Measurement->Token = ALit_DB_STOP;
|
||||
Measurement->Module = ALit_DB_STOP;
|
||||
break;
|
||||
|
||||
case MODULE_LOADIMAGE_START_ID:
|
||||
case MODULE_LOADIMAGE_END_ID:
|
||||
Measurement->Token = ALit_LOAD_IMAGE;
|
||||
Measurement->Module = ALit_LOAD_IMAGE;
|
||||
break;
|
||||
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
|
||||
Measurement->Handle = StartHandle;
|
||||
break;
|
||||
|
||||
case FPDT_GUID_QWORD_STRING_EVENT_TYPE:
|
||||
ModuleGuid = &(((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Guid);
|
||||
Measurement->Identifier = ((UINT32)((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->ProgressID);
|
||||
if (IsStart) {
|
||||
Measurement->StartTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD*)RecordHeader)->Timestamp;
|
||||
} else {
|
||||
Measurement->EndTimeStamp = ((FPDT_GUID_QWORD_STRING_EVENT_RECORD *)RecordHeader)->Timestamp;
|
||||
}
|
||||
//
|
||||
// Currently only "DB:Start:" end record with FPDT_GUID_QWORD_STRING_EVENT_TYPE.
|
||||
//
|
||||
switch (Measurement->Identifier) {
|
||||
case MODULE_DB_END_ID:
|
||||
Measurement->Token = ALit_DB_START;
|
||||
Measurement->Module = ALit_DB_START;
|
||||
break;
|
||||
default:
|
||||
ASSERT(FALSE);
|
||||
}
|
||||
GetHandleFormModuleGuid(ModuleGuid, &StartHandle);
|
||||
Measurement->Handle = StartHandle;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Search the start measurement in the mMeasurementList for the end measurement.
|
||||
|
||||
@param EndMeasureMent Measurement for end record.
|
||||
|
||||
**/
|
||||
VOID
|
||||
SearchMeasurement (
|
||||
IN MEASUREMENT_RECORD *EndMeasureMent
|
||||
)
|
||||
{
|
||||
INTN Index;
|
||||
|
||||
for (Index = mMeasurementNum - 1; Index >= 0; Index--) {
|
||||
if (AsciiStrCmp (EndMeasureMent->Token, ALit_PEIM) == 0) {
|
||||
if (mMeasurementList[Index].EndTimeStamp == 0 && EndMeasureMent->Handle!= NULL && mMeasurementList[Index].Handle != NULL&&
|
||||
CompareGuid(mMeasurementList[Index].Handle, EndMeasureMent->Handle) &&
|
||||
(AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
|
||||
(AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {
|
||||
mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (mMeasurementList[Index].EndTimeStamp == 0 && mMeasurementList[Index].Handle == EndMeasureMent->Handle &&
|
||||
(AsciiStrCmp (mMeasurementList[Index].Token, EndMeasureMent->Token) == 0) &&
|
||||
(AsciiStrCmp (mMeasurementList[Index].Module, EndMeasureMent->Module) == 0)) {
|
||||
mMeasurementList[Index].EndTimeStamp = EndMeasureMent->EndTimeStamp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Generate the measure record array.
|
||||
|
||||
**/
|
||||
EFI_STATUS
|
||||
BuildMeasurementList (
|
||||
)
|
||||
{
|
||||
EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *RecordHeader;
|
||||
UINT8 *PerformanceTablePtr;
|
||||
UINT16 StartProgressId;
|
||||
UINTN TableLength;
|
||||
UINT8 *StartRecordEvent;
|
||||
MEASUREMENT_RECORD MeasureMent;
|
||||
|
||||
mMeasurementList = AllocateZeroPool (mBootPerformanceTableSize);
|
||||
if (mMeasurementList == NULL) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
TableLength = sizeof (BOOT_PERFORMANCE_TABLE);
|
||||
PerformanceTablePtr = (mBootPerformanceTable + TableLength);
|
||||
|
||||
while (TableLength < mBootPerformanceTableSize) {
|
||||
RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER*) PerformanceTablePtr;
|
||||
StartRecordEvent = (UINT8 *)RecordHeader;
|
||||
StartProgressId = ((FPDT_GUID_EVENT_RECORD *)StartRecordEvent)->ProgressID;
|
||||
|
||||
//
|
||||
// If the record is the start record, fill the info to the measurement in the mMeasurementList.
|
||||
// If the record is the end record, find the related start measurement in the mMeasurementList and fill the EndTimeStamp.
|
||||
//
|
||||
if (((StartProgressId >= PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x000F) == 0)) ||
|
||||
(StartProgressId < PERF_EVENTSIGNAL_START_ID && ((StartProgressId & 0x0001) != 0)))) {
|
||||
//
|
||||
// Since PEIM and StartImage has same Type and ID when PCD PcdEdkiiFpdtStringRecordEnableOnly = FALSE
|
||||
// So we need to identify these two kinds of record through different phase.
|
||||
//
|
||||
if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_PEI) == 0) {
|
||||
mPeiPhase = TRUE;
|
||||
} else if (AsciiStrCmp (((FPDT_DYNAMIC_STRING_EVENT_RECORD *)StartRecordEvent)->String, ALit_DXE) == 0) {
|
||||
mDxePhase = TRUE;
|
||||
mPeiPhase = FALSE;
|
||||
}
|
||||
// Get measurement info form the start record to the mMeasurementList.
|
||||
GetMeasurementInfo (RecordHeader, TRUE, &(mMeasurementList[mMeasurementNum]));
|
||||
mMeasurementNum ++;
|
||||
} else {
|
||||
GetMeasurementInfo (RecordHeader, FALSE, &MeasureMent);
|
||||
SearchMeasurement (&MeasureMent);
|
||||
}
|
||||
TableLength += RecordHeader->Length;
|
||||
PerformanceTablePtr += RecordHeader->Length;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Initialize the cumulative data.
|
||||
|
||||
@ -155,6 +709,7 @@ RunDp (
|
||||
PERF_CUM_DATA *CustomCumulativeData;
|
||||
UINTN NameSize;
|
||||
SHELL_STATUS ShellStatus;
|
||||
TIMER_INFO TimerInfo;
|
||||
|
||||
StringPtr = NULL;
|
||||
SummaryMode = FALSE;
|
||||
@ -174,6 +729,36 @@ RunDp (
|
||||
Status = ShellInitialize();
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
|
||||
//
|
||||
// DP dump performance data by parsing FPDT table in ACPI table.
|
||||
// Folloing 3 steps are to get the measurement form the FPDT table.
|
||||
//
|
||||
|
||||
//
|
||||
//1. Get FPDT from ACPI table.
|
||||
//
|
||||
Status = GetBootPerformanceTable ();
|
||||
if (EFI_ERROR(Status)) {
|
||||
ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GET_BOOT_PERFORMANCE_TABLE_FAIL), mDpHiiHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
//2. Cache the ModuleGuid and hanlde mapping table.
|
||||
//
|
||||
Status = BuildCachedGuidHandleTable();
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
//3. Build the measurement array form the FPDT records.
|
||||
//
|
||||
Status = BuildMeasurementList ();
|
||||
if (EFI_ERROR(Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Process Command Line arguments
|
||||
//
|
||||
@ -267,11 +852,9 @@ RunDp (
|
||||
}
|
||||
|
||||
TimerInfo.Frequency = (UINT32)DivU64x32 (PerformanceProperty->Frequency, 1000);
|
||||
TimerInfo.StartCount = PerformanceProperty->TimerStartValue;
|
||||
TimerInfo.EndCount = PerformanceProperty->TimerEndValue;
|
||||
|
||||
// Determine in which direction the performance counter counts.
|
||||
TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);
|
||||
TimerInfo.StartCount = 0;
|
||||
TimerInfo.EndCount = 0xFFFF;
|
||||
TimerInfo.CountUp = TRUE;
|
||||
|
||||
//
|
||||
// Print header
|
||||
@ -385,6 +968,12 @@ Done:
|
||||
}
|
||||
SHELL_FREE_NON_NULL (CustomCumulativeData);
|
||||
|
||||
SHELL_FREE_NON_NULL (mMeasurementList);
|
||||
|
||||
SHELL_FREE_NON_NULL (mCacheHandleGuidTable);
|
||||
|
||||
mMeasurementNum = 0;
|
||||
mCachePairCount = 0;
|
||||
return ShellStatus;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user