+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. 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
- Performance.c\r
-\r
-Abstract:\r
-\r
- This file include the file which can help to get the system\r
- performance, all the function will only include if the performance\r
- switch is set.\r
-\r
---*/\r
-\r
-#include "Performance.h"\r
-\r
-VOID\r
-ClearDebugRegisters (\r
- VOID\r
- )\r
-{\r
- //\r
- // BugBug: We should not need to do this. We need to root cause this bug!!!!\r
- //\r
- AsmWriteDr0 (0);\r
- AsmWriteDr1 (0);\r
-}\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
- AsciiStrCpy (GaugeString, " ");\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 == PERF_TOKEN_LENGTH - 1) {\r
- break;\r
- }\r
- }\r
-\r
- GaugeString[Index1] = 0;\r
- }\r
-\r
- return ;\r
-}\r
-\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
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
-\r
- ZeroMem (&ImageContext, sizeof (ImageContext));\r
- ImageContext.Handle = ImageBase;\r
- ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;\r
-\r
- PeCoffLoaderGetImageInfo (&ImageContext);\r
-\r
- return ImageContext.PdbPointer;\r
-}\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
- AsciiStrCpy (GaugeString, " ");\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
-\r
-\r
-VOID\r
-WriteBootToOsPerformanceData (\r
- VOID\r
- )\r
-/*++\r
-\r
-Routine Description:\r
- \r
- Allocates a block of memory and writes performance data of booting to OS into it.\r
-\r
-Arguments:\r
- \r
- None\r
- \r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- EFI_CPU_ARCH_PROTOCOL *Cpu;\r
- EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase;\r
- UINT32 mAcpiLowMemoryLength;\r
- UINT32 LimitCount;\r
- PERF_HEADER mPerfHeader;\r
- PERF_DATA mPerfData;\r
- EFI_HANDLE *Handles;\r
- UINTN NoHandles;\r
- CHAR8 GaugeString[PERF_TOKEN_LENGTH];\r
- UINT8 *Ptr;\r
- UINT32 mIndex;\r
- UINT64 Ticker;\r
- UINT64 Freq;\r
- UINT32 Duration;\r
- UINT64 CurrentTicker;\r
- UINT64 TimerPeriod;\r
- UINTN LogEntryKey;\r
- CONST VOID *Handle;\r
- CONST CHAR8 *Token;\r
- CONST CHAR8 *Module;\r
- UINT64 StartTicker;\r
- UINT64 EndTicker;\r
-\r
- //\r
- // Retrive time stamp count as early as possilbe\r
- //\r
- Ticker = AsmReadTsc ();\r
-\r
- //\r
- // Allocate a block of memory that contain performance data to OS\r
- //\r
- mAcpiLowMemoryBase = 0xFFFFFFFF;\r
- Status = gBS->AllocatePages (\r
- AllocateMaxAddress,\r
- EfiReservedMemoryType,\r
- 4,\r
- &mAcpiLowMemoryBase\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return ;\r
- }\r
-\r
- mAcpiLowMemoryLength = EFI_PAGES_TO_SIZE(4);\r
-\r
- Ptr = (UINT8 *) ((UINT32) mAcpiLowMemoryBase + sizeof (PERF_HEADER));\r
- LimitCount = (mAcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);\r
-\r
- //\r
- // Initialize performance data structure\r
- //\r
- ZeroMem (&mPerfHeader, sizeof (PERF_HEADER));\r
-\r
- //\r
- // Get CPU frequency\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiCpuArchProtocolGuid,\r
- NULL,\r
- (VOID **)&Cpu\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages (mAcpiLowMemoryBase, 4);\r
- return ;\r
- }\r
- //\r
- // Get Cpu Frequency\r
- //\r
- Status = Cpu->GetTimerValue (Cpu, 0, &(CurrentTicker), &TimerPeriod);\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages (mAcpiLowMemoryBase, 4);\r
- return ;\r
- }\r
-\r
- Freq = DivU64x32 (1000000000000ULL, (UINTN) TimerPeriod);\r
-\r
- mPerfHeader.CpuFreq = Freq;\r
-\r
- //\r
- // Record BDS raw performance data\r
- //\r
- mPerfHeader.BDSRaw = Ticker;\r
-\r
- //\r
- // Put Detailed performance data into memory\r
- //\r
- Handles = NULL;\r
- Status = gBS->LocateHandleBuffer (\r
- AllHandles,\r
- NULL,\r
- NULL,\r
- &NoHandles,\r
- &Handles\r
- );\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages (mAcpiLowMemoryBase, 4);\r
- return ;\r
- }\r
- //\r
- // Get DXE drivers performance\r
- //\r
- for (mIndex = 0; mIndex < NoHandles; mIndex++) {\r
- Ticker = 0;\r
- LogEntryKey = 0;\r
- while ((LogEntryKey = GetPerformanceMeasurement (\r
- LogEntryKey,\r
- &Handle,\r
- &Token,\r
- &Module,\r
- &StartTicker,\r
- &EndTicker)) != 0) {\r
- if ((Handle == Handles[mIndex]) && (StartTicker < EndTicker)) {\r
- Ticker += (EndTicker - StartTicker);\r
- }\r
- }\r
-\r
- Duration = (UINT32) DivU64x32 (\r
- Ticker,\r
- (UINT32) Freq\r
- );\r
-\r
- if (Duration > 0) {\r
- ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
-\r
- GetNameFromHandle (Handles[mIndex], GaugeString);\r
-\r
- AsciiStrCpy (mPerfData.Token, GaugeString);\r
- mPerfData.Duration = Duration;\r
-\r
- CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
- Ptr += sizeof (PERF_DATA);\r
-\r
- mPerfHeader.Count++;\r
- if (mPerfHeader.Count == LimitCount) {\r
- goto Done;\r
- }\r
- }\r
- }\r
-\r
- gBS->FreePool (Handles);\r
-\r
- //\r
- // Get inserted performance data\r
- //\r
- LogEntryKey = 0;\r
- while ((LogEntryKey = GetPerformanceMeasurement (\r
- LogEntryKey,\r
- &Handle,\r
- &Token,\r
- &Module,\r
- &StartTicker,\r
- &EndTicker)) != 0) {\r
- if ((Handle == NULL) && (StartTicker <= EndTicker)) {\r
-\r
- ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
-\r
- AsciiStrnCpy (mPerfData.Token, Token, DXE_PERFORMANCE_STRING_SIZE);\r
- mPerfData.Duration = (UINT32) DivU64x32 (\r
- EndTicker - StartTicker,\r
- (UINT32) Freq\r
- );\r
-\r
- CopyMem (Ptr, &mPerfData, sizeof (PERF_DATA));\r
- Ptr += sizeof (PERF_DATA);\r
-\r
- mPerfHeader.Count++;\r
- if (mPerfHeader.Count == LimitCount) {\r
- goto Done;\r
- }\r
- }\r
- }\r
-\r
-Done:\r
-\r
- ClearDebugRegisters ();\r
-\r
- mPerfHeader.Signiture = 0x66726550;\r
-\r
- //\r
- // Put performance data to memory\r
- //\r
- CopyMem (\r
- (UINT32 *) (UINT32) mAcpiLowMemoryBase,\r
- &mPerfHeader,\r
- sizeof (PERF_HEADER)\r
- );\r
-\r
- gRT->SetVariable (\r
- L"PerfDataMemAddr",\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
- sizeof (UINT32),\r
- (VOID *) &mAcpiLowMemoryBase\r
- );\r
-\r
- return ;\r
-}\r