]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/UefiBootManagerLib/BmPerformance.c
ArmPlatformPkg/ArmJunoDxe: Fix build
[mirror_edk2.git] / MdeModulePkg / Library / UefiBootManagerLib / BmPerformance.c
CommitLineData
1d112229
RN
1/** @file
2 This file include the file which can help to get the system
3 performance, all the function will only include if the performance
4 switch is set.
5
6Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
7This program and the accompanying materials
8are licensed and made available under the terms and conditions of the BSD License
9which accompanies this distribution. The full text of the license may be found at
10http://opensource.org/licenses/bsd-license.php
11
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14
15**/
16
17#include "InternalBm.h"
18
19PERF_HEADER mBmPerfHeader;
20PERF_DATA mBmPerfData;
21EFI_PHYSICAL_ADDRESS mBmAcpiLowMemoryBase = 0x0FFFFFFFFULL;
22
23/**
24 Get the short verion of PDB file name to be
25 used in performance data logging.
26
27 @param PdbFileName The long PDB file name.
28 @param GaugeString The output string to be logged by performance logger.
29
30**/
31VOID
32BmGetShortPdbFileName (
33 IN CONST CHAR8 *PdbFileName,
34 OUT CHAR8 *GaugeString
35 )
36{
37 UINTN Index;
38 UINTN Index1;
39 UINTN StartIndex;
40 UINTN EndIndex;
41
42 if (PdbFileName == NULL) {
43 AsciiStrCpy (GaugeString, " ");
44 } else {
45 StartIndex = 0;
46 for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
47 ;
48
49 for (Index = 0; PdbFileName[Index] != 0; Index++) {
50 if (PdbFileName[Index] == '\\') {
51 StartIndex = Index + 1;
52 }
53
54 if (PdbFileName[Index] == '.') {
55 EndIndex = Index;
56 }
57 }
58
59 Index1 = 0;
60 for (Index = StartIndex; Index < EndIndex; Index++) {
61 GaugeString[Index1] = PdbFileName[Index];
62 Index1++;
63 if (Index1 == PERF_TOKEN_LENGTH - 1) {
64 break;
65 }
66 }
67
68 GaugeString[Index1] = 0;
69 }
70
71 return ;
72}
73
74/**
75 Get the name from the Driver handle, which can be a handle with
76 EFI_LOADED_IMAGE_PROTOCOL or EFI_DRIVER_BINDING_PROTOCOL installed.
77 This name can be used in performance data logging.
78
79 @param Handle Driver handle.
80 @param GaugeString The output string to be logged by performance logger.
81
82**/
83VOID
84BmGetNameFromHandle (
85 IN EFI_HANDLE Handle,
86 OUT CHAR8 *GaugeString
87 )
88{
89 EFI_STATUS Status;
90 EFI_LOADED_IMAGE_PROTOCOL *Image;
91 CHAR8 *PdbFileName;
92 EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
93
94 AsciiStrCpy (GaugeString, " ");
95
96 //
97 // Get handle name from image protocol
98 //
99 Status = gBS->HandleProtocol (
100 Handle,
101 &gEfiLoadedImageProtocolGuid,
102 (VOID **) &Image
103 );
104
105 if (EFI_ERROR (Status)) {
106 Status = gBS->OpenProtocol (
107 Handle,
108 &gEfiDriverBindingProtocolGuid,
109 (VOID **) &DriverBinding,
110 NULL,
111 NULL,
112 EFI_OPEN_PROTOCOL_GET_PROTOCOL
113 );
114 if (EFI_ERROR (Status)) {
115 return ;
116 }
117 //
118 // Get handle name from image protocol
119 //
120 Status = gBS->HandleProtocol (
121 DriverBinding->ImageHandle,
122 &gEfiLoadedImageProtocolGuid,
123 (VOID **) &Image
124 );
125 }
126
127 PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);
128
129 if (PdbFileName != NULL) {
130 BmGetShortPdbFileName (PdbFileName, GaugeString);
131 }
132
133 return ;
134}
135
136/**
137
138 Writes performance data of booting into the allocated memory.
139 OS can process these records.
140
141 @param Event The triggered event.
142 @param Context Context for this event.
143
144**/
145VOID
146EFIAPI
147BmWriteBootToOsPerformanceData (
148 IN EFI_EVENT Event,
149 IN VOID *Context
150 )
151{
152 EFI_STATUS Status;
153 UINT32 LimitCount;
154 EFI_HANDLE *Handles;
155 UINTN NoHandles;
156 CHAR8 GaugeString[PERF_TOKEN_LENGTH];
157 UINT8 *Ptr;
158 UINT32 Index;
159 UINT64 Ticker;
160 UINT64 Freq;
161 UINT32 Duration;
162 UINTN LogEntryKey;
163 CONST VOID *Handle;
164 CONST CHAR8 *Token;
165 CONST CHAR8 *Module;
166 UINT64 StartTicker;
167 UINT64 EndTicker;
168 UINT64 StartValue;
169 UINT64 EndValue;
170 BOOLEAN CountUp;
171 UINTN EntryIndex;
172 UINTN NumPerfEntries;
173 //
174 // List of flags indicating PerfEntry contains DXE handle
175 //
176 BOOLEAN *PerfEntriesAsDxeHandle;
177 UINTN VarSize;
178
179 //
180 // Record the performance data for End of BDS
181 //
182 PERF_END(NULL, "BDS", NULL, 0);
183
184 //
185 // Retrieve time stamp count as early as possible
186 //
187 Ticker = GetPerformanceCounter ();
188
189 Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);
190
191 Freq = DivU64x32 (Freq, 1000);
192
193 mBmPerfHeader.CpuFreq = Freq;
194
195 //
196 // Record BDS raw performance data
197 //
198 if (EndValue >= StartValue) {
199 mBmPerfHeader.BDSRaw = Ticker - StartValue;
200 CountUp = TRUE;
201 } else {
202 mBmPerfHeader.BDSRaw = StartValue - Ticker;
203 CountUp = FALSE;
204 }
205
206 if (mBmAcpiLowMemoryBase == 0x0FFFFFFFF) {
207 VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
208 Status = gRT->GetVariable (
209 L"PerfDataMemAddr",
210 &gPerformanceProtocolGuid,
211 NULL,
212 &VarSize,
213 &mBmAcpiLowMemoryBase
214 );
215 if (EFI_ERROR (Status)) {
216 //
217 // Fail to get the variable, return.
218 //
219 return;
220 }
221 }
222
223 //
224 // Put Detailed performance data into memory
225 //
226 Handles = NULL;
227 Status = gBS->LocateHandleBuffer (
228 AllHandles,
229 NULL,
230 NULL,
231 &NoHandles,
232 &Handles
233 );
234 if (EFI_ERROR (Status)) {
235 return ;
236 }
237
238 Ptr = (UINT8 *) ((UINT32) mBmAcpiLowMemoryBase + sizeof (PERF_HEADER));
239 LimitCount = (UINT32) (PERF_DATA_MAX_LENGTH - sizeof (PERF_HEADER)) / sizeof (PERF_DATA);
240
241 NumPerfEntries = 0;
242 LogEntryKey = 0;
243 while ((LogEntryKey = GetPerformanceMeasurement (
244 LogEntryKey,
245 &Handle,
246 &Token,
247 &Module,
248 &StartTicker,
249 &EndTicker)) != 0) {
250 NumPerfEntries++;
251 }
252 PerfEntriesAsDxeHandle = AllocateZeroPool (NumPerfEntries * sizeof (BOOLEAN));
253 ASSERT (PerfEntriesAsDxeHandle != NULL);
254
255 //
256 // Get DXE drivers performance
257 //
258 for (Index = 0; Index < NoHandles; Index++) {
259 Ticker = 0;
260 LogEntryKey = 0;
261 EntryIndex = 0;
262 while ((LogEntryKey = GetPerformanceMeasurement (
263 LogEntryKey,
264 &Handle,
265 &Token,
266 &Module,
267 &StartTicker,
268 &EndTicker)) != 0) {
269 if (Handle == Handles[Index] && !PerfEntriesAsDxeHandle[EntryIndex]) {
270 PerfEntriesAsDxeHandle[EntryIndex] = TRUE;
271 }
272 EntryIndex++;
273 if ((Handle == Handles[Index]) && (EndTicker != 0)) {
274 if (StartTicker == 1) {
275 StartTicker = StartValue;
276 }
277 if (EndTicker == 1) {
278 EndTicker = StartValue;
279 }
280 Ticker += CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
281 }
282 }
283
284 Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
285
286 if (Duration > 0) {
287
288 BmGetNameFromHandle (Handles[Index], GaugeString);
289
290 AsciiStrCpy (mBmPerfData.Token, GaugeString);
291 mBmPerfData.Duration = Duration;
292
293 CopyMem (Ptr, &mBmPerfData, sizeof (PERF_DATA));
294 Ptr += sizeof (PERF_DATA);
295
296 mBmPerfHeader.Count++;
297 if (mBmPerfHeader.Count == LimitCount) {
298 goto Done;
299 }
300 }
301 }
302
303 //
304 // Get inserted performance data
305 //
306 LogEntryKey = 0;
307 EntryIndex = 0;
308 while ((LogEntryKey = GetPerformanceMeasurement (
309 LogEntryKey,
310 &Handle,
311 &Token,
312 &Module,
313 &StartTicker,
314 &EndTicker)) != 0) {
315 if (!PerfEntriesAsDxeHandle[EntryIndex] && EndTicker != 0) {
316
317 ZeroMem (&mBmPerfData, sizeof (PERF_DATA));
318
319 AsciiStrnCpy (mBmPerfData.Token, Token, PERF_TOKEN_LENGTH);
320 if (StartTicker == 1) {
321 StartTicker = StartValue;
322 }
323 if (EndTicker == 1) {
324 EndTicker = StartValue;
325 }
326 Ticker = CountUp ? (EndTicker - StartTicker) : (StartTicker - EndTicker);
327
328 mBmPerfData.Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);
329
330 CopyMem (Ptr, &mBmPerfData, sizeof (PERF_DATA));
331 Ptr += sizeof (PERF_DATA);
332
333 mBmPerfHeader.Count++;
334 if (mBmPerfHeader.Count == LimitCount) {
335 goto Done;
336 }
337 }
338 EntryIndex++;
339 }
340
341Done:
342
343 FreePool (Handles);
344 FreePool (PerfEntriesAsDxeHandle);
345
346 mBmPerfHeader.Signiture = PERFORMANCE_SIGNATURE;
347
348 //
349 // Put performance data to Reserved memory
350 //
351 CopyMem (
352 (UINTN *) (UINTN) mBmAcpiLowMemoryBase,
353 &mBmPerfHeader,
354 sizeof (PERF_HEADER)
355 );
356
357 return ;
358}