From nobody Mon Feb 9 13:59:50 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+110327+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+110327+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1698686018; cv=none; d=zohomail.com; s=zohoarc; b=JuB8KW9AvxvE4ZpyOOOkZ8pMHRVUgi4plBv4du3VN2G4NftRnvAYJqsO29JewjufpmBpF9JgWLTMCRkI+AFTiRoiLHYtuX/NDew+iQiFtPitM81EMlz7HLrWj8xRCFRSEqEvp6BdGwmEJfCpncRcFi7YPEjGgvK7ioeX/rEc5FI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1698686018; 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=/UO2gOJH60ykgCdUv30fR5Mag9tJVQK6n2GhCqPUcBw=; b=aP4KEVem/8U3m1tWZxgRcPuYRRy9XdHmUKJRrkNDLiHNFdmfHOEqdC28glmKdwxuMV4IblDnLGDLG9NK9Mcdb8fVC+UK85n15rWLyGP/j70NTQtBkOSAj8wmkgRZi5WvBGBGGBriM/yp1hCW43Vr1Buj91R5WVHSFovSH4on+64= 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+110327+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 1698686018622166.5478837799269; Mon, 30 Oct 2023 10:13:38 -0700 (PDT) Return-Path: DKIM-Signature: a=rsa-sha256; bh=Ci8Jh5M7GNJmhMGsrGvTOH3SK1YiTQb4J7V/000rEDg=; 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=JAUbTFOuBba4hrkw8lsDH4DzKxUr/cCd0W8hbj4oDHkY5mfQ2t3eafEDviBtyrmmHlvDcKoY bCPdiR6hbYIC2/23pyun7JmMU6OMlqjlQqJgjMP8TAZ1grCPQmoeZOmmHa3OgRUGvhhyJ7wa7VJ 14y8eYAlhZ/lhRE/yEcEEq50= X-Received: by 127.0.0.2 with SMTP id ODSdYY1788612xKtdEXICy1N; 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="390840889" X-IronPort-AV: E=Sophos;i="6.03,261,1694761200"; d="scan'208";a="390840889" 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:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10878"; a="795098442" X-IronPort-AV: E=Sophos;i="6.03,261,1694761200"; d="scan'208";a="795098442" 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 2/4] IpmiFeaturePkg: Add ServerManagementLib Date: Sun, 29 Oct 2023 13:27:38 -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: CvGviBfY1vsjFxznPANWguB7x1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1698686019981100002 Content-Type: text/plain; charset="utf-8" Lightweight lib to support Server Management drivers. Signed-off-by: Zhen Gong --- .../IpmiFeaturePkg/Include/IpmiFeature.dsc | 1 + .../ServerManagementLib.inf | 35 + .../ServerManagementLibNull.inf | 38 + .../Include/Library/ServerMgmtRtLib.h | 147 ++++ .../ServerManagementLib/ServerManagementLib.c | 696 ++++++++++++++++++ .../ServerManagementLibNull.c | 144 ++++ 6 files changed, 1061 insertions(+) create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/ServerManagementLib/ServerManagementLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/ServerManagementLibNull/ServerManagementLibNull.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Inclu= de/Library/ServerMgmtRtLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/ServerManagementLib/ServerManagementLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Libra= ry/ServerManagementLibNull/ServerManagementLibNull.c diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipmi= Feature.dsc b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Ipm= iFeature.dsc index fa98e5672d83..fc9001e98473 100644 --- a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature= .dsc +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature= .dsc @@ -51,6 +51,7 @@ [LibraryClasses.common.DXE_DRIVER,LibraryClasses.common.U= EFI_DRIVER] [LibraryClasses.common] BmcCommonInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/Bm= cCommonInterfaceLib.inf BtInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfa= ceLib/BtInterfaceLib.inf + ServerManagementLib|IpmiFeaturePkg/Library/ServerManagementLib/ServerMan= agementLib.inf =20 [LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVE= R] SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInt= erfaceLib/DxeSsifInterfaceLib.inf diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/Serv= erManagementLib/ServerManagementLib.inf b/Features/Intel/OutOfBandManagemen= t/IpmiFeaturePkg/Library/ServerManagementLib/ServerManagementLib.inf new file mode 100644 index 000000000000..25a3a7540762 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManag= ementLib/ServerManagementLib.inf @@ -0,0 +1,35 @@ +### @file +# +# Copyright (c) 2023, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +### + + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D ServerManagementLib + FILE_GUID =3D D43C86F0-7C8B-4992-9593-8CB6FBC66A0A + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + PI_SPECIFICATION_VERSION =3D 0x0001000A + LIBRARY_CLASS =3D ServerManagementLib + +[Sources] + ServerManagementLib.c + +[Packages] + IpmiFeaturePkg/IpmiFeaturePkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + IoLib + DebugLib + UefiBootServicesTableLib + +[Protocols] + gEfiGenericElogProtocolGuid + + + diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/Serv= erManagementLibNull/ServerManagementLibNull.inf b/Features/Intel/OutOfBandM= anagement/IpmiFeaturePkg/Library/ServerManagementLibNull/ServerManagementLi= bNull.inf new file mode 100644 index 000000000000..6b66b44857f3 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManag= ementLibNull/ServerManagementLibNull.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 ServerManagementLibNull + FILE_GUID =3D 3AC01DE9-5A96-4df5-A645-ECD092C29AF9 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + PI_SPECIFICATION_VERSION =3D 0x0001000A + LIBRARY_CLASS =3D ServerManagementLib + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources.common] + ServerManagementLibNull.c + + +[Packages] + MdePkg/MdePkg.dec + ServerPlatformPkg/PlatformPkg.dec + +[LibraryClasses] + DebugLib + +[Protocols] + + diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Libr= ary/ServerMgmtRtLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/I= nclude/Library/ServerMgmtRtLib.h new file mode 100644 index 000000000000..12b2e82f9e6e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/Ser= verMgmtRtLib.h @@ -0,0 +1,147 @@ +/** @file + Server Management Driver Lib. + +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _SERVER_MGMT_LIB_H_ +#define _SERVER_MGMT_LIB_H_ + +#include + +/** + ELOG Library Initializer. +**/ + +/** + The function will set up a notification on the ELOG protocol. This func= tion is required to be called prior + to utilizing the ELOG protocol from within this library. + @param None + + @retval EFI_SUCCESS After the notification has been setup. + @retval Other Failure in constructor. + +**/ +EFI_STATUS +EfiInitializeGenericElog ( + VOID + ); + +/** + + This function sends event log data to the destination such as LAN, ICMB,= BMC etc. + @param[in] ElogData A pointer to the event log data that needs to be rec= orded + @param[in] DataType Type of Elog data that is being recorded. The Elog = is redirected based on this + parameter. + @param[in] AlertEvent An indication that the input data type is an alert= . The underlying + drivers need to decide if they need to listen to the Data= Type and send it on + an appropriate channel as an alert use of the information. + @param[in] DataSize The size of the data to be logged + @param[out] RecordId The array of record IDs sent by the target. This c= an be used to retrieve the + records or erase the records. + + @retval EFI_SUCCESS If the data was logged. + @retval EFI_INVALID_PARAMETER If the DataType is >=3D EfiSmElogMax + @retval EFI_OUT_OF_RESOURCES If the DataSize is larger than the Elog tem= p buffer and we cannot log the record + @retval EFI_NOT_FOUND The event log target was not found + @retval EFI_PROTOCOL_ERROR There was a data formatting error + +**/ +EFI_STATUS +EfiSmSetEventLogData ( + IN UINT8 *ElogData, + IN EFI_SM_ELOG_TYPE DataType, + IN BOOLEAN AlertEvent, + IN UINTN DataSize, + OUT UINT64 *RecordId + ); + +/** + + This function gets event log data from the destination dependent on the = DataType. The destination + can be a remote target such as LAN, ICMB, IPMI, or a FV. The ELOG redir= driver will resolve the + destination. + @param[in] ElogData Pointer to the event log data buffer to contain the = data to be retrieved. + @param[in] DataType This is the type of Elog data to be gotten. Elog is= redirected based upon this + information. + @param[in, out] DataSize This is the size of the data to be retrieved. + @param[in, out] RecordId The RecordId of the next record. If ElogData i= s NULL, this gives the RecordId of the first + record available in the database with the correct DataSi= ze. A value of 0 on return indicates + that it was last record if the Status is EFI_SUCCESS. + + @retval EFI_SUCCESS If the event log was retrieved successfully. + @retval EFI_NOT_FOUND If the event log target was not found. + @retval EFI_NO_RESPONSE If the event log target is not responding. This= is done by the redir driver. + @retval EFI_INVALID_PARAMETER DataType or another parameter was invalid. + @retval EFI_BUFFER_TOO_SMALL The ElogData buffer is too small to be fill= ed with the requested data. + +**/ +EFI_STATUS +EfiSmGetEventLogData ( + IN UINT8 *ElogData, + IN EFI_SM_ELOG_TYPE DataType, + IN OUT UINTN *DataSize, + IN OUT UINT64 *RecordId + ); + +/** + This function erases the event log data defined by the DataType. The re= dir driver associated with + the DataType resolves the path to the record. + + @param[in] DataType The type of Elog data that is to be erased. + @param[in, out] RecordId The RecordId of the data to be erased. If Reco= rdId is NULL, all records in the + database are erased if permitted by the target. RecordI= d will contain the deleted + RecordId on return. + + @retval EFI_SUCCESS The record or collection of records were erased. + @retval EFI_NOT_FOUND The event log target was not found. + @retval EFI_NO_RESPONSE The event log target was found but did not respo= nd. + @retval EFI_INVALID_PARAMETER One of the parameters was invalid. + +**/ +EFI_STATUS +EfiSmEraseEventlogData ( + IN EFI_SM_ELOG_TYPE DataType, + IN OUT UINT64 *RecordId + ); + +/** + + This function enables or disables the event log defined by the DataType. + @param[in] DataType The type of Elog data that is being activated. + @param[in] EnableElog Enables or disables the event log defined by the D= ataType. If it is NULL + it returns the current status of the DataType log. + @param[out] ElogStatus Is the current status of the Event log defined by= the DataType. Enabled is + TRUE and Disabled is FALSE. + + @retval EFI_SUCCESS If the event log was successfully enabled or disable= d. + @retval EFI_NOT_FOUND The event log target was not found. + @retval EFI_NO_RESPONSE The event log target was found but did not respo= nd. + @retval EFI_INVALID_PARAMETER One of the parameters was invalid. + +**/ +EFI_STATUS +EfiSmActivateEventLog ( + IN EFI_SM_ELOG_TYPE DataType, + IN BOOLEAN *EnableElog, + OUT BOOLEAN *ElogStatus + ); + +/** + + Return Date and Time from RTC in Unix format which fits in 32 bit format. + + @param[out] NumOfSeconds Pointer to return calculated time. + + @retval EFI_SUCCESS + @retval Other EFI status if error occurred. + +**/ +EFI_STATUS +EfiSmGetTimeStamp ( + OUT UINT32 *NumOfSeconds + ); + +#endif // _SERVER_MGMT_LIB_H_ diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/Serv= erManagementLib/ServerManagementLib.c b/Features/Intel/OutOfBandManagement/= IpmiFeaturePkg/Library/ServerManagementLib/ServerManagementLib.c new file mode 100644 index 000000000000..66a481fa57b4 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManag= ementLib/ServerManagementLib.c @@ -0,0 +1,696 @@ +/** @file + Lightweight lib to support EFI Server Management drivers. + +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +#include + +// #include EFI_PROTOCOL_DEPENDENCY (CpuIo) + +#define PCAT_RTC_ADDRESS_REGISTER 0x70 +#define PCAT_RTC_DATA_REGISTER 0x71 + +#define RTC_ADDRESS_SECONDS 0 // R/W Range 0..59 +#define RTC_ADDRESS_MINUTES 2 // R/W Range 0..59 +#define RTC_ADDRESS_HOURS 4 // R/W Range 1..12 or 0..23 Bit= 7 is AM/PM +#define RTC_ADDRESS_DAY_OF_THE_MONTH 7 // R/W Range 1..31 +#define RTC_ADDRESS_MONTH 8 // R/W Range 1..12 +#define RTC_ADDRESS_YEAR 9 // R/W Range 0..99 +#define RTC_ADDRESS_REGISTER_A 10 // R/W[0..6] R0[7] +#define RTC_ADDRESS_REGISTER_B 11 // R/W +#define RTC_ADDRESS_REGISTER_C 12 // RO +#define RTC_ADDRESS_REGISTER_D 13 // RO +#define RTC_ADDRESS_CENTURY 50 // R/W Range 19..20 Bit 8 is R/W + +// +// Register A +// +typedef struct { + UINT8 RS : 4; // Rate Selection Bits + UINT8 DV : 3; // Divisor + UINT8 UIP : 1; // Update in progress +} RTC_REGISTER_A_BITS; + +typedef union { + RTC_REGISTER_A_BITS Bits; + UINT8 Data; +} RTC_REGISTER_A; + +// +// Register B +// +typedef struct { + UINT8 DSE : 1; // 0 - Daylight saving disabled 1 - Daylight savings= enabled + UINT8 MIL : 1; // 0 - 12 hour mode 1 - 24 hour mode + UINT8 DM : 1; // 0 - BCD Format 1 - Binary Format + UINT8 SQWE : 1; // 0 - Disable SQWE output 1 - Enable SQWE outp= ut + UINT8 UIE : 1; // 0 - Update INT disabled 1 - Update INT enabl= ed + UINT8 AIE : 1; // 0 - Alarm INT disabled 1 - Alarm INT Enabled + UINT8 PIE : 1; // 0 - Periodic INT disabled 1 - Periodic INT Ena= bled + UINT8 SET : 1; // 0 - Normal operation. 1 - Updates inhibited +} RTC_REGISTER_B_BITS; + +typedef union { + RTC_REGISTER_B_BITS Bits; + UINT8 Data; +} RTC_REGISTER_B; + +// +// Register D +// +typedef struct { + UINT8 Reserved : 7; // Read as zero. Can not be written. + UINT8 VRT : 1; // Valid RAM and Time +} RTC_REGISTER_D_BITS; + +typedef union { + RTC_REGISTER_D_BITS Bits; + UINT8 Data; +} RTC_REGISTER_D; + +// +// Module Globals +// +EFI_SM_ELOG_PROTOCOL *mGenericElogProtocol =3D NULL; +VOID *mGenericElogRegistration =3D NULL; + +INTN DaysOfMonth[12] =3D { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31= }; + +/** + This function is called whenever an instance of ELOG protocol is created= . When the function is notified + it initializes the module global data. + + @param Event This is used only for EFI compatibility. + @param Context This is used only for EFI compatibility. + +**/ +VOID +EFIAPI +GenericElogNotificationFunction ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + + Status =3D gBS->LocateProtocol (&gEfiGenericElogProtocolGuid, NULL, (VOI= D **)&mGenericElogProtocol); + if (EFI_ERROR (Status)) { + mGenericElogProtocol =3D NULL; + } +} + +/** + The function will set up a notification on the ELOG protocol. This func= tion is required to be called prior + to utilizing the ELOG protocol from within this library. + + @retval EFI_SUCCESS after the notification has been setup. +**/ +EFI_STATUS +EfiInitializeGenericElog ( + VOID + ) +{ + EFI_EVENT Event; + EFI_STATUS Status; + + Status =3D gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, GenericElo= gNotificationFunction, NULL, &Event); + ASSERT_EFI_ERROR (Status); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + Status =3D gBS->RegisterProtocolNotify (&gEfiGenericElogProtocolGuid, Ev= ent, &mGenericElogRegistration); + ASSERT_EFI_ERROR (Status); + if (Status !=3D EFI_SUCCESS) { + return Status; + } + + gBS->SignalEvent (Event); + + return EFI_SUCCESS; +} + +/** + This function sends event log data to the destination such as LAN, ICMB,= BMC etc. + + @param ElogData is a pointer to the event log data that needs to be = recorded + @param DataType type of Elog data that is being recorded. The Elog = is redirected based on this parameter. + @param AlertEvent is an indication that the input data type is an aler= t. The underlying + drivers need to decide if they need to listen to the= DataType and send it on + an appropriate channel as an alert use of the inform= ation. + @param DataSize is the size of the data to be logged + @param RecordId is the array of record IDs sent by the target. This= can be used to retrieve the + records or erase the records. + @retval EFI_SUCCESS - if the data was logged. + @retval EFI_INVALID_PARAMETER - if the DataType is >=3D EfiSmElogMax + @retval EFI_NOT_FOUND - the event log target was not found + @retval EFI_PROTOCOL_ERROR - there was a data formatting error + +**/ +EFI_STATUS +EfiSmSetEventLogData ( + IN UINT8 *ElogData, + IN EFI_SM_ELOG_TYPE DataType, + IN BOOLEAN AlertEvent, + IN UINTN DataSize, + OUT UINT64 *RecordId + ) +{ + // + // If the protocol is not found return EFI_NOT_FOUND + // + if (mGenericElogProtocol =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return mGenericElogProtocol->SetEventLogData ( + mGenericElogProtocol, + ElogData, + DataType, + AlertEvent, + DataSize, + RecordId + ); +} + +/** + This function gets event log data from the destination dependent on the = DataType. The destination + can be a remote target such as LAN, ICMB, IPMI, or a FV. The ELOG redir= driver will resolve the + destination. + + @param ElogData - pointer to the event log data buffer to contain the da= ta to be retrieved. + @param DataType - this is the type of Elog data to be gotten. Elog is r= edirected based upon this + information. + @param DataSize - this is the size of the data to be retrieved. + @param RecordId - 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 Data= Size. A value of 0 on return indicates + that it was last record if the Status is EFI_SUCCESS. + + @retval EFI_SUCCESS - if the event log was retrieved successfully. + @retval EFI_NOT_FOUND - if the event log target was not found. + @retval EFI_NO_RESPONSE - if the event log target is not responding. Th= is is done by the redir driver. + @retval EFI_INVALID_PARAMETER - DataType or another parameter was invali= d. + @retval EFI_BUFFER_TOO_SMALL -the ElogData buffer is too small to be fil= led with the requested data. + +**/ +EFI_STATUS +EfiSmGetEventLogData ( + IN UINT8 *ElogData, + IN EFI_SM_ELOG_TYPE DataType, + IN OUT UINTN *DataSize, + IN OUT UINT64 *RecordId + ) +{ + // + // If the protocol is not found return EFI_NOT_FOUND + // + if (mGenericElogProtocol =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return mGenericElogProtocol->GetEventLogData ( + mGenericElogProtocol, + ElogData, + DataType, + DataSize, + RecordId + ); +} + +/** + This function erases the event log data defined by the DataType. The re= dir driver associated with + the DataType resolves the path to the record. + + @param DataType - the type of Elog data that is to be erased. + @param RecordId - the RecordId of the data to be erased. If RecordId is= NULL, all records in the + database are erased if permitted by the target. Recor= dId will contain the deleted + RecordId on return. + + @retval EFI_SUCCESS - the record or collection of records were erased. + @retval EFI_NOT_FOUND - the event log target was not found. + @retval EFI_NO_RESPONSE - the event log target was found but did not res= pond. + @retval EFI_INVALID_PARAMETER - one of the parameters was invalid. + +**/ +EFI_STATUS +EfiSmEraseEventlogData ( + IN EFI_SM_ELOG_TYPE DataType, + IN OUT UINT64 *RecordId + ) +{ + // + // If the protocol is not found return EFI_NOT_FOUND + // + if (mGenericElogProtocol =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return mGenericElogProtocol->EraseEventlogData ( + mGenericElogProtocol, + DataType, + RecordId + ); +} + +/** + This function enables or disables the event log defined by the DataType. + + + @param DataType - the type of Elog data that is being activated. + @param EnableElog - enables or disables the event log defined by the Dat= aType. If it is NULL + it returns the current status of the DataType log. + @param ElogStatus - is the current status of the Event log defined by th= e DataType. Enabled is + TRUE and Disabled is FALSE. + + @retval EFI_SUCCESS - if the event log was successfully enabled or disab= led. + @retval EFI_NOT_FOUND - the event log target was not found. + @retval EFI_NO_RESPONSE - the event log target was found but did not res= pond. + @retval EFI_INVALID_PARAMETER - one of the parameters was invalid. + +**/ +EFI_STATUS +EfiSmActivateEventLog ( + IN EFI_SM_ELOG_TYPE DataType, + IN BOOLEAN *EnableElog, + OUT BOOLEAN *ElogStatus + ) +{ + // + // If the protocol is not found return EFI_NOT_FOUND + // + if (mGenericElogProtocol =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + return mGenericElogProtocol->ActivateEventLog ( + mGenericElogProtocol, + DataType, + EnableElog, + ElogStatus + ); +} + +/** + This function verifies the leap year + + @param Year year in YYYY format. + + @retval TRUE if the year is a leap year + +**/ +STATIC +BOOLEAN +IsLeapYear ( + IN UINT16 Year + ) +{ + if (Year % 4 =3D=3D 0) { + if (Year % 100 =3D=3D 0) { + if (Year % 400 =3D=3D 0) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } + } else { + return FALSE; + } +} + +/** + This function calculates the total number leap days from 1970 to the cur= rent year + + @param Time - Current Time + + @retval Returns the number of leap days since the base year, 1970. + +**/ +STATIC +UINTN +CountNumOfLeapDays ( + IN EFI_TIME *Time + ) +{ + UINT16 NumOfYear; + UINT16 BaseYear; + UINT16 Index; + UINTN Count; + + Count =3D 0; + BaseYear =3D 1970; + NumOfYear =3D Time->Year - 1970; + + for (Index =3D 0; Index <=3D NumOfYear; Index++) { + if (IsLeapYear (BaseYear + Index)) { + Count++; + } + } + + // + // If the current year is a leap year but the month is January or Februa= ry, + // then the leap day has not occurred and should not be counted. If it is + // February 29, the leap day is accounted for in CalculateNumOfDayPassed= ThisYear( ) + // + if (IsLeapYear (Time->Year)) { + if ((Count > 0) && (Time->Month < 3)) { + Count--; + } + } + + return Count; +} + +/** + This function calculates the total number of days passed till the day in= a year. + If the year is a leap year, an extra day is not added since the number o= f leap + days is calculated in CountNumOfLeapDays. + + @param Time This structure contains detailed information about date = and time + + @retval Returns the number of days passed until the input day. + +**/ +STATIC +UINTN +CalculateNumOfDayPassedThisYear ( + IN EFI_TIME Time + ) +{ + UINTN Index; + UINTN NumOfDays; + + NumOfDays =3D 0; + for (Index =3D 1; Index < Time.Month; Index++) { + NumOfDays +=3D DaysOfMonth[Index - 1]; + } + + NumOfDays +=3D Time.Day; + return NumOfDays; +} + +/** + Function converts a BCD to a decimal value. + + @param[in] BcdValue An 8 bit BCD value + + @return The decimal value of the BcdValue +**/ +STATIC +UINT8 +BcdToDecimal ( + IN UINT8 BcdValue + ) +{ + UINTN High; + UINTN Low; + + High =3D BcdValue >> 4; + Low =3D BcdValue - (High << 4); + + return (UINT8)(Low + (High * 10)); +} + +// +// RTC read functions were copied here since we need to get the time +// in both DXE and runtime code. The PcRtc driver is not currently a +// dual mode driver, this is more efficient since making PcRtc dual mode +// would unnecessarily bloat the SMM code space. +// + +/** + Read data register and return contents. + + @param Address - Register address to read + + @retval Value of data register contents + +**/ +STATIC +UINT8 +RtcRead ( + IN UINT8 Address + ) +{ + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8)(Address | (UINT8)(IoRead8 (= PCAT_RTC_ADDRESS_REGISTER) & 0x80))); + return IoRead8 (PCAT_RTC_DATA_REGISTER); +} + +/** + Write data to register address. + + @param Address - Register address to write + @param Data - Data to write to register + +**/ +STATIC +VOID +RtcWrite ( + IN UINT8 Address, + IN UINT8 Data + ) +{ + IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, (UINT8)(Address | (UINT8)(IoRead8 (= PCAT_RTC_ADDRESS_REGISTER) & 0x80))); + IoWrite8 (PCAT_RTC_DATA_REGISTER, Data); +} + +/** + Convert Rtc Time To Efi Time. + + @param Time + @param RegisterB + +**/ +STATIC +VOID +ConvertRtcTimeToEfiTime ( + IN EFI_TIME *Time, + IN RTC_REGISTER_B RegisterB + ) +{ + BOOLEAN Pm; + + if ((Time->Hour) & 0x80) { + Pm =3D TRUE; + } else { + Pm =3D FALSE; + } + + Time->Hour =3D (UINT8)(Time->Hour & 0x7f); + + if (RegisterB.Bits.DM =3D=3D 0) { + Time->Year =3D BcdToDecimal ((UINT8)Time->Year); + Time->Month =3D BcdToDecimal (Time->Month); + Time->Day =3D BcdToDecimal (Time->Day); + Time->Hour =3D BcdToDecimal (Time->Hour); + Time->Minute =3D BcdToDecimal (Time->Minute); + Time->Second =3D BcdToDecimal (Time->Second); + } + + // + // If time is in 12 hour format, convert it to 24 hour format + // + if (RegisterB.Bits.MIL =3D=3D 0) { + if (Pm && (Time->Hour < 12)) { + Time->Hour =3D (UINT8)(Time->Hour + 12); + } + + if (!Pm && (Time->Hour =3D=3D 12)) { + Time->Hour =3D 0; + } + } + + Time->Nanosecond =3D 0; + Time->TimeZone =3D EFI_UNSPECIFIED_TIMEZONE; + Time->Daylight =3D 0; +} + +/** + Test Century Register. + + @retval EFI_SUCCESS + @retval EFI_DEVICE_ERROR + +**/ +STATIC +EFI_STATUS +RtcTestCenturyRegister ( + VOID + ) +{ + UINT8 Century; + UINT8 Temp; + + Century =3D RtcRead (RTC_ADDRESS_CENTURY); + + // + // Always sync-up the Bit7 "semaphore"...this maintains + // consistency across the different chips/implementations of + // the RTC... + // + RtcWrite (RTC_ADDRESS_CENTURY, 0x00); + Temp =3D (UINT8)(RtcRead (RTC_ADDRESS_CENTURY) & 0x7f); + RtcWrite (RTC_ADDRESS_CENTURY, Century); + if ((Temp =3D=3D 0x19) || (Temp =3D=3D 0x20)) { + return EFI_SUCCESS; + } + + return EFI_DEVICE_ERROR; +} + +/** + Waits until RTC register A and D show data is valid. + + @param Timeout - Maximum time to wait + + @retval EFI_DEVICE_ERROR + @retval EFI_SUCCESS + +**/ +STATIC +EFI_STATUS +RtcWaitToUpdate ( + UINTN Timeout + ) +{ + RTC_REGISTER_A RegisterA; + RTC_REGISTER_D RegisterD; + + // + // See if the RTC is functioning correctly + // + RegisterD.Data =3D RtcRead (RTC_ADDRESS_REGISTER_D); + + if (RegisterD.Bits.VRT =3D=3D 0) { + return EFI_DEVICE_ERROR; + } + + // + // Wait for up to 0.1 seconds for the RTC to be ready. + // + Timeout =3D (Timeout / 10) + 1; + RegisterA.Data =3D RtcRead (RTC_ADDRESS_REGISTER_A); + while (RegisterA.Bits.UIP =3D=3D 1 && Timeout > 0) { + gBS->Stall (10); + RegisterA.Data =3D RtcRead (RTC_ADDRESS_REGISTER_A); + Timeout--; + } + + RegisterD.Data =3D RtcRead (RTC_ADDRESS_REGISTER_D); + if ((Timeout =3D=3D 0) || (RegisterD.Bits.VRT =3D=3D 0)) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Get time from RTC. + + @param Time - pointer to time structure + + @retval EFI_INVALID_PARAMETER + @retval EFI_SUCCESS + +**/ +STATIC +EFI_STATUS +RtcGetTime ( + OUT EFI_TIME *Time + ) +{ + RTC_REGISTER_B RegisterB; + UINT8 Century; + EFI_STATUS Status; + + // + // Check parameters for null pointer + // + if (Time =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Wait for up to 0.1 seconds for the RTC to be updated + // + Status =3D RtcWaitToUpdate (100000); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Read Register B + // + RegisterB.Data =3D RtcRead (RTC_ADDRESS_REGISTER_B); + + // + // Get the Time/Date/Daylight Savings values. + // + Time->Second =3D RtcRead (RTC_ADDRESS_SECONDS); + Time->Minute =3D RtcRead (RTC_ADDRESS_MINUTES); + Time->Hour =3D RtcRead (RTC_ADDRESS_HOURS); + Time->Day =3D RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH); + Time->Month =3D RtcRead (RTC_ADDRESS_MONTH); + Time->Year =3D RtcRead (RTC_ADDRESS_YEAR); + + ConvertRtcTimeToEfiTime (Time, RegisterB); + + if (RtcTestCenturyRegister () =3D=3D EFI_SUCCESS) { + Century =3D BcdToDecimal ((UINT8)(RtcRead (RTC_ADDRESS_CENTURY) & 0x7f= )); + } else { + Century =3D BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY)); + } + + Time->Year =3D (UINT16)(Century * 100 + Time->Year); + + return EFI_SUCCESS; +} + +/** + Return Date and Time from RTC in Unix format which fits in 32 bit format. + + @param NumOfSeconds - pointer to return calculated time + + @retval EFI_SUCCESS + @retval EFI status if error occurred + +**/ +EFI_STATUS +EfiSmGetTimeStamp ( + OUT UINT32 *NumOfSeconds + ) +{ + UINT16 NumOfYears; + UINTN NumOfLeapDays; + UINTN NumOfDays; + EFI_TIME Time; + EFI_STATUS Status; + + Status =3D RtcGetTime (&Time); + if (EFI_ERROR (Status)) { + return Status; + } + + NumOfYears =3D Time.Year - 1970; + NumOfLeapDays =3D CountNumOfLeapDays (&Time); + NumOfDays =3D CalculateNumOfDayPassedThisYear (Time); + + // + // Add 365 days for all years. Add additional days for Leap Years. Subtr= act off current day. + // + NumOfDays +=3D (NumOfLeapDays + (365 * NumOfYears) - 1); + + *NumOfSeconds =3D (UINT32)(3600 * 24 * NumOfDays + (Time.Hour * 3600) + = (60 * Time.Minute) + Time.Second); + + return EFI_SUCCESS; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/Serv= erManagementLibNull/ServerManagementLibNull.c b/Features/Intel/OutOfBandMan= agement/IpmiFeaturePkg/Library/ServerManagementLibNull/ServerManagementLibN= ull.c new file mode 100644 index 000000000000..7dd27f34878e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManag= ementLibNull/ServerManagementLibNull.c @@ -0,0 +1,144 @@ +/** @file + Lightweight lib to support EFI Server Management drivers. + +Copyright (c) 2023, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** + The function will set up a notification on the ELOG protocol. This func= tion is required to be called prior + to utilizing the ELOG protocol from within this library. + + @retval EFI_SUCCESS after the notification has been setup. +**/ +EFI_STATUS +EfiInitializeGenericElog ( + VOID + ) +{ + return EFI_UNSUPPORTED; +} + +/** + This function sends event log data to the destination such as LAN, ICMB,= BMC etc. + + @param ElogData is a pointer to the event log data that needs to be = recorded + @param DataType type of Elog data that is being recorded. The Elog = is redirected based on this parameter. + @param AlertEvent is an indication that the input data type is an aler= t. The underlying + drivers need to decide if they need to listen to the= DataType and send it on + an appropriate channel as an alert use of the inform= ation. + @param DataSize is the size of the data to be logged + @param RecordId is the array of record IDs sent by the target. This= can be used to retrieve the + records or erase the records. + @retval EFI_NOT_FOUND - the event log target was not found + +**/ +EFI_STATUS +EfiSmSetEventLogData ( + IN UINT8 *ElogData, + IN EFI_SM_ELOG_TYPE DataType, + IN BOOLEAN AlertEvent, + IN UINTN DataSize, + OUT UINT64 *RecordId + ) +{ + return EFI_NOT_FOUND; +} + +/** + This function gets event log data from the destination dependent on the = DataType. The destination + can be a remote target such as LAN, ICMB, IPMI, or a FV. The ELOG redir= driver will resolve the + destination. + + @param ElogData - pointer to the event log data buffer to contain the da= ta to be retrieved. + @param DataType - this is the type of Elog data to be gotten. Elog is r= edirected based upon this + information. + @param DataSize - this is the size of the data to be retrieved. + @param RecordId - 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 Data= Size. A value of 0 on return indicates + that it was last record if the Status is EFI_SUCCESS. + + @retval EFI_NOT_FOUND - if the event log target was not found. + +**/ +EFI_STATUS +EfiSmGetEventLogData ( + IN UINT8 *ElogData, + IN EFI_SM_ELOG_TYPE DataType, + IN OUT UINTN *DataSize, + IN OUT UINT64 *RecordId + ) +{ + return EFI_NOT_FOUND; +} + +/** + This function erases the event log data defined by the DataType. The re= dir driver associated with + the DataType resolves the path to the record. + + @param DataType - the type of Elog data that is to be erased. + @param RecordId - the RecordId of the data to be erased. If RecordId is= NULL, all records in the + database are erased if permitted by the target. Recor= dId will contain the deleted + RecordId on return. + + @retval EFI_SUCCESS - the record or collection of records were erased. + @retval EFI_NOT_FOUND - the event log target was not found. + @retval EFI_NO_RESPONSE - the event log target was found but did not res= pond. + @retval EFI_INVALID_PARAMETER - one of the parameters was invalid. + +**/ +EFI_STATUS +EfiSmEraseEventlogData ( + IN EFI_SM_ELOG_TYPE DataType, + IN OUT UINT64 *RecordId + ) +{ + return EFI_NOT_FOUND; +} + +/** + This function enables or disables the event log defined by the DataType. + + + @param DataType - the type of Elog data that is being activated. + @param EnableElog - enables or disables the event log defined by the Dat= aType. If it is NULL + it returns the current status of the DataType log. + @param ElogStatus - is the current status of the Event log defined by th= e DataType. Enabled is + TRUE and Disabled is FALSE. + + @retval EFI_NOT_FOUND - the event log target was not found. + +**/ +EFI_STATUS +EfiSmActivateEventLog ( + IN EFI_SM_ELOG_TYPE DataType, + IN BOOLEAN *EnableElog, + OUT BOOLEAN *ElogStatus + ) +{ + return EFI_NOT_FOUND; +} + +/** + Return Date and Time from RTC in Unix format which fits in 32 bit format. + + @param NumOfSeconds - pointer to return calculated time + + @retval EFI_SUCCESS + @retval EFI status if error occurred + +**/ +EFI_STATUS +EfiSmGetTimeStamp ( + OUT UINT32 *NumOfSeconds + ) +{ + *NumOfSeconds =3D 0; + + return EFI_NOT_FOUND; +} --=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 (#110327): https://edk2.groups.io/g/devel/message/110327 Mute This Topic: https://groups.io/mt/102279906/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-