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