Skip to content

Commit

Permalink
Implement StandaloneMmGenericIpmi driver and IpmiBaseLibMm library (#268
Browse files Browse the repository at this point in the history
)

## Description

Implement the StandaloneMmGenericIpmi driver.

For details on how to complete these options and their meaning refer to
[CONTRIBUTING.md](https://github.com/microsoft/mu/blob/HEAD/CONTRIBUTING.md).

- [x] Impacts functionality?
- [ ] Impacts security?
- [ ] Breaking change?
- [ ] Includes tests?
- [ ] Includes documentation?

## How This Was Tested

Verified the build and boot on a simulator

## Integration Instructions

Include the driver in DSC and FDF file

---------

Co-authored-by: Marc Chen <[email protected]>
  • Loading branch information
MarcChen46 and Marc Chen authored Nov 19, 2024
1 parent 8b659c6 commit ff0ac37
Show file tree
Hide file tree
Showing 7 changed files with 316 additions and 1 deletion.
113 changes: 113 additions & 0 deletions IpmiFeaturePkg/GenericIpmi/StandaloneMm/StandaloneMmGenericIpmi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/** @file
Generic Standalone MM IPMI stack driver
@copyright
Copyright 1999 - 2021 Intel Corporation. <BR>
Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

//
// Statements that include other files
//
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/MmServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/IpmiBaseLib.h>
#include <Library/HobLib.h>

#include <IndustryStandard/Ipmi.h>
#include <SmStatusCodes.h>

#include <GenericIpmi.h>

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;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
## @file
# Generic IPMI StandaloneMm Driver.
#
# @copyright
# Copyright 2010 - 2021 Intel Corporation. <BR>
# 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
3 changes: 3 additions & 0 deletions IpmiFeaturePkg/IpmiCoreLibs.dsc.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion IpmiFeaturePkg/IpmiFeaturePkg.ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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":[
Expand Down
9 changes: 9 additions & 0 deletions IpmiFeaturePkg/IpmiFeaturePkg.dsc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
98 changes: 98 additions & 0 deletions IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/** @file
A Library to support all BMC access via IPMI command during MM Phase.
@copyright
Copyright 1999 - 2021 Intel Corporation. <BR>
Copyright (c) Microsoft Corporation
SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <PiDxe.h>
#include <Protocol/IpmiTransportProtocol.h>
#include <Library/IpmiBaseLib.h>
#include <Library/MmServicesTableLib.h>
#include <Library/DebugLib.h>

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;
}
33 changes: 33 additions & 0 deletions IpmiFeaturePkg/Library/IpmiBaseLibMm/IpmiBaseLibMm.inf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## @file
#
# @copyright
# Copyright 2010 - 2021 Intel Corporation. <BR>
# 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

0 comments on commit ff0ac37

Please sign in to comment.