diff --git a/EmulatorPkg/EmulatorPkg.dec b/EmulatorPkg/EmulatorPkg.dec
index 064f963c72..5d7fe6473e 100644
--- a/EmulatorPkg/EmulatorPkg.dec
+++ b/EmulatorPkg/EmulatorPkg.dec
@@ -46,6 +46,7 @@
gEmuSystemConfigGuid = { 0xF8626165, 0x6CEB, 0x924A, { 0xBA, 0xFC, 0xF1, 0x3A, 0xB9, 0xD6, 0x57, 0x28 } }
gEmuVirtualDisksGuid = { 0xf2ba331a, 0x8985, 0x11db, { 0xa4, 0x06, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }
gEmuPhysicalDisksGuid = { 0xf2bdcc96, 0x8985, 0x11db, { 0x87, 0x19, 0x00, 0x40, 0xd0, 0x2b, 0x18, 0x35 } }
+ gEmuRedfishServiceGuid = { 0x3fb208ac, 0x2185, 0x498c, { 0xbf, 0x46, 0xdc, 0x23, 0xda, 0x58, 0x7b, 0x55 } }
[PcdsFeatureFlag]
## If TRUE, if symbols only load on breakpoints and gdb entry
diff --git a/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c b/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c
new file mode 100644
index 0000000000..4e7bb65c06
--- /dev/null
+++ b/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.c
@@ -0,0 +1,528 @@
+/** @file
+ PCI/PCIe network interface instace of RedfishPlatformHostInterfaceLib
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#define VERBOSE_COLUME_SIZE (16)
+
+REDFISH_OVER_IP_PROTOCOL_DATA *mRedfishOverIpProtocolData;
+UINT8 mRedfishProtocolDataSize;
+
+/**
+ Get the MAC address of NIC.
+
+ @param[out] MacAddress Pointer to retrieve MAC address
+
+ @retval EFI_SUCCESS MAC address is returned in MacAddress
+
+**/
+EFI_STATUS
+GetMacAddressInformation (
+ OUT EFI_MAC_ADDRESS *MacAddress
+ )
+{
+ MAC_ADDR_DEVICE_PATH *Mac;
+ REST_EX_SERVICE_DEVICE_PATH_DATA *RestExServiceDevicePathData;
+ EFI_DEVICE_PATH_PROTOCOL *RestExServiceDevicePath;
+ MAC_ADDR_DEVICE_PATH *MacAddressDevicePath;
+
+ Mac = NULL;
+ RestExServiceDevicePathData = NULL;
+ RestExServiceDevicePath = NULL;
+
+ RestExServiceDevicePathData = (REST_EX_SERVICE_DEVICE_PATH_DATA *)PcdGetPtr(PcdRedfishRestExServiceDevicePath);
+ if (RestExServiceDevicePathData == NULL ||
+ RestExServiceDevicePathData->DevicePathNum == 0 ||
+ !IsDevicePathValid (RestExServiceDevicePathData->DevicePath, 0)) {
+ return EFI_NOT_FOUND;
+ }
+
+ RestExServiceDevicePath = RestExServiceDevicePathData->DevicePath;
+ if (RestExServiceDevicePathData->DevicePathMatchMode != DEVICE_PATH_MATCH_MAC_NODE) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find Mac DevicePath Node.
+ //
+ while (!IsDevicePathEnd (RestExServiceDevicePath) &&
+ ((DevicePathType (RestExServiceDevicePath) != MESSAGING_DEVICE_PATH) ||
+ (DevicePathSubType (RestExServiceDevicePath) != MSG_MAC_ADDR_DP))) {
+ RestExServiceDevicePath = NextDevicePathNode (RestExServiceDevicePath);
+ }
+
+ if (!IsDevicePathEnd (RestExServiceDevicePath)) {
+ MacAddressDevicePath = (MAC_ADDR_DEVICE_PATH *)RestExServiceDevicePath;
+ CopyMem ((VOID *)MacAddress, (VOID *)&MacAddressDevicePath->MacAddress, sizeof (EFI_MAC_ADDRESS));
+ return EFI_SUCCESS;
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Get platform Redfish host interface device descriptor.
+
+ @param[out] DeviceType Pointer to retrieve device type.
+ @param[out] DeviceDescriptor Pointer to retrieve REDFISH_INTERFACE_DATA, caller has to free
+ this memory using FreePool().
+ @retval EFI_SUCCESS Device descriptor is returned successfully in DeviceDescriptor.
+ @retval EFI_NOT_FOUND No Redfish host interface descriptor provided on this platform.
+ @retval Others Fail to get device descriptor.
+**/
+EFI_STATUS
+RedfishPlatformHostInterfaceDeviceDescriptor (
+ OUT UINT8 *DeviceType,
+ OUT REDFISH_INTERFACE_DATA **DeviceDescriptor
+)
+{
+ EFI_STATUS Status;
+ EFI_MAC_ADDRESS MacAddress;
+ REDFISH_INTERFACE_DATA *RedfishInterfaceData;
+ PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *ThisDeviceDescriptor;
+
+ RedfishInterfaceData = AllocateZeroPool (sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1);
+ if (RedfishInterfaceData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ RedfishInterfaceData->DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2;
+ //
+ // Fill up device type information.
+ //
+ ThisDeviceDescriptor = (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *)((UINT8 *)RedfishInterfaceData + 1);
+ ThisDeviceDescriptor->Length = sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1;
+ Status = GetMacAddressInformation (&MacAddress);
+ if (EFI_ERROR (Status)) {
+ FreePool (RedfishInterfaceData);
+ return EFI_NOT_FOUND;
+ }
+ CopyMem ((VOID *)&ThisDeviceDescriptor->MacAddress, (VOID *)&MacAddress, sizeof (ThisDeviceDescriptor->MacAddress));
+ *DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2;
+ *DeviceDescriptor = RedfishInterfaceData;
+ return EFI_SUCCESS;
+}
+/**
+ Get platform Redfish host interface protocol data.
+ Caller should pass NULL in ProtocolRecord to retrive the first protocol record.
+ Then continuously pass previous ProtocolRecord for retrieving the next ProtocolRecord.
+
+ @param[out] ProtocolRecord Pointer to retrieve the protocol record.
+ caller has to free the new protocol record returned from
+ this function using FreePool().
+ @param[in] IndexOfProtocolData The index of protocol data.
+
+ @retval EFI_SUCCESS Protocol records are all returned.
+ @retval EFI_NOT_FOUND No more protocol records.
+ @retval Others Fail to get protocol records.
+**/
+EFI_STATUS
+RedfishPlatformHostInterfaceProtocolData (
+ OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord,
+ IN UINT8 IndexOfProtocolData
+)
+{
+ MC_HOST_INTERFACE_PROTOCOL_RECORD *ThisProtocolRecord;
+
+ if (mRedfishOverIpProtocolData == 0) {
+ return EFI_NOT_FOUND;
+ }
+ if (IndexOfProtocolData == 0) {
+ //
+ // Return the first Redfish protocol data to caller. We only have
+ // one protocol data in this case.
+ //
+ ThisProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD *) AllocatePool (mRedfishProtocolDataSize + sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - 1);
+ ThisProtocolRecord->ProtocolType = MCHostInterfaceProtocolTypeRedfishOverIP;
+ ThisProtocolRecord->ProtocolTypeDataLen = mRedfishProtocolDataSize;
+ CopyMem ((VOID *)&ThisProtocolRecord->ProtocolTypeData, (VOID *)mRedfishOverIpProtocolData, mRedfishProtocolDataSize);
+ *ProtocolRecord = ThisProtocolRecord;
+ return EFI_SUCCESS;
+ }
+ return EFI_NOT_FOUND;
+}
+/**
+ Dump IPv4 address.
+
+ @param[in] Ip IPv4 address
+**/
+VOID
+InternalDumpIp4Addr (
+ IN EFI_IPv4_ADDRESS *Ip
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < 4; Index++) {
+ DEBUG ((DEBUG_VERBOSE, "%d", Ip->Addr[Index]));
+ if (Index < 3) {
+ DEBUG ((DEBUG_VERBOSE, "."));
+ }
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+/**
+ Dump IPv6 address.
+
+ @param[in] Ip IPv6 address
+**/
+VOID
+InternalDumpIp6Addr (
+ IN EFI_IPv6_ADDRESS *Ip
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < 16; Index++) {
+ if (Ip->Addr[Index] != 0) {
+ DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index]));
+ }
+ Index++;
+
+ if (Index > 15) {
+ return;
+ }
+
+ if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {
+ DEBUG ((DEBUG_VERBOSE, "0"));
+ }
+ DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index]));
+
+ if (Index < 15) {
+ DEBUG ((DEBUG_VERBOSE, ":"));
+ }
+ }
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+/**
+ Dump data
+
+ @param[in] Data Pointer to data.
+ @param[in] Size size of data to dump.
+**/
+VOID
+InternalDumpData (
+ IN UINT8 *Data,
+ IN UINTN Size
+ )
+{
+ UINTN Index;
+ for (Index = 0; Index < Size; Index++) {
+ DEBUG ((DEBUG_VERBOSE, "%02x ", (UINTN)Data[Index]));
+ }
+}
+/**
+ Dump hex data
+
+ @param[in] Data Pointer to hex data.
+ @param[in] Size size of hex data to dump.
+**/
+VOID
+InternalDumpHex (
+ IN UINT8 *Data,
+ IN UINTN Size
+ )
+{
+ UINTN Index;
+ UINTN Count;
+ UINTN Left;
+
+ Count = Size / VERBOSE_COLUME_SIZE;
+ Left = Size % VERBOSE_COLUME_SIZE;
+ for (Index = 0; Index < Count; Index++) {
+ InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, VERBOSE_COLUME_SIZE);
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+ }
+
+ if (Left != 0) {
+ InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, Left);
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "\n"));
+}
+/**
+ Dump Redfish over IP protocol data
+
+ @param[in] RedfishProtocolData Pointer to REDFISH_OVER_IP_PROTOCOL_DATA
+ @param[in] RedfishProtocolDataSize size of data to dump.
+**/
+VOID
+DumpRedfishIpProtocolData (
+ IN REDFISH_OVER_IP_PROTOCOL_DATA *RedfishProtocolData,
+ IN UINT8 RedfishProtocolDataSize
+ )
+{
+ CHAR16 Hostname[16];
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData: \n"));
+ InternalDumpHex ((UINT8 *) RedfishProtocolData, RedfishProtocolDataSize);
+
+ DEBUG ((DEBUG_VERBOSE, "Parsing as below: \n"));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->ServiceUuid - %g\n", &(RedfishProtocolData->ServiceUuid)));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAssignmentType - %d\n", RedfishProtocolData->HostIpAssignmentType));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddressFormat - %d\n", RedfishProtocolData->HostIpAddressFormat));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddress: \n"));
+ if (RedfishProtocolData->HostIpAddressFormat == 0x01) {
+ InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpAddress));
+ } else {
+ InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpAddress));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpMask: \n"));
+ if (RedfishProtocolData->HostIpAddressFormat == 0x01) {
+ InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpMask));
+ } else {
+ InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpMask));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpDiscoveryType - %d\n", RedfishProtocolData->RedfishServiceIpDiscoveryType));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddressFormat - %d\n", RedfishProtocolData->RedfishServiceIpAddressFormat));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddress: \n"));
+ if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) {
+ InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress));
+ } else {
+ InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpMask: \n"));
+ if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) {
+ InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask));
+ } else {
+ InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpPort - %d\n", RedfishProtocolData->RedfishServiceIpPort));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceVlanId - %d\n", RedfishProtocolData->RedfishServiceVlanId));
+
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostnameLength - %d\n", RedfishProtocolData->RedfishServiceHostnameLength));
+
+ AsciiStrToUnicodeStrS((CHAR8 *) RedfishProtocolData->RedfishServiceHostname, Hostname, sizeof (Hostname) / sizeof (Hostname[0]));
+ DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostname - %s\n", Hostname));
+}
+
+/**
+ Get Redfish host interface protocol data from variale.
+
+ @param[out] RedfishProtocolData Pointer to retrieve REDFISH_OVER_IP_PROTOCOL_DATA.
+ @param[out] RedfishProtocolDataSize Size of REDFISH_OVER_IP_PROTOCOL_DATA.
+
+ @retval EFI_SUCESS REDFISH_OVER_IP_PROTOCOL_DATA is returned successfully.
+**/
+EFI_STATUS
+GetRedfishRecordFromVariable (
+ OUT REDFISH_OVER_IP_PROTOCOL_DATA **RedfishProtocolData,
+ OUT UINT8 *RedfishProtocolDataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 HostIpAssignmentType;
+ UINTN HostIpAssignmentTypeSize;
+ EFI_IPv4_ADDRESS HostIpAddress;
+ UINTN IPv4DataSize;
+ EFI_IPv4_ADDRESS HostIpMask;
+ EFI_IPv4_ADDRESS RedfishServiceIpAddress;
+ EFI_IPv4_ADDRESS RedfishServiceIpMask;
+ UINT16 RedfishServiceIpPort;
+ UINTN IpPortDataSize;
+ UINT8 HostNameSize;
+ CHAR8 RedfishHostName[20];
+
+ if (RedfishProtocolData == NULL || RedfishProtocolDataSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // 1. Retrieve Address Information from variable.
+ //
+ Status = gRT->GetVariable (
+ L"HostIpAssignmentType",
+ &gEmuRedfishServiceGuid,
+ NULL,
+ &HostIpAssignmentTypeSize,
+ &HostIpAssignmentType
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAssignmentType - %r\n", Status));
+ return Status;
+ }
+
+ IPv4DataSize = sizeof (EFI_IPv4_ADDRESS);
+ if (HostIpAssignmentType == 1 ) {
+ Status = gRT->GetVariable (
+ L"HostIpAddress",
+ &gEmuRedfishServiceGuid,
+ NULL,
+ &IPv4DataSize,
+ &HostIpAddress
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAddress - %r\n", Status));
+ return Status;
+ }
+
+ Status = gRT->GetVariable (
+ L"HostIpMask",
+ &gEmuRedfishServiceGuid,
+ NULL,
+ &IPv4DataSize,
+ &HostIpMask
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpMask - %r\n", Status));
+ return Status;
+ }
+ }
+
+ Status = gRT->GetVariable (
+ L"RedfishServiceIpAddress",
+ &gEmuRedfishServiceGuid,
+ NULL,
+ &IPv4DataSize,
+ &RedfishServiceIpAddress
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpAddress - %r\n", Status));
+ return Status;
+ }
+
+ Status = gRT->GetVariable (
+ L"RedfishServiceIpMask",
+ &gEmuRedfishServiceGuid,
+ NULL,
+ &IPv4DataSize,
+ &RedfishServiceIpMask
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpMask - %r\n", Status));
+ return Status;
+ }
+
+ Status = gRT->GetVariable (
+ L"RedfishServiceIpPort",
+ &gEmuRedfishServiceGuid,
+ NULL,
+ &IpPortDataSize,
+ &RedfishServiceIpPort
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpPort - %r\n", Status));
+ return Status;
+ }
+
+ AsciiSPrint (
+ RedfishHostName,
+ sizeof (RedfishHostName),
+ "%d.%d.%d.%d",
+ RedfishServiceIpAddress.Addr[0],
+ RedfishServiceIpAddress.Addr[1],
+ RedfishServiceIpAddress.Addr[2],
+ RedfishServiceIpAddress.Addr[3]
+ );
+
+ HostNameSize = (UINT8) AsciiStrLen (RedfishHostName) + 1;
+
+ //
+ // 2. Protocol Data Size.
+ //
+ *RedfishProtocolDataSize = sizeof (REDFISH_OVER_IP_PROTOCOL_DATA) - 1 + HostNameSize;
+
+ //
+ // 3. Protocol Data.
+ //
+ *RedfishProtocolData = (REDFISH_OVER_IP_PROTOCOL_DATA *) AllocateZeroPool (*RedfishProtocolDataSize);
+ if (*RedfishProtocolData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyGuid (&(*RedfishProtocolData)->ServiceUuid, &gEmuRedfishServiceGuid);
+
+ (*RedfishProtocolData)->HostIpAssignmentType = HostIpAssignmentType;
+ (*RedfishProtocolData)->HostIpAddressFormat = 1; // Only support IPv4
+
+ if (HostIpAssignmentType == 1 ) {
+ (*RedfishProtocolData)->HostIpAddress[0] = HostIpAddress.Addr[0];
+ (*RedfishProtocolData)->HostIpAddress[1] = HostIpAddress.Addr[1];
+ (*RedfishProtocolData)->HostIpAddress[2] = HostIpAddress.Addr[2];
+ (*RedfishProtocolData)->HostIpAddress[3] = HostIpAddress.Addr[3];
+
+ (*RedfishProtocolData)->HostIpMask[0] = HostIpMask.Addr[0];
+ (*RedfishProtocolData)->HostIpMask[1] = HostIpMask.Addr[1];
+ (*RedfishProtocolData)->HostIpMask[2] = HostIpMask.Addr[2];
+ (*RedfishProtocolData)->HostIpMask[3] = HostIpMask.Addr[3];
+ }
+
+ (*RedfishProtocolData)->RedfishServiceIpDiscoveryType = 1; // Use static IP address
+ (*RedfishProtocolData)->RedfishServiceIpAddressFormat = 1; // Only support IPv4
+
+ (*RedfishProtocolData)->RedfishServiceIpAddress[0] = RedfishServiceIpAddress.Addr[0];
+ (*RedfishProtocolData)->RedfishServiceIpAddress[1] = RedfishServiceIpAddress.Addr[1];
+ (*RedfishProtocolData)->RedfishServiceIpAddress[2] = RedfishServiceIpAddress.Addr[2];
+ (*RedfishProtocolData)->RedfishServiceIpAddress[3] = RedfishServiceIpAddress.Addr[3];
+
+ (*RedfishProtocolData)->RedfishServiceIpMask[0] = RedfishServiceIpMask.Addr[0];
+ (*RedfishProtocolData)->RedfishServiceIpMask[1] = RedfishServiceIpMask.Addr[1];
+ (*RedfishProtocolData)->RedfishServiceIpMask[2] = RedfishServiceIpMask.Addr[2];
+ (*RedfishProtocolData)->RedfishServiceIpMask[3] = RedfishServiceIpMask.Addr[3];
+
+ (*RedfishProtocolData)->RedfishServiceIpPort = RedfishServiceIpPort;
+ (*RedfishProtocolData)->RedfishServiceVlanId = 0xffffffff;
+
+ (*RedfishProtocolData)->RedfishServiceHostnameLength = HostNameSize;
+ AsciiStrCpyS ((CHAR8 *) ((*RedfishProtocolData)->RedfishServiceHostname), HostNameSize, RedfishHostName);
+
+ return Status;
+}
+
+/**
+ Construct Redfish host interface protocol data.
+
+ @param ImageHandle The image handle.
+ @param SystemTable The system table.
+
+ @retval EFI_SUCEESS Install Boot manager menu success.
+ @retval Other Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishPlatformHostInterfaceConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ Status = GetRedfishRecordFromVariable (&mRedfishOverIpProtocolData, &mRedfishProtocolDataSize);
+ DEBUG ((DEBUG_INFO, "%a: GetRedfishRecordFromVariable() - %r\n", __FUNCTION__, Status));
+ if (!EFI_ERROR (Status)) {
+ DumpRedfishIpProtocolData (mRedfishOverIpProtocolData, mRedfishProtocolDataSize);
+ }
+ return EFI_SUCCESS;
+}
diff --git a/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf b/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf
new file mode 100644
index 0000000000..668a81351e
--- /dev/null
+++ b/EmulatorPkg/Library/RedfishPlatformHostInterfaceLib/RedfishPlatformHostInterfaceLib.inf
@@ -0,0 +1,47 @@
+## @file
+# NULL instance of RedfishPlatformHostInterfaceLib
+#
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001000b
+ BASE_NAME = RedfishPlatformHostInterfaceLib
+ FILE_GUID = D5ECB7F2-4906-94E2-45B1-31BF4FD90122
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RedfishPlatformHostInterfaceLib
+ CONSTRUCTOR = RedfishPlatformHostInterfaceConstructor
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ RedfishPlatformHostInterfaceLib.c
+
+[Packages]
+ EmulatorPkg/EmulatorPkg.dec
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ RedfishPkg/RedfishPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ MemoryAllocationLib
+ PcdLib
+ UefiLib
+
+[Pcd]
+ gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExServiceDevicePath ## CONSUMES
+
+[Guids]
+ gEmuRedfishServiceGuid
+
+[Depex]
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid