SMI handler profile feature - jljusten/tianocore GitHub Wiki
The SMI handler profile feature was introduced to help a developer analyzes which SMI handlers are exposed in an given boot.
The SMI handler includes:
- The root SMI handler or GUID SMI handler which is registered by SmmCore.
- The hardware child SMI handler which is registered by SmmChildDispatcher.
The SMI handler profile information includes:
- The function name of SMI Handler.
- The Name of the dispatcher the handler is registered with
- Source file name, line number.
- SMI context, such as SWSMI number.
This wiki page focuses on how to enable SMI handler profile feature.
The PCD - PcdSmiHandlerProfilePropertyMask defined in MdeModulePkg.dec(https://github.com/tianocore/edk2/blob/master/MdeModulePkg/MdeModulePkg.dec) to control the behaviors of SMI handler profile feature.
## The mask is used to control SmiHandlerProfile behavior.<BR><BR>
# BIT0 - Enable SmiHandlerProfile.<BR>
# @Prompt SmiHandlerProfile Property.
# @Expression 0x80000002 | (gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask & 0xFE) == 0
gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|0|UINT8|0x00000108
After SMI handler profile feature is enabled by configuring PCDs above, SmmChildDispatcher driver should call SmiHandlerProfileRegisterHandler() to report SMI handler information. This API is defined in SmiHandlerProfileLib library class(https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Library/SmiHandlerProfileLib.h).
SmiHandlerProfileLib|MdeModulePkg/Library/SmmSmiHandlerProfileLib/SmmSmiHandlerProfileLib.inf
If SMI handler profile feature is disabled, the SmmChildDispatcher driver can link NULL instance.
SmiHandlerProfileLib|MdePkg/Library/SmiHandlerProfileLibNull/SmiHandlerProfileLibNull.inf
After SMI handler profile feature is enabled and the system boots to SHELL, SmiHandlerProfileInfo(https://github.com/tianocore/edk2/tree/master/MdeModulePkg/Application/SmiHandlerProfileInfo) application in MdeModulePkg can be used to dump the information, then SmiHandlerProfileSymbolGen.py(https://github.com/tianocore/edk2/blob/master/BaseTools/Scripts/SmiHandlerProfileSymbolGen.py) can be used to convert RVA address to symbols and convert GUID name to a user readable string. In Linux, SmiHandlerProfileSymbolGen.py will parse the debug information generated by the GCC compiler through “nm”. In Windows, SmiHandlerProfileSymbolGen.py will parse the PDB information generated by the MSVC compiler through Microsoft Visual Studio “DIA SDK”.
- Set PcdSmiHandlerProfilePropertyMask.
[PcdsFixedAtBuild]
gEfiMdeModulePkgTokenSpaceGuid.PcdSmiHandlerProfilePropertyMask|1
- Link correct SmiHandlerProfileLib instances in platform dsc.
[LibraryClasses]
SmiHandlerProfileLib|MdeModulePkg/Library/SmmSmiHandlerProfileLib/SmmSmiHandlerProfileLib.inf
- Update SmmChildDispatcher driver to report SMI handler via SmiHandlerProfileRegisterHandler().
diff --git a/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c diff --git a/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c b/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c
index c2f75f8..0a8239c 100644
--- a/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c
+++ b/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c
@@ -2,7 +2,7 @@
This driver is responsible for the registration of child drivers
and the abstraction of the QNC SMI sources.
-Copyright (c) 2013-2016 Intel Corporation.
+Copyright (c) 2013-2017 Intel Corporation.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@@ -23,6 +23,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include "QNCSmm.h"
#include "QNCSmmHelpers.h"
+#include <Library/SmiHandlerProfileLib.h>
+
//
// /////////////////////////////////////////////////////////////////////////////
// MODULE / GLOBAL DATA
@@ -331,6 +333,7 @@ Returns:
DATABASE_RECORD *Record;
QNC_SMM_QUALIFIED_PROTOCOL *Qualified;
INTN Index;
+ UINTN ContextSize;
//
// Check for invalid parameter
@@ -363,6 +366,7 @@ Returns:
// Perform linked list housekeeping
//
Record->Signature = DATABASE_RECORD_SIGNATURE;
+ ContextSize = 0;
switch (Qualified->Type) {
//
@@ -383,6 +387,7 @@ Returns:
InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
CopyMem (&Record->SrcDesc, &SX_SOURCE_DESC, sizeof (Record->SrcDesc));
+ ContextSize = sizeof(Record->ChildContext.Sx);
//
// use default clear source function
//
@@ -425,6 +430,7 @@ Returns:
InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
CopyMem (&Record->SrcDesc, &SW_SOURCE_DESC, sizeof (Record->SrcDesc));
Record->BufferSize = sizeof (EFI_SMM_SW_REGISTER_CONTEXT);
+ ContextSize = sizeof(Record->ChildContext.Sw);
//
// use default clear source function
//
@@ -434,6 +440,7 @@ Returns:
InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
CopyMem (&Record->SrcDesc, &GPI_SOURCE_DESC, sizeof (Record->SrcDesc));
+ ContextSize = sizeof(Record->ChildContext.Gpi);
//
// use default clear source function
//
@@ -450,6 +457,7 @@ Returns:
InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
CopyMem (&Record->SrcDesc, &QNCN_SOURCE_DESCS[Record->ChildContext.QNCn.Type], sizeof (Record->SrcDesc));
Record->ClearSource = QNCSmmQNCnClearSource;
+ ContextSize = sizeof(Record->ChildContext.QNCn);
break;
case PeriodicTimerType:
@@ -462,6 +470,7 @@ Returns:
InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
Record->BufferSize = sizeof (EFI_SMM_PERIODIC_TIMER_CONTEXT);
Record->ClearSource = QNCSmmPeriodicTimerClearSource;
+ ContextSize = sizeof(Record->ChildContext.PeriodicTimer);
break;
default:
@@ -488,6 +497,8 @@ Returns:
//
*DispatchHandle = (EFI_HANDLE) (&Record->Link);
+ SmiHandlerProfileRegisterHandler (Qualified->Guid, DispatchFunction, (UINTN)RETURN_ADDRESS (0), RegisterContext, ContextSize);
+
return EFI_SUCCESS;
Error:
@@ -522,6 +533,8 @@ Returns:
DATABASE_RECORD *RecordToDelete;
DATABASE_RECORD *RecordInDb;
LIST_ENTRY *LinkInDb;
+ QNC_SMM_QUALIFIED_PROTOCOL *Qualified;
+ UINTN ContextSize;
if (DispatchHandle == NULL) {
return EFI_INVALID_PARAMETER;
@@ -552,7 +565,31 @@ Returns:
}
if (SafeToDisable) {
QNCSmmDisableSource( &RecordToDelete->SrcDesc );
-}
+ }
+
+ Qualified = QUALIFIED_PROTOCOL_FROM_GENERIC (This);
+ switch (Qualified->Type) {
+ case SxType:
+ ContextSize = sizeof(RecordToDelete->ChildContext.Sx);
+ break;
+ case SwType:
+ ContextSize = sizeof(RecordToDelete->ChildContext.Sw);
+ break;
+ case GpiType:
+ ContextSize = sizeof(RecordToDelete->ChildContext.Gpi);
+ break;
+ case QNCnType:
+ ContextSize = sizeof(RecordToDelete->ChildContext.QNCn);
+ break;
+ case PeriodicTimerType:
+ ContextSize = sizeof(RecordToDelete->ChildContext.PeriodicTimer);
+ break;
+ default:
+ ASSERT(FALSE);
+ ContextSize = 0;
+ break;
+ }
+ SmiHandlerProfileUnregisterHandler (Qualified->Guid, RecordToDelete->Callback, RecordToDelete->CallbackContext, ContextSize);
FreePool (RecordToDelete);
diff --git a/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf b/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
index ed94825..23b806a 100644
--- a/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
+++ b/QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf
@@ -3,7 +3,7 @@
#
# This driver is responsible for the registration of child drivers
# and the abstraction of the ICH SMI sources.
-# Copyright (c) 2013-2015 Intel Corporation.
+# Copyright (c) 2013-2017 Intel Corporation.
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -66,6 +66,7 @@
DevicePathLib
S3IoLib
QNCAccessLib
+ SmiHandlerProfileLib
[Protocols]
gEfiSmmCpuProtocolGuid # PROTOCOL ALWAYS_CONSUMED
- Include SmiHandlerProfileInfo application in platform dsc.
[Components]
MdeModulePkg/Application/SmiHandlerProfileInfo/SmiHandlerProfileInfo.inf
NOTE: Please make sure SmmCommunicationBufferDxe driver is include in both dsc and fdf.
[Components]
MdeModulePkg/Universal/SmmCommunicationBufferDxe/SmmCommunicationBufferDxe.inf
- Boot system to shell, run SmiHandlerProfileInfo.efi to dump the profile information.
SmiHandlerProfileInfo.efi >a SmiHandlerProfileInfoTemp.txt
The sample SmiHandlerProfileInfoTemp.txt is like below.
<?xml version="1.0" encoding="utf-8"?>
<SmiHandlerProfile>
<ImageDatabase>
<!-- SMM image loaded -->
<Image Base="0xFFEB000" EntryPoint="0xFFEC159" FvFile="E94F54CD-81EB-47ED-AEC3-856F5DC157A9" Name="PiSmmCore" Size="0x14000">
<Pdb>c:\home\edkiigit\Build\Quark\DEBUG_VS2015x86\IA32\MdeModulePkg\Core\PiSmmCore\PiSmmCore\DEBUG\PiSmmCore.pdb</Pdb>
</Image>
<Image Base="0xFFDF000" EntryPoint="0xFFE0139" FvFile="A6885402-D022-4B0E-A509-4711B90F2A39" Name="ReportStatusCodeRouterSmm" Size="0x6000">
<Pdb>c:\home\edkiigit\Build\Quark\DEBUG_VS2015x86\IA32\MdeModulePkg\Universal\ReportStatusCodeRouter\Smm\ReportStatusCodeRouterSmm\DEBUG\ReportStatusCodeRouterSmm.pdb</Pdb>
</Image>
......
</ImageDatabase>
<SmiHandlerDatabase>
<!-- SMI Handler registered -->
<SmiHandlerCategory Name="RootSmi">
<!-- The root SMI Handler registered by SmmCore -->
<SmiEntry>
<SmiHandler>
<Module>QNCSmmDispatcher</Module>
<Handler Address="0xFF2C89B">
<RVA>0x189B</RVA>
</Handler>
<Caller Address="0xFF2C442">
<RVA>0x1442</RVA>
</Caller>
</SmiHandler>
</SmiEntry>
</SmiHandlerCategory>
<SmiHandlerCategory Name="GuidSmi">
<!-- The GUID SMI Handler registered by SmmCore -->
<SmiEntry HandlerType="ED32D533-99E6-4209-9CC0-2D72CDD998A7">
<SmiHandler>
<Module>VariableSmm</Module>
<Handler Address="0xFFCE6D8">
<RVA>0x16D8</RVA>
</Handler>
<Caller Address="0xFFCED12">
<RVA>0x1D12</RVA>
</Caller>
</SmiHandler>
</SmiEntry>
<SmiEntry HandlerType="2A3CFEBD-27E8-4D0A-8B79-D688C2A3E1C0">
<SmiHandler>
<Module>SmmLockBox</Module>
<Handler Address="0xFF4C527">
<RVA>0x1527</RVA>
</Handler>
<Caller Address="0xFF4C67C">
<RVA>0x167C</RVA>
</Caller>
</SmiHandler>
</SmiEntry>
......
</SmiHandlerCategory>
<SmiHandlerCategory Name="HardwareSmi">
<!-- The hardware SMI Handler registered by SmmChildDispatcher -->
<SmiEntry HandlerType="18A3C6DC-5EEA-48C8-A1C1-B53389F98999">
<SmiHandler SwSmi="0x1">
<Module>PiSmmCommunicationSmm</Module>
<Handler Address="0xFF1A2ED">
<RVA>0x12ED</RVA>
</Handler>
<Caller Address="0xFF1A489">
<RVA>0x1489</RVA>
</Caller>
</SmiHandler>
<SmiHandler SwSmi="0xA0">
<Module>AcpiSmmPlatform</Module>
<Handler Address="0xFF037B3">
<RVA>0x17B3</RVA>
</Handler>
<Caller Address="0xFF036CA">
<RVA>0x16CA</RVA>
</Caller>
</SmiHandler>
......
</SmiEntry>
<SmiEntry HandlerType="456D2859-A84B-4E47-A2EE-3276D886997D">
<SmiHandler SxPhase="SxEntry" SxType="SxS3">
<Module>AcpiSmmPlatform</Module>
<Handler Address="0xFF0383C">
<RVA>0x183C</RVA>
</Handler>
<Caller Address="0xFF03718">
<RVA>0x1718</RVA>
</Caller>
</SmiHandler>
......
</SmiEntry>
</SmiHandlerCategory>
</SmiHandlerDatabase>
</SmiHandlerProfile>
- Copy SmiHandlerProfileInfoTemp.txt to OS, run SmiHandlerProfileSymbolGen.py to convert RVA address to symbols and GUID to human readable string.
Note: In Windows, SmiHandlerProfileSymbolGen.py will parse the PDB information generated by the MSVC compiler through Microsoft Visual Studio “DIA SDK”, if you have no Dia2Dump.exe, you need to build out Dia2Dump.exe from source(for example, C:\Program Files (x86)\Microsoft Visual Studio 14.0\DIA SDK\Samples\DIA2Dump).
SmiHandlerProfileSymbolGen.py -i SmiHandlerProfileInfoTemp.txt -o SmiHandlerProfileInfoFinal.txt -g Guid.xref
The sample SmiHandlerProfileInfoFinal.txt is like below.
<?xml version="1.0" encoding="utf-8"?>
<SmiHandlerProfile>
<ImageDatabase>
<!-- SMM image loaded -->
<Image Base="0xFFEB000" EntryPoint="0xFFEC159" FvFile="E94F54CD-81EB-47ED-AEC3-856F5DC157A9" Name="PiSmmCore" Size="0x14000">
<Pdb>c:\home\edkiigit\Build\Quark\DEBUG_VS2015x86\IA32\MdeModulePkg\Core\PiSmmCore\PiSmmCore\DEBUG\PiSmmCore.pdb</Pdb>
</Image>
<Image Base="0xFFDF000" EntryPoint="0xFFE0139" FvFile="A6885402-D022-4B0E-A509-4711B90F2A39" Name="ReportStatusCodeRouterSmm" Size="0x6000">
<Pdb>c:\home\edkiigit\Build\Quark\DEBUG_VS2015x86\IA32\MdeModulePkg\Universal\ReportStatusCodeRouter\Smm\ReportStatusCodeRouterSmm\DEBUG\ReportStatusCodeRouterSmm.pdb</Pdb>
</Image>
......
</ImageDatabase>
<SmiHandlerDatabase>
<!-- SMI Handler registered -->
<SmiHandlerCategory Name="RootSmi">
<!-- The root SMI Handler registered by SmmCore -->
<SmiEntry>
<SmiHandler>
<Module>QNCSmmDispatcher</Module>
<Handler Address="0xFF2C89B">
<RVA>0x189B</RVA>
<Symbol>
<Function>QNCSmmCoreDispatcher</Function>
<SourceFile>c:\home\edkiigit\edk2\quarksocpkg\quarknorthcluster\smm\dxesmm\qncsmmdispatcher\qncsmmcore.c</SourceFile>
<LineNumber>611</LineNumber>
</Symbol>
</Handler>
<Caller Address="0xFF2C442">
<RVA>0x1442</RVA>
<Symbol>
<Function>InitializeQNCSmmDispatcher</Function>
<SourceFile>c:\home\edkiigit\edk2\quarksocpkg\quarknorthcluster\smm\dxesmm\qncsmmdispatcher\qncsmmcore.c</SourceFile>
<LineNumber>212</LineNumber>
</Symbol>
</Caller>
</SmiHandler>
</SmiEntry>
</SmiHandlerCategory>
<SmiHandlerCategory Name="GuidSmi">
<!-- The GUID SMI Handler registered by SmmCore -->
<SmiEntry HandlerType="gEfiSmmVariableProtocolGuid">
<SmiHandler>
<Module>VariableSmm</Module>
<Handler Address="0xFFCE6D8">
<RVA>0x16D8</RVA>
<Symbol>
<Function>SmmVariableHandler</Function>
<SourceFile>c:\home\edkiigit\edk2\mdemodulepkg\universal\variable\runtimedxe\variablesmm.c</SourceFile>
<LineNumber>469</LineNumber>
</Symbol>
</Handler>
<Caller Address="0xFFCED12">
<RVA>0x1D12</RVA>
<Symbol>
<Function>VariableServiceInitialize</Function>
<SourceFile>c:\home\edkiigit\edk2\mdemodulepkg\universal\variable\runtimedxe\variablesmm.c</SourceFile>
<LineNumber>970</LineNumber>
</Symbol>
</Caller>
</SmiHandler>
</SmiEntry>
<SmiEntry HandlerType="gEfiSmmLockBoxCommunicationGuid">
<SmiHandler>
<Module>SmmLockBox</Module>
<Handler Address="0xFF4C527">
<RVA>0x1527</RVA>
<Symbol>
<Function>SmmLockBoxHandler</Function>
<SourceFile>c:\home\edkiigit\edk2\mdemodulepkg\universal\lockbox\smmlockbox\smmlockbox.c</SourceFile>
<LineNumber>266</LineNumber>
</Symbol>
</Handler>
<Caller Address="0xFF4C67C">
<RVA>0x167C</RVA>
<Symbol>
<Function>SmmLockBoxEntryPoint</Function>
<SourceFile>c:\home\edkiigit\edk2\mdemodulepkg\universal\lockbox\smmlockbox\smmlockbox.c</SourceFile>
<LineNumber>395</LineNumber>
</Symbol>
</Caller>
</SmiHandler>
</SmiEntry>
......
</SmiHandlerCategory>
<SmiHandlerCategory Name="HardwareSmi">
<!-- The hardware SMI Handler registered by SmmChildDispatcher -->
<SmiEntry HandlerType="gEfiSmmSwDispatch2ProtocolGuid">
<SmiHandler SwSmi="0x1">
<Module>PiSmmCommunicationSmm</Module>
<Handler Address="0xFF1A2ED">
<RVA>0x12ED</RVA>
<Symbol>
<Function>PiSmmCommunicationHandler</Function>
<SourceFile>c:\home\edkiigit\edk2\ueficpupkg\pismmcommunication\pismmcommunicationsmm.c</SourceFile>
<LineNumber>99</LineNumber>
</Symbol>
</Handler>
<Caller Address="0xFF1A489">
<RVA>0x1489</RVA>
<Symbol>
<Function>PiSmmCommunicationSmmEntryPoint</Function>
<SourceFile>c:\home\edkiigit\edk2\ueficpupkg\pismmcommunication\pismmcommunicationsmm.c</SourceFile>
<LineNumber>230</LineNumber>
</Symbol>
</Caller>
</SmiHandler>
<SmiHandler SwSmi="0xA0">
<Module>AcpiSmmPlatform</Module>
<Handler Address="0xFF037B3">
<RVA>0x17B3</RVA>
<Symbol>
<Function>EnableAcpiCallback</Function>
<SourceFile>c:\home\edkiigit\edk2\quarkplatformpkg\acpi\dxesmm\acpismm\acpismmplatform.c</SourceFile>
<LineNumber>623</LineNumber>
</Symbol>
</Handler>
<Caller Address="0xFF036CA">
<RVA>0x16CA</RVA>
<Symbol>
<Function>RegisterToDispatchDriver</Function>
<SourceFile>c:\home\edkiigit\edk2\quarkplatformpkg\acpi\dxesmm\acpismm\acpismmplatform.c</SourceFile>
<LineNumber>434</LineNumber>
</Symbol>
</Caller>
</SmiHandler>
......
</SmiEntry>
<SmiEntry HandlerType="gEfiSmmSxDispatch2ProtocolGuid">
<SmiHandler SxPhase="SxEntry" SxType="SxS3">
<Module>AcpiSmmPlatform</Module>
<Handler Address="0xFF0383C">
<RVA>0x183C</RVA>
<Symbol>
<Function>SxSleepEntryCallBack</Function>
<SourceFile>c:\home\edkiigit\edk2\quarkplatformpkg\acpi\dxesmm\acpismm\acpismmplatform.c</SourceFile>
<LineNumber>681</LineNumber>
</Symbol>
</Handler>
<Caller Address="0xFF03718">
<RVA>0x1718</RVA>
<Symbol>
<Function>RegisterToDispatchDriver</Function>
<SourceFile>c:\home\edkiigit\edk2\quarkplatformpkg\acpi\dxesmm\acpismm\acpismmplatform.c</SourceFile>
<LineNumber>459</LineNumber>
</Symbol>
</Caller>
</SmiHandler>
......
</SmiEntry>
</SmiHandlerCategory>
</SmiHandlerDatabase>
</SmiHandlerProfile>