From 3cbfba02fef9dae07a041fdbf2e89611d72d6f90 Mon Sep 17 00:00:00 2001 From: David Wei Date: Mon, 12 Jan 2015 09:37:20 +0000 Subject: Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to https://svn.code.sf.net/p/edk2/code/trunk/edk2/, which are for MinnowBoard MAX open source project. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: David Wei Reviewed-by: Mike Wu Reviewed-by: Hot Tian git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16599 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Library/GenericBdsLib/Performance.c | 358 +++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c (limited to 'Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c') diff --git a/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c b/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c new file mode 100644 index 0000000000..047d2a7dbc --- /dev/null +++ b/Vlv2TbltDevicePkg/Override/IntelFrameworkModulePkg/Library/GenericBdsLib/Performance.c @@ -0,0 +1,358 @@ +/** @file + This file include the file which can help to get the system + performance, all the function will only include if the performance + switch is set. + +Copyright (c) 2004 - 2013, 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 "InternalBdsLib.h" + +PERF_HEADER mPerfHeader; +PERF_DATA mPerfData; +EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase = 0x0FFFFFFFFULL; + +/** + Get the short verion of PDB file name to be + used in performance data logging. + + @param PdbFileName The long PDB file name. + @param GaugeString The output string to be logged by performance logger. + +**/ +VOID +GetShortPdbFileName ( + IN CONST CHAR8 *PdbFileName, + OUT CHAR8 *GaugeString + ) +{ + UINTN Index; + UINTN Index1; + UINTN StartIndex; + UINTN EndIndex; + + if (PdbFileName == NULL) { + AsciiStrCpy (GaugeString, " "); + } else { + StartIndex = 0; + for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++) + ; + + for (Index = 0; PdbFileName[Index] != 0; Index++) { + if (PdbFileName[Index] == '\\') { + StartIndex = Index + 1; + } + + if (PdbFileName[Index] == '.') { + EndIndex = Index; + } + } + + Index1 = 0; + for (Index = StartIndex; Index < EndIndex; Index++) { + GaugeString[Index1] = PdbFileName[Index]; + Index1++; + if (Index1 == PERF_TOKEN_LENGTH - 1) { + break; + } + } + + GaugeString[Index1] = 0; + } + + return ; +} + +/** + Get the name from the Driver handle, which can be a handle with + EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed. + This name can be used in performance data logging. + + @param Handle Driver handle. + @param GaugeString The output string to be logged by performance logger. + +**/ +VOID +GetNameFromHandle ( + IN EFI_HANDLE Handle, + OUT CHAR8 *GaugeString + ) +{ + EFI_STATUS Status; + EFI_LOADED_IMAGE_PROTOCOL *Image; + CHAR8 *PdbFileName; + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + + AsciiStrCpy (GaugeString, " "); + + // + // Get handle name from image protocol + // + Status = gBS->HandleProtocol ( + Handle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &Image + ); + + if (EFI_ERROR (Status)) { + Status = gBS->OpenProtocol ( + Handle, + &gEfiDriverBindingProtocolGuid, + (VOID **) &DriverBinding, + NULL, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return ; + } + // + // Get handle name from image protocol + // + Status = gBS->HandleProtocol ( + DriverBinding->ImageHandle, + &gEfiLoadedImageProtocolGuid, + (VOID **) &Image + ); + } + + PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase); + + if (PdbFileName != NULL) { + GetShortPdbFileName (PdbFileName, GaugeString); + } + + return ; +} + +/** + + Writes performance data of booting into the allocated memory. + OS can process these records. + + @param Event The triggered event. + @param Context Context for this event. + +**/ +VOID +EFIAPI +WriteBootToOsPerformanceData ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + UINT32 LimitCount; + EFI_HANDLE *Handles; + UINTN NoHandles; + CHAR8 GaugeString[PERF_TOKEN_LENGTH]; + UINT8 *Ptr; + UINT32 Index; + UINT64 Ticker; + UINT64 Freq; + UINT32 Duration; + UINTN LogEntryKey; + CONST VOID *Handle; + CONST CHAR8 *Token; + CONST CHAR8 *Module; + UINT64 StartTicker; + UINT64 EndTicker; + UINT64 StartValue; + UINT64 EndValue; + BOOLEAN CountUp; + UINTN EntryIndex; + UINTN NumPerfEntries; + // + // List of flags indicating PerfEntry contains DXE handle + // + BOOLEAN *PerfEntriesAsDxeHandle; + UINTN VarSize; + + // + // Record the performance data for End of BDS + // + PERF_END(NULL, "BDS", NULL, 0); + + // + // Retrieve time stamp count as early as possible + // + Ticker = GetPerformanceCounter (); + + Freq = GetPerformanceCounterProperties (&StartValue, &EndValue); + + Freq = DivU64x32 (Freq, 1000); + + mPerfHeader.CpuFreq = Freq; + + // + // Record BDS raw performance data + // + if (EndValue >= StartValue) { + mPerfHeader.BDSRaw = Ticker - StartValue; + CountUp = TRUE; + } else { + mPerfHeader.BDSRaw = StartValue - Ticker; + CountUp = FALSE; + } + + if (mAcpiLowMemoryBase == 0x0FFFFFFFF) { + VarSize = sizeof (EFI_PHYSICAL_ADDRESS); + Status = gRT->GetVariable ( + L"PerfDataMemAddr", + &gPerformanceProtocolGuid, + NULL, + &VarSize, + &mAcpiLowMemoryBase + ); + if (EFI_ERROR (Status)) { + // + // Fail to get the variable, return. + // + return; + } + } + + // + // Put Detailed performance data into memory + // + Handles = NULL; + Status = gBS->LocateHandleBuffer ( + AllHandles, + NULL, + NULL, + &NoHandles, + &Handles + ); + if (EFI_ERROR (Status)) { + return ; + } + + Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER)); + LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA); + + NumPerfEntries = 0; + LogEntryKey = 0; + while ((LogEntryKey = GetPerformanceMeasurement ( + LogEntryKey, + &Handle, + &Token, + &Module, + &StartTicker, + &EndTicker)) != 0) { + NumPerfEntries++; + } + PerfEntriesAsDxeHandle = AllocateZeroPool (NumPerfEntries * sizeof (BOOLEAN)); + ASSERT (PerfEntriesAsDxeHandle != NULL); + + // + // Get DXE drivers performance + // + for (Index = 0; Index < NoHandles; Index++) { + Ticker = 0; + LogEntryKey = 0; + EntryIndex = 0; + while ((LogEntryKey = GetPerformanceMeasurement ( + LogEntryKey, + &Handle, + &Token, + &Module, + &StartTicker, + &EndTicker)) != 0) { + if (Handle == Handles[Index] && !PerfEntriesAsDxeHandle[EntryIndex]) { + PerfEntriesAsDxeHandle[EntryIndex] = TRUE; + } + EntryIndex++; + if ((Handle == Handles[Index]) && (EndTicker != 0)) { + if (StartTicker == 1) { + StartTicker = StartValue; + } + if (EndTicker == 1) { + EndTicker = StartValue; + } + Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker); + } + } + + Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq); + + if (Duration > 0) { + + GetNameFromHandle (Handles[Index], GaugeString); + + AsciiStrCpy (mPerfData.Token, GaugeString); + mPerfData.Duration = Duration; + + CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA)); + Ptr += sizeof (PERF_DATA); + + mPerfHeader.Count++; + if (mPerfHeader.Count == LimitCount) { + goto Done; + } + } + } + + // + // Get inserted performance data + // + LogEntryKey = 0; + EntryIndex = 0; + while ((LogEntryKey = GetPerformanceMeasurement ( + LogEntryKey, + &Handle, + &Token, + &Module, + &StartTicker, + &EndTicker)) != 0) { + if (!PerfEntriesAsDxeHandle[EntryIndex] && EndTicker != 0) { + + ZeroMem (&mPerfData, sizeof (PERF_DATA)); + + AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH); + if (StartTicker == 1) { + StartTicker = StartValue; + } + if (EndTicker == 1) { + EndTicker = StartValue; + } + Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker); + + mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq); + + CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA)); + Ptr += sizeof (PERF_DATA); + + mPerfHeader.Count++; + if (mPerfHeader.Count == LimitCount) { + goto Done; + } + } + EntryIndex++; + } + +Done: + + FreePool (Handles); + FreePool (PerfEntriesAsDxeHandle); + + mPerfHeader.Signiture = PERFORMANCE_SIGNATURE; + + // + // Put performance data to Reserved memory + // + CopyMem ( + (UINTN *) (UINTN) mAcpiLowMemoryBase, + &mPerfHeader, + sizeof (PERF_HEADER) + ); + + return ; +} -- cgit v1.2.3