mirror of https://github.com/acidanthera/audk.git
235 lines
6.9 KiB
C
235 lines
6.9 KiB
C
/*++
|
|
|
|
Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
|
|
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:
|
|
|
|
Perf.c
|
|
|
|
Abstract:
|
|
|
|
Support for performance primitives.
|
|
|
|
--*/
|
|
|
|
#include "Tiano.h"
|
|
#include "Pei.h"
|
|
#include "PeiLib.h"
|
|
#include "PeiHob.h"
|
|
|
|
#include EFI_GUID_DEFINITION (PeiPerformanceHob)
|
|
|
|
//
|
|
// Perfomance HOB data definitions
|
|
//
|
|
|
|
#define MAX_PEI_PERF_LOG_ENTRIES 28
|
|
|
|
//
|
|
// Prototype functions
|
|
//
|
|
EFI_STATUS
|
|
GetTimerValue (
|
|
OUT UINT64 *TimerValue
|
|
);
|
|
|
|
|
|
VOID
|
|
EFIAPI
|
|
PeiPerfMeasure (
|
|
EFI_PEI_SERVICES **PeiServices,
|
|
IN UINT16 *Token,
|
|
IN EFI_FFS_FILE_HEADER *FileHeader,
|
|
IN BOOLEAN EntryExit,
|
|
IN UINT64 Value
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Log a timestamp count.
|
|
|
|
Arguments:
|
|
|
|
PeiServices - Pointer to the PEI Core Services table
|
|
|
|
Token - Pointer to Token Name
|
|
|
|
FileHeader - Pointer to the file header
|
|
|
|
EntryExit - Indicates start or stop measurement
|
|
|
|
Value - The start time or the stop time
|
|
|
|
Returns:
|
|
|
|
--*/
|
|
{
|
|
EFI_STATUS Status;
|
|
EFI_HOB_GUID_TYPE *Hob;
|
|
EFI_HOB_GUID_DATA_PERFORMANCE_LOG *PerfHobData;
|
|
PEI_PERFORMANCE_MEASURE_LOG_ENTRY *Log;
|
|
EFI_PEI_PPI_DESCRIPTOR *PerfHobDescriptor;
|
|
UINT64 TimeCount;
|
|
INTN Index;
|
|
UINTN Index2;
|
|
EFI_GUID *Guid;
|
|
EFI_GUID *CheckGuid;
|
|
|
|
TimeCount = 0;
|
|
//
|
|
// Get the END time as early as possible to make it more accurate.
|
|
//
|
|
if (EntryExit) {
|
|
GetTimerValue (&TimeCount);
|
|
}
|
|
|
|
//
|
|
// Locate the Pei Performance Log Hob.
|
|
//
|
|
Status = (*PeiServices)->LocatePpi (
|
|
PeiServices,
|
|
&gEfiPeiPerformanceHobGuid,
|
|
0,
|
|
&PerfHobDescriptor,
|
|
NULL
|
|
);
|
|
|
|
//
|
|
// If the Performance Hob was not found, build and install one.
|
|
//
|
|
if (EFI_ERROR(Status)) {
|
|
Status = PeiBuildHobGuid (
|
|
PeiServices,
|
|
&gEfiPeiPerformanceHobGuid,
|
|
(sizeof(EFI_HOB_GUID_DATA_PERFORMANCE_LOG) +
|
|
((MAX_PEI_PERF_LOG_ENTRIES-1) *
|
|
sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY)) +
|
|
sizeof(EFI_PEI_PPI_DESCRIPTOR)
|
|
),
|
|
(VOID **) &Hob
|
|
);
|
|
ASSERT_PEI_ERROR((CONST EFI_PEI_SERVICES **) PeiServices, Status);
|
|
|
|
PerfHobData = (EFI_HOB_GUID_DATA_PERFORMANCE_LOG *)(Hob+1);
|
|
PerfHobData->NumberOfEntries = 0;
|
|
|
|
PerfHobDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)((UINT8 *)(PerfHobData+1) +
|
|
(sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY) *
|
|
(MAX_PEI_PERF_LOG_ENTRIES-1)
|
|
)
|
|
);
|
|
PerfHobDescriptor->Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
|
|
PerfHobDescriptor->Guid = &gEfiPeiPerformanceHobGuid;
|
|
PerfHobDescriptor->Ppi = NULL;
|
|
|
|
(*PeiServices)->InstallPpi (
|
|
PeiServices,
|
|
PerfHobDescriptor
|
|
);
|
|
}
|
|
|
|
PerfHobData = (EFI_HOB_GUID_DATA_PERFORMANCE_LOG *)(((UINT8 *)(PerfHobDescriptor)) -
|
|
((sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY) *
|
|
(MAX_PEI_PERF_LOG_ENTRIES-1)
|
|
)
|
|
+ sizeof(EFI_HOB_GUID_DATA_PERFORMANCE_LOG)
|
|
)
|
|
);
|
|
|
|
if (PerfHobData->NumberOfEntries >= MAX_PEI_PERF_LOG_ENTRIES) {
|
|
return;
|
|
}
|
|
|
|
if (!EntryExit) {
|
|
Log = &(PerfHobData->Log[PerfHobData->NumberOfEntries]);
|
|
(*PeiServices)->SetMem (Log, sizeof(PEI_PERFORMANCE_MEASURE_LOG_ENTRY), 0);
|
|
|
|
//
|
|
// If not NULL pointer, copy the file name
|
|
//
|
|
if (FileHeader != NULL) {
|
|
Log->Name = FileHeader->Name;
|
|
}
|
|
|
|
//
|
|
// Copy the description string
|
|
//
|
|
(*PeiServices)->CopyMem (
|
|
&(Log->DescriptionString),
|
|
Token,
|
|
(PEI_PERF_MAX_DESC_STRING-1) * sizeof(UINT16)
|
|
);
|
|
|
|
//
|
|
// Get the start time as late as possible to make it more accurate.
|
|
//
|
|
GetTimerValue (&TimeCount);
|
|
|
|
//
|
|
// Record the time stamp.
|
|
//
|
|
if (Value != 0) {
|
|
Log->StartTimeCount = Value;
|
|
} else {
|
|
Log->StartTimeCount = TimeCount;
|
|
}
|
|
Log->StopTimeCount = 0;
|
|
|
|
//
|
|
// Increment the number of valid log entries.
|
|
//
|
|
PerfHobData->NumberOfEntries++;
|
|
|
|
} else {
|
|
|
|
for (Index = PerfHobData->NumberOfEntries-1; Index >= 0; Index--) {
|
|
Log = NULL;
|
|
for (Index2 = 0; Index2 < PEI_PERF_MAX_DESC_STRING; Index2++) {
|
|
if (PerfHobData->Log[Index].DescriptionString[Index2] == 0) {
|
|
Log = &(PerfHobData->Log[Index]);
|
|
break;
|
|
}
|
|
if (PerfHobData->Log[Index].DescriptionString[Index2] !=
|
|
Token[Index2]) {
|
|
break;
|
|
}
|
|
}
|
|
if (Log != NULL) {
|
|
if (FileHeader != NULL) {
|
|
Guid = &(Log->Name);
|
|
CheckGuid = &(FileHeader->Name);
|
|
if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
|
|
(((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
|
|
(((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
|
|
(((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {
|
|
if (Value != 0) {
|
|
Log->StopTimeCount = Value;
|
|
} else {
|
|
Log->StopTimeCount = TimeCount;
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
if (Value != 0) {
|
|
Log->StopTimeCount = Value;
|
|
} else {
|
|
Log->StopTimeCount = TimeCount;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
|
}
|