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"
48 if (PdbFileName
== NULL
) {
49 AsciiStrCpy (GaugeString
, " ");
52 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++)
55 for (Index
= 0; PdbFileName
[Index
] != 0; Index
++) {
56 if (PdbFileName
[Index
] == '\\') {
57 StartIndex
= Index
+ 1;
60 if (PdbFileName
[Index
] == '.') {
66 for (Index
= StartIndex
; Index
< EndIndex
; Index
++) {
67 GaugeString
[Index1
] = PdbFileName
[Index
];
69 if (Index1
== PERF_TOKEN_LENGTH
- 1) {
74 GaugeString
[Index1
] = 0;
91 Located PDB path name in PE image
95 ImageBase - base of PE to search
99 Pointer into image at offset of PDB file name if PDB file name is found,
100 Otherwise a pointer to an empty string.
104 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
106 ZeroMem (&ImageContext
, sizeof (ImageContext
));
107 ImageContext
.Handle
= ImageBase
;
108 ImageContext
.ImageRead
= PeCoffLoaderImageReadFromMemory
;
110 PeCoffLoaderGetImageInfo (&ImageContext
);
112 return ImageContext
.PdbPointer
;
119 IN EFI_HANDLE Handle
,
120 OUT CHAR8
*GaugeString
124 EFI_LOADED_IMAGE_PROTOCOL
*Image
;
126 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
128 AsciiStrCpy (GaugeString
, " ");
131 // Get handle name from image protocol
133 Status
= gBS
->HandleProtocol (
135 &gEfiLoadedImageProtocolGuid
,
139 if (EFI_ERROR (Status
)) {
140 Status
= gBS
->OpenProtocol (
142 &gEfiDriverBindingProtocolGuid
,
143 (VOID
**) &DriverBinding
,
146 EFI_OPEN_PROTOCOL_GET_PROTOCOL
148 if (EFI_ERROR (Status
)) {
152 // Get handle name from image protocol
154 Status
= gBS
->HandleProtocol (
155 DriverBinding
->ImageHandle
,
156 &gEfiLoadedImageProtocolGuid
,
161 PdbFileName
= GetPdbPath (Image
->ImageBase
);
163 if (PdbFileName
!= NULL
) {
164 GetShortPdbFileName (PdbFileName
, GaugeString
);
173 WriteBootToOsPerformanceData (
180 Allocates a block of memory and writes performance data of booting to OS into it.
193 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
194 EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase
;
195 UINT32 mAcpiLowMemoryLength
;
197 PERF_HEADER mPerfHeader
;
201 CHAR8 GaugeString
[PERF_TOKEN_LENGTH
];
207 UINT64 CurrentTicker
;
217 // Retrive time stamp count as early as possilbe
219 Ticker
= AsmReadTsc ();
222 // Allocate a block of memory that contain performance data to OS
224 mAcpiLowMemoryBase
= 0xFFFFFFFF;
225 Status
= gBS
->AllocatePages (
227 EfiReservedMemoryType
,
231 if (EFI_ERROR (Status
)) {
235 mAcpiLowMemoryLength
= EFI_PAGES_TO_SIZE(4);
237 Ptr
= (UINT8
*) ((UINT32
) mAcpiLowMemoryBase
+ sizeof (PERF_HEADER
));
238 LimitCount
= (mAcpiLowMemoryLength
- sizeof (PERF_HEADER
)) / sizeof (PERF_DATA
);
241 // Initialize performance data structure
243 ZeroMem (&mPerfHeader
, sizeof (PERF_HEADER
));
248 Status
= gBS
->LocateProtocol (
249 &gEfiCpuArchProtocolGuid
,
253 if (EFI_ERROR (Status
)) {
254 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
260 Status
= Cpu
->GetTimerValue (Cpu
, 0, &(CurrentTicker
), &TimerPeriod
);
261 if (EFI_ERROR (Status
)) {
262 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
266 Freq
= DivU64x32 (1000000000000, (UINTN
) TimerPeriod
);
268 mPerfHeader
.CpuFreq
= Freq
;
271 // Record BDS raw performance data
273 mPerfHeader
.BDSRaw
= Ticker
;
276 // Put Detailed performance data into memory
279 Status
= gBS
->LocateHandleBuffer (
286 if (EFI_ERROR (Status
)) {
287 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
291 // Get DXE drivers performance
293 for (mIndex
= 0; mIndex
< NoHandles
; mIndex
++) {
296 while ((LogEntryKey
= GetPerformanceMeasurement (
303 if ((Handle
== Handles
[mIndex
]) && (StartTicker
< EndTicker
)) {
304 Ticker
+= (EndTicker
- StartTicker
);
308 Duration
= (UINT32
) DivU64x32 (
314 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
316 GetNameFromHandle (Handles
[mIndex
], GaugeString
);
318 AsciiStrCpy (mPerfData
.Token
, GaugeString
);
319 mPerfData
.Duration
= Duration
;
321 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
322 Ptr
+= sizeof (PERF_DATA
);
325 if (mPerfHeader
.Count
== LimitCount
) {
331 gBS
->FreePool (Handles
);
334 // Get inserted performance data
337 while ((LogEntryKey
= GetPerformanceMeasurement (
344 if ((Handle
== NULL
) && (StartTicker
<= EndTicker
)) {
346 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
348 AsciiStrnCpy (mPerfData
.Token
, Token
, DXE_PERFORMANCE_STRING_SIZE
);
349 mPerfData
.Duration
= (UINT32
) DivU64x32 (
350 EndTicker
- StartTicker
,
354 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
355 Ptr
+= sizeof (PERF_DATA
);
358 if (mPerfHeader
.Count
== LimitCount
) {
366 mPerfHeader
.Signiture
= 0x66726550;
369 // Put performance data to memory
372 (UINT32
*) (UINT32
) mAcpiLowMemoryBase
,
379 &gEfiGlobalVariableGuid
,
380 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
382 (VOID
*) &mAcpiLowMemoryBase