From: Zhen Gong <zhen.gong@intel.com>
To: devel@edk2.groups.io
Cc: Zhen Gong <zhen.gong@intel.com>
Subject: [edk2-devel] [PATCH edk2-platforms 1/4] IpmiFeaturePkg: Add Elog drivers
Date: Fri, 27 Oct 2023 13:11:13 -0700 [thread overview]
Message-ID: <151e2cd3461b6c577cd15e0ce862309e409129f0.1698437221.git.zhen.gong@intel.com> (raw)
In-Reply-To: <cover.1698437221.git.zhen.gong@intel.com>
Add generic Elog driver and support BMC Elog operations.
Signed-off-by: Zhen Gong <zhen.gong@intel.com>
---
.../IpmiFeaturePkg/IpmiFeaturePkg.dec | 5 +
.../IpmiFeaturePkg/Include/IpmiFeature.dsc | 7 +-
.../IpmiFeaturePkg/Include/PostMemory.fdf | 5 +-
.../IpmiFeaturePkg/Include/PreMemory.fdf | 1 +
.../BmcElog/{BmcElog.inf => DxeBmcElog.inf} | 25 +-
.../IpmiFeaturePkg/BmcElog/PeiBmcElog.inf | 43 ++
.../IpmiFeaturePkg/BmcElog/SmmBmcElog.inf | 44 ++
.../GenericElog/Dxe/GenericElog.inf | 38 ++
.../GenericElog/Smm/GenericElog.inf | 38 ++
.../BmcElog/Common/BmcElogCommon.h | 144 +++++
.../IpmiFeaturePkg/BmcElog/Dxe/BmcElog.h | 42 ++
.../IpmiFeaturePkg/BmcElog/Pei/BmcElog.h | 44 ++
.../IpmiFeaturePkg/BmcElog/Smm/BmcElog.h | 43 ++
.../GenericElog/Dxe/GenericElog.h | 194 ++++++
.../GenericElog/Smm/GenericElog.h | 216 +++++++
.../IpmiFeaturePkg/Include/Ppi/GenericElog.h | 84 +++
.../Include/Protocol/GenericElog.h | 99 +++
.../IpmiFeaturePkg/BmcElog/BmcElog.c | 236 -------
.../BmcElog/Common/BmcElogCommon.c | 465 ++++++++++++++
.../IpmiFeaturePkg/BmcElog/Dxe/BmcElog.c | 287 +++++++++
.../IpmiFeaturePkg/BmcElog/Pei/BmcElog.c | 297 +++++++++
.../IpmiFeaturePkg/BmcElog/Smm/BmcElog.c | 288 +++++++++
.../GenericElog/Dxe/GenericElog.c | 576 ++++++++++++++++++
.../GenericElog/Smm/GenericElog.c | 558 +++++++++++++++++
24 files changed, 3535 insertions(+), 244 deletions(-)
rename Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/{BmcElog.inf => DxeBmcElog.inf} (56%)
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/PeiBmcElog.inf
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/SmmBmcElog.inf
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.inf
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.inf
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.h
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.h
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.h
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.h
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.h
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.h
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/GenericElog.h
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/GenericElog.h
delete mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcElog.c
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.c
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.c
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.c
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.c
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.c
create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.c
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.dec b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.dec
index 5df71300cbd1..22bc4e69be8a 100644
--- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.dec
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.dec
@@ -67,6 +67,7 @@ [Guids]
[Ppis]
gPeiIpmiTransportPpiGuid = {0x7bf5fecc, 0xc5b5, 0x4b25, {0x81, 0x1b, 0xb4, 0xb5, 0xb, 0x28, 0x79, 0xf7}}
gPeiIpmiTransport2PpiGuid = {0x8122CEBD, 0xF4FD, 0x4EA8, { 0x97, 0x6C, 0xF0, 0x30, 0xAD, 0xDC, 0x4C, 0xB4 }}
+ gPeiRedirElogPpiGuid = { 0x7a7c1591, 0xfc67, 0x4f69, { 0xa3, 0x78, 0xfc, 0x3d, 0x4a, 0xd7, 0x92, 0xf7 } }
[Protocols]
gIpmiTransportProtocolGuid = {0x6bb945e8, 0x3743, 0x433e, {0xb9, 0x0e, 0x29, 0xb3, 0x0d, 0x5d, 0xc6, 0x30}}
@@ -74,6 +75,10 @@ [Protocols]
gEfiVideoPrintProtocolGuid = {0x3dbf3e06, 0x9d0c, 0x40d3, {0xb2, 0x17, 0x45, 0x5f, 0x33, 0x9e, 0x29, 0x09}}
gIpmiTransport2ProtocolGuid = { 0x4A1D0E66, 0x5271, 0x4E22, { 0x83, 0xFE, 0x90, 0x92, 0x1B, 0x74, 0x82, 0x13 }}
gSmmIpmiTransport2ProtocolGuid = { 0x1DBD1503, 0x0A60, 0x4230, { 0xAA, 0xA3, 0x80, 0x16, 0xD8, 0xC3, 0xDE, 0x2F }}
+ gEfiGenericElogProtocolGuid = { 0x59d02fcd, 0x9233, 0x4d34, { 0xbc, 0xfe, 0x87, 0xca, 0x81, 0xd3, 0xdd, 0xa7 } }
+ gSmmGenericElogProtocolGuid = { 0x664ef1f6, 0x19bf, 0x4498, { 0xab, 0x6a, 0xfc, 0x05, 0x72, 0xfb, 0x98, 0x51 } }
+ gEfiRedirElogProtocolGuid = { 0x16d11030, 0x71ba, 0x4e5e, { 0xa9, 0xf9, 0xb4, 0x75, 0xa5, 0x49, 0x4, 0x8a } }
+ gSmmRedirElogProtocolGuid = { 0x79ac2d9c, 0x9216, 0x43c5, { 0xa0, 0x74, 0x0b, 0x45, 0xc7, 0x64, 0x22, 0xc1 } }
[PcdsFeatureFlag]
gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiFeatureEnable|FALSE|BOOLEAN|0xA0000001
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc
index 0401974b82e2..fa98e5672d83 100644
--- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc
@@ -57,6 +57,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER]
IpmbInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/DxeIpmbInterfaceLib.inf
[LibraryClasses.common.DXE_SMM_DRIVER]
+ IpmiBaseLib|IpmiFeaturePkg/Library/SmmIpmiBaseLib/SmmIpmiBaseLib.inf
SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/SmmSsifInterfaceLib.inf
IpmbInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInterfaceLib/SmmIpmbInterfaceLib.inf
@@ -96,6 +97,7 @@ [Components.IA32]
IpmiFeaturePkg/GenericIpmi/Pei/PeiGenericIpmi.inf
IpmiFeaturePkg/Frb/FrbPei.inf
IpmiFeaturePkg/IpmiInit/PeiIpmiInit.inf
+ IpmiFeaturePkg/BmcElog/PeiBmcElog.inf
#
# Feature DXE Components
@@ -119,7 +121,10 @@ [Components.X64]
IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.inf
IpmiFeaturePkg/Library/SmmIpmiBaseLib/SmmIpmiBaseLib.inf
IpmiFeaturePkg/BmcAcpi/BmcAcpi.inf
- IpmiFeaturePkg/BmcElog/BmcElog.inf
+ IpmiFeaturePkg/BmcElog/DxeBmcElog.inf
+ IpmiFeaturePkg/BmcElog/SmmBmcElog.inf
+ IpmiFeaturePkg/GenericElog/Dxe/GenericElog.inf
+ IpmiFeaturePkg/GenericElog/Smm/GenericElog.inf
IpmiFeaturePkg/Frb/FrbDxe.inf
IpmiFeaturePkg/IpmiFru/IpmiFru.inf
IpmiFeaturePkg/IpmiInit/DxeIpmiInit.inf
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PostMemory.fdf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PostMemory.fdf
index e0f3bbe158d9..f29810bc0b34 100644
--- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PostMemory.fdf
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PostMemory.fdf
@@ -10,8 +10,11 @@
INF IpmiFeaturePkg/GenericIpmi/Dxe/GenericIpmi.inf
INF IpmiFeaturePkg/IpmiInit/DxeIpmiInit.inf
INF RuleOverride = DRIVER_ACPITABLE IpmiFeaturePkg/BmcAcpi/BmcAcpi.inf
-INF IpmiFeaturePkg/BmcElog/BmcElog.inf
+INF IpmiFeaturePkg/BmcElog/DxeBmcElog.inf
+INF IpmiFeaturePkg/BmcElog/SmmBmcElog.inf
INF IpmiFeaturePkg/Frb/FrbDxe.inf
INF IpmiFeaturePkg/IpmiFru/IpmiFru.inf
+INF IpmiFeaturePkg/GenericElog/Dxe/GenericElog.inf
+INF IpmiFeaturePkg/GenericElog/Smm/GenericElog.inf
INF IpmiFeaturePkg/OsWdt/OsWdt.inf
INF IpmiFeaturePkg/SolStatus/SolStatus.inf
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PreMemory.fdf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PreMemory.fdf
index d214988bd141..ca20546e9aa8 100644
--- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PreMemory.fdf
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PreMemory.fdf
@@ -10,3 +10,4 @@
INF IpmiFeaturePkg/GenericIpmi/Pei/PeiGenericIpmi.inf
INF IpmiFeaturePkg/IpmiInit/PeiIpmiInit.inf
INF IpmiFeaturePkg/Frb/FrbPei.inf
+INF IpmiFeaturePkg/BmcElog/PeiBmcElog.inf
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcElog.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/DxeBmcElog.inf
similarity index 56%
rename from Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcElog.inf
rename to Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/DxeBmcElog.inf
index 388dd2740c69..dce3bc42ce05 100644
--- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcElog.inf
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/DxeBmcElog.inf
@@ -1,12 +1,12 @@
### @file
-# Component description file for BMC ELOG.
#
-# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
###
+
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BmcElog
@@ -17,17 +17,30 @@ [Defines]
ENTRY_POINT = InitializeBmcElogLayer
[Sources]
- BmcElog.c
+ Dxe/BmcElog.c
+ Dxe/BmcElog.h
+ Common/BmcElogCommon.h
+ Common/BmcElogCommon.c
[Packages]
- MdePkg/MdePkg.dec
IpmiFeaturePkg/IpmiFeaturePkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
UefiDriverEntryPoint
DebugLib
UefiBootServicesTableLib
- IpmiCommandLib
+ ReportStatusCodeLib
+ MemoryAllocationLib
+ IpmiBaseLib
+
+[Protocols]
+ gEfiRedirElogProtocolGuid # PROTOCOL ALWAYS_PRODUCED
[Depex]
- TRUE
+ gEfiLoadedImageProtocolGuid AND
+ gIpmiTransportProtocolGuid
+
+
+
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/PeiBmcElog.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/PeiBmcElog.inf
new file mode 100644
index 000000000000..8274033e42e6
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/PeiBmcElog.inf
@@ -0,0 +1,43 @@
+### @file
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BmcElog
+ FILE_GUID = FD2A000E-09EA-4899-B40E-32BE30A58EBD
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeBmcElogLayer
+
+[Sources]
+ Pei/BmcElog.c
+ Pei/BmcElog.h
+ Common/BmcElogCommon.h
+ Common/BmcElogCommon.c
+
+[Packages]
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ ReportStatusCodeLib
+ MemoryAllocationLib
+ PeiServicesLib
+ PeimEntryPoint
+ IpmiBaseLib
+
+[Ppis]
+ gPeiRedirElogPpiGuid # PPI ALWAYS_PRODUCED
+ gPeiIpmiTransportPpiGuid
+
+[Depex]
+ TRUE
+
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/SmmBmcElog.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/SmmBmcElog.inf
new file mode 100644
index 000000000000..d6880f8baa1b
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/SmmBmcElog.inf
@@ -0,0 +1,44 @@
+### @file
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmBmcElog
+ FILE_GUID = BE29A700-9D5A-4bb9-86B1-D1DB7A05D594
+ MODULE_TYPE = DXE_SMM_DRIVER
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeSmBmcElogLayer
+
+[Sources]
+ Smm/BmcElog.c
+ Smm/BmcElog.h
+ Common/BmcElogCommon.h
+ Common/BmcElogCommon.c
+
+[Packages]
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ DebugLib
+ UefiBootServicesTableLib
+ ReportStatusCodeLib
+ SmmServicesTableLib
+ IpmiBaseLib
+
+[Protocols]
+ gSmmRedirElogProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+
+[Depex]
+ gEfiLoadedImageProtocolGuid AND
+ gSmmIpmiTransportProtocolGuid
+
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.inf
new file mode 100644
index 000000000000..1073d3687d38
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.inf
@@ -0,0 +1,38 @@
+### @file
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = GenericElog
+ FILE_GUID = FD2D7E66-C5A7-47de-BDCC-4F1B5DC6ADA8
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeElogLayer
+
+[Sources]
+ GenericElog.c
+ GenericElog.h
+
+[Packages]
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ DebugLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+
+[Protocols]
+ gEfiGenericElogProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gEfiRedirElogProtocolGuid #PROTOCOL ALWAYS_COMSUMED
+
+[Depex]
+ gEfiRedirElogProtocolGuid
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.inf
new file mode 100644
index 000000000000..00f4154cdd39
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.inf
@@ -0,0 +1,38 @@
+### @file
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+###
+
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmGenericElog
+ FILE_GUID = 870B000E-D3AD-4fb2-B846-AB0ADE8799CB
+ MODULE_TYPE = DXE_SMM_DRIVER
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeSmElogLayer
+
+[Sources]
+ GenericElog.c
+ GenericElog.h
+
+[Packages]
+ IpmiFeaturePkg/IpmiFeaturePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ DebugLib
+ SmmServicesTableLib
+
+[Protocols]
+ gSmmGenericElogProtocolGuid # PROTOCOL ALWAYS_PRODUCED
+ gSmmRedirElogProtocolGuid #PROTOCOL ALWAYS_COMSUMED
+
+[Depex]
+ gSmmRedirElogProtocolGuid AND
+ gSmmIpmiTransportProtocolGuid
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.h
new file mode 100644
index 000000000000..23c535d1dd6c
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.h
@@ -0,0 +1,144 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _BMCELOG_COMMON_H_
+#define _BMCELOG_COMMON_H_
+
+//
+// Statements that include other files
+//
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#include "ServerManagement.h"
+#include <SmStatusCodes.h>
+#include <IndustryStandard/Ipmi.h>
+#include <Library/IpmiBaseLib.h>
+
+#define MAX_TEMP_DATA 160
+#define CLEAR_SEL_COUNTER 0x200
+#define SEL_RECORD_SIZE 0x10 // 16 bytes : Entire SEL Record size
+#define SEL_RECORD_ID_SIZE 0x2 // 2 bytes : SEL Record-ID size
+
+#ifndef _EFI_SM_ELOG_TYPE
+#define _EFI_SM_ELOG_TYPE
+typedef enum {
+ EfiElogSmSMBIOS,
+ EfiElogSmIPMI,
+ EfiElogSmMachineCritical,
+ EfiElogSmASF,
+ EfiElogSmOEM,
+ EfiSmElogMax
+} EFI_SM_ELOG_TYPE;
+#endif
+
+/**
+ WaitTillClearSel.
+
+ @param ResvId Reserved ID
+
+ @retval EFI_SUCCESS
+ @retval EFI_NO_RESPONSE
+
+**/
+EFI_STATUS
+WaitTillClearSel (
+ UINT8 *ResvId
+ );
+
+/**
+ Set Bmc Elog Data.
+
+
+ @param ElogData Buffer for log storage
+ @param DataType Event Log type
+ @param AlertEvent If it is an alert event
+ @param Size Log data size
+ @param RecordId Indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+SetBmcElogRecord (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN Size,
+ OUT UINT64 *RecordId
+ );
+
+/**
+ Get Bmc Elog Data.
+
+ @param ElogData Buffer for log data store
+ @param DataType Event log type
+ @param Size Size of log data
+ @param RecordId indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+GetBmcElogRecord (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *Size,
+ IN OUT UINT64 *RecordId
+ );
+
+/**
+ Erase Bmc Elog Data.
+
+ @param This Protocol pointer
+ @param DataType Event log type
+ @param RecordId return which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EraseBmcElogRecord (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ );
+
+/**
+ Activate Bmc Elog.
+
+ @param DataType indicate event log type
+ @param EnableElog Enable/Disable event log
+ @param ElogStatus return log status
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ActivateBmcElog (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ );
+
+/**
+ This function verifies the BMC SEL is full and When it is reports the error to the Error Manager.
+
+ @retval EFI_SUCCESS
+ @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+EFIAPI
+CheckIfSelIsFull (
+ VOID
+ );
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.h
new file mode 100644
index 000000000000..d70261c7c537
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.h
@@ -0,0 +1,42 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_BMCELOG_H_
+#define _EFI_BMCELOG_H_
+
+//
+// Statements that include other files
+//
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/IpmiTransportProtocol.h>
+#include <Protocol/GenericElog.h>
+#include "BmcElogCommon.h"
+
+//
+// BMC Elog instance data
+//
+typedef struct {
+ UINTN Signature;
+ SM_COM_ADDRESS ControllerAddress;
+ SM_COM_ADDRESS TargetAddress;
+ UINT16 Instance;
+ EFI_SM_ELOG_TYPE DataType;
+ UINT8 TempData[MAX_TEMP_DATA + 1];
+ EFI_SM_ELOG_REDIR_PROTOCOL BmcElog;
+} EFI_BMC_ELOG_INSTANCE_DATA;
+
+//
+// BMC Elog Instance signature
+//
+#define EFI_ELOG_REDIR_SIGNATURE SIGNATURE_32 ('e', 'e', 'l', 'g')
+
+#define INSTANCE_FROM_EFI_ELOG_REDIR_THIS(a) CR (a, EFI_BMC_ELOG_INSTANCE_DATA, BmcElog, EFI_ELOG_REDIR_SIGNATURE)
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.h
new file mode 100644
index 000000000000..c1b53f3e468d
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.h
@@ -0,0 +1,44 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_PEIBMCELOG_H_
+#define _EFI_PEIBMCELOG_H_
+
+//
+// Statements that include other files
+//
+
+#include <Ppi/GenericElog.h>
+#include <Ppi/IpmiTransportPpi.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <IndustryStandard/Ipmi.h>
+#include "BmcElogCommon.h"
+
+//
+// BMC Elog instance data
+//
+typedef struct {
+ UINTN Signature;
+ SM_COM_ADDRESS ControllerAddress;
+ SM_COM_ADDRESS TargetAddress;
+ UINT16 Instance;
+ EFI_SM_ELOG_TYPE DataType;
+ UINT8 TempData[MAX_TEMP_DATA + 1];
+ EFI_SM_ELOG_REDIR_PPI BmcElogPpi;
+ EFI_PEI_PPI_DESCRIPTOR BmcElog;
+} EFI_PEI_BMC_ELOG_INSTANCE_DATA;
+
+//
+// BMC Elog Instance signature
+//
+#define EFI_PEI_ELOG_REDIR_SIGNATURE SIGNATURE_32 ('e', 'p', 'l', 'g')
+
+#define INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS(a) CR (a, EFI_PEI_BMC_ELOG_INSTANCE_DATA, BmcElogPpi, EFI_PEI_ELOG_REDIR_SIGNATURE)
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.h
new file mode 100644
index 000000000000..218af380a229
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.h
@@ -0,0 +1,43 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SMM_BMCELOG_H_
+#define _SMM_BMCELOG_H_
+
+//
+// Statements that include other files
+//
+
+#include <Library/SmmServicesTableLib.h>
+#include <Library/SmmLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/IpmiTransportProtocol.h>
+#include <Protocol/GenericElog.h>
+#include "BmcElogCommon.h"
+
+//
+// BMC Elog instance data
+//
+typedef struct {
+ UINTN Signature;
+ SM_COM_ADDRESS ControllerAddress;
+ SM_COM_ADDRESS TargetAddress;
+ UINT16 Instance;
+ EFI_SM_ELOG_TYPE DataType;
+ UINT8 TempData[MAX_TEMP_DATA + 1];
+ EFI_SM_ELOG_REDIR_PROTOCOL BmcElog;
+} EFI_BMC_ELOG_INSTANCE_DATA;
+
+//
+// BMC Elog Instance signature
+//
+#define SM_ELOG_REDIR_SIGNATURE SIGNATURE_32 ('e', 'l', 'o', 'f')
+
+#define INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS(a) CR (a, EFI_BMC_ELOG_INSTANCE_DATA, BmcElog, SM_ELOG_REDIR_SIGNATURE)
+
+#endif //_SMM_BMCELOG_H_
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.h
new file mode 100644
index 000000000000..460185455648
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.h
@@ -0,0 +1,194 @@
+/** @file
+ Generic Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EFI_GENELOG_H_
+#define _EFI_GENELOG_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include "ServerManagement.h"
+
+#include <Protocol/IpmiTransportProtocol.h>
+#include <Protocol/GenericElog.h>
+
+#define EFI_ELOG_PHYSICAL 0
+#define EFI_ELOG_VIRTUAL 1
+#define MAX_REDIR_DESCRIPTOR 10
+
+///
+/// A pointer to a function in IPF points to a plabel.
+///
+typedef struct {
+ UINT64 EntryPoint;
+ UINT64 GP;
+} EFI_PLABEL;
+
+typedef struct {
+ EFI_PLABEL *Function;
+ EFI_PLABEL Plabel;
+} FUNCTION_PTR;
+
+typedef struct {
+ EFI_SM_ELOG_REDIR_PROTOCOL *This;
+ FUNCTION_PTR SetEventLogData;
+ FUNCTION_PTR GetEventLogData;
+ FUNCTION_PTR EraseEventLogData;
+ FUNCTION_PTR ActivateEventLog;
+} REDIR_MODULE_PROC;
+
+typedef struct {
+ BOOLEAN Valid;
+ REDIR_MODULE_PROC Command[2];
+} REDIR_MODULES;
+
+typedef struct {
+ REDIR_MODULES Redir[MAX_REDIR_DESCRIPTOR];
+ UINTN MaxDescriptors;
+} ELOG_MODULE_GLOBAL;
+
+/**
+ Efi Convert Function.
+
+ @param Function
+
+ @retval EFI_SUCCESS
+**/
+EFI_STATUS
+EfiConvertFunction (
+ IN FUNCTION_PTR *Function
+ );
+
+/**
+ Efi Set Function Entry.
+
+ @param FunctionPointer
+ @param Function
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiSetFunctionEntry (
+ IN FUNCTION_PTR *FunctionPointer,
+ IN VOID *Function
+ );
+
+/**
+ Elog Service Initialize.
+
+ @param ImageHandle
+ @param SystemTable
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+ElogServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Efi Lib Set Elog Data.
+
+ @param ElogData
+ @param DataType
+ @param AlertEvent
+ @param DataSize
+ @param RecordId
+ @param Global
+ @param Virtual
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiLibSetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+/**
+ Efi Lib Get Elog Data.
+
+ @param ElogData
+ @param DataType
+ @param DataSize
+ @param RecordId
+ @param Global
+ @param Virtual
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiLibGetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+/**
+ Efi Lib Erase Elog Data.
+
+ @param DataType
+ @param RecordId
+ @param Global
+ @param Virtual
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiLibEraseElogData (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+/**
+ This API enables/Disables Event Log.
+
+ @param DataType - Type of Elog Data that is being Activated.
+ @param EnableElog - Enables (TRUE) / Disables (FALSE) Event Log. If NULL just returns the
+ Current ElogStatus.
+ @param ElogStatus - Current (New) Status of Event Log. Enabled (TRUE), Disabled (FALSE).
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was recorded successfully
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+
+**/
+
+EFI_STATUS
+EfiLibActivateElog (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+#endif //_EFI_GENELOG_H_
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.h
new file mode 100644
index 000000000000..ad6530616309
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.h
@@ -0,0 +1,216 @@
+/** @file
+ Generic Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SMM_GENELOG_H_
+#define _SMM_GENELOG_H_
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/SmmLib.h>
+#include <Library/DebugLib.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/SmmServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include "ServerManagement.h"
+#include <Protocol/IpmiTransportProtocol.h>
+#include <Protocol/GenericElog.h>
+
+#define EFI_ELOG_PHYSICAL 0
+#define EFI_ELOG_VIRTUAL 1
+#define MAX_REDIR_DESCRIPTOR 10
+
+///
+/// A pointer to a function in IPF points to a plabel.
+///
+typedef struct {
+ UINT64 EntryPoint;
+ UINT64 GP;
+} EFI_PLABEL;
+
+typedef struct {
+ EFI_PLABEL *Function;
+ EFI_PLABEL Plabel;
+} FUNCTION_PTR;
+
+typedef struct {
+ EFI_SM_ELOG_REDIR_PROTOCOL *This;
+ FUNCTION_PTR SetEventLogData;
+ FUNCTION_PTR GetEventLogData;
+ FUNCTION_PTR EraseEventLogData;
+ FUNCTION_PTR ActivateEventLog;
+} REDIR_MODULE_PROC;
+
+typedef struct {
+ BOOLEAN Valid;
+ REDIR_MODULE_PROC Command[2];
+} REDIR_MODULES;
+
+typedef struct {
+ REDIR_MODULES Redir[MAX_REDIR_DESCRIPTOR];
+ UINTN MaxDescriptors;
+} ELOG_MODULE_GLOBAL;
+
+/**
+ Efi Convert Function.
+
+ @param Function
+
+ @retval EFI_SUCCESS
+**/
+EFI_STATUS
+EfiConvertFunction (
+ IN FUNCTION_PTR *Function
+ );
+
+/**
+ Set the function entry.
+
+ @param FunctionPointer - The destination function pointer
+ @param Function - The source function pointer
+
+ @retval EFI_SUCCESS - Set the function pointer successfully
+
+**/
+EFI_STATUS
+EfiSetFunctionEntry (
+ IN FUNCTION_PTR *FunctionPointer,
+ IN VOID *Function
+ );
+
+/**
+ Entry point of SM Elog service Driver
+
+ @param ImageHandle - The Image handle of this driver.
+ @param SystemTable - The pointer of EFI_SYSTEM_TABLE.
+
+ @retval EFI_SUCCESS - The driver successfully initialized
+
+**/
+EFI_STATUS
+SmElogServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Sm Redir Address Change Event.
+
+ @param Event
+ @param Context
+
+**/
+VOID
+SmRedirAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Sends the Event-Log data to the destination.
+
+ @param ElogData - Pointer to the Event-Log data that needs to be recorded.
+ @param DataType - Type of Elog Data that is being recorded.
+ @param AlertEvent - This is an indication that the input data type is an Alert.
+ @param DataSize - Data Size.
+ @param RecordId - Record ID sent by the target.
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was recorded successfully.
+ @retval EFI_OUT_OF_RESOURCES - Not enough resources to record data.
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported.
+
+**/
+EFI_STATUS
+EfiLibSetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+/**
+ Gets the Event-Log data from the destination.
+
+ @param ElogData - Pointer to the Event-Log data buffer that will contain the data to be retrieved.
+ @param DataType - Type of Elog Data that is being recorded.
+ @param DataSize - Data Size.
+ @param RecordId - This is the RecordId of the next record. If ElogData is NULL,
+ this gives the RecordId of the first record available in the database with the correct DataSize.
+ A value of 0 on return indicates the last record if the EFI_STATUS indicates a success
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was retrieved successfully.
+ @retval EFI_NOT_FOUND - Event-Log target not found.
+ @retval EFI_BUFFER_TOO_SMALL - Target buffer is too small to retrieve the data.
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+
+**/
+EFI_STATUS
+EfiLibGetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+/**
+ Erases the Event-Log data from the destination.
+
+ @param DataType - Type of Elog Data that is being Erased.
+ @param RecordId - This is the RecordId of the data to be erased. If RecordId is NULL, all
+ the records on the database are erased if permitted by the target.
+ Contains the deleted RecordId on return
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was erased successfully
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+ @retval EFI_NOT_FOUND - Event-Log target not found
+
+**/
+EFI_STATUS
+EfiLibEraseElogData (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+/**
+ This API enables/Disables Event Log.
+
+ @param DataType - Type of Elog Data that is being Activated.
+ @param EnableElog - Enables (TRUE) / Disables (FALSE) Event Log. If NULL just returns the
+ Current ElogStatus.
+ @param ElogStatus - Current (New) Status of Event Log. Enabled (TRUE), Disabled (FALSE).
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was recorded successfully
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+
+**/
+EFI_STATUS
+EfiLibActivateElog (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ );
+
+#endif //_SMM_GENELOG_H_
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/GenericElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/GenericElog.h
new file mode 100644
index 000000000000..4b3b3ee2af33
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/GenericElog.h
@@ -0,0 +1,84 @@
+/** @file
+ This code abstracts the generic ELOG Protocol.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _GENERIC_ELOG_H_
+#define _GENERIC_ELOG_H_
+
+#include "ServerManagement.h"
+
+typedef struct _EFI_SM_ELOG_PPI EFI_SM_ELOG_REDIR_PPI;
+
+//
+// Common Defines
+//
+#ifndef _EFI_SM_ELOG_TYPE
+#define _EFI_SM_ELOG_TYPE
+typedef enum {
+ EfiElogSmSMBIOS,
+ EfiElogSmIPMI,
+ EfiElogSmMachineCritical,
+ EfiElogSmASF,
+ EfiElogSmOEM,
+ EfiSmElogMax
+} EFI_SM_ELOG_TYPE;
+#endif
+
+//
+// Generic ELOG Function Prototypes
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_ELOG_DATA)(
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_ELOG_DATA)(
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN OUT UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ERASE_ELOG_DATA)(
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVATE_ELOG)(
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ );
+
+//
+// IPMI TRANSPORT PPI
+//
+struct _EFI_SM_ELOG_PPI {
+ EFI_SET_ELOG_DATA SetEventLogData;
+ EFI_GET_ELOG_DATA GetEventLogData;
+ EFI_ERASE_ELOG_DATA EraseEventlogData;
+ EFI_ACTIVATE_ELOG ActivateEventLog;
+};
+
+extern EFI_GUID gPeiRedirElogPpiGuid;
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/GenericElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/GenericElog.h
new file mode 100644
index 000000000000..19726ff58f0f
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/GenericElog.h
@@ -0,0 +1,99 @@
+/** @file
+ This code abstracts the generic ELOG Protocol.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _GENERIC_ELOG_H_
+#define _GENERIC_ELOG_H_
+
+#include "ServerManagement.h"
+
+#define EFI_SM_ELOG_PROTOCOL_GUID \
+ { \
+ 0x59d02fcd, 0x9233, 0x4d34, 0xbc, 0xfe, 0x87, 0xca, 0x81, 0xd3, 0xdd, 0xa7 \
+ }
+
+#define EFI_SM_ELOG_REDIR_PROTOCOL_GUID \
+ { \
+ 0x16d11030, 0x71ba, 0x4e5e, 0xa9, 0xf9, 0xb4, 0x75, 0xa5, 0x49, 0x4, 0x8a \
+ }
+
+//
+// Common Defines
+//
+#ifndef _EFI_SM_ELOG_TYPE
+#define _EFI_SM_ELOG_TYPE
+typedef enum {
+ EfiElogSmSMBIOS,
+ EfiElogSmIPMI,
+ EfiElogSmMachineCritical,
+ EfiElogSmASF,
+ EfiElogSmOEM,
+ EfiSmElogMax
+} EFI_SM_ELOG_TYPE;
+#endif
+
+typedef struct _EFI_SM_ELOG_PROTOCOL EFI_SM_ELOG_PROTOCOL;
+
+typedef struct _EFI_SM_ELOG_PROTOCOL EFI_SM_ELOG_REDIR_PROTOCOL;
+
+//
+// Generic ELOG Function Prototypes
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_ELOG_DATA)(
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_ELOG_DATA)(
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN OUT UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ERASE_ELOG_DATA)(
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVATE_ELOG)(
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ );
+
+//
+// IPMI TRANSPORT PROTOCOL
+//
+struct _EFI_SM_ELOG_PROTOCOL {
+ EFI_SET_ELOG_DATA SetEventLogData;
+ EFI_GET_ELOG_DATA GetEventLogData;
+ EFI_ERASE_ELOG_DATA EraseEventlogData;
+ EFI_ACTIVATE_ELOG ActivateEventLog;
+};
+
+extern EFI_GUID gEfiGenericElogProtocolGuid;
+extern EFI_GUID gEfiRedirElogProtocolGuid;
+extern EFI_GUID gSmmGenericElogProtocolGuid;
+extern EFI_GUID gSmmRedirElogProtocolGuid;
+
+#endif
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcElog.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcElog.c
deleted file mode 100644
index a6d075b19c49..000000000000
--- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcElog.c
+++ /dev/null
@@ -1,236 +0,0 @@
-/** @file
- BMC Event Log functions.
-
-Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <Uefi.h>
-#include <Library/BaseLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/IpmiCommandLib.h>
-
-EFI_STATUS
-EFIAPI
-CheckIfSelIsFull (
- VOID
- );
-
-/*++
-
- Routine Description:
- This function verifies the BMC SEL is full and When it is reports the error to the Error Manager.
-
- Arguments:
- None
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-EFI_STATUS
-WaitTillErased (
- UINT8 *ResvId
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
- BmcElogPrivateData - Bmc event log instance
- ResvId - Reserved ID
-
-Returns:
-
- EFI_SUCCESS
- EFI_NO_RESPONSE
-
---*/
-{
- INTN Counter;
- IPMI_CLEAR_SEL_REQUEST ClearSel;
- IPMI_CLEAR_SEL_RESPONSE ClearSelResponse;
-
- Counter = 0x200;
- ZeroMem (&ClearSelResponse, sizeof(ClearSelResponse));
-
- while (TRUE) {
- ZeroMem (&ClearSel, sizeof(ClearSel));
- ClearSel.Reserve[0] = ResvId[0];
- ClearSel.Reserve[1] = ResvId[1];
- ClearSel.AscC = 0x43;
- ClearSel.AscL = 0x4C;
- ClearSel.AscR = 0x52;
- ClearSel.Erase = 0x00;
-
- IpmiClearSel (
- &ClearSel,
- &ClearSelResponse
- );
-
- if ((ClearSelResponse.ErasureProgress & 0xf) == 1) {
- return EFI_SUCCESS;
- }
- //
- // If there is not a response from the BMC controller we need to return and not hang.
- //
- --Counter;
- if (Counter == 0x0) {
- return EFI_NO_RESPONSE;
- }
- }
-}
-
-EFI_STATUS
-EfiActivateBmcElog (
- IN BOOLEAN *EnableElog,
- OUT BOOLEAN *ElogStatus
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
- This - Protocol pointer
- DataType - indicate event log type
- EnableElog - Enable/Disable event log
- ElogStatus - return log status
-
-Returns:
-
- EFI_STATUS
-
---*/
-{
- EFI_STATUS Status;
- UINT8 ElogStat;
- IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST SetBmcGlobalEnables;
- IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE GetBmcGlobalEnables;
- UINT8 CompletionCode;
-
- Status = EFI_SUCCESS;
- ElogStat = 0;
-
- Status = IpmiGetBmcGlobalEnables (&GetBmcGlobalEnables);
- if (EFI_ERROR(Status)) {
- return Status;
- }
-
- if (EnableElog == NULL) {
- *ElogStatus = GetBmcGlobalEnables.GetEnables.Bits.SystemEventLogging;
- } else {
- if (Status == EFI_SUCCESS) {
- if (*EnableElog) {
- ElogStat = 1;
- }
-
- CopyMem (&SetBmcGlobalEnables, (UINT8 *)&GetBmcGlobalEnables + 1, sizeof(UINT8));
- SetBmcGlobalEnables.SetEnables.Bits.SystemEventLogging = ElogStat;
-
- Status = IpmiSetBmcGlobalEnables (&SetBmcGlobalEnables, &CompletionCode);
- }
- }
-
- return Status;
-}
-
-EFI_STATUS
-SetElogRedirInstall (
- VOID
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
- None
-
-Returns:
-
- EFI_SUCCESS
-
---*/
-{
- BOOLEAN EnableElog;
- BOOLEAN ElogStatus;
-
- //
- // Activate the Event Log (This should depend upon Setup).
- //
- EfiActivateBmcElog (&EnableElog, &ElogStatus);
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-InitializeBmcElogLayer (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-/*++
-
-Routine Description:
-
-Arguments:
-
- ImageHandle - ImageHandle of the loaded driver
- SystemTable - Pointer to the System Table
-
-Returns:
-
- EFI_STATUS
-
---*/
-{
- SetElogRedirInstall ();
-
- CheckIfSelIsFull ();
-
- return EFI_SUCCESS;
-}
-
-EFI_STATUS
-EFIAPI
-CheckIfSelIsFull (
- VOID
- )
-/*++
-
- Routine Description:
- This function verifies the BMC SEL is full and When it is reports the error to the Error Manager.
-
- Arguments:
- None
-
- Returns:
- EFI_SUCCESS
- EFI_DEVICE_ERROR
-
---*/
-{
- EFI_STATUS Status;
- UINT8 SelIsFull;
- IPMI_GET_SEL_INFO_RESPONSE SelInfo;
-
- Status = IpmiGetSelInfo (&SelInfo);
- if (EFI_ERROR (Status)) {
- return EFI_DEVICE_ERROR;
- }
-
- //
- // Check the Bit7 of the OperationByte if SEL is OverFlow.
- //
- SelIsFull = (SelInfo.OperationSupport & 0x80);
- DEBUG ((DEBUG_INFO, "SelIsFull - 0x%x\n", SelIsFull));
-
- return EFI_SUCCESS;
-}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.c
new file mode 100644
index 000000000000..b0688e3afb6c
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcElogCommon.c
@@ -0,0 +1,465 @@
+/** @file
+ BMC Event Log Common functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BmcElogCommon.h"
+
+/**
+ WaitTillClearSel.
+
+ @param ResvId - Reserved ID
+
+ @retval EFI_SUCCESS
+ @retval EFI_NO_RESPONSE
+
+**/
+EFI_STATUS
+WaitTillClearSel (
+ UINT8 *ResvId
+ )
+{
+ INTN Counter;
+ UINT32 ResponseDataSize;
+ IPMI_CLEAR_SEL_REQUEST ClearSelRequest;
+ IPMI_CLEAR_SEL_RESPONSE ClearSelResponse;
+ EFI_STATUS Status;
+
+ Counter = 0x200;
+ Status = EFI_SUCCESS;
+ while (TRUE) {
+ ClearSelRequest.Reserve[0] = ResvId[0];
+ ClearSelRequest.Reserve[1] = ResvId[1];
+ ClearSelRequest.AscC = IPMI_CLEAR_SEL_REQUEST_C_CHAR_ASCII;
+ ClearSelRequest.AscL = IPMI_CLEAR_SEL_REQUEST_L_CHAR_ASCII;
+ ClearSelRequest.AscR = IPMI_CLEAR_SEL_REQUEST_R_CHAR_ASCII;
+ ClearSelRequest.Erase = IPMI_CLEAR_SEL_REQUEST_GET_ERASE_STATUS;
+ ResponseDataSize = sizeof (ClearSelResponse);
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_CLEAR_SEL,
+ (UINT8 *)&ClearSelRequest,
+ sizeof (ClearSelRequest),
+ (UINT8 *)&ClearSelResponse,
+ &ResponseDataSize
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "IpmiSubmitCommand ClearSelRequest Failed %r\n", Status));
+ }
+
+ if ((ClearSelResponse.ErasureProgress & 0xf) == IPMI_CLEAR_SEL_RESPONSE_ERASURE_COMPLETED) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If there is not a response from the BMC controller we need to return and not hang.
+ //
+ --Counter;
+ if (Counter == 0x0) {
+ return EFI_NO_RESPONSE;
+ }
+ }
+}
+
+/**
+ Set Bmc Elog Data.
+
+
+ @param ElogData - Buffer for log storage
+ @param DataType - Event Log type
+ @param AlertEvent - If it is an alert event
+ @param Size - Log data size
+ @param RecordId - Indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+SetBmcElogRecord (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN Size,
+ OUT UINT64 *RecordId
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ResponseDataSize;
+ UINT8 EvntMsgResponse;
+ IPMI_PLATFORM_EVENT_MESSAGE_DATA_REQUEST EvntMsgRequest;
+ IPMI_ADD_SEL_ENTRY_REQUEST AddSelRequest;
+ IPMI_ADD_SEL_ENTRY_RESPONSE AddSelResponse;
+
+ Status = EFI_SUCCESS;
+ CopyMem (&AddSelRequest.RecordData, ElogData, Size);
+
+ *RecordId = 0;
+
+ if (AlertEvent) {
+ EvntMsgRequest.GeneratorId = (UINT8)AddSelRequest.RecordData.GeneratorId;
+ EvntMsgRequest.EvMRevision = AddSelRequest.RecordData.EvMRevision;
+ EvntMsgRequest.SensorType = AddSelRequest.RecordData.SensorType;
+ EvntMsgRequest.SensorNumber = AddSelRequest.RecordData.SensorNumber;
+ EvntMsgRequest.EventDirType = AddSelRequest.RecordData.EventDirType;
+ EvntMsgRequest.OEMEvData1 = AddSelRequest.RecordData.OEMEvData1;
+ EvntMsgRequest.OEMEvData2 = AddSelRequest.RecordData.OEMEvData2;
+ EvntMsgRequest.OEMEvData3 = AddSelRequest.RecordData.OEMEvData3;
+
+ ResponseDataSize = sizeof (EvntMsgResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_SENSOR_EVENT,
+ IPMI_SENSOR_PLATFORM_EVENT_MESSAGE,
+ (UINT8 *)&EvntMsgRequest,
+ sizeof (EvntMsgRequest),
+ (UINT8 *)&EvntMsgResponse,
+ &ResponseDataSize
+ );
+ } else {
+ ResponseDataSize = sizeof (AddSelResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_ADD_SEL_ENTRY,
+ (UINT8 *)&AddSelRequest,
+ sizeof (AddSelRequest),
+ (UINT8 *)&AddSelResponse,
+ &ResponseDataSize
+ );
+
+ if (Status == EFI_SUCCESS) {
+ *RecordId = AddSelResponse.RecordId;
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Get Bmc Elog Data.
+
+ @param ElogData - Buffer for log data store
+ @param DataType - Event log type
+ @param Size - Size of log data
+ @param RecordId - indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+GetBmcElogRecord (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *Size,
+ IN OUT UINT64 *RecordId
+ )
+{
+ UINT64 ReceiveKey;
+ EFI_STATUS Status;
+ IPMI_GET_SEL_ENTRY_REQUEST GetSelEntryRequest;
+ IPMI_GET_SEL_ENTRY_RESPONSE GetSelEntryResponse;
+ UINT32 ResponseDataSize;
+
+ Status = EFI_SUCCESS;
+ ReceiveKey = *RecordId;
+ GetSelEntryRequest.ReserveId[0] = 0;
+ GetSelEntryRequest.ReserveId[1] = 0;
+ GetSelEntryRequest.SelRecID[0] = (UINT8)ReceiveKey;
+ ReceiveKey = DivU64x32 (ReceiveKey, (UINT32)(1 << 8));
+ GetSelEntryRequest.SelRecID[1] = (UINT8)ReceiveKey;
+ GetSelEntryRequest.Offset = 0;
+ GetSelEntryRequest.BytesToRead = IPMI_COMPLETE_SEL_RECORD;
+ ResponseDataSize = sizeof (GetSelEntryResponse);
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SEL_ENTRY,
+ (UINT8 *)&GetSelEntryRequest,
+ sizeof (GetSelEntryRequest),
+ (UINT8 *)&GetSelEntryResponse,
+ &ResponseDataSize
+ );
+ //
+ // Per IPMI spec, Entire Record is 16 Bytes
+ // If less than 16 bytes pointer is sent return buffer too small
+ //
+ if (Status == EFI_SUCCESS) {
+ if (*Size < (SEL_RECORD_SIZE)) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (GetSelEntryResponse.NextSelRecordId == 0xFFFF) {
+ return EFI_NOT_FOUND;
+ }
+
+ *RecordId = GetSelEntryResponse.NextSelRecordId;
+ CopyMem (ElogData, &GetSelEntryResponse.RecordData, sizeof (GetSelEntryResponse.RecordData));
+ *Size = SEL_RECORD_SIZE;
+ }
+
+ return Status;
+}
+
+/**
+ Erase Bmc Elog Data.
+
+ @param DataType - Event log type
+ @param RecordId - return which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EraseBmcElogRecord (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ )
+{
+ EFI_STATUS Status;
+ UINT64 ReceiveKey;
+ UINT8 ResvId[2];
+ BOOLEAN SelReserveIdIsSupported;
+ UINT8 OperationSupport;
+ UINT8 SelReserveIdvalue;
+ UINT32 ResponseDataSize;
+ IPMI_GET_SEL_INFO_RESPONSE GetSelInfoResponse;
+ IPMI_RESERVE_SEL_RESPONSE ReserveSelResponse;
+ IPMI_DELETE_SEL_ENTRY_REQUEST DeleteSelRequest;
+ IPMI_DELETE_SEL_ENTRY_RESPONSE DeleteSelResponse;
+ IPMI_CLEAR_SEL_REQUEST ClearSelRequest;
+ IPMI_CLEAR_SEL_RESPONSE ClearSelResponse;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Before issuing this SEL reservation ID, Check whether this command is supported or not by issuing the
+ // GetSelInfoCommand. If it does not support ResvId should be 0000h
+ //
+ ResponseDataSize = sizeof (GetSelInfoResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SEL_INFO,
+ NULL,
+ 0,
+ (UINT8 *)&GetSelInfoResponse,
+ &ResponseDataSize
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ OperationSupport = GetSelInfoResponse.OperationSupport;
+ SelReserveIdvalue = (OperationSupport & IPMI_GET_SEL_INFO_OPERATION_SUPPORT_RESERVE_SEL_CMD);
+ if (SelReserveIdvalue == IPMI_GET_SEL_INFO_OPERATION_SUPPORT_RESERVE_SEL_CMD) {
+ SelReserveIdIsSupported = TRUE;
+ } else {
+ SelReserveIdIsSupported = FALSE;
+ }
+
+ //
+ // if SelReserveIdcommand not supported do not issue the RESERVE_SEL_ENTRY command, and set the ResvId value to 0000h
+ //
+
+ //
+ // Get the SEL reservation ID
+ //
+
+ if (SelReserveIdIsSupported) {
+ ResponseDataSize = sizeof (ReserveSelResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_RESERVE_SEL,
+ NULL,
+ 0,
+ (UINT8 *)&ReserveSelResponse,
+ &ResponseDataSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ResvId[0] = ReserveSelResponse.ReservationId[0];
+ ResvId[1] = ReserveSelResponse.ReservationId[1];
+ } else {
+ ResvId[0] = 0x00;
+ ResvId[1] = 0x00;
+ }
+
+ //
+ // Clear the SEL
+ //
+ if (RecordId != NULL) {
+ ReceiveKey = *RecordId;
+ DeleteSelRequest.ReserveId[0] = ResvId[0];
+ DeleteSelRequest.ReserveId[1] = ResvId[1];
+ DeleteSelRequest.RecordToDelete[0] = (UINT8)ReceiveKey;
+ ReceiveKey = DivU64x32 (ReceiveKey, (UINT32)(1 << 8));
+ DeleteSelRequest.RecordToDelete[1] = (UINT8)ReceiveKey;
+
+ ResponseDataSize = sizeof (DeleteSelResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_DELETE_SEL_ENTRY,
+ (UINT8 *)&DeleteSelRequest,
+ sizeof (DeleteSelRequest),
+ (UINT8 *)&DeleteSelResponse,
+ &ResponseDataSize
+ );
+ } else {
+ ClearSelRequest.Reserve[0] = ResvId[0];
+ ClearSelRequest.Reserve[1] = ResvId[1];
+ ClearSelRequest.AscC = IPMI_CLEAR_SEL_REQUEST_C_CHAR_ASCII;
+ ClearSelRequest.AscL = IPMI_CLEAR_SEL_REQUEST_L_CHAR_ASCII;
+ ClearSelRequest.AscR = IPMI_CLEAR_SEL_REQUEST_R_CHAR_ASCII;
+ ClearSelRequest.Erase = IPMI_CLEAR_SEL_REQUEST_INITIALIZE_ERASE;
+ ResponseDataSize = sizeof (ClearSelResponse);
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_CLEAR_SEL,
+ (UINT8 *)&ClearSelRequest,
+ sizeof (ClearSelRequest),
+ (UINT8 *)&ClearSelResponse,
+ &ResponseDataSize
+ );
+ }
+
+ if (Status == EFI_SUCCESS) {
+ if (RecordId == NULL) {
+ WaitTillClearSel (ResvId);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Activate Bmc Elog.
+
+ @param DataType - indicate event log type
+ @param EnableElog - Enable/Disable event log
+ @param ElogStatus - return log status
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+ActivateBmcElog (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ )
+{
+ EFI_STATUS Status;
+ UINT8 ElogStat;
+ IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE GetBmcGlobalResponse;
+ IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST SetBmcGlobalRequest;
+ UINT8 SetBmcGlobalResponse;
+ UINT32 ResponseDataSize;
+
+ Status = EFI_SUCCESS;
+ ElogStat = 0;
+
+ ResponseDataSize = sizeof (GetBmcGlobalResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_GET_BMC_GLOBAL_ENABLES,
+ NULL,
+ 0,
+ (UINT8 *)&GetBmcGlobalResponse,
+ &ResponseDataSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "IpmiSubmitCommand App Get Bmc Global Enables Failed %r\n", Status));
+ }
+
+ if (EnableElog == NULL) {
+ *ElogStatus = (UINT8)(GetBmcGlobalResponse.GetEnables.Bits.SystemEventLogging);
+ } else {
+ if (Status == EFI_SUCCESS) {
+ if (*EnableElog) {
+ ElogStat = 0x1; // Setting SystemEventLogging
+ }
+
+ SetBmcGlobalRequest.SetEnables.Uint8 = GetBmcGlobalResponse.GetEnables.Uint8;
+ SetBmcGlobalRequest.SetEnables.Bits.SystemEventLogging = ElogStat;
+
+ ResponseDataSize = sizeof (SetBmcGlobalResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_SET_BMC_GLOBAL_ENABLES,
+ (UINT8 *)&SetBmcGlobalRequest,
+ sizeof (SetBmcGlobalRequest),
+ (UINT8 *)&SetBmcGlobalResponse,
+ &ResponseDataSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "IpmiSubmitCommand App Set Bmc Global Enables Failed %r\n", Status));
+ }
+ }
+ }
+
+ return Status;
+}
+
+/**
+ This function checks the BMC SEL is full and whether to report the error.
+
+ @retval EFI_SUCCESS
+ @retval EFI_DEVICE_ERROR
+
+**/
+EFI_STATUS
+EFIAPI
+CheckIfSelIsFull (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ResponseDataSize;
+ UINT8 OperationSupportByte;
+ UINT8 SelIsFull;
+ IPMI_GET_SEL_INFO_RESPONSE GetSelInfoResponse;
+
+ OperationSupportByte = 0;
+ SelIsFull = 0;
+
+ ResponseDataSize = sizeof (GetSelInfoResponse);
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SEL_INFO,
+ NULL,
+ 0,
+ (UINT8 *)&GetSelInfoResponse,
+ &ResponseDataSize
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ OperationSupportByte = GetSelInfoResponse.OperationSupport;
+
+ //
+ // Check the Bit7 of the OperationByte if SEL is OverFlow.
+ //
+ SelIsFull = (OperationSupportByte & IPMI_GET_SEL_INFO_OPERATION_SUPPORT_OVERFLOW_FLAG);
+
+ if (SelIsFull == IPMI_GET_SEL_INFO_OPERATION_SUPPORT_OVERFLOW_FLAG) {
+ //
+ // Report the Error code that SEL Log is full
+ //
+ ReportStatusCode (
+ (EFI_ERROR_CODE | EFI_ERROR_MINOR),
+ (SOFTWARE_EFI_BMC | EFI_SW_EC_EVENT_LOG_FULL)
+ );
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.c
new file mode 100644
index 000000000000..0b1e2f5b1355
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Dxe/BmcElog.c
@@ -0,0 +1,287 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BmcElog.h"
+
+//
+// Define module globals used to register for notification of when
+// the ELOG REDIR protocol has been produced.
+//
+EFI_EVENT mEfiBmcTransEvent;
+EFI_BMC_ELOG_INSTANCE_DATA *mRedirProtoPrivate;
+
+/**
+ WaitTillErased.
+
+ @param BmcElogPrivateData - Bmc event log instance
+ @param ResvId - Reserved ID
+
+ @retval EFI_SUCCESS
+ @retval EFI_NO_RESPONSE
+
+**/
+EFI_STATUS
+WaitTillErased (
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData,
+ UINT8 *ResvId
+ )
+{
+ EFI_STATUS Status;
+
+ Status = WaitTillClearSel (ResvId);
+ return Status;
+}
+
+/**
+ Efi Set Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param ElogData - Buffer for log storage
+ @param DataType - Event Log type
+ @param AlertEvent - If it is an alert event
+ @param Size - Log data size
+ @param RecordId - Indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiSetBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN Size,
+ OUT UINT64 *RecordId
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Size > SEL_RECORD_SIZE) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = SetBmcElogRecord (ElogData, DataType, AlertEvent, Size, RecordId);
+ }
+
+ return Status;
+}
+
+/**
+ Efi Get Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param ElogData - Buffer for log data store
+ @param DataType - Event log type
+ @param Size - Size of log data
+ @param RecordId - indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiGetBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN OUT UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *Size,
+ IN OUT UINT64 *RecordId
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = GetBmcElogRecord (ElogData, DataType, Size, RecordId);
+ }
+
+ return Status;
+}
+
+/**
+ Efi Erase Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param DataType - Event log type
+ @param RecordId - return which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiEraseBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = EraseBmcElogRecord (DataType, RecordId);
+
+ if (Status == EFI_SUCCESS) {
+ if (RecordId != NULL) {
+ *RecordId = (UINT16)(*((UINT16 *)&BmcElogPrivateData->TempData[0]));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Efi Activate Bmc Elog.
+
+ @param This - Protocol pointer
+ @param DataType - indicate event log type
+ @param EnableElog - Enable/Disable event log
+ @param ElogStatus - return log status
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiActivateBmcElog (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = ActivateBmcElog (DataType, EnableElog, ElogStatus);
+ }
+
+ return Status;
+}
+
+/**
+ Set Elog Redir Install.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+SetElogRedirInstall (
+ VOID
+ )
+{
+ EFI_HANDLE NewHandle;
+ EFI_STATUS Status;
+ BOOLEAN EnableElog;
+ BOOLEAN ElogStatus;
+ UINT16 Instance;
+
+ Status = EFI_SUCCESS;
+ EnableElog = TRUE;
+ ElogStatus = TRUE;
+ Instance = 0;
+
+ mRedirProtoPrivate->Signature = EFI_ELOG_REDIR_SIGNATURE;
+ mRedirProtoPrivate->DataType = EfiElogSmIPMI;
+ mRedirProtoPrivate->BmcElog.ActivateEventLog = EfiActivateBmcElog;
+ mRedirProtoPrivate->BmcElog.EraseEventlogData = EfiEraseBmcElogData;
+ mRedirProtoPrivate->BmcElog.GetEventLogData = EfiGetBmcElogData;
+ mRedirProtoPrivate->BmcElog.SetEventLogData = EfiSetBmcElogData;
+ mRedirProtoPrivate->Instance = Instance;
+ //
+ // Now install the Protocol
+ //
+ NewHandle = NULL;
+
+ Status = gBS->InstallProtocolInterface (
+ &NewHandle,
+ &gEfiRedirElogProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mRedirProtoPrivate->BmcElog
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ //
+ // Activate the Event Log (This should depend upon Setup).
+ //
+ EfiActivateBmcElog (&mRedirProtoPrivate->BmcElog, EfiElogSmIPMI, &EnableElog, &ElogStatus);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ InitializeBmcElogLayer.
+
+ @param ImageHandle - ImageHandle of the loaded driver
+ @param SystemTable - Pointer to the System Table
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+InitializeBmcElogLayer (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ InitializeIpmiBase ();
+
+ mRedirProtoPrivate = AllocatePool (sizeof (EFI_BMC_ELOG_INSTANCE_DATA));
+ ASSERT (mRedirProtoPrivate != NULL);
+ if (mRedirProtoPrivate == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SetElogRedirInstall ();
+
+ //
+ // Check if the BMC System Event Log (SEL) is full and whether to report the error.
+ //
+
+ CheckIfSelIsFull ();
+
+ return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.c
new file mode 100644
index 000000000000..f791d872b7a1
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Pei/BmcElog.c
@@ -0,0 +1,297 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BmcElog.h"
+
+//
+// Define module globals used to register for notification of when
+// the ELOG REDIR protocol has been produced.
+//
+
+EFI_STATUS
+NotifyPeiBmcElogCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiIpmiTransportPpiGuid,
+ NotifyPeiBmcElogCallback
+ }
+};
+
+/**
+ Efi Set Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param ElogData - Buffer for log storage
+ @param DataType - Event Log type
+ @param AlertEvent - If it is an alert event
+ @param Size - Log data size
+ @param RecordId - Indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiSetBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN Size,
+ OUT UINT64 *RecordId
+ )
+{
+ EFI_PEI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Size > SEL_RECORD_SIZE) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = SetBmcElogRecord (ElogData, DataType, AlertEvent, Size, RecordId);
+ }
+
+ return Status;
+}
+
+/**
+ Efi Get Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param ElogData - Buffer for log data store
+ @param DataType - Event log type
+ @param Size - Size of log data
+ @param RecordId - indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiGetBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN OUT UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *Size,
+ IN OUT UINT64 *RecordId
+ )
+{
+ EFI_PEI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = GetBmcElogRecord (ElogData, DataType, Size, RecordId);
+ }
+
+ return Status;
+}
+
+/**
+ Efi Erase Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param DataType - Event log type
+ @param RecordId - return which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiEraseBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ )
+{
+ EFI_PEI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = EraseBmcElogRecord (DataType, RecordId);
+
+ if (Status == EFI_SUCCESS) {
+ if (RecordId != NULL) {
+ *RecordId = (UINT16)(*((UINT16 *)&BmcElogPrivateData->TempData[0]));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Efi Activate Bmc Elog.
+
+ @param This - Protocol pointer
+ @param DataType - indicate event log type
+ @param EnableElog - Enable/Disable event log
+ @param ElogStatus - return log status
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiActivateBmcElog (
+ IN EFI_SM_ELOG_REDIR_PPI *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ )
+{
+ EFI_PEI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = ActivateBmcElog (DataType, EnableElog, ElogStatus);
+ }
+
+ return Status;
+}
+
+/**
+ Set Elog Redir Install.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+SetElogRedirInstall (
+ EFI_PEI_BMC_ELOG_INSTANCE_DATA *mRedirPeiProtoPrivate
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN EnableElog;
+ BOOLEAN ElogStatus;
+ UINT16 Instance;
+
+ Status = EFI_SUCCESS;
+ EnableElog = TRUE;
+ ElogStatus = TRUE;
+ Instance = 0;
+
+ mRedirPeiProtoPrivate->Signature = EFI_PEI_ELOG_REDIR_SIGNATURE;
+ mRedirPeiProtoPrivate->DataType = EfiElogSmIPMI;
+ mRedirPeiProtoPrivate->BmcElogPpi.ActivateEventLog = EfiActivateBmcElog;
+ mRedirPeiProtoPrivate->BmcElogPpi.EraseEventlogData = EfiEraseBmcElogData;
+ mRedirPeiProtoPrivate->BmcElogPpi.GetEventLogData = EfiGetBmcElogData;
+ mRedirPeiProtoPrivate->BmcElogPpi.SetEventLogData = EfiSetBmcElogData;
+
+ mRedirPeiProtoPrivate->BmcElog.Guid = &gPeiRedirElogPpiGuid;
+ mRedirPeiProtoPrivate->BmcElog.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ mRedirPeiProtoPrivate->BmcElog.Ppi = (VOID *)&mRedirPeiProtoPrivate->BmcElogPpi;
+ mRedirPeiProtoPrivate->Instance = Instance;
+ //
+ // Now install the Protocol
+ //
+
+ Status = PeiServicesInstallPpi (&mRedirPeiProtoPrivate->BmcElog);
+ ASSERT_EFI_ERROR (Status);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ //
+ // Activate the Event Log (This should depend upon Setup).
+ //
+ EfiActivateBmcElog (&mRedirPeiProtoPrivate->BmcElogPpi, EfiElogSmIPMI, &EnableElog, &ElogStatus);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ InitializeBmcElogLayer.
+
+ @param ImageHandle - ImageHandle of the loaded driver
+ @param SystemTable - Pointer to the System Table
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+InitializeBmcElogLayer (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ Status = PeiServicesNotifyPpi (&mNotifyList[0]);
+ return Status;
+}
+
+/**
+ NotifyPeiBmcElogCallback This notification function is invoked when an instance of the
+ IPMI Transport layer at PEI is produced.
+
+ @param PeiServices - Pointer to the PEI Services table
+ @param NotifyDescriptor - Pointer to the NotifyPpi Descriptor
+ @param Ppi - Pointer to the PPI passed during Notify
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+NotifyPeiBmcElogCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_BMC_ELOG_INSTANCE_DATA *mRedirPeiProtoPrivate;
+
+ Status = EFI_SUCCESS;
+
+ mRedirPeiProtoPrivate = AllocateZeroPool (sizeof (EFI_PEI_BMC_ELOG_INSTANCE_DATA));
+
+ if (mRedirPeiProtoPrivate == NULL) {
+ DEBUG ((DEBUG_ERROR, "IPMI BMCELog Peim:EFI_OUT_OF_RESOURCES of memory allocation\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SetElogRedirInstall (mRedirPeiProtoPrivate);
+
+ CheckIfSelIsFull ();
+
+ return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.c
new file mode 100644
index 000000000000..efaa61f43869
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Smm/BmcElog.c
@@ -0,0 +1,288 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "BmcElog.h"
+
+//
+// Define module globals used to register for notification of when
+// the ELOG REDIR protocol has been produced.
+//
+EFI_EVENT mEfiBmcTransEvent;
+EFI_BMC_ELOG_INSTANCE_DATA *mRedirProtoPrivate;
+
+/**
+ WaitTillErased.
+
+ @param BmcElogPrivateData - Bmc event log instance
+ @param ResvId - Reserved ID
+
+ @retval EFI_SUCCESS
+ @retval EFI_NO_RESPONSE
+
+**/
+EFI_STATUS
+WaitTillErased (
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData,
+ UINT8 *ResvId
+ )
+{
+ EFI_STATUS Status;
+
+ Status = WaitTillClearSel (ResvId);
+ return Status;
+}
+
+/**
+ Efi Set Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param ElogData - Buffer for log storage
+ @param DataType - Event Log type
+ @param AlertEvent - If it is an alert event
+ @param Size - Log data size
+ @param RecordId - Indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiSetBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN Size,
+ OUT UINT64 *RecordId
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Size > SEL_RECORD_SIZE) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = SetBmcElogRecord (ElogData, DataType, AlertEvent, Size, RecordId);
+ }
+
+ return Status;
+}
+
+/**
+ Efi Get Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param ElogData - Buffer for log data store
+ @param DataType - Event log type
+ @param Size - Size of log data
+ @param RecordId - indicate which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiGetBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN OUT UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *Size,
+ IN OUT UINT64 *RecordId
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = GetBmcElogRecord (ElogData, DataType, Size, RecordId);
+ }
+
+ return Status;
+}
+
+/**
+ Efi Erase Bmc Elog Data.
+
+ @param This - Protocol pointer
+ @param DataType - Event log type
+ @param RecordId - return which recorder it is
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiEraseBmcElogData (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = EraseBmcElogRecord (DataType, RecordId);
+
+ if (Status == EFI_SUCCESS) {
+ if (RecordId != NULL) {
+ *RecordId = (UINT16)(*((UINT16 *)&BmcElogPrivateData->TempData[0]));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Efi Activate Bmc Elog.
+
+ @param This - Protocol pointer
+ @param DataType - indicate event log type
+ @param EnableElog - Enable/Disable event log
+ @param ElogStatus - return log status
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EfiActivateBmcElog (
+ IN EFI_SM_ELOG_REDIR_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ )
+{
+ EFI_BMC_ELOG_INSTANCE_DATA *BmcElogPrivateData;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+ BmcElogPrivateData = INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This);
+
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BmcElogPrivateData->DataType == DataType) {
+ Status = ActivateBmcElog (DataType, EnableElog, ElogStatus);
+ }
+
+ return Status;
+}
+
+/**
+ Set Elog Redir Install.
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+SetElogRedirInstall (
+ VOID
+ )
+{
+ EFI_HANDLE NewHandle;
+ EFI_STATUS Status;
+ BOOLEAN EnableElog;
+ BOOLEAN ElogStatus;
+ UINT16 Instance;
+
+ Status = EFI_SUCCESS;
+ EnableElog = TRUE;
+ ElogStatus = TRUE;
+ Instance = 0;
+
+ mRedirProtoPrivate->Signature = SM_ELOG_REDIR_SIGNATURE;
+ mRedirProtoPrivate->DataType = EfiElogSmIPMI;
+ mRedirProtoPrivate->BmcElog.ActivateEventLog = (EFI_ACTIVATE_ELOG)EfiActivateBmcElog;
+ mRedirProtoPrivate->BmcElog.EraseEventlogData = (EFI_ERASE_ELOG_DATA)EfiEraseBmcElogData;
+ mRedirProtoPrivate->BmcElog.GetEventLogData = (EFI_GET_ELOG_DATA)EfiGetBmcElogData;
+ mRedirProtoPrivate->BmcElog.SetEventLogData = (EFI_SET_ELOG_DATA)EfiSetBmcElogData;
+ mRedirProtoPrivate->Instance = Instance;
+ //
+ // Now install the Protocol
+ //
+ NewHandle = NULL;
+ Status = gSmst->SmmInstallProtocolInterface (
+ &NewHandle,
+ &gSmmRedirElogProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mRedirProtoPrivate->BmcElog
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ //
+ // Activate the Event Log (This should depend upon Setup).
+ //
+ EfiActivateBmcElog (&mRedirProtoPrivate->BmcElog, EfiElogSmIPMI, &EnableElog, &ElogStatus);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ InitializeBmcElogLayer.
+
+ @param ImageHandle - ImageHandle of the loaded driver
+ @param SystemTable - Pointer to the System Table
+
+ @retval EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeSmBmcElogLayer (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ gST = SystemTable;
+ gBS = gST->BootServices;
+
+ mRedirProtoPrivate = AllocatePool (sizeof (EFI_BMC_ELOG_INSTANCE_DATA));
+ ASSERT (mRedirProtoPrivate != NULL);
+ if (mRedirProtoPrivate == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SetElogRedirInstall ();
+ //
+ // Check if the BMC System Event Log (SEL) is full and whether to report the error.
+ //
+
+ CheckIfSelIsFull ();
+
+ return Status;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.c
new file mode 100644
index 000000000000..d432b2151664
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/GenericElog.c
@@ -0,0 +1,576 @@
+/** @file
+ Generic Event Log functions of DXE driver.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "GenericElog.h"
+
+ELOG_MODULE_GLOBAL *mElogModuleGlobal;
+
+//
+// Define module globals used to register for notification of when
+// the ELOG REDIR protocol has been produced.
+//
+EFI_EVENT mEfiElogRedirProtocolEvent;
+
+/**
+ Sends the Event-Log data to the destination.
+
+ @param[in] ElogData Pointer to the Event-Log data that needs to be recorded.
+ @param[in] DataType Type of Elog Data that is being recorded.
+ @param[in] AlertEvent This is an indication that the input data type is an Alert.
+ @param[in] DataSize
+ @param[out] RecordId Record ID sent by the target.
+ @param[in] Global The module global variable pointer.
+ @param[in] Virtual If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS Event-Log was recorded successfully.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources to record data.
+ @retval EFI_UNSUPPORTED The Data Type is unsupported.
+
+**/
+EFI_STATUS
+EfiLibSetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId,
+ IN ELOG_MODULE_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].SetEventLogData.Function;
+ Status = (*((EFI_SET_ELOG_DATA *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, ElogData, DataType, AlertEvent, DataSize, RecordId);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Add function description.
+
+ @param This - add argument description
+ @param ElogData - add argument description
+ @param DataType - add argument description
+ @param AlertEvent - add argument description
+ @param DataSize - add argument description
+ @param RecordId - add argument description
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiSetElogData (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId
+ )
+{
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EfiLibSetElogData (
+ ElogData,
+ DataType,
+ AlertEvent,
+ DataSize,
+ RecordId,
+ mElogModuleGlobal,
+ FALSE
+ );
+}
+
+/**
+ Gets the Event-Log data from the destination.
+
+ @param[in] ElogData Pointer to the Event-Log data buffer that will contain the data to be retrieved.
+ @param[in] DataType Type of Elog Data that is being recorded.
+ @param[in, out] DataSize
+ @param[in, out] RecordId This is the RecordId of the next record. If ElogData is NULL,
+ this gives the RecordId of the first record available in the database with the correct DataSize.
+ A value of 0 on return indicates the last record if the EFI_STATUS indicates a success
+ @param[in] Global The module global variable pointer.
+ @param[in] Virtual If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS Event-Log was retrieved successfully.
+ @retval EFI_NOT_FOUND Event-Log target not found.
+ @retval EFI_BUFFER_TOO_SMALL Target buffer is too small to retrieve the data.
+ @retval EFI_UNSUPPORTED The Data Type is unsupported
+
+**/
+EFI_STATUS
+EfiLibGetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId,
+ IN ELOG_MODULE_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].GetEventLogData.Function;
+ Status = (*((EFI_GET_ELOG_DATA *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, ElogData, DataType, DataSize, RecordId);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Add function description.
+
+ @param This - Protocol instance pointer.
+ @param ElogData - Pointer to the Event-Log data buffer that will contain the data to be retrieved.
+ @param DataType - Type of Elog Data that is being recorded.
+ @param DataSize - Size of Elog Data in bytes.
+ @param RecordId - This is the RecordId of the next record. If ElogData is NULL,
+ this gives the RecordId of the first record available in the database with the correct DataSize.
+ A value of 0 on return indicates the last record if the EFI_STATUS indicates a success
+
+ @retval EFI_SUCCESS add return values
+
+**/
+EFI_STATUS
+EfiGetElogData (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId
+ )
+{
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EfiLibGetElogData (ElogData, DataType, DataSize, RecordId, mElogModuleGlobal, FALSE);
+}
+
+/**
+ Erases the Event-Log data from the destination.
+
+ @param DataType - Type of Elog Data that is being Erased.
+ @param RecordId - This is the RecordId of the data to be erased. If RecordId is NULL, all
+ the records on the database are erased if permitted by the target.
+ Contains the deleted RecordId on return
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was erased successfully
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+ @retval EFI_NOT_FOUND - Event-Log target not found
+
+**/
+EFI_STATUS
+EfiLibEraseElogData (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId,
+ IN ELOG_MODULE_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].EraseEventLogData.Function;
+ Status = (*((EFI_ERASE_ELOG_DATA *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, DataType, RecordId);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Efi Erase Elog Data.
+
+ @param This
+ @param DataType
+ @param RecordId
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiEraseElogData (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ )
+{
+ return EfiLibEraseElogData (DataType, RecordId, mElogModuleGlobal, FALSE);
+}
+
+/**
+ This API enables/Disables Event Log.
+
+ @param DataType - Type of Elog Data that is being Activated.
+ @param EnableElog - Enables (TRUE) / Disables (FALSE) Event Log. If NULL just returns the
+ Current ElogStatus.
+ @param ElogStatus - Current (New) Status of Event Log. Enabled (TRUE), Disabled (FALSE).
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was recorded successfully
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+
+**/
+EFI_STATUS
+EfiLibActivateElog (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].ActivateEventLog.Function;
+ Status = (*((EFI_ACTIVATE_ELOG *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, DataType, EnableElog, ElogStatus);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Efi Activate Elog.
+
+ @param This
+ @param DataType
+ @param EnableElog
+ @param ElogStatus
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiActivateElog (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ )
+{
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EfiLibActivateElog (DataType, EnableElog, ElogStatus, mElogModuleGlobal, FALSE);
+}
+
+/**
+ SetElogRedirInstances.
+
+ @retval EFI_SUCCESS - The Redir instances were successfully set.
+ @retval Other - Failed to set Redir instances.
+
+**/
+EFI_STATUS
+SetElogRedirInstances (
+ VOID
+ )
+{
+ UINTN NumHandles;
+ UINTN Index;
+ UINTN Instance;
+ UINTN EmptyIndex;
+ EFI_HANDLE *Buffer;
+ EFI_STATUS Status;
+ EFI_SM_ELOG_REDIR_PROTOCOL *Redir;
+ REDIR_MODULE_PROC *RedirProc;
+
+ Buffer = NULL;
+
+ //
+ // Check for all IPMI Controllers
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiRedirElogProtocolGuid,
+ NULL,
+ &NumHandles,
+ &Buffer
+ );
+
+ if (EFI_ERROR (Status) || (NumHandles == 0)) {
+ return EFI_SUCCESS;
+ }
+
+ for (Index = 0; ((Index < NumHandles) && (Index < mElogModuleGlobal->MaxDescriptors)); Index++) {
+ EmptyIndex = mElogModuleGlobal->MaxDescriptors;
+
+ Status = gBS->HandleProtocol (
+ Buffer[Index],
+ &gEfiRedirElogProtocolGuid,
+ (VOID *)&Redir
+ );
+ if (EFI_ERROR (Status) || (Redir == NULL)) {
+ continue;
+ }
+
+ for (Instance = 0; Instance < mElogModuleGlobal->MaxDescriptors; Instance++) {
+ if (mElogModuleGlobal->Redir[Instance].Valid == FALSE) {
+ if (EmptyIndex >= mElogModuleGlobal->MaxDescriptors) {
+ EmptyIndex = Instance;
+ }
+ } else {
+ if (Redir == mElogModuleGlobal->Redir[Instance].Command->This) {
+ EmptyIndex = mElogModuleGlobal->MaxDescriptors;
+ break;
+ //
+ // FIX: changed continue to break.
+ //
+ }
+ }
+ }
+
+ if (EmptyIndex < mElogModuleGlobal->MaxDescriptors) {
+ RedirProc = (REDIR_MODULE_PROC *)mElogModuleGlobal->Redir[EmptyIndex].Command;
+ mElogModuleGlobal->Redir[EmptyIndex].Valid = TRUE;
+
+ EfiSetFunctionEntry (&RedirProc->ActivateEventLog, *((VOID **)&Redir->ActivateEventLog));
+ EfiSetFunctionEntry (&RedirProc->EraseEventLogData, *((VOID **)&Redir->EraseEventlogData));
+ EfiSetFunctionEntry (&RedirProc->GetEventLogData, *((VOID **)&Redir->GetEventLogData));
+ EfiSetFunctionEntry (&RedirProc->SetEventLogData, *((VOID **)&Redir->SetEventLogData));
+ RedirProc->This = Redir;
+
+ CopyMem (&RedirProc[EFI_ELOG_VIRTUAL], &RedirProc[EFI_ELOG_PHYSICAL], sizeof (REDIR_MODULE_PROC));
+ }
+ }
+
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This notification function is invoked when an instance of the
+ ELOG REDIR protocol is produced.
+
+ @param Event - The event that occurred
+ @param Context - For EFI compatibility. Not used.
+
+**/
+VOID
+EFIAPI
+NotifyElogRedirEventCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ SetElogRedirInstances ();
+}
+
+/**
+ Initialize the generic Elog driver of server management.
+
+ @param ImageHandle - The image handle of this driver
+ @param SystemTable - The pointer of EFI_SYSTEM_TABLE
+
+ @retval EFI_SUCCESS - The driver initialized successfully
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeElogLayer (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HANDLE NewHandle;
+ EFI_STATUS Status;
+ EFI_SM_ELOG_PROTOCOL *ElogProtocol;
+ EFI_EVENT Event;
+
+ mElogModuleGlobal = AllocateZeroPool (sizeof (ELOG_MODULE_GLOBAL));
+ ASSERT (mElogModuleGlobal != NULL);
+ if (mElogModuleGlobal == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ElogServiceInitialize (ImageHandle, SystemTable);
+
+ mElogModuleGlobal->MaxDescriptors = MAX_REDIR_DESCRIPTOR;
+
+ //
+ // Check for all IPMI Controllers
+ //
+ SetElogRedirInstances ();
+
+ ElogProtocol = AllocatePool (sizeof (EFI_SM_ELOG_PROTOCOL));
+ ASSERT (ElogProtocol != NULL);
+ if (ElogProtocol == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ElogProtocol->ActivateEventLog = EfiActivateElog;
+ ElogProtocol->EraseEventlogData = EfiEraseElogData;
+ ElogProtocol->GetEventLogData = EfiGetElogData;
+ ElogProtocol->SetEventLogData = EfiSetElogData;
+
+ NewHandle = NULL;
+ Status = gBS->InstallProtocolInterface (
+ &NewHandle,
+ &gEfiGenericElogProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ ElogProtocol
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ //
+ // Register to be notified when the ELOG REDIR protocol has been
+ // produced.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ NotifyElogRedirEventCallback,
+ NULL,
+ &Event
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->RegisterProtocolNotify (
+ &gEfiRedirElogProtocolGuid,
+ Event,
+ &mEfiElogRedirProtocolEvent
+ );
+ }
+
+ return Status;
+}
+
+/**
+ Set the function entry.
+
+ @param FunctionPointer - The destination function pointer
+ @param Function - The source function pointer
+
+ @retval EFI_SUCCESS - Set the function pointer successfully
+
+**/
+EFI_STATUS
+EfiSetFunctionEntry (
+ IN FUNCTION_PTR *FunctionPointer,
+ IN VOID *Function
+ )
+{
+ FunctionPointer->Function = (EFI_PLABEL *)Function;
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize Dxe generic event log.
+
+ @param ImageHandle - The Image handle of this driver.
+ @param SystemTable - The pointer of EFI_SYSTEM_TABLE.
+
+ @retval EFI_SUCCESS - The driver successfully initialized
+
+**/
+EFI_STATUS
+ElogServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.c
new file mode 100644
index 000000000000..d6a129a181fb
--- /dev/null
+++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/GenericElog.c
@@ -0,0 +1,558 @@
+/** @file
+ Generic Event Log functions of SMM driver.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "GenericElog.h"
+
+ELOG_MODULE_GLOBAL *mElogModuleGlobal;
+
+//
+// Define module globals used to register for notification of when
+// the ELOG REDIR protocol has been produced.
+//
+EFI_EVENT mEfiElogRedirProtocolEvent;
+
+/**
+ Sends the Event-Log data to the destination.
+
+ @param ElogData - Pointer to the Event-Log data that needs to be recorded.
+ @param DataType - Type of Elog Data that is being recorded.
+ @param AlertEvent - This is an indication that the input data type is an Alert.
+ @param DataSize - Size of the data to be logged.
+ @param RecordId - Record ID sent by the target.
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was recorded successfully.
+ @retval EFI_OUT_OF_RESOURCES - Not enough resources to record data.
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported.
+
+**/
+EFI_STATUS
+EfiLibSetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId,
+ IN ELOG_MODULE_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].SetEventLogData.Function;
+ Status = (*((EFI_SET_ELOG_DATA *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, ElogData, DataType, AlertEvent, DataSize, RecordId);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Efi Set Elog Data.
+
+ @param This
+ @param ElogData
+ @param DataType
+ @param AlertEvent
+ @param DataSize
+ @param RecordId
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiSetElogData (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN AlertEvent,
+ IN UINTN DataSize,
+ OUT UINT64 *RecordId
+ )
+{
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EfiLibSetElogData (
+ ElogData,
+ DataType,
+ AlertEvent,
+ DataSize,
+ RecordId,
+ mElogModuleGlobal,
+ FALSE
+ );
+}
+
+/**
+ Gets the Event-Log data from the destination.
+
+ @param ElogData - Pointer to the Event-Log data buffer that will contain the data to be retrieved.
+ @param DataType - Type of Elog Data that is being recorded.
+ @param DataSize - Size of the data to be retrieved. .
+ @param RecordId - This is the RecordId of the next record. If ElogData is NULL,
+ this gives the RecordId of the first record available in the database with the correct DataSize.
+ A value of 0 on return indicates the last record if the EFI_STATUS indicates a success
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was retrieved successfully.
+ @retval EFI_NOT_FOUND - Event-Log target not found.
+ @retval EFI_BUFFER_TOO_SMALL - Target buffer is too small to retrieve the data.
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+
+**/
+EFI_STATUS
+EfiLibGetElogData (
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId,
+ IN ELOG_MODULE_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].GetEventLogData.Function;
+ Status = (*((EFI_GET_ELOG_DATA *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, ElogData, DataType, DataSize, RecordId);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Efi Get Elog Data.
+
+ @param This
+ @param ElogData
+ @param DataType
+ @param DataSize
+ @param RecordId
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiGetElogData (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN UINT8 *ElogData,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINTN *DataSize,
+ IN OUT UINT64 *RecordId
+ )
+{
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EfiLibGetElogData (ElogData, DataType, DataSize, RecordId, mElogModuleGlobal, FALSE);
+}
+
+/**
+ Erases the Event-Log data from the destination.
+
+ @param DataType - Type of Elog Data that is being Erased.
+ @param RecordId - This is the RecordId of the data to be erased. If RecordId is NULL, all
+ the records on the database are erased if permitted by the target.
+ Contains the deleted RecordId on return
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was erased successfully
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+ @retval EFI_NOT_FOUND - Event-Log target not found
+
+**/
+EFI_STATUS
+EfiLibEraseElogData (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId,
+ IN ELOG_MODULE_GLOBAL *Global,
+ IN BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].EraseEventLogData.Function;
+ Status = (*((EFI_ERASE_ELOG_DATA *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, DataType, RecordId);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Efi Erase Elog Data
+
+ @param This
+ @param DataType
+ @param RecordId
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiEraseElogData (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN OUT UINT64 *RecordId
+ )
+{
+ return EfiLibEraseElogData (DataType, RecordId, mElogModuleGlobal, FALSE);
+}
+
+/**
+ This API enables/Disables Event Log.
+
+ @param DataType - Type of Elog Data that is being Activated.
+ @param EnableElog - Enables (TRUE) / Disables (FALSE) Event Log. If NULL just returns the
+ Current ElogStatus.
+ @param ElogStatus - Current (New) Status of Event Log. Enabled (TRUE), Disabled (FALSE).
+ @param Global - The module global variable pointer.
+ @param Virtual - If this function is called in virtual mode or physical mode
+
+ @retval EFI_SUCCESS - Event-Log was recorded successfully
+ @retval EFI_UNSUPPORTED - The Data Type is unsupported
+
+**/
+EFI_STATUS
+EfiLibActivateElog (
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus,
+ ELOG_MODULE_GLOBAL *Global,
+ BOOLEAN Virtual
+ )
+{
+ UINT8 Index;
+ VOID *ElogRedirCommand;
+ EFI_STATUS Status;
+ EFI_STATUS RetStatus;
+
+ RetStatus = EFI_UNSUPPORTED;
+ if (DataType >= EfiSmElogMax) {
+ RetStatus = EFI_INVALID_PARAMETER;
+ return RetStatus;
+ }
+
+ for (Index = 0; Index < Global->MaxDescriptors; Index++) {
+ if (Global->Redir[Index].Valid) {
+ ElogRedirCommand = Global->Redir[Index].Command[Virtual].ActivateEventLog.Function;
+ Status = (*((EFI_ACTIVATE_ELOG *)&ElogRedirCommand))(Global->Redir[Index].Command[Virtual].This, DataType, EnableElog, ElogStatus);
+
+ if (!EFI_ERROR (Status)) {
+ RetStatus = EFI_SUCCESS;
+ break;
+ } else if (Status != EFI_UNSUPPORTED) {
+ RetStatus = Status;
+ break;
+ }
+ }
+ }
+
+ return RetStatus;
+}
+
+/**
+ Efi Activate Elog.
+
+ @param This
+ @param DataType
+ @param EnableElog
+ @param ElogStatus
+
+ @retval EFI_SUCCESS
+
+**/
+EFI_STATUS
+EfiActivateElog (
+ IN EFI_SM_ELOG_PROTOCOL *This,
+ IN EFI_SM_ELOG_TYPE DataType,
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ )
+{
+ if (DataType >= EfiSmElogMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EfiLibActivateElog (DataType, EnableElog, ElogStatus, mElogModuleGlobal, FALSE);
+}
+
+/**
+ Set Elog Redir Instances.
+
+ @retval EFI_SUCCESS - The Redir instances were successfully set.
+ @retval Other - Failed to set Redir instances.
+
+**/
+EFI_STATUS
+SetElogRedirInstances (
+ VOID
+ )
+{
+ UINTN NumHandles;
+ UINTN Index;
+ UINTN Instance;
+ UINTN EmptyIndex;
+ EFI_HANDLE *Buffer;
+ EFI_STATUS Status;
+ EFI_SM_ELOG_REDIR_PROTOCOL *Redir;
+ REDIR_MODULE_PROC *RedirProc;
+
+ Buffer = NULL;
+
+ //
+ // Check for all IPMI Controllers
+ //
+ Status = gSmst->SmmLocateHandle (
+ ByProtocol,
+ &gSmmRedirElogProtocolGuid,
+ NULL,
+ &NumHandles,
+ Buffer
+ );
+
+ if (EFI_ERROR (Status) || (NumHandles == 0) || (Buffer == NULL)) {
+ return Status;
+ }
+
+ for (Index = 0; ((Index < NumHandles) && (Index < mElogModuleGlobal->MaxDescriptors)); Index++) {
+ EmptyIndex = mElogModuleGlobal->MaxDescriptors;
+
+ Status = gSmst->SmmHandleProtocol (
+ Buffer[Index],
+ &gSmmRedirElogProtocolGuid,
+ (VOID *)&Redir
+ );
+ if (EFI_ERROR (Status) || (Redir == NULL)) {
+ continue;
+ }
+
+ for (Instance = 0; Instance < mElogModuleGlobal->MaxDescriptors; Instance++) {
+ if (mElogModuleGlobal->Redir[Instance].Valid == FALSE) {
+ if (EmptyIndex >= mElogModuleGlobal->MaxDescriptors) {
+ EmptyIndex = Instance;
+ }
+ } else {
+ if (Redir == mElogModuleGlobal->Redir[Instance].Command->This) {
+ EmptyIndex = mElogModuleGlobal->MaxDescriptors;
+ break;
+ //
+ // FIX: changed continue to break.
+ //
+ }
+ }
+ }
+
+ if (EmptyIndex < mElogModuleGlobal->MaxDescriptors) {
+ RedirProc = (REDIR_MODULE_PROC *)mElogModuleGlobal->Redir[EmptyIndex].Command;
+ mElogModuleGlobal->Redir[EmptyIndex].Valid = TRUE;
+
+ EfiSetFunctionEntry (&RedirProc->ActivateEventLog, *((VOID **)&Redir->ActivateEventLog));
+ EfiSetFunctionEntry (&RedirProc->EraseEventLogData, *((VOID **)&Redir->EraseEventlogData));
+ EfiSetFunctionEntry (&RedirProc->GetEventLogData, *((VOID **)&Redir->GetEventLogData));
+ EfiSetFunctionEntry (&RedirProc->SetEventLogData, *((VOID **)&Redir->SetEventLogData));
+ RedirProc->This = Redir;
+
+ CopyMem (&RedirProc[EFI_ELOG_VIRTUAL], &RedirProc[EFI_ELOG_PHYSICAL], sizeof (REDIR_MODULE_PROC));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This notification function is invoked when an instance of the
+ ELOG REDIR protocol is produced.
+
+ @param Event - The event that occurred
+ @param Context - For EFI compatibility. Not used.
+
+**/
+VOID
+EFIAPI
+NotifyElogRedirEventCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ SetElogRedirInstances ();
+}
+
+/**
+ Initialize the generic Elog driver of server management.
+
+ @param ImageHandle - The image handle of this driver
+ @param SystemTable - The pointer of EFI_SYSTEM_TABLE
+
+ @retval EFI_SUCCESS - The driver initialized successfully
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeSmElogLayer (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HANDLE NewHandle;
+ EFI_STATUS Status;
+ EFI_SM_ELOG_PROTOCOL *ElogProtocol;
+
+ mElogModuleGlobal = AllocatePool (sizeof (ELOG_MODULE_GLOBAL));
+ ASSERT (mElogModuleGlobal != NULL);
+ if (mElogModuleGlobal == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SmElogServiceInitialize (ImageHandle, SystemTable);
+
+ mElogModuleGlobal->MaxDescriptors = MAX_REDIR_DESCRIPTOR;
+
+ //
+ // Check for all IPMI Controllers
+ //
+ SetElogRedirInstances ();
+
+ ElogProtocol = AllocatePool (sizeof (EFI_SM_ELOG_PROTOCOL));
+ ASSERT (ElogProtocol != NULL);
+ if (ElogProtocol == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ElogProtocol->ActivateEventLog = (EFI_ACTIVATE_ELOG)EfiActivateElog;
+ ElogProtocol->EraseEventlogData = (EFI_ERASE_ELOG_DATA)EfiEraseElogData;
+ ElogProtocol->GetEventLogData = (EFI_GET_ELOG_DATA)EfiGetElogData;
+ ElogProtocol->SetEventLogData = (EFI_SET_ELOG_DATA)EfiSetElogData;
+
+ NewHandle = NULL;
+ Status = gSmst->SmmInstallProtocolInterface (
+ &NewHandle,
+ &gSmmGenericElogProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ ElogProtocol
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ //
+ // Register to be notified when the ELOG REDIR protocol has been
+ // produced.
+ //
+ Status = gSmst->SmmRegisterProtocolNotify (
+ &gSmmRedirElogProtocolGuid,
+ NULL,
+ &mEfiElogRedirProtocolEvent
+ );
+ return Status;
+}
+
+/**
+ Set the function entry.
+
+ @param FunctionPointer - The destination function pointer
+ @param Function - The source function pointer
+
+ @retval EFI_SUCCESS - Set the function pointer successfully
+
+**/
+EFI_STATUS
+EfiSetFunctionEntry (
+ IN FUNCTION_PTR *FunctionPointer,
+ IN VOID *Function
+ )
+{
+ FunctionPointer->Function = (EFI_PLABEL *)Function;
+ return EFI_SUCCESS;
+}
+
+/**
+ Entry point of SM Elog service Driver
+
+ @param ImageHandle - The Image handle of this driver.
+ @param SystemTable - The pointer of EFI_SYSTEM_TABLE.
+
+ @retval EFI_SUCCESS - The driver successfully initialized
+
+**/
+EFI_STATUS
+SmElogServiceInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
--
2.39.2.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#110229): https://edk2.groups.io/g/devel/message/110229
Mute This Topic: https://groups.io/mt/102231766/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-10-27 22:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-27 20:11 [edk2-devel] [PATCH edk2-platforms 0/4] IpmiFeaturePkg: Add server management features Zhen Gong
2023-10-27 20:11 ` Zhen Gong [this message]
2023-10-27 20:11 ` [edk2-devel] [PATCH edk2-platforms 2/4] IpmiFeaturePkg: Add ServerManagementLib Zhen Gong
2023-10-27 20:11 ` [edk2-devel] [PATCH edk2-platforms 3/4] IpmiFeaturePkg: Add ACPI power state drivers Zhen Gong
2023-10-27 20:11 ` [edk2-devel] [PATCH edk2-platforms 4/4] IpmiFeaturePkg: Add FRU drivers Zhen Gong
2023-10-29 1:58 ` [edk2-devel] [PATCH edk2-platforms 0/4] IpmiFeaturePkg: Add server management features Chang, Abner via groups.io
2023-10-29 21:07 ` Zhen Gong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=151e2cd3461b6c577cd15e0ce862309e409129f0.1698437221.git.zhen.gong@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox