]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / DxePerformanceLib / DxePerformanceLib.c
CommitLineData
8dbae30d 1/** @file\r
2 Performance Library\r
a0afd019 3\r
857dfc45 4 This library instance provides infrastructure for DXE phase drivers to log performance\r
f0da4d7d
SZ
5 data. It consumes PerformanceEx or Performance Protocol published by DxeCorePerformanceLib\r
6 to log performance data. If both PerformanceEx and Performance Protocol is not available, it does not log any\r
857dfc45 7 performance information.\r
8\r
d1102dba 9 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 10SPDX-License-Identifier: BSD-2-Clause-Patent\r
a0afd019 11\r
8dbae30d 12**/\r
a0afd019 13\r
a0afd019 14#include <PiDxe.h>\r
ed7748fe 15\r
137fb13d 16#include <Guid/PerformanceMeasurement.h>\r
ed7748fe 17\r
a0afd019 18#include <Library/PerformanceLib.h>\r
19#include <Library/DebugLib.h>\r
20#include <Library/UefiBootServicesTableLib.h>\r
21#include <Library/PcdLib.h>\r
22\r
857dfc45 23//\r
f0da4d7d 24// The cached Performance Protocol and PerformanceEx Protocol interface.\r
857dfc45 25//\r
1436aea4 26EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL *mPerformanceMeasurement = NULL;\r
a0afd019 27\r
28/**\r
f0da4d7d 29 The function caches the pointers to PerformanceEx protocol and Performance Protocol.\r
a0afd019 30\r
f0da4d7d 31 The function locates PerformanceEx protocol and Performance Protocol from protocol database.\r
a0afd019 32\r
f0da4d7d
SZ
33 @retval EFI_SUCCESS PerformanceEx protocol or Performance Protocol is successfully located.\r
34 @retval EFI_NOT_FOUND Both PerformanceEx protocol and Performance Protocol are not located to log performance.\r
a0afd019 35\r
36**/\r
a0afd019 37EFI_STATUS\r
137fb13d 38GetPerformanceMeasurementProtocol (\r
a0afd019 39 VOID\r
40 )\r
41{\r
1436aea4
MK
42 EFI_STATUS Status;\r
43 EDKII_PERFORMANCE_MEASUREMENT_PROTOCOL *PerformanceMeasurement;\r
a0afd019 44\r
137fb13d 45 if (mPerformanceMeasurement != NULL) {\r
f0da4d7d
SZ
46 return EFI_SUCCESS;\r
47 }\r
48\r
1436aea4 49 Status = gBS->LocateProtocol (&gEdkiiPerformanceMeasurementProtocolGuid, NULL, (VOID **)&PerformanceMeasurement);\r
f0da4d7d 50 if (!EFI_ERROR (Status)) {\r
137fb13d 51 ASSERT (PerformanceMeasurement != NULL);\r
f0da4d7d 52 //\r
137fb13d 53 // Cache PerformanceMeasurement Protocol.\r
f0da4d7d 54 //\r
137fb13d 55 mPerformanceMeasurement = PerformanceMeasurement;\r
f0da4d7d 56 return EFI_SUCCESS;\r
a0afd019 57 }\r
58\r
f0da4d7d 59 return EFI_NOT_FOUND;\r
a0afd019 60}\r
61\r
62/**\r
63 Creates a record for the beginning of a performance measurement.\r
64\r
f0da4d7d 65 Creates a record that contains the Handle, Token, Module and Identifier.\r
a0afd019 66 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
67 If TimeStamp is zero, then this function reads the current time stamp\r
68 and adds that time stamp value to the record as the start time.\r
69\r
70 @param Handle Pointer to environment specific context used\r
71 to identify the component being measured.\r
72 @param Token Pointer to a Null-terminated ASCII string\r
73 that identifies the component being measured.\r
74 @param Module Pointer to a Null-terminated ASCII string\r
75 that identifies the module being measured.\r
76 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
77 @param Identifier 32-bit identifier. If the value is 0, the created record\r
78 is same as the one created by StartPerformanceMeasurement.\r
a0afd019 79\r
80 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
81 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
82\r
83**/\r
84RETURN_STATUS\r
85EFIAPI\r
f0da4d7d 86StartPerformanceMeasurementEx (\r
e3917e22
MK
87 IN CONST VOID *Handle OPTIONAL,\r
88 IN CONST CHAR8 *Token OPTIONAL,\r
89 IN CONST CHAR8 *Module OPTIONAL,\r
f0da4d7d
SZ
90 IN UINT64 TimeStamp,\r
91 IN UINT32 Identifier\r
a0afd019 92 )\r
93{\r
1436aea4
MK
94 EFI_STATUS Status;\r
95 CONST CHAR8 *String;\r
a0afd019 96\r
137fb13d 97 Status = GetPerformanceMeasurementProtocol ();\r
a0afd019 98 if (EFI_ERROR (Status)) {\r
137fb13d
BD
99 return RETURN_NOT_FOUND;\r
100 }\r
101\r
102 if (Token != NULL) {\r
103 String = Token;\r
104 } else if (Module != NULL) {\r
105 String = Module;\r
106 } else {\r
107 String = NULL;\r
a0afd019 108 }\r
109\r
137fb13d
BD
110 if (mPerformanceMeasurement != NULL) {\r
111 Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfStartEntry);\r
f0da4d7d
SZ
112 } else {\r
113 ASSERT (FALSE);\r
114 }\r
a0afd019 115\r
1436aea4 116 return (RETURN_STATUS)Status;\r
a0afd019 117}\r
118\r
119/**\r
120 Fills in the end time of a performance measurement.\r
121\r
7a9395cd 122 Looks up the record that matches Handle, Token and Module.\r
a0afd019 123 If the record can not be found then return RETURN_NOT_FOUND.\r
124 If the record is found and TimeStamp is not zero,\r
125 then TimeStamp is added to the record as the end time.\r
126 If the record is found and TimeStamp is zero, then this function reads\r
127 the current time stamp and adds that time stamp value to the record as the end time.\r
a0afd019 128\r
129 @param Handle Pointer to environment specific context used\r
130 to identify the component being measured.\r
131 @param Token Pointer to a Null-terminated ASCII string\r
132 that identifies the component being measured.\r
133 @param Module Pointer to a Null-terminated ASCII string\r
134 that identifies the module being measured.\r
135 @param TimeStamp 64-bit time stamp.\r
f0da4d7d
SZ
136 @param Identifier 32-bit identifier. If the value is 0, the found record\r
137 is same as the one found by EndPerformanceMeasurement.\r
a0afd019 138\r
139 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
140 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
141\r
142**/\r
143RETURN_STATUS\r
144EFIAPI\r
f0da4d7d 145EndPerformanceMeasurementEx (\r
e3917e22
MK
146 IN CONST VOID *Handle OPTIONAL,\r
147 IN CONST CHAR8 *Token OPTIONAL,\r
148 IN CONST CHAR8 *Module OPTIONAL,\r
f0da4d7d
SZ
149 IN UINT64 TimeStamp,\r
150 IN UINT32 Identifier\r
a0afd019 151 )\r
152{\r
1436aea4
MK
153 EFI_STATUS Status;\r
154 CONST CHAR8 *String;\r
a0afd019 155\r
137fb13d 156 Status = GetPerformanceMeasurementProtocol ();\r
a0afd019 157 if (EFI_ERROR (Status)) {\r
158 return RETURN_NOT_FOUND;\r
159 }\r
160\r
137fb13d
BD
161 if (Token != NULL) {\r
162 String = Token;\r
163 } else if (Module != NULL) {\r
164 String = Module;\r
165 } else {\r
166 String = NULL;\r
167 }\r
168\r
169 if (mPerformanceMeasurement != NULL) {\r
170 Status = mPerformanceMeasurement->CreatePerformanceMeasurement (Handle, NULL, String, TimeStamp, 0, Identifier, PerfEndEntry);\r
f0da4d7d
SZ
171 } else {\r
172 ASSERT (FALSE);\r
173 }\r
a0afd019 174\r
1436aea4 175 return (RETURN_STATUS)Status;\r
a0afd019 176}\r
177\r
178/**\r
179 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
f0da4d7d
SZ
180 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,\r
181 and then assign the Identifier with 0.\r
a0afd019 182\r
183 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
184 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
185 and the key for the second entry in the log is returned. If the performance log is empty,\r
186 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
187 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
188 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
189 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
190 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
191 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
f0da4d7d 192 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.\r
a0afd019 193 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
194 If Handle is NULL, then ASSERT().\r
195 If Token is NULL, then ASSERT().\r
196 If Module is NULL, then ASSERT().\r
197 If StartTimeStamp is NULL, then ASSERT().\r
198 If EndTimeStamp is NULL, then ASSERT().\r
f0da4d7d 199 If Identifier is NULL, then ASSERT().\r
a0afd019 200\r
201 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
202 0, then the first performance measurement log entry is retrieved.\r
857dfc45 203 On exit, the key of the next performance log entry.\r
a0afd019 204 @param Handle Pointer to environment specific context used to identify the component\r
205 being measured.\r
206 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
207 being measured.\r
208 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
209 being measured.\r
210 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
211 was started.\r
212 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
213 was ended.\r
f0da4d7d 214 @param Identifier Pointer to the 32-bit identifier that was recorded.\r
a0afd019 215\r
216 @return The key for the next performance log entry (in general case).\r
217\r
218**/\r
219UINTN\r
220EFIAPI\r
f0da4d7d 221GetPerformanceMeasurementEx (\r
1436aea4
MK
222 IN UINTN LogEntryKey,\r
223 OUT CONST VOID **Handle,\r
224 OUT CONST CHAR8 **Token,\r
225 OUT CONST CHAR8 **Module,\r
226 OUT UINT64 *StartTimeStamp,\r
227 OUT UINT64 *EndTimeStamp,\r
228 OUT UINT32 *Identifier\r
a0afd019 229 )\r
230{\r
137fb13d 231 return 0;\r
a0afd019 232}\r
233\r
f0da4d7d
SZ
234/**\r
235 Creates a record for the beginning of a performance measurement.\r
236\r
237 Creates a record that contains the Handle, Token, and Module.\r
238 If TimeStamp is not zero, then TimeStamp is added to the record as the start time.\r
239 If TimeStamp is zero, then this function reads the current time stamp\r
240 and adds that time stamp value to the record as the start time.\r
241\r
242 @param Handle Pointer to environment specific context used\r
243 to identify the component being measured.\r
244 @param Token Pointer to a Null-terminated ASCII string\r
245 that identifies the component being measured.\r
246 @param Module Pointer to a Null-terminated ASCII string\r
247 that identifies the module being measured.\r
248 @param TimeStamp 64-bit time stamp.\r
249\r
250 @retval RETURN_SUCCESS The start of the measurement was recorded.\r
251 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.\r
252\r
253**/\r
254RETURN_STATUS\r
255EFIAPI\r
256StartPerformanceMeasurement (\r
e3917e22
MK
257 IN CONST VOID *Handle OPTIONAL,\r
258 IN CONST CHAR8 *Token OPTIONAL,\r
259 IN CONST CHAR8 *Module OPTIONAL,\r
f0da4d7d
SZ
260 IN UINT64 TimeStamp\r
261 )\r
262{\r
263 return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
264}\r
265\r
266/**\r
267 Fills in the end time of a performance measurement.\r
268\r
269 Looks up the record that matches Handle, Token, and Module.\r
270 If the record can not be found then return RETURN_NOT_FOUND.\r
271 If the record is found and TimeStamp is not zero,\r
272 then TimeStamp is added to the record as the end time.\r
273 If the record is found and TimeStamp is zero, then this function reads\r
274 the current time stamp and adds that time stamp value to the record as the end time.\r
275\r
276 @param Handle Pointer to environment specific context used\r
277 to identify the component being measured.\r
278 @param Token Pointer to a Null-terminated ASCII string\r
279 that identifies the component being measured.\r
280 @param Module Pointer to a Null-terminated ASCII string\r
281 that identifies the module being measured.\r
282 @param TimeStamp 64-bit time stamp.\r
283\r
284 @retval RETURN_SUCCESS The end of the measurement was recorded.\r
285 @retval RETURN_NOT_FOUND The specified measurement record could not be found.\r
286\r
287**/\r
288RETURN_STATUS\r
289EFIAPI\r
290EndPerformanceMeasurement (\r
e3917e22
MK
291 IN CONST VOID *Handle OPTIONAL,\r
292 IN CONST CHAR8 *Token OPTIONAL,\r
293 IN CONST CHAR8 *Module OPTIONAL,\r
f0da4d7d
SZ
294 IN UINT64 TimeStamp\r
295 )\r
296{\r
297 return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);\r
298}\r
299\r
300/**\r
301 Attempts to retrieve a performance measurement log entry from the performance measurement log.\r
302 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,\r
303 and then eliminate the Identifier.\r
304\r
305 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is\r
306 zero on entry, then an attempt is made to retrieve the first entry from the performance log,\r
307 and the key for the second entry in the log is returned. If the performance log is empty,\r
308 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance\r
309 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is\r
310 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is\r
311 retrieved and an implementation specific non-zero key value that specifies the end of the performance\r
312 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry\r
313 is retrieved and zero is returned. In the cases where a performance log entry can be returned,\r
314 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.\r
315 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().\r
316 If Handle is NULL, then ASSERT().\r
317 If Token is NULL, then ASSERT().\r
318 If Module is NULL, then ASSERT().\r
319 If StartTimeStamp is NULL, then ASSERT().\r
320 If EndTimeStamp is NULL, then ASSERT().\r
321\r
322 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.\r
323 0, then the first performance measurement log entry is retrieved.\r
324 On exit, the key of the next performance log entry.\r
325 @param Handle Pointer to environment specific context used to identify the component\r
326 being measured.\r
327 @param Token Pointer to a Null-terminated ASCII string that identifies the component\r
328 being measured.\r
329 @param Module Pointer to a Null-terminated ASCII string that identifies the module\r
330 being measured.\r
331 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
332 was started.\r
333 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement\r
334 was ended.\r
335\r
336 @return The key for the next performance log entry (in general case).\r
337\r
338**/\r
339UINTN\r
340EFIAPI\r
341GetPerformanceMeasurement (\r
1436aea4
MK
342 IN UINTN LogEntryKey,\r
343 OUT CONST VOID **Handle,\r
344 OUT CONST CHAR8 **Token,\r
345 OUT CONST CHAR8 **Module,\r
346 OUT UINT64 *StartTimeStamp,\r
347 OUT UINT64 *EndTimeStamp\r
f0da4d7d
SZ
348 )\r
349{\r
137fb13d 350 return 0;\r
f0da4d7d
SZ
351}\r
352\r
a0afd019 353/**\r
354 Returns TRUE if the performance measurement macros are enabled.\r
355\r
356 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
357 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.\r
358\r
359 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
360 PcdPerformanceLibraryPropertyMask is set.\r
361 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of\r
362 PcdPerformanceLibraryPropertyMask is clear.\r
363\r
364**/\r
365BOOLEAN\r
366EFIAPI\r
367PerformanceMeasurementEnabled (\r
368 VOID\r
369 )\r
370{\r
1436aea4 371 return (BOOLEAN)((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);\r
a0afd019 372}\r
6b4d58a1
BD
373\r
374/**\r
375 Create performance record with event description and a timestamp.\r
376\r
377 @param CallerIdentifier - Image handle or pointer to caller ID GUID\r
378 @param Guid - Pointer to a GUID\r
379 @param String - Pointer to a string describing the measurement\r
380 @param Address - Pointer to a location in memory relevant to the measurement\r
381 @param Identifier - Performance identifier describing the type of measurement\r
382\r
383 @retval RETURN_SUCCESS - Successfully created performance record\r
384 @retval RETURN_OUT_OF_RESOURCES - Ran out of space to store the records\r
385 @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL\r
386 pointer or invalid PerfId\r
387\r
388**/\r
389RETURN_STATUS\r
390EFIAPI\r
391LogPerformanceMeasurement (\r
392 IN CONST VOID *CallerIdentifier,\r
e3917e22
MK
393 IN CONST VOID *Guid OPTIONAL,\r
394 IN CONST CHAR8 *String OPTIONAL,\r
1436aea4 395 IN UINT64 Address OPTIONAL,\r
6b4d58a1
BD
396 IN UINT32 Identifier\r
397 )\r
398{\r
399 EFI_STATUS Status;\r
400\r
401 Status = GetPerformanceMeasurementProtocol ();\r
402 if (EFI_ERROR (Status)) {\r
403 return RETURN_OUT_OF_RESOURCES;\r
404 }\r
405\r
406 if (mPerformanceMeasurement != NULL) {\r
407 Status = mPerformanceMeasurement->CreatePerformanceMeasurement (CallerIdentifier, Guid, String, 0, Address, Identifier, PerfEntry);\r
408 } else {\r
409 ASSERT (FALSE);\r
410 }\r
411\r
1436aea4 412 return (RETURN_STATUS)Status;\r
6b4d58a1
BD
413}\r
414\r
415/**\r
416 Check whether the specified performance measurement can be logged.\r
417\r
418 This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set\r
419 and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.\r
420\r
421 @param Type - Type of the performance measurement entry.\r
422\r
423 @retval TRUE The performance measurement can be logged.\r
424 @retval FALSE The performance measurement can NOT be logged.\r
425\r
426**/\r
427BOOLEAN\r
428EFIAPI\r
429LogPerformanceMeasurementEnabled (\r
1436aea4 430 IN CONST UINTN Type\r
6b4d58a1
BD
431 )\r
432{\r
433 //\r
434 // When Performance measurement is enabled and the type is not filtered, the performance can be logged.\r
435 //\r
1436aea4 436 if (PerformanceMeasurementEnabled () && ((PcdGet8 (PcdPerformanceLibraryPropertyMask) & Type) == 0)) {\r
6b4d58a1
BD
437 return TRUE;\r
438 }\r
1436aea4 439\r
6b4d58a1
BD
440 return FALSE;\r
441}\r