From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 7291F941991 for ; Mon, 30 Oct 2023 17:13:39 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=MwUYmp9RgykymMsrX14LYXl8ZRXCu/6Y95n+EOpjCHE=; 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=Xkr/QZYr4oDCJBnwFpyAvEMPniOzW9oDiihIftnBNLxQYddMJw+xc9M1CDlxW2IU9eTotdGf kDLZjnRYxA88dP47uhsD2MITuZVRVsAYZsVTtt2m1X73782ULK2u6G9xg0gZKrqBEyLuN58eEe4 Dw/eh9BQSH2gqOOecShir2MA= X-Received: by 127.0.0.2 with SMTP id vk33YY7687511xOT9rYBiex2; 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: NgCQFzkgIgZXZuQFotbRV4xSx7686176AA= Content-Transfer-Encoding: 8bit X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b="Xkr/QZYr"; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io 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/Library/ServerManagementLib/ServerManagementLib.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLibNull/ServerManagementLibNull.inf create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/ServerMgmtRtLib.h create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLib/ServerManagementLib.c create mode 100644 Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLibNull/ServerManagementLibNull.c diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.dsc b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/IpmiFeature.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.UEFI_DRIVER] [LibraryClasses.common] BmcCommonInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BmcCommonInterfaceLib.inf BtInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/BtInterfaceLib/BtInterfaceLib.inf + ServerManagementLib|IpmiFeaturePkg/Library/ServerManagementLib/ServerManagementLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER, LibraryClasses.common.DXE_DRIVER] SsifInterfaceLib|IpmiFeaturePkg/Library/BmcInterfaceCommonAccess/SsifInterfaceLib/DxeSsifInterfaceLib.inf diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLib/ServerManagementLib.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLib/ServerManagementLib.inf new file mode 100644 index 000000000000..25a3a7540762 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLib/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 = 0x00010005 + BASE_NAME = ServerManagementLib + FILE_GUID = D43C86F0-7C8B-4992-9593-8CB6FBC66A0A + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + LIBRARY_CLASS = 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/ServerManagementLibNull/ServerManagementLibNull.inf b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLibNull/ServerManagementLibNull.inf new file mode 100644 index 000000000000..6b66b44857f3 --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLibNull/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 = 0x00010005 + BASE_NAME = ServerManagementLibNull + FILE_GUID = 3AC01DE9-5A96-4df5-A645-ECD092C29AF9 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + PI_SPECIFICATION_VERSION = 0x0001000A + LIBRARY_CLASS = ServerManagementLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + ServerManagementLibNull.c + + +[Packages] + MdePkg/MdePkg.dec + ServerPlatformPkg/PlatformPkg.dec + +[LibraryClasses] + DebugLib + +[Protocols] + + diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/ServerMgmtRtLib.h b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/ServerMgmtRtLib.h new file mode 100644 index 000000000000..12b2e82f9e6e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Include/Library/ServerMgmtRtLib.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 function 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 recorded + @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 DataType 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 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 >= EfiSmElogMax + @retval EFI_OUT_OF_RESOURCES If the DataSize is larger than the Elog temp 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 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 + 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 filled 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 redir 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 RecordId is NULL, all records in the + database are erased if permitted by the target. RecordId 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 respond. + @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 DataType. 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 disabled. + @retval EFI_NOT_FOUND The event log target was not found. + @retval EFI_NO_RESPONSE The event log target was found but did not respond. + @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/ServerManagementLib/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/ServerManagementLib/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 output + UINT8 UIE : 1; // 0 - Update INT disabled 1 - Update INT enabled + UINT8 AIE : 1; // 0 - Alarm INT disabled 1 - Alarm INT Enabled + UINT8 PIE : 1; // 0 - Periodic INT disabled 1 - Periodic INT Enabled + 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 = NULL; +VOID *mGenericElogRegistration = NULL; + +INTN DaysOfMonth[12] = { 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 = gBS->LocateProtocol (&gEfiGenericElogProtocolGuid, NULL, (VOID **)&mGenericElogProtocol); + if (EFI_ERROR (Status)) { + mGenericElogProtocol = NULL; + } +} + +/** + The function will set up a notification on the ELOG protocol. This function 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 = gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, GenericElogNotificationFunction, NULL, &Event); + ASSERT_EFI_ERROR (Status); + if (Status != EFI_SUCCESS) { + return Status; + } + + Status = gBS->RegisterProtocolNotify (&gEfiGenericElogProtocolGuid, Event, &mGenericElogRegistration); + ASSERT_EFI_ERROR (Status); + if (Status != 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 alert. 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 information. + @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 >= 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 == 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 data to be retrieved. + @param DataType - this is the type of Elog data to be gotten. Elog is redirected 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 DataSize. 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 filled 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 == 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 redir 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. RecordId 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 respond. + @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 == 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 DataType. 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 the DataType. Enabled is + TRUE and Disabled is FALSE. + + @retval EFI_SUCCESS - if the event log was successfully enabled or disabled. + @retval EFI_NOT_FOUND - the event log target was not found. + @retval EFI_NO_RESPONSE - the event log target was found but did not respond. + @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 == 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 == 0) { + if (Year % 100 == 0) { + if (Year % 400 == 0) { + return TRUE; + } else { + return FALSE; + } + } else { + return TRUE; + } + } else { + return FALSE; + } +} + +/** + This function calculates the total number leap days from 1970 to the current 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 = 0; + BaseYear = 1970; + NumOfYear = Time->Year - 1970; + + for (Index = 0; Index <= NumOfYear; Index++) { + if (IsLeapYear (BaseYear + Index)) { + Count++; + } + } + + // + // If the current year is a leap year but the month is January or February, + // then the leap day has not occurred and should not be counted. If it is + // February 29, the leap day is accounted for in CalculateNumOfDayPassedThisYear( ) + // + 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 of 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 = 0; + for (Index = 1; Index < Time.Month; Index++) { + NumOfDays += DaysOfMonth[Index - 1]; + } + + NumOfDays += 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 = BcdValue >> 4; + Low = 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 = TRUE; + } else { + Pm = FALSE; + } + + Time->Hour = (UINT8)(Time->Hour & 0x7f); + + if (RegisterB.Bits.DM == 0) { + Time->Year = BcdToDecimal ((UINT8)Time->Year); + Time->Month = BcdToDecimal (Time->Month); + Time->Day = BcdToDecimal (Time->Day); + Time->Hour = BcdToDecimal (Time->Hour); + Time->Minute = BcdToDecimal (Time->Minute); + Time->Second = BcdToDecimal (Time->Second); + } + + // + // If time is in 12 hour format, convert it to 24 hour format + // + if (RegisterB.Bits.MIL == 0) { + if (Pm && (Time->Hour < 12)) { + Time->Hour = (UINT8)(Time->Hour + 12); + } + + if (!Pm && (Time->Hour == 12)) { + Time->Hour = 0; + } + } + + Time->Nanosecond = 0; + Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE; + Time->Daylight = 0; +} + +/** + Test Century Register. + + @retval EFI_SUCCESS + @retval EFI_DEVICE_ERROR + +**/ +STATIC +EFI_STATUS +RtcTestCenturyRegister ( + VOID + ) +{ + UINT8 Century; + UINT8 Temp; + + Century = 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 = (UINT8)(RtcRead (RTC_ADDRESS_CENTURY) & 0x7f); + RtcWrite (RTC_ADDRESS_CENTURY, Century); + if ((Temp == 0x19) || (Temp == 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 = RtcRead (RTC_ADDRESS_REGISTER_D); + + if (RegisterD.Bits.VRT == 0) { + return EFI_DEVICE_ERROR; + } + + // + // Wait for up to 0.1 seconds for the RTC to be ready. + // + Timeout = (Timeout / 10) + 1; + RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A); + while (RegisterA.Bits.UIP == 1 && Timeout > 0) { + gBS->Stall (10); + RegisterA.Data = RtcRead (RTC_ADDRESS_REGISTER_A); + Timeout--; + } + + RegisterD.Data = RtcRead (RTC_ADDRESS_REGISTER_D); + if ((Timeout == 0) || (RegisterD.Bits.VRT == 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 == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Wait for up to 0.1 seconds for the RTC to be updated + // + Status = RtcWaitToUpdate (100000); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Read Register B + // + RegisterB.Data = RtcRead (RTC_ADDRESS_REGISTER_B); + + // + // Get the Time/Date/Daylight Savings values. + // + Time->Second = RtcRead (RTC_ADDRESS_SECONDS); + Time->Minute = RtcRead (RTC_ADDRESS_MINUTES); + Time->Hour = RtcRead (RTC_ADDRESS_HOURS); + Time->Day = RtcRead (RTC_ADDRESS_DAY_OF_THE_MONTH); + Time->Month = RtcRead (RTC_ADDRESS_MONTH); + Time->Year = RtcRead (RTC_ADDRESS_YEAR); + + ConvertRtcTimeToEfiTime (Time, RegisterB); + + if (RtcTestCenturyRegister () == EFI_SUCCESS) { + Century = BcdToDecimal ((UINT8)(RtcRead (RTC_ADDRESS_CENTURY) & 0x7f)); + } else { + Century = BcdToDecimal (RtcRead (RTC_ADDRESS_CENTURY)); + } + + Time->Year = (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 = RtcGetTime (&Time); + if (EFI_ERROR (Status)) { + return Status; + } + + NumOfYears = Time.Year - 1970; + NumOfLeapDays = CountNumOfLeapDays (&Time); + NumOfDays = CalculateNumOfDayPassedThisYear (Time); + + // + // Add 365 days for all years. Add additional days for Leap Years. Subtract off current day. + // + NumOfDays += (NumOfLeapDays + (365 * NumOfYears) - 1); + + *NumOfSeconds = (UINT32)(3600 * 24 * NumOfDays + (Time.Hour * 3600) + (60 * Time.Minute) + Time.Second); + + return EFI_SUCCESS; +} diff --git a/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLibNull/ServerManagementLibNull.c b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLibNull/ServerManagementLibNull.c new file mode 100644 index 000000000000..7dd27f34878e --- /dev/null +++ b/Features/Intel/OutOfBandManagement/IpmiFeaturePkg/Library/ServerManagementLibNull/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 function 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 alert. 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 information. + @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 data to be retrieved. + @param DataType - this is the type of Elog data to be gotten. Elog is redirected 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 DataSize. 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 redir 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. RecordId 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 respond. + @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 DataType. 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 the 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 = 0; + + return EFI_NOT_FOUND; +} -- 2.39.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- 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/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-