diff --git a/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.c b/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.c new file mode 100644 index 0000000000..ec7faefed7 --- /dev/null +++ b/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.c @@ -0,0 +1,243 @@ +/** @file + RedfishHostInterfaceDxe builds up SMBIOS Type 42h host interface + record for Redfish service host interface using EFI MBIOS Protocol. + RedfishHostInterfacePlatformLib is the platform-level library which + provides the content of Redfish host interface type 42h record. + + 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 + +/** + Create SMBIOS type 42 record for Redfish host interface. + + @retval EFI_SUCESS SMBIOS type 42 record is created. + @retval Others Fail to create SMBIOS 42 record. + +**/ +EFI_STATUS +RedfishCreateSmbiosTable42 ( + VOID + ) +{ + REDFISH_INTERFACE_DATA *DeviceDescriptor; + UINT8 DeviceDataLength; + UINT8 DeviceType; + EFI_STATUS Status; + MC_HOST_INTERFACE_PROTOCOL_RECORD *ProtocolRecord; + VOID *ProtocolRecords; + VOID *NewProtocolRecords; + UINT8 ProtocolCount; + UINT8 CurrentProtocolsDataLength; + UINT8 NewProtocolsDataLength; + UINT8 ProtocolDataSize; + SMBIOS_TABLE_TYPE42 *Type42Record; + EFI_SMBIOS_PROTOCOL *Smbios; + EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle; + + // + // Get platform Redfish host interface device type descriptor data. + // + Status = RedfishPlatformHostInterfaceDeviceDescriptor (&DeviceType, &DeviceDescriptor); + if (EFI_ERROR (Status)) { + if (Status == EFI_NOT_FOUND) { + DEBUG ((DEBUG_ERROR, "%a: No Redfish host interface descriptor is provided on this platform.", __FUNCTION__)); + return EFI_NOT_FOUND; + } + DEBUG((DEBUG_ERROR, "%a: Fail to get device descriptor, %r.", __FUNCTION__, Status)); + return Status; + } + if (DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2 && + DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2 + ) { + DEBUG ((DEBUG_ERROR, "%a: Only support either protocol type 04h or 05h as Redfish host interface.", __FUNCTION__)); + return EFI_UNSUPPORTED; + } + if (DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) { + DeviceDataLength = DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.Length; + } else { + DeviceDataLength = DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.Length; + } + // + // Loop to get platform Redfish host interface protocol type data. + // + ProtocolRecord = NULL; + ProtocolRecords = NULL; + NewProtocolRecords = NULL; + Type42Record = NULL; + ProtocolCount = 0; + CurrentProtocolsDataLength = 0; + NewProtocolsDataLength = 0; + while (TRUE) { + Status = RedfishPlatformHostInterfaceProtocolData (&ProtocolRecord, ProtocolCount); + if (Status == EFI_NOT_FOUND) { + break; + } + if (EFI_ERROR(Status)) { + DEBUG ((DEBUG_ERROR, "%a: Fail to get Redfish host interafce protocol type data.", __FUNCTION__)); + if (ProtocolRecords != NULL) { + FreePool (ProtocolRecords); + } + if (ProtocolRecord != NULL) { + FreePool (ProtocolRecord); + } + return Status; + } + ProtocolDataSize = sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - sizeof(ProtocolRecord->ProtocolTypeData) + ProtocolRecord->ProtocolTypeDataLen; + NewProtocolsDataLength += ProtocolDataSize; + if (ProtocolRecords == NULL) { + ProtocolRecords = AllocateZeroPool (NewProtocolsDataLength); + if (ProtocolRecords == NULL) { + FreePool (ProtocolRecord); + return EFI_OUT_OF_RESOURCES; + } + CopyMem ((VOID *)ProtocolRecords, (VOID *)ProtocolRecord, ProtocolDataSize); + NewProtocolRecords = ProtocolRecords; + } else { + NewProtocolRecords = ReallocatePool(CurrentProtocolsDataLength, NewProtocolsDataLength, (VOID *)ProtocolRecords); + if (NewProtocolRecords == NULL) { + DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for Redfish host interface protocol data.")); + FreePool (ProtocolRecords); + FreePool (ProtocolRecord); + return EFI_OUT_OF_RESOURCES; + } + CopyMem ( + (VOID *)((UINT8 *)NewProtocolRecords + CurrentProtocolsDataLength), + (VOID *)ProtocolRecord, + ProtocolDataSize + ); + } + FreePool (ProtocolRecord); + CurrentProtocolsDataLength = NewProtocolsDataLength; + ProtocolCount ++; + }; + if (ProtocolCount == 0) { + goto ON_EXIT; + } + // + // Construct SMBIOS Type 42h for Redfish host inteface. + // + // SMBIOS type 42 Record for Redfish Interface + // 00h Type BYTE 42 Management Controller Host Interface structure indicator + // 01h Length BYTE Varies Length of the structure, a minimum of 09h + // 02h Handle WORD Varies + // 04h Interface Type BYTE Varies Management Controller Interface Type. + // 05h Interface Specific Data Length (n) + // 06h Interface Specific data + // 06h+n number of protocols defined for the host interface (typically 1) + // 07h+n Include a Protocol Record for each protocol supported. + // + Type42Record = (SMBIOS_TABLE_TYPE42 *) AllocateZeroPool ( + sizeof (SMBIOS_TABLE_TYPE42) - 4 + + DeviceDataLength + + 1 /// For Protocol Record Count + + CurrentProtocolsDataLength + + 2 /// Double NULL terminator/ + ); + if (Type42Record == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Type42Record->Hdr.Type = EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE; + Type42Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE42) - 4 + + DeviceDataLength + + 1 + + CurrentProtocolsDataLength; + Type42Record->Hdr.Handle = 0; + Type42Record->InterfaceType = MCHostInterfaceTypeNetworkHostInterface; // Network Host Interface + + // + // Fill in InterfaceTypeSpecificDataLength field + // + Type42Record->InterfaceTypeSpecificDataLength = DeviceDataLength; + + // + // Fill in InterfaceTypeSpecificData field + // + CopyMem (Type42Record->InterfaceTypeSpecificData, DeviceDescriptor, DeviceDataLength); + FreePool (DeviceDescriptor); + DeviceDescriptor = NULL; + + // + // Fill in InterfaceTypeSpecificData Protocol Count field + // + *(Type42Record->InterfaceTypeSpecificData + DeviceDataLength) = ProtocolCount; + + // + // Fill in Redfish Protocol Data + // + CopyMem ( + Type42Record->InterfaceTypeSpecificData + DeviceDataLength + 1, + NewProtocolRecords, + CurrentProtocolsDataLength + ); + + // + // 5. Add Redfish interface data record to SMBIOS table 42 + // + Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID**)&Smbios); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; + Status = Smbios->Add ( + Smbios, + NULL, + &MemArrayMappedAddrSmbiosHandle, + (EFI_SMBIOS_TABLE_HEADER*) Type42Record + ); + DEBUG ((DEBUG_INFO, "RedfishPlatformDxe: Smbios->Add() - %r\n", Status)); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + Status = EFI_SUCCESS; + +ON_EXIT: + if (DeviceDescriptor != NULL) { + FreePool (DeviceDescriptor); + } + if (NewProtocolRecords != NULL) { + FreePool (NewProtocolRecords); + } + if (Type42Record != NULL) { + FreePool (Type42Record); + } + return Status; +} + +/** + Main entry for this driver. + + @param ImageHandle Image handle this driver. + @param SystemTable Pointer to SystemTable. + + @retval EFI_SUCESS This function always complete successfully. + +**/ +EFI_STATUS +EFIAPI +RedfishHostInterfaceDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + // + // Create SMBIOS type 42 record. + // + return RedfishCreateSmbiosTable42 (); +} diff --git a/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf b/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf new file mode 100644 index 0000000000..1cdae149aa --- /dev/null +++ b/RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf @@ -0,0 +1,50 @@ +## @file +# RedfishHostInterfaceDxe builds up SMBIOS Type 42h host interface +# record for Redfish service host interface using SMBIOS Protocol. +# RedfishHostInterfacePlatformLib is the platform-level library which +# provides the content of Redfish host interface type 42h record. +# +# Copyright (c) 2019, Intel Corporation. All rights reserved.
+# (C) Copyright 2020 Hewlett Packard Enterprise Development LP
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001000b + BASE_NAME = RedfishHostInterfaceDxe + FILE_GUID = 592626DA-4A1E-8B39-28BA-FEAD92C4A0A4 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = RedfishHostInterfaceDxeEntryPoint + +# +# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64 RISCV64 +# + +[Sources] + RedfishHostInterfaceDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + RedfishPkg/RedfishPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + MemoryAllocationLib + PrintLib + RedfishPlatformHostInterfaceLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + +[Protocols] + gEfiSmbiosProtocolGuid ## TO_START + +[Depex] + gEfiSmbiosProtocolGuid +