From nobody Mon Feb 9 06:02:13 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+110326+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+110326+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1698686019; cv=none; d=zohomail.com; s=zohoarc; b=S8jJJMa1B5AFeCqCGdh/vcnTKWL51CAN+fPveXzWMKg5mZ+Y6nughPSAphcKNdLGE9GnS8OMNV7xvt4wME7mGpOsoz7AiOl8Xar/95voc7h05EJLCIMe8s5oJmTUkNQQvb3+N5VYThilMiJdkWlIxkP1jrMpfpmJKyPqAqMruxU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1698686019; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=PBx3uRPs437JD3nwQUxvEk3MB5OuU5iLSOWR9FLec7A=; b=aKSDV32M3qu7qRQDS9wRJS9fje73QxTHgtovEugJdtx1TyLQV/7wgm3iDzF2l0I1TiJFG5Ku/4C1ZpF/novdxXsVDnmhZ8sAJjfHPISftuU45cwf1Sk+vwAJZpChqm20xF/gUsiEWwMdy16Jo+cZCBY/t8N/8Ye0Jw0vRXjwzcs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+110326+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1698686019351867.3592792806921; Mon, 30 Oct 2023 10:13:39 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=oYaWsWpiyW7e2Ru6Y+f3BMYRCdoSKdll+zQN4g2EKW4=; 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=1698686018; v=1; b=kMCzJzkfFxDwvJ2cfBUnGb3vevU58diSZZjaD/gq9QChBksglJdkzc/zabtISQFGqMuthwxt BUyCDJnTmflxFI6IfnbDC+ilaa/JV/nSy72ChSy5D7FuYJyw5n9VIH5dWyPvQ0LjE0xBLygUw4d 8Ilo61JVG1AQP7qIfqn92ZB8= X-Received: by 127.0.0.2 with SMTP id pklzYY1788612xL3imSLjuP3; Mon, 30 Oct 2023 10:13:38 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web10.80041.1698611264012724787 for ; Sun, 29 Oct 2023 13:27:49 -0700 X-IronPort-AV: E=McAfee;i="6600,9927,10878"; a="390840888" X-IronPort-AV: E=Sophos;i="6.03,261,1694761200"; d="scan'208";a="390840888" X-Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 29 Oct 2023 13:27:48 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10878"; a="795098438" X-IronPort-AV: E=Sophos;i="6.03,261,1694761200"; d="scan'208";a="795098438" X-Received: from scsrds0181.amr.corp.intel.com ([10.116.50.7]) by orsmga001.jf.intel.com with ESMTP; 29 Oct 2023 13:27:48 -0700 From: "Zhen Gong" To: devel@edk2.groups.io Cc: Zhen Gong Subject: [edk2-devel] [PATCH edk2-platforms v2 1/4] IpmiFeaturePkg: Add Elog drivers Date: Sun, 29 Oct 2023 13:27:37 -0700 Message-Id: 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: Nz88rytTKOk99MPKQliROua3x1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1698686020250100006 Content-Type: text/plain; charset="utf-8" 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 =3D> DxeBmcElog.inf} | 19 +- .../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, 3530 insertions(+), 243 deletions(-) rename Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/{BmcElog.= inf =3D> DxeBmcElog.inf} (60%) create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/PeiBmcElog.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/SmmBmcElog.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icElog/Dxe/GenericElog.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icElog/Smm/GenericElog.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Common/BmcElogCommon.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Dxe/BmcElog.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Pei/BmcElog.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Smm/BmcElog.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icElog/Dxe/GenericElog.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icElog/Smm/GenericElog.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Ppi/GenericElog.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Protocol/GenericElog.h delete mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/BmcElog.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Common/BmcElogCommon.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Dxe/BmcElog.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Pei/BmcElog.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcEl= og/Smm/BmcElog.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icElog/Dxe/GenericElog.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Gener= icElog/Smm/GenericElog.c diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeatureP= kg.dec b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/IpmiFeaturePkg.d= ec 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 =3D {0x7bf5fecc, 0xc5b5, 0x4b25, {0x81, 0x1b, 0= xb4, 0xb5, 0xb, 0x28, 0x79, 0xf7}} gPeiIpmiTransport2PpiGuid =3D {0x8122CEBD, 0xF4FD, 0x4EA8, { 0x97, 0x6C,= 0xF0, 0x30, 0xAD, 0xDC, 0x4C, 0xB4 }} + gPeiRedirElogPpiGuid =3D { 0x7a7c1591, 0xfc67, 0x4f69, { 0xa3, 0x78, 0xf= c, 0x3d, 0x4a, 0xd7, 0x92, 0xf7 } } =20 [Protocols] gIpmiTransportProtocolGuid =3D {0x6bb945e8, 0x3743, 0x433e, {0xb9, 0x0e= , 0x29, 0xb3, 0x0d, 0x5d, 0xc6, 0x30}} @@ -74,6 +75,10 @@ [Protocols] gEfiVideoPrintProtocolGuid =3D {0x3dbf3e06, 0x9d0c, 0x40d3, {0xb2, 0= x17, 0x45, 0x5f, 0x33, 0x9e, 0x29, 0x09}} gIpmiTransport2ProtocolGuid =3D { 0x4A1D0E66, 0x5271, 0x4E22, { 0x83, 0x= FE, 0x90, 0x92, 0x1B, 0x74, 0x82, 0x13 }} gSmmIpmiTransport2ProtocolGuid =3D { 0x1DBD1503, 0x0A60, 0x4230, { 0xAA,= 0xA3, 0x80, 0x16, 0xD8, 0xC3, 0xDE, 0x2F }} + gEfiGenericElogProtocolGuid =3D { 0x59d02fcd, 0x9233, 0x4d34, { 0xbc, 0x= fe, 0x87, 0xca, 0x81, 0xd3, 0xdd, 0xa7 } } + gSmmGenericElogProtocolGuid =3D { 0x664ef1f6, 0x19bf, 0x4498, { 0xab, 0x= 6a, 0xfc, 0x05, 0x72, 0xfb, 0x98, 0x51 } } + gEfiRedirElogProtocolGuid =3D { 0x16d11030, 0x71ba, 0x4e5e, { 0xa9, 0xf9= , 0xb4, 0x75, 0xa5, 0x49, 0x4, 0x8a } } + gSmmRedirElogProtocolGuid =3D { 0x79ac2d9c, 0x9216, 0x43c5, { 0xa0, 0x74= , 0x0b, 0x45, 0xc7, 0x64, 0x22, 0xc1 } } =20 [PcdsFeatureFlag] gIpmiFeaturePkgTokenSpaceGuid.PcdIpmiFeatureEnable|FALSE|BOOLEAN|0xA0000= 001 diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipmi= Feature.dsc b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipm= iFeature.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/IpmbInt= erfaceLib/DxeIpmbInterfaceLib.inf =20 [LibraryClasses.common.DXE_SMM_DRIVER] + IpmiBaseLib|IpmiFeaturePkg/Library/SmmIpmiBaseLib/SmmIpmiBaseLib.inf SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInt= erfaceLib/SmmSsifInterfaceLib.inf IpmbInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/IpmbInt= erfaceLib/SmmIpmbInterfaceLib.inf =20 @@ -96,6 +97,7 @@ [Components.IA32] IpmiFeaturePkg/GenericIpmi/Pei/PeiGenericIpmi.inf IpmiFeaturePkg/Frb/FrbPei.inf IpmiFeaturePkg/IpmiInit/PeiIpmiInit.inf + IpmiFeaturePkg/BmcElog/PeiBmcElog.inf =20 # # 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/Post= Memory.fdf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Post= Memory.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 =3D 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/PreM= emory.fdf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PreMe= mory.fdf index d214988bd141..ca20546e9aa8 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PreMemory.f= df +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/PreMemory.f= df @@ -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/BmcE= log.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/DxeBmcE= log.inf similarity index 60% rename from Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/BmcEl= og.inf rename to Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/DxeBmcE= log.inf index 1e7a7658b7b0..7d8db9b633de 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 # ### =20 + [Defines] INF_VERSION =3D 0x00010005 BASE_NAME =3D BmcElog @@ -17,7 +17,10 @@ [Defines] ENTRY_POINT =3D InitializeBmcElogLayer =20 [Sources] - BmcElog.c + Dxe/BmcElog.c + Dxe/BmcElog.h + Common/BmcElogCommon.h + Common/BmcElogCommon.c =20 [Packages] MdePkg/MdePkg.dec @@ -28,7 +31,13 @@ [LibraryClasses] UefiDriverEntryPoint DebugLib UefiBootServicesTableLib - IpmiCommandLib + ReportStatusCodeLib + MemoryAllocationLib + IpmiBaseLib + +[Protocols] + gEfiRedirElogProtocolGuid # PROTOCOL ALWAYS_PRODUCED =20 [Depex] - TRUE + gEfiLoadedImageProtocolGuid AND + gIpmiTransportProtocolGuid diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/PeiB= mcElog.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/PeiB= mcElog.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 =3D 0x00010005 + BASE_NAME =3D BmcElog + FILE_GUID =3D FD2A000E-09EA-4899-B40E-32BE30A58EBD + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D 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/SmmB= mcElog.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/SmmB= mcElog.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 =3D 0x00010005 + BASE_NAME =3D SmBmcElog + FILE_GUID =3D BE29A700-9D5A-4bb9-86B1-D1DB7A05D594 + MODULE_TYPE =3D DXE_SMM_DRIVER + PI_SPECIFICATION_VERSION =3D 0x0001000A + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D 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/Gen= ericElog/Dxe/GenericElog.inf new file mode 100644 index 000000000000..1073d3687d38 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/Gen= ericElog.inf @@ -0,0 +1,38 @@ +### @file +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +### + + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D GenericElog + FILE_GUID =3D FD2D7E66-C5A7-47de-BDCC-4F1B5DC6ADA8 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D 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/Gen= ericElog/Smm/GenericElog.inf new file mode 100644 index 000000000000..00f4154cdd39 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/Gen= ericElog.inf @@ -0,0 +1,38 @@ +### @file +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +### + + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D SmGenericElog + FILE_GUID =3D 870B000E-D3AD-4fb2-B846-AB0ADE8799CB + MODULE_TYPE =3D DXE_SMM_DRIVER + PI_SPECIFICATION_VERSION =3D 0x0001000A + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D 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/Comm= on/BmcElogCommon.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcE= log/Common/BmcElogCommon.h new file mode 100644 index 000000000000..23c535d1dd6c --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcE= logCommon.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 er= ror 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/B= mcElog.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/B= mcElog.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/B= mcElog.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_INSTA= NCE_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/Gener= icElog/Dxe/GenericElog.h new file mode 100644 index 000000000000..460185455648 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/Gen= ericElog.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 L= og. If NULL just returns the + Current ElogStatus. + @param ElogStatus - Current (New) Status of Event Log. Enable= d (TRUE), Disabled (FALSE). + @param Global - The module global variable pointer. + @param Virtual - If this function is called in virtual mod= e 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/Gener= icElog/Smm/GenericElog.h new file mode 100644 index 000000000000..ad6530616309 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/Gen= ericElog.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 mod= e 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 recor= d 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 mod= e 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 t= he 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 er= ased. 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 mod= e 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 L= og. If NULL just returns the + Current ElogStatus. + @param ElogStatus - Current (New) Status of Event Log. Enable= d (TRUE), Disabled (FALSE). + @param Global - The module global variable pointer. + @param Virtual - If this function is called in virtual mod= e 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/P= pi/GenericElog.h new file mode 100644 index 000000000000..4b3b3ee2af33 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ppi/Generic= Elog.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/Prot= ocol/GenericElog.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Incl= ude/Protocol/GenericElog.h new file mode 100644 index 000000000000..19726ff58f0f --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Protocol/Ge= nericElog.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, 0= x8a \ + } + +// +// 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/BmcE= log.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 =3D 0x200; - ZeroMem (&ClearSelResponse, sizeof(ClearSelResponse)); - - while (TRUE) { - ZeroMem (&ClearSel, sizeof(ClearSel)); - ClearSel.Reserve[0] =3D ResvId[0]; - ClearSel.Reserve[1] =3D ResvId[1]; - ClearSel.AscC =3D 0x43; - ClearSel.AscL =3D 0x4C; - ClearSel.AscR =3D 0x52; - ClearSel.Erase =3D 0x00; - - IpmiClearSel ( - &ClearSel, - &ClearSelResponse - ); - - if ((ClearSelResponse.ErasureProgress & 0xf) =3D=3D 1) { - return EFI_SUCCESS; - } - // - // If there is not a response from the BMC controller we need to retu= rn and not hang. - // - --Counter; - if (Counter =3D=3D 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 =3D EFI_SUCCESS; - ElogStat =3D 0; - - Status =3D IpmiGetBmcGlobalEnables (&GetBmcGlobalEnables); - if (EFI_ERROR(Status)) { - return Status; - } - - if (EnableElog =3D=3D NULL) { - *ElogStatus =3D GetBmcGlobalEnables.GetEnables.Bits.SystemEventLogging; - } else { - if (Status =3D=3D EFI_SUCCESS) { - if (*EnableElog) { - ElogStat =3D 1; - } - - CopyMem (&SetBmcGlobalEnables, (UINT8 *)&GetBmcGlobalEnables + 1, si= zeof(UINT8)); - SetBmcGlobalEnables.SetEnables.Bits.SystemEventLogging =3D ElogStat; - - Status =3D IpmiSetBmcGlobalEnables (&SetBmcGlobalEnables, &Completio= nCode); - } - } - - 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 =3D IpmiGetSelInfo (&SelInfo); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } - - // - // Check the Bit7 of the OperationByte if SEL is OverFlow. - // - SelIsFull =3D (SelInfo.OperationSupport & 0x80); - DEBUG ((DEBUG_INFO, "SelIsFull - 0x%x\n", SelIsFull)); - - return EFI_SUCCESS; -} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Comm= on/BmcElogCommon.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcE= log/Common/BmcElogCommon.c new file mode 100644 index 000000000000..b0688e3afb6c --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/BmcElog/Common/BmcE= logCommon.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 =3D 0x200; + Status =3D EFI_SUCCESS; + while (TRUE) { + ClearSelRequest.Reserve[0] =3D ResvId[0]; + ClearSelRequest.Reserve[1] =3D ResvId[1]; + ClearSelRequest.AscC =3D IPMI_CLEAR_SEL_REQUEST_C_CHAR_ASCII; + ClearSelRequest.AscL =3D IPMI_CLEAR_SEL_REQUEST_L_CHAR_ASCII; + ClearSelRequest.AscR =3D IPMI_CLEAR_SEL_REQUEST_R_CHAR_ASCII; + ClearSelRequest.Erase =3D IPMI_CLEAR_SEL_REQUEST_GET_ERASE_STATUS; + ResponseDataSize =3D sizeof (ClearSelResponse); + + Status =3D 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) =3D=3D IPMI_CLEAR_SEL_RES= PONSE_ERASURE_COMPLETED) { + return EFI_SUCCESS; + } + + // + // If there is not a response from the BMC controller we need to retu= rn and not hang. + // + --Counter; + if (Counter =3D=3D 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 =3D EFI_SUCCESS; + CopyMem (&AddSelRequest.RecordData, ElogData, Size); + + *RecordId =3D 0; + + if (AlertEvent) { + EvntMsgRequest.GeneratorId =3D (UINT8)AddSelRequest.RecordData.Genera= torId; + EvntMsgRequest.EvMRevision =3D AddSelRequest.RecordData.EvMRevision; + EvntMsgRequest.SensorType =3D AddSelRequest.RecordData.SensorType; + EvntMsgRequest.SensorNumber =3D AddSelRequest.RecordData.SensorNumber; + EvntMsgRequest.EventDirType =3D AddSelRequest.RecordData.EventDirType; + EvntMsgRequest.OEMEvData1 =3D AddSelRequest.RecordData.OEMEvData1; + EvntMsgRequest.OEMEvData2 =3D AddSelRequest.RecordData.OEMEvData2; + EvntMsgRequest.OEMEvData3 =3D AddSelRequest.RecordData.OEMEvData3; + + ResponseDataSize =3D sizeof (EvntMsgResponse); + Status =3D IpmiSubmitCommand ( + IPMI_NETFN_SENSOR_EVENT, + IPMI_SENSOR_PLATFORM_EVENT_MESSAGE, + (UINT8 *)&EvntMsgRequest, + sizeof (EvntMsgRequest), + (UINT8 *)&EvntMsgResponse, + &ResponseDataSize + ); + } else { + ResponseDataSize =3D sizeof (AddSelResponse); + Status =3D IpmiSubmitCommand ( + IPMI_NETFN_STORAGE, + IPMI_STORAGE_ADD_SEL_ENTRY, + (UINT8 *)&AddSelRequest, + sizeof (AddSelRequest), + (UINT8 *)&AddSelResponse, + &ResponseDataSize + ); + + if (Status =3D=3D EFI_SUCCESS) { + *RecordId =3D 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 =3D EFI_SUCCESS; + ReceiveKey =3D *RecordId; + GetSelEntryRequest.ReserveId[0] =3D 0; + GetSelEntryRequest.ReserveId[1] =3D 0; + GetSelEntryRequest.SelRecID[0] =3D (UINT8)ReceiveKey; + ReceiveKey =3D DivU64x32 (ReceiveKey, (UINT32)(1 <<= 8)); + GetSelEntryRequest.SelRecID[1] =3D (UINT8)ReceiveKey; + GetSelEntryRequest.Offset =3D 0; + GetSelEntryRequest.BytesToRead =3D IPMI_COMPLETE_SEL_RECORD; + ResponseDataSize =3D sizeof (GetSelEntryResponse); + + Status =3D 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 =3D=3D EFI_SUCCESS) { + if (*Size < (SEL_RECORD_SIZE)) { + return EFI_BUFFER_TOO_SMALL; + } + + if (GetSelEntryResponse.NextSelRecordId =3D=3D 0xFFFF) { + return EFI_NOT_FOUND; + } + + *RecordId =3D GetSelEntryResponse.NextSelRecordId; + CopyMem (ElogData, &GetSelEntryResponse.RecordData, sizeof (GetSelEntr= yResponse.RecordData)); + *Size =3D 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 =3D 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 =3D sizeof (GetSelInfoResponse); + Status =3D IpmiSubmitCommand ( + IPMI_NETFN_STORAGE, + IPMI_STORAGE_GET_SEL_INFO, + NULL, + 0, + (UINT8 *)&GetSelInfoResponse, + &ResponseDataSize + ); + if (EFI_ERROR (Status)) { + return Status; + } + + OperationSupport =3D GetSelInfoResponse.OperationSupport; + SelReserveIdvalue =3D (OperationSupport & IPMI_GET_SEL_INFO_OPERATION_SU= PPORT_RESERVE_SEL_CMD); + if (SelReserveIdvalue =3D=3D IPMI_GET_SEL_INFO_OPERATION_SUPPORT_RESERVE= _SEL_CMD) { + SelReserveIdIsSupported =3D TRUE; + } else { + SelReserveIdIsSupported =3D FALSE; + } + + // + // if SelReserveIdcommand not supported do not issue the RESERVE_SEL_ENT= RY command, and set the ResvId value to 0000h + // + + // + // Get the SEL reservation ID + // + + if (SelReserveIdIsSupported) { + ResponseDataSize =3D sizeof (ReserveSelResponse); + Status =3D IpmiSubmitCommand ( + IPMI_NETFN_STORAGE, + IPMI_STORAGE_RESERVE_SEL, + NULL, + 0, + (UINT8 *)&ReserveSelResponse, + &ResponseDataSize + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + ResvId[0] =3D ReserveSelResponse.ReservationId[0]; + ResvId[1] =3D ReserveSelResponse.ReservationId[1]; + } else { + ResvId[0] =3D 0x00; + ResvId[1] =3D 0x00; + } + + // + // Clear the SEL + // + if (RecordId !=3D NULL) { + ReceiveKey =3D *RecordId; + DeleteSelRequest.ReserveId[0] =3D ResvId[0]; + DeleteSelRequest.ReserveId[1] =3D ResvId[1]; + DeleteSelRequest.RecordToDelete[0] =3D (UINT8)ReceiveKey; + ReceiveKey =3D DivU64x32 (ReceiveKey, (UINT32)= (1 << 8)); + DeleteSelRequest.RecordToDelete[1] =3D (UINT8)ReceiveKey; + + ResponseDataSize =3D sizeof (DeleteSelResponse); + Status =3D IpmiSubmitCommand ( + IPMI_NETFN_STORAGE, + IPMI_STORAGE_DELETE_SEL_ENTRY, + (UINT8 *)&DeleteSelRequest, + sizeof (DeleteSelRequest), + (UINT8 *)&DeleteSelResponse, + &ResponseDataSize + ); + } else { + ClearSelRequest.Reserve[0] =3D ResvId[0]; + ClearSelRequest.Reserve[1] =3D ResvId[1]; + ClearSelRequest.AscC =3D IPMI_CLEAR_SEL_REQUEST_C_CHAR_ASCII; + ClearSelRequest.AscL =3D IPMI_CLEAR_SEL_REQUEST_L_CHAR_ASCII; + ClearSelRequest.AscR =3D IPMI_CLEAR_SEL_REQUEST_R_CHAR_ASCII; + ClearSelRequest.Erase =3D IPMI_CLEAR_SEL_REQUEST_INITIALIZE_ERASE; + ResponseDataSize =3D sizeof (ClearSelResponse); + + Status =3D IpmiSubmitCommand ( + IPMI_NETFN_STORAGE, + IPMI_STORAGE_CLEAR_SEL, + (UINT8 *)&ClearSelRequest, + sizeof (ClearSelRequest), + (UINT8 *)&ClearSelResponse, + &ResponseDataSize + ); + } + + if (Status =3D=3D EFI_SUCCESS) { + if (RecordId =3D=3D 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 =3D EFI_SUCCESS; + ElogStat =3D 0; + + ResponseDataSize =3D sizeof (GetBmcGlobalResponse); + Status =3D 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 Fai= led %r\n", Status)); + } + + if (EnableElog =3D=3D NULL) { + *ElogStatus =3D (UINT8)(GetBmcGlobalResponse.GetEnables.Bits.SystemEve= ntLogging); + } else { + if (Status =3D=3D EFI_SUCCESS) { + if (*EnableElog) { + ElogStat =3D 0x1; // Setting SystemEventLogging + } + + SetBmcGlobalRequest.SetEnables.Uint8 =3D GetBmcGlo= balResponse.GetEnables.Uint8; + SetBmcGlobalRequest.SetEnables.Bits.SystemEventLogging =3D ElogStat; + + ResponseDataSize =3D sizeof (SetBmcGlobalResponse); + Status =3D 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 =3D 0; + SelIsFull =3D 0; + + ResponseDataSize =3D sizeof (GetSelInfoResponse); + + Status =3D IpmiSubmitCommand ( + IPMI_NETFN_STORAGE, + IPMI_STORAGE_GET_SEL_INFO, + NULL, + 0, + (UINT8 *)&GetSelInfoResponse, + &ResponseDataSize + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + OperationSupportByte =3D GetSelInfoResponse.OperationSupport; + + // + // Check the Bit7 of the OperationByte if SEL is OverFlow. + // + SelIsFull =3D (OperationSupportByte & IPMI_GET_SEL_INFO_OPERATION_SUPPOR= T_OVERFLOW_FLAG); + + if (SelIsFull =3D=3D 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/B= mcElog.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 =3D 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (Size > SEL_RECORD_SIZE) { + return EFI_OUT_OF_RESOURCES; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D SetBmcElogRecord (ElogData, DataType, AlertEvent, Size, Rec= ordId); + } + + 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D EraseBmcElogRecord (DataType, RecordId); + + if (Status =3D=3D EFI_SUCCESS) { + if (RecordId !=3D NULL) { + *RecordId =3D (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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D 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 =3D EFI_SUCCESS; + EnableElog =3D TRUE; + ElogStatus =3D TRUE; + Instance =3D 0; + + mRedirProtoPrivate->Signature =3D EFI_ELOG_REDIR_SIGNATU= RE; + mRedirProtoPrivate->DataType =3D EfiElogSmIPMI; + mRedirProtoPrivate->BmcElog.ActivateEventLog =3D EfiActivateBmcElog; + mRedirProtoPrivate->BmcElog.EraseEventlogData =3D EfiEraseBmcElogData; + mRedirProtoPrivate->BmcElog.GetEventLogData =3D EfiGetBmcElogData; + mRedirProtoPrivate->BmcElog.SetEventLogData =3D EfiSetBmcElogData; + mRedirProtoPrivate->Instance =3D Instance; + // + // Now install the Protocol + // + NewHandle =3D NULL; + + Status =3D gBS->InstallProtocolInterface ( + &NewHandle, + &gEfiRedirElogProtocolGuid, + EFI_NATIVE_INTERFACE, + &mRedirProtoPrivate->BmcElog + ); + ASSERT_EFI_ERROR (Status); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + // + // Activate the Event Log (This should depend upon Setup). + // + EfiActivateBmcElog (&mRedirProtoPrivate->BmcElog, EfiElogSmIPMI, &Enable= Elog, &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 =3D EFI_SUCCESS; + + InitializeIpmiBase (); + + mRedirProtoPrivate =3D AllocatePool (sizeof (EFI_BMC_ELOG_INSTANCE_DATA)= ); + ASSERT (mRedirProtoPrivate !=3D NULL); + if (mRedirProtoPrivate =3D=3D 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/B= mcElog.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[] =3D { + { + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMIN= ATE_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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (Size > SEL_RECORD_SIZE) { + return EFI_OUT_OF_RESOURCES; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D SetBmcElogRecord (ElogData, DataType, AlertEvent, Size, Rec= ordId); + } + + 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D EraseBmcElogRecord (DataType, RecordId); + + if (Status =3D=3D EFI_SUCCESS) { + if (RecordId !=3D NULL) { + *RecordId =3D (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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_PEI_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D 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 =3D EFI_SUCCESS; + EnableElog =3D TRUE; + ElogStatus =3D TRUE; + Instance =3D 0; + + mRedirPeiProtoPrivate->Signature =3D EFI_PEI_ELOG_RED= IR_SIGNATURE; + mRedirPeiProtoPrivate->DataType =3D EfiElogSmIPMI; + mRedirPeiProtoPrivate->BmcElogPpi.ActivateEventLog =3D EfiActivateBmcEl= og; + mRedirPeiProtoPrivate->BmcElogPpi.EraseEventlogData =3D EfiEraseBmcElogD= ata; + mRedirPeiProtoPrivate->BmcElogPpi.GetEventLogData =3D EfiGetBmcElogDat= a; + mRedirPeiProtoPrivate->BmcElogPpi.SetEventLogData =3D EfiSetBmcElogDat= a; + + mRedirPeiProtoPrivate->BmcElog.Guid =3D &gPeiRedirElogPpiGuid; + mRedirPeiProtoPrivate->BmcElog.Flags =3D EFI_PEI_PPI_DESCRIPTOR_PPI | EF= I_PEI_PPI_DESCRIPTOR_TERMINATE_LIST; + mRedirPeiProtoPrivate->BmcElog.Ppi =3D (VOID *)&mRedirPeiProtoPrivate-= >BmcElogPpi; + mRedirPeiProtoPrivate->Instance =3D Instance; + // + // Now install the Protocol + // + + Status =3D PeiServicesInstallPpi (&mRedirPeiProtoPrivate->BmcElog); + ASSERT_EFI_ERROR (Status); + if (Status !=3D 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 =3D EFI_SUCCESS; + + Status =3D 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 =3D EFI_SUCCESS; + + mRedirPeiProtoPrivate =3D AllocateZeroPool (sizeof (EFI_PEI_BMC_ELOG_INS= TANCE_DATA)); + + if (mRedirPeiProtoPrivate =3D=3D 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/B= mcElog.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 =3D 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (Size > SEL_RECORD_SIZE) { + return EFI_OUT_OF_RESOURCES; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D SetBmcElogRecord (ElogData, DataType, AlertEvent, Size, Rec= ordId); + } + + 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D 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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D EraseBmcElogRecord (DataType, RecordId); + + if (Status =3D=3D EFI_SUCCESS) { + if (RecordId !=3D NULL) { + *RecordId =3D (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 =3D EFI_SUCCESS; + BmcElogPrivateData =3D INSTANCE_FROM_EFI_SM_ELOG_REDIR_THIS (This); + + if (DataType >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + if (BmcElogPrivateData->DataType =3D=3D DataType) { + Status =3D 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 =3D EFI_SUCCESS; + EnableElog =3D TRUE; + ElogStatus =3D TRUE; + Instance =3D 0; + + mRedirProtoPrivate->Signature =3D SM_ELOG_REDIR_SIGNATUR= E; + mRedirProtoPrivate->DataType =3D EfiElogSmIPMI; + mRedirProtoPrivate->BmcElog.ActivateEventLog =3D (EFI_ACTIVATE_ELOG)Efi= ActivateBmcElog; + mRedirProtoPrivate->BmcElog.EraseEventlogData =3D (EFI_ERASE_ELOG_DATA)E= fiEraseBmcElogData; + mRedirProtoPrivate->BmcElog.GetEventLogData =3D (EFI_GET_ELOG_DATA)Efi= GetBmcElogData; + mRedirProtoPrivate->BmcElog.SetEventLogData =3D (EFI_SET_ELOG_DATA)Efi= SetBmcElogData; + mRedirProtoPrivate->Instance =3D Instance; + // + // Now install the Protocol + // + NewHandle =3D NULL; + Status =3D gSmst->SmmInstallProtocolInterface ( + &NewHandle, + &gSmmRedirElogProtocolGuid, + EFI_NATIVE_INTERFACE, + &mRedirProtoPrivate->BmcElog + ); + + ASSERT_EFI_ERROR (Status); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + // + // Activate the Event Log (This should depend upon Setup). + // + EfiActivateBmcElog (&mRedirProtoPrivate->BmcElog, EfiElogSmIPMI, &Enable= Elog, &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 =3D EFI_SUCCESS; + + gST =3D SystemTable; + gBS =3D gST->BootServices; + + mRedirProtoPrivate =3D AllocatePool (sizeof (EFI_BMC_ELOG_INSTANCE_DATA)= ); + ASSERT (mRedirProtoPrivate !=3D NULL); + if (mRedirProtoPrivate =3D=3D 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/Gener= icElog/Dxe/GenericElog.c new file mode 100644 index 000000000000..d432b2151664 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Dxe/Gen= ericElog.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 recor= ded. + @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 physica= l 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 =3D EFI_UNSUPPORTED; + + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].SetEventL= ogData.Function; + Status =3D (*((EFI_SET_ELOG_DATA *)&ElogRedirCommand))(Glo= bal->Redir[Index].Command[Virtual].This, ElogData, DataType, AlertEvent, Da= taSize, RecordId); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D 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 >=3D 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 conta= in 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 Elo= gData is NULL, + this gives the RecordId of the first record availab= le in the database with the correct DataSize. + A value of 0 on return indicates the last record i= f 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 physica= l 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 =3D EFI_UNSUPPORTED; + + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].GetEventL= ogData.Function; + Status =3D (*((EFI_GET_ELOG_DATA *)&ElogRedirCommand))(Glo= bal->Redir[Index].Command[Virtual].This, ElogData, DataType, DataSize, Reco= rdId); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D Status; + break; + } + } + } + + return RetStatus; +} + +/** + Add function description. + + @param This - Protocol instance pointer. + @param ElogData - Pointer to the Event-Log data buffer that will contai= n 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 t= he 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 >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + return EfiLibGetElogData (ElogData, DataType, DataSize, RecordId, mElogM= oduleGlobal, 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 er= ased. 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 mod= e 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 =3D EFI_UNSUPPORTED; + + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].EraseEven= tLogData.Function; + Status =3D (*((EFI_ERASE_ELOG_DATA *)&ElogRedirCommand))(G= lobal->Redir[Index].Command[Virtual].This, DataType, RecordId); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D 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 L= og. If NULL just returns the + Current ElogStatus. + @param ElogStatus - Current (New) Status of Event Log. Enable= d (TRUE), Disabled (FALSE). + @param Global - The module global variable pointer. + @param Virtual - If this function is called in virtual mod= e 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 =3D EFI_UNSUPPORTED; + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].ActivateE= ventLog.Function; + Status =3D (*((EFI_ACTIVATE_ELOG *)&ElogRedirCommand))(Glo= bal->Redir[Index].Command[Virtual].This, DataType, EnableElog, ElogStatus); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D 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 >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + return EfiLibActivateElog (DataType, EnableElog, ElogStatus, mElogModule= Global, 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 =3D NULL; + + // + // Check for all IPMI Controllers + // + Status =3D gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiRedirElogProtocolGuid, + NULL, + &NumHandles, + &Buffer + ); + + if (EFI_ERROR (Status) || (NumHandles =3D=3D 0)) { + return EFI_SUCCESS; + } + + for (Index =3D 0; ((Index < NumHandles) && (Index < mElogModuleGlobal->M= axDescriptors)); Index++) { + EmptyIndex =3D mElogModuleGlobal->MaxDescriptors; + + Status =3D gBS->HandleProtocol ( + Buffer[Index], + &gEfiRedirElogProtocolGuid, + (VOID *)&Redir + ); + if (EFI_ERROR (Status) || (Redir =3D=3D NULL)) { + continue; + } + + for (Instance =3D 0; Instance < mElogModuleGlobal->MaxDescriptors; Ins= tance++) { + if (mElogModuleGlobal->Redir[Instance].Valid =3D=3D FALSE) { + if (EmptyIndex >=3D mElogModuleGlobal->MaxDescriptors) { + EmptyIndex =3D Instance; + } + } else { + if (Redir =3D=3D mElogModuleGlobal->Redir[Instance].Command->This)= { + EmptyIndex =3D mElogModuleGlobal->MaxDescriptors; + break; + // + // FIX: changed continue to break. + // + } + } + } + + if (EmptyIndex < mElogModuleGlobal->MaxDescriptors) { + RedirProc =3D (REDIR_MODULE_PROC *)= mElogModuleGlobal->Redir[EmptyIndex].Command; + mElogModuleGlobal->Redir[EmptyIndex].Valid =3D TRUE; + + EfiSetFunctionEntry (&RedirProc->ActivateEventLog, *((VOID **)&Redir= ->ActivateEventLog)); + EfiSetFunctionEntry (&RedirProc->EraseEventLogData, *((VOID **)&Redi= r->EraseEventlogData)); + EfiSetFunctionEntry (&RedirProc->GetEventLogData, *((VOID **)&Redir-= >GetEventLogData)); + EfiSetFunctionEntry (&RedirProc->SetEventLogData, *((VOID **)&Redir-= >SetEventLogData)); + RedirProc->This =3D Redir; + + CopyMem (&RedirProc[EFI_ELOG_VIRTUAL], &RedirProc[EFI_ELOG_PHYSICAL]= , sizeof (REDIR_MODULE_PROC)); + } + } + + if (Buffer !=3D 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 =3D AllocateZeroPool (sizeof (ELOG_MODULE_GLOBAL)); + ASSERT (mElogModuleGlobal !=3D NULL); + if (mElogModuleGlobal =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ElogServiceInitialize (ImageHandle, SystemTable); + + mElogModuleGlobal->MaxDescriptors =3D MAX_REDIR_DESCRIPTOR; + + // + // Check for all IPMI Controllers + // + SetElogRedirInstances (); + + ElogProtocol =3D AllocatePool (sizeof (EFI_SM_ELOG_PROTOCOL)); + ASSERT (ElogProtocol !=3D NULL); + if (ElogProtocol =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ElogProtocol->ActivateEventLog =3D EfiActivateElog; + ElogProtocol->EraseEventlogData =3D EfiEraseElogData; + ElogProtocol->GetEventLogData =3D EfiGetElogData; + ElogProtocol->SetEventLogData =3D EfiSetElogData; + + NewHandle =3D NULL; + Status =3D gBS->InstallProtocolInterface ( + &NewHandle, + &gEfiGenericElogProtocolGuid, + EFI_NATIVE_INTERFACE, + ElogProtocol + ); + + ASSERT_EFI_ERROR (Status); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + // + // Register to be notified when the ELOG REDIR protocol has been + // produced. + // + Status =3D gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_CALLBACK, + NotifyElogRedirEventCallback, + NULL, + &Event + ); + + if (!EFI_ERROR (Status)) { + Status =3D 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 =3D (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/Gener= icElog/Smm/GenericElog.c new file mode 100644 index 000000000000..d6a129a181fb --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/GenericElog/Smm/Gen= ericElog.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 mod= e 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 =3D EFI_UNSUPPORTED; + + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].SetEventL= ogData.Function; + Status =3D (*((EFI_SET_ELOG_DATA *)&ElogRedirCommand))(Glo= bal->Redir[Index].Command[Virtual].This, ElogData, DataType, AlertEvent, Da= taSize, RecordId); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D 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 >=3D 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 recor= d 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 mod= e 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 t= he 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 =3D EFI_UNSUPPORTED; + + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].GetEventL= ogData.Function; + Status =3D (*((EFI_GET_ELOG_DATA *)&ElogRedirCommand))(Glo= bal->Redir[Index].Command[Virtual].This, ElogData, DataType, DataSize, Reco= rdId); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D 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 >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + return EfiLibGetElogData (ElogData, DataType, DataSize, RecordId, mElogM= oduleGlobal, 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 er= ased. 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 mod= e 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 =3D EFI_UNSUPPORTED; + + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].EraseEven= tLogData.Function; + Status =3D (*((EFI_ERASE_ELOG_DATA *)&ElogRedirCommand))(G= lobal->Redir[Index].Command[Virtual].This, DataType, RecordId); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D 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 L= og. If NULL just returns the + Current ElogStatus. + @param ElogStatus - Current (New) Status of Event Log. Enable= d (TRUE), Disabled (FALSE). + @param Global - The module global variable pointer. + @param Virtual - If this function is called in virtual mod= e 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 =3D EFI_UNSUPPORTED; + if (DataType >=3D EfiSmElogMax) { + RetStatus =3D EFI_INVALID_PARAMETER; + return RetStatus; + } + + for (Index =3D 0; Index < Global->MaxDescriptors; Index++) { + if (Global->Redir[Index].Valid) { + ElogRedirCommand =3D Global->Redir[Index].Command[Virtual].ActivateE= ventLog.Function; + Status =3D (*((EFI_ACTIVATE_ELOG *)&ElogRedirCommand))(Glo= bal->Redir[Index].Command[Virtual].This, DataType, EnableElog, ElogStatus); + + if (!EFI_ERROR (Status)) { + RetStatus =3D EFI_SUCCESS; + break; + } else if (Status !=3D EFI_UNSUPPORTED) { + RetStatus =3D 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 >=3D EfiSmElogMax) { + return EFI_INVALID_PARAMETER; + } + + return EfiLibActivateElog (DataType, EnableElog, ElogStatus, mElogModule= Global, 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 =3D NULL; + + // + // Check for all IPMI Controllers + // + Status =3D gSmst->SmmLocateHandle ( + ByProtocol, + &gSmmRedirElogProtocolGuid, + NULL, + &NumHandles, + Buffer + ); + + if (EFI_ERROR (Status) || (NumHandles =3D=3D 0) || (Buffer =3D=3D NULL))= { + return Status; + } + + for (Index =3D 0; ((Index < NumHandles) && (Index < mElogModuleGlobal->M= axDescriptors)); Index++) { + EmptyIndex =3D mElogModuleGlobal->MaxDescriptors; + + Status =3D gSmst->SmmHandleProtocol ( + Buffer[Index], + &gSmmRedirElogProtocolGuid, + (VOID *)&Redir + ); + if (EFI_ERROR (Status) || (Redir =3D=3D NULL)) { + continue; + } + + for (Instance =3D 0; Instance < mElogModuleGlobal->MaxDescriptors; Ins= tance++) { + if (mElogModuleGlobal->Redir[Instance].Valid =3D=3D FALSE) { + if (EmptyIndex >=3D mElogModuleGlobal->MaxDescriptors) { + EmptyIndex =3D Instance; + } + } else { + if (Redir =3D=3D mElogModuleGlobal->Redir[Instance].Command->This)= { + EmptyIndex =3D mElogModuleGlobal->MaxDescriptors; + break; + // + // FIX: changed continue to break. + // + } + } + } + + if (EmptyIndex < mElogModuleGlobal->MaxDescriptors) { + RedirProc =3D (REDIR_MODULE_PROC *)= mElogModuleGlobal->Redir[EmptyIndex].Command; + mElogModuleGlobal->Redir[EmptyIndex].Valid =3D TRUE; + + EfiSetFunctionEntry (&RedirProc->ActivateEventLog, *((VOID **)&Redir= ->ActivateEventLog)); + EfiSetFunctionEntry (&RedirProc->EraseEventLogData, *((VOID **)&Redi= r->EraseEventlogData)); + EfiSetFunctionEntry (&RedirProc->GetEventLogData, *((VOID **)&Redir-= >GetEventLogData)); + EfiSetFunctionEntry (&RedirProc->SetEventLogData, *((VOID **)&Redir-= >SetEventLogData)); + RedirProc->This =3D 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 =3D AllocatePool (sizeof (ELOG_MODULE_GLOBAL)); + ASSERT (mElogModuleGlobal !=3D NULL); + if (mElogModuleGlobal =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + SmElogServiceInitialize (ImageHandle, SystemTable); + + mElogModuleGlobal->MaxDescriptors =3D MAX_REDIR_DESCRIPTOR; + + // + // Check for all IPMI Controllers + // + SetElogRedirInstances (); + + ElogProtocol =3D AllocatePool (sizeof (EFI_SM_ELOG_PROTOCOL)); + ASSERT (ElogProtocol !=3D NULL); + if (ElogProtocol =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + ElogProtocol->ActivateEventLog =3D (EFI_ACTIVATE_ELOG)EfiActivateElog; + ElogProtocol->EraseEventlogData =3D (EFI_ERASE_ELOG_DATA)EfiEraseElogDat= a; + ElogProtocol->GetEventLogData =3D (EFI_GET_ELOG_DATA)EfiGetElogData; + ElogProtocol->SetEventLogData =3D (EFI_SET_ELOG_DATA)EfiSetElogData; + + NewHandle =3D NULL; + Status =3D gSmst->SmmInstallProtocolInterface ( + &NewHandle, + &gSmmGenericElogProtocolGuid, + EFI_NATIVE_INTERFACE, + ElogProtocol + ); + + ASSERT_EFI_ERROR (Status); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + // + // Register to be notified when the ELOG REDIR protocol has been + // produced. + // + Status =3D 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 =3D (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; +} --=20 2.39.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#110326): https://edk2.groups.io/g/devel/message/110326 Mute This Topic: https://groups.io/mt/102279905/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-