]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / PeiPerformanceLib / PeiPerformanceLib.c
1 /** @file
2 Performance library instance used in PEI phase.
3
4 This file implements all APIs in Performance Library class in MdePkg. It creates
5 performance logging GUIDed HOB on the first performance logging and then logs the
6 performance data to the GUIDed HOB. Due to the limitation of temporary RAM, the maximum
7 number of performance logging entry is specified by PcdMaxPeiPerformanceLogEntries or
8 PcdMaxPeiPerformanceLogEntries16.
9
10 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
11 (C) Copyright 2015-2016 Hewlett Packard Enterprise Development LP<BR>
12 SPDX-License-Identifier: BSD-2-Clause-Patent
13
14 **/
15
16 #include <PiPei.h>
17
18 #include <Guid/ExtendedFirmwarePerformance.h>
19 #include <Guid/PerformanceMeasurement.h>
20
21 #include <Library/PerformanceLib.h>
22 #include <Library/DebugLib.h>
23 #include <Library/HobLib.h>
24 #include <Library/BaseLib.h>
25 #include <Library/TimerLib.h>
26 #include <Library/PcdLib.h>
27 #include <Library/BaseMemoryLib.h>
28
29 #define STRING_SIZE (FPDT_STRING_EVENT_RECORD_NAME_LENGTH * sizeof (CHAR8))
30 #define PEI_MAX_RECORD_SIZE (sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD) + STRING_SIZE)
31
32 /**
33 Return the pointer to the FPDT record in the allocated memory.
34
35 @param RecordSize The size of FPDT record.
36 @param FpdtRecordPtr Pointer the FPDT record in the allocated memory.
37 @param PeiPerformanceLogHeader Pointer to the header of the PEI Performance records in the GUID Hob.
38
39 @retval EFI_SUCCESS Successfully get the pointer to the FPDT record.
40 @retval EFI_OUT_OF_RESOURCES Ran out of space to store the records.
41 **/
42 EFI_STATUS
43 GetFpdtRecordPtr (
44 IN UINT8 RecordSize,
45 IN OUT FPDT_RECORD_PTR *FpdtRecordPtr,
46 IN OUT FPDT_PEI_EXT_PERF_HEADER **PeiPerformanceLogHeader
47 )
48 {
49 UINT16 PeiPerformanceLogEntries;
50 UINTN PeiPerformanceSize;
51 UINT8 *PeiFirmwarePerformance;
52 EFI_HOB_GUID_TYPE *GuidHob;
53
54 //
55 // Get the number of PeiPerformanceLogEntries form PCD.
56 //
57 PeiPerformanceLogEntries = (UINT16)(PcdGet16 (PcdMaxPeiPerformanceLogEntries16) != 0 ?
58 PcdGet16 (PcdMaxPeiPerformanceLogEntries16) :
59 PcdGet8 (PcdMaxPeiPerformanceLogEntries));
60
61 //
62 // Create GUID HOB Data.
63 //
64 GuidHob = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);
65 PeiFirmwarePerformance = NULL;
66 while (GuidHob != NULL) {
67 //
68 // PEI Performance HOB was found, then return the existing one.
69 //
70 PeiFirmwarePerformance = (UINT8 *)GET_GUID_HOB_DATA (GuidHob);
71 *PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
72 if (!(*PeiPerformanceLogHeader)->HobIsFull && ((*PeiPerformanceLogHeader)->SizeOfAllEntries + RecordSize > (PeiPerformanceLogEntries * PEI_MAX_RECORD_SIZE))) {
73 (*PeiPerformanceLogHeader)->HobIsFull = TRUE;
74 }
75
76 if (!(*PeiPerformanceLogHeader)->HobIsFull && ((*PeiPerformanceLogHeader)->SizeOfAllEntries + RecordSize <= (PeiPerformanceLogEntries * PEI_MAX_RECORD_SIZE))) {
77 FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER) + (*PeiPerformanceLogHeader)->SizeOfAllEntries);
78 break;
79 }
80
81 //
82 // Previous HOB is used, then find next one.
83 //
84 GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));
85 }
86
87 if (GuidHob == NULL) {
88 //
89 // PEI Performance HOB was not found, then build one.
90 //
91 PeiPerformanceSize = sizeof (FPDT_PEI_EXT_PERF_HEADER) +
92 PEI_MAX_RECORD_SIZE * PeiPerformanceLogEntries;
93 PeiFirmwarePerformance = (UINT8 *)BuildGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, PeiPerformanceSize);
94 if (PeiFirmwarePerformance != NULL) {
95 ZeroMem (PeiFirmwarePerformance, PeiPerformanceSize);
96 (*PeiPerformanceLogHeader) = (FPDT_PEI_EXT_PERF_HEADER *)PeiFirmwarePerformance;
97 FpdtRecordPtr->RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)(PeiFirmwarePerformance + sizeof (FPDT_PEI_EXT_PERF_HEADER));
98 }
99 }
100
101 if (PeiFirmwarePerformance == NULL) {
102 //
103 // there is no enough resource to store performance data
104 //
105 return EFI_OUT_OF_RESOURCES;
106 }
107
108 return EFI_SUCCESS;
109 }
110
111 /**
112 Check whether the Token is a known one which is uesed by core.
113
114 @param Token Pointer to a Null-terminated ASCII string
115
116 @retval TRUE Is a known one used by core.
117 @retval FALSE Not a known one.
118
119 **/
120 BOOLEAN
121 IsKnownTokens (
122 IN CONST CHAR8 *Token
123 )
124 {
125 if (Token == NULL) {
126 return FALSE;
127 }
128
129 if ((AsciiStrCmp (Token, SEC_TOK) == 0) ||
130 (AsciiStrCmp (Token, PEI_TOK) == 0) ||
131 (AsciiStrCmp (Token, DXE_TOK) == 0) ||
132 (AsciiStrCmp (Token, BDS_TOK) == 0) ||
133 (AsciiStrCmp (Token, DRIVERBINDING_START_TOK) == 0) ||
134 (AsciiStrCmp (Token, DRIVERBINDING_SUPPORT_TOK) == 0) ||
135 (AsciiStrCmp (Token, DRIVERBINDING_STOP_TOK) == 0) ||
136 (AsciiStrCmp (Token, LOAD_IMAGE_TOK) == 0) ||
137 (AsciiStrCmp (Token, START_IMAGE_TOK) == 0) ||
138 (AsciiStrCmp (Token, PEIM_TOK) == 0))
139 {
140 return TRUE;
141 } else {
142 return FALSE;
143 }
144 }
145
146 /**
147 Check whether the ID is a known one which map to the known Token.
148
149 @param Identifier 32-bit identifier.
150
151 @retval TRUE Is a known one used by core.
152 @retval FALSE Not a known one.
153
154 **/
155 BOOLEAN
156 IsKnownID (
157 IN UINT32 Identifier
158 )
159 {
160 if ((Identifier == MODULE_START_ID) ||
161 (Identifier == MODULE_END_ID) ||
162 (Identifier == MODULE_LOADIMAGE_START_ID) ||
163 (Identifier == MODULE_LOADIMAGE_END_ID) ||
164 (Identifier == MODULE_DB_START_ID) ||
165 (Identifier == MODULE_DB_END_ID) ||
166 (Identifier == MODULE_DB_SUPPORT_START_ID) ||
167 (Identifier == MODULE_DB_SUPPORT_END_ID) ||
168 (Identifier == MODULE_DB_STOP_START_ID) ||
169 (Identifier == MODULE_DB_STOP_END_ID))
170 {
171 return TRUE;
172 } else {
173 return FALSE;
174 }
175 }
176
177 /**
178 Get the FPDT record identifier.
179
180 @param Attribute The attribute of the Record.
181 PerfStartEntry: Start Record.
182 PerfEndEntry: End Record.
183 @param Handle Pointer to environment specific context used to identify the component being measured.
184 @param String Pointer to a Null-terminated ASCII string that identifies the component being measured.
185 @param ProgressID On return, pointer to the ProgressID.
186
187 @retval EFI_SUCCESS Get record info successfully.
188 @retval EFI_INVALID_PARAMETER No matched FPDT record.
189
190 **/
191 EFI_STATUS
192 GetFpdtRecordId (
193 IN BOOLEAN Attribute,
194 IN CONST VOID *Handle,
195 IN CONST CHAR8 *String,
196 OUT UINT16 *ProgressID
197 )
198 {
199 //
200 // Get the ProgressID based on the Token.
201 // When PcdEdkiiFpdtStringRecordEnableOnly is TRUE, all records are with type of FPDT_DYNAMIC_STRING_EVENT_TYPE.
202 //
203 if (String != NULL) {
204 if (AsciiStrCmp (String, LOAD_IMAGE_TOK) == 0) {
205 // "LoadImage:"
206 if (Attribute == PerfStartEntry) {
207 *ProgressID = MODULE_LOADIMAGE_START_ID;
208 } else {
209 *ProgressID = MODULE_LOADIMAGE_END_ID;
210 }
211 } else if ((AsciiStrCmp (String, SEC_TOK) == 0) || // "SEC"
212 (AsciiStrCmp (String, PEI_TOK) == 0)) // "PEI"
213 {
214 if (Attribute == PerfStartEntry) {
215 *ProgressID = PERF_CROSSMODULE_START_ID;
216 } else {
217 *ProgressID = PERF_CROSSMODULE_END_ID;
218 }
219 } else if (AsciiStrCmp (String, PEIM_TOK) == 0) {
220 // "PEIM"
221 if (Attribute == PerfStartEntry) {
222 *ProgressID = MODULE_START_ID;
223 } else {
224 *ProgressID = MODULE_END_ID;
225 }
226 } else {
227 // Pref used in Modules.
228 if (Attribute == PerfStartEntry) {
229 *ProgressID = PERF_INMODULE_START_ID;
230 } else {
231 *ProgressID = PERF_INMODULE_END_ID;
232 }
233 }
234 } else if (Handle != NULL) {
235 // Pref used in Modules.
236 if (Attribute == PerfStartEntry) {
237 *ProgressID = PERF_INMODULE_START_ID;
238 } else {
239 *ProgressID = PERF_INMODULE_END_ID;
240 }
241 } else {
242 return EFI_INVALID_PARAMETER;
243 }
244
245 return EFI_SUCCESS;
246 }
247
248 /**
249 Copies the string from Source into Destination and updates Length with the
250 size of the string.
251
252 @param Destination - destination of the string copy
253 @param Source - pointer to the source string which will get copied
254 @param Length - pointer to a length variable to be updated
255
256 **/
257 VOID
258 CopyStringIntoPerfRecordAndUpdateLength (
259 IN OUT CHAR8 *Destination,
260 IN CONST CHAR8 *Source,
261 IN OUT UINT8 *Length
262 )
263 {
264 UINTN StringLen;
265 UINTN DestMax;
266
267 ASSERT (Source != NULL);
268
269 if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
270 DestMax = STRING_SIZE;
271 } else {
272 DestMax = AsciiStrSize (Source);
273 if (DestMax > STRING_SIZE) {
274 DestMax = STRING_SIZE;
275 }
276 }
277
278 StringLen = AsciiStrLen (Source);
279 if (StringLen >= DestMax) {
280 StringLen = DestMax -1;
281 }
282
283 AsciiStrnCpyS (Destination, DestMax, Source, StringLen);
284 *Length += (UINT8)DestMax;
285
286 return;
287 }
288
289 /**
290 Convert PEI performance log to FPDT String boot record.
291
292 @param CallerIdentifier - Image handle or pointer to caller ID GUID.
293 @param Guid - Pointer to a GUID.
294 @param String - Pointer to a string describing the measurement.
295 @param Ticker - 64-bit time stamp.
296 @param Address - Pointer to a location in memory relevant to the measurement.
297 @param PerfId - Performance identifier describing the type of measurement.
298 @param Attribute - The attribute of the measurement. According to attribute can create a start
299 record for PERF_START/PERF_START_EX, or a end record for PERF_END/PERF_END_EX,
300 or a general record for other Perf macros.
301
302 @retval EFI_SUCCESS - Successfully created performance record.
303 @retval EFI_OUT_OF_RESOURCES - Ran out of space to store the records.
304 @retval EFI_INVALID_PARAMETER - Invalid parameter passed to function - NULL
305 pointer or invalid PerfId.
306
307 **/
308 EFI_STATUS
309 InsertFpdtRecord (
310 IN CONST VOID *CallerIdentifier OPTIONAL,
311 IN CONST VOID *Guid OPTIONAL,
312 IN CONST CHAR8 *String OPTIONAL,
313 IN UINT64 Ticker,
314 IN UINT64 Address OPTIONAL,
315 IN UINT16 PerfId,
316 IN PERF_MEASUREMENT_ATTRIBUTE Attribute
317 )
318 {
319 FPDT_RECORD_PTR FpdtRecordPtr;
320 CONST VOID *ModuleGuid;
321 CONST CHAR8 *StringPtr;
322 EFI_STATUS Status;
323 UINT64 TimeStamp;
324 FPDT_PEI_EXT_PERF_HEADER *PeiPerformanceLogHeader;
325
326 StringPtr = NULL;
327 FpdtRecordPtr.RecordHeader = NULL;
328 PeiPerformanceLogHeader = NULL;
329
330 //
331 // 1. Get the Perf Id for records from PERF_START/PERF_END, PERF_START_EX/PERF_END_EX.
332 // notes: For other Perf macros (Attribute == PerfEntry), their Id is known.
333 //
334 if (Attribute != PerfEntry) {
335 //
336 // If PERF_START_EX()/PERF_END_EX() have specified the ProgressID,it has high priority.
337 // !!! Note: If the Perf is not the known Token used in the core but have same
338 // ID with the core Token, this case will not be supported.
339 // And in currtnt usage mode, for the unkown ID, there is a general rule:
340 // If it is start pref: the lower 4 bits of the ID should be 0.
341 // If it is end pref: the lower 4 bits of the ID should not be 0.
342 // If input ID doesn't follow the rule, we will adjust it.
343 //
344 if ((PerfId != 0) && (IsKnownID (PerfId)) && (!IsKnownTokens (String))) {
345 return EFI_UNSUPPORTED;
346 } else if ((PerfId != 0) && (!IsKnownID (PerfId)) && (!IsKnownTokens (String))) {
347 if ((Attribute == PerfStartEntry) && ((PerfId & 0x000F) != 0)) {
348 PerfId &= 0xFFF0;
349 } else if ((Attribute == PerfEndEntry) && ((PerfId & 0x000F) == 0)) {
350 PerfId += 1;
351 }
352 } else if (PerfId == 0) {
353 Status = GetFpdtRecordId (Attribute, CallerIdentifier, String, &PerfId);
354 if (EFI_ERROR (Status)) {
355 return Status;
356 }
357 }
358 }
359
360 //
361 // 2. Get the buffer to store the FPDT record.
362 //
363 Status = GetFpdtRecordPtr (PEI_MAX_RECORD_SIZE, &FpdtRecordPtr, &PeiPerformanceLogHeader);
364 if (EFI_ERROR (Status)) {
365 return Status;
366 }
367
368 //
369 // 3 Get the TimeStamp.
370 //
371 if (Ticker == 0) {
372 Ticker = GetPerformanceCounter ();
373 TimeStamp = GetTimeInNanoSecond (Ticker);
374 } else if (Ticker == 1) {
375 TimeStamp = 0;
376 } else {
377 TimeStamp = GetTimeInNanoSecond (Ticker);
378 }
379
380 //
381 // 4.Get the ModuleGuid.
382 //
383 if (CallerIdentifier != NULL) {
384 ModuleGuid = CallerIdentifier;
385 } else {
386 ModuleGuid = &gEfiCallerIdGuid;
387 }
388
389 //
390 // 5. Fill in the FPDT record according to different Performance Identifier.
391 //
392 switch (PerfId) {
393 case MODULE_START_ID:
394 case MODULE_END_ID:
395 StringPtr = PEIM_TOK;
396 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
397 FpdtRecordPtr.GuidEvent->Header.Type = FPDT_GUID_EVENT_TYPE;
398 FpdtRecordPtr.GuidEvent->Header.Length = sizeof (FPDT_GUID_EVENT_RECORD);
399 FpdtRecordPtr.GuidEvent->Header.Revision = FPDT_RECORD_REVISION_1;
400 FpdtRecordPtr.GuidEvent->ProgressID = PerfId;
401 FpdtRecordPtr.GuidEvent->Timestamp = TimeStamp;
402 CopyMem (&FpdtRecordPtr.GuidEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
403 }
404
405 break;
406
407 case MODULE_LOADIMAGE_START_ID:
408 case MODULE_LOADIMAGE_END_ID:
409 StringPtr = LOAD_IMAGE_TOK;
410 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
411 FpdtRecordPtr.GuidQwordEvent->Header.Type = FPDT_GUID_QWORD_EVENT_TYPE;
412 FpdtRecordPtr.GuidQwordEvent->Header.Length = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);
413 FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1;
414 FpdtRecordPtr.GuidQwordEvent->ProgressID = PerfId;
415 FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp;
416 if (PerfId == MODULE_LOADIMAGE_START_ID) {
417 PeiPerformanceLogHeader->LoadImageCount++;
418 }
419
420 FpdtRecordPtr.GuidQwordEvent->Qword = PeiPerformanceLogHeader->LoadImageCount;
421 CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
422 }
423
424 break;
425
426 case PERF_EVENTSIGNAL_START_ID:
427 case PERF_EVENTSIGNAL_END_ID:
428 case PERF_CALLBACK_START_ID:
429 case PERF_CALLBACK_END_ID:
430 if ((String == NULL) || (Guid == NULL)) {
431 return EFI_INVALID_PARAMETER;
432 }
433
434 StringPtr = String;
435 if (AsciiStrLen (String) == 0) {
436 StringPtr = "unknown name";
437 }
438
439 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
440 FpdtRecordPtr.DualGuidStringEvent->Header.Type = FPDT_DUAL_GUID_STRING_EVENT_TYPE;
441 FpdtRecordPtr.DualGuidStringEvent->Header.Length = sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD);
442 FpdtRecordPtr.DualGuidStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
443 FpdtRecordPtr.DualGuidStringEvent->ProgressID = PerfId;
444 FpdtRecordPtr.DualGuidStringEvent->Timestamp = TimeStamp;
445 CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, ModuleGuid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1));
446 CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2));
447 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DualGuidStringEvent->String, StringPtr, &FpdtRecordPtr.DualGuidStringEvent->Header.Length);
448 }
449
450 break;
451
452 case PERF_EVENT_ID:
453 case PERF_FUNCTION_START_ID:
454 case PERF_FUNCTION_END_ID:
455 case PERF_INMODULE_START_ID:
456 case PERF_INMODULE_END_ID:
457 case PERF_CROSSMODULE_START_ID:
458 case PERF_CROSSMODULE_END_ID:
459 if ((String != NULL) && (AsciiStrLen (String) != 0)) {
460 StringPtr = String;
461 } else {
462 StringPtr = "unknown name";
463 }
464
465 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
466 FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;
467 FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
468 FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
469 FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;
470 FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;
471 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
472 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
473 }
474
475 break;
476
477 default:
478 if (Attribute != PerfEntry) {
479 if ((String != NULL) && (AsciiStrLen (String) != 0)) {
480 StringPtr = String;
481 } else {
482 StringPtr = "unknown name";
483 }
484
485 if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
486 FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;
487 FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
488 FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
489 FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;
490 FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;
491 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));
492 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
493 }
494 } else {
495 return EFI_INVALID_PARAMETER;
496 }
497
498 break;
499 }
500
501 //
502 // 5.2 When PcdEdkiiFpdtStringRecordEnableOnly==TRUE, create string record for all Perf entries.
503 //
504 if (PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {
505 FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;
506 FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);
507 FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;
508 FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;
509 FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;
510 if (Guid != NULL) {
511 //
512 // Cache the event guid in string event record.
513 //
514 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, Guid, sizeof (EFI_GUID));
515 } else {
516 CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, ModuleGuid, sizeof (EFI_GUID));
517 }
518
519 CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);
520 }
521
522 //
523 // 6. Update the length of the used buffer after fill in the record.
524 //
525 PeiPerformanceLogHeader->SizeOfAllEntries += FpdtRecordPtr.RecordHeader->Length;
526
527 return EFI_SUCCESS;
528 }
529
530 /**
531 Creates a record for the beginning of a performance measurement.
532
533 If TimeStamp is zero, then this function reads the current time stamp
534 and adds that time stamp value to the record as the start time.
535
536 If TimeStamp is one, then this function reads 0 as the start time.
537
538 If TimeStamp is other value, then TimeStamp is added to the record as the start time.
539
540 @param Handle Pointer to environment specific context used
541 to identify the component being measured.
542 @param Token Pointer to a Null-terminated ASCII string
543 that identifies the component being measured.
544 @param Module Pointer to a Null-terminated ASCII string
545 that identifies the module being measured.
546 @param TimeStamp 64-bit time stamp.
547 @param Identifier 32-bit identifier. If the value is 0, the created record
548 is same as the one created by StartPerformanceMeasurement.
549
550 @retval RETURN_SUCCESS The start of the measurement was recorded.
551 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
552
553 **/
554 RETURN_STATUS
555 EFIAPI
556 StartPerformanceMeasurementEx (
557 IN CONST VOID *Handle OPTIONAL,
558 IN CONST CHAR8 *Token OPTIONAL,
559 IN CONST CHAR8 *Module OPTIONAL,
560 IN UINT64 TimeStamp,
561 IN UINT32 Identifier
562 )
563 {
564 CONST CHAR8 *String;
565
566 if (Token != NULL) {
567 String = Token;
568 } else if (Module != NULL) {
569 String = Module;
570 } else {
571 String = NULL;
572 }
573
574 return (RETURN_STATUS)InsertFpdtRecord (Handle, NULL, String, TimeStamp, 0, (UINT16)Identifier, PerfStartEntry);
575 }
576
577 /**
578
579 Creates a record for the end of a performance measurement.
580
581 If the TimeStamp is not zero or one, then TimeStamp is added to the record as the end time.
582 If the TimeStamp is zero, then this function reads the current time stamp and adds that time stamp value to the record as the end time.
583 If the TimeStamp is one, then this function reads 0 as the end time.
584
585 @param Handle Pointer to environment specific context used
586 to identify the component being measured.
587 @param Token Pointer to a Null-terminated ASCII string
588 that identifies the component being measured.
589 @param Module Pointer to a Null-terminated ASCII string
590 that identifies the module being measured.
591 @param TimeStamp 64-bit time stamp.
592 @param Identifier 32-bit identifier. If the value is 0, the found record
593 is same as the one found by EndPerformanceMeasurement.
594
595 @retval RETURN_SUCCESS The end of the measurement was recorded.
596 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
597
598 **/
599 RETURN_STATUS
600 EFIAPI
601 EndPerformanceMeasurementEx (
602 IN CONST VOID *Handle OPTIONAL,
603 IN CONST CHAR8 *Token OPTIONAL,
604 IN CONST CHAR8 *Module OPTIONAL,
605 IN UINT64 TimeStamp,
606 IN UINT32 Identifier
607 )
608 {
609 CONST CHAR8 *String;
610
611 if (Token != NULL) {
612 String = Token;
613 } else if (Module != NULL) {
614 String = Module;
615 } else {
616 String = NULL;
617 }
618
619 return (RETURN_STATUS)InsertFpdtRecord (Handle, NULL, String, TimeStamp, 0, (UINT16)Identifier, PerfEndEntry);
620 }
621
622 /**
623 Attempts to retrieve a performance measurement log entry from the performance measurement log.
624 It can also retrieve the log created by StartPerformanceMeasurement and EndPerformanceMeasurement,
625 and then assign the Identifier with 0.
626
627 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
628 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
629 and the key for the second entry in the log is returned. If the performance log is empty,
630 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
631 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
632 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
633 retrieved and an implementation specific non-zero key value that specifies the end of the performance
634 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
635 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
636 the log entry is returned in Handle, Token, Module, StartTimeStamp, EndTimeStamp and Identifier.
637 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
638 If Handle is NULL, then ASSERT().
639 If Token is NULL, then ASSERT().
640 If Module is NULL, then ASSERT().
641 If StartTimeStamp is NULL, then ASSERT().
642 If EndTimeStamp is NULL, then ASSERT().
643 If Identifier is NULL, then ASSERT().
644
645 !!!NOT Support yet!!!
646
647 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
648 0, then the first performance measurement log entry is retrieved.
649 On exit, the key of the next performance of entry entry.
650 @param Handle Pointer to environment specific context used to identify the component
651 being measured.
652 @param Token Pointer to a Null-terminated ASCII string that identifies the component
653 being measured.
654 @param Module Pointer to a Null-terminated ASCII string that identifies the module
655 being measured.
656 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
657 was started.
658 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
659 was ended.
660 @param Identifier Pointer to the 32-bit identifier that was recorded.
661
662 @return The key for the next performance log entry (in general case).
663
664 **/
665 UINTN
666 EFIAPI
667 GetPerformanceMeasurementEx (
668 IN UINTN LogEntryKey,
669 OUT CONST VOID **Handle,
670 OUT CONST CHAR8 **Token,
671 OUT CONST CHAR8 **Module,
672 OUT UINT64 *StartTimeStamp,
673 OUT UINT64 *EndTimeStamp,
674 OUT UINT32 *Identifier
675 )
676 {
677 return 0;
678 }
679
680 /**
681 Creates a record for the beginning of a performance measurement.
682
683 If TimeStamp is zero, then this function reads the current time stamp
684 and adds that time stamp value to the record as the start time.
685
686 If TimeStamp is one, then this function reads 0 as the start time.
687
688 If TimeStamp is other value, then TimeStamp is added to the record as the start time.
689
690
691 @param Handle Pointer to environment specific context used
692 to identify the component being measured.
693 @param Token Pointer to a Null-terminated ASCII string
694 that identifies the component being measured.
695 @param Module Pointer to a Null-terminated ASCII string
696 that identifies the module being measured.
697 @param TimeStamp 64-bit time stamp.
698
699 @retval RETURN_SUCCESS The start of the measurement was recorded.
700 @retval RETURN_OUT_OF_RESOURCES There are not enough resources to record the measurement.
701
702 **/
703 RETURN_STATUS
704 EFIAPI
705 StartPerformanceMeasurement (
706 IN CONST VOID *Handle OPTIONAL,
707 IN CONST CHAR8 *Token OPTIONAL,
708 IN CONST CHAR8 *Module OPTIONAL,
709 IN UINT64 TimeStamp
710 )
711 {
712 return StartPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
713 }
714
715 /**
716
717 Creates a record for the end of a performance measurement.
718
719 If the TimeStamp is not zero or one, then TimeStamp is added to the record as the end time.
720 If the TimeStamp is zero, then this function reads the current time stamp and adds that time stamp value to the record as the end time.
721 If the TimeStamp is one, then this function reads 0 as the end time.
722
723 @param Handle Pointer to environment specific context used
724 to identify the component being measured.
725 @param Token Pointer to a Null-terminated ASCII string
726 that identifies the component being measured.
727 @param Module Pointer to a Null-terminated ASCII string
728 that identifies the module being measured.
729 @param TimeStamp 64-bit time stamp.
730
731 @retval RETURN_SUCCESS The end of the measurement was recorded.
732 @retval RETURN_NOT_FOUND The specified measurement record could not be found.
733
734 **/
735 RETURN_STATUS
736 EFIAPI
737 EndPerformanceMeasurement (
738 IN CONST VOID *Handle OPTIONAL,
739 IN CONST CHAR8 *Token OPTIONAL,
740 IN CONST CHAR8 *Module OPTIONAL,
741 IN UINT64 TimeStamp
742 )
743 {
744 return EndPerformanceMeasurementEx (Handle, Token, Module, TimeStamp, 0);
745 }
746
747 /**
748 Attempts to retrieve a performance measurement log entry from the performance measurement log.
749 It can also retrieve the log created by StartPerformanceMeasurementEx and EndPerformanceMeasurementEx,
750 and then eliminate the Identifier.
751
752 Attempts to retrieve the performance log entry specified by LogEntryKey. If LogEntryKey is
753 zero on entry, then an attempt is made to retrieve the first entry from the performance log,
754 and the key for the second entry in the log is returned. If the performance log is empty,
755 then no entry is retrieved and zero is returned. If LogEntryKey is not zero, then the performance
756 log entry associated with LogEntryKey is retrieved, and the key for the next entry in the log is
757 returned. If LogEntryKey is the key for the last entry in the log, then the last log entry is
758 retrieved and an implementation specific non-zero key value that specifies the end of the performance
759 log is returned. If LogEntryKey is equal this implementation specific non-zero key value, then no entry
760 is retrieved and zero is returned. In the cases where a performance log entry can be returned,
761 the log entry is returned in Handle, Token, Module, StartTimeStamp, and EndTimeStamp.
762 If LogEntryKey is not a valid log entry key for the performance measurement log, then ASSERT().
763 If Handle is NULL, then ASSERT().
764 If Token is NULL, then ASSERT().
765 If Module is NULL, then ASSERT().
766 If StartTimeStamp is NULL, then ASSERT().
767 If EndTimeStamp is NULL, then ASSERT().
768
769 NOT Support yet.
770
771 @param LogEntryKey On entry, the key of the performance measurement log entry to retrieve.
772 0, then the first performance measurement log entry is retrieved.
773 On exit, the key of the next performance of entry entry.
774 @param Handle Pointer to environment specific context used to identify the component
775 being measured.
776 @param Token Pointer to a Null-terminated ASCII string that identifies the component
777 being measured.
778 @param Module Pointer to a Null-terminated ASCII string that identifies the module
779 being measured.
780 @param StartTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
781 was started.
782 @param EndTimeStamp Pointer to the 64-bit time stamp that was recorded when the measurement
783 was ended.
784
785 @return The key for the next performance log entry (in general case).
786
787 **/
788 UINTN
789 EFIAPI
790 GetPerformanceMeasurement (
791 IN UINTN LogEntryKey,
792 OUT CONST VOID **Handle,
793 OUT CONST CHAR8 **Token,
794 OUT CONST CHAR8 **Module,
795 OUT UINT64 *StartTimeStamp,
796 OUT UINT64 *EndTimeStamp
797 )
798 {
799 return 0;
800 }
801
802 /**
803 Returns TRUE if the performance measurement macros are enabled.
804
805 This function returns TRUE if the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
806 PcdPerformanceLibraryPropertyMask is set. Otherwise FALSE is returned.
807
808 @retval TRUE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
809 PcdPerformanceLibraryPropertyMask is set.
810 @retval FALSE The PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of
811 PcdPerformanceLibraryPropertyMask is clear.
812
813 **/
814 BOOLEAN
815 EFIAPI
816 PerformanceMeasurementEnabled (
817 VOID
818 )
819 {
820 return (BOOLEAN)((PcdGet8 (PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0);
821 }
822
823 /**
824 Create performance record with event description and a timestamp.
825
826 @param CallerIdentifier - Image handle or pointer to caller ID GUID
827 @param Guid - Pointer to a GUID
828 @param String - Pointer to a string describing the measurement
829 @param Address - Pointer to a location in memory relevant to the measurement
830 @param Identifier - Performance identifier describing the type of measurement
831
832 @retval RETURN_SUCCESS - Successfully created performance record
833 @retval RETURN_OUT_OF_RESOURCES - Ran out of space to store the records
834 @retval RETURN_INVALID_PARAMETER - Invalid parameter passed to function - NULL
835 pointer or invalid PerfId
836
837 **/
838 RETURN_STATUS
839 EFIAPI
840 LogPerformanceMeasurement (
841 IN CONST VOID *CallerIdentifier,
842 IN CONST VOID *Guid OPTIONAL,
843 IN CONST CHAR8 *String OPTIONAL,
844 IN UINT64 Address OPTIONAL,
845 IN UINT32 Identifier
846 )
847 {
848 return (RETURN_STATUS)InsertFpdtRecord (CallerIdentifier, Guid, String, 0, Address, (UINT16)Identifier, PerfEntry);
849 }
850
851 /**
852 Check whether the specified performance measurement can be logged.
853
854 This function returns TRUE when the PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED bit of PcdPerformanceLibraryPropertyMask is set
855 and the Type disable bit in PcdPerformanceLibraryPropertyMask is not set.
856
857 @param Type - Type of the performance measurement entry.
858
859 @retval TRUE The performance measurement can be logged.
860 @retval FALSE The performance measurement can NOT be logged.
861
862 **/
863 BOOLEAN
864 EFIAPI
865 LogPerformanceMeasurementEnabled (
866 IN CONST UINTN Type
867 )
868 {
869 //
870 // When Performance measurement is enabled and the type is not filtered, the performance can be logged.
871 //
872 if (PerformanceMeasurementEnabled () && ((PcdGet8 (PcdPerformanceLibraryPropertyMask) & Type) == 0)) {
873 return TRUE;
874 }
875
876 return FALSE;
877 }