summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiewen Yao <jiewen.yao@intel.com>2018-03-04 22:08:25 +0800
committerJiewen Yao <jiewen.yao@intel.com>2018-03-16 16:41:15 +0800
commit923863e826faf98bf5755be50c533b2ea80f4a38 (patch)
treeb0477d7e151b3cf1b55ba6df593da5362673aeaa
parenta71c975862481cfdf4905801718ce0f5d8f20710 (diff)
downloadedk2-platforms-923863e826faf98bf5755be50c533b2ea80f4a38.tar.xz
Add IPMI support.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen.yao@intel.com>
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec10
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc21
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.c255
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.inf54
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/BmcSsdt.asl34
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/IpmiOprRegions.asi64
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.c240
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.inf40
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.c243
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.inf43
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.c90
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.inf43
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/IpmiEx.h296
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiCommandLib.h242
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiPlatformHookLib.h29
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.c73
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.inf41
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.c150
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.inf40
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.c95
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.inf38
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLib.inf38
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnApp.c255
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnChassis.c108
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnStorage.c282
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnTransport.c88
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.c52
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.inf34
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.c42
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.inf35
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.c118
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.inf40
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.c175
-rw-r--r--Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.inf44
34 files changed, 3452 insertions, 0 deletions
diff --git a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec
index a0e6f78a42..fb27647d3a 100644
--- a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+++ b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dec
@@ -28,6 +28,7 @@ PACKAGE_GUID = 290127D9-ABED-4DD8-A35D-73DCB4261BCB
[Includes]
Include
+Ipmi/Include
[Guids]
gAdvancedFeaturePkgTokenSpaceGuid = {0xa8514688, 0x6693, 0x4ab5, {0xaa, 0xc8, 0xcc, 0xa9, 0x8d, 0xde, 0x90, 0xe1}}
@@ -143,7 +144,16 @@ gAdvancedFeaturePkgTokenSpaceGuid = {0xa8514688, 0x6693, 0x4ab5, {0xaa,
}
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosType32SystemBootInformation.BootStatus|BootInformationStatusNoError
+[PcdsFixedAtBuild]
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdMaxSOLChannels|0x3|UINT8|0x40000009
+
+[PcdsDynamic, PcdsDynamicEx]
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress|0xCA2|UINT16|0x90000022
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdFRB2EnabledFlag|TRUE|BOOLEAN|0x10000030
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdFRBTimeoutValue|360|UINT16|0x10000040
+
[PcdsFeatureFlag]
gAdvancedFeaturePkgTokenSpaceGuid.PcdNetworkEnable |FALSE|BOOLEAN|0xF00000A1
gAdvancedFeaturePkgTokenSpaceGuid.PcdSmbiosEnable |FALSE|BOOLEAN|0xF00000A2
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdIpmiEnable |FALSE|BOOLEAN|0xF00000A3
diff --git a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
index fa590c3262..4fcf9ac002 100644
--- a/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
+++ b/Platform/Intel/AdvancedFeaturePkg/AdvancedFeaturePkg.dsc
@@ -99,9 +99,16 @@
UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+ ReportStatusCodeLib|MdePkg/Library/BaseReportStatusCodeLibNull/BaseReportStatusCodeLibNull.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+
+ IpmiPlatformHookLib|AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.inf
+ IpmiLib|AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.inf
+ IpmiCommandLib|AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLib.inf
+
[LibraryClasses.common.SEC,LibraryClasses.common.PEI_CORE,LibraryClasses.common.PEIM]
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
@@ -112,6 +119,9 @@
PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+[LibraryClasses.common.DXE_SMM_DRIVER,LibraryClasses.common.SMM_CORE]
+ SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTableLib.inf
+
###################################################################################################
#
# Components Section - list of the modules and components that will be processed by compilation
@@ -134,3 +144,14 @@
[Components]
AdvancedFeaturePkg/Smbios/SmbiosBasicDxe/SmbiosBasicDxe.inf
+
+ AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.inf
+ AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.inf
+ AdvancedFeaturePkg/Ipmi/Frb/FrbPei.inf
+ AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.inf
+ AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.inf
+ AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.inf
+ AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.inf
+ AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.inf
+ AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.inf
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.c
new file mode 100644
index 0000000000..5df9513dfb
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.c
@@ -0,0 +1,255 @@
+/** @file
+ BMC ACPI.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// Statements that include other header files
+//
+#include <PiDxe.h>
+
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/AcpiTable.h>
+
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+
+#ifndef EFI_ACPI_CREATOR_ID
+#define EFI_ACPI_CREATOR_ID SIGNATURE_32 ('M', 'S', 'F', 'T')
+#endif
+#ifndef EFI_ACPI_CREATOR_REVISION
+#define EFI_ACPI_CREATOR_REVISION 0x0100000D
+#endif
+
+/**
+
+ Locate the first instance of a protocol. If the protocol requested is an
+ FV protocol, then it will return the first FV that contains the ACPI table
+ storage file.
+
+ @param Protocol - The protocol to find.
+ Instance - Return pointer to the first instance of the protocol.
+ Type - The type of protocol to locate.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - The protocol could not be located.
+ @retval EFI_OUT_OF_RESOURCES - There are not enough resources to find the protocol.
+
+**/
+EFI_STATUS
+LocateSupportProtocol (
+ IN EFI_GUID *Protocol,
+ OUT VOID **Instance,
+ IN UINT32 Type
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ EFI_FV_FILETYPE FileType;
+ UINT32 FvStatus = 0;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN Size;
+ UINTN Index;
+
+ Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NumberOfHandles, &HandleBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Looking for FV with ACPI storage file
+ //
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ Status = gBS->HandleProtocol (HandleBuffer[Index], Protocol, Instance);
+ ASSERT (!EFI_ERROR (Status));
+
+ if (!Type) {
+ //
+ // Not looking for the FV protocol, so find the first instance of the
+ // protocol. There should not be any errors because our handle buffer
+ // should always contain at least one or LocateHandleBuffer would have
+ // returned not found.
+ //
+ break;
+ }
+ //
+ // See if it has the ACPI storage file
+ //
+ Status = ((EFI_FIRMWARE_VOLUME2_PROTOCOL *) (*Instance))->ReadFile (
+ *Instance,
+ &gEfiCallerIdGuid,
+ NULL,
+ &Size,
+ &FileType,
+ &Attributes,
+ &FvStatus
+ );
+
+ //
+ // If we found it, then we are done
+ //
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ gBS->FreePool (HandleBuffer);
+ return Status;
+}
+
+
+EFI_STATUS
+UpdateDeviceSsdtTable (
+ IN OUT EFI_ACPI_COMMON_HEADER *Table
+ )
+{
+ EFI_ACPI_DESCRIPTION_HEADER *TableHeader = NULL;
+ UINT64 TempOemTableId;
+ UINT8 *DataPtr;
+ EFI_ACPI_IO_PORT_DESCRIPTOR *IoRsc;
+
+ TableHeader = (EFI_ACPI_DESCRIPTION_HEADER *)Table;
+
+ //
+ // Update the OEMID and OEM Table ID.
+ //
+ CopyMem (&TableHeader->OemId, PcdGetPtr (PcdAcpiDefaultOemId), sizeof(TableHeader->OemId));
+ TempOemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
+ CopyMem (&TableHeader->OemTableId, &TempOemTableId, sizeof(UINT64));
+ TableHeader->CreatorId = EFI_ACPI_CREATOR_ID;
+ TableHeader->CreatorRevision = EFI_ACPI_CREATOR_REVISION;
+
+ //
+ // Update IO(Decode16, 0xCA2, 0xCA2, 0, 2)
+ //
+ DEBUG ((DEBUG_INFO, "UpdateDeviceSsdtTable - IPMI\n"));
+ for (DataPtr = (UINT8 *)(Table + 1);
+ DataPtr < (UINT8 *) ((UINT8 *) Table + Table->Length - 4);
+ DataPtr++) {
+ if (CompareMem(DataPtr, "_CRS", 4) == 0) {
+ DataPtr += 4; // Skip _CRS
+ ASSERT (*DataPtr == AML_BUFFER_OP);
+ DataPtr ++; // Skip AML_BUFFER_OP
+ ASSERT ((*DataPtr & (BIT7|BIT6)) == 0);
+ DataPtr ++; // Skip PkgLength - 0xD
+ ASSERT ((*DataPtr) == AML_BYTE_PREFIX);
+ DataPtr ++; // Skip BufferSize OpCode
+ DataPtr ++; // Skip BufferSize - 0xA
+ IoRsc = (VOID *)DataPtr;
+ ASSERT (IoRsc->Header.Bits.Type == ACPI_SMALL_ITEM_FLAG);
+ ASSERT (IoRsc->Header.Bits.Name == ACPI_SMALL_IO_PORT_DESCRIPTOR_NAME);
+ ASSERT (IoRsc->Header.Bits.Length == sizeof(EFI_ACPI_IO_PORT_DESCRIPTOR) - sizeof(ACPI_SMALL_RESOURCE_HEADER));
+ DEBUG ((DEBUG_INFO, "IPMI IO Base in ASL update - 0x%04x <= 0x%04x\n", IoRsc->BaseAddressMin, PcdGet16(PcdIpmiIoBaseAddress)));
+ IoRsc->BaseAddressMin = PcdGet16(PcdIpmiIoBaseAddress);
+ IoRsc->BaseAddressMax = PcdGet16(PcdIpmiIoBaseAddress);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+
+ Entry point for Acpi platform driver.
+
+ @param ImageHandle - A handle for the image that is initializing this driver.
+ @param SystemTable - A pointer to the EFI system table.
+
+ @retval EFI_SUCCESS - Driver initialized successfully.
+ @retval EFI_LOAD_ERROR - Failed to Initialize or has been loaded.
+ @retval EFI_OUT_OF_RESOURCES - Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EFIAPI
+BmcAcpiEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_STATUS AcpiStatus;
+
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+ INTN Instance = 0;
+ EFI_ACPI_COMMON_HEADER *CurrentTable = NULL;
+ UINTN TableHandle = 0;
+ UINT32 FvStatus;
+ UINT32 Size;
+
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ UINTN TableSize;
+
+
+ //
+ // Find the AcpiTable protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID**)&AcpiTable);
+ if (EFI_ERROR (Status)) {
+ return EFI_ABORTED;
+ }
+
+ //
+ // Locate the firmware volume protocol
+ //
+ Status = LocateSupportProtocol (&gEfiFirmwareVolume2ProtocolGuid, &FwVol, 1);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EFI_SUCCESS;
+ Instance = 0;
+
+ //
+ // Read tables from the storage file.
+ //
+ while (!EFI_ERROR (Status)) {
+ CurrentTable = NULL;
+
+ Status = FwVol->ReadSection (FwVol, &gEfiCallerIdGuid, EFI_SECTION_RAW, Instance, &CurrentTable, (UINTN *) &Size, &FvStatus);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Perform any table specific updates.
+ //
+ AcpiStatus = UpdateDeviceSsdtTable (CurrentTable);
+ if (!EFI_ERROR (AcpiStatus)) {
+
+ TableHandle = 0;
+ TableSize = ((EFI_ACPI_DESCRIPTION_HEADER *) CurrentTable)->Length;
+ ASSERT (Size >= TableSize);
+
+ Status = AcpiTable->InstallAcpiTable (
+ AcpiTable,
+ CurrentTable,
+ TableSize,
+ &TableHandle
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Increment the instance
+ //
+ Instance++;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.inf
new file mode 100644
index 0000000000..8a87991f19
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcAcpi.inf
@@ -0,0 +1,54 @@
+### @file
+# Component description file for BMC ACPI.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BmcAcpi
+ FILE_GUID = F59DAA23-D5D5-4d16-91FC-D03ABDC12FFE
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = BmcAcpiEntryPoint
+
+[Sources]
+ BmcAcpi.c
+ BmcSsdt/BmcSsdt.asl
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ BaseMemoryLib
+ DebugLib
+ UefiLib
+
+[Protocols]
+ gEfiFirmwareVolume2ProtocolGuid
+ gEfiAcpiTableProtocolGuid
+
+[Pcd]
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdIpmiIoBaseAddress
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+
+[Depex]
+ gEfiAcpiTableProtocolGuid
+
+[BuildOptions]
+ *_*_*_ASL_FLAGS = -oi
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/BmcSsdt.asl b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/BmcSsdt.asl
new file mode 100644
index 0000000000..98c015df0b
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/BmcSsdt.asl
@@ -0,0 +1,34 @@
+/** @file
+ BMC ACPI SSDT.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+DefinitionBlock (
+ "BmcSsdt.aml",
+ "SSDT",
+ 0x02, // SSDT revision.
+ // A Revision field value greater than or equal to 2 signifies that integers
+ // declared within the Definition Block are to be evaluated as 64-bit values
+ "INTEL", // OEM ID (6 byte string)
+ "BMCACPI", // OEM table ID (8 byte string)
+ 0x0 // OEM version of DSDT table (4 byte Integer)
+ )
+{
+
+ External(\_SB.PC00.LPC0, DeviceObj)
+
+ Scope (\_SB.PC00.LPC0)
+ {
+ #include "IpmiOprRegions.asi"
+ }
+
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/IpmiOprRegions.asi b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/IpmiOprRegions.asi
new file mode 100644
index 0000000000..7d01f74f01
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcAcpi/BmcSsdt/IpmiOprRegions.asi
@@ -0,0 +1,64 @@
+/** @file
+ IPMI ACPI SSDT.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+Device(IPMC)
+{
+ // Config DWord, modified during POST
+ // Bit definitions are the same as PPMFlags:
+ // [00] = Plug and Play BMC Detection enabled in setup
+ // [31:01] = Reserved = 0
+
+ Name(ECFL, 0x80000000)
+
+ // Return the interface specification revision
+ Method(_SRV)
+ {
+ // IPMI Specification Revision v2.0
+ Return(0x0200)
+ }
+
+ Method(_STA, 0)
+ {
+ //
+ // Assume OK
+ //
+ Store (0xF, Local0)
+
+ Return(Local0)
+
+ // Bit 0 - Set if the device is present.
+ // Bit 1 - Set if the device is enabled and decoding its resources.
+ // Bit 2 - Set if the device should be shown in the UI.
+ // Bit 3 - Set if the device is functioning properly (cleared if the device failed its diagnostics).
+ // Bit 4 - Set if the battery is present.
+ // Bit 5 - Reserved (must be cleared).
+ } // end of _STA
+
+ // Return the x86 resources consumed by BMC
+ Name(_CRS, ResourceTemplate()
+ {
+ // Uses 8-bit ports 0xCA2-0xCA5
+ IO(Decode16, 0xCA2, 0xCA2, 0, 2)
+ })
+
+ Name(_HID, "IPI0001") // IPMI device
+ Name(_IFT, 0x1) // KCS system interface type
+ Name(_STR, Unicode("IPMI_KCS"))
+
+ Name(_UID, 0) // First interface.
+
+
+} // end of Device(IPMC)
+
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.c
new file mode 100644
index 0000000000..988b179c01
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.c
@@ -0,0 +1,240 @@
+/** @file
+ BMC Event Log functions.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/IpmiCommandLib.h>
+
+EFI_STATUS
+EFIAPI
+CheckIfSelIsFull (
+ VOID
+ );
+
+/*++
+
+ Routine Description:
+ This function verifies the BMC SEL is full and When it is reports the error to the Error Manager.
+
+ Arguments:
+ None
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+EFI_STATUS
+WaitTillErased (
+ UINT8 *ResvId
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ BmcElogPrivateData - Bmc event log instance
+ ResvId - Reserved ID
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NO_RESPONSE
+
+--*/
+{
+ INTN Counter;
+ IPMI_CLEAR_SEL_REQUEST ClearSel;
+ IPMI_CLEAR_SEL_RESPONSE ClearSelResponse;
+
+ Counter = 0x200;
+
+ while (TRUE) {
+ ZeroMem (&ClearSel, sizeof(ClearSel));
+ ClearSel.Reserve[0] = ResvId[0];
+ ClearSel.Reserve[1] = ResvId[1];
+ ClearSel.AscC = 0x43;
+ ClearSel.AscL = 0x4C;
+ ClearSel.AscR = 0x52;
+ ClearSel.Erase = 0x00;
+
+ IpmiClearSel (
+ &ClearSel,
+ &ClearSelResponse
+ );
+
+ if ((ClearSelResponse.ErasureProgress & 0xf) == 1) {
+ return EFI_SUCCESS;
+ }
+ //
+ // If there is not a response from the BMC controller we need to return and not hang.
+ //
+ --Counter;
+ if (Counter == 0x0) {
+ return EFI_NO_RESPONSE;
+ }
+ }
+}
+
+EFI_STATUS
+EfiActivateBmcElog (
+ IN BOOLEAN *EnableElog,
+ OUT BOOLEAN *ElogStatus
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ This - Protocol pointer
+ DataType - indicate event log type
+ EnableElog - Enable/Disable event log
+ ElogStatus - return log status
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT8 ElogStat;
+ IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST SetBmcGlobalEnables;
+ IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE GetBmcGlobalEnables;
+ UINT8 CompletionCode;
+
+ Status = EFI_SUCCESS;
+ ElogStat = 0;
+
+ Status = IpmiGetBmcGlobalEnables (&GetBmcGlobalEnables);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ if (EnableElog == NULL) {
+ *ElogStatus = GetBmcGlobalEnables.SystemEventLogging;
+ } else {
+ if (Status == EFI_SUCCESS) {
+ if (*EnableElog) {
+ ElogStat = 1;
+ }
+
+ CopyMem (&SetBmcGlobalEnables, (UINT8 *)&GetBmcGlobalEnables + sizeof(UINT8), sizeof(UINT8));
+ SetBmcGlobalEnables.EnableSystemEventLogging = ElogStat;
+
+ Status = IpmiSetBmcGlobalEnables (&SetBmcGlobalEnables, &CompletionCode);
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+SetElogRedirInstall (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ BOOLEAN EnableElog;
+ BOOLEAN ElogStatus;
+
+ //
+ // Activate the Event Log (This should depend upon Setup).
+ //
+ EfiActivateBmcElog (&EnableElog, &ElogStatus);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializeBmcElogLayer (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ ImageHandle - ImageHandle of the loaded driver
+ SystemTable - Pointer to the System Table
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ SetElogRedirInstall ();
+
+ CheckIfSelIsFull ();
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+CheckIfSelIsFull (
+ VOID
+ )
+/*++
+
+ Routine Description:
+ This function verifies the BMC SEL is full and When it is reports the error to the Error Manager.
+
+ Arguments:
+ None
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT8 SelIsFull;
+ IPMI_GET_SEL_INFO_RESPONSE SelInfo;
+
+ Status = IpmiGetSelInfo (&SelInfo);
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Check the Bit7 of the OperationByte if SEL is OverFlow.
+ //
+ SelIsFull = (SelInfo.OperationSupport & 0x80);
+ DEBUG ((DEBUG_INFO, "SelIsFull - 0x%x\n", SelIsFull));
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.inf
new file mode 100644
index 0000000000..93b30d665b
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/BmcElog/BmcElog.inf
@@ -0,0 +1,40 @@
+### @file
+# Component description file for BMC ELOG.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = BmcElog
+ FILE_GUID = 8A17F6CA-BF1A-45C4-FFFF-FFFF0C829DDD
+ MODULE_TYPE = DXE_DRIVER
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeBmcElogLayer
+
+[Sources]
+ BmcElog.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ DebugLib
+ UefiBootServicesTableLib
+ IpmiCommandLib
+
+[Depex]
+ TRUE
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.c
new file mode 100644
index 0000000000..42fc6fc2ec
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.c
@@ -0,0 +1,243 @@
+/** @file
+ IPMI FRB Driver.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IpmiCommandLib.h>
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+EFI_STATUS
+EfiDisableFrb (
+ VOID
+ )
+/*++
+
+ Routine Description:
+ This routine disables the specified FRB timer.
+
+ Arguments:
+ This - This pointer
+ FrbType - Type of FRB timer to get data on
+
+ Returns:
+ EFI_SUCCESS - FRB timer was disabled
+ EFI_ABORTED - Timer was already stopped
+ EFI_UNSUPPORTED - This type of FRB timer is not supported.
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_SET_WATCHDOG_TIMER_REQUEST SetWatchdogTimer;
+ UINT8 CompletionCode;
+ IPMI_GET_WATCHDOG_TIMER_RESPONSE GetWatchdogTimer;
+
+ Status = IpmiGetWatchdogTimer (&GetWatchdogTimer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check if timer is still running, if not abort disable routine.
+ //
+ if (GetWatchdogTimer.TimerUse.TimerRunning == 0) {
+ return EFI_ABORTED;
+ }
+
+ ZeroMem (&SetWatchdogTimer, sizeof(SetWatchdogTimer));
+ //
+ // Just flip the Timer Use bit. This should release the timer.
+ //
+ SetWatchdogTimer.TimerUse.TimerRunning = 0;
+ SetWatchdogTimer.TimerUse.TimerUse = IPMI_WATCHDOG_TIMER_BIOS_FRB2;
+ SetWatchdogTimer.TimerUseExpirationFlagsClear &= ~BIT2;
+ SetWatchdogTimer.TimerUseExpirationFlagsClear |= BIT1 | BIT4;
+
+ Status = IpmiSetWatchdogTimer (&SetWatchdogTimer, &CompletionCode);
+ return Status;
+}
+
+VOID
+EFIAPI
+DisableFRB2Handler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+ Routine Description:
+ Disables FRB2. This function gets called each time the
+ EFI_EVENT_SIGNAL_READY_TO_BOOT gets signaled
+
+ Arguments:
+ Standard event notification function arguments:
+ Event - the event that is signaled.
+ Context - not used here.
+
+ Returns:
+
+--*/
+{
+ DEBUG((EFI_D_ERROR, "!!! enter DisableFRB2Handler()!!!\n"));
+
+ EfiDisableFrb ();
+}
+
+EFI_STATUS
+CheckForAndReportErrors(
+ VOID
+ )
+/*++
+
+ Routine Description:
+ Check the Watchdog timer expiration flags and report the kind of watchdog
+ timeout occurred to the Error Manager.
+
+ Arguments:
+
+ Returns:
+ EFI_SUCCESS - Errors retrieved and reported
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_GET_WATCHDOG_TIMER_RESPONSE GetWatchdogTimer;
+ IPMI_SET_WATCHDOG_TIMER_REQUEST SetWatchdogTimer;
+ UINT8 CompletionCode;
+
+ //
+ // Get the Watchdog timer info to find out what kind of timer expiration occurred.
+ //
+ Status = IpmiGetWatchdogTimer (&GetWatchdogTimer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // If FRB2 Failure occurred, report it to the error manager and log a SEL.
+ //
+ if ((GetWatchdogTimer.TimerUseExpirationFlagsClear & BIT1) != 0) {
+ //
+ // Report the FRB2 time-out error
+ //
+ } else if ((GetWatchdogTimer.TimerUseExpirationFlagsClear & BIT3) != 0) {
+ //
+ // Report the OS Watchdog timer failure
+ //
+ }
+
+ //
+ // Need to clear Timer expiration flags after checking.
+ //
+ ZeroMem (&SetWatchdogTimer, sizeof(SetWatchdogTimer));
+ SetWatchdogTimer.TimerUse = GetWatchdogTimer.TimerUse;
+ SetWatchdogTimer.TimerActions = GetWatchdogTimer.TimerActions;
+ SetWatchdogTimer.PretimeoutInterval = GetWatchdogTimer.PretimeoutInterval;
+ SetWatchdogTimer.TimerUseExpirationFlagsClear = GetWatchdogTimer.TimerUseExpirationFlagsClear;
+ SetWatchdogTimer.InitialCountdownValue = GetWatchdogTimer.InitialCountdownValue;
+ SetWatchdogTimer.TimerUse.TimerRunning = 1;
+ SetWatchdogTimer.TimerUseExpirationFlagsClear |= BIT1 | BIT2 | BIT3;
+
+ Status = IpmiSetWatchdogTimer (&SetWatchdogTimer, &CompletionCode);
+
+ return Status;
+}
+
+EFI_STATUS
+ReportFrb2Status (
+ VOID
+ )
+/*++
+
+ Routine Description:
+ This routine is built only when DEBUG_MODE is enabled. It is used
+ to report the status of FRB2 when the FRB2 driver is installed.
+
+ Arguments:
+ none
+
+ Returns:
+ EFI_SUCCESS: All info was retrieved and reported
+ EFI_ERROR: There was an error during info retrieval
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_GET_WATCHDOG_TIMER_RESPONSE GetWatchdogTimer;
+
+ //
+ // Get the Watchdog timer info to find out what kind of timer expiration occurred.
+ //
+ Status = IpmiGetWatchdogTimer (&GetWatchdogTimer);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "Failed to get Watchdog Timer info from BMC.\n"));
+ return Status;
+ }
+
+ //
+ // Check if timer is running, report status to DEBUG_MODE output.
+ //
+ if (GetWatchdogTimer.TimerUse.TimerRunning == 1) {
+ DEBUG ((DEBUG_INFO, "FRB2 Timer is running.\n"));
+ } else {
+ DEBUG ((DEBUG_INFO, "FRB2 Timer is not running.\n"));
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FrbDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+ This is the standard EFI driver point. This function intitializes
+ the private data required for creating FRB Driver.
+
+ Arguments:
+ ImageHandle - Handle for the image of this driver
+ SystemTable - Pointer to the EFI System Table
+
+ Returns:
+ EFI_SUCCESS - Protocol successfully started and installed
+ EFI_UNSUPPORTED - Protocol can't be started
+
+--*/
+{
+ EFI_EVENT ReadyToBootEvent;
+ EFI_STATUS Status;
+
+ CheckForAndReportErrors();
+ ReportFrb2Status ();
+
+ //
+ // Register the event to Disable FRB2 before Boot.
+ //
+ Status = EfiCreateEventReadyToBootEx (
+ TPL_NOTIFY,
+ DisableFRB2Handler,
+ NULL,
+ &ReadyToBootEvent
+ );
+
+ return Status;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.inf
new file mode 100644
index 0000000000..6709bc5746
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbDxe.inf
@@ -0,0 +1,43 @@
+### @file
+# Component description file for IPMI FRB.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FrbDxe
+ FILE_GUID = F6C7812D-81BF-4e6d-A87D-E75AF17BD511
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FrbDxeEntryPoint
+
+[Sources]
+ FrbDxe.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ MemoryAllocationLib
+ UefiLib
+ DebugLib
+ BaseMemoryLib
+ IpmiCommandLib
+ PcdLib
+
+[Depex]
+ TRUE
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.c
new file mode 100644
index 0000000000..73f401284c
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.c
@@ -0,0 +1,90 @@
+/** @file
+ IPMI FRB PEIM.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IpmiCommandLib.h>
+
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+VOID
+SetWatchDogTimer (
+ IN BOOLEAN Frb2Enabled
+ )
+{
+ EFI_STATUS Status;
+ IPMI_SET_WATCHDOG_TIMER_REQUEST FrbTimer;
+ IPMI_GET_WATCHDOG_TIMER_RESPONSE GetWatchdogTimer;
+ UINT8 CompletionCode;
+
+ Status = IpmiGetWatchdogTimer (&GetWatchdogTimer);
+ if (EFI_ERROR(Status)) {
+ return ;
+ }
+
+ if (Frb2Enabled) {
+ ZeroMem (&FrbTimer, sizeof(FrbTimer));
+ //Byte 1
+ FrbTimer.TimerUse.TimerUse = IPMI_WATCHDOG_TIMER_BIOS_FRB2;
+ //Byte 2
+ FrbTimer.TimerActions = 0; //NormalBoot, NoTimeOutInterrupt. i.e no action when BMC watchdog timeout
+ //Byte 3
+ FrbTimer.PretimeoutInterval = 0;
+ //Byte 4
+ FrbTimer.TimerUseExpirationFlagsClear |= BIT1; //set Frb2ExpirationFlag
+
+ //Data Byte 5/6
+ FrbTimer.InitialCountdownValue = PcdGet16(PcdFRBTimeoutValue) * 10;
+
+ //Set BMC watchdog timer
+ Status = IpmiSetWatchdogTimer (&FrbTimer, &CompletionCode);
+ Status = IpmiResetWatchdogTimer (&CompletionCode);
+ }
+}
+
+EFI_STATUS
+InitializeFrbPei (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+ FfsHeader
+ PeiServices
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ BOOLEAN Frb2Enabled;
+
+ //
+ // If we are booting with defaults, then make sure FRB2 is enabled.
+ //
+ Frb2Enabled = PcdGetBool (PcdFRB2EnabledFlag);
+
+ SetWatchDogTimer (Frb2Enabled);
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.inf
new file mode 100644
index 0000000000..3c4771ef9c
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Frb/FrbPei.inf
@@ -0,0 +1,43 @@
+### @file
+# Component description file for IPMI FRB PEIM.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FrbPei
+ FILE_GUID = 7F9F9788-9F1F-4725-895C-3932F1A04DE8
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeFrbPei
+
+[Sources]
+ FrbPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ BaseMemoryLib
+ PcdLib
+ IpmiCommandLib
+
+[Pcd]
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdFRB2EnabledFlag
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdFRBTimeoutValue
+
+[Depex]
+ TRUE
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/IpmiEx.h b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/IpmiEx.h
new file mode 100644
index 0000000000..788ad40890
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/IpmiEx.h
@@ -0,0 +1,296 @@
+/** @file
+ IPMI 2.0 definitions from the IPMI Specification Version 2.0, Revision 1.1.
+
+ See IPMI specification, Appendix G, Command Assignments
+ and Appendix H, Sub-function Assignments.
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef _IPMI_EX_H_
+#define _IPMI_EX_H_
+
+#pragma pack(1)
+
+//
+// Generic completion Codes
+//
+#define IPMI_COMP_CODE_NORMAL 0x00
+#define IPMI_COMP_CODE_NODE_BUSY 0xC0
+#define IPMI_COMP_CODE_TIMEOUT 0xC3
+#define IPMI_COMP_CODE_OUT_OF_SPACE 0xC4
+#define IPMI_COMP_CODE_OUT_OF_RANGE 0xC9
+#define IPMI_COMP_CODE_CMD_RESP_NOT_PROVIDED 0xCE
+#define IPMI_COMP_CODE_FAIL_DUP_REQUEST 0xCF
+#define IPMI_COMP_CODE_SDR_REP_IN_UPDATE_MODE 0xD0
+#define IPMI_COMP_CODE_DEV_IN_FW_UPDATE_MODE 0xD1
+#define IPMI_COMP_CODE_BMC_INIT_IN_PROGRESS 0xD2
+#define IPMI_COMP_CODE_UNSPECIFIED 0xFF
+
+//
+// Watchdog timer
+//
+#define IPMI_WATCHDOG_TIMER_BIOS_FRB2 0x1
+#define IPMI_WATCHDOG_TIMER_BIOS_POST 0x2
+#define IPMI_WATCHDOG_TIMER_OS_LOADER 0x3
+#define IPMI_WATCHDOG_TIMER_SMS 0x4
+
+#define IPMI_WATCHDOG_TIMER_ACTION_NO_ACTION 0x0
+#define IPMI_WATCHDOG_TIMER_ACTION_HARD_RESET 0x1
+#define IPMI_WATCHDOG_TIMER_ACTION_POWER_DONW 0x2
+#define IPMI_WATCHDOG_TIMER_ACTION_POWER_CYCLE 0x3
+
+//
+// Device and Messaging
+//
+
+typedef struct {
+ UINT8 EnableReceiveMessageQueueInterrupt : 1;
+ UINT8 EnableEventMessageBufferFullInterrupt : 1;
+ UINT8 EnableEventMessageBuffer : 1;
+ UINT8 EnableSystemEventLogging : 1;
+ UINT8 Reserved : 1;
+ UINT8 Oem0Enable : 1;
+ UINT8 Oem1Enable : 1;
+ UINT8 Oem2Enable : 1;
+} IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 ReceiveMessageQueueInterrupt : 1;
+ UINT8 EventMessageBufferFullInterrupt : 1;
+ UINT8 EventMessageBuffer : 1;
+ UINT8 SystemEventLogging : 1;
+ UINT8 Reserved : 1;
+ UINT8 Oem0Enable : 1;
+ UINT8 Oem1Enable : 1;
+ UINT8 Oem2Enable : 1;
+} IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE;
+
+typedef struct {
+ UINT8 ClearReceiveMessageQueue : 1;
+ UINT8 ClearEventMessageBuffer : 1;
+ UINT8 Reserved0 : 1;
+ UINT8 ClearWatchdogPerTimeoutInterruptFlag : 1;
+ UINT8 Reserved : 1;
+ UINT8 ClearOem0Enable : 1;
+ UINT8 ClearOem1Enable : 1;
+ UINT8 ClearOem2Enable : 1;
+} IPMI_CLEAR_MESSAGE_FLAGS_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 ReceiveMessageAvailable : 1;
+ UINT8 EventMessageBufferFull : 1;
+ UINT8 Reserved0 : 1;
+ UINT8 WatchdogPerTimeoutInterruptOccurred : 1;
+ UINT8 Reserved : 1;
+ UINT8 Oem0DataAvailable : 1;
+ UINT8 Oem1DataAvailable : 1;
+ UINT8 Oem2DataAvailable : 1;
+} IPMI_GET_MESSAGE_FLAGS_RESPONSE;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 ChannelNumber : 4;
+ UINT8 InferredPrivilegeLevel : 4;
+ UINT8 MessageData[];
+} IPMI_GET_MESSAGE_RESPONSE;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 ChannelNumber : 4;
+ UINT8 Authentication : 1;
+ UINT8 Encryption : 1;
+ UINT8 Tracking : 2;
+ UINT8 MessageData[];
+} IPMI_SEND_MESSAGE_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 ResponseData[];
+} IPMI_SEND_MESSAGE_RESPONSE;
+
+//
+// SOL
+//
+
+typedef struct {
+ UINT8 SessionState : 4;
+ UINT8 Reserved : 4;
+ UINT8 PayloadInstance;
+ UINT8 FormatVersionMajor; // 1
+ UINT8 FormatVersionMinor; // 0
+} IPMI_SOL_ACTIVATING_REQUEST;
+
+typedef struct {
+ UINT8 ChannelNumber : 4;
+ UINT8 Reserved : 4;
+ UINT8 ParameterSelector;
+ UINT8 ParameterData[1];
+} IPMI_SET_SOL_CONFIGURATION_PARAMETERS_REQUEST;
+
+typedef struct {
+ UINT8 ChannelNumber : 4;
+ UINT8 Reserved : 3;
+ UINT8 GetParameter : 1;
+ UINT8 ParameterSelector;
+ UINT8 SetSelector;
+ UINT8 BlockSelector;
+} IPMI_GET_SOL_CONFIGURATION_PARAMETERS_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 ParameterRevision;
+ UINT8 ParameterData[1];
+} IPMI_GET_SOL_CONFIGURATION_PARAMETERS_RESPONSE;
+
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SET_IN_PROGRESS 0
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_ENABLE 1
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_AUTHENTICATION 2
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_CHARACTER_PARAM 3
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_RETRY 4
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_NV_BIT_RATE 5
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_VOLATILE_BIT_RATE 6
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_PAYLOAD_CHANNEL 7
+#define IPMI_SOL_CONFIGURATION_PARAMETER_SOL_PAYLOAD_PORT 8
+
+//
+// Chasis
+//
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 CapabilitiesFlags;
+ UINT8 ChassisFruInfoDeviceAddress;
+ UINT8 ChassisSDRDeviceAddress;
+ UINT8 ChassisSELDeviceAddress;
+ UINT8 ChassisSystemManagementDeviceAddress;
+ UINT8 ChassisBridgeDeviceAddress;
+} IPMI_GET_CHASSIS_CAPABILITIES_RESPONSE;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 CurrentPowerState;
+ UINT8 LastPowerEvent;
+ UINT8 MiscChassisState;
+ UINT8 FrontPanelButtonCapabilities;
+} IPMI_GET_CHASSIS_STATUS_RESPONSE;
+
+typedef struct {
+ UINT8 ChassisControl:4;
+ UINT8 Reserved:4;
+} IPMI_CHASSIS_CONTROL_REQUEST;
+
+typedef struct {
+ UINT8 PowerRestorePolicy:3;
+ UINT8 Reserved:5;
+} IPMI_SET_POWER_RESTORE_POLICY_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 PowerRestorePolicySupport;
+} IPMI_SET_POWER_RESTORE_POLICY_RESPONSE;
+
+//
+// FRU
+//
+
+typedef struct {
+ UINT8 DeviceId;
+} IPMI_GET_FRU_INVENTORY_AREA_INFO_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT16 InventoryAreaSize;
+ UINT8 AccessType;
+} IPMI_GET_FRU_INVENTORY_AREA_INFO_RESPONSE;
+
+typedef struct {
+ UINT8 DeviceId;
+ UINT16 InventoryOffset;
+ UINT8 CountToRead;
+} IPMI_READ_FRU_DATA_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 CountReturned;
+ UINT8 Data[];
+} IPMI_READ_FRU_DATA_RESPONSE;
+
+typedef struct {
+ UINT8 DeviceId;
+ UINT16 InventoryOffset;
+ UINT8 Data[];
+} IPMI_WRITE_FRU_DATA_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 CountWritten;
+} IPMI_WRITE_FRU_DATA_RESPONSE;
+
+//
+// SEL
+//
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT16 NextSelRecord;
+ UINT8 RecordData[];
+} IPMI_GET_SEL_ENTRY_RESPONSE;
+
+typedef struct {
+ UINT8 RecordData[16];
+} IPMI_ADD_SEL_ENTRY_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT16 RecordId;
+} IPMI_ADD_SEL_ENTRY_RESPONSE;
+
+typedef struct {
+ UINT16 ReservationId;
+ UINT16 RecordId;
+ UINT8 OffsetIntoRecord;
+ UINT8 InProgress;
+ UINT8 RecordData[];
+} IPMI_PARTIAL_ADD_SEL_ENTRY_REQUEST;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT16 RecordId;
+} IPMI_PARTIAL_ADD_SEL_ENTRY_RESPONSE;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT8 ErasureProgress;
+} IPMI_CLEAR_SEL_RESPONSE;
+
+typedef struct {
+ UINT8 CompletionCode;
+ UINT32 Timestamp;
+} IPMI_GET_SEL_TIME_RESPONSE;
+
+typedef struct {
+ UINT32 Timestamp;
+} IPMI_SET_SEL_TIME_REQUEST;
+
+//
+// SDR
+//
+typedef struct {
+ UINT8 CompletionCode;
+ UINT16 RecordId;
+ UINT8 RecordData[];
+} IPMI_GET_SDR_RESPONSE;
+
+#pragma pack()
+
+#endif \ No newline at end of file
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiCommandLib.h b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiCommandLib.h
new file mode 100644
index 0000000000..216f2adb55
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiCommandLib.h
@@ -0,0 +1,242 @@
+/** @file
+ This library abstract how to send/receive IPMI command.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _IPMI_COMMAND_LIB_H_
+#define _IPMI_COMMAND_LIB_H_
+
+#include <Uefi.h>
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+//
+// NetFnApp
+//
+EFI_STATUS
+EFIAPI
+IpmiGetDeviceId (
+ OUT IPMI_GET_DEVICE_ID_RESPONSE *DeviceId
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelfTestResult (
+ OUT IPMI_SELF_TEST_RESULT_RESPONSE *SelfTestResult
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiResetWatchdogTimer (
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiSetWatchdogTimer (
+ IN IPMI_SET_WATCHDOG_TIMER_REQUEST *SetWatchdogTimer,
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetWatchdogTimer (
+ OUT IPMI_GET_WATCHDOG_TIMER_RESPONSE *GetWatchdogTimer
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiSetBmcGlobalEnables (
+ IN IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST *SetBmcGlobalEnables,
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetBmcGlobalEnables (
+ OUT IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE *GetBmcGlobalEnables
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiClearMessageFlags (
+ IN IPMI_CLEAR_MESSAGE_FLAGS_REQUEST *ClearMessageFlagsRequest,
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetMessageFlags (
+ OUT IPMI_GET_MESSAGE_FLAGS_RESPONSE *GetMessageFlagsResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetMessage (
+ OUT IPMI_GET_MESSAGE_RESPONSE *GetMessageResponse,
+ IN OUT UINT32 *GetMessageResponseSize
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiSendMessage (
+ IN IPMI_SEND_MESSAGE_REQUEST *SendMessageRequest,
+ IN UINT32 SendMessageRequestSize,
+ OUT IPMI_SEND_MESSAGE_RESPONSE *SendMessageResponse,
+ IN OUT UINT32 *SendMessageResponseSize
+ );
+
+//
+// NetFnTransport
+//
+EFI_STATUS
+EFIAPI
+IpmiSolActivating (
+ IN IPMI_SOL_ACTIVATING_REQUEST *SolActivatingRequest,
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiSetSolConfigurationParameters (
+ IN IPMI_SET_SOL_CONFIGURATION_PARAMETERS_REQUEST *SetConfigurationParametersRequest,
+ IN UINT32 SetConfigurationParametersRequestSize,
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetSolConfigurationParameters (
+ IN IPMI_GET_SOL_CONFIGURATION_PARAMETERS_REQUEST *GetConfigurationParametersRequest,
+ OUT IPMI_GET_SOL_CONFIGURATION_PARAMETERS_RESPONSE *GetConfigurationParametersResponse,
+ IN OUT UINT32 *GetConfigurationParametersResponseSize
+ );
+
+//
+// NetFnChasis
+//
+EFI_STATUS
+EFIAPI
+IpmiGetChassisCapabilities (
+ OUT IPMI_GET_CHASSIS_CAPABILITIES_RESPONSE *GetChassisCapabilitiesResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetChassisStatus (
+ OUT IPMI_GET_CHASSIS_STATUS_RESPONSE *GetChassisStatusResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiChassisControl (
+ IN IPMI_CHASSIS_CONTROL_REQUEST *ChassisControlRequest,
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiSetPowerRestorePolicy (
+ IN IPMI_SET_POWER_RESTORE_POLICY_REQUEST *ChassisControlRequest,
+ OUT IPMI_SET_POWER_RESTORE_POLICY_RESPONSE *ChassisControlResponse
+ );
+
+//
+// NetFnStorage
+//
+EFI_STATUS
+EFIAPI
+IpmiGetFruInventoryAreaInfo (
+ IN IPMI_GET_FRU_INVENTORY_AREA_INFO_REQUEST *GetFruInventoryAreaInfoRequest,
+ OUT IPMI_GET_FRU_INVENTORY_AREA_INFO_RESPONSE *GetFruInventoryAreaInfoResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiReadFruData (
+ IN IPMI_READ_FRU_DATA_REQUEST *ReadFruDataRequest,
+ OUT IPMI_READ_FRU_DATA_RESPONSE *ReadFruDataResponse,
+ IN OUT UINT32 *ReadFruDataResponseSize
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiWriteFruData (
+ IN IPMI_WRITE_FRU_DATA_REQUEST *WriteFruDataRequest,
+ IN UINT32 WriteFruDataRequestSize,
+ OUT IPMI_WRITE_FRU_DATA_RESPONSE *WriteFruDataResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelInfo (
+ OUT IPMI_GET_SEL_INFO_RESPONSE *GetSelInfoResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelEntry (
+ IN IPMI_GET_SEL_ENTRY_REQUEST *GetSelEntryRequest,
+ OUT IPMI_GET_SEL_ENTRY_RESPONSE *GetSelEntryResponse,
+ IN OUT UINT32 *GetSelEntryResponseSize
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiAddSelEntry (
+ IN IPMI_ADD_SEL_ENTRY_REQUEST *AddSelEntryRequest,
+ OUT IPMI_ADD_SEL_ENTRY_RESPONSE *AddSelEntryResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiPartialAddSelEntry (
+ IN IPMI_PARTIAL_ADD_SEL_ENTRY_REQUEST *PartialAddSelEntryRequest,
+ IN UINT32 PartialAddSelEntryRequestSize,
+ OUT IPMI_PARTIAL_ADD_SEL_ENTRY_RESPONSE *PartialAddSelEntryResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiClearSel (
+ IN IPMI_CLEAR_SEL_REQUEST *ClearSelRequest,
+ OUT IPMI_CLEAR_SEL_RESPONSE *ClearSelResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelTime (
+ OUT IPMI_GET_SEL_TIME_RESPONSE *GetSelTimeResponse
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiSetSelTime (
+ IN IPMI_SET_SEL_TIME_REQUEST *SetSelTimeRequest,
+ OUT UINT8 *CompletionCode
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetSdrRepositoryInfo (
+ OUT IPMI_GET_SDR_REPOSITORY_INFO *GetSdrRepositoryInfo
+ );
+
+EFI_STATUS
+EFIAPI
+IpmiGetSdr (
+ IN IPMI_GET_SDR_REQUEST *GetSdrRequest,
+ OUT IPMI_GET_SDR_RESPONSE *GetSdrResponse,
+ IN OUT UINT32 *GetSdrResponseSize
+ );
+
+#endif
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiPlatformHookLib.h b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiPlatformHookLib.h
new file mode 100644
index 0000000000..404233e4b8
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Include/Library/IpmiPlatformHookLib.h
@@ -0,0 +1,29 @@
+/** @file
+ This library abstract the platform specific hook for IPMI.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _IPMI_PLATFORM_UPDATE_LIB_H_
+#define _IPMI_PLATFORM_UPDATE_LIB_H_
+
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/Smbios.h>
+
+EFI_STATUS
+EFIAPI
+PlatformIpmiIoRangeSet(
+ UINT16 IpmiIoBase
+ );
+
+#endif
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.c
new file mode 100644
index 0000000000..8371a90015
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.c
@@ -0,0 +1,73 @@
+/** @file
+ IPMI FRU Driver.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/IpmiCommandLib.h>
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+EFI_STATUS
+InitializeFru (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ Initialize SM Redirection Fru Layer
+
+Arguments:
+
+ ImageHandle - ImageHandle of the loaded driver
+ SystemTable - Pointer to the System Table
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_GET_DEVICE_ID_RESPONSE ControllerInfo;
+ IPMI_GET_FRU_INVENTORY_AREA_INFO_REQUEST GetFruInventoryAreaInfoRequest;
+ IPMI_GET_FRU_INVENTORY_AREA_INFO_RESPONSE GetFruInventoryAreaInfoResponse;
+
+ //
+ // Get all the SDR Records from BMC and retrieve the Record ID from the structure for future use.
+ //
+ Status = IpmiGetDeviceId (&ControllerInfo);
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "!!! IpmiFru IpmiGetDeviceId Status=%x\n", Status));
+ return Status;
+ }
+
+ DEBUG((EFI_D_ERROR, "!!! IpmiFru FruInventorySupport %x\n", ControllerInfo.FruInventorySupport));
+
+ if (ControllerInfo.FruInventorySupport) {
+ GetFruInventoryAreaInfoRequest.DeviceId = 0;
+ Status = IpmiGetFruInventoryAreaInfo (&GetFruInventoryAreaInfoRequest, &GetFruInventoryAreaInfoResponse);
+ if (EFI_ERROR (Status)) {
+ DEBUG((EFI_D_ERROR, "!!! IpmiFru IpmiGetFruInventoryAreaInfo Status=%x\n", Status));
+ return Status;
+ }
+ DEBUG((EFI_D_ERROR, "!!! IpmiFru InventoryAreaSize=%x\n", GetFruInventoryAreaInfoResponse.InventoryAreaSize));
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.inf
new file mode 100644
index 0000000000..755aa7025d
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiFru/IpmiFru.inf
@@ -0,0 +1,41 @@
+### @file
+# Component description file for IPMI FRU.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IpmiFru
+ FILE_GUID = 3F1D6464-2B4C-4640-BAC4-3DD905D26CDA
+ MODULE_TYPE = DXE_DRIVER
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeFru
+
+[Sources]
+ IpmiFru.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiLib
+ DebugLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ IpmiCommandLib
+
+[Depex]
+ TRUE
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.c
new file mode 100644
index 0000000000..0a49b87859
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.c
@@ -0,0 +1,150 @@
+/** @file
+ IPMI stack initialization.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IpmiCommandLib.h>
+
+#define BMC_TIMEOUT 30 // [s] How long shall BIOS wait for BMC
+#define BMC_KCS_TIMEOUT 5 // [s] Single KSC request timeout
+
+EFI_STATUS
+GetSelfTest (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Execute the Get Self Test results command to determine whether or not the BMC self tests
+ have passed
+
+Arguments:
+
+ mIpmiInstance - Data structure describing BMC variables and used for sending commands
+ StatusCodeValue - An array used to accumulate error codes for later reporting.
+ ErrorCount - Counter used to keep track of error codes in StatusCodeValue
+
+Returns:
+
+ EFI_SUCCESS - BMC Self test results are retrieved and saved into BmcStatus
+ EFI_DEVICE_ERROR - BMC failed to return self test results.
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_SELF_TEST_RESULT_RESPONSE TestResult;
+
+ //
+ // Get the SELF TEST Results.
+ //
+ Status = IpmiGetSelfTestResult (&TestResult);
+ if (EFI_ERROR(Status)) {
+ DEBUG((DEBUG_ERROR, "\n[IPMI] BMC does not respond (status: %r)!\n\n", Status));
+ return Status;
+ }
+
+ DEBUG((DEBUG_INFO, "[IPMI] BMC self-test result: %02X-%02X\n", TestResult.Result, TestResult.Param));
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetDeviceId (
+ OUT BOOLEAN *UpdateMode
+ )
+/*++
+
+Routine Description:
+ Execute the Get Device ID command to determine whether or not the BMC is in Force Update
+ Mode. If it is, then report it to the error manager.
+
+Arguments:
+
+Returns:
+ Status
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_GET_DEVICE_ID_RESPONSE BmcInfo;
+ UINT32 Retries;
+
+ //
+ // Set up a loop to retry for up to 30 seconds. Calculate retries not timeout
+ // so that in case KCS is not enabled and EfiIpmiSendCommand() returns
+ // immediately we will not wait all the 30 seconds.
+ //
+ Retries = BMC_TIMEOUT / BMC_KCS_TIMEOUT + 1;
+ //
+ // Get the device ID information for the BMC.
+ //
+ do {
+ Status = IpmiGetDeviceId (&BmcInfo);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ DEBUG ((DEBUG_ERROR, "[IPMI] BMC does not respond (status: %r), %d retries left\n", Status, Retries));
+ MicroSecondDelay(50 * 1000);
+ if (Retries-- == 0) {
+ return Status;
+ }
+ } while (TRUE);
+
+ DEBUG((DEBUG_INFO, "[IPMI] BMC Device ID: 0x%02X, firmware version: %d.%02X\n", BmcInfo.DeviceId, BmcInfo.MajorFirmwareRev, BmcInfo.MinorFirmwareRev));
+ *UpdateMode = (BOOLEAN)BmcInfo.UpdateMode;
+ return Status;
+}
+
+/**
+ The entry point of the Ipmi DXE.
+
+@param[in] ImageHandle - Handle of this driver image
+@param[in] SystemTable - Table containing standard EFI services
+
+@retval EFI_SUCCESS - Always success is returned even if KCS does not function
+
+ **/
+EFI_STATUS
+EFIAPI
+IpmiInterfaceInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ BOOLEAN UpdateMode;
+ EFI_STATUS Status;
+
+ DEBUG((EFI_D_ERROR,"IPMI Dxe:Get BMC Device Id\n"));
+
+ //
+ // Get the Device ID and check if the system is in Force Update mode.
+ //
+ Status = GetDeviceId (&UpdateMode);
+ //
+ // Do not continue initialization if the BMC is in Force Update Mode.
+ //
+ if (!EFI_ERROR(Status) && !UpdateMode) {
+ //
+ // Get the SELF TEST Results.
+ //
+ GetSelfTest ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.inf
new file mode 100644
index 0000000000..7c0b222187
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/DxeIpmiInit.inf
@@ -0,0 +1,40 @@
+### @file
+# Component description file for IPMI initialization.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = DxeIpmiInit
+ FILE_GUID = 07A01ACF-46D5-48de-A63D-74FA92AA8450
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = IpmiInterfaceInit
+
+[Sources]
+ DxeIpmiInit.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiBootServicesTableLib
+ DebugLib
+ UefiDriverEntryPoint
+ IpmiCommandLib
+ TimerLib
+
+[Depex]
+ TRUE \ No newline at end of file
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.c
new file mode 100644
index 0000000000..962aff6f4b
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.c
@@ -0,0 +1,95 @@
+/** @file
+ IPMI stack initialization in PEI.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IpmiCommandLib.h>
+
+#define BMC_TIMEOUT_PEI 50 // [s] How long shall BIOS wait for BMC
+#define BMC_KCS_TIMEOUT 5 // [s] Single KSC request timeout
+
+EFI_STATUS
+GetDeviceId (
+ OUT BOOLEAN *UpdateMode
+ )
+/*++
+
+Routine Description:
+ Execute the Get Device ID command to determine whether or not the BMC is in Force Update
+ Mode. If it is, then report it to the error manager.
+
+Arguments:
+
+Returns:
+ Status
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_GET_DEVICE_ID_RESPONSE BmcInfo;
+ UINT32 Retries;
+
+ //
+ // Set up a loop to retry for up to 30 seconds. Calculate retries not timeout
+ // so that in case KCS is not enabled and EfiIpmiSendCommand() returns
+ // immediately we will not wait all the 30 seconds.
+ //
+ Retries = BMC_TIMEOUT_PEI/ BMC_KCS_TIMEOUT + 1;
+ //
+ // Get the device ID information for the BMC.
+ //
+ do {
+ Status = IpmiGetDeviceId (&BmcInfo);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ DEBUG ((DEBUG_ERROR, "[IPMI] BMC does not respond (status: %r), %d retries left\n", Status, Retries));
+ if (Retries-- == 0) {
+ return Status;
+ }
+ } while (TRUE);
+
+ DEBUG((DEBUG_INFO, "[IPMI] BMC Device ID: 0x%02X, firmware version: %d.%02X\n", BmcInfo.DeviceId, BmcInfo.MajorFirmwareRev, BmcInfo.MinorFirmwareRev));
+ *UpdateMode = (BOOLEAN)BmcInfo.UpdateMode;
+ return Status;
+}
+
+/**
+ The entry point of the Ipmi PEIM.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS Indicates that Ipmi initialization completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+PeimIpmiInterfaceInit (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ BOOLEAN UpdateMode;
+ EFI_STATUS Status;
+
+ DEBUG((EFI_D_ERROR,"IPMI Peim:Get BMC Device Id\n"));
+
+ //
+ // Get the Device ID and check if the system is in Force Update mode.
+ //
+ Status = GetDeviceId (&UpdateMode);
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.inf
new file mode 100644
index 0000000000..4565701c1a
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/IpmiInit/PeiIpmiInit.inf
@@ -0,0 +1,38 @@
+### @file
+# Component description file for IPMI initialization in PEI.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = PeiIpmiInit
+ FILE_GUID = D8F57F4E-D67D-4f2c-8351-C7092986542F
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ ENTRY_POINT = PeimIpmiInterfaceInit
+
+[Sources]
+ PeiIpmiInit.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ DebugLib
+ IpmiCommandLib
+
+[Depex]
+ TRUE \ No newline at end of file
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLib.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLib.inf
new file mode 100644
index 0000000000..5c8b19c4df
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLib.inf
@@ -0,0 +1,38 @@
+### @file
+# Component description file for IPMI Command Library.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IpmiCommandLib
+ FILE_GUID = E599C9C7-5913-40A0-8669-67282E2BEC53
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = IpmiCommandLib
+
+[sources]
+ IpmiCommandLibNetFnApp.c
+ IpmiCommandLibNetFnTransport.c
+ IpmiCommandLibNetFnChassis.c
+ IpmiCommandLibNetFnStorage.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ IpmiLib
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnApp.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnApp.c
new file mode 100644
index 0000000000..f11b23a439
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnApp.c
@@ -0,0 +1,255 @@
+/** @file
+ IPMI Command - NetFnApp.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IpmiLib.h>
+
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+EFI_STATUS
+EFIAPI
+IpmiGetDeviceId (
+ OUT IPMI_GET_DEVICE_ID_RESPONSE *DeviceId
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*DeviceId);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_GET_DEVICE_ID,
+ NULL,
+ 0,
+ (VOID *)DeviceId,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelfTestResult (
+ OUT IPMI_SELF_TEST_RESULT_RESPONSE *SelfTestResult
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*SelfTestResult);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_GET_SELFTEST_RESULTS,
+ NULL,
+ 0,
+ (VOID *)SelfTestResult,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiResetWatchdogTimer (
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_RESET_WATCHDOG_TIMER,
+ NULL,
+ 0,
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiSetWatchdogTimer (
+ IN IPMI_SET_WATCHDOG_TIMER_REQUEST *SetWatchdogTimer,
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_SET_WATCHDOG_TIMER,
+ (VOID *)SetWatchdogTimer,
+ sizeof(*SetWatchdogTimer),
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetWatchdogTimer (
+ OUT IPMI_GET_WATCHDOG_TIMER_RESPONSE *GetWatchdogTimer
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetWatchdogTimer);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_GET_WATCHDOG_TIMER,
+ NULL,
+ 0,
+ (VOID *)GetWatchdogTimer,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiSetBmcGlobalEnables (
+ IN IPMI_SET_BMC_GLOBAL_ENABLES_REQUEST *SetBmcGlobalEnables,
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_SET_BMC_GLOBAL_ENABLES,
+ (VOID *)SetBmcGlobalEnables,
+ sizeof(*SetBmcGlobalEnables),
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetBmcGlobalEnables (
+ OUT IPMI_GET_BMC_GLOBAL_ENABLES_RESPONSE *GetBmcGlobalEnables
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetBmcGlobalEnables);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_GET_BMC_GLOBAL_ENABLES,
+ NULL,
+ 0,
+ (VOID *)GetBmcGlobalEnables,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiClearMessageFlags (
+ IN IPMI_CLEAR_MESSAGE_FLAGS_REQUEST *ClearMessageFlagsRequest,
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_CLEAR_MESSAGE_FLAGS,
+ (VOID *)ClearMessageFlagsRequest,
+ sizeof(*ClearMessageFlagsRequest),
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetMessageFlags (
+ OUT IPMI_GET_MESSAGE_FLAGS_RESPONSE *GetMessageFlagsResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetMessageFlagsResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_GET_MESSAGE_FLAGS,
+ NULL,
+ 0,
+ (VOID *)GetMessageFlagsResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetMessage (
+ OUT IPMI_GET_MESSAGE_RESPONSE *GetMessageResponse,
+ IN OUT UINT32 *GetMessageResponseSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_GET_MESSAGE,
+ NULL,
+ 0,
+ (VOID *)GetMessageResponse,
+ GetMessageResponseSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiSendMessage (
+ IN IPMI_SEND_MESSAGE_REQUEST *SendMessageRequest,
+ IN UINT32 SendMessageRequestSize,
+ OUT IPMI_SEND_MESSAGE_RESPONSE *SendMessageResponse,
+ IN OUT UINT32 *SendMessageResponseSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_APP,
+ IPMI_APP_SEND_MESSAGE,
+ (VOID *)SendMessageRequest,
+ SendMessageRequestSize,
+ (VOID *)SendMessageResponse,
+ SendMessageResponseSize
+ );
+ return Status;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnChassis.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnChassis.c
new file mode 100644
index 0000000000..eb699907a2
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnChassis.c
@@ -0,0 +1,108 @@
+/** @file
+ IPMI Command - NetFnChassis.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IpmiLib.h>
+
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+
+EFI_STATUS
+EFIAPI
+IpmiGetChassisCapabilities (
+ OUT IPMI_GET_CHASSIS_CAPABILITIES_RESPONSE *GetChassisCapabilitiesResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetChassisCapabilitiesResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_CHASSIS,
+ IPMI_CHASSIS_GET_CAPABILITIES,
+ NULL,
+ 0,
+ (VOID *)GetChassisCapabilitiesResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetChassisStatus (
+ OUT IPMI_GET_CHASSIS_STATUS_RESPONSE *GetChassisStatusResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetChassisStatusResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_CHASSIS,
+ IPMI_CHASSIS_GET_STATUS,
+ NULL,
+ 0,
+ (VOID *)GetChassisStatusResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiChassisControl (
+ IN IPMI_CHASSIS_CONTROL_REQUEST *ChassisControlRequest,
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_CHASSIS,
+ IPMI_CHASSIS_CONTROL,
+ (VOID *)ChassisControlRequest,
+ sizeof(*ChassisControlRequest),
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiSetPowerRestorePolicy (
+ IN IPMI_SET_POWER_RESTORE_POLICY_REQUEST *ChassisControlRequest,
+ OUT IPMI_SET_POWER_RESTORE_POLICY_RESPONSE *ChassisControlResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*ChassisControlResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_CHASSIS,
+ IPMI_CHASSIS_SET_POWER_RESTORE_POLICY,
+ (VOID *)ChassisControlRequest,
+ sizeof(*ChassisControlRequest),
+ (VOID *)ChassisControlResponse,
+ &DataSize
+ );
+ return Status;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnStorage.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnStorage.c
new file mode 100644
index 0000000000..ce2b7b9eb8
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnStorage.c
@@ -0,0 +1,282 @@
+/** @file
+ IPMI Command - NetFnStorage.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IpmiLib.h>
+
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+
+EFI_STATUS
+EFIAPI
+IpmiGetFruInventoryAreaInfo (
+ IN IPMI_GET_FRU_INVENTORY_AREA_INFO_REQUEST *GetFruInventoryAreaInfoRequest,
+ OUT IPMI_GET_FRU_INVENTORY_AREA_INFO_RESPONSE *GetFruInventoryAreaInfoResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetFruInventoryAreaInfoResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_FRU_INVENTORY_AREAINFO,
+ (VOID *)GetFruInventoryAreaInfoRequest,
+ sizeof(*GetFruInventoryAreaInfoRequest),
+ (VOID *)GetFruInventoryAreaInfoResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiReadFruData (
+ IN IPMI_READ_FRU_DATA_REQUEST *ReadFruDataRequest,
+ OUT IPMI_READ_FRU_DATA_RESPONSE *ReadFruDataResponse,
+ IN OUT UINT32 *ReadFruDataResponseSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_READ_FRU_DATA,
+ (VOID *)ReadFruDataRequest,
+ sizeof(*ReadFruDataRequest),
+ (VOID *)ReadFruDataResponse,
+ ReadFruDataResponseSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiWriteFruData (
+ IN IPMI_WRITE_FRU_DATA_REQUEST *WriteFruDataRequest,
+ IN UINT32 WriteFruDataRequestSize,
+ OUT IPMI_WRITE_FRU_DATA_RESPONSE *WriteFruDataResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*WriteFruDataResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_WRITE_FRU_DATA,
+ (VOID *)WriteFruDataRequest,
+ WriteFruDataRequestSize,
+ (VOID *)WriteFruDataResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelInfo (
+ OUT IPMI_GET_SEL_INFO_RESPONSE *GetSelInfoResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetSelInfoResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SEL_INFO,
+ NULL,
+ 0,
+ (VOID *)GetSelInfoResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelEntry (
+ IN IPMI_GET_SEL_ENTRY_REQUEST *GetSelEntryRequest,
+ OUT IPMI_GET_SEL_ENTRY_RESPONSE *GetSelEntryResponse,
+ IN OUT UINT32 *GetSelEntryResponseSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SEL_ENTRY,
+ (VOID *)GetSelEntryRequest,
+ sizeof(*GetSelEntryRequest),
+ (VOID *)GetSelEntryResponse,
+ GetSelEntryResponseSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiAddSelEntry (
+ IN IPMI_ADD_SEL_ENTRY_REQUEST *AddSelEntryRequest,
+ OUT IPMI_ADD_SEL_ENTRY_RESPONSE *AddSelEntryResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*AddSelEntryResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_ADD_SEL_ENTRY,
+ (VOID *)AddSelEntryRequest,
+ sizeof(*AddSelEntryRequest),
+ (VOID *)AddSelEntryResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiPartialAddSelEntry (
+ IN IPMI_PARTIAL_ADD_SEL_ENTRY_REQUEST *PartialAddSelEntryRequest,
+ IN UINT32 PartialAddSelEntryRequestSize,
+ OUT IPMI_PARTIAL_ADD_SEL_ENTRY_RESPONSE *PartialAddSelEntryResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*PartialAddSelEntryResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_PARTIAL_ADD_SEL_ENTRY,
+ (VOID *)PartialAddSelEntryRequest,
+ PartialAddSelEntryRequestSize,
+ (VOID *)PartialAddSelEntryResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiClearSel (
+ IN IPMI_CLEAR_SEL_REQUEST *ClearSelRequest,
+ OUT IPMI_CLEAR_SEL_RESPONSE *ClearSelResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*ClearSelResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_CLEAR_SEL,
+ (VOID *)ClearSelRequest,
+ sizeof(*ClearSelRequest),
+ (VOID *)ClearSelResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetSelTime (
+ OUT IPMI_GET_SEL_TIME_RESPONSE *GetSelTimeResponse
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetSelTimeResponse);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SEL_TIME,
+ NULL,
+ 0,
+ (VOID *)GetSelTimeResponse,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiSetSelTime (
+ IN IPMI_SET_SEL_TIME_REQUEST *SetSelTimeRequest,
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_SET_SEL_TIME,
+ (VOID *)SetSelTimeRequest,
+ sizeof(*SetSelTimeRequest),
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetSdrRepositoryInfo (
+ OUT IPMI_GET_SDR_REPOSITORY_INFO *GetSdrRepositoryInfo
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*GetSdrRepositoryInfo);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SDR_REPOSITORY_INFO,
+ NULL,
+ 0,
+ (VOID *)GetSdrRepositoryInfo,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetSdr (
+ IN IPMI_GET_SDR_REQUEST *GetSdrRequest,
+ OUT IPMI_GET_SDR_RESPONSE *GetSdrResponse,
+ IN OUT UINT32 *GetSdrResponseSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_STORAGE,
+ IPMI_STORAGE_GET_SDR,
+ (VOID *)GetSdrRequest,
+ sizeof(*GetSdrRequest),
+ (VOID *)GetSdrResponse,
+ GetSdrResponseSize
+ );
+ return Status;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnTransport.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnTransport.c
new file mode 100644
index 0000000000..925436e61e
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiCommandLib/IpmiCommandLibNetFnTransport.c
@@ -0,0 +1,88 @@
+/** @file
+ IPMI Command - NetFnTransport.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IpmiLib.h>
+
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+
+EFI_STATUS
+EFIAPI
+IpmiSolActivating (
+ IN IPMI_SOL_ACTIVATING_REQUEST *SolActivatingRequest,
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_TRANSPORT,
+ IPMI_TRANSPORT_SOL_ACTIVATING,
+ (VOID *)SolActivatingRequest,
+ sizeof(*SolActivatingRequest),
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiSetSolConfigurationParameters (
+ IN IPMI_SET_SOL_CONFIGURATION_PARAMETERS_REQUEST *SetConfigurationParametersRequest,
+ IN UINT32 SetConfigurationParametersRequestSize,
+ OUT UINT8 *CompletionCode
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DataSize;
+
+ DataSize = sizeof(*CompletionCode);
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_TRANSPORT,
+ IPMI_TRANSPORT_SET_SOL_CONFIG_PARAM,
+ (VOID *)SetConfigurationParametersRequest,
+ SetConfigurationParametersRequestSize,
+ (VOID *)CompletionCode,
+ &DataSize
+ );
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+IpmiGetSolConfigurationParameters (
+ IN IPMI_GET_SOL_CONFIGURATION_PARAMETERS_REQUEST *GetConfigurationParametersRequest,
+ OUT IPMI_GET_SOL_CONFIGURATION_PARAMETERS_RESPONSE *GetConfigurationParametersResponse,
+ IN OUT UINT32 *GetConfigurationParametersResponseSize
+ )
+{
+ EFI_STATUS Status;
+
+ Status = IpmiSubmitCommand (
+ IPMI_NETFN_TRANSPORT,
+ IPMI_TRANSPORT_GET_SOL_CONFIG_PARAM,
+ (VOID *)GetConfigurationParametersRequest,
+ sizeof(*GetConfigurationParametersRequest),
+ (VOID *)GetConfigurationParametersResponse,
+ GetConfigurationParametersResponseSize
+ );
+ return Status;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.c
new file mode 100644
index 0000000000..cdeac9d651
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.c
@@ -0,0 +1,52 @@
+/** @file
+ IPMI library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+/**
+ This service enables submitting commands via Ipmi.
+
+ @param[in] NetFunction Net function of the command.
+ @param[in] Command IPMI Command.
+ @param[in] RequestData Command Request Data.
+ @param[in] RequestDataSize Size of Command Request Data.
+ @param[out] ResponseData Command Response Data. The completion code is the first byte of response data.
+ @param[in, out] ResponseDataSize Size of Command Response Data.
+
+ @retval EFI_SUCCESS The command byte stream was successfully submit to the device and a response was successfully received.
+ @retval EFI_NOT_FOUND The command was not successfully sent to the device or a response was not successfully received from the device.
+ @retval EFI_NOT_READY Ipmi Device is not ready for Ipmi command access.
+ @retval EFI_DEVICE_ERROR Ipmi Device hardware error.
+ @retval EFI_TIMEOUT The command time out.
+ @retval EFI_UNSUPPORTED The command was not successfully sent to the device.
+ @retval EFI_OUT_OF_RESOURCES The resource allcation is out of resource or data size error.
+**/
+EFI_STATUS
+EFIAPI
+IpmiSubmitCommand (
+ IN UINT8 NetFunction,
+ IN UINT8 Command,
+ IN UINT8 *RequestData,
+ IN UINT32 RequestDataSize,
+ OUT UINT8 *ResponseData,
+ IN OUT UINT32 *ResponseDataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.inf
new file mode 100644
index 0000000000..c1860fbcae
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiLibNull/IpmiLibNull.inf
@@ -0,0 +1,34 @@
+### @file
+# Component description file for IPMI NULL Library.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IpmiLibNull
+ FILE_GUID = DDF0E1D9-F53F-429A-BD9C-5D12A321E625
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = IpmiLib
+
+[sources]
+ IpmiLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+
+[Pcd]
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.c
new file mode 100644
index 0000000000..4c8cb2af23
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.c
@@ -0,0 +1,42 @@
+/** @file
+ IPMI platform hook library.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/IpmiPlatformHookLib.h>
+
+//
+// Prototype definitions for IPMI Platform Update Library
+//
+EFI_STATUS
+EFIAPI
+PlatformIpmiIoRangeSet(
+ UINT16 IpmiIoBase
+ )
+/*++
+
+ Routine Description:
+
+ This function sets IPMI Io range
+
+ Arguments:
+
+ IpmiIoBase
+
+ Returns:
+
+ Status
+
+--*/
+{
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.inf
new file mode 100644
index 0000000000..bc4ad96690
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/Library/IpmiPlatformHookLibNull/IpmiPlatformHookLibNull.inf
@@ -0,0 +1,35 @@
+### @file
+# Component description file for IPMI platform Library.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = IpmiPlatformHookLibNull
+ FILE_GUID = C31A5B17-81DB-4D86-B376-17711BB6E0A5
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = IpmiPlatformHookLib
+
+[sources]
+ IpmiPlatformHookLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ DebugLib
+
+[Protocols]
+ gEfiIpmiTransportProtocolGuid
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.c
new file mode 100644
index 0000000000..c64c70f2a9
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.c
@@ -0,0 +1,118 @@
+/** @file
+ IPMI Os watchdog timer Driver.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/IpmiCommandLib.h>
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+BOOLEAN mOsWdtFlag = FALSE;
+
+EFI_EVENT mExitBootServicesEvent;
+
+VOID
+EFIAPI
+EnableEfiOsBootWdtHandler (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+ Enable the OS Boot Watchdog Timer.
+ Is called only on legacy or EFI OS boot.
+
+Arguments:
+ Event - Event type
+ *Context - Context for the event
+
+Returns:
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ IPMI_SET_WATCHDOG_TIMER_REQUEST SetWatchdogTimer;
+ UINT8 CompletionCode;
+ IPMI_GET_WATCHDOG_TIMER_RESPONSE GetWatchdogTimer;
+ static BOOLEAN OsWdtEventHandled = FALSE;
+
+ DEBUG((EFI_D_ERROR, "!!! EnableEfiOsBootWdtHandler()!!!\n"));
+
+ //
+ // Make sure it processes once only. And proceess it only if OsWdtFlag==TRUE;
+ //
+ if (OsWdtEventHandled || !mOsWdtFlag) {
+ return ;
+ }
+
+ OsWdtEventHandled = TRUE;
+
+ Status = IpmiGetWatchdogTimer (&GetWatchdogTimer);
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+
+ ZeroMem (&SetWatchdogTimer, sizeof(SetWatchdogTimer));
+ //
+ // Just flip the Timer Use bit. This should release the timer.
+ //
+ SetWatchdogTimer.TimerUse.TimerRunning = 1;
+ SetWatchdogTimer.TimerUse.TimerUse = IPMI_WATCHDOG_TIMER_OS_LOADER;
+ SetWatchdogTimer.TimerActions = IPMI_WATCHDOG_TIMER_ACTION_HARD_RESET;
+ SetWatchdogTimer.TimerUseExpirationFlagsClear &= ~BIT4;
+ SetWatchdogTimer.TimerUseExpirationFlagsClear |= BIT1 | BIT2;
+ SetWatchdogTimer.InitialCountdownValue = 600; // 100ms / count
+
+ Status = IpmiSetWatchdogTimer (&SetWatchdogTimer, &CompletionCode);
+ return ;
+}
+
+EFI_STATUS
+EFIAPI
+DriverInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This is the standard EFI driver point. This function intitializes
+ the private data required for creating ASRR Driver.
+
+Arguments:
+ As required for DXE driver enrty routine.
+ ImageHandle - ImageHandle of the loaded driver
+ SystemTable - Pointer to the System Table
+
+Returns:
+ EFI_SUCCESS - Protocol successfully started and installed.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_NOTIFY,
+ EnableEfiOsBootWdtHandler,
+ NULL,
+ &mExitBootServicesEvent
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.inf
new file mode 100644
index 0000000000..31e78ccc30
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/OsWdt/OsWdt.inf
@@ -0,0 +1,40 @@
+### @file
+# Component description file for IPMI OS watch dog timer driver.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = OsWdt
+ FILE_GUID = BE9B694A-B5D9-48e0-A527-6E1A49EB7028
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = DriverInit
+
+[Sources]
+ OsWdt.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ DebugLib
+ UefiBootServicesTableLib
+ BaseMemoryLib
+ IpmiCommandLib
+
+[Depex]
+ TRUE
+
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.c b/Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.c
new file mode 100644
index 0000000000..6d2dbd5bea
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.c
@@ -0,0 +1,175 @@
+/** @file
+ IPMI Serial Over Lan Driver.
+
+Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/IpmiCommandLib.h>
+#include <IndustryStandard/Ipmi.h>
+#include <IpmiEx.h>
+
+#define SOL_CMD_RETRY_COUNT 10
+
+/*++
+
+Routine Description:
+
+ This routine gets the SOL payload status or settings for a specific channel.
+
+Arguments:
+ Channel - LAN channel naumber.
+ ParamSel - Configuration parameter selection.
+ Data - Information returned from BMC.
+Returns:
+ EFI_SUCCESS - SOL configuration parameters are successfully read from BMC.
+ Others - SOL configuration parameters could not be read from BMC.
+
+--*/
+EFI_STATUS
+GetSOLStatus (
+ IN UINT8 Channel,
+ IN UINT8 ParamSel,
+ IN OUT UINT8 *Data
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ IPMI_GET_SOL_CONFIGURATION_PARAMETERS_REQUEST GetConfigurationParametersRequest;
+ IPMI_GET_SOL_CONFIGURATION_PARAMETERS_RESPONSE GetConfigurationParametersResponse;
+ UINT32 DataSize;
+ UINT8 RetryCount;
+
+ for (RetryCount = 0; RetryCount < SOL_CMD_RETRY_COUNT; RetryCount++) {
+ ZeroMem (&GetConfigurationParametersRequest, sizeof(GetConfigurationParametersRequest));
+ GetConfigurationParametersRequest.ChannelNumber = Channel;
+ GetConfigurationParametersRequest.ParameterSelector = ParamSel;
+
+ ZeroMem (&GetConfigurationParametersResponse, sizeof(GetConfigurationParametersResponse));
+
+ DataSize = sizeof(GetConfigurationParametersResponse);
+ Status = IpmiGetSolConfigurationParameters (
+ &GetConfigurationParametersRequest,
+ &GetConfigurationParametersResponse,
+ &DataSize
+ );
+
+ if (Status == EFI_SUCCESS){
+ break;
+ } else {
+ gBS->Stall(100000);
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ *Data = GetConfigurationParametersResponse.ParameterData[0];
+ }
+
+ return Status;
+}
+
+/*++
+
+Routine Description:
+
+ This routine sets the SOL payload configuration parameters for a specific channel.
+
+Arguments:
+ Channel - LAN channel naumber.
+ ParamSel - Configuration parameter selection.
+ Data - Configuration parameter values.
+Returns:
+ EFI_SUCCESS - SOL configuration parameters are sent to BMC.
+ Others - SOL configuration parameters could not be sent to BMC.
+
+--*/
+EFI_STATUS
+SetSOLParams (
+ IN UINT8 Channel,
+ IN UINT8 ParamSel,
+ IN UINT8 Data
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ IPMI_SET_SOL_CONFIGURATION_PARAMETERS_REQUEST SetConfigurationParametersRequest;
+ UINT8 CompletionCode;
+ UINT8 RetryCount;
+
+ for (RetryCount = 0; RetryCount < SOL_CMD_RETRY_COUNT; RetryCount++) {
+ ZeroMem (&SetConfigurationParametersRequest, sizeof(SetConfigurationParametersRequest));
+ SetConfigurationParametersRequest.ChannelNumber = Channel;
+ SetConfigurationParametersRequest.ParameterSelector = ParamSel;
+ SetConfigurationParametersRequest.ParameterData[0] = Data;
+
+ CompletionCode = 0;
+
+ Status = IpmiSetSolConfigurationParameters (
+ &SetConfigurationParametersRequest,
+ sizeof(SetConfigurationParametersRequest),
+ &CompletionCode
+ );
+
+ if (Status == EFI_SUCCESS) {
+ break;
+ } else {
+ gBS->Stall(100000);
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SolStatusEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+ This is the standard EFI driver point. This function intitializes
+ the private data required for creating SOL Status Driver.
+
+ Arguments:
+ ImageHandle - Handle for the image of this driver
+ SystemTable - Pointer to the EFI System Table
+
+ Returns:
+ EFI_SUCCESS - Protocol successfully installed
+ EFI_UNSUPPORTED - Protocol can't be installed.
+
+--*/
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 Channel;
+ BOOLEAN Enabled = FALSE;
+ BOOLEAN SOLEnabled = FALSE;
+
+ for (Channel = 1; Channel <= PcdGet8(PcdMaxSOLChannels); Channel++) {
+ Status = GetSOLStatus (Channel, IPMI_SOL_CONFIGURATION_PARAMETER_SOL_ENABLE, &Enabled);
+ if (Status == EFI_SUCCESS) {
+ if (Enabled == TRUE) {
+ SOLEnabled = TRUE;
+ }
+ DEBUG ((EFI_D_ERROR, "SOL enabling status for channel %x is %x\n", Channel, Enabled));
+ } else {
+ DEBUG ((EFI_D_ERROR, "Failed to get channel %x SOL status from BMC!, status is %x\n", Channel, Status));
+ }
+ }
+
+ return Status;
+}
diff --git a/Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.inf b/Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.inf
new file mode 100644
index 0000000000..886f6412ff
--- /dev/null
+++ b/Platform/Intel/AdvancedFeaturePkg/Ipmi/SolStatus/SolStatus.inf
@@ -0,0 +1,44 @@
+### @file
+# Component description file for IPMI Serial Over LAN driver.
+#
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SolStatus
+ FILE_GUID = F9887B5E-2D46-4213-8794-14F1FD39F6B8
+ MODULE_TYPE = DXE_DRIVER
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SolStatusEntryPoint
+
+[Sources]
+ SolStatus.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ AdvancedFeaturePkg/AdvancedFeaturePkg.dec
+
+[Pcd]
+ gAdvancedFeaturePkgTokenSpaceGuid.PcdMaxSOLChannels
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ DebugLib
+ UefiBootServicesTableLib
+ IpmiCommandLib
+ PcdLib
+
+[Depex]
+ TRUE
+