]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/SmmCorePerformanceLib/SmmCorePerformanceLib.c
Refine the code to follow coding style.
[mirror_edk2.git] / MdeModulePkg / Library / SmmCorePerformanceLib / SmmCorePerformanceLib.c
CommitLineData
d042c6e8 1/** @file\r
2 Performance library instance used by SMM Core.\r
3\r
4 This library provides the performance measurement interfaces and initializes performance\r
5 logging for the SMM phase.\r
f0da4d7d 6 It initializes SMM phase performance logging by publishing the SMM Performance and PerformanceEx Protocol,\r
d042c6e8 7 which is consumed by SmmPerformanceLib to logging performance data in SMM phase.\r
8\r
9 This library is mainly used by SMM Core to start performance logging to ensure that\r
f0da4d7d 10 SMM Performance and PerformanceEx Protocol are installed at the very beginning of SMM phase.\r
d042c6e8 11\r
f0da4d7d 12Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>\r
d042c6e8 13This program and the accompanying materials\r
14are licensed and made available under the terms and conditions of the BSD License\r
15which accompanies this distribution. The full text of the license may be found at\r
16http://opensource.org/licenses/bsd-license.php\r
17\r
18THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
19WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
20\r
21**/\r
22\r
23\r
24#include "SmmCorePerformanceLibInternal.h"\r
25\r
26//\r
27// The data structure to hold global performance data.\r
28//\r
29GAUGE_DATA_HEADER *mGaugeData;\r
30\r
31//\r
32// The current maximum number of logging entries. If current number of \r
33// entries exceeds this value, it will re-allocate a larger array and\r
34// migration the old data to the larger array.\r
35//\r
36UINT32 mMaxGaugeRecords;\r
37\r
38//\r
39// The handle to install Performance Protocol instance.\r
40//\r
41EFI_HANDLE mHandle = NULL;\r
42\r
43BOOLEAN mPerformanceMeasurementEnabled;\r
44\r
45SPIN_LOCK mSmmPerfLock;\r
46\r
47EFI_SMRAM_DESCRIPTOR *mSmramRanges;\r
48UINTN mSmramRangeCount;\r
49\r
50//\r
f0da4d7d 51// Interfaces for SMM Performance Protocol.\r
d042c6e8 52//\r
53PERFORMANCE_PROTOCOL mPerformanceInterface = {\r
54 StartGauge,\r
55 EndGauge,\r
56 GetGauge\r
57};\r
58\r
f0da4d7d
SZ
59//\r
60// Interfaces for SMM PerformanceEx Protocol.\r
61//\r
62PERFORMANCE_EX_PROTOCOL mPerformanceExInterface = {\r
63 StartGaugeEx,\r
64 EndGaugeEx,\r
65 GetGaugeEx\r
66};\r
67\r
d042c6e8 68/**\r
f0da4d7d 69 Searches in the gauge array with keyword Handle, Token, Module and Identfier.\r
d042c6e8 70\r
71 This internal function searches for the gauge entry in the gauge array.\r
f0da4d7d 72 If there is an entry that exactly matches the given keywords\r
d042c6e8 73 and its end time stamp is zero, then the index of that gauge entry is returned;\r
74 otherwise, the the number of gauge entries in the array is returned.\r
75\r
76 @param Handle Pointer to environment specific context used\r
77 to identify the component being measured.\r
78 @param Token Pointer to a Null-terminated ASCII string\r
79 that identifies the component being measured.\r
80 @param Module Pointer to a Null-terminated ASCII string\r
81 that identifies the module being measured.\r
f0da4d7d 82 @param Identifier 32-bit identifier.\r
d042c6e8 83\r
84 @retval The index of gauge entry in the array.\r
85\r
86**/\r
87UINT32\r
88SmmSearchForGaugeEntry (\r
89 IN CONST VOID *Handle, OPTIONAL\r
90 IN CONST CHAR8 *Token, OPTIONAL\r
f0da4d7d
SZ
91 IN CONST CHAR8 *Module, OPTIONAL\r
92 IN CONST UINT32 Identifier\r
d042c6e8 93 )\r
94{\r
95 UINT32 Index;\r
96 UINT32 NumberOfEntries;\r
f0da4d7d 97 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
d042c6e8 98\r
99 if (Token == NULL) {\r
100 Token = "";\r
101 }\r
102 if (Module == NULL) {\r
103 Module = "";\r
104 }\r
105\r
106 NumberOfEntries = mGaugeData->NumberOfEntries;\r
f0da4d7d 107 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
d042c6e8 108\r
109 for (Index = 0; Index < NumberOfEntries; Index++) {\r
f0da4d7d
SZ
110 if ((GaugeEntryExArray[Index].Handle == (EFI_PHYSICAL_ADDRESS) (UINTN) Handle) &&\r
111 AsciiStrnCmp (GaugeEntryExArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&\r
112 AsciiStrnCmp (GaugeEntryExArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH) == 0 &&\r
113 (GaugeEntryExArray[Index].Identifier == Identifier) &&\r
114 GaugeEntryExArray[Index].EndTimeStamp == 0) {\r
d042c6e8 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
d042c6e8 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
d042c6e8 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
147EFI_STATUS\r
148EFIAPI\r
f0da4d7d 149StartGaugeEx (\r
d042c6e8 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
d042c6e8 155 )\r
156{\r
f0da4d7d 157 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
d042c6e8 158 UINTN GaugeDataSize;\r
f0da4d7d 159 GAUGE_DATA_HEADER *NewGaugeData;\r
d042c6e8 160 UINTN OldGaugeDataSize;\r
161 GAUGE_DATA_HEADER *OldGaugeData;\r
162 UINT32 Index;\r
163\r
164 AcquireSpinLock (&mSmmPerfLock);\r
165\r
166 Index = mGaugeData->NumberOfEntries;\r
167 if (Index >= mMaxGaugeRecords) {\r
168 //\r
169 // Try to enlarge the scale of gauge array.\r
170 //\r
171 OldGaugeData = mGaugeData;\r
f0da4d7d 172 OldGaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords;\r
d042c6e8 173\r
f0da4d7d 174 GaugeDataSize = sizeof (GAUGE_DATA_HEADER) + sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords * 2;\r
d042c6e8 175\r
f0da4d7d
SZ
176 NewGaugeData = AllocateZeroPool (GaugeDataSize);\r
177 if (NewGaugeData == NULL) {\r
178 ReleaseSpinLock (&mSmmPerfLock);\r
d042c6e8 179 return EFI_OUT_OF_RESOURCES;\r
180 }\r
f0da4d7d
SZ
181\r
182 mGaugeData = NewGaugeData;\r
183 mMaxGaugeRecords *= 2;\r
184\r
d042c6e8 185 //\r
186 // Initialize new data array and migrate old data one.\r
187 //\r
188 mGaugeData = CopyMem (mGaugeData, OldGaugeData, OldGaugeDataSize);\r
189\r
190 FreePool (OldGaugeData);\r
191 }\r
192\r
f0da4d7d
SZ
193 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
194 GaugeEntryExArray[Index].Handle = (EFI_PHYSICAL_ADDRESS) (UINTN) Handle;\r
d042c6e8 195\r
196 if (Token != NULL) {\r
f0da4d7d 197 AsciiStrnCpy (GaugeEntryExArray[Index].Token, Token, SMM_PERFORMANCE_STRING_LENGTH);\r
d042c6e8 198 }\r
199 if (Module != NULL) {\r
f0da4d7d 200 AsciiStrnCpy (GaugeEntryExArray[Index].Module, Module, SMM_PERFORMANCE_STRING_LENGTH);\r
d042c6e8 201 }\r
202\r
f0da4d7d
SZ
203 GaugeEntryExArray[Index].EndTimeStamp = 0;\r
204 GaugeEntryExArray[Index].Identifier = Identifier;\r
205\r
d042c6e8 206 if (TimeStamp == 0) {\r
207 TimeStamp = GetPerformanceCounter ();\r
208 }\r
f0da4d7d 209 GaugeEntryExArray[Index].StartTimeStamp = TimeStamp;\r
d042c6e8 210\r
211 mGaugeData->NumberOfEntries++;\r
212\r
213 ReleaseSpinLock (&mSmmPerfLock);\r
214\r
215 return EFI_SUCCESS;\r
216}\r
217\r
218/**\r
219 Searches the performance measurement log from the beginning of the log\r
220 for the first matching record that contains a zero end time and fills in a valid end time.\r
221\r
222 Searches the performance measurement log from the beginning of the log\r
f0da4d7d 223 for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\r
d042c6e8 224 If the record can not be found then return EFI_NOT_FOUND.\r
225 If the record is found and TimeStamp is not zero,\r
226 then the end time in the record is filled in with the value specified by TimeStamp.\r
227 If the record is found and TimeStamp is zero, then the end time in the matching record\r
228 is filled in with the current time stamp value.\r
229\r
230 @param Handle Pointer to environment specific context used\r
231 to identify the component being measured.\r
232 @param Token Pointer to a Null-terminated ASCII string\r
233 that identifies the component being measured.\r
234 @param Module Pointer to a Null-terminated ASCII string\r
235 that identifies the module being measured.\r
236 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
237 @param Identifier 32-bit identifier. If the value is 0, the found record\r
238 is same as the one found by EndGauge of PERFORMANCE_PROTOCOL.\r
d042c6e8 239\r
240 @retval EFI_SUCCESS The end of the measurement was recorded.\r
241 @retval EFI_NOT_FOUND The specified measurement record could not be found.\r
242\r
243**/\r
244EFI_STATUS\r
245EFIAPI\r
f0da4d7d 246EndGaugeEx (\r
d042c6e8 247 IN CONST VOID *Handle, OPTIONAL\r
248 IN CONST CHAR8 *Token, OPTIONAL\r
249 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
250 IN UINT64 TimeStamp,\r
251 IN UINT32 Identifier\r
d042c6e8 252 )\r
253{\r
f0da4d7d
SZ
254 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
255 UINT32 Index;\r
256\r
257 AcquireSpinLock (&mSmmPerfLock);\r
d042c6e8 258\r
259 if (TimeStamp == 0) {\r
260 TimeStamp = GetPerformanceCounter ();\r
261 }\r
262\r
f0da4d7d 263 Index = SmmSearchForGaugeEntry (Handle, Token, Module, Identifier);\r
d042c6e8 264 if (Index >= mGaugeData->NumberOfEntries) {\r
f0da4d7d 265 ReleaseSpinLock (&mSmmPerfLock);\r
d042c6e8 266 return EFI_NOT_FOUND;\r
267 }\r
f0da4d7d
SZ
268 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
269 GaugeEntryExArray[Index].EndTimeStamp = TimeStamp;\r
270\r
271 ReleaseSpinLock (&mSmmPerfLock);\r
d042c6e8 272\r
273 return EFI_SUCCESS;\r
274}\r
275\r
276/**\r
277 Retrieves a previously logged performance measurement.\r
f0da4d7d
SZ
278 It can also retrieve the log created by StartGauge and EndGauge of PERFORMANCE_PROTOCOL,\r
279 and then assign the Identifier with 0.\r
d042c6e8 280\r
281 Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
282 If it stands for a valid entry, then EFI_SUCCESS is returned and\r
f0da4d7d 283 GaugeDataEntryEx stores the pointer to that entry.\r
d042c6e8 284\r
285 @param LogEntryKey The key for the previous performance measurement log entry.\r
286 If 0, then the first performance measurement log entry is retrieved.\r
f0da4d7d 287 @param GaugeDataEntryEx The indirect pointer to the extended gauge data entry specified by LogEntryKey\r
d042c6e8 288 if the retrieval is successful.\r
289\r
f0da4d7d 290 @retval EFI_SUCCESS The GuageDataEntryEx is successfully found based on LogEntryKey.\r
d042c6e8 291 @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number).\r
292 @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number).\r
f0da4d7d 293 @retval EFI_INVALIDE_PARAMETER GaugeDataEntryEx is NULL.\r
d042c6e8 294\r
295**/\r
296EFI_STATUS\r
297EFIAPI\r
f0da4d7d
SZ
298GetGaugeEx (\r
299 IN UINTN LogEntryKey,\r
300 OUT GAUGE_DATA_ENTRY_EX **GaugeDataEntryEx\r
d042c6e8 301 )\r
302{\r
303 UINTN NumberOfEntries;\r
f0da4d7d 304 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
d042c6e8 305\r
306 NumberOfEntries = (UINTN) (mGaugeData->NumberOfEntries);\r
307 if (LogEntryKey > NumberOfEntries) {\r
308 return EFI_INVALID_PARAMETER;\r
309 }\r
310 if (LogEntryKey == NumberOfEntries) {\r
311 return EFI_NOT_FOUND;\r
312 }\r
313\r
f0da4d7d 314 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
d042c6e8 315\r
f0da4d7d 316 if (GaugeDataEntryEx == NULL) {\r
d042c6e8 317 return EFI_INVALID_PARAMETER;\r
318 }\r
f0da4d7d 319 *GaugeDataEntryEx = &GaugeEntryExArray[LogEntryKey];\r
d042c6e8 320\r
321 return EFI_SUCCESS;\r
322}\r
323\r
f0da4d7d
SZ
324/**\r
325 Adds a record at the end of the performance measurement log\r
326 that records the start time of a performance measurement.\r
327\r
328 Adds a record to the end of the performance measurement log\r
329 that contains the Handle, Token, and Module.\r
330 The end time of the new record must be set to zero.\r
331 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
332 If TimeStamp is zero, the start time in the record is filled in with the value\r
333 read from the current time stamp.\r
334\r
335 @param Handle Pointer to environment specific context used\r
336 to identify the component being measured.\r
337 @param Token Pointer to a Null-terminated ASCII string\r
338 that identifies the component being measured.\r
339 @param Module Pointer to a Null-terminated ASCII string\r
340 that identifies the module being measured.\r
341 @param TimeStamp 64-bit time stamp.\r
342\r
343 @retval EFI_SUCCESS The data was read correctly from the device.\r
344 @retval EFI_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
345\r
346**/\r
347EFI_STATUS\r
348EFIAPI\r
349StartGauge (\r
350 IN CONST VOID *Handle, OPTIONAL\r
351 IN CONST CHAR8 *Token, OPTIONAL\r
352 IN CONST CHAR8 *Module, OPTIONAL\r
353 IN UINT64 TimeStamp\r
354 )\r
355{\r
356 return StartGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
357}\r
358\r
359/**\r
360 Searches the performance measurement log from the beginning of the log\r
361 for the first matching record that contains a zero end time and fills in a valid end time.\r
362\r
363 Searches the performance measurement log from the beginning of the log\r
364 for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
365 If the record can not be found then return EFI_NOT_FOUND.\r
366 If the record is found and TimeStamp is not zero,\r
367 then the end time in the record is filled in with the value specified by TimeStamp.\r
368 If the record is found and TimeStamp is zero, then the end time in the matching record\r
369 is filled in with the current time stamp value.\r
370\r
371 @param Handle Pointer to environment specific context used\r
372 to identify the component being measured.\r
373 @param Token Pointer to a Null-terminated ASCII string\r
374 that identifies the component being measured.\r
375 @param Module Pointer to a Null-terminated ASCII string\r
376 that identifies the module being measured.\r
377 @param TimeStamp 64-bit time stamp.\r
378\r
379 @retval EFI_SUCCESS The end of the measurement was recorded.\r
380 @retval EFI_NOT_FOUND The specified measurement record could not be found.\r
381\r
382**/\r
383EFI_STATUS\r
384EFIAPI\r
385EndGauge (\r
386 IN CONST VOID *Handle, OPTIONAL\r
387 IN CONST CHAR8 *Token, OPTIONAL\r
388 IN CONST CHAR8 *Module, OPTIONAL\r
389 IN UINT64 TimeStamp\r
390 )\r
391{\r
392 return EndGaugeEx (Handle, Token, Module, TimeStamp, 0);\r
393}\r
394\r
395/**\r
396 Retrieves a previously logged performance measurement.\r
397 It can also retrieve the log created by StartGaugeEx and EndGaugeEx of PERFORMANCE_EX_PROTOCOL,\r
398 and then eliminate the Identifier.\r
399\r
400 Retrieves the performance log entry from the performance log specified by LogEntryKey.\r
401 If it stands for a valid entry, then EFI_SUCCESS is returned and\r
402 GaugeDataEntry stores the pointer to that entry.\r
403\r
404 @param LogEntryKey The key for the previous performance measurement log entry.\r
405 If 0, then the first performance measurement log entry is retrieved.\r
406 @param GaugeDataEntry The indirect pointer to the gauge data entry specified by LogEntryKey\r
407 if the retrieval is successful.\r
408\r
409 @retval EFI_SUCCESS The GuageDataEntry is successfully found based on LogEntryKey.\r
410 @retval EFI_NOT_FOUND The LogEntryKey is the last entry (equals to the total entry number).\r
411 @retval EFI_INVALIDE_PARAMETER The LogEntryKey is not a valid entry (greater than the total entry number).\r
412 @retval EFI_INVALIDE_PARAMETER GaugeDataEntry is NULL.\r
413\r
414**/\r
415EFI_STATUS\r
416EFIAPI\r
417GetGauge (\r
418 IN UINTN LogEntryKey,\r
419 OUT GAUGE_DATA_ENTRY **GaugeDataEntry\r
420 )\r
421{\r
422 EFI_STATUS Status;\r
423 GAUGE_DATA_ENTRY_EX *GaugeEntryEx;\r
424\r
1658440e
SZ
425 GaugeEntryEx = NULL;\r
426\r
f0da4d7d
SZ
427 Status = GetGaugeEx (LogEntryKey, &GaugeEntryEx);\r
428 if (EFI_ERROR (Status)) {\r
429 return Status;\r
430 }\r
431\r
432 if (GaugeDataEntry == NULL) {\r
433 return EFI_INVALID_PARAMETER;\r
434 }\r
435\r
436 *GaugeDataEntry = (GAUGE_DATA_ENTRY *) GaugeEntryEx;\r
437\r
438 return EFI_SUCCESS;\r
439}\r
d042c6e8 440\r
441/**\r
442 This function check if the address is in SMRAM.\r
443\r
444 @param Buffer the buffer address to be checked.\r
445 @param Length the buffer length to be checked.\r
446\r
447 @retval TRUE this address is in SMRAM.\r
448 @retval FALSE this address is NOT in SMRAM.\r
449**/\r
450BOOLEAN\r
451IsAddressInSmram (\r
452 IN EFI_PHYSICAL_ADDRESS Buffer,\r
453 IN UINT64 Length\r
454 )\r
455{\r
456 UINTN Index;\r
457\r
458 for (Index = 0; Index < mSmramRangeCount; Index ++) {\r
459 if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||\r
460 ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {\r
461 return TRUE;\r
462 }\r
463 }\r
464\r
465 return FALSE;\r
466}\r
467\r
468/**\r
469 Communication service SMI Handler entry.\r
470\r
f0da4d7d
SZ
471 This SMI handler provides services for the performance wrapper driver.\r
472\r
473 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
474 @param[in] RegisterContext Points to an optional handler context which was specified when the\r
475 handler was registered.\r
476 @param[in, out] CommBuffer A pointer to a collection of data in memory that will\r
477 be conveyed from a non-SMM environment into an SMM environment.\r
478 @param[in, out] CommBufferSize The size of the CommBuffer.\r
479\r
480 @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers \r
481 should still be called.\r
482 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should \r
483 still be called.\r
484 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still \r
485 be called.\r
486 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.\r
487**/\r
488EFI_STATUS\r
489EFIAPI\r
490SmmPerformanceHandlerEx (\r
491 IN EFI_HANDLE DispatchHandle,\r
492 IN CONST VOID *RegisterContext,\r
493 IN OUT VOID *CommBuffer,\r
494 IN OUT UINTN *CommBufferSize\r
495 )\r
496{\r
497 EFI_STATUS Status;\r
498 SMM_PERF_COMMUNICATE_EX *SmmPerfCommData;\r
499 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
500 UINTN DataSize;\r
501\r
502 GaugeEntryExArray = NULL;\r
503\r
504 ASSERT (CommBuffer != NULL);\r
505\r
506 SmmPerfCommData = (SMM_PERF_COMMUNICATE_EX *)CommBuffer;\r
507\r
508 switch (SmmPerfCommData->Function) {\r
509 case SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER :\r
510 SmmPerfCommData->NumberOfEntries = mGaugeData->NumberOfEntries;\r
511 Status = EFI_SUCCESS;\r
512 break;\r
513\r
514 case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
515 if ( SmmPerfCommData->GaugeDataEx == NULL || SmmPerfCommData->NumberOfEntries == 0 ||\r
516 (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
517 Status = EFI_INVALID_PARAMETER;\r
518 break;\r
519 }\r
520\r
521 //\r
522 // Sanity check\r
523 //\r
524 DataSize = SmmPerfCommData->NumberOfEntries * sizeof(GAUGE_DATA_ENTRY_EX);\r
525 if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)SmmPerfCommData->GaugeDataEx, DataSize)) {\r
526 DEBUG ((EFI_D_ERROR, "Smm Performance Data buffer is in SMRAM!\n"));\r
527 Status = EFI_ACCESS_DENIED;\r
528 break ;\r
529 }\r
530\r
531 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
532 CopyMem(\r
533 (UINT8 *) (SmmPerfCommData->GaugeDataEx),\r
534 (UINT8 *) &GaugeEntryExArray[SmmPerfCommData->LogEntryKey],\r
535 DataSize\r
536 );\r
537 Status = EFI_SUCCESS;\r
538 break;\r
539\r
540 default:\r
541 ASSERT (FALSE);\r
542 Status = EFI_UNSUPPORTED;\r
543 }\r
544\r
545 SmmPerfCommData->ReturnStatus = Status;\r
546 return EFI_SUCCESS;\r
547}\r
548\r
549/**\r
550 Communication service SMI Handler entry.\r
551\r
552 This SMI handler provides services for the performance wrapper driver.\r
d042c6e8 553\r
554 @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
555 @param[in] RegisterContext Points to an optional handler context which was specified when the\r
556 handler was registered.\r
557 @param[in, out] CommBuffer A pointer to a collection of data in memory that will\r
558 be conveyed from a non-SMM environment into an SMM environment.\r
559 @param[in, out] CommBufferSize The size of the CommBuffer.\r
560\r
561 @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers \r
562 should still be called.\r
563 @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should \r
564 still be called.\r
565 @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still \r
566 be called.\r
567 @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.\r
568**/\r
569EFI_STATUS\r
570EFIAPI\r
571SmmPerformanceHandler (\r
572 IN EFI_HANDLE DispatchHandle,\r
573 IN CONST VOID *RegisterContext,\r
f0da4d7d
SZ
574 IN OUT VOID *CommBuffer,\r
575 IN OUT UINTN *CommBufferSize\r
d042c6e8 576 )\r
577{\r
578 EFI_STATUS Status;\r
579 SMM_PERF_COMMUNICATE *SmmPerfCommData;\r
f0da4d7d 580 GAUGE_DATA_ENTRY_EX *GaugeEntryExArray;\r
d042c6e8 581 UINTN DataSize;\r
f0da4d7d
SZ
582 UINTN Index;\r
583 UINTN LogEntryKey;\r
584\r
585 GaugeEntryExArray = NULL;\r
d042c6e8 586\r
d042c6e8 587 ASSERT (CommBuffer != NULL);\r
588\r
f0da4d7d 589 SmmPerfCommData = (SMM_PERF_COMMUNICATE *)CommBuffer;\r
d042c6e8 590\r
591 switch (SmmPerfCommData->Function) {\r
592 case SMM_PERF_FUNCTION_GET_GAUGE_ENTRY_NUMBER :\r
593 SmmPerfCommData->NumberOfEntries = mGaugeData->NumberOfEntries;\r
f0da4d7d 594 Status = EFI_SUCCESS;\r
d042c6e8 595 break;\r
596\r
597 case SMM_PERF_FUNCTION_GET_GAUGE_DATA :\r
f0da4d7d
SZ
598 if ( SmmPerfCommData->GaugeData == NULL || SmmPerfCommData->NumberOfEntries == 0 ||\r
599 (SmmPerfCommData->LogEntryKey + SmmPerfCommData->NumberOfEntries) > mGaugeData->NumberOfEntries) {\r
d042c6e8 600 Status = EFI_INVALID_PARAMETER;\r
601 break;\r
d042c6e8 602 }\r
f0da4d7d 603\r
d042c6e8 604 //\r
605 // Sanity check\r
606 //\r
607 DataSize = SmmPerfCommData->NumberOfEntries * sizeof(GAUGE_DATA_ENTRY);\r
608 if (IsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)SmmPerfCommData->GaugeData, DataSize)) {\r
609 DEBUG ((EFI_D_ERROR, "Smm Performance Data buffer is in SMRAM!\n"));\r
610 Status = EFI_ACCESS_DENIED;\r
611 break ;\r
612 }\r
613\r
f0da4d7d
SZ
614 GaugeEntryExArray = (GAUGE_DATA_ENTRY_EX *) (mGaugeData + 1);\r
615\r
616 LogEntryKey = SmmPerfCommData->LogEntryKey;\r
617 for (Index = 0; Index < SmmPerfCommData->NumberOfEntries; Index++) {\r
618 CopyMem(\r
619 (UINT8 *) &(SmmPerfCommData->GaugeData[Index]),\r
620 (UINT8 *) &GaugeEntryExArray[LogEntryKey++],\r
621 sizeof (GAUGE_DATA_ENTRY)\r
622 );\r
623 }\r
624 Status = EFI_SUCCESS;\r
d042c6e8 625 break;\r
626\r
627 default:\r
628 ASSERT (FALSE);\r
629 Status = EFI_UNSUPPORTED;\r
f0da4d7d 630 }\r
d042c6e8 631\r
632 SmmPerfCommData->ReturnStatus = Status;\r
633 return EFI_SUCCESS;\r
634}\r
635\r
636/**\r
637 SmmBase2 protocol notify callback function, when SMST and SMM memory service get initialized \r
f0da4d7d 638 this function is callbacked to initialize the Smm Performance Lib \r
d042c6e8 639\r
640 @param Event The event of notify protocol.\r
641 @param Context Notify event context.\r
642\r
643**/\r
644VOID\r
645EFIAPI\r
646InitializeSmmCorePerformanceLib (\r
647 IN EFI_EVENT Event,\r
648 IN VOID *Context\r
649 )\r
650{\r
651 EFI_STATUS Status;\r
652 EFI_HANDLE Handle;\r
653 EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;\r
654 UINTN Size;\r
655\r
656\r
657 //\r
658 // Initialize spin lock\r
659 //\r
660 InitializeSpinLock (&mSmmPerfLock);\r
661\r
f0da4d7d 662 mMaxGaugeRecords = INIT_SMM_GAUGE_DATA_ENTRIES;\r
d042c6e8 663\r
f0da4d7d 664 mGaugeData = AllocateZeroPool (sizeof (GAUGE_DATA_HEADER) + (sizeof (GAUGE_DATA_ENTRY_EX) * mMaxGaugeRecords));\r
d042c6e8 665 ASSERT (mGaugeData != NULL);\r
666 \r
667 //\r
668 // Get SMRAM information\r
669 //\r
670 Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);\r
671 ASSERT_EFI_ERROR (Status);\r
672\r
673 Size = 0;\r
674 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);\r
675 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
676\r
677 Status = gSmst->SmmAllocatePool (\r
678 EfiRuntimeServicesData,\r
679 Size,\r
680 (VOID **)&mSmramRanges\r
681 );\r
682 ASSERT_EFI_ERROR (Status);\r
683\r
684 Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);\r
685 ASSERT_EFI_ERROR (Status);\r
686\r
687 mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
688\r
689 //\r
690 // Install the protocol interfaces.\r
691 //\r
692 Status = gSmst->SmmInstallProtocolInterface (\r
693 &mHandle,\r
694 &gSmmPerformanceProtocolGuid,\r
695 EFI_NATIVE_INTERFACE,\r
696 &mPerformanceInterface\r
697 );\r
698 ASSERT_EFI_ERROR (Status);\r
699\r
f0da4d7d
SZ
700 Status = gSmst->SmmInstallProtocolInterface (\r
701 &mHandle,\r
702 &gSmmPerformanceExProtocolGuid,\r
703 EFI_NATIVE_INTERFACE,\r
704 &mPerformanceExInterface\r
705 );\r
706 ASSERT_EFI_ERROR (Status);\r
707\r
d042c6e8 708 ///\r
709 /// Register SMM Performance SMI handler\r
710 ///\r
711 Handle = NULL;\r
712 Status = gSmst->SmiHandlerRegister (SmmPerformanceHandler, &gSmmPerformanceProtocolGuid, &Handle);\r
713 ASSERT_EFI_ERROR (Status);\r
f0da4d7d
SZ
714 Status = gSmst->SmiHandlerRegister (SmmPerformanceHandlerEx, &gSmmPerformanceExProtocolGuid, &Handle);\r
715 ASSERT_EFI_ERROR (Status);\r
d042c6e8 716}\r
717\r
718/**\r
f0da4d7d
SZ
719 The constructor function initializes the Performance Measurement Enable flag and \r
720 registers SmmBase2 protocol notify callback.\r
d042c6e8 721 It will ASSERT() if one of these operations fails and it will always return EFI_SUCCESS.\r
722\r
723 @param ImageHandle The firmware allocated handle for the EFI image.\r
724 @param SystemTable A pointer to the EFI System Table.\r
725\r
726 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
727\r
728**/\r
729EFI_STATUS\r
730EFIAPI\r
731SmmCorePerformanceLibConstructor (\r
732 IN EFI_HANDLE ImageHandle,\r
733 IN EFI_SYSTEM_TABLE *SystemTable\r
734 )\r
735{\r
736 EFI_STATUS Status;\r
737 EFI_EVENT Event;\r
738 VOID *Registration;\r
739\r
740 mPerformanceMeasurementEnabled = (BOOLEAN) ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);\r
741 if (!mPerformanceMeasurementEnabled) {\r
742 //\r
743 // Do not initialize performance infrastructure if not required.\r
744 //\r
745 return EFI_SUCCESS;\r
746 }\r
747\r
748 //\r
749 // Create the events to do the library init.\r
750 //\r
751 Status = gBS->CreateEvent (\r
752 EVT_NOTIFY_SIGNAL,\r
753 TPL_CALLBACK,\r
754 InitializeSmmCorePerformanceLib,\r
755 NULL,\r
756 &Event\r
757 );\r
758 ASSERT_EFI_ERROR (Status);\r
759\r
760 //\r
761 // Register for protocol notifications on this event\r
762 //\r
763 Status = gBS->RegisterProtocolNotify (\r
764 &gEfiSmmBase2ProtocolGuid,\r
765 Event,\r
766 &Registration\r
767 );\r
768\r
769 ASSERT_EFI_ERROR (Status);\r
770\r
771 return EFI_SUCCESS;\r
772}\r
773\r
774/**\r
775 Adds a record at the end of the performance measurement log\r
776 that records the start time of a performance measurement.\r
777\r
778 Adds a record to the end of the performance measurement log\r
f0da4d7d 779 that contains the Handle, Token, Module and Identifier.\r
d042c6e8 780 The end time of the new record must be set to zero.\r
781 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
782 If TimeStamp is zero, the start time in the record is filled in with the value\r
783 read from the current time stamp.\r
784\r
785 @param Handle Pointer to environment specific context used\r
786 to identify the component being measured.\r
787 @param Token Pointer to a Null-terminated ASCII string\r
788 that identifies the component being measured.\r
789 @param Module Pointer to a Null-terminated ASCII string\r
790 that identifies the module being measured.\r
791 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
792 @param Identifier 32-bit identifier. If the value is 0, the created record\r
793 is same as the one created by StartPerformanceMeasurement.\r
d042c6e8 794\r
795 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
796 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
797\r
798**/\r
799RETURN_STATUS\r
800EFIAPI\r
f0da4d7d 801StartPerformanceMeasurementEx (\r
d042c6e8 802 IN CONST VOID *Handle, OPTIONAL\r
803 IN CONST CHAR8 *Token, OPTIONAL\r
804 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
805 IN UINT64 TimeStamp,\r
806 IN UINT32 Identifier\r
d042c6e8 807 )\r
808{\r
f0da4d7d 809 return (RETURN_STATUS) StartGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
d042c6e8 810}\r
811\r
812/**\r
813 Searches the performance measurement log from the beginning of the log\r
814 for the first matching record that contains a zero end time and fills in a valid end time.\r
815\r
816 Searches the performance measurement log from the beginning of the log\r
f0da4d7d 817 for the first record that matches Handle, Token, Module and Identifier and has an end time value of zero.\r
d042c6e8 818 If the record can not be found then return RETURN_NOT_FOUND.\r
819 If the record is found and TimeStamp is not zero,\r
820 then the end time in the record is filled in with the value specified by TimeStamp.\r
821 If the record is found and TimeStamp is zero, then the end time in the matching record\r
822 is filled in with the current time stamp value.\r
823\r
824 @param Handle Pointer to environment specific context used\r
825 to identify the component being measured.\r
826 @param Token Pointer to a Null-terminated ASCII string\r
827 that identifies the component being measured.\r
828 @param Module Pointer to a Null-terminated ASCII string\r
829 that identifies the module being measured.\r
830 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
831 @param Identifier 32-bit identifier. If the value is 0, the found record\r
832 is same as the one found by EndPerformanceMeasurement.\r
d042c6e8 833\r
834 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
835 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
836\r
837**/\r
838RETURN_STATUS\r
839EFIAPI\r
f0da4d7d 840EndPerformanceMeasurementEx (\r
d042c6e8 841 IN CONST VOID *Handle, OPTIONAL\r
842 IN CONST CHAR8 *Token, OPTIONAL\r
843 IN CONST CHAR8 *Module, OPTIONAL\r
f0da4d7d
SZ
844 IN UINT64 TimeStamp,\r
845 IN UINT32 Identifier\r
d042c6e8 846 )\r
847{\r
f0da4d7d 848 return (RETURN_STATUS) EndGaugeEx (Handle, Token, Module, TimeStamp, Identifier);\r
d042c6e8 849}\r
850\r
851/**\r
852 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
f0da4d7d
SZ
853 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
854 and then assign the Identifier with 0.\r
d042c6e8 855\r
856 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
857 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
858 and the key for the second entry in the log is returned. If the performance log is empty,\r
859 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
860 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
861 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
862 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
863 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
864 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
f0da4d7d 865 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
d042c6e8 866 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
867 If Handle is NULL, then ASSERT().\r
868 If Token is NULL, then ASSERT().\r
869 If Module is NULL, then ASSERT().\r
870 If StartTimeStamp is NULL, then ASSERT().\r
871 If EndTimeStamp is NULL, then ASSERT().\r
f0da4d7d 872 If Identifier is NULL, then ASSERT().\r
d042c6e8 873\r
874 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
875 0, then the first performance measurement log entry is retrieved.\r
876 On exit, the key of the next performance log entry.\r
877 @param Handle Pointer to environment specific context used to identify the component\r
878 being measured.\r
879 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
880 being measured.\r
881 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
882 being measured.\r
883 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
884 was started.\r
885 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
886 was ended.\r
f0da4d7d 887 @param Identifier Pointer to the 32-bit identifier that was recorded.\r
d042c6e8 888\r
889 @return The key for the next performance log entry (in general case).\r
890\r
891**/\r
892UINTN\r
893EFIAPI\r
f0da4d7d
SZ
894GetPerformanceMeasurementEx (\r
895 IN UINTN LogEntryKey, \r
d042c6e8 896 OUT CONST VOID **Handle,\r
897 OUT CONST CHAR8 **Token,\r
898 OUT CONST CHAR8 **Module,\r
899 OUT UINT64 *StartTimeStamp,\r
f0da4d7d
SZ
900 OUT UINT64 *EndTimeStamp,\r
901 OUT UINT32 *Identifier\r
d042c6e8 902 )\r
903{\r
f0da4d7d
SZ
904 EFI_STATUS Status;\r
905 GAUGE_DATA_ENTRY_EX *GaugeData;\r
d042c6e8 906\r
907 GaugeData = NULL;\r
908 \r
909 ASSERT (Handle != NULL);\r
910 ASSERT (Token != NULL);\r
911 ASSERT (Module != NULL);\r
912 ASSERT (StartTimeStamp != NULL);\r
913 ASSERT (EndTimeStamp != NULL);\r
f0da4d7d 914 ASSERT (Identifier != NULL);\r
d042c6e8 915\r
f0da4d7d 916 Status = GetGaugeEx (LogEntryKey++, &GaugeData);\r
d042c6e8 917\r
918 //\r
919 // Make sure that LogEntryKey is a valid log entry key,\r
920 //\r
921 ASSERT (Status != EFI_INVALID_PARAMETER);\r
922\r
923 if (EFI_ERROR (Status)) {\r
924 //\r
925 // The LogEntryKey is the last entry (equals to the total entry number).\r
926 //\r
927 return 0;\r
928 }\r
929\r
930 ASSERT (GaugeData != NULL);\r
931\r
932 *Handle = (VOID *) (UINTN) GaugeData->Handle;\r
933 *Token = GaugeData->Token;\r
934 *Module = GaugeData->Module;\r
935 *StartTimeStamp = GaugeData->StartTimeStamp;\r
936 *EndTimeStamp = GaugeData->EndTimeStamp;\r
f0da4d7d 937 *Identifier = GaugeData->Identifier;\r
d042c6e8 938\r
939 return LogEntryKey;\r
940}\r
941\r
f0da4d7d
SZ
942/**\r
943 Adds a record at the end of the performance measurement log\r
944 that records the start time of a performance measurement.\r
945\r
946 Adds a record to the end of the performance measurement log\r
947 that contains the Handle, Token, and Module.\r
948 The end time of the new record must be set to zero.\r
949 If TimeStamp is not zero, then TimeStamp is used to fill in the start time in the record.\r
950 If TimeStamp is zero, the start time in the record is filled in with the value\r
951 read from the current time stamp.\r
952\r
953 @param Handle Pointer to environment specific context used\r
954 to identify the component being measured.\r
955 @param Token Pointer to a Null-terminated ASCII string\r
956 that identifies the component being measured.\r
957 @param Module Pointer to a Null-terminated ASCII string\r
958 that identifies the module being measured.\r
959 @param TimeStamp 64-bit time stamp.\r
960\r
961 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
962 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
963\r
964**/\r
965RETURN_STATUS\r
966EFIAPI\r
967StartPerformanceMeasurement (\r
968 IN CONST VOID *Handle, OPTIONAL\r
969 IN CONST CHAR8 *Token, OPTIONAL\r
970 IN CONST CHAR8 *Module, OPTIONAL\r
971 IN UINT64 TimeStamp\r
972 )\r
973{\r
974 return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
975}\r
976\r
977/**\r
978 Searches the performance measurement log from the beginning of the log\r
979 for the first matching record that contains a zero end time and fills in a valid end time.\r
980\r
981 Searches the performance measurement log from the beginning of the log\r
982 for the first record that matches Handle, Token, and Module and has an end time value of zero.\r
983 If the record can not be found then return RETURN_NOT_FOUND.\r
984 If the record is found and TimeStamp is not zero,\r
985 then the end time in the record is filled in with the value specified by TimeStamp.\r
986 If the record is found and TimeStamp is zero, then the end time in the matching record\r
987 is filled in with the current time stamp value.\r
988\r
989 @param Handle Pointer to environment specific context used\r
990 to identify the component being measured.\r
991 @param Token Pointer to a Null-terminated ASCII string\r
992 that identifies the component being measured.\r
993 @param Module Pointer to a Null-terminated ASCII string\r
994 that identifies the module being measured.\r
995 @param TimeStamp 64-bit time stamp.\r
996\r
997 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
998 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
999\r
1000**/\r
1001RETURN_STATUS\r
1002EFIAPI\r
1003EndPerformanceMeasurement (\r
1004 IN CONST VOID *Handle, OPTIONAL\r
1005 IN CONST CHAR8 *Token, OPTIONAL\r
1006 IN CONST CHAR8 *Module, OPTIONAL\r
1007 IN UINT64 TimeStamp\r
1008 )\r
1009{\r
1010 return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
1011}\r
1012\r
1013/**\r
1014 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
1015 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
1016 and then eliminate the Identifier.\r
1017\r
1018 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
1019 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
1020 and the key for the second entry in the log is returned. If the performance log is empty,\r
1021 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
1022 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
1023 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
1024 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
1025 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
1026 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
1027 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
1028 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
1029 If Handle is NULL, then ASSERT().\r
1030 If Token is NULL, then ASSERT().\r
1031 If Module is NULL, then ASSERT().\r
1032 If StartTimeStamp is NULL, then ASSERT().\r
1033 If EndTimeStamp is NULL, then ASSERT().\r
1034\r
1035 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
1036 0, then the first performance measurement log entry is retrieved.\r
1037 On exit, the key of the next performance log entry.\r
1038 @param Handle Pointer to environment specific context used to identify the component\r
1039 being measured.\r
1040 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
1041 being measured.\r
1042 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
1043 being measured.\r
1044 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
1045 was started.\r
1046 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
1047 was ended.\r
1048\r
1049 @return The key for the next performance log entry (in general case).\r
1050\r
1051**/\r
1052UINTN\r
1053EFIAPI\r
1054GetPerformanceMeasurement (\r
1055 IN UINTN LogEntryKey,\r
1056 OUT CONST VOID **Handle,\r
1057 OUT CONST CHAR8 **Token,\r
1058 OUT CONST CHAR8 **Module,\r
1059 OUT UINT64 *StartTimeStamp,\r
1060 OUT UINT64 *EndTimeStamp\r
1061 )\r
1062{\r
1063 UINT32 Identifier;\r
1064 return GetPerformanceMeasurementEx (LogEntryKey, Handle, Token, Module, StartTimeStamp, EndTimeStamp, &Identifier);\r
1065}\r
1066\r
d042c6e8 1067/**\r
1068 Returns TRUE if the performance measurement macros are enabled.\r
1069\r
1070 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
1071 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.\r
1072\r
1073 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
1074 PcdPerformanceLibraryPropertyMask is set.\r
1075 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
1076 PcdPerformanceLibraryPropertyMask is clear.\r
1077\r
1078**/\r
1079BOOLEAN\r
1080EFIAPI\r
1081PerformanceMeasurementEnabled (\r
1082 VOID\r
1083 )\r
1084{\r
1085 return mPerformanceMeasurementEnabled;\r
1086}\r