aboutsummaryrefslogtreecommitdiffstats
path: root/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm
diff options
context:
space:
mode:
authorAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
committerAngelos Mouzakitis <a.mouzakitis@virtualopensystems.com>2023-10-10 14:33:42 +0000
commitaf1a266670d040d2f4083ff309d732d648afba2a (patch)
tree2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm
parente02cda008591317b1625707ff8e115a4841aa889 (diff)
Add submodule dependency filesHEADmaster
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm')
-rw-r--r--roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c318
-rw-r--r--roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf67
-rw-r--r--roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.uni17
-rw-r--r--roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmmExtra.uni14
4 files changed, 416 insertions, 0 deletions
diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
new file mode 100644
index 000000000..d6c6e7693
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
@@ -0,0 +1,318 @@
+/** @file
+ This module collects performance data for SMM driver boot records and S3 Suspend Performance Record.
+
+ This module registers report status code listener to collect performance data
+ for SMM driver boot records and S3 Suspend Performance Record.
+
+ Caution: This module requires additional review when modified.
+ This driver will have external input - communicate buffer in SMM mode.
+ This external input must be validated carefully to avoid security issue like
+ buffer overflow, integer overflow.
+
+ FpdtSmiHandler() will receive untrusted input and do basic validation.
+
+ Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiSmm.h>
+
+#include <Protocol/SmmReportStatusCodeHandler.h>
+
+#include <Guid/FirmwarePerformance.h>
+
+#include <Library/SmmServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/LockBoxLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/SmmMemLib.h>
+
+SMM_BOOT_PERFORMANCE_TABLE *mSmmBootPerformanceTable = NULL;
+
+EFI_SMM_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
+UINT64 mSuspendStartTime = 0;
+BOOLEAN mS3SuspendLockBoxSaved = FALSE;
+UINT32 mBootRecordSize = 0;
+UINT8 *mBootRecordBuffer = NULL;
+
+SPIN_LOCK mSmmFpdtLock;
+BOOLEAN mSmramIsOutOfResource = FALSE;
+
+/**
+ Report status code listener for SMM. This is used to record the performance
+ data for S3 Suspend Start and S3 Suspend End 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
+FpdtStatusCodeListenerSmm (
+ 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;
+ UINT64 CurrentTime;
+ EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD S3SuspendRecord;
+
+ //
+ // Check whether status code is what we are interested in.
+ //
+ if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Collect one or more Boot records in boot time
+ //
+ if (Data != NULL && CompareGuid (&Data->Type, &gEdkiiFpdtExtendedFirmwarePerformanceGuid)) {
+ AcquireSpinLock (&mSmmFpdtLock);
+ //
+ // Get the boot performance data.
+ //
+ CopyMem (&mSmmBootPerformanceTable, Data + 1, Data->Size);
+ mBootRecordBuffer = ((UINT8 *) (mSmmBootPerformanceTable)) + sizeof (SMM_BOOT_PERFORMANCE_TABLE);
+
+ ReleaseSpinLock (&mSmmFpdtLock);
+ return EFI_SUCCESS;
+ }
+
+ if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {
+ DEBUG ((DEBUG_ERROR, "FpdtStatusCodeListenerSmm: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableSmm\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((Value != PcdGet32 (PcdProgressCodeS3SuspendStart)) &&
+ (Value != PcdGet32 (PcdProgressCodeS3SuspendEnd))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Retrieve current time.
+ //
+ CurrentTime = GetTimeInNanoSecond (GetPerformanceCounter ());
+
+ if (Value == PcdGet32 (PcdProgressCodeS3SuspendStart)) {
+ //
+ // S3 Suspend started, record the performance data and return.
+ //
+ mSuspendStartTime = CurrentTime;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // We are going to S3 sleep, record S3 Suspend End performance data.
+ //
+ S3SuspendRecord.SuspendStart = mSuspendStartTime;
+ S3SuspendRecord.SuspendEnd = CurrentTime;
+
+ //
+ // Save S3 suspend performance data to lock box, it will be used by Firmware Performance PEIM.
+ //
+ if (!mS3SuspendLockBoxSaved) {
+ Status = SaveLockBox (
+ &gEfiFirmwarePerformanceGuid,
+ &S3SuspendRecord,
+ sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mS3SuspendLockBoxSaved = TRUE;
+ } else {
+ Status = UpdateLockBox (
+ &gEfiFirmwarePerformanceGuid,
+ 0,
+ &S3SuspendRecord,
+ sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD)
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Communication service SMI Handler entry.
+
+ This SMI handler provides services for report SMM boot records.
+
+ Caution: This function may receive untrusted input.
+ Communicate buffer and buffer size are external input, so this function will do basic validation.
+
+ @param[in] DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().
+ @param[in] RegisterContext Points to an optional handler context which was specified when the
+ handler was registered.
+ @param[in, out] CommBuffer A pointer to a collection of data in memory that will
+ be conveyed from a non-SMM environment into an SMM environment.
+ @param[in, out] CommBufferSize The size of the CommBuffer.
+
+ @retval EFI_SUCCESS The interrupt was handled and quiesced. No other handlers
+ should still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED The interrupt has been quiesced but other handlers should
+ still be called.
+ @retval EFI_WARN_INTERRUPT_SOURCE_PENDING The interrupt is still pending and other handlers should still
+ be called.
+ @retval EFI_INTERRUPT_PENDING The interrupt could not be quiesced.
+
+**/
+EFI_STATUS
+EFIAPI
+FpdtSmiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *RegisterContext,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ )
+{
+ EFI_STATUS Status;
+ SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
+ UINTN BootRecordOffset;
+ UINTN BootRecordSize;
+ VOID *BootRecordData;
+ UINTN TempCommBufferSize;
+
+ //
+ // If input is invalid, stop processing this SMI
+ //
+ if (CommBuffer == NULL || CommBufferSize == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ TempCommBufferSize = *CommBufferSize;
+
+ if(TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
+ return EFI_SUCCESS;
+ }
+
+ if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM communication data buffer in SMRAM or overflow!\n"));
+ return EFI_SUCCESS;
+ }
+
+ SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)CommBuffer;
+
+ Status = EFI_SUCCESS;
+
+ switch (SmmCommData->Function) {
+ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE :
+ if (mSmmBootPerformanceTable != NULL) {
+ mBootRecordSize = mSmmBootPerformanceTable->Header.Length - sizeof (SMM_BOOT_PERFORMANCE_TABLE);
+ }
+ SmmCommData->BootRecordSize = mBootRecordSize;
+ break;
+
+ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :
+ Status = EFI_UNSUPPORTED;
+ break;
+
+ case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET :
+ BootRecordOffset = SmmCommData->BootRecordOffset;
+ BootRecordData = SmmCommData->BootRecordData;
+ BootRecordSize = SmmCommData->BootRecordSize;
+ if (BootRecordData == NULL || BootRecordOffset >= mBootRecordSize) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ //
+ // Sanity check
+ //
+ if (BootRecordSize > mBootRecordSize - BootRecordOffset) {
+ BootRecordSize = mBootRecordSize - BootRecordOffset;
+ }
+ SmmCommData->BootRecordSize = BootRecordSize;
+ if (!SmmIsBufferOutsideSmmValid ((UINTN)BootRecordData, BootRecordSize)) {
+ DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM Data buffer in SMRAM or overflow!\n"));
+ Status = EFI_ACCESS_DENIED;
+ break;
+ }
+
+ CopyMem (
+ (UINT8*)BootRecordData,
+ mBootRecordBuffer + BootRecordOffset,
+ BootRecordSize
+ );
+ break;
+
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ SmmCommData->ReturnStatus = Status;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The module Entry Point of the Firmware Performance Data Table SMM 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
+FirmwarePerformanceSmmEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ //
+ // Initialize spin lock
+ //
+ InitializeSpinLock (&mSmmFpdtLock);
+
+ //
+ // Get SMM Report Status Code Handler Protocol.
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmRscHandlerProtocolGuid,
+ NULL,
+ (VOID **) &mRscHandlerProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register report status code listener for BootRecords and S3 Suspend Start and End.
+ //
+ Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerSmm);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register SMI handler.
+ //
+ Handle = NULL;
+ Status = gSmst->SmiHandlerRegister (FpdtSmiHandler, &gEfiFirmwarePerformanceGuid, &Handle);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf
new file mode 100644
index 000000000..618cbd56c
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.inf
@@ -0,0 +1,67 @@
+## @file
+# This module collects performance data for SMM driver boot records and S3 Suspend Performance Record.
+#
+# This module registers report status code listener to collect performance data
+# for SMM boot performance records and S3 Suspend Performance Record.
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FirmwarePerformanceSmm
+ MODULE_UNI_FILE = FirmwarePerformanceSmm.uni
+ FILE_GUID = 044310AB-77FD-402a-AF1A-87D4120E7329
+ MODULE_TYPE = DXE_SMM_DRIVER
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ ENTRY_POINT = FirmwarePerformanceSmmEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ FirmwarePerformanceSmm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ SmmServicesTableLib
+ BaseLib
+ DebugLib
+ TimerLib
+ LockBoxLib
+ PcdLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ SynchronizationLib
+ SmmMemLib
+
+[Protocols]
+ gEfiSmmRscHandlerProtocolGuid ## CONSUMES
+
+[Guids]
+ ## SOMETIMES_PRODUCES ## UNDEFINED # SaveLockBox
+ ## PRODUCES ## UNDEFINED # SmiHandlerRegister
+ ## SOMETIMES_CONSUMES ## UNDEFINED # StatusCode Data
+ gEfiFirmwarePerformanceGuid
+ gEdkiiFpdtExtendedFirmwarePerformanceGuid ## SOMETIMES_PRODUCES ## UNDEFINED # StatusCode Data
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendEnd ## CONSUMES
+
+[Depex]
+ gEfiSmmRscHandlerProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ FirmwarePerformanceSmmExtra.uni
diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.uni b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.uni
new file mode 100644
index 000000000..dc940a78f
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.uni
@@ -0,0 +1,17 @@
+// /** @file
+// This module collects performance data for SMM driver boot records and S3 Suspend Performance Record.
+//
+// This module registers report status code listener to collect performance data
+// for SMM boot performance records and S3 Suspend Performance Record.
+//
+// Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Collects performance data for SMM driver boot records and S3 Suspend Performance Record"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module registers report status code listener to collect performance data for SMM boot performance records and S3 Suspend Performance Record."
+
diff --git a/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmmExtra.uni b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmmExtra.uni
new file mode 100644
index 000000000..edb57b528
--- /dev/null
+++ b/roms/edk2/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmmExtra.uni
@@ -0,0 +1,14 @@
+// /** @file
+// FirmwarePerformanceSmm Localized Strings and Content
+//
+// Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"SMM Firmware Performance Driver"
+
+