diff --git a/IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.c b/IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.c
new file mode 100644
index 0000000..6876b6c
--- /dev/null
+++ b/IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.c
@@ -0,0 +1,113 @@
+/** @file
+ Generic Standalone MM IPMI stack driver
+
+ @copyright
+ Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) Microsoft Corporation.
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+//
+// Statements that include other files
+//
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+IPMI_BMC_INSTANCE_DATA *mIpmiInstance;
+EFI_HANDLE mImageHandle;
+
+/**
+ Setup and initialize the BMC for the Standalone MM phase. In order to verify the BMC is functioning
+ as expected, the BMC Selftest is performed. The results are then checked and any errors are
+ reported to the error manager. Errors are collected throughout this routine and reported
+ just prior to installing the driver. If there are more errors than MAX_SOFT_COUNT, then they
+ will be ignored.
+
+ @param[in] ImageHandle A handle to driver image.
+ @param[in] SystemTable A pointer to system table.
+
+ @retval EFI_SUCCESS Successful driver initialization.
+**/
+EFI_STATUS
+EFIAPI
+InitializeStandaloneMmGenericIpmi (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ IPMI_BMC_HOB *BmcHob;
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ DEBUG ((DEBUG_INFO, "InitializeStandaloneMmGenericIpmi entry\n"));
+ mImageHandle = ImageHandle;
+
+ mIpmiInstance = AllocateZeroPool (sizeof (IPMI_BMC_INSTANCE_DATA));
+ ASSERT (mIpmiInstance != NULL);
+ if (mIpmiInstance == NULL) {
+ DEBUG ((DEBUG_ERROR, "ERROR!! Null Pointer returned by AllocateZeroPool ()\n"));
+ ASSERT_EFI_ERROR (EFI_OUT_OF_RESOURCES);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the KCS transaction timeout. Assume delay unit is 1000 us.
+ //
+ mIpmiInstance->IpmiTimeoutPeriod =
+ (PcdGet8 (PcdIpmiCommandTimeoutSeconds) * 1000 * 1000) / IPMI_DELAY_UNIT;
+
+ //
+ // Initialize IPMI IO Base, we still use SMS IO base to get device ID and
+ // Self-test result since MM IF may have different cmds supported.
+ //
+
+ mIpmiInstance->Signature = SM_IPMI_BMC_SIGNATURE;
+ mIpmiInstance->SlaveAddress = BMC_SLAVE_ADDRESS;
+ mIpmiInstance->BmcStatus = BMC_NOTREADY;
+ mIpmiInstance->IpmiTransport.IpmiSubmitCommand = IpmiSendCommand;
+ mIpmiInstance->IpmiTransport.GetBmcStatus = IpmiGetBmcStatus;
+
+ //
+ // Check if PEI already initialized the BMC connection.
+ //
+
+ GuidHob = GetFirstGuidHob (&gIpmiBmcHobGuid);
+ if (GuidHob == NULL) {
+ //
+ // PEI did not create a BMC HOB, initialize the BMC now.
+ //
+
+ Status = IpmiInitializeBmc (mIpmiInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "[IPMI] Failed to initialize BMC. %r\n", Status));
+ return Status;
+ }
+ } else {
+ BmcHob = (IPMI_BMC_HOB *)GET_GUID_HOB_DATA (GuidHob);
+ mIpmiInstance->BmcStatus = BmcHob->BmcStatus;
+ DEBUG ((DEBUG_INFO, "[IPMI] Found IPMI BMC HOB. BMC Status = 0x%d\n", BmcHob->BmcStatus));
+ }
+
+ Handle = NULL;
+ DEBUG ((DEBUG_INFO, "[IPMI] Installing MM protocol!\n"));
+ Status = gMmst->MmInstallProtocolInterface (
+ &Handle,
+ &gSmmIpmiTransportProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mIpmiInstance->IpmiTransport
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.inf b/IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.inf
new file mode 100644
index 0000000..bfde88a
--- /dev/null
+++ b/IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.inf
@@ -0,0 +1,58 @@
+## @file
+# Generic IPMI StandaloneMm Driver.
+#
+# @copyright
+# Copyright 2010 - 2021 Intel Corporation.
+# Copyright (c) Microsoft Corporation.
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = StandaloneMmGenericIpmi
+ FILE_GUID = CE919FB2-87DE-4583-A878-CEEAF6098A35
+ MODULE_TYPE = MM_STANDALONE
+ PI_SPECIFICATION_VERSION = 0x00010032
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeStandaloneMmGenericIpmi
+
+[Sources]
+ ../Common/IpmiHooks.h
+ ../Common/IpmiHooks.c
+ ../Common/GenericIpmi.c
+ ../Common/IpmiInitialize.c
+ ../Common/GenericIpmi.h
+ StandaloneMmGenericIpmi.c #GenericIpmi.c+IpmiBmcInitialize.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseLib
+ MmServicesTableLib
+ DebugLib
+ StandaloneMmDriverEntryPoint
+ ReportStatusCodeLib
+ TimerLib
+ HobLib
+ IpmiTransportLib
+ IpmiPlatformLib
+
+[Protocols]
+ gSmmIpmiTransportProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+
+[Guids]
+ gIpmiBmcHobGuid
+
+[Pcd]
+ gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress
+ gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiBmcReadyDelayTimer
+ gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiCommandTimeoutSeconds
+ gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiCommandMaxReties
+ gIpmiFeaturePkgTokenSpaceGuid.PcdBmcTimeoutSeconds
+ gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiCheckSelfTestResults
+
+[Depex]
+ TRUE
diff --git a/IpmiFeaturePkg/IpmiCoreLibs.dsc.inc b/IpmiFeaturePkg/IpmiCoreLibs.dsc.inc
index c6b359b..0689d75 100644
--- a/IpmiFeaturePkg/IpmiCoreLibs.dsc.inc
+++ b/IpmiFeaturePkg/IpmiCoreLibs.dsc.inc
@@ -22,3 +22,6 @@
[LibraryClasses.common.DXE_SMM_DRIVER,LibraryClasses.common.SMM_CORE]
IpmiBaseLib|IpmiFeaturePkg/Library/IpmiBaseLibSmm/IpmiBaseLibSmm.inf
+
+[LibraryClasses.common.MM_STANDALONE,LibraryClasses.common.MM_CORE_STANDALONE]
+ IpmiBaseLib|IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.inf
diff --git a/IpmiFeaturePkg/IpmiFeaturePkg.ci.yaml b/IpmiFeaturePkg/IpmiFeaturePkg.ci.yaml
index c4acc52..a5c2759 100644
--- a/IpmiFeaturePkg/IpmiFeaturePkg.ci.yaml
+++ b/IpmiFeaturePkg/IpmiFeaturePkg.ci.yaml
@@ -39,7 +39,8 @@
"MdePkg/MdePkg.dec",
"MdeModulePkg/MdeModulePkg.dec",
"PolicyServicePkg/PolicyServicePkg.dec",
- "IpmiFeaturePkg/IpmiFeaturePkg.dec"
+ "IpmiFeaturePkg/IpmiFeaturePkg.dec",
+ "StandaloneMmPkg/StandaloneMmPkg.dec"
],
# For host based unit tests
"AcceptableDependencies-HOST_APPLICATION":[
diff --git a/IpmiFeaturePkg/IpmiFeaturePkg.dsc b/IpmiFeaturePkg/IpmiFeaturePkg.dsc
index 81dc08d..a1d1612 100644
--- a/IpmiFeaturePkg/IpmiFeaturePkg.dsc
+++ b/IpmiFeaturePkg/IpmiFeaturePkg.dsc
@@ -41,7 +41,9 @@
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+ MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/StandaloneMmServicesTableLib.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
@@ -88,15 +90,22 @@
ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+[LibraryClasses.common.MM_STANDALONE]
+ MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationLib/StandaloneMmMemoryAllocationLib.inf
+ ReportStatusCodeLib|MdeModulePkg/Library/SmmReportStatusCodeLib/StandaloneMmReportStatusCodeLib.inf
+ HobLib|StandaloneMmPkg/Library/StandaloneMmHobLib/StandaloneMmHobLib.inf
+
[Components]
IpmiFeaturePkg/Library/IpmiCommandLib/IpmiCommandLib.inf
IpmiFeaturePkg/Library/IpmiBaseLibNull/IpmiBaseLibNull.inf
IpmiFeaturePkg/Library/IpmiBaseLibDxe/IpmiBaseLibDxe.inf
IpmiFeaturePkg/Library/IpmiBaseLibPei/IpmiBaseLibPei.inf
IpmiFeaturePkg/Library/IpmiBaseLibSmm/IpmiBaseLibSmm.inf
+ IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.inf
IpmiFeaturePkg/Library/BmcSmbusLibNull/BmcSmbusLibNull.inf
IpmiFeaturePkg/GenericIpmi/Pei/PeiGenericIpmi.inf
IpmiFeaturePkg/GenericIpmi/Dxe/DxeGenericIpmi.inf
+ IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.inf
IpmiFeaturePkg/BmcAcpi/BmcAcpi.inf
IpmiFeaturePkg/BmcAcpiPowerState/BmcAcpiPowerStateSmm.inf
IpmiFeaturePkg/SpmiTable/SpmiTable.inf
diff --git a/IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.c b/IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.c
new file mode 100644
index 0000000..dc9ac3f
--- /dev/null
+++ b/IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.c
@@ -0,0 +1,98 @@
+/** @file
+ A Library to support all BMC access via IPMI command during MM Phase.
+
+ @copyright
+ Copyright 1999 - 2021 Intel Corporation.
+ Copyright (c) Microsoft Corporation
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include
+#include
+#include
+#include
+#include
+
+STATIC IPMI_TRANSPORT *mIpmiTransport = NULL;
+
+/**
+ Sends a IPMI command to the BMC and returns the response.
+
+ @param[in] NetFunction Net function of the command.
+ @param[in] Command IPMI command number.
+ @param[in] CommandData Command data buffer.
+ @param[in] CommandDataSize Size of command data.
+ @param[out] ResponseData Response Data buffer.
+ @param[in,out] ResponseDataSize Response data buffer size on input, size of
+ read data or required size on return.
+
+ @retval EFI_SUCCESS Successfully send IPMI command.
+ @retval EFI_NOT_AVAILABLE_YET Ipmi interface is not installed yet.
+**/
+EFI_STATUS
+EFIAPI
+IpmiSubmitCommand (
+ IN UINT8 NetFunction,
+ IN UINT8 Command,
+ IN UINT8 *CommandData,
+ IN UINT32 CommandDataSize,
+ OUT UINT8 *ResponseData,
+ IN OUT UINT32 *ResponseDataSize
+ )
+{
+ EFI_STATUS Status;
+
+ if (mIpmiTransport == NULL) {
+ Status = gMmst->MmLocateProtocol (&gSmmIpmiTransportProtocolGuid, NULL, (VOID **)&mIpmiTransport);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to locate IPMI protocol. %r\n", __func__, Status));
+ return Status;
+ }
+ }
+
+ Status = mIpmiTransport->IpmiSubmitCommand (
+ mIpmiTransport,
+ NetFunction,
+ 0,
+ Command,
+ CommandData,
+ CommandDataSize,
+ ResponseData,
+ ResponseDataSize
+ );
+ return Status;
+}
+
+/**
+ Gets the current status of the BMC from the IPMI module.
+
+ @param[out] BmcStatus The current status of the BMC.
+ @param[out] ComAddress The address of the BMC.
+
+ @retval EFI_SUCCESS Successfully retrieved BMC status
+ @retval EFI_NOT_FOUND Ipmi interface is not installed yet.
+**/
+EFI_STATUS
+EFIAPI
+GetBmcStatus (
+ OUT BMC_STATUS *BmcStatus,
+ OUT SM_COM_ADDRESS *ComAddress
+ )
+{
+ EFI_STATUS Status;
+
+ if (mIpmiTransport == NULL) {
+ Status = gMmst->MmLocateProtocol (&gSmmIpmiTransportProtocolGuid, NULL, (VOID **)&mIpmiTransport);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "%a: Failed to locate IPMI protocol. %r\n", __func__, Status));
+ return Status;
+ }
+ }
+
+ Status = mIpmiTransport->GetBmcStatus (
+ mIpmiTransport,
+ BmcStatus,
+ ComAddress
+ );
+ return Status;
+}
diff --git a/IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.inf b/IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.inf
new file mode 100644
index 0000000..e518367
--- /dev/null
+++ b/IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.inf
@@ -0,0 +1,33 @@
+## @file
+#
+# @copyright
+# Copyright 2010 - 2021 Intel Corporation.
+# Copyright (c) Microsoft Corporation
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 1.26
+ PI_SPECIFICATION_VERSION = 0x00010032
+ BASE_NAME = IpmiBaseLibMm
+ FILE_GUID = 06C28B6D-F15F-42C3-8316-01BD3E93D2DE
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = IpmiBaseLib|MM_STANDALONE MM_CORE_STANDALONE
+
+[sources]
+ IpmiBaseLibMm.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ MmServicesTableLib
+
+[Protocols]
+ gSmmIpmiTransportProtocolGuid
+
+[Depex]
+ TRUE