]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.c
MdeModulePkg: Update PerformanceLib instances not to check Identifier.
[mirror_edk2.git] / MdeModulePkg / Library / DxeCorePerformanceLib / DxeCorePerformanceLib.c
CommitLineData
8dbae30d 1/** @file\r
857dfc45 2 Performance library instance mainly used by DxeCore.\r
3\r
4 This library provides the performance measurement interfaces and initializes performance\r
5 logging for DXE phase. It first initializes its private global data structure for\r
6 performance logging and saves the performance GUIDed HOB passed from PEI phase. \r
f0da4d7d
SZ
7 It initializes DXE phase performance logging by publishing the Performance and PerformanceEx Protocol,\r
8 which are consumed by DxePerformanceLib to logging performance data in DXE phase.\r
857dfc45 9\r
10 This library is mainly used by DxeCore to start performance logging to ensure that\r
11 Performance Protocol is installed at the very beginning of DXE phase.\r
a0afd019 12\r
7a9395cd 13Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
7c50b343 14(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
cd5ebaa0 15This program and the accompanying materials\r
a0afd019 16are licensed and made available under the terms and conditions of the BSD License\r
17which accompanies this distribution. The full text of the license may be found at\r
18http://opensource.org/licenses/bsd-license.php\r
19\r
20THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
21WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
22\r
8dbae30d 23**/\r
a0afd019 24\r
ed7748fe 25\r
aa79b0b3 26#include "DxeCorePerformanceLibInternal.h"\r
ed7748fe 27\r
a0afd019 28\r
29//\r
857dfc45 30// The data structure to hold global performance data.\r
a0afd019 31//\r
fe1e36e5 32GAUGE_DATA_HEADER *mGaugeData;\r
857dfc45 33\r
34//\r
35// The current maximum number of logging entries. If current number of \r
36// entries exceeds this value, it will re-allocate a larger array and\r
37// migration the old data to the larger array.\r
38//\r
fe1e36e5 39UINT32 mMaxGaugeRecords;\r
a0afd019 40\r
857dfc45 41//\r
42// The handle to install Performance Protocol instance.\r
43//\r
a0afd019 44EFI_HANDLE mHandle = NULL;\r
857dfc45 45\r
46//\r
f0da4d7d 47// Interfaces for Performance Protocol.\r
857dfc45 48//\r
a0afd019 49PERFORMANCE_PROTOCOL mPerformanceInterface = {\r
50 StartGauge,\r
51 EndGauge,\r
52 GetGauge\r
53 };\r
54\r
f0da4d7d
SZ
55//\r
56// Interfaces for PerformanceEx Protocol.\r
57//\r
58PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {\r
59 StartGaugeEx,\r
60 EndGaugeEx,\r
61 GetGaugeEx\r
62 };\r
63\r
a0afd019 64/**\r
f0da4d7d 65 Searches in the gauge array with keyword Handle, Token, Module and Identifier.\r
a0afd019 66\r
67 This internal function searches for the gauge entry in the gauge array.\r
f0da4d7d 68 If there is an entry that exactly matches the given keywords\r
a0afd019 69 and its end time stamp is zero, then the index of that gauge entry is returned;\r
70 otherwise, the the number of gauge entries in the array is returned.\r
71\r
72 @param Handle Pointer to environment specific context used\r
73 to identify the component being measured.\r
74 @param Token Pointer to a Null-terminated ASCII string\r
75 that identifies the component being measured.\r
76 @param Module Pointer to a Null-terminated ASCII string\r
77 that identifies the module being measured.\r
f0da4d7d 78 @param Identifier 32-bit identifier.\r
a0afd019 79\r
80 @retval The index of gauge entry in the array.\r
81\r
82**/\r
a0afd019 83UINT32\r
84InternalSearchForGaugeEntry (\r
85 IN CONST VOID *Handle, OPTIONAL\r
86 IN CONST CHAR8 *Token, OPTIONAL\r
f0da4d7d
SZ
87 IN CONST CHAR8 *Module, OPTIONAL\r
88 IN UINT32 Identifier\r
a0afd019 89 )\r
90{\r
91 UINT32 Index;\r
b504f519 92 UINT32 Index2;\r
a0afd019 93 UINT32 NumberOfEntries;\r
f0da4d7d 94 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
a0afd019 95\r
96 if (Token == NULL) {\r
97 Token = "";\r
98 }\r
99 if (Module == NULL) {\r
100 Module = "";\r
101 }\r
102\r
103 NumberOfEntries = mGaugeData->NumberOfEntries;\r
f0da4d7d 104 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
a0afd019 105\r
b504f519
SZ
106 Index2 = 0;\r
107\r
a0afd019 108 for (Index = 0; Index < NumberOfEntries; Index++) {\r
b504f519
SZ
109 Index2 = NumberOfEntries - 1 - Index;\r
110 if (GaugeEntryExArray[Index2].EndTimeStamp == 0 &&\r
111 (GaugeEntryExArray[Index2].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&\r
112 AsciiStrnCmp (GaugeEntryExArray[Index2].Token, Token, DXE_PERFORMANCE_STRING_LENGTH) == 0 &&\r
7a9395cd 113 AsciiStrnCmp (GaugeEntryExArray[Index2].Module, Module, DXE_PERFORMANCE_STRING_LENGTH) == 0) {\r
b504f519 114 Index = Index2;\r
a0afd019 115 break;\r
116 }\r
117 }\r
118\r
119 return Index;\r
120}\r
121\r
122/**\r
123 Adds a record at the end of the performance measurement log\r
124 that records the start time of a performance measurement.\r
125\r
126 Adds a record to the end of the performance measurement log\r
f0da4d7d 127 that contains the Handle, Token, Module and Identifier.\r
a0afd019 128 The end time of the new record must be set to zero.\r
129 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
130 If TimeStamp is zero, the start time in the record is filled in with the value\r
131 read from the current time stamp.\r
132\r
133 @param Handle Pointer to environment specific context used\r
134 to identify the component being measured.\r
135 @param Token Pointer to a Null-terminated ASCII string\r
136 that identifies the component being measured.\r
137 @param Module Pointer to a Null-terminated ASCII string\r
138 that identifies the module being measured.\r
139 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
140 @param Identifier 32-bit identifier. If the value is 0, the created record\r
141 is same as the one created by StartGauge of PERFORMANCE_PROTOCOL.\r
a0afd019 142\r
143 @retval EFI_SUCCESS The data was read correctly from the device.\r
144 @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
145\r
146**/\r
a0afd019 147EFI_STATUS\r
148EFIAPI\r
f0da4d7d 149StartGaugeEx (\r
a0afd019 150 IN CONST VOID *Handle, OPTIONAL\r
151 IN CONST CHAR8 *Token, OPTIONAL\r
152 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
153 IN UINT64 TimeStamp,\r
154 IN UINT32 Identifier\r
a0afd019 155 )\r
156{\r
f0da4d7d 157 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
a0afd019 158 UINTN GaugeDataSize;\r
f0da4d7d 159 GAUGE_DATA_HEADER *NewGaugeData;\r
a0afd019 160 UINTN OldGaugeDataSize;\r
161 GAUGE_DATA_HEADER *OldGaugeData;\r
162 UINT32 Index;\r
163\r
164 Index = mGaugeData->NumberOfEntries;\r
165 if (Index >= mMaxGaugeRecords) {\r
166 //\r
857dfc45 167 // Try to enlarge the scale of gauge array.\r
a0afd019 168 //\r
169 OldGaugeData = mGaugeData;\r
f0da4d7d 170 OldGaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords;\r
a0afd019 171\r
f0da4d7d 172 GaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords * 2;\r
a0afd019 173\r
f0da4d7d
SZ
174 NewGaugeData = AllocateZeroPool (GaugeDataSize);\r
175 if (NewGaugeData == NULL) {\r
a0afd019 176 return EFI_OUT_OF_RESOURCES;\r
177 }\r
f0da4d7d
SZ
178\r
179 mGaugeData = NewGaugeData;\r
180 mMaxGaugeRecords *= 2;\r
181\r
a0afd019 182 //\r
857dfc45 183 // Initialize new data array and migrate old data one.\r
a0afd019 184 //\r
185 mGaugeData = CopyMem (mGaugeData, OldGaugeData, OldGaugeDataSize);\r
186\r
187 FreePool (OldGaugeData);\r
188 }\r
189\r
f0da4d7d
SZ
190 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
191 GaugeEntryExArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;\r
a0afd019 192\r
193 if (Token != NULL) {\r
0ec2bfc8 194 AsciiStrnCpyS (GaugeEntryExArray[Index].Token, DXE_PERFORMANCE_STRING_SIZE, Token, DXE_PERFORMANCE_STRING_LENGTH);\r
a0afd019 195 }\r
196 if (Module != NULL) {\r
0ec2bfc8 197 AsciiStrnCpyS (GaugeEntryExArray[Index].Module, DXE_PERFORMANCE_STRING_SIZE, Module, DXE_PERFORMANCE_STRING_LENGTH);\r
a0afd019 198 }\r
199\r
f0da4d7d
SZ
200 GaugeEntryExArray[Index].EndTimeStamp = 0;\r
201 GaugeEntryExArray[Index].Identifier = Identifier;\r
202\r
a0afd019 203 if (TimeStamp == 0) {\r
204 TimeStamp = GetPerformanceCounter ();\r
205 }\r
f0da4d7d 206 GaugeEntryExArray[Index].StartTimeStamp = TimeStamp;\r
a0afd019 207\r
208 mGaugeData->NumberOfEntries++;\r
209\r
210 return EFI_SUCCESS;\r
211}\r
212\r
213/**\r
214 Searches the performance measurement log from the beginning of the log\r
215 for the first matching record that contains a zero end time and fills in a valid end time.\r
216\r
217 Searches the performance measurement log from the beginning of the log\r
7a9395cd 218 for the first record that matches Handle, Token and Module and has an end time value of zero.\r
a0afd019 219 If the record can not be found then return EFI_NOT_FOUND.\r
220 If the record is found and TimeStamp is not zero,\r
221 then the end time in the record is filled in with the value specified by TimeStamp.\r
222 If the record is found and TimeStamp is zero, then the end time in the matching record\r
223 is filled in with the current time stamp value.\r
224\r
225 @param Handle Pointer to environment specific context used\r
226 to identify the component being measured.\r
227 @param Token Pointer to a Null-terminated ASCII string\r
228 that identifies the component being measured.\r
229 @param Module Pointer to a Null-terminated ASCII string\r
230 that identifies the module being measured.\r
231 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
232 @param Identifier 32-bit identifier. If the value is 0, the found record\r
233 is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.\r
a0afd019 234\r
235 @retval EFI_SUCCESS The end of the measurement was recorded.\r
236 @retval EFI_NOT_FOUND The specified measurement record could not be found.\r
237\r
238**/\r
a0afd019 239EFI_STATUS\r
240EFIAPI\r
f0da4d7d 241EndGaugeEx (\r
a0afd019 242 IN CONST VOID *Handle, OPTIONAL\r
243 IN CONST CHAR8 *Token, OPTIONAL\r
244 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
245 IN UINT64 TimeStamp,\r
246 IN UINT32 Identifier\r
a0afd019 247 )\r
248{\r
f0da4d7d
SZ
249 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
250 UINT32 Index;\r
a0afd019 251\r
252 if (TimeStamp == 0) {\r
253 TimeStamp = GetPerformanceCounter ();\r
254 }\r
255\r
f0da4d7d 256 Index = InternalSearchForGaugeEntry (Handle, Token, Module, Identifier);\r
a0afd019 257 if (Index >= mGaugeData->NumberOfEntries) {\r
258 return EFI_NOT_FOUND;\r
259 }\r
f0da4d7d
SZ
260 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
261 GaugeEntryExArray[Index].EndTimeStamp = TimeStamp;\r
a0afd019 262\r
263 return EFI_SUCCESS;\r
264}\r
265\r
266/**\r
267 Retrieves a previously logged performance measurement.\r
f0da4d7d
SZ
268 It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,\r
269 and then assign the Identifier with 0.\r
a0afd019 270\r
271 Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
272 If it stands for a valid entry, then EFI_SUCCESS is returned and\r
f0da4d7d 273 GaugeDataEntryEx stores the pointer to that entry.\r
a0afd019 274\r
275 @param LogEntryKey The key for the previous performance measurement log entry.\r
276 If 0, then the first performance measurement log entry is retrieved.\r
f0da4d7d 277 @param GaugeDataEntryEx The indirect pointer to the extended gauge data entry specified by LogEntryKey\r
a0afd019 278 if the retrieval is successful.\r
279\r
f0da4d7d 280 @retval EFI_SUCCESS The GuageDataEntryEx is successfully found based on LogEntryKey.\r
a0afd019 281 @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number).\r
282 @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number).\r
f0da4d7d 283 @retval EFI_INVALIDE_PARAMETER GaugeDataEntryEx is NULL.\r
a0afd019 284\r
285**/\r
a0afd019 286EFI_STATUS\r
287EFIAPI\r
f0da4d7d
SZ
288GetGaugeEx (\r
289 IN UINTN LogEntryKey,\r
290 OUT GAUGE_DATA_ENTRY_EX **GaugeDataEntryEx\r
a0afd019 291 )\r
292{\r
293 UINTN NumberOfEntries;\r
f0da4d7d 294 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
a0afd019 295\r
296 NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries);\r
297 if (LogEntryKey > NumberOfEntries) {\r
298 return EFI_INVALID_PARAMETER;\r
299 }\r
300 if (LogEntryKey == NumberOfEntries) {\r
301 return EFI_NOT_FOUND;\r
302 }\r
303\r
f0da4d7d
SZ
304 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
305\r
306 if (GaugeDataEntryEx == NULL) {\r
307 return EFI_INVALID_PARAMETER;\r
308 }\r
309 *GaugeDataEntryEx = &GaugeEntryExArray[LogEntryKey];\r
310\r
311 return EFI_SUCCESS;\r
312}\r
313\r
314/**\r
315 Adds a record at the end of the performance measurement log\r
316 that records the start time of a performance measurement.\r
317\r
318 Adds a record to the end of the performance measurement log\r
319 that contains the Handle, Token, and Module.\r
320 The end time of the new record must be set to zero.\r
321 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
322 If TimeStamp is zero, the start time in the record is filled in with the value\r
323 read from the current time stamp.\r
324\r
325 @param Handle Pointer to environment specific context used\r
326 to identify the component being measured.\r
327 @param Token Pointer to a Null-terminated ASCII string\r
328 that identifies the component being measured.\r
329 @param Module Pointer to a Null-terminated ASCII string\r
330 that identifies the module being measured.\r
331 @param TimeStamp 64-bit time stamp.\r
332\r
333 @retval EFI_SUCCESS The data was read correctly from the device.\r
334 @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
335\r
336**/\r
337EFI_STATUS\r
338EFIAPI\r
339StartGauge (\r
340 IN CONST VOID *Handle, OPTIONAL\r
341 IN CONST CHAR8 *Token, OPTIONAL\r
342 IN CONST CHAR8 *Module, OPTIONAL\r
343 IN UINT64 TimeStamp\r
344 )\r
345{\r
346 return StartGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
347}\r
348\r
349/**\r
350 Searches the performance measurement log from the beginning of the log\r
351 for the first matching record that contains a zero end time and fills in a valid end time.\r
352\r
353 Searches the performance measurement log from the beginning of the log\r
354 for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
355 If the record can not be found then return EFI_NOT_FOUND.\r
356 If the record is found and TimeStamp is not zero,\r
357 then the end time in the record is filled in with the value specified by TimeStamp.\r
358 If the record is found and TimeStamp is zero, then the end time in the matching record\r
359 is filled in with the current time stamp value.\r
360\r
361 @param Handle Pointer to environment specific context used\r
362 to identify the component being measured.\r
363 @param Token Pointer to a Null-terminated ASCII string\r
364 that identifies the component being measured.\r
365 @param Module Pointer to a Null-terminated ASCII string\r
366 that identifies the module being measured.\r
367 @param TimeStamp 64-bit time stamp.\r
368\r
369 @retval EFI_SUCCESS The end of the measurement was recorded.\r
370 @retval EFI_NOT_FOUND The specified measurement record could not be found.\r
371\r
372**/\r
373EFI_STATUS\r
374EFIAPI\r
375EndGauge (\r
376 IN CONST VOID *Handle, OPTIONAL\r
377 IN CONST CHAR8 *Token, OPTIONAL\r
378 IN CONST CHAR8 *Module, OPTIONAL\r
379 IN UINT64 TimeStamp\r
380 )\r
381{\r
382 return EndGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
383}\r
384\r
385/**\r
386 Retrieves a previously logged performance measurement.\r
387 It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,\r
388 and then eliminate the Identifier.\r
389\r
390 Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
391 If it stands for a valid entry, then EFI_SUCCESS is returned and\r
392 GaugeDataEntry stores the pointer to that entry.\r
393\r
394 @param LogEntryKey The key for the previous performance measurement log entry.\r
395 If 0, then the first performance measurement log entry is retrieved.\r
396 @param GaugeDataEntry The indirect pointer to the gauge data entry specified by LogEntryKey\r
397 if the retrieval is successful.\r
398\r
399 @retval EFI_SUCCESS The GuageDataEntry is successfully found based on LogEntryKey.\r
400 @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number).\r
401 @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number).\r
402 @retval EFI_INVALIDE_PARAMETER GaugeDataEntry is NULL.\r
403\r
404**/\r
405EFI_STATUS\r
406EFIAPI\r
407GetGauge (\r
408 IN UINTN LogEntryKey,\r
409 OUT GAUGE_DATA_ENTRY **GaugeDataEntry\r
410 )\r
411{\r
412 EFI_STATUS Status;\r
413 GAUGE_DATA_ENTRY_EX *GaugeEntryEx;\r
414\r
1658440e
SZ
415 GaugeEntryEx = NULL;\r
416\r
f0da4d7d
SZ
417 Status = GetGaugeEx (LogEntryKey, &GaugeEntryEx);\r
418 if (EFI_ERROR (Status)) {\r
419 return Status;\r
420 }\r
a0afd019 421\r
422 if (GaugeDataEntry == NULL) {\r
423 return EFI_INVALID_PARAMETER;\r
424 }\r
f0da4d7d
SZ
425\r
426 *GaugeDataEntry = (GAUGE_DATA_ENTRY *) GaugeEntryEx;\r
a0afd019 427\r
428 return EFI_SUCCESS;\r
429}\r
430\r
431/**\r
432 Dumps all the PEI performance log to DXE performance gauge array.\r
433\r
434 This internal function dumps all the PEI performance log to the DXE performance gauge array.\r
435 It retrieves the optional GUID HOB for PEI performance and then saves the performance data\r
436 to DXE performance data structures.\r
437\r
438**/\r
a0afd019 439VOID\r
440InternalGetPeiPerformance (\r
441 VOID\r
442 )\r
443{\r
444 EFI_HOB_GUID_TYPE *GuidHob;\r
445 PEI_PERFORMANCE_LOG_HEADER *LogHob;\r
446 PEI_PERFORMANCE_LOG_ENTRY *LogEntryArray;\r
f0da4d7d
SZ
447 UINT32 *LogIdArray;\r
448 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
a0afd019 449 UINT32 Index;\r
450 UINT32 NumberOfEntries;\r
451\r
452 NumberOfEntries = 0;\r
f0da4d7d 453 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
a0afd019 454\r
455 //\r
456 // Dump PEI Log Entries to DXE Guage Data structure.\r
457 //\r
ee0961f7 458 GuidHob = GetFirstGuidHob (&gPerformanceProtocolGuid);\r
a0afd019 459 if (GuidHob != NULL) {\r
460 LogHob = GET_GUID_HOB_DATA (GuidHob);\r
461 LogEntryArray = (PEI_PERFORMANCE_LOG_ENTRY *) (LogHob + 1);\r
a0afd019 462\r
463 NumberOfEntries = LogHob->NumberOfEntries;\r
464 for (Index = 0; Index < NumberOfEntries; Index++) {\r
f0da4d7d 465 GaugeEntryExArray[Index].Handle = LogEntryArray[Index].Handle;\r
96f983fa
QS
466 AsciiStrCpyS (GaugeEntryExArray[Index].Token, DXE_PERFORMANCE_STRING_SIZE, LogEntryArray[Index].Token);\r
467 AsciiStrCpyS (GaugeEntryExArray[Index].Module, DXE_PERFORMANCE_STRING_SIZE, LogEntryArray[Index].Module);\r
f0da4d7d
SZ
468 GaugeEntryExArray[Index].StartTimeStamp = LogEntryArray[Index].StartTimeStamp;\r
469 GaugeEntryExArray[Index].EndTimeStamp = LogEntryArray[Index].EndTimeStamp;\r
470 GaugeEntryExArray[Index].Identifier = 0;\r
471 }\r
472\r
473 GuidHob = GetFirstGuidHob (&gPerformanceExProtocolGuid);\r
474 if (GuidHob != NULL) {\r
475 LogIdArray = GET_GUID_HOB_DATA (GuidHob);\r
476 for (Index = 0; Index < NumberOfEntries; Index++) {\r
477 GaugeEntryExArray[Index].Identifier = LogIdArray[Index];\r
478 }\r
a0afd019 479 }\r
480 }\r
481 mGaugeData->NumberOfEntries = NumberOfEntries;\r
482}\r
483\r
484/**\r
485 The constructor function initializes Performance infrastructure for DXE phase.\r
486\r
f0da4d7d 487 The constructor function publishes Performance and PerformanceEx protocol, allocates memory to log DXE performance\r
a0afd019 488 and merges PEI performance data to DXE performance log.\r
489 It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.\r
490\r
491 @param ImageHandle The firmware allocated handle for the EFI image.\r
492 @param SystemTable A pointer to the EFI System Table.\r
493\r
494 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
495\r
496**/\r
497EFI_STATUS\r
498EFIAPI\r
499DxeCorePerformanceLibConstructor (\r
500 IN EFI_HANDLE ImageHandle,\r
501 IN EFI_SYSTEM_TABLE *SystemTable\r
502 )\r
503{\r
504 EFI_STATUS Status;\r
505\r
506 if (!PerformanceMeasurementEnabled ()) {\r
507 //\r
508 // Do not initialize performance infrastructure if not required.\r
509 //\r
510 return EFI_SUCCESS;\r
511 }\r
512 //\r
513 // Install the protocol interfaces.\r
514 //\r
f0da4d7d 515 Status = gBS->InstallMultipleProtocolInterfaces (\r
a0afd019 516 &mHandle,\r
517 &gPerformanceProtocolGuid,\r
f0da4d7d
SZ
518 &mPerformanceInterface,\r
519 &gPerformanceExProtocolGuid,\r
520 &mPerformanceExInterface,\r
521 NULL\r
a0afd019 522 );\r
523 ASSERT_EFI_ERROR (Status);\r
524\r
7c50b343
CS
525 mMaxGaugeRecords = INIT_DXE_GAUGE_DATA_ENTRIES + (UINT16) (PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ?\r
526 PcdGet16 (PcdMaxPeiPerformanceLogEntries16) :\r
527 PcdGet8 (PcdMaxPeiPerformanceLogEntries));\r
a0afd019 528\r
f0da4d7d 529 mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords));\r
a0afd019 530 ASSERT (mGaugeData != NULL);\r
531\r
532 InternalGetPeiPerformance ();\r
533\r
534 return Status;\r
535}\r
536\r
537/**\r
538 Adds a record at the end of the performance measurement log\r
539 that records the start time of a performance measurement.\r
540\r
541 Adds a record to the end of the performance measurement log\r
f0da4d7d 542 that contains the Handle, Token, Module and Identifier.\r
a0afd019 543 The end time of the new record must be set to zero.\r
544 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
545 If TimeStamp is zero, the start time in the record is filled in with the value\r
546 read from the current time stamp.\r
547\r
548 @param Handle Pointer to environment specific context used\r
549 to identify the component being measured.\r
550 @param Token Pointer to a Null-terminated ASCII string\r
551 that identifies the component being measured.\r
552 @param Module Pointer to a Null-terminated ASCII string\r
553 that identifies the module being measured.\r
554 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
555 @param Identifier 32-bit identifier. If the value is 0, the created record\r
556 is same as the one created by StartPerformanceMeasurement.\r
a0afd019 557\r
558 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
559 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
560\r
561**/\r
562RETURN_STATUS\r
563EFIAPI\r
f0da4d7d 564StartPerformanceMeasurementEx (\r
a0afd019 565 IN CONST VOID *Handle, OPTIONAL\r
566 IN CONST CHAR8 *Token, OPTIONAL\r
567 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
568 IN UINT64 TimeStamp,\r
569 IN UINT32 Identifier\r
a0afd019 570 )\r
571{\r
f0da4d7d 572 return (RETURN_STATUS) StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
a0afd019 573}\r
574\r
575/**\r
576 Searches the performance measurement log from the beginning of the log\r
577 for the first matching record that contains a zero end time and fills in a valid end time.\r
578\r
579 Searches the performance measurement log from the beginning of the log\r
7a9395cd 580 for the first record that matches Handle, Token and Module and has an end time value of zero.\r
a0afd019 581 If the record can not be found then return RETURN_NOT_FOUND.\r
582 If the record is found and TimeStamp is not zero,\r
583 then the end time in the record is filled in with the value specified by TimeStamp.\r
584 If the record is found and TimeStamp is zero, then the end time in the matching record\r
585 is filled in with the current time stamp value.\r
586\r
587 @param Handle Pointer to environment specific context used\r
588 to identify the component being measured.\r
589 @param Token Pointer to a Null-terminated ASCII string\r
590 that identifies the component being measured.\r
591 @param Module Pointer to a Null-terminated ASCII string\r
592 that identifies the module being measured.\r
593 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
594 @param Identifier 32-bit identifier. If the value is 0, the found record\r
595 is same as the one found by EndPerformanceMeasurement.\r
a0afd019 596\r
597 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
598 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
599\r
600**/\r
601RETURN_STATUS\r
602EFIAPI\r
f0da4d7d 603EndPerformanceMeasurementEx (\r
a0afd019 604 IN CONST VOID *Handle, OPTIONAL\r
605 IN CONST CHAR8 *Token, OPTIONAL\r
606 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
607 IN UINT64 TimeStamp,\r
608 IN UINT32 Identifier\r
a0afd019 609 )\r
610{\r
f0da4d7d 611 return (RETURN_STATUS) EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
a0afd019 612}\r
613\r
614/**\r
615 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
f0da4d7d
SZ
616 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
617 and then assign the Identifier with 0.\r
a0afd019 618\r
619 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
620 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
621 and the key for the second entry in the log is returned. If the performance log is empty,\r
622 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
623 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
624 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
625 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
626 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
627 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
f0da4d7d 628 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
a0afd019 629 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
630 If Handle is NULL, then ASSERT().\r
631 If Token is NULL, then ASSERT().\r
632 If Module is NULL, then ASSERT().\r
633 If StartTimeStamp is NULL, then ASSERT().\r
634 If EndTimeStamp is NULL, then ASSERT().\r
f0da4d7d 635 If Identifier is NULL, then ASSERT().\r
a0afd019 636\r
637 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
638 0, then the first performance measurement log entry is retrieved.\r
857dfc45 639 On exit, the key of the next performance log entry.\r
a0afd019 640 @param Handle Pointer to environment specific context used to identify the component\r
641 being measured.\r
642 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
643 being measured.\r
644 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
645 being measured.\r
646 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
647 was started.\r
648 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
649 was ended.\r
f0da4d7d 650 @param Identifier Pointer to the 32-bit identifier that was recorded.\r
a0afd019 651\r
652 @return The key for the next performance log entry (in general case).\r
653\r
654**/\r
655UINTN\r
656EFIAPI\r
f0da4d7d
SZ
657GetPerformanceMeasurementEx (\r
658 IN UINTN LogEntryKey, \r
a0afd019 659 OUT CONST VOID **Handle,\r
660 OUT CONST CHAR8 **Token,\r
661 OUT CONST CHAR8 **Module,\r
662 OUT UINT64 *StartTimeStamp,\r
f0da4d7d
SZ
663 OUT UINT64 *EndTimeStamp,\r
664 OUT UINT32 *Identifier\r
a0afd019 665 )\r
666{\r
f0da4d7d
SZ
667 EFI_STATUS Status;\r
668 GAUGE_DATA_ENTRY_EX *GaugeData;\r
a0afd019 669\r
952671b3 670 GaugeData = NULL;\r
671 \r
a0afd019 672 ASSERT (Handle != NULL);\r
673 ASSERT (Token != NULL);\r
674 ASSERT (Module != NULL);\r
675 ASSERT (StartTimeStamp != NULL);\r
676 ASSERT (EndTimeStamp != NULL);\r
f0da4d7d 677 ASSERT (Identifier != NULL);\r
a0afd019 678\r
f0da4d7d 679 Status = GetGaugeEx (LogEntryKey++, &GaugeData);\r
a0afd019 680\r
681 //\r
682 // Make sure that LogEntryKey is a valid log entry key,\r
683 //\r
684 ASSERT (Status != EFI_INVALID_PARAMETER);\r
685\r
686 if (EFI_ERROR (Status)) {\r
687 //\r
688 // The LogEntryKey is the last entry (equals to the total entry number).\r
689 //\r
690 return 0;\r
691 }\r
692\r
693 ASSERT (GaugeData != NULL);\r
694\r
695 *Handle = (VOID *) (UINTN) GaugeData->Handle;\r
696 *Token = GaugeData->Token;\r
697 *Module = GaugeData->Module;\r
698 *StartTimeStamp = GaugeData->StartTimeStamp;\r
699 *EndTimeStamp = GaugeData->EndTimeStamp;\r
f0da4d7d 700 *Identifier = GaugeData->Identifier;\r
a0afd019 701\r
702 return LogEntryKey;\r
703}\r
704\r
f0da4d7d
SZ
705/**\r
706 Adds a record at the end of the performance measurement log\r
707 that records the start time of a performance measurement.\r
708\r
709 Adds a record to the end of the performance measurement log\r
710 that contains the Handle, Token, and Module.\r
711 The end time of the new record must be set to zero.\r
712 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
713 If TimeStamp is zero, the start time in the record is filled in with the value\r
714 read from the current time stamp.\r
715\r
716 @param Handle Pointer to environment specific context used\r
717 to identify the component being measured.\r
718 @param Token Pointer to a Null-terminated ASCII string\r
719 that identifies the component being measured.\r
720 @param Module Pointer to a Null-terminated ASCII string\r
721 that identifies the module being measured.\r
722 @param TimeStamp 64-bit time stamp.\r
723\r
724 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
725 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
726\r
727**/\r
728RETURN_STATUS\r
729EFIAPI\r
730StartPerformanceMeasurement (\r
731 IN CONST VOID *Handle, OPTIONAL\r
732 IN CONST CHAR8 *Token, OPTIONAL\r
733 IN CONST CHAR8 *Module, OPTIONAL\r
734 IN UINT64 TimeStamp\r
735 )\r
736{\r
737 return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
738}\r
739\r
740/**\r
741 Searches the performance measurement log from the beginning of the log\r
742 for the first matching record that contains a zero end time and fills in a valid end time.\r
743\r
744 Searches the performance measurement log from the beginning of the log\r
745 for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
746 If the record can not be found then return RETURN_NOT_FOUND.\r
747 If the record is found and TimeStamp is not zero,\r
748 then the end time in the record is filled in with the value specified by TimeStamp.\r
749 If the record is found and TimeStamp is zero, then the end time in the matching record\r
750 is filled in with the current time stamp value.\r
751\r
752 @param Handle Pointer to environment specific context used\r
753 to identify the component being measured.\r
754 @param Token Pointer to a Null-terminated ASCII string\r
755 that identifies the component being measured.\r
756 @param Module Pointer to a Null-terminated ASCII string\r
757 that identifies the module being measured.\r
758 @param TimeStamp 64-bit time stamp.\r
759\r
760 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
761 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
762\r
763**/\r
764RETURN_STATUS\r
765EFIAPI\r
766EndPerformanceMeasurement (\r
767 IN CONST VOID *Handle, OPTIONAL\r
768 IN CONST CHAR8 *Token, OPTIONAL\r
769 IN CONST CHAR8 *Module, OPTIONAL\r
770 IN UINT64 TimeStamp\r
771 )\r
772{\r
773 return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
774}\r
775\r
776/**\r
777 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
778 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
779 and then eliminate the Identifier.\r
780\r
781 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
782 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
783 and the key for the second entry in the log is returned. If the performance log is empty,\r
784 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
785 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
786 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
787 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
788 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
789 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
790 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
791 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
792 If Handle is NULL, then ASSERT().\r
793 If Token is NULL, then ASSERT().\r
794 If Module is NULL, then ASSERT().\r
795 If StartTimeStamp is NULL, then ASSERT().\r
796 If EndTimeStamp is NULL, then ASSERT().\r
797\r
798 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
799 0, then the first performance measurement log entry is retrieved.\r
800 On exit, the key of the next performance log entry.\r
801 @param Handle Pointer to environment specific context used to identify the component\r
802 being measured.\r
803 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
804 being measured.\r
805 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
806 being measured.\r
807 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
808 was started.\r
809 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
810 was ended.\r
811\r
812 @return The key for the next performance log entry (in general case).\r
813\r
814**/\r
815UINTN\r
816EFIAPI\r
817GetPerformanceMeasurement (\r
818 IN UINTN LogEntryKey,\r
819 OUT CONST VOID **Handle,\r
820 OUT CONST CHAR8 **Token,\r
821 OUT CONST CHAR8 **Module,\r
822 OUT UINT64 *StartTimeStamp,\r
823 OUT UINT64 *EndTimeStamp\r
824 )\r
825{\r
826 UINT32 Identifier;\r
827 return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
828}\r
829\r
a0afd019 830/**\r
831 Returns TRUE if the performance measurement macros are enabled.\r
832\r
833 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
834 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.\r
835\r
836 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
837 PcdPerformanceLibraryPropertyMask is set.\r
838 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
839 PcdPerformanceLibraryPropertyMask is clear.\r
840\r
841**/\r
842BOOLEAN\r
843EFIAPI\r
844PerformanceMeasurementEnabled (\r
845 VOID\r
846 )\r
847{\r
848 return (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);\r
849}\r