--- /dev/null
+/** @file\r
+ RedfishHostInterfaceDxe builds up SMBIOS Type 42h host interface\r
+ record for Redfish service host interface using EFI MBIOS Protocol.\r
+ RedfishHostInterfacePlatformLib is the platform-level library which\r
+ provides the content of Redfish host interface type 42h record.\r
+\r
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+ (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+#include <Uefi.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/RedfishHostInterfaceLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+\r
+/**\r
+ Create SMBIOS type 42 record for Redfish host interface.\r
+\r
+ @retval EFI_SUCESS SMBIOS type 42 record is created.\r
+ @retval Others Fail to create SMBIOS 42 record.\r
+\r
+**/\r
+EFI_STATUS\r
+RedfishCreateSmbiosTable42 (\r
+ VOID\r
+ )\r
+{\r
+ REDFISH_INTERFACE_DATA *DeviceDescriptor;\r
+ UINT8 DeviceDataLength;\r
+ UINT8 DeviceType;\r
+ EFI_STATUS Status;\r
+ MC_HOST_INTERFACE_PROTOCOL_RECORD *ProtocolRecord;\r
+ VOID *ProtocolRecords;\r
+ VOID *NewProtocolRecords;\r
+ UINT8 ProtocolCount;\r
+ UINT8 CurrentProtocolsDataLength;\r
+ UINT8 NewProtocolsDataLength;\r
+ UINT8 ProtocolDataSize;\r
+ SMBIOS_TABLE_TYPE42 *Type42Record;\r
+ EFI_SMBIOS_PROTOCOL *Smbios;\r
+ EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;\r
+\r
+ //\r
+ // Get platform Redfish host interface device type descriptor data.\r
+ //\r
+ Status = RedfishPlatformHostInterfaceDeviceDescriptor (&DeviceType, &DeviceDescriptor);\r
+ if (EFI_ERROR (Status)) {\r
+ if (Status == EFI_NOT_FOUND) {\r
+ DEBUG ((DEBUG_ERROR, "%a: No Redfish host interface descriptor is provided on this platform.", __FUNCTION__));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+ DEBUG((DEBUG_ERROR, "%a: Fail to get device descriptor, %r.", __FUNCTION__, Status));\r
+ return Status;\r
+ }\r
+ if (DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2 &&\r
+ DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2\r
+ ) {\r
+ DEBUG ((DEBUG_ERROR, "%a: Only support either protocol type 04h or 05h as Redfish host interface.", __FUNCTION__));\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ if (DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {\r
+ DeviceDataLength = DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.Length;\r
+ } else {\r
+ DeviceDataLength = DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.Length;\r
+ }\r
+ //\r
+ // Loop to get platform Redfish host interface protocol type data.\r
+ //\r
+ ProtocolRecord = NULL;\r
+ ProtocolRecords = NULL;\r
+ NewProtocolRecords = NULL;\r
+ Type42Record = NULL;\r
+ ProtocolCount = 0;\r
+ CurrentProtocolsDataLength = 0;\r
+ NewProtocolsDataLength = 0;\r
+ while (TRUE) {\r
+ Status = RedfishPlatformHostInterfaceProtocolData (&ProtocolRecord, ProtocolCount);\r
+ if (Status == EFI_NOT_FOUND) {\r
+ break;\r
+ }\r
+ if (EFI_ERROR(Status)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: Fail to get Redfish host interafce protocol type data.", __FUNCTION__));\r
+ if (ProtocolRecords != NULL) {\r
+ FreePool (ProtocolRecords);\r
+ }\r
+ if (ProtocolRecord != NULL) {\r
+ FreePool (ProtocolRecord);\r
+ }\r
+ return Status;\r
+ }\r
+ ProtocolDataSize = sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - sizeof(ProtocolRecord->ProtocolTypeData) + ProtocolRecord->ProtocolTypeDataLen;\r
+ NewProtocolsDataLength += ProtocolDataSize;\r
+ if (ProtocolRecords == NULL) {\r
+ ProtocolRecords = AllocateZeroPool (NewProtocolsDataLength);\r
+ if (ProtocolRecords == NULL) {\r
+ FreePool (ProtocolRecord);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem ((VOID *)ProtocolRecords, (VOID *)ProtocolRecord, ProtocolDataSize);\r
+ NewProtocolRecords = ProtocolRecords;\r
+ } else {\r
+ NewProtocolRecords = ReallocatePool(CurrentProtocolsDataLength, NewProtocolsDataLength, (VOID *)ProtocolRecords);\r
+ if (NewProtocolRecords == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for Redfish host interface protocol data."));\r
+ FreePool (ProtocolRecords);\r
+ FreePool (ProtocolRecord);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (\r
+ (VOID *)((UINT8 *)NewProtocolRecords + CurrentProtocolsDataLength),\r
+ (VOID *)ProtocolRecord,\r
+ ProtocolDataSize\r
+ );\r
+ }\r
+ FreePool (ProtocolRecord);\r
+ CurrentProtocolsDataLength = NewProtocolsDataLength;\r
+ ProtocolCount ++;\r
+ };\r
+ if (ProtocolCount == 0) {\r
+ goto ON_EXIT;\r
+ }\r
+ //\r
+ // Construct SMBIOS Type 42h for Redfish host inteface.\r
+ //\r
+ // SMBIOS type 42 Record for Redfish Interface\r
+ // 00h Type BYTE 42 Management Controller Host Interface structure indicator\r
+ // 01h Length BYTE Varies Length of the structure, a minimum of 09h\r
+ // 02h Handle WORD Varies\r
+ // 04h Interface Type BYTE Varies Management Controller Interface Type.\r
+ // 05h Interface Specific Data Length (n)\r
+ // 06h Interface Specific data\r
+ // 06h+n number of protocols defined for the host interface (typically 1)\r
+ // 07h+n Include a Protocol Record for each protocol supported.\r
+ //\r
+ Type42Record = (SMBIOS_TABLE_TYPE42 *) AllocateZeroPool (\r
+ sizeof (SMBIOS_TABLE_TYPE42) - 4\r
+ + DeviceDataLength\r
+ + 1 /// For Protocol Record Count\r
+ + CurrentProtocolsDataLength\r
+ + 2 /// Double NULL terminator/\r
+ );\r
+ if (Type42Record == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ Type42Record->Hdr.Type = EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE;\r
+ Type42Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE42) - 4\r
+ + DeviceDataLength\r
+ + 1\r
+ + CurrentProtocolsDataLength;\r
+ Type42Record->Hdr.Handle = 0;\r
+ Type42Record->InterfaceType = MCHostInterfaceTypeNetworkHostInterface; // Network Host Interface\r
+\r
+ //\r
+ // Fill in InterfaceTypeSpecificDataLength field\r
+ //\r
+ Type42Record->InterfaceTypeSpecificDataLength = DeviceDataLength;\r
+\r
+ //\r
+ // Fill in InterfaceTypeSpecificData field\r
+ //\r
+ CopyMem (Type42Record->InterfaceTypeSpecificData, DeviceDescriptor, DeviceDataLength);\r
+ FreePool (DeviceDescriptor);\r
+ DeviceDescriptor = NULL;\r
+\r
+ //\r
+ // Fill in InterfaceTypeSpecificData Protocol Count field\r
+ //\r
+ *(Type42Record->InterfaceTypeSpecificData + DeviceDataLength) = ProtocolCount;\r
+\r
+ //\r
+ // Fill in Redfish Protocol Data\r
+ //\r
+ CopyMem (\r
+ Type42Record->InterfaceTypeSpecificData + DeviceDataLength + 1,\r
+ NewProtocolRecords,\r
+ CurrentProtocolsDataLength\r
+ );\r
+\r
+ //\r
+ // 5. Add Redfish interface data record to SMBIOS table 42\r
+ //\r
+ Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios);\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;\r
+ Status = Smbios->Add (\r
+ Smbios,\r
+ NULL,\r
+ &MemArrayMappedAddrSmbiosHandle,\r
+ (EFI_SMBIOS_TABLE_HEADER*) Type42Record\r
+ );\r
+ DEBUG ((DEBUG_INFO, "RedfishPlatformDxe: Smbios->Add() - %r\n", Status));\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+ Status = EFI_SUCCESS;\r
+\r
+ON_EXIT:\r
+ if (DeviceDescriptor != NULL) {\r
+ FreePool (DeviceDescriptor);\r
+ }\r
+ if (NewProtocolRecords != NULL) {\r
+ FreePool (NewProtocolRecords);\r
+ }\r
+ if (Type42Record != NULL) {\r
+ FreePool (Type42Record);\r
+ }\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Main entry for this driver.\r
+\r
+ @param ImageHandle Image handle this driver.\r
+ @param SystemTable Pointer to SystemTable.\r
+\r
+ @retval EFI_SUCESS This function always complete successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+RedfishHostInterfaceDxeEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
+{\r
+ //\r
+ // Create SMBIOS type 42 record.\r
+ //\r
+ return RedfishCreateSmbiosTable42 ();\r
+}\r