Removes redundant code and adds data size check for certificate data in DxeImageVerif...
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / FirmwarePerformanceDataTableDxe / FirmwarePerformanceDxe.c
CommitLineData
0284e90c
LG
1/** @file\r
2 This module install ACPI Firmware Performance Data Table (FPDT).\r
3\r
4 This module register report status code listener to collect performance data\r
5 for Firmware Basic Boot Performance Record and install FPDT to ACPI table.\r
6\r
7 Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
8 This program and the accompanying materials\r
9 are licensed and made available under the terms and conditions of the BSD License\r
10 which accompanies this distribution. The full text of the license may be found at\r
11 http://opensource.org/licenses/bsd-license.php\r
12\r
13 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
14 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
15\r
16**/\r
17\r
18#include <PiDxe.h>\r
19\r
20#include <IndustryStandard/Acpi50.h>\r
21\r
22#include <Protocol/ReportStatusCodeHandler.h>\r
23#include <Protocol/AcpiTable.h>\r
24\r
25#include <Guid/Acpi.h>\r
26#include <Guid/FirmwarePerformance.h>\r
27#include <Guid/EventGroup.h>\r
28#include <Guid/EventLegacyBios.h>\r
29\r
30#include <Library/UefiBootServicesTableLib.h>\r
31#include <Library/UefiRuntimeServicesTableLib.h>\r
32#include <Library/BaseLib.h>\r
33#include <Library/DebugLib.h>\r
34#include <Library/TimerLib.h>\r
35#include <Library/BaseMemoryLib.h>\r
36#include <Library/MemoryAllocationLib.h>\r
37#include <Library/PcdLib.h>\r
38#include <Library/HobLib.h>\r
39#include <Library/PcdLib.h>\r
40\r
41//\r
42// ACPI table information used to initialize tables.\r
43//\r
44#define EFI_ACPI_OEM_ID "INTEL"\r
45#define EFI_ACPI_OEM_TABLE_ID 0x2020204F4E414954ULL // "TIANO "\r
46#define EFI_ACPI_OEM_REVISION 0x00000001\r
47#define EFI_ACPI_CREATOR_ID 0x5446534D // TBD "MSFT"\r
48#define EFI_ACPI_CREATOR_REVISION 0x01000013 // TBD\r
49\r
50EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;\r
51\r
52EFI_EVENT mReadyToBootEvent;\r
53EFI_EVENT mLegacyBootEvent;\r
54EFI_EVENT mExitBootServicesEvent;\r
55UINTN mFirmwarePerformanceTableTemplateKey = 0;\r
56\r
57FIRMWARE_PERFORMANCE_RUNTIME_DATA *mPerformanceRuntimeData = NULL;\r
58BOOT_PERFORMANCE_TABLE *mAcpiBootPerformanceTable = NULL;\r
59S3_PERFORMANCE_TABLE *mAcpiS3PerformanceTable = NULL;\r
60\r
61FIRMWARE_PERFORMANCE_TABLE mFirmwarePerformanceTableTemplate = {\r
62 {\r
63 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE,\r
64 sizeof (FIRMWARE_PERFORMANCE_TABLE),\r
65 EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION, // Revision\r
66 0x00, // Checksum will be updated at runtime\r
67 //\r
68 // It is expected that these values will be updated at runtime.\r
69 //\r
70 EFI_ACPI_OEM_ID, // OEMID is a 6 bytes long field\r
71 EFI_ACPI_OEM_TABLE_ID, // OEM table identification(8 bytes long)\r
72 EFI_ACPI_OEM_REVISION, // OEM revision number\r
73 EFI_ACPI_CREATOR_ID, // ASL compiler vendor ID\r
74 EFI_ACPI_CREATOR_REVISION, // ASL compiler revision number\r
75 },\r
76 //\r
77 // Firmware Basic Boot Performance Table Pointer Record.\r
78 //\r
79 {\r
80 {\r
81 EFI_ACPI_5_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER , // Type\r
82 sizeof (EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD), // Length\r
83 EFI_ACPI_5_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER // Revision\r
84 },\r
85 0, // Reserved\r
86 0 // BootPerformanceTablePointer will be updated at runtime.\r
87 },\r
88 //\r
89 // S3 Performance Table Pointer Record.\r
90 //\r
91 {\r
92 {\r
93 EFI_ACPI_5_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER, // Type\r
94 sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD), // Length\r
95 EFI_ACPI_5_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER // Revision\r
96 },\r
97 0, // Reserved\r
98 0 // S3PerformanceTablePointer will be updated at runtime.\r
99 }\r
100};\r
101\r
102BOOT_PERFORMANCE_TABLE mBootPerformanceTableTemplate = {\r
103 {\r
104 EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE,\r
105 sizeof (BOOT_PERFORMANCE_TABLE)\r
106 },\r
107 {\r
108 {\r
109 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT, // Type\r
110 sizeof (EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD), // Length\r
111 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT // Revision\r
112 },\r
113 0, // Reserved\r
114 //\r
115 // These values will be updated at runtime.\r
116 //\r
117 0, // ResetEnd\r
118 0, // OsLoaderLoadImageStart\r
119 0, // OsLoaderStartImageStart\r
120 0, // ExitBootServicesEntry\r
121 0 // ExitBootServicesExit\r
122 }\r
123};\r
124\r
125S3_PERFORMANCE_TABLE mS3PerformanceTableTemplate = {\r
126 {\r
127 EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE,\r
128 sizeof (S3_PERFORMANCE_TABLE)\r
129 },\r
130 {\r
131 {\r
132 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME, // Type\r
133 sizeof (EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD), // Length\r
134 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME // Revision\r
135 },\r
136 //\r
137 // These values will be updated by Firmware Performance PEIM.\r
138 //\r
139 0, // ResumeCount\r
140 0, // FullResume\r
141 0 // AverageResume\r
142 },\r
143 {\r
144 {\r
145 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND, // Type\r
146 sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD), // Length\r
147 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND // Revision\r
148 },\r
149 //\r
150 // These values will be updated bye Firmware Performance SMM driver.\r
151 //\r
152 0, // SuspendStart\r
153 0 // SuspendEnd\r
154 }\r
155};\r
156\r
157/**\r
158 This function calculates and updates an UINT8 checksum.\r
159\r
160 @param[in] Buffer Pointer to buffer to checksum\r
161 @param[in] Size Number of bytes to checksum\r
162\r
163**/\r
164VOID\r
165FpdtAcpiTableChecksum (\r
166 IN UINT8 *Buffer,\r
167 IN UINTN Size\r
168 )\r
169{\r
170 UINTN ChecksumOffset;\r
171\r
172 ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);\r
173\r
174 //\r
175 // Set checksum to 0 first.\r
176 //\r
177 Buffer[ChecksumOffset] = 0;\r
178\r
179 //\r
180 // Update checksum value.\r
181 //\r
182 Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);\r
183}\r
184\r
185/**\r
186 Allocate EfiReservedMemoryType below 4G memory address.\r
187\r
188 This function allocates EfiReservedMemoryType below 4G memory address.\r
189\r
190 @param[in] Size Size of memory to allocate.\r
191\r
192 @return Allocated address for output.\r
193\r
194**/\r
195VOID *\r
196FpdtAllocateReservedMemoryBelow4G (\r
197 IN UINTN Size\r
198 )\r
199{\r
200 UINTN Pages;\r
201 EFI_PHYSICAL_ADDRESS Address;\r
202 EFI_STATUS Status;\r
203 VOID *Buffer;\r
204\r
205 Pages = EFI_SIZE_TO_PAGES (Size);\r
206 Address = 0xffffffff;\r
207\r
208 Status = gBS->AllocatePages (\r
209 AllocateMaxAddress,\r
210 EfiReservedMemoryType,\r
211 Pages,\r
212 &Address\r
213 );\r
214 ASSERT_EFI_ERROR (Status);\r
215\r
216 Buffer = (VOID *) (UINTN) Address;\r
217 ZeroMem (Buffer, Size);\r
218\r
219 return Buffer;\r
220}\r
221\r
222/**\r
223 Install ACPI Firmware Performance Data Table (FPDT).\r
224\r
225 @return Status code.\r
226\r
227**/\r
228EFI_STATUS\r
229InstallFirmwarePerformanceDataTable (\r
230 VOID\r
231 )\r
232{\r
233 EFI_STATUS Status;\r
234 EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;\r
235 FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;\r
236 EFI_PHYSICAL_ADDRESS Address;\r
237 UINTN Size;\r
238\r
239 //\r
240 // Get AcpiTable Protocol.\r
241 //\r
242 Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);\r
243 if (EFI_ERROR (Status)) {\r
244 return Status;\r
245 }\r
246\r
247 //\r
248 // Prepare memory for runtime Performance Record.\r
249 //\r
250 mPerformanceRuntimeData = NULL;\r
251 ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable));\r
252 //\r
253 // Try to allocate the same runtime buffer as last time boot.\r
254 //\r
255 Size = sizeof (FIRMWARE_PERFORMANCE_VARIABLE);\r
256 Status = gRT->GetVariable (\r
257 EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,\r
258 &gEfiFirmwarePerformanceGuid,\r
259 NULL,\r
260 &Size,\r
261 &PerformanceVariable\r
262 );\r
263 if (!EFI_ERROR (Status)) {\r
264 Address = PerformanceVariable.BootPerformanceTablePointer;\r
265 Status = gBS->AllocatePages (\r
266 AllocateAddress,\r
267 EfiReservedMemoryType,\r
268 EFI_SIZE_TO_PAGES (sizeof (FIRMWARE_PERFORMANCE_RUNTIME_DATA)),\r
269 &Address\r
270 );\r
271 if (!EFI_ERROR (Status)) {\r
272 mPerformanceRuntimeData = (FIRMWARE_PERFORMANCE_RUNTIME_DATA *) (UINTN) Address;\r
273 }\r
274 }\r
275\r
276 if (mPerformanceRuntimeData == NULL) {\r
277 //\r
278 // Fail to allocate at specified address, continue to allocate at any address.\r
279 //\r
280 mPerformanceRuntimeData = FpdtAllocateReservedMemoryBelow4G (sizeof (FIRMWARE_PERFORMANCE_RUNTIME_DATA));\r
281 }\r
282 DEBUG ((EFI_D_INFO, "FPDT: Performance Runtime Data address = 0x%x\n", mPerformanceRuntimeData));\r
283\r
284 if (mPerformanceRuntimeData == NULL) {\r
285 return EFI_OUT_OF_RESOURCES;\r
286 }\r
287\r
288 //\r
289 // Prepare Boot Performance Table.\r
290 //\r
291 mAcpiBootPerformanceTable = &mPerformanceRuntimeData->BootPerformance;\r
292 CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate));\r
293 DEBUG ((EFI_D_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));\r
294 //\r
295 // Save Boot Performance Table address to Variable for use in S4 resume.\r
296 //\r
297 PerformanceVariable.BootPerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiBootPerformanceTable;\r
298 //\r
299 // Update Boot Performance Table Pointer in template.\r
300 //\r
301 mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable;\r
302\r
303 if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {\r
304 //\r
305 // Prepare S3 Performance Table.\r
306 //\r
307 mAcpiS3PerformanceTable = &mPerformanceRuntimeData->S3Performance;\r
308 CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate, sizeof (mS3PerformanceTableTemplate));\r
309 DEBUG ((EFI_D_INFO, "FPDT: ACPI S3 Performance Table address = 0x%x\n", mAcpiS3PerformanceTable));\r
310\r
311 //\r
312 // Save S3 Performance Table address to Variable for use in Firmware Performance PEIM.\r
313 //\r
314 PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable;\r
315\r
316 //\r
317 // Update S3 Performance Table Pointer in template.\r
318 //\r
319 mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) PerformanceVariable.S3PerformanceTablePointer;\r
320 } else {\r
321 //\r
322 // Exclude S3 Performance Table Pointer from FPDT table template.\r
323 //\r
324 mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD);\r
325 }\r
326\r
327 //\r
328 // Save Runtime Performance Table pointers to Variable.\r
329 //\r
330 Status = gRT->SetVariable (\r
331 EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,\r
332 &gEfiFirmwarePerformanceGuid,\r
333 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,\r
334 sizeof (FIRMWARE_PERFORMANCE_VARIABLE),\r
335 &PerformanceVariable\r
336 );\r
337 ASSERT_EFI_ERROR (Status);\r
338\r
339 //\r
340 // Publish Firmware Performance Data Table.\r
341 //\r
342 FpdtAcpiTableChecksum ((UINT8 *) &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length);\r
343 Status = AcpiTableProtocol->InstallAcpiTable (\r
344 AcpiTableProtocol,\r
345 &mFirmwarePerformanceTableTemplate,\r
346 mFirmwarePerformanceTableTemplate.Header.Length,\r
347 &mFirmwarePerformanceTableTemplateKey\r
348 );\r
349 if (EFI_ERROR (Status)) {\r
350 FreePool (mPerformanceRuntimeData);\r
351 mAcpiBootPerformanceTable = NULL;\r
352 mAcpiS3PerformanceTable = NULL;\r
353 return Status;\r
354 }\r
355\r
356 return EFI_SUCCESS;\r
357}\r
358\r
359/**\r
360 Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to\r
361 install the Firmware Performance Data Table.\r
362\r
363 @param[in] Event The Event that is being processed.\r
364 @param[in] Context The Event Context.\r
365\r
366**/\r
367VOID\r
368EFIAPI\r
369FpdtReadyToBootEventNotify (\r
370 IN EFI_EVENT Event,\r
371 IN VOID *Context\r
372 )\r
373{\r
374 if (mAcpiBootPerformanceTable == NULL) {\r
375 //\r
376 // ACPI Firmware Performance Data Table not installed yet, install it now.\r
377 //\r
378 InstallFirmwarePerformanceDataTable ();\r
379 }\r
380}\r
381\r
382/**\r
383 Notify function for event group EFI_EVENT_LEGACY_BOOT_GUID. This is used to\r
384 record performance data for OsLoaderLoadImageStart in FPDT for legacy boot.\r
385\r
386 @param[in] Event The Event that is being processed.\r
387 @param[in] Context The Event Context.\r
388\r
389**/\r
390VOID\r
391EFIAPI\r
392FpdtLegacyBootEventNotify (\r
393 IN EFI_EVENT Event,\r
394 IN VOID *Context\r
395 )\r
396{\r
397 if (mAcpiBootPerformanceTable == NULL) {\r
398 //\r
399 // Firmware Performance Data Table not installed, do nothing.\r
400 //\r
401 return ;\r
402 }\r
403\r
404 //\r
405 // Update Firmware Basic Boot Performance Record for legacy boot.\r
406 //\r
407 mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart = 0;\r
408 mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());\r
409 mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = 0;\r
410 mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesExit = 0;\r
411\r
412 //\r
413 // Dump FPDT Boot Performance record.\r
414 //\r
415 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));\r
416 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = 0\n"));\r
417 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));\r
418 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = 0\n"));\r
419 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesExit = 0\n"));\r
420}\r
421\r
422/**\r
423 Notify function for event EVT_SIGNAL_EXIT_BOOT_SERVICES. This is used to record\r
424 performance data for ExitBootServicesEntry in FPDT.\r
425\r
426 @param[in] Event The Event that is being processed.\r
427 @param[in] Context The Event Context.\r
428\r
429**/\r
430VOID\r
431EFIAPI\r
432FpdtExitBootServicesEventNotify (\r
433 IN EFI_EVENT Event,\r
434 IN VOID *Context\r
435 )\r
436{\r
437 if (mAcpiBootPerformanceTable == NULL) {\r
438 //\r
439 // Firmware Performance Data Table not installed, do nothing.\r
440 //\r
441 return ;\r
442 }\r
443\r
444 //\r
445 // Update Firmware Basic Boot Performance Record for UEFI boot.\r
446 //\r
447 mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = GetTimeInNanoSecond (GetPerformanceCounter ());\r
448\r
449 //\r
450 // Dump FPDT Boot Performance record.\r
451 //\r
452 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));\r
453 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart));\r
454 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));\r
455 DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry));\r
456 //\r
457 // ExitBootServicesExit will be updated later, so don't dump it here.\r
458 //\r
459}\r
460\r
461/**\r
462 Report status code listener of FPDT. This is used to collect performance data\r
463 for OsLoaderLoadImageStart and OsLoaderStartImageStart in FPDT.\r
464\r
465 @param[in] CodeType Indicates the type of status code being reported.\r
466 @param[in] Value Describes the current status of a hardware or software entity.\r
467 This included information about the class and subclass that is used to\r
468 classify the entity as well as an operation.\r
469 @param[in] Instance The enumeration of a hardware or software entity within\r
470 the system. Valid instance numbers start with 1.\r
471 @param[in] CallerId This optional parameter may be used to identify the caller.\r
472 This parameter allows the status code driver to apply different rules to\r
473 different callers.\r
474 @param[in] Data This optional parameter may be used to pass additional data.\r
475\r
476 @retval EFI_SUCCESS Status code is what we expected.\r
477 @retval EFI_UNSUPPORTED Status code not supported.\r
478\r
479**/\r
480EFI_STATUS\r
481EFIAPI\r
482FpdtStatusCodeListenerDxe (\r
483 IN EFI_STATUS_CODE_TYPE CodeType,\r
484 IN EFI_STATUS_CODE_VALUE Value,\r
485 IN UINT32 Instance,\r
486 IN EFI_GUID *CallerId,\r
487 IN EFI_STATUS_CODE_DATA *Data\r
488 )\r
489{\r
490 EFI_STATUS Status;\r
491\r
492 //\r
493 // Check whether status code is what we are interested in.\r
494 //\r
495 if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) {\r
496 return EFI_UNSUPPORTED;\r
497 }\r
498\r
499 Status = EFI_SUCCESS;\r
500 if (Value == PcdGet32 (PcdProgressCodeOsLoaderLoad)) {\r
501 //\r
502 // Progress code for OS Loader LoadImage.\r
503 //\r
504 if (mAcpiBootPerformanceTable == NULL) {\r
505 return Status;\r
506 }\r
507\r
508 //\r
509 // Update OS Loader LoadImage Start for UEFI boot.\r
510 //\r
511 mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());\r
512 } else if (Value == PcdGet32 (PcdProgressCodeOsLoaderStart)) {\r
513 //\r
514 // Progress code for OS Loader StartImage.\r
515 //\r
516 if (mAcpiBootPerformanceTable == NULL) {\r
517 return Status;\r
518 }\r
519\r
520 //\r
521 // Update OS Loader StartImage Start for UEFI boot.\r
522 //\r
523 mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());\r
524 } else if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)) {\r
525 //\r
526 // Progress code for ExitBootServices.\r
527 //\r
528 if (mAcpiBootPerformanceTable == NULL) {\r
529 return Status;\r
530 }\r
531\r
532 //\r
533 // Update ExitBootServicesExit for UEFI boot.\r
534 //\r
535 mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesExit = GetTimeInNanoSecond (GetPerformanceCounter ());\r
536\r
537 //\r
538 // Unregister boot time report status code listener.\r
539 //\r
540 mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe);\r
541 } else {\r
542 //\r
543 // Ignore else progress code.\r
544 //\r
545 Status = EFI_UNSUPPORTED;\r
546 }\r
547\r
548 return Status;\r
549}\r
550\r
551/**\r
552 The module Entry Point of the Firmware Performance Data Table DXE driver.\r
553\r
554 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
555 @param[in] SystemTable A pointer to the EFI System Table.\r
556\r
557 @retval EFI_SUCCESS The entry point is executed successfully.\r
558 @retval Other Some error occurs when executing this entry point.\r
559\r
560**/\r
561EFI_STATUS\r
562EFIAPI\r
563FirmwarePerformanceDxeEntryPoint (\r
564 IN EFI_HANDLE ImageHandle,\r
565 IN EFI_SYSTEM_TABLE *SystemTable\r
566 )\r
567{\r
568 EFI_STATUS Status;\r
569 EFI_HOB_GUID_TYPE *GuidHob;\r
570 FIRMWARE_SEC_PERFORMANCE *Performance;\r
571\r
572 //\r
573 // Get Report Status Code Handler Protocol.\r
574 //\r
575 Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol);\r
576 ASSERT_EFI_ERROR (Status);\r
577\r
578 //\r
579 // Register report status code listener for OS Loader load and start.\r
580 //\r
581 Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL);\r
582 ASSERT_EFI_ERROR (Status);\r
583\r
584 //\r
585 // Register the notify function to update FPDT on ExitBootServices Event.\r
586 //\r
587 Status = gBS->CreateEventEx (\r
588 EVT_NOTIFY_SIGNAL,\r
589 TPL_NOTIFY,\r
590 FpdtExitBootServicesEventNotify,\r
591 NULL,\r
592 &gEfiEventExitBootServicesGuid,\r
593 &mExitBootServicesEvent\r
594 );\r
595 ASSERT_EFI_ERROR (Status);\r
596\r
597 //\r
598 // Create ready to boot event to install ACPI FPDT table.\r
599 //\r
600 Status = gBS->CreateEventEx (\r
601 EVT_NOTIFY_SIGNAL,\r
602 TPL_NOTIFY,\r
603 FpdtReadyToBootEventNotify,\r
604 NULL,\r
605 &gEfiEventReadyToBootGuid,\r
606 &mReadyToBootEvent\r
607 );\r
608 ASSERT_EFI_ERROR (Status);\r
609\r
610 //\r
611 // Create legacy boot event to log OsLoaderStartImageStart for legacy boot.\r
612 //\r
613 Status = gBS->CreateEventEx (\r
614 EVT_NOTIFY_SIGNAL,\r
615 TPL_NOTIFY,\r
616 FpdtLegacyBootEventNotify,\r
617 NULL,\r
618 &gEfiEventLegacyBootGuid,\r
619 &mLegacyBootEvent\r
620 );\r
621 ASSERT_EFI_ERROR (Status);\r
622\r
623 //\r
624 // Retrieve GUID HOB data that contains the ResetEnd.\r
625 //\r
626 GuidHob = GetFirstGuidHob (&gEfiFirmwarePerformanceGuid);\r
627 if (GuidHob != NULL) {\r
628 Performance = (FIRMWARE_SEC_PERFORMANCE *) GET_GUID_HOB_DATA (GuidHob);\r
629 mBootPerformanceTableTemplate.BasicBoot.ResetEnd = Performance->ResetEnd;\r
630 } else {\r
631 //\r
632 // SEC Performance Data Hob not found, ResetEnd in ACPI FPDT table will be 0.\r
633 //\r
634 DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n"));\r
635 }\r
636\r
637 return EFI_SUCCESS;\r
638}\r