3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 This file include the file which can help to get the system
19 performance, all the function will only include if the performance
24 #include "Performance.h"
32 // BugBug: We should not need to do this. We need to root cause this bug!!!!
59 if (PdbFileName
== NULL
) {
60 AsciiStrCpy (GaugeString
, " ");
63 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++)
66 for (Index
= 0; PdbFileName
[Index
] != 0; Index
++) {
67 if (PdbFileName
[Index
] == '\\') {
68 StartIndex
= Index
+ 1;
71 if (PdbFileName
[Index
] == '.') {
77 for (Index
= StartIndex
; Index
< EndIndex
; Index
++) {
78 GaugeString
[Index1
] = PdbFileName
[Index
];
80 if (Index1
== PERF_TOKEN_LENGTH
- 1) {
85 GaugeString
[Index1
] = 0;
102 Located PDB path name in PE image
106 ImageBase - base of PE to search
110 Pointer into image at offset of PDB file name if PDB file name is found,
111 Otherwise a pointer to an empty string.
115 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
117 ZeroMem (&ImageContext
, sizeof (ImageContext
));
118 ImageContext
.Handle
= ImageBase
;
119 ImageContext
.ImageRead
= PeCoffLoaderImageReadFromMemory
;
121 PeCoffLoaderGetImageInfo (&ImageContext
);
123 return ImageContext
.PdbPointer
;
130 IN EFI_HANDLE Handle
,
131 OUT CHAR8
*GaugeString
135 EFI_LOADED_IMAGE_PROTOCOL
*Image
;
137 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
139 AsciiStrCpy (GaugeString
, " ");
142 // Get handle name from image protocol
144 Status
= gBS
->HandleProtocol (
146 &gEfiLoadedImageProtocolGuid
,
150 if (EFI_ERROR (Status
)) {
151 Status
= gBS
->OpenProtocol (
153 &gEfiDriverBindingProtocolGuid
,
154 (VOID
**) &DriverBinding
,
157 EFI_OPEN_PROTOCOL_GET_PROTOCOL
159 if (EFI_ERROR (Status
)) {
163 // Get handle name from image protocol
165 Status
= gBS
->HandleProtocol (
166 DriverBinding
->ImageHandle
,
167 &gEfiLoadedImageProtocolGuid
,
172 PdbFileName
= GetPdbPath (Image
->ImageBase
);
174 if (PdbFileName
!= NULL
) {
175 GetShortPdbFileName (PdbFileName
, GaugeString
);
184 WriteBootToOsPerformanceData (
191 Allocates a block of memory and writes performance data of booting to OS into it.
204 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
205 EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase
;
206 UINT32 mAcpiLowMemoryLength
;
208 PERF_HEADER mPerfHeader
;
212 CHAR8 GaugeString
[PERF_TOKEN_LENGTH
];
218 UINT64 CurrentTicker
;
228 // Retrive time stamp count as early as possilbe
230 Ticker
= AsmReadTsc ();
233 // Allocate a block of memory that contain performance data to OS
235 mAcpiLowMemoryBase
= 0xFFFFFFFF;
236 Status
= gBS
->AllocatePages (
238 EfiReservedMemoryType
,
242 if (EFI_ERROR (Status
)) {
246 mAcpiLowMemoryLength
= EFI_PAGES_TO_SIZE(4);
248 Ptr
= (UINT8
*) ((UINT32
) mAcpiLowMemoryBase
+ sizeof (PERF_HEADER
));
249 LimitCount
= (mAcpiLowMemoryLength
- sizeof (PERF_HEADER
)) / sizeof (PERF_DATA
);
252 // Initialize performance data structure
254 ZeroMem (&mPerfHeader
, sizeof (PERF_HEADER
));
259 Status
= gBS
->LocateProtocol (
260 &gEfiCpuArchProtocolGuid
,
264 if (EFI_ERROR (Status
)) {
265 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
271 Status
= Cpu
->GetTimerValue (Cpu
, 0, &(CurrentTicker
), &TimerPeriod
);
272 if (EFI_ERROR (Status
)) {
273 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
277 Freq
= DivU64x32 (1000000000000ULL, (UINTN
) TimerPeriod
);
279 mPerfHeader
.CpuFreq
= Freq
;
282 // Record BDS raw performance data
284 mPerfHeader
.BDSRaw
= Ticker
;
287 // Put Detailed performance data into memory
290 Status
= gBS
->LocateHandleBuffer (
297 if (EFI_ERROR (Status
)) {
298 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
302 // Get DXE drivers performance
304 for (mIndex
= 0; mIndex
< NoHandles
; mIndex
++) {
307 while ((LogEntryKey
= GetPerformanceMeasurement (
314 if ((Handle
== Handles
[mIndex
]) && (StartTicker
< EndTicker
)) {
315 Ticker
+= (EndTicker
- StartTicker
);
319 Duration
= (UINT32
) DivU64x32 (
325 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
327 GetNameFromHandle (Handles
[mIndex
], GaugeString
);
329 AsciiStrCpy (mPerfData
.Token
, GaugeString
);
330 mPerfData
.Duration
= Duration
;
332 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
333 Ptr
+= sizeof (PERF_DATA
);
336 if (mPerfHeader
.Count
== LimitCount
) {
342 gBS
->FreePool (Handles
);
345 // Get inserted performance data
348 while ((LogEntryKey
= GetPerformanceMeasurement (
355 if ((Handle
== NULL
) && (StartTicker
<= EndTicker
)) {
357 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
359 AsciiStrnCpy (mPerfData
.Token
, Token
, DXE_PERFORMANCE_STRING_SIZE
);
360 mPerfData
.Duration
= (UINT32
) DivU64x32 (
361 EndTicker
- StartTicker
,
365 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
366 Ptr
+= sizeof (PERF_DATA
);
369 if (mPerfHeader
.Count
== LimitCount
) {
377 ClearDebugRegisters ();
379 mPerfHeader
.Signiture
= 0x66726550;
382 // Put performance data to memory
385 (UINT32
*) (UINT32
) mAcpiLowMemoryBase
,
392 &gEfiGlobalVariableGuid
,
393 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
395 (VOID
*) &mAcpiLowMemoryBase