From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 3BA7ED800D7 for ; Fri, 27 Oct 2023 22:38:07 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=iXsYQzXN3FtcmJkxg3DdSDLbfJi0Ok2/wqOqMq8/YLI=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1698446285; v=1; b=t8QQVNl+okhkTFNGJ5unEFmt7pLpAZI2NVZQ/aUCjATCe2JxQqOhTEdwU6IbBkLKms8Jjw70 I4v9DxUkh7Qwe0HKBIqYGT7EPIDN1FEF5MCfWonwvzW8ZS65ELkWl+Ds2U8jvX6ous/VHQRoq0k JIYiZWXFTZUAL7qPAP9IwHH0= X-Received: by 127.0.0.2 with SMTP id 8h8OYY7687511xMiHmqh8Msq; Fri, 27 Oct 2023 15:38:05 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.126]) by mx.groups.io with SMTP id smtpd.web10.16428.1698437518249532788 for ; Fri, 27 Oct 2023 13:11:58 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10876"; a="372897515" X-IronPort-AV: E=Sophos;i="6.03,257,1694761200"; d="scan'208";a="372897515" X-Received: from fmviesa002.fm.intel.com ([10.60.135.142]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Oct 2023 13:11:57 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.03,257,1694761200"; d="scan'208";a="948589" X-Received: from scsrds0181.amr.corp.intel.com ([10.116.50.7]) by fmviesa002.fm.intel.com with ESMTP; 27 Oct 2023 13:11:46 -0700 From: Zhen Gong To: devel@edk2.groups.io Cc: Zhen Gong Subject: [edk2-devel] [PATCH edk2-platforms 1/4] IpmiFeaturePkg: Add Elog drivers Date: Fri, 27 Oct 2023 13:11:13 -0700 Message-Id: <151e2cd3461b6c577cd15e0ce862309e409129f0.1698437221.git.zhen.gong@intel.com> In-Reply-To: References: MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,zhen.gong@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: GrsfpLeWCgBGTzNLeW8PouSBx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=t8QQVNl+; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none) Add generic Elog driver and support BMC Elog operations. Signed-off-by: Zhen Gong --- .../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.
+# Copyright (c) 2023, Intel Corporation. All rights reserved.
# # 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.
+# +# 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.
+# +# 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.
+# +# 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.
+# +# 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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _BMCELOG_COMMON_H_ +#define _BMCELOG_COMMON_H_ + +// +// Statements that include other files +// +#include +#include +#include +#include +#include +#include +#include "ServerManagement.h" +#include +#include +#include + +#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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_BMCELOG_H_ +#define _EFI_BMCELOG_H_ + +// +// Statements that include other files +// + +#include +#include +#include +#include +#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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_PEIBMCELOG_H_ +#define _EFI_PEIBMCELOG_H_ + +// +// Statements that include other files +// + +#include +#include +#include +#include +#include +#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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_BMCELOG_H_ +#define _SMM_BMCELOG_H_ + +// +// Statements that include other files +// + +#include +#include +#include +#include +#include +#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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _EFI_GENELOG_H_ +#define _EFI_GENELOG_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ServerManagement.h" + +#include +#include + +#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.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SMM_GENELOG_H_ +#define _SMM_GENELOG_H_ + +#include +#include +#include +#include + +#include +#include +#include + +#include "ServerManagement.h" +#include +#include + +#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.
+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.
+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.
-SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include - -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.
+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.
+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.
+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.
+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.
+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.
+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] -=-=-=-=-=-=-=-=-=-=-=-