From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001 From: Angelos Mouzakitis Date: Tue, 10 Oct 2023 14:33:42 +0000 Subject: Add submodule dependency files Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec --- .../FirmwarePerformanceDxe.c | 677 +++++++++++++++++++++ .../FirmwarePerformanceDxe.inf | 83 +++ .../FirmwarePerformanceDxe.uni | 18 + .../FirmwarePerformanceDxeExtra.uni | 14 + 4 files changed, 792 insertions(+) create mode 100644 roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c create mode 100644 roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf create mode 100644 roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.uni create mode 100644 roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxeExtra.uni (limited to 'roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe') diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c new file mode 100644 index 000000000..61a7704b3 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c @@ -0,0 +1,677 @@ +/** @file + This module install ACPI Firmware Performance Data Table (FPDT). + + This module register report status code listener to collect performance data + for Firmware Basic Boot Performance Record and other boot performance records, + and install FPDT to ACPI table. + + Copyright (c) 2011 - 2019, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SMM_BOOT_RECORD_COMM_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof(SMM_BOOT_RECORD_COMMUNICATE)) + +EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL; + +BOOLEAN mLockBoxReady = FALSE; +EFI_EVENT mReadyToBootEvent; +EFI_EVENT mLegacyBootEvent; +static EFI_EVENT mExitBootServicesEvent; +UINTN mFirmwarePerformanceTableTemplateKey = 0; +BOOLEAN mDxeCoreReportStatusCodeEnable = FALSE; + +BOOT_PERFORMANCE_TABLE *mAcpiBootPerformanceTable = NULL; +BOOT_PERFORMANCE_TABLE *mReceivedAcpiBootPerformanceTable = NULL; +S3_PERFORMANCE_TABLE *mAcpiS3PerformanceTable = NULL; + +FIRMWARE_PERFORMANCE_TABLE mFirmwarePerformanceTableTemplate = { + { + EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE, + sizeof (FIRMWARE_PERFORMANCE_TABLE), + EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION, // Revision + 0x00, // Checksum will be updated at runtime + // + // It is expected that these values will be updated at EntryPoint. + // + {0x00}, // OEM ID is a 6 bytes long field + 0x00, // OEM Table ID(8 bytes long) + 0x00, // OEM Revision + 0x00, // Creator ID + 0x00, // Creator Revision + }, + // + // Firmware Basic Boot Performance Table Pointer Record. + // + { + { + EFI_ACPI_5_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER , // Type + sizeof (EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD), // Length + EFI_ACPI_5_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER // Revision + }, + 0, // Reserved + 0 // BootPerformanceTablePointer will be updated at runtime. + }, + // + // S3 Performance Table Pointer Record. + // + { + { + EFI_ACPI_5_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER, // Type + sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD), // Length + EFI_ACPI_5_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER // Revision + }, + 0, // Reserved + 0 // S3PerformanceTablePointer will be updated at runtime. + } +}; + +BOOT_PERFORMANCE_TABLE mBootPerformanceTableTemplate = { + { + EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE, + sizeof (BOOT_PERFORMANCE_TABLE) + }, + { + { + EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT, // Type + sizeof (EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD), // Length + EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT // Revision + }, + 0, // Reserved + // + // These values will be updated at runtime. + // + 0, // ResetEnd + 0, // OsLoaderLoadImageStart + 0, // OsLoaderStartImageStart + 0, // ExitBootServicesEntry + 0 // ExitBootServicesExit + } +}; + +S3_PERFORMANCE_TABLE mS3PerformanceTableTemplate = { + { + EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE, + sizeof (S3_PERFORMANCE_TABLE) + }, + { + { + EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME, // Type + sizeof (EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD), // Length + EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME // Revision + }, + // + // These values will be updated by Firmware Performance PEIM. + // + 0, // ResumeCount + 0, // FullResume + 0 // AverageResume + }, + { + { + EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND, // Type + sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD), // Length + EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND // Revision + }, + // + // These values will be updated bye Firmware Performance SMM driver. + // + 0, // SuspendStart + 0 // SuspendEnd + } +}; + +/** + This function calculates and updates an UINT8 checksum. + + @param[in] Buffer Pointer to buffer to checksum + @param[in] Size Number of bytes to checksum + +**/ +VOID +FpdtAcpiTableChecksum ( + IN UINT8 *Buffer, + IN UINTN Size + ) +{ + UINTN ChecksumOffset; + + ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum); + + // + // Set checksum to 0 first. + // + Buffer[ChecksumOffset] = 0; + + // + // Update checksum value. + // + Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size); +} + +/** + Callback function upon VariableArchProtocol and LockBoxProtocol + to allocate S3 performance table memory and save the pointer to LockBox. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. +**/ +VOID +EFIAPI +FpdtAllocateS3PerformanceTableMemory ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + VOID *Interface; + FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable; + UINTN Size; + EFI_PHYSICAL_ADDRESS S3PerformanceTablePointer; + + if (mLockBoxReady && (mAcpiS3PerformanceTable != NULL)) { + // + // The memory for S3 performance table should have been ready, + // and the pointer should have been saved to LockBox, just return. + // + return; + } + + if (!mLockBoxReady) { + Status = gBS->LocateProtocol (&gEfiLockBoxProtocolGuid, NULL, &Interface); + if (!EFI_ERROR (Status)) { + // + // LockBox services has been ready. + // + mLockBoxReady = TRUE; + } + } + + if (mAcpiS3PerformanceTable == NULL) { + Status = gBS->LocateProtocol (&gEfiVariableArchProtocolGuid, NULL, &Interface); + if (!EFI_ERROR (Status)) { + // + // Try to allocate the same runtime buffer as last time boot. + // + ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable)); + Size = sizeof (PerformanceVariable); + Status = gRT->GetVariable ( + EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, + &gEfiFirmwarePerformanceGuid, + NULL, + &Size, + &PerformanceVariable + ); + if (!EFI_ERROR (Status)) { + Status = gBS->AllocatePages ( + AllocateAddress, + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE)), + &PerformanceVariable.S3PerformanceTablePointer + ); + if (!EFI_ERROR (Status)) { + mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.S3PerformanceTablePointer; + } + } + if (mAcpiS3PerformanceTable == NULL) { + // + // Fail to allocate at specified address, continue to allocate at any address. + // + mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) AllocatePeiAccessiblePages ( + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE)) + ); + } + DEBUG ((EFI_D_INFO, "FPDT: ACPI S3 Performance Table address = 0x%x\n", mAcpiS3PerformanceTable)); + if (mAcpiS3PerformanceTable != NULL) { + CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate, sizeof (mS3PerformanceTableTemplate)); + } + } + } + + if (mLockBoxReady && (mAcpiS3PerformanceTable != NULL)) { + // + // If LockBox services has been ready and memory for FPDT S3 performance table has been allocated, + // save the pointer to LockBox for use in S3 resume. + // + S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable; + Status = SaveLockBox ( + &gFirmwarePerformanceS3PointerGuid, + &S3PerformanceTablePointer, + sizeof (EFI_PHYSICAL_ADDRESS) + ); + ASSERT_EFI_ERROR (Status); + } +} + +/** + Install ACPI Firmware Performance Data Table (FPDT). + + @return Status code. + +**/ +EFI_STATUS +InstallFirmwarePerformanceDataTable ( + VOID + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; + UINTN BootPerformanceDataSize; + FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable; + UINTN Size; + + // + // Get AcpiTable Protocol. + // + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol); + if (EFI_ERROR (Status)) { + return Status; + } + + if (mReceivedAcpiBootPerformanceTable != NULL) { + mAcpiBootPerformanceTable = mReceivedAcpiBootPerformanceTable; + mAcpiBootPerformanceTable->BasicBoot.ResetEnd = mBootPerformanceTableTemplate.BasicBoot.ResetEnd; + } else { + // + // Try to allocate the same runtime buffer as last time boot. + // + BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE); + ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable)); + Size = sizeof (PerformanceVariable); + Status = gRT->GetVariable ( + EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, + &gEfiFirmwarePerformanceGuid, + NULL, + &Size, + &PerformanceVariable + ); + if (!EFI_ERROR (Status)) { + Status = gBS->AllocatePages ( + AllocateAddress, + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES (BootPerformanceDataSize), + &PerformanceVariable.BootPerformanceTablePointer + ); + if (!EFI_ERROR (Status)) { + mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.BootPerformanceTablePointer; + } + } + if (mAcpiBootPerformanceTable == NULL) { + // + // Fail to allocate at specified address, continue to allocate at any address. + // + mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) AllocatePeiAccessiblePages ( + EfiReservedMemoryType, + EFI_SIZE_TO_PAGES (BootPerformanceDataSize) + ); + } + DEBUG ((DEBUG_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable)); + if (mAcpiBootPerformanceTable == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // + // Fill Basic Boot record to Boot Performance Table. + // + CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate)); + } + BootPerformanceDataSize = mAcpiBootPerformanceTable->Header.Length; + + // + // Save Boot Performance Table address to Variable for use in S4 resume. + // + PerformanceVariable.BootPerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiBootPerformanceTable; + // + // Update Boot Performance Table Pointer in template. + // + mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable; + + // + // Save S3 Performance Table address to Variable for use in S4 resume. + // + PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable; + // + // Update S3 Performance Table Pointer in template. + // + mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) (UINTN) mAcpiS3PerformanceTable; + // + // Save Runtime Performance Table pointers to Variable. + // Don't check SetVariable return status. It doesn't impact FPDT table generation. + // + gRT->SetVariable ( + EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, + &gEfiFirmwarePerformanceGuid, + EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, + sizeof (PerformanceVariable), + &PerformanceVariable + ); + + // + // Publish Firmware Performance Data Table. + // + FpdtAcpiTableChecksum ((UINT8 *) &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length); + Status = AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + &mFirmwarePerformanceTableTemplate, + mFirmwarePerformanceTableTemplate.Header.Length, + &mFirmwarePerformanceTableTemplateKey + ); + if (EFI_ERROR (Status)) { + if (mAcpiBootPerformanceTable != NULL) { + FreePages (mAcpiBootPerformanceTable, EFI_SIZE_TO_PAGES (BootPerformanceDataSize)); + } + if (mAcpiS3PerformanceTable != NULL) { + FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE))); + } + mAcpiBootPerformanceTable = NULL; + mAcpiS3PerformanceTable = NULL; + return Status; + } + return EFI_SUCCESS; +} + +/** + Report status code listener of FPDT. This is used to collect performance data + for OsLoaderLoadImageStart and OsLoaderStartImageStart in FPDT. + + @param[in] CodeType Indicates the type of status code being reported. + @param[in] Value Describes the current status of a hardware or software entity. + This included information about the class and subclass that is used to + classify the entity as well as an operation. + @param[in] Instance The enumeration of a hardware or software entity within + the system. Valid instance numbers start with 1. + @param[in] CallerId This optional parameter may be used to identify the caller. + This parameter allows the status code driver to apply different rules to + different callers. + @param[in] Data This optional parameter may be used to pass additional data. + + @retval EFI_SUCCESS Status code is what we expected. + @retval EFI_UNSUPPORTED Status code not supported. + +**/ +EFI_STATUS +EFIAPI +FpdtStatusCodeListenerDxe ( + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN UINT32 Instance, + IN EFI_GUID *CallerId, + IN EFI_STATUS_CODE_DATA *Data + ) +{ + EFI_STATUS Status; + + // + // Check whether status code is what we are interested in. + // + if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) { + return EFI_UNSUPPORTED; + } + + if (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)) { + // + // DxeCore ReportStatusCode Enable so that the capability can be supported. + // + mDxeCoreReportStatusCodeEnable = TRUE; + } + + Status = EFI_SUCCESS; + if (Value == PcdGet32 (PcdProgressCodeOsLoaderLoad)) { + // + // Progress code for OS Loader LoadImage. + // + if (mAcpiBootPerformanceTable == NULL) { + return Status; + } + + // + // Update OS Loader LoadImage Start for UEFI boot. + // + mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart = GetTimeInNanoSecond (GetPerformanceCounter ()); + } else if (Value == PcdGet32 (PcdProgressCodeOsLoaderStart)) { + // + // Progress code for OS Loader StartImage. + // + if (mAcpiBootPerformanceTable == NULL) { + return Status; + } + + // + // Update OS Loader StartImage Start for UEFI boot. + // + mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ()); + } else if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)) { + // + // Unregister boot time report status code listener. + // + mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe); + + // + // Progress code for ExitBootServices. + // + if (mAcpiBootPerformanceTable == NULL) { + return Status; + } + + // + // Update ExitBootServicesExit for UEFI boot. + // + mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesExit = GetTimeInNanoSecond (GetPerformanceCounter ()); + } else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)) { + if (mAcpiBootPerformanceTable == NULL) { + // + // Firmware Performance Data Table not installed, do nothing. + // + return Status; + } + + // + // Update Firmware Basic Boot Performance Record for legacy boot. + // + mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ()); + + // + // Dump FPDT Boot Performance record. + // + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd)); + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = 0\n")); + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart)); + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = 0\n")); + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesExit = 0\n")); + } else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)) { + if (mAcpiBootPerformanceTable == NULL) { + // + // ACPI Firmware Performance Data Table not installed yet, install it now. + // + InstallFirmwarePerformanceDataTable (); + } + } else if (Data != NULL && CompareGuid (&Data->Type, &gEdkiiFpdtExtendedFirmwarePerformanceGuid)) { + // + // Get the Boot performance table and then install it to ACPI table. + // + CopyMem (&mReceivedAcpiBootPerformanceTable, Data + 1, Data->Size); + } else if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) { + DEBUG ((DEBUG_ERROR, "FpdtStatusCodeListenerDxe: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableDxe\n")); + Status = EFI_UNSUPPORTED; + } else { + // + // Ignore else progress code. + // + Status = EFI_UNSUPPORTED; + } + + return Status; +} + + +/** + Notify function for event EVT_SIGNAL_EXIT_BOOT_SERVICES. This is used to record + performance data for ExitBootServicesEntry in FPDT. + + @param[in] Event The Event that is being processed. + @param[in] Context The Event Context. + +**/ +VOID +EFIAPI +FpdtExitBootServicesEventNotify ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + if (!mDxeCoreReportStatusCodeEnable) { + // + // When DxeCore Report Status Code is disabled, + // Unregister boot time report status code listener at ExitBootService Event. + // + mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe); + } + + if (mAcpiBootPerformanceTable == NULL) { + // + // Firmware Performance Data Table not installed, do nothing. + // + return ; + } + + // + // Update Firmware Basic Boot Performance Record for UEFI boot. + // + mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = GetTimeInNanoSecond (GetPerformanceCounter ()); + + // + // Dump FPDT Boot Performance record. + // + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd)); + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart)); + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart)); + DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry)); + // + // ExitBootServicesExit will be updated later, so don't dump it here. + // +} + +/** + The module Entry Point of the Firmware Performance Data Table DXE driver. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval Other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +FirmwarePerformanceDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HOB_GUID_TYPE *GuidHob; + FIRMWARE_SEC_PERFORMANCE *Performance; + VOID *Registration; + UINT64 OemTableId; + + CopyMem ( + mFirmwarePerformanceTableTemplate.Header.OemId, + PcdGetPtr (PcdAcpiDefaultOemId), + sizeof (mFirmwarePerformanceTableTemplate.Header.OemId) + ); + OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId); + CopyMem (&mFirmwarePerformanceTableTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64)); + mFirmwarePerformanceTableTemplate.Header.OemRevision = PcdGet32 (PcdAcpiDefaultOemRevision); + mFirmwarePerformanceTableTemplate.Header.CreatorId = PcdGet32 (PcdAcpiDefaultCreatorId); + mFirmwarePerformanceTableTemplate.Header.CreatorRevision = PcdGet32 (PcdAcpiDefaultCreatorRevision); + + // + // Get Report Status Code Handler Protocol. + // + Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol); + ASSERT_EFI_ERROR (Status); + + // + // Register report status code listener for OS Loader load and start. + // + Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL); + ASSERT_EFI_ERROR (Status); + + // + // Register the notify function to update FPDT on ExitBootServices Event. + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FpdtExitBootServicesEventNotify, + NULL, + &gEfiEventExitBootServicesGuid, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Retrieve GUID HOB data that contains the ResetEnd. + // + GuidHob = GetFirstGuidHob (&gEfiFirmwarePerformanceGuid); + if (GuidHob != NULL) { + Performance = (FIRMWARE_SEC_PERFORMANCE *) GET_GUID_HOB_DATA (GuidHob); + mBootPerformanceTableTemplate.BasicBoot.ResetEnd = Performance->ResetEnd; + } else { + // + // SEC Performance Data Hob not found, ResetEnd in ACPI FPDT table will be 0. + // + DEBUG ((DEBUG_WARN, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n")); + } + + if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) { + // + // Register callback function upon VariableArchProtocol and LockBoxProtocol + // to allocate S3 performance table memory and save the pointer to LockBox. + // + EfiCreateProtocolNotifyEvent ( + &gEfiVariableArchProtocolGuid, + TPL_CALLBACK, + FpdtAllocateS3PerformanceTableMemory, + NULL, + &Registration + ); + EfiCreateProtocolNotifyEvent ( + &gEfiLockBoxProtocolGuid, + TPL_CALLBACK, + FpdtAllocateS3PerformanceTableMemory, + NULL, + &Registration + ); + } else { + // + // Exclude S3 Performance Table Pointer from FPDT table template. + // + mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD); + } + + return EFI_SUCCESS; +} diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf new file mode 100644 index 000000000..1debb0193 --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf @@ -0,0 +1,83 @@ +## @file +# This module installs ACPI Firmware Performance Data Table (FPDT). +# +# This module registers report status code listener to collect performance data +# for Firmware Basic Boot Performance Record and other boot performance records, +# and install FPDT to ACPI table. +# +# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FirmwarePerformanceDxe + MODULE_UNI_FILE = FirmwarePerformanceDxe.uni + FILE_GUID = 00160F8D-2B35-4df2-BBE0-B272A8D631F0 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FirmwarePerformanceDxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + FirmwarePerformanceDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + BaseLib + DebugLib + DxeServicesLib + TimerLib + BaseMemoryLib + MemoryAllocationLib + PcdLib + HobLib + LockBoxLib + UefiLib + +[Protocols] + gEfiAcpiTableProtocolGuid ## CONSUMES + gEfiRscHandlerProtocolGuid ## CONSUMES + gEfiVariableArchProtocolGuid ## CONSUMES + gEfiLockBoxProtocolGuid ## CONSUMES + +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + ## SOMETIMES_CONSUMES ## HOB + ## SOMETIMES_CONSUMES ## Variable:L"FirmwarePerformance" + ## PRODUCES ## Variable:L"FirmwarePerformance" + ## SOMETIMES_CONSUMES ## UNDEFINED # Used to do smm communication + ## SOMETIMES_CONSUMES ## UNDEFINED # StatusCode Data + gEfiFirmwarePerformanceGuid + gEdkiiFpdtExtendedFirmwarePerformanceGuid ## SOMETIMES_CONSUMES ## UNDEFINED # StatusCode Data + gFirmwarePerformanceS3PointerGuid ## PRODUCES ## UNDEFINED # SaveLockBox + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderStart ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId ## CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision ## CONSUMES + +[FeaturePcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwarePerformanceDataTableS3Support ## CONSUMES + +[Depex] + gEfiRscHandlerProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + FirmwarePerformanceDxeExtra.uni diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.uni b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.uni new file mode 100644 index 000000000..a27b2cefa --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.uni @@ -0,0 +1,18 @@ +// /** @file +// This module installs ACPI Firmware Performance Data Table (FPDT). +// +// This module registers report status code listener to collect performance data +// for Firmware Basic Boot Performance Record and other boot performance records, +// and install FPDT to ACPI table. +// +// Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Installs ACPI Firmware Performance Data Table (FPDT)" + +#string STR_MODULE_DESCRIPTION #language en-US "This module registers report status code listener to collect performance data for Firmware Basic Boot Performance Record and other boot performance records, and installs FPDT to the ACPI table." + diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxeExtra.uni b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxeExtra.uni new file mode 100644 index 000000000..02e307e1f --- /dev/null +++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxeExtra.uni @@ -0,0 +1,14 @@ +// /** @file +// FirmwarePerformanceDxe Localized Strings and Content +// +// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"ACPI Firmware Performance DXE Driver" + + -- cgit