-/** @file
-
-Copyright (c) 2004 - 2007, 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.
-
-Module Name:
-
- Performance.c
-
-Abstract:
-
- 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.
-
-
-**/
-
-#include "InternalBdsLib.h"
-
-STATIC PERF_HEADER mPerfHeader;
-STATIC PERF_DATA mPerfData;
-
-STATIC
-VOID
-GetShortPdbFileName (
- CHAR8 *PdbFileName,
- CHAR8 *GaugeString
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
-Returns:
-
---*/
-{
- 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 ;
-}
-
-STATIC
-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 ;
-}
-
-VOID
-WriteBootToOsPerformanceData (
- VOID
- )
-/*++
-
-Routine Description:
-
- Allocates a block of memory and writes performance data of booting to OS into it.
-
-Arguments:
-
- None
-
-Returns:
-
- None
-
---*/
-{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS AcpiLowMemoryBase;
- UINT32 AcpiLowMemoryLength;
- 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;
-
- //
- // Retrive time stamp count as early as possilbe
- //
- 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;
- }
-
- AcpiLowMemoryLength = 0x2000;
-
- //
- // Allocate a block of memory that contain performance data to OS
- //
- Status = gBS->AllocatePages (
- AllocateAnyPages,
- EfiACPIReclaimMemory,
- EFI_SIZE_TO_PAGES (AcpiLowMemoryLength),
- &AcpiLowMemoryBase
- );
- if (EFI_ERROR (Status)) {
- return ;
- }
-
-
- Ptr = (UINT8 *) ((UINT32) AcpiLowMemoryBase + sizeof (PERF_HEADER));
- LimitCount = (AcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
-
- //
- // Put Detailed performance data into memory
- //
- Handles = NULL;
- Status = gBS->LocateHandleBuffer (
- AllHandles,
- NULL,
- NULL,
- &NoHandles,
- &Handles
- );
- if (EFI_ERROR (Status)) {
- gBS->FreePages (AcpiLowMemoryBase, 1);
- return ;
- }
- //
- // Get DXE drivers performance
- //
- for (Index = 0; Index < NoHandles; Index++) {
- Ticker = 0;
- LogEntryKey = 0;
- while ((LogEntryKey = GetPerformanceMeasurement (
- LogEntryKey,
- &Handle,
- &Token,
- &Module,
- &StartTicker,
- &EndTicker)) != 0) {
- if ((Handle == Handles[Index]) && (EndTicker != 0)) {
- 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;
- }
- }
- }
-
- FreePool (Handles);
-
- //
- // Get inserted performance data
- //
- LogEntryKey = 0;
- while ((LogEntryKey = GetPerformanceMeasurement (
- LogEntryKey,
- &Handle,
- &Token,
- &Module,
- &StartTicker,
- &EndTicker)) != 0) {
- if (Handle == NULL && EndTicker != 0) {
-
- ZeroMem (&mPerfData, sizeof (PERF_DATA));
-
- AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH);
- 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;
- }
- }
- }
-
-Done:
-
- mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;
-
- //
- // Put performance data to memory
- //
- CopyMem (
- (UINTN *) (UINTN) AcpiLowMemoryBase,
- &mPerfHeader,
- sizeof (PERF_HEADER)
- );
-
- gRT->SetVariable (
- L"PerfDataMemAddr",
- &gEfiGenericPlatformVariableGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof (EFI_PHYSICAL_ADDRESS),
- &AcpiLowMemoryBase
- );
-
- return ;
-}
+/** @file\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
+Copyright (c) 2004 - 2008, Intel Corporation. <BR>\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
+**/\r
+\r
+#include "InternalBdsLib.h"\r
+\r
+STATIC PERF_HEADER mPerfHeader;\r
+STATIC PERF_DATA mPerfData;\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
+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 = PeCoffLoaderGetPdbPointer (Image->ImageBase);\r
+\r
+ if (PdbFileName != NULL) {\r
+ GetShortPdbFileName (PdbFileName, GaugeString);\r
+ }\r
+\r
+ return ;\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_PHYSICAL_ADDRESS AcpiLowMemoryBase;\r
+ UINT32 AcpiLowMemoryLength;\r
+ UINT32 LimitCount;\r
+ EFI_HANDLE *Handles;\r
+ UINTN NoHandles;\r
+ CHAR8 GaugeString[PERF_TOKEN_LENGTH];\r
+ UINT8 *Ptr;\r
+ UINT32 Index;\r
+ UINT64 Ticker;\r
+ UINT64 Freq;\r
+ UINT32 Duration;\r
+ UINTN LogEntryKey;\r
+ CONST VOID *Handle;\r
+ CONST CHAR8 *Token;\r
+ CONST CHAR8 *Module;\r
+ UINT64 StartTicker;\r
+ UINT64 EndTicker;\r
+ UINT64 StartValue;\r
+ UINT64 EndValue;\r
+ BOOLEAN CountUp;\r
+\r
+ //\r
+ // Retrive time stamp count as early as possilbe\r
+ //\r
+ Ticker = GetPerformanceCounter ();\r
+\r
+ Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);\r
+ \r
+ Freq = DivU64x32 (Freq, 1000);\r
+\r
+ mPerfHeader.CpuFreq = Freq;\r
+\r
+ //\r
+ // Record BDS raw performance data\r
+ //\r
+ if (EndValue >= StartValue) {\r
+ mPerfHeader.BDSRaw = Ticker - StartValue;\r
+ CountUp = TRUE;\r
+ } else {\r
+ mPerfHeader.BDSRaw = StartValue - Ticker;\r
+ CountUp = FALSE;\r
+ }\r
+\r
+ AcpiLowMemoryLength = 0x2000;\r
+\r
+ //\r
+ // Allocate a block of memory that contain performance data to OS\r
+ //\r
+ Status = gBS->AllocatePages (\r
+ AllocateAnyPages,\r
+ EfiACPIReclaimMemory,\r
+ EFI_SIZE_TO_PAGES (AcpiLowMemoryLength),\r
+ &AcpiLowMemoryBase\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+\r
+\r
+ Ptr = (UINT8 *) ((UINT32) AcpiLowMemoryBase + sizeof (PERF_HEADER));\r
+ LimitCount = (AcpiLowMemoryLength - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);\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 (AcpiLowMemoryBase, 1);\r
+ return ;\r
+ }\r
+ //\r
+ // Get DXE drivers performance\r
+ //\r
+ for (Index = 0; Index < NoHandles; Index++) {\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[Index]) && (EndTicker != 0)) {\r
+ Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
+ }\r
+ }\r
+\r
+ Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
+\r
+ if (Duration > 0) {\r
+\r
+ GetNameFromHandle (Handles[Index], 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
+ 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 && EndTicker != 0) {\r
+\r
+ ZeroMem (&mPerfData, sizeof (PERF_DATA));\r
+\r
+ AsciiStrnCpy (mPerfData.Token, Token, PERF_TOKEN_LENGTH);\r
+ Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
+\r
+ mPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\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
+ mPerfHeader.Signiture = PERFORMANCE_SIGNATURE;\r
+\r
+ //\r
+ // Put performance data to memory\r
+ //\r
+ CopyMem (\r
+ (UINTN *) (UINTN) AcpiLowMemoryBase,\r
+ &mPerfHeader,\r
+ sizeof (PERF_HEADER)\r
+ );\r
+\r
+ gRT->SetVariable (\r
+ L"PerfDataMemAddr",\r
+ &gEfiGenericPlatformVariableGuid,\r
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
+ sizeof (EFI_PHYSICAL_ADDRESS),\r
+ &AcpiLowMemoryBase\r
+ );\r
+\r
+ return ;\r
+}\r