3 Copyright (c) 2006 - 2007, 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
25 // Include common header file for this module.
27 #include "CommonHeader.h"
29 #include "Performance.h"
53 if (PdbFileName
== NULL
) {
54 AsciiStrCpy (GaugeString
, " ");
57 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++)
60 for (Index
= 0; PdbFileName
[Index
] != 0; Index
++) {
61 if (PdbFileName
[Index
] == '\\') {
62 StartIndex
= Index
+ 1;
65 if (PdbFileName
[Index
] == '.') {
71 for (Index
= StartIndex
; Index
< EndIndex
; Index
++) {
72 GaugeString
[Index1
] = PdbFileName
[Index
];
74 if (Index1
== PERF_TOKEN_LENGTH
- 1) {
79 GaugeString
[Index1
] = 0;
96 Located PDB path name in PE image
100 ImageBase - base of PE to search
104 Pointer into image at offset of PDB file name if PDB file name is found,
105 Otherwise a pointer to an empty string.
109 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
111 ZeroMem (&ImageContext
, sizeof (ImageContext
));
112 ImageContext
.Handle
= ImageBase
;
113 ImageContext
.ImageRead
= PeCoffLoaderImageReadFromMemory
;
115 PeCoffLoaderGetImageInfo (&ImageContext
);
117 return ImageContext
.PdbPointer
;
124 IN EFI_HANDLE Handle
,
125 OUT CHAR8
*GaugeString
129 EFI_LOADED_IMAGE_PROTOCOL
*Image
;
131 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
133 AsciiStrCpy (GaugeString
, " ");
136 // Get handle name from image protocol
138 Status
= gBS
->HandleProtocol (
140 &gEfiLoadedImageProtocolGuid
,
144 if (EFI_ERROR (Status
)) {
145 Status
= gBS
->OpenProtocol (
147 &gEfiDriverBindingProtocolGuid
,
148 (VOID
**) &DriverBinding
,
151 EFI_OPEN_PROTOCOL_GET_PROTOCOL
153 if (EFI_ERROR (Status
)) {
157 // Get handle name from image protocol
159 Status
= gBS
->HandleProtocol (
160 DriverBinding
->ImageHandle
,
161 &gEfiLoadedImageProtocolGuid
,
166 PdbFileName
= GetPdbPath (Image
->ImageBase
);
168 if (PdbFileName
!= NULL
) {
169 GetShortPdbFileName (PdbFileName
, GaugeString
);
178 WriteBootToOsPerformanceData (
185 Allocates a block of memory and writes performance data of booting to OS into it.
198 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
199 EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase
;
200 UINT32 mAcpiLowMemoryLength
;
202 PERF_HEADER mPerfHeader
;
206 CHAR8 GaugeString
[PERF_TOKEN_LENGTH
];
212 UINT64 CurrentTicker
;
222 // Retrive time stamp count as early as possilbe
224 Ticker
= AsmReadTsc ();
227 // Allocate a block of memory that contain performance data to OS
229 mAcpiLowMemoryBase
= 0xFFFFFFFF;
230 Status
= gBS
->AllocatePages (
232 EfiReservedMemoryType
,
236 if (EFI_ERROR (Status
)) {
240 mAcpiLowMemoryLength
= EFI_PAGES_TO_SIZE(4);
242 Ptr
= (UINT8
*) ((UINT32
) mAcpiLowMemoryBase
+ sizeof (PERF_HEADER
));
243 LimitCount
= (mAcpiLowMemoryLength
- sizeof (PERF_HEADER
)) / sizeof (PERF_DATA
);
246 // Initialize performance data structure
248 ZeroMem (&mPerfHeader
, sizeof (PERF_HEADER
));
253 Status
= gBS
->LocateProtocol (
254 &gEfiCpuArchProtocolGuid
,
258 if (EFI_ERROR (Status
)) {
259 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
265 Status
= Cpu
->GetTimerValue (Cpu
, 0, &(CurrentTicker
), &TimerPeriod
);
266 if (EFI_ERROR (Status
)) {
267 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
271 Freq
= DivU64x32 (1000000000000, (UINTN
) TimerPeriod
);
273 mPerfHeader
.CpuFreq
= Freq
;
276 // Record BDS raw performance data
278 mPerfHeader
.BDSRaw
= Ticker
;
281 // Put Detailed performance data into memory
284 Status
= gBS
->LocateHandleBuffer (
291 if (EFI_ERROR (Status
)) {
292 gBS
->FreePages (mAcpiLowMemoryBase
, 4);
296 // Get DXE drivers performance
298 for (mIndex
= 0; mIndex
< NoHandles
; mIndex
++) {
301 while ((LogEntryKey
= GetPerformanceMeasurement (
308 if ((Handle
== Handles
[mIndex
]) && (StartTicker
< EndTicker
)) {
309 Ticker
+= (EndTicker
- StartTicker
);
313 Duration
= (UINT32
) DivU64x32 (
319 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
321 GetNameFromHandle (Handles
[mIndex
], GaugeString
);
323 AsciiStrCpy (mPerfData
.Token
, GaugeString
);
324 mPerfData
.Duration
= Duration
;
326 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
327 Ptr
+= sizeof (PERF_DATA
);
330 if (mPerfHeader
.Count
== LimitCount
) {
339 // Get inserted performance data
342 while ((LogEntryKey
= GetPerformanceMeasurement (
349 if ((Handle
== NULL
) && (StartTicker
<= EndTicker
)) {
351 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
353 AsciiStrnCpy (mPerfData
.Token
, Token
, DXE_PERFORMANCE_STRING_SIZE
);
354 mPerfData
.Duration
= (UINT32
) DivU64x32 (
355 EndTicker
- StartTicker
,
359 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
360 Ptr
+= sizeof (PERF_DATA
);
363 if (mPerfHeader
.Count
== LimitCount
) {
371 mPerfHeader
.Signiture
= 0x66726550;
374 // Put performance data to memory
377 (UINT32
*) (UINT32
) mAcpiLowMemoryBase
,
384 &gEfiGenericPlatformVariableGuid
,
385 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
387 (VOID
*) &mAcpiLowMemoryBase