4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This module install ACPI Firmware Performance Data Table (FPDT).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This module register report status code listener to collect performance data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for Firmware Basic Boot Performance Record and other boot performance records,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync and install FPDT to ACPI table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This program and the accompanying materials
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync are licensed and made available under the terms and conditions of the BSD License
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync which accompanies this distribution. The full text of the license may be found at
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync// ACPI table information used to initialize tables.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define EFI_ACPI_OEM_TABLE_ID 0x2020204F4E414954ULL // "TIANO "
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define EFI_ACPI_CREATOR_ID 0x5446534D // TBD "MSFT"
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync#define SMM_BOOT_RECORD_COMM_SIZE OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof(SMM_BOOT_RECORD_COMMUNICATE)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncEFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOT_PERFORMANCE_TABLE *mAcpiBootPerformanceTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncS3_PERFORMANCE_TABLE *mAcpiS3PerformanceTable = NULL;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncFIRMWARE_PERFORMANCE_TABLE mFirmwarePerformanceTableTemplate = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION, // Revision
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // It is expected that these values will be updated at runtime.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_OEM_TABLE_ID, // OEM table identification(8 bytes long)
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_CREATOR_REVISION, // ASL compiler revision number
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Firmware Basic Boot Performance Table Pointer Record.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER , // Type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD), // Length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER // Revision
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // Reserved
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 // BootPerformanceTablePointer will be updated at runtime.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // S3 Performance Table Pointer Record.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER, // Type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD), // Length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER // Revision
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // Reserved
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 // S3PerformanceTablePointer will be updated at runtime.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncBOOT_PERFORMANCE_TABLE mBootPerformanceTableTemplate = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT, // Type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD), // Length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT // Revision
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // Reserved
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // These values will be updated at runtime.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // ResetEnd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // OsLoaderLoadImageStart
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // OsLoaderStartImageStart
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // ExitBootServicesEntry
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 // ExitBootServicesExit
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsyncS3_PERFORMANCE_TABLE mS3PerformanceTableTemplate = {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME, // Type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD), // Length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME // Revision
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // These values will be updated by Firmware Performance PEIM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // ResumeCount
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // FullResume
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 // AverageResume
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND, // Type
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD), // Length
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND // Revision
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // These values will be updated bye Firmware Performance SMM driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0, // SuspendStart
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync 0 // SuspendEnd
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function calculates and updates an UINT8 checksum.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Buffer Pointer to buffer to checksum
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Size Number of bytes to checksum
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Set checksum to 0 first.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update checksum value.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Allocate EfiReservedMemoryType below 4G memory address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This function allocates EfiReservedMemoryType below 4G memory address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Size Size of memory to allocate.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Allocated address for output.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Install ACPI Firmware Performance Data Table (FPDT).
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @return Status code.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync UINT8 SmmBootRecordCommBuffer[SMM_BOOT_RECORD_COMM_SIZE];
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get AcpiTable Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Collect boot records from SMM drivers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &Communication);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Initialize communicate buffer
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER*)SmmBootRecordCommBuffer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)SmmCommBufferHeader->Data;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem((UINT8*)SmmCommData, sizeof(SMM_BOOT_RECORD_COMMUNICATE));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyGuid (&SmmCommBufferHeader->HeaderGuid, &gEfiFirmwarePerformanceGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommBufferHeader->MessageLength = sizeof(SMM_BOOT_RECORD_COMMUNICATE);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get the size of boot records.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (!EFI_ERROR (SmmCommData->ReturnStatus) && SmmCommData->BootRecordSize != 0) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get all boot records
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommData->Function = SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync SmmCommData->BootRecordData = AllocateZeroPool(SmmCommData->BootRecordSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = Communication->Communicate (Communication, SmmBootRecordCommBuffer, &CommSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Prepare memory for runtime Performance Record.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Runtime performance records includes two tables S3 performance table and Boot performance table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // S3 Performance table includes S3Resume and S3Suspend records.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Boot Performance table includes BasicBoot record, and one or more appended Boot Records.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeDataSize = sizeof (S3_PERFORMANCE_TABLE) + sizeof (BOOT_PERFORMANCE_TABLE) + mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeDataSize += SmmCommData->BootRecordSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Try to allocate the same runtime buffer as last time boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Address = PerformanceVariable.S3PerformanceTablePointer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeData = (UINT8 *) (UINTN) Address;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fail to allocate at specified address, continue to allocate at any address.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeData = FpdtAllocateReservedMemoryBelow4G (PerformanceRuntimeDataSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Performance Runtime Data address = 0x%x\n", PerformanceRuntimeData));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeDataHead = PerformanceRuntimeData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Prepare S3 Performance Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) PerformanceRuntimeData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate, sizeof (mS3PerformanceTableTemplate));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeData = PerformanceRuntimeData + mAcpiS3PerformanceTable->Header.Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: ACPI S3 Performance Table address = 0x%x\n", mAcpiS3PerformanceTable));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save S3 Performance Table address to Variable for use in Firmware Performance PEIM.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update S3 Performance Table Pointer in template.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) PerformanceVariable.S3PerformanceTablePointer;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Exclude S3 Performance Table Pointer from FPDT table template.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Prepare Boot Performance Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) PerformanceRuntimeData;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill Basic Boot record to Boot Performance Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PerformanceRuntimeData, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeData = PerformanceRuntimeData + mAcpiBootPerformanceTable->Header.Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill Boot records from boot drivers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PerformanceRuntimeData, mBootRecordBuffer, mBootRecordSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->Header.Length += mBootRecordSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeData = PerformanceRuntimeData + mBootRecordSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Fill Boot records from SMM drivers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (PerformanceRuntimeData, SmmCommData->BootRecordData, SmmCommData->BootRecordSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->Header.Length = (UINT32) (mAcpiBootPerformanceTable->Header.Length + SmmCommData->BootRecordSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeData = PerformanceRuntimeData + SmmCommData->BootRecordSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Reserve space for boot records after ReadyToBoot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceRuntimeData = PerformanceRuntimeData + PcdGet32 (PcdExtFpdtBootRecordPadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save Boot Performance Table address to Variable for use in S4 resume.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync PerformanceVariable.BootPerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiBootPerformanceTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update Boot Performance Table Pointer in template.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save Runtime Performance Table pointers to Variable.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Publish Firmware Performance Data Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync FpdtAcpiTableChecksum ((UINT8 *) &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Free temp Boot record, and update Boot Record to point to Basic Boot performance table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootRecordBuffer = (UINT8 *) mAcpiBootPerformanceTable;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootRecordSize = mAcpiBootPerformanceTable->Header.Length;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootRecordMaxSize = mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for event group EFI_EVENT_GROUP_READY_TO_BOOT. This is used to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync install the Firmware Performance Data Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The Event that is being processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The Event Context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ACPI Firmware Performance Data Table not installed yet, install it now.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for event group EFI_EVENT_LEGACY_BOOT_GUID. This is used to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync record performance data for OsLoaderLoadImageStart in FPDT for legacy boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The Event that is being processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The Event Context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Firmware Performance Data Table not installed, do nothing.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update Firmware Basic Boot Performance Record for legacy boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesExit = 0;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Dump FPDT Boot Performance record.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = 0\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = 0\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesExit = 0\n"));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Notify function for event EVT_SIGNAL_EXIT_BOOT_SERVICES. This is used to record
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync performance data for ExitBootServicesEntry in FPDT.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Event The Event that is being processed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Context The Event Context.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Firmware Performance Data Table not installed, do nothing.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update Firmware Basic Boot Performance Record for UEFI boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = GetTimeInNanoSecond (GetPerformanceCounter ());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Dump FPDT Boot Performance record.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry));
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // ExitBootServicesExit will be updated later, so don't dump it here.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Report status code listener of FPDT. This is used to collect performance data
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync for OsLoaderLoadImageStart and OsLoaderStartImageStart in FPDT.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] CodeType Indicates the type of status code being reported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Value Describes the current status of a hardware or software entity.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This included information about the class and subclass that is used to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync classify the entity as well as an operation.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Instance The enumeration of a hardware or software entity within
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync the system. Valid instance numbers start with 1.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] CallerId This optional parameter may be used to identify the caller.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync This parameter allows the status code driver to apply different rules to
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync different callers.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] Data This optional parameter may be used to pass additional data.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS Status code is what we expected.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_UNSUPPORTED Status code not supported.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Check whether status code is what we are interested in.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (Value == PcdGet32 (PcdProgressCodeOsLoaderLoad)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Progress code for OS Loader LoadImage.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update OS Loader LoadImage Start for UEFI boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Value == PcdGet32 (PcdProgressCodeOsLoaderStart)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Progress code for OS Loader StartImage.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update OS Loader StartImage Start for UEFI boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Progress code for ExitBootServices.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Update ExitBootServicesExit for UEFI boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesExit = GetTimeInNanoSecond (GetPerformanceCounter ());
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Unregister boot time report status code listener.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync } else if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Append one or more Boot records
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Append Boot records before FPDT ACPI table is installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootRecordSize + Data->Size > mBootRecordMaxSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootRecordBuffer = ReallocatePool (mBootRecordSize, mBootRecordSize + Data->Size + EXTENSION_RECORD_SIZE, mBootRecordBuffer);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootRecordMaxSize = mBootRecordSize + Data->Size + EXTENSION_RECORD_SIZE;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save boot record into the temp memory space.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (mBootRecordBuffer + mBootRecordSize, Data + 1, Data->Size);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Append Boot records after FPDT ACPI table is installed.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync if (mBootRecordSize + Data->Size > mBootRecordMaxSize) {
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // No enough space to save boot record.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Save boot record into BootPerformance table
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync CopyMem (mBootRecordBuffer + mBootRecordSize, Data + 1, Data->Size);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mAcpiBootPerformanceTable->Header.Length = mBootRecordSize;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Ignore else progress code.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync The module Entry Point of the Firmware Performance Data Table DXE driver.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] ImageHandle The firmware allocated handle for the EFI image.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @param[in] SystemTable A pointer to the EFI System Table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval EFI_SUCCESS The entry point is executed successfully.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync @retval Other Some error occurs when executing this entry point.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Get Report Status Code Handler Protocol.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Register report status code listener for OS Loader load and start.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Register the notify function to update FPDT on ExitBootServices Event.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create ready to boot event to install ACPI FPDT table.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Create legacy boot event to log OsLoaderStartImageStart for legacy boot.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // Retrieve GUID HOB data that contains the ResetEnd.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync GuidHob = GetFirstGuidHob (&gEfiFirmwarePerformanceGuid);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync Performance = (FIRMWARE_SEC_PERFORMANCE *) GET_GUID_HOB_DATA (GuidHob);
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync mBootPerformanceTableTemplate.BasicBoot.ResetEnd = Performance->ResetEnd;
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync // SEC Performance Data Hob not found, ResetEnd in ACPI FPDT table will be 0.
4fd606d1f5abe38e1f42c38de1d2e895166bd0f4vboxsync DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n"));