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