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"
56 if (PdbFileName
== NULL
) {
57 AsciiStrCpy (GaugeString
, " ");
60 for (EndIndex
= 0; PdbFileName
[EndIndex
] != 0; EndIndex
++)
63 for (Index
= 0; PdbFileName
[Index
] != 0; Index
++) {
64 if (PdbFileName
[Index
] == '\\') {
65 StartIndex
= Index
+ 1;
68 if (PdbFileName
[Index
] == '.') {
74 for (Index
= StartIndex
; Index
< EndIndex
; Index
++) {
75 GaugeString
[Index1
] = PdbFileName
[Index
];
77 if (Index1
== PERF_TOKEN_LENGTH
- 1) {
82 GaugeString
[Index1
] = 0;
97 Located PDB path name in PE image
101 ImageBase - base of PE to search
105 Pointer into image at offset of PDB file name if PDB file name is found,
106 Otherwise a pointer to an empty string.
112 EFI_IMAGE_DOS_HEADER
*DosHdr
;
113 EFI_IMAGE_NT_HEADERS
*NtHdr
;
114 EFI_IMAGE_OPTIONAL_HEADER
*OptionalHdr
;
115 EFI_IMAGE_DATA_DIRECTORY
*DirectoryEntry
;
116 EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*DebugEntry
;
117 VOID
*CodeViewEntryPointer
;
119 CodeViewEntryPointer
= NULL
;
123 if (DosHdr
->e_magic
== EFI_IMAGE_DOS_SIGNATURE
) {
124 NtHdr
= (EFI_IMAGE_NT_HEADERS
*) ((UINT8
*) DosHdr
+ DosHdr
->e_lfanew
);
125 OptionalHdr
= (VOID
*) &NtHdr
->OptionalHeader
;
126 DirectoryEntry
= (EFI_IMAGE_DATA_DIRECTORY
*) &(OptionalHdr
->DataDirectory
[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG
]);
127 if (DirectoryEntry
->VirtualAddress
!= 0) {
129 (DirCount
< DirectoryEntry
->Size
/ sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
)) && CodeViewEntryPointer
== NULL
;
132 DebugEntry
= (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
*) (DirectoryEntry
->VirtualAddress
+ (UINTN
) ImageBase
+ DirCount
* sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY
));
133 if (DebugEntry
->Type
== EFI_IMAGE_DEBUG_TYPE_CODEVIEW
) {
134 CodeViewEntryPointer
= (VOID
*) ((UINTN
) DebugEntry
->RVA
+ (UINTN
) ImageBase
);
135 switch (*(UINT32
*) CodeViewEntryPointer
) {
136 case CODEVIEW_SIGNATURE_NB10
:
137 PdbPath
= (CHAR8
*) CodeViewEntryPointer
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY
);
140 case CODEVIEW_SIGNATURE_RSDS
:
141 PdbPath
= (CHAR8
*) CodeViewEntryPointer
+ sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY
);
158 IN EFI_HANDLE Handle
,
159 OUT CHAR8
*GaugeString
163 EFI_LOADED_IMAGE_PROTOCOL
*Image
;
165 EFI_DRIVER_BINDING_PROTOCOL
*DriverBinding
;
167 AsciiStrCpy (GaugeString
, " ");
170 // Get handle name from image protocol
172 Status
= gBS
->HandleProtocol (
174 &gEfiLoadedImageProtocolGuid
,
178 if (EFI_ERROR (Status
)) {
179 Status
= gBS
->OpenProtocol (
181 &gEfiDriverBindingProtocolGuid
,
182 (VOID
**) &DriverBinding
,
185 EFI_OPEN_PROTOCOL_GET_PROTOCOL
187 if (EFI_ERROR (Status
)) {
191 // Get handle name from image protocol
193 Status
= gBS
->HandleProtocol (
194 DriverBinding
->ImageHandle
,
195 &gEfiLoadedImageProtocolGuid
,
200 PdbFileName
= GetPdbPath (Image
->ImageBase
);
202 if (PdbFileName
!= NULL
) {
203 GetShortPdbFileName (PdbFileName
, GaugeString
);
212 WriteBootToOsPerformanceData (
219 Allocates a block of memory and writes performance data of booting to OS into it.
232 EFI_CPU_ARCH_PROTOCOL
*Cpu
;
233 EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase
;
234 UINT32 mAcpiLowMemoryLength
;
236 PERF_HEADER mPerfHeader
;
240 CHAR8 GaugeString
[PERF_TOKEN_LENGTH
];
246 UINT64 CurrentTicker
;
256 // Retrive time stamp count as early as possilbe
258 Ticker
= AsmReadTsc ();
261 // Allocate a block of memory that contain performance data to OS
263 Status
= gBS
->AllocatePages (
265 EfiACPIReclaimMemory
,
269 if (EFI_ERROR (Status
)) {
273 mAcpiLowMemoryLength
= 0x1000;
275 Ptr
= (UINT8
*) ((UINT32
) mAcpiLowMemoryBase
+ sizeof (PERF_HEADER
));
276 LimitCount
= (mAcpiLowMemoryLength
- sizeof (PERF_HEADER
)) / sizeof (PERF_DATA
);
279 // Initialize performance data structure
281 ZeroMem (&mPerfHeader
, sizeof (PERF_HEADER
));
286 Status
= gBS
->LocateProtocol (
287 &gEfiCpuArchProtocolGuid
,
291 if (EFI_ERROR (Status
)) {
292 gBS
->FreePages (mAcpiLowMemoryBase
, 1);
298 Status
= Cpu
->GetTimerValue (Cpu
, 0, &(CurrentTicker
), &TimerPeriod
);
299 if (EFI_ERROR (Status
)) {
300 gBS
->FreePages (mAcpiLowMemoryBase
, 1);
304 Freq
= DivU64x32 (1000000000000, (UINTN
) TimerPeriod
);
306 mPerfHeader
.CpuFreq
= Freq
;
309 // Record BDS raw performance data
311 mPerfHeader
.BDSRaw
= Ticker
;
314 // Put Detailed performance data into memory
317 Status
= gBS
->LocateHandleBuffer (
324 if (EFI_ERROR (Status
)) {
325 gBS
->FreePages (mAcpiLowMemoryBase
, 1);
329 // Get DXE drivers performance
331 for (mIndex
= 0; mIndex
< NoHandles
; mIndex
++) {
334 while ((LogEntryKey
= GetPerformanceMeasurement (
341 if ((Handle
== Handles
[mIndex
]) && (StartTicker
< EndTicker
)) {
342 Ticker
+= (EndTicker
- StartTicker
);
346 Duration
= (UINT32
) DivU64x32 (
352 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
354 GetNameFromHandle (Handles
[mIndex
], GaugeString
);
356 AsciiStrCpy (mPerfData
.Token
, GaugeString
);
357 mPerfData
.Duration
= Duration
;
359 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
360 Ptr
+= sizeof (PERF_DATA
);
363 if (mPerfHeader
.Count
== LimitCount
) {
369 gBS
->FreePool (Handles
);
372 // Get inserted performance data
375 while ((LogEntryKey
= GetPerformanceMeasurement (
382 if ((Handle
== NULL
) && (StartTicker
<= EndTicker
)) {
384 ZeroMem (&mPerfData
, sizeof (PERF_DATA
));
386 AsciiStrnCpy (mPerfData
.Token
, Token
, DXE_PERFORMANCE_STRING_SIZE
);
387 mPerfData
.Duration
= (UINT32
) DivU64x32 (
388 EndTicker
- StartTicker
,
392 CopyMem (Ptr
, &mPerfData
, sizeof (PERF_DATA
));
393 Ptr
+= sizeof (PERF_DATA
);
396 if (mPerfHeader
.Count
== LimitCount
) {
404 ClearDebugRegisters ();
406 mPerfHeader
.Signiture
= 0x66726550;
409 // Put performance data to memory
412 (UINT32
*) (UINT32
) mAcpiLowMemoryBase
,
419 &gEfiGlobalVariableGuid
,
420 EFI_VARIABLE_NON_VOLATILE
| EFI_VARIABLE_BOOTSERVICE_ACCESS
| EFI_VARIABLE_RUNTIME_ACCESS
,
422 (VOID
*) &mAcpiLowMemoryBase