From: Zhen Gong <zhen.gong@intel.com>
To: devel@edk2.groups.io
Cc: Zhen Gong <zhen.gong@intel.com>
Subject: [edk2-devel] [PATCH edk2-platforms 2/4] IpmiFeaturePkg: Add ServerManagementLib
Date: Fri, 27 Oct 2023 13:11:14 -0700 [thread overview]
Message-ID: <0dd43a52d5280ce892f5a6987c145081d708b4f2.1698437221.git.zhen.gong@intel.com> (raw)
In-Reply-To: <cover.1698437221.git.zhen.gong@intel.com>
Lightweight lib to support Server Management drivers.
Signed-off-by: Zhen Gong <zhen.gong@intel.com>
---
.../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.<BR>
+#
+# 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.<BR>
+#
+# 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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SERVER_MGMT_LIB_H_
+#define _SERVER_MGMT_LIB_H_
+
+#include <Protocol/GenericElog.h>
+
+/**
+ 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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/GenericElog.h>
+
+#include <Library/ServerMgmtRtLib.h>
+
+// #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.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/ServerMgmtRtLib.h>
+
+/**
+ 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 (#110230): https://edk2.groups.io/g/devel/message/110230
Mute This Topic: https://groups.io/mt/102231767/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-10-27 22:38 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-27 20:11 [edk2-devel] [PATCH edk2-platforms 0/4] IpmiFeaturePkg: Add server management features Zhen Gong
2023-10-27 20:11 ` [edk2-devel] [PATCH edk2-platforms 1/4] IpmiFeaturePkg: Add Elog drivers Zhen Gong
2023-10-27 20:11 ` Zhen Gong [this message]
2023-10-27 20:11 ` [edk2-devel] [PATCH edk2-platforms 3/4] IpmiFeaturePkg: Add ACPI power state drivers Zhen Gong
2023-10-27 20:11 ` [edk2-devel] [PATCH edk2-platforms 4/4] IpmiFeaturePkg: Add FRU drivers Zhen Gong
2023-10-29 1:58 ` [edk2-devel] [PATCH edk2-platforms 0/4] IpmiFeaturePkg: Add server management features Chang, Abner via groups.io
2023-10-29 21:07 ` Zhen Gong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=0dd43a52d5280ce892f5a6987c145081d708b4f2.1698437221.git.zhen.gong@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox