+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- Perf.c\r
-\r
-Abstract:\r
-\r
- Support for Performance primatives. \r
-\r
---*/\r
-\r
-#include "Tiano.h"\r
-#include "EfiDriverLib.h"\r
-#include EFI_PROTOCOL_DEFINITION (Performance)\r
-#include EFI_PROTOCOL_DEFINITION (LoadedImage)\r
-#include EFI_GUID_DEFINITION (Hob)\r
-#include EFI_GUID_DEFINITION (PeiPerformanceHob)\r
-#include "LinkedList.h"\r
-#include "EfiHobLib.h"\r
-#include "EfiImage.h"\r
-\r
-EFI_STATUS\r
-GetTimerValue (\r
- OUT UINT64 *TimerValue\r
- );\r
-\r
-EFI_STATUS\r
-GetPeiPerformance (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable,\r
- IN UINT64 Ticker\r
- );\r
-\r
-#define EFI_PERFORMANCE_DATA_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'D', 'A')\r
-\r
-typedef struct {\r
- UINT32 Signature;\r
- EFI_LIST_ENTRY Link;\r
- EFI_GAUGE_DATA GaugeData;\r
-} EFI_PERF_DATA_LIST;\r
-\r
-#define GAUGE_DATA_FROM_LINK(_link) \\r
- CR(_link, EFI_PERF_DATA_LIST, Link, EFI_PERFORMANCE_DATA_SIGNATURE)\r
-\r
-#define GAUGE_DATA_FROM_GAUGE(_GaugeData) \\r
- CR(_GaugeData, EFI_PERF_DATA_LIST, GaugeData, EFI_PERFORMANCE_DATA_SIGNATURE)\r
-\r
-#define EFI_PERFORMANCE_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'R', 'F')\r
-\r
-//\r
-// Performance protocol instance data structure\r
-//\r
-typedef struct {\r
- UINTN Signature;\r
- EFI_HANDLE Handle;\r
- EFI_PERFORMANCE_PROTOCOL Perf;\r
- UINT8 Phase;\r
-} EFI_PERFORMANCE_INSTANCE;\r
-\r
-//\r
-// Performace protocol instance containing record macro\r
-//\r
-\r
-#define EFI_PERFORMANCE_FROM_THIS(a) \\r
- CR(a, EFI_PERFORMANCE_INSTANCE, Perf, EFI_PERFORMANCE_SIGNATURE)\r
-\r
-EFI_LIST_ENTRY mPerfDataHead = INITIALIZE_LIST_HEAD_VARIABLE(mPerfDataHead);\r
-\r
-STATIC\r
-VOID\r
-GetShortPdbFileName (\r
- CHAR8 *PdbFileName,\r
- CHAR8 *GaugeString\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
-Arguments:\r
-\r
-Returns:\r
-\r
---*/\r
-{\r
- UINTN Index;\r
- UINTN Index1;\r
- UINTN StartIndex;\r
- UINTN EndIndex;\r
-\r
- if (PdbFileName == NULL) {\r
- EfiAsciiStrCpy (GaugeString, (CHAR8 *)" ");\r
- } else {\r
- StartIndex = 0;\r
- for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)\r
- ;\r
-\r
- for (Index = 0; PdbFileName[Index] != 0; Index++) {\r
- if (PdbFileName[Index] == '\\') {\r
- StartIndex = Index + 1;\r
- }\r
-\r
- if (PdbFileName[Index] == '.') {\r
- EndIndex = Index;\r
- }\r
- }\r
-\r
- Index1 = 0;\r
- for (Index = StartIndex; Index < EndIndex; Index++) {\r
- GaugeString[Index1] = PdbFileName[Index];\r
- Index1++;\r
- if (Index1 == EFI_PERF_PDBFILENAME_LENGTH - 1) {\r
- break;\r
- }\r
- }\r
-\r
- GaugeString[Index1] = 0;\r
- }\r
-\r
- return ;\r
-}\r
-\r
-STATIC\r
-CHAR8 *\r
-GetPdbPath (\r
- VOID *ImageBase\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Located PDB path name in PE image\r
-\r
-Arguments:\r
-\r
- ImageBase - base of PE to search\r
-\r
-Returns:\r
-\r
- Pointer into image at offset of PDB file name if PDB file name is found,\r
- Otherwise a pointer to an empty string.\r
-\r
---*/\r
-{\r
- CHAR8 *PdbPath;\r
- UINT32 DirCount;\r
- EFI_IMAGE_DOS_HEADER *DosHdr;\r
- EFI_IMAGE_NT_HEADERS *NtHdr;\r
- UINT16 Magic;\r
- EFI_IMAGE_OPTIONAL_HEADER32 *OptionalHdr32;\r
- EFI_IMAGE_OPTIONAL_HEADER64 *OptionalHdr64;\r
- EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;\r
- EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;\r
- VOID *CodeViewEntryPointer;\r
-\r
- CodeViewEntryPointer = NULL;\r
- PdbPath = NULL;\r
- DosHdr = ImageBase;\r
- if (DosHdr && DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
- NtHdr = (EFI_IMAGE_NT_HEADERS *) ((UINT8 *) DosHdr + DosHdr->e_lfanew);\r
- //\r
- // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.\r
- // It is for backward-compatibility consideration, because\r
- // some system will generate PE32+ image with PE32 Magic.\r
- //\r
- if (NtHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {\r
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;\r
- } else if (NtHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {\r
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- } else if (NtHdr->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {\r
- Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;\r
- } else {\r
- Magic = NtHdr->OptionalHeader.Magic;\r
- }\r
- if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- OptionalHdr32 = (VOID *) &NtHdr->OptionalHeader;\r
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr32->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
- } else {\r
- OptionalHdr64 = (VOID *) &NtHdr->OptionalHeader;\r
- DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr64->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);\r
- }\r
- \r
- if (DirectoryEntry->VirtualAddress != 0) {\r
- for (DirCount = 0;\r
- (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;\r
- DirCount++\r
- ) {\r
- DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (DirectoryEntry->VirtualAddress + (UINTN) ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));\r
- if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {\r
- CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageBase);\r
- switch (*(UINT32 *) CodeViewEntryPointer) {\r
- case CODEVIEW_SIGNATURE_NB10:\r
- PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);\r
- break;\r
-\r
- case CODEVIEW_SIGNATURE_RSDS:\r
- PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- return PdbPath;\r
-}\r
-\r
-STATIC\r
-VOID\r
-GetNameFromHandle (\r
- IN EFI_HANDLE Handle,\r
- OUT CHAR8 *GaugeString\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_LOADED_IMAGE_PROTOCOL *Image;\r
- CHAR8 *PdbFileName;\r
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
-\r
- EfiAsciiStrCpy (GaugeString, (CHAR8 *)" ");\r
-\r
- //\r
- // Get handle name from image protocol\r
- //\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiLoadedImageProtocolGuid,\r
- (VOID**)&Image\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- Status = gBS->OpenProtocol (\r
- Handle,\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID **) &DriverBinding,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
- //\r
- // Get handle name from image protocol\r
- //\r
- Status = gBS->HandleProtocol (\r
- DriverBinding->ImageHandle,\r
- &gEfiLoadedImageProtocolGuid,\r
- (VOID**)&Image\r
- );\r
- }\r
-\r
- PdbFileName = GetPdbPath (Image->ImageBase);\r
-\r
- if (PdbFileName != NULL) {\r
- GetShortPdbFileName (PdbFileName, GaugeString);\r
- }\r
-\r
- return ;\r
-}\r
-\r
-EFI_PERF_DATA_LIST *\r
-CreateDataNode (\r
- IN EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Create a EFI_PERF_DATA_LIST data node.\r
-\r
-Arguments:\r
-\r
- Handle - Handle of gauge data\r
- Token - Token of gauge data\r
- Host - Host of gauge data\r
-\r
-Returns:\r
-\r
- Pointer to a data node created.\r
-\r
---*/\r
-{\r
- EFI_PERF_DATA_LIST *Node;\r
-\r
- //\r
- // Al\ a new image structure\r
- //\r
- Node = EfiLibAllocateZeroPool (sizeof (EFI_PERF_DATA_LIST));\r
- if (Node != NULL) {\r
-\r
- Node->Signature = EFI_PERFORMANCE_DATA_SIGNATURE;\r
-\r
- Node->GaugeData.Handle = Handle;\r
-\r
- if (Token != NULL) {\r
- EfiStrCpy ((Node->GaugeData).Token, Token);\r
- }\r
-\r
- if (Host != NULL) {\r
- EfiStrCpy ((Node->GaugeData).Host, Host);\r
- }\r
-\r
- if (Handle != NULL) {\r
- GetNameFromHandle (Handle, Node->GaugeData.PdbFileName);\r
- }\r
- }\r
-\r
- return Node;\r
-}\r
-\r
-\r
-EFI_PERF_DATA_LIST *\r
-GetDataNode (\r
- IN EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host,\r
- IN EFI_GUID *GuidName,\r
- IN EFI_GAUGE_DATA *PrevGauge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Search gauge node list to find one node with matched handle, token, host and Guid name.\r
-\r
-Arguments:\r
-\r
- Handle - Handle to match\r
- Token - Token to match\r
- Host - Host to match\r
- GuidName - Guid name to match\r
- PrevGauge - Start node, start from list head if NULL\r
-\r
-Returns:\r
-\r
- Return pointer to the node found, NULL if not found.\r
-\r
---*/\r
-{\r
- EFI_PERF_DATA_LIST *Node;\r
- EFI_PERF_DATA_LIST *Temp;\r
- EFI_PERF_DATA_LIST *Temp2;\r
- EFI_LIST_ENTRY *CurrentLink;\r
- EFI_GUID NullGuid = EFI_NULL_GUID;\r
-\r
- Node = NULL;\r
- Temp = NULL;\r
- Temp2 = NULL;\r
-\r
- if (PrevGauge == NULL) {\r
- CurrentLink = mPerfDataHead.ForwardLink;\r
- } else {\r
- Temp2 = GAUGE_DATA_FROM_GAUGE (PrevGauge);\r
- CurrentLink = (Temp2->Link).ForwardLink;\r
- }\r
-\r
- while (CurrentLink && CurrentLink != &mPerfDataHead) {\r
- Node = GAUGE_DATA_FROM_LINK (CurrentLink);\r
-\r
- if (Handle == 0 && Token == NULL && Host == NULL && GuidName == NULL) {\r
- return Node;\r
- }\r
-\r
- if (Handle != (Node->GaugeData).Handle) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if (GuidName == NULL && !EfiCompareGuid (&((Node->GaugeData).GuidName), &NullGuid)) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if (GuidName && !EfiCompareGuid (&((Node->GaugeData).GuidName), GuidName)) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if (Token == NULL && EfiStrCmp (Node->GaugeData.Token, L"")) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if (Token && EfiStrCmp (Node->GaugeData.Token, Token)) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if (Host == NULL && EfiStrCmp (Node->GaugeData.Host, L"")) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- if (Host && EfiStrCmp (Node->GaugeData.Host, Host)) {\r
- CurrentLink = CurrentLink->ForwardLink;\r
- continue;\r
- }\r
-\r
- Temp = Node;\r
- break;\r
- }\r
-\r
- return Temp;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-StartGauge (\r
- IN EFI_PERFORMANCE_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host,\r
- IN UINT64 Ticker\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Create a guage data node and initialized it.\r
-\r
-Arguments:\r
-\r
- This - Calling context\r
- Handle - Handle of gauge data\r
- Token - Token of gauge data\r
- Host - Host of gauge data\r
- Ticker - Set gauge data's StartTick. If 0, StartTick is current timer.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS - Successfully create and initialized a guage data node.\r
- EFI_OUT_OF_RESOURCES - No enough resource to create a guage data node.\r
-\r
---*/\r
-{\r
- EFI_PERFORMANCE_INSTANCE *PerfInstance;\r
- EFI_PERF_DATA_LIST *Node;\r
- UINT64 TimerValue;\r
-\r
- TimerValue = 0;\r
- PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);\r
-\r
- Node = CreateDataNode (Handle, Token, Host);\r
- if (!Node) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- if (Ticker != 0) {\r
- TimerValue = Ticker;\r
- } else {\r
- GetTimerValue (&TimerValue);\r
- }\r
-\r
- Node->GaugeData.StartTick = TimerValue;\r
-\r
- if (!EfiStrCmp (Token, DXE_TOK)) {\r
- PerfInstance->Phase = DXE_PHASE;\r
- }\r
-\r
- if (!EfiStrCmp (Token, SHELL_TOK)) {\r
- PerfInstance->Phase = SHELL_PHASE;\r
- }\r
-\r
- Node->GaugeData.Phase = PerfInstance->Phase;\r
-\r
- InsertTailList (&mPerfDataHead, &(Node->Link));\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-EndGauge (\r
- IN EFI_PERFORMANCE_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host,\r
- IN UINT64 Ticker\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- End all unfinished gauge data node that match specified handle, token and host.\r
-\r
-Arguments:\r
-\r
- This - Calling context\r
- Handle - Handle to stop\r
- Token - Token to stop\r
- Host - Host to stop\r
- Ticker - End tick, if 0 then get current timer\r
-\r
-Returns:\r
-\r
- EFI_NOT_FOUND - Node not found\r
- EFI_SUCCESS - Gauge data node successfully ended.\r
-\r
---*/\r
-{\r
- EFI_PERF_DATA_LIST *Node;\r
- UINT64 TimerValue;\r
-\r
- TimerValue = 0;\r
-\r
- Node = GetDataNode (Handle, Token, Host, NULL, NULL);\r
- if (!Node) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- while (Node->GaugeData.EndTick != 0) {\r
- Node = GetDataNode (Handle, Token, Host, NULL, &(Node->GaugeData));\r
- if (!Node) {\r
- return EFI_NOT_FOUND;\r
- }\r
- }\r
-\r
- if (Ticker != 0) {\r
- TimerValue = Ticker;\r
- } else {\r
- GetTimerValue (&TimerValue);\r
- }\r
-\r
- Node->GaugeData.EndTick = TimerValue;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_GAUGE_DATA *\r
-EFIAPI\r
-GetGauge (\r
- IN EFI_PERFORMANCE_PROTOCOL *This,\r
- IN EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host,\r
- IN EFI_GAUGE_DATA *PrevGauge\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Get gauge.\r
-\r
-Arguments:\r
- This - A pointer to the EFI_PERFORMANCE_PROTOCOL.\r
- Handle - A pointer of a efi handle.\r
- Token - A pointer to the token.\r
- Host - A pointer to the host.\r
- PrevGauge - A pointer to the EFI_GAUGE_DATA structure.\r
-\r
-\r
-Returns:\r
- Status code.\r
-\r
---*/\r
-{\r
- EFI_PERF_DATA_LIST *Node;\r
-\r
- Node = GetDataNode (Handle, Token, Host, NULL, PrevGauge);\r
- if (Node != NULL) {\r
- return &(Node->GaugeData);\r
- } else {\r
- return NULL;\r
- }\r
-}\r
-\r
-//\r
-// Driver entry point\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-InitializePerformanceInfrastructure (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable,\r
- IN UINT64 Ticker\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Install gEfiPerformanceProtocolGuid protocol and transfer PEI performance to gauge data nodes.\r
-\r
-Arguments:\r
-\r
- ImageHandle - Standard driver entry point parameter\r
- SystemTable - Standard driver entry point parameter\r
- Ticker - End tick for PEI performance\r
-\r
-Returns:\r
-\r
- EFI_OUT_OF_RESOURCES - No enough buffer to allocate\r
- EFI_SUCCESS - Protocol installed.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_PERFORMANCE_INSTANCE *PerfInstance;\r
-\r
- //\r
- // Allocate a new image structure\r
- //\r
- PerfInstance = EfiLibAllocateZeroPool (sizeof (EFI_PERFORMANCE_INSTANCE));\r
- if (PerfInstance == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- PerfInstance->Signature = EFI_PERFORMANCE_SIGNATURE;\r
- PerfInstance->Perf.StartGauge = StartGauge;\r
- PerfInstance->Perf.EndGauge = EndGauge;\r
- PerfInstance->Perf.GetGauge = GetGauge;\r
-\r
- //\r
- // Install the protocol interfaces\r
- //\r
- Status = gBS->InstallProtocolInterface (\r
- &PerfInstance->Handle,\r
- &gEfiPerformanceProtocolGuid,\r
- EFI_NATIVE_INTERFACE,\r
- &PerfInstance->Perf\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- GetPeiPerformance (ImageHandle, SystemTable, Ticker);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-StartMeasure (\r
- EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host,\r
- IN UINT64 Ticker\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Start to gauge on a specified handle, token and host, with Ticker as start tick.\r
-\r
-Arguments:\r
-\r
- Handle - Handle to measure\r
- Token - Token to measure\r
- Host - Host to measure\r
- Ticker - Ticker as start tick\r
-\r
-Returns:\r
-\r
- Status code.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_PERFORMANCE_PROTOCOL *Perf;\r
-\r
- Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- return Perf->StartGauge (Perf, Handle, Token, Host, Ticker);\r
-\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-EndMeasure (\r
- EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host,\r
- IN UINT64 Ticker\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- End gauging on a specified handle, token and host, with Ticker as end tick.\r
-\r
-Arguments:\r
-\r
- Handle - Handle to stop\r
- Token - Token to stop\r
- Host - Host to stop\r
- Ticker - Ticker as end tick\r
-\r
-Returns:\r
-\r
- Status code.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_PERFORMANCE_PROTOCOL *Perf;\r
-\r
- Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);\r
- if (Status != EFI_SUCCESS) {\r
- return Status;\r
- }\r
-\r
- return (Perf->EndGauge( Perf, Handle, Token, Host, Ticker)) ;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-UpdateMeasure (\r
- EFI_HANDLE Handle,\r
- IN UINT16 *Token,\r
- IN UINT16 *Host,\r
- EFI_HANDLE HandleNew,\r
- IN UINT16 *TokenNew,\r
- IN UINT16 *HostNew\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- Update measure.\r
-\r
-Arguments:\r
- Handle - A pointer of an efi handle.\r
- Token - A pointer to the token.\r
- Host - A pointer to the host.\r
- HandleNew - A pointer of an new efi handle.\r
- TokenNew - A pointer to the new token.\r
- HostNew - A pointer to the new host.\r
-\r
-Returns:\r
- Status code.\r
-\r
- EFI_NOT_FOUND - The speicified gauge data node not found.\r
- \r
- EFI_SUCCESS - Update successfully.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_GAUGE_DATA *GaugeData;\r
- EFI_PERFORMANCE_PROTOCOL *Perf;\r
-\r
- Status = gBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- GaugeData = Perf->GetGauge (Perf, Handle, Token, Host, NULL);\r
- if (!GaugeData) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- GaugeData->Handle = HandleNew;\r
- if (HostNew != NULL) {\r
- EfiStrCpy (GaugeData->Host, HostNew);\r
- } else {\r
- EfiStrCpy (GaugeData->Host, L"");\r
- }\r
-\r
- if (TokenNew != NULL) {\r
- EfiStrCpy (GaugeData->Token, TokenNew);\r
- } else {\r
- EfiStrCpy (GaugeData->Token, L"");\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-\r
-EFI_STATUS\r
-GetPeiPerformance (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable,\r
- IN UINT64 Ticker\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Transfer PEI performance data to gauge data node.\r
-\r
-Arguments:\r
-\r
- ImageHandle - Standard entry point parameter\r
- SystemTable - Standard entry point parameter\r
- Ticker - Start tick\r
-\r
-Returns:\r
-\r
- EFI_OUT_OF_RESOURCES - No enough resource to create data node.\r
- EFI_SUCCESS - Transfer done successfully.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- VOID *HobList;\r
- EFI_HOB_GUID_DATA_PERFORMANCE_LOG *LogHob;\r
- PEI_PERFORMANCE_MEASURE_LOG_ENTRY *LogEntry;\r
- UINT32 Index;\r
- EFI_PERF_DATA_LIST *Node;\r
- UINT64 TimerValue;\r
-\r
- Node = CreateDataNode (0, PEI_TOK, NULL);\r
- if (!Node) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // Initialize 'LogHob' to NULL before usage.\r
- //\r
- LogHob = NULL;\r
-\r
- if (Ticker != 0) {\r
- TimerValue = Ticker;\r
- } else {\r
- GetTimerValue (&TimerValue);\r
- }\r
- (Node->GaugeData).EndTick = TimerValue;\r
-\r
- InsertTailList (&mPerfDataHead, &(Node->Link));\r
-\r
- EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);\r
- do {\r
- Status = GetNextGuidHob (&HobList, &gEfiPeiPerformanceHobGuid, (VOID **) &LogHob, NULL);\r
- if (EFI_ERROR (Status) || (LogHob == NULL)) {\r
- //\r
- // Failed to get HOB for ProtocolGuid.\r
- //\r
- break;\r
- }\r
-\r
- for (Index = 0; Index < LogHob->NumberOfEntries; Index++) {\r
- LogEntry = &(LogHob->Log[Index]);\r
- Node = CreateDataNode (0, LogEntry->DescriptionString, NULL);\r
- if (!Node) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
- (Node->GaugeData).StartTick = LogEntry->StartTimeCount;\r
-\r
- EfiCopyMem (&(Node->GaugeData.GuidName), &LogEntry->Name, sizeof (EFI_GUID));\r
-\r
- InsertTailList (&mPerfDataHead, &(Node->Link));\r
-\r
- (Node->GaugeData).EndTick = LogEntry->StopTimeCount;\r
- }\r
- } while (!EFI_ERROR (Status));\r
-\r
- return EFI_SUCCESS;\r
-}\r