2011-12-01 02:57:27 +01:00
/** @file
2020-12-17 23:15:13 +01:00
This module collects performance data for MM driver boot records and S3 Suspend Performance Record .
2011-12-01 02:57:27 +01:00
2012-05-08 05:09:54 +02:00
This module registers report status code listener to collect performance data
2020-12-17 23:15:13 +01:00
for MM driver boot records and S3 Suspend Performance Record .
2011-12-01 02:57:27 +01:00
2012-06-27 07:08:49 +02:00
Caution : This module requires additional review when modified .
2020-12-17 23:15:13 +01:00
This driver will have external input - communicate buffer in MM mode .
2012-06-27 07:08:49 +02:00
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 .
2021-06-28 13:50:22 +02:00
Copyright ( c ) 2011 - 2021 , Intel Corporation . All rights reserved . < BR >
2019-04-04 01:05:13 +02:00
SPDX - License - Identifier : BSD - 2 - Clause - Patent
2011-12-01 02:57:27 +01:00
* */
2020-12-17 23:15:13 +01:00
# include <PiMm.h>
2011-12-01 02:57:27 +01:00
2020-12-17 23:15:13 +01:00
# include <Protocol/MmReportStatusCodeHandler.h>
2011-12-01 02:57:27 +01:00
# include <Guid/FirmwarePerformance.h>
2020-12-17 23:15:13 +01:00
# include <Library/MmServicesTableLib.h>
2011-12-01 02:57:27 +01:00
# include <Library/BaseLib.h>
# include <Library/DebugLib.h>
# include <Library/TimerLib.h>
# include <Library/LockBoxLib.h>
# include <Library/PcdLib.h>
2012-05-08 05:09:54 +02:00
# include <Library/BaseMemoryLib.h>
2020-12-17 23:15:13 +01:00
# include "FirmwarePerformanceCommon.h"
2012-05-08 05:09:54 +02:00
2020-12-17 23:15:13 +01:00
EFI_MM_RSC_HANDLER_PROTOCOL * mRscHandlerProtocol = NULL ;
2011-12-01 02:57:27 +01:00
UINT64 mSuspendStartTime = 0 ;
BOOLEAN mS3SuspendLockBoxSaved = FALSE ;
/**
2020-12-17 23:15:13 +01:00
Report status code listener for MM . This is used to record the performance
2011-12-01 02:57:27 +01:00
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
2020-12-17 23:15:13 +01:00
FpdtStatusCodeListenerMm (
2011-12-01 02:57:27 +01:00
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 ;
}
2018-06-27 15:08:52 +02:00
2018-04-10 07:51:08 +02:00
if ( ( Data ! = NULL ) & & CompareGuid ( & Data - > Type , & gEfiFirmwarePerformanceGuid ) ) {
2020-12-17 23:15:13 +01:00
DEBUG ( ( DEBUG_ERROR , " FpdtStatusCodeListenerMm: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableMm \n " ) ) ;
2018-04-10 07:51:08 +02:00
return EFI_UNSUPPORTED ;
}
2011-12-01 02:57:27 +01:00
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 ;
}
/**
2020-12-17 23:15:13 +01:00
The module Entry Point of the Firmware Performance Data Table MM driver .
2011-12-01 02:57:27 +01:00
@ retval EFI_SUCCESS The entry point is executed successfully .
@ retval Other Some error occurs when executing this entry point .
* */
EFI_STATUS
2020-12-17 23:15:13 +01:00
FirmwarePerformanceCommonEntryPoint (
VOID
2011-12-01 02:57:27 +01:00
)
{
2012-05-08 05:09:54 +02:00
EFI_STATUS Status ;
2018-06-27 15:08:52 +02:00
2012-05-08 05:09:54 +02:00
//
2020-12-17 23:15:13 +01:00
// Get MM Report Status Code Handler Protocol.
2012-05-08 05:09:54 +02:00
//
2020-12-17 23:15:13 +01:00
Status = gMmst - > MmLocateProtocol (
& gEfiMmRscHandlerProtocolGuid ,
2012-05-08 05:09:54 +02:00
NULL ,
( VOID * * ) & mRscHandlerProtocol
) ;
ASSERT_EFI_ERROR ( Status ) ;
2011-12-01 02:57:27 +01:00
2012-05-08 05:09:54 +02:00
//
// Register report status code listener for BootRecords and S3 Suspend Start and End.
//
2020-12-17 23:15:13 +01:00
Status = mRscHandlerProtocol - > Register ( FpdtStatusCodeListenerMm ) ;
2012-05-08 05:09:54 +02:00
ASSERT_EFI_ERROR ( Status ) ;
2011-12-01 02:57:27 +01:00
2012-05-08 05:09:54 +02:00
return Status ;
2011-12-01 02:57:27 +01:00
}