RedfishHostInterfaceDxe.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. /** @file
  2. RedfishHostInterfaceDxe builds up SMBIOS Type 42h host interface
  3. record for Redfish service host interface using EFI MBIOS Protocol.
  4. RedfishHostInterfacePlatformLib is the platform-level library which
  5. provides the content of Redfish host interface type 42h record.
  6. Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  7. (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
  8. SPDX-License-Identifier: BSD-2-Clause-Patent
  9. **/
  10. #include <Uefi.h>
  11. #include <Library/BaseLib.h>
  12. #include <Library/BaseMemoryLib.h>
  13. #include <Library/DebugLib.h>
  14. #include <Library/MemoryAllocationLib.h>
  15. #include <Library/PrintLib.h>
  16. #include <Library/RedfishHostInterfaceLib.h>
  17. #include <Library/UefiLib.h>
  18. #include <Library/UefiBootServicesTableLib.h>
  19. #include <Library/UefiRuntimeServicesTableLib.h>
  20. /**
  21. Create SMBIOS type 42 record for Redfish host interface.
  22. @retval EFI_SUCCESS SMBIOS type 42 record is created.
  23. @retval Others Fail to create SMBIOS 42 record.
  24. **/
  25. EFI_STATUS
  26. RedfishCreateSmbiosTable42 (
  27. VOID
  28. )
  29. {
  30. REDFISH_INTERFACE_DATA *DeviceDescriptor;
  31. UINT8 DeviceDataLength;
  32. UINT8 DeviceType;
  33. EFI_STATUS Status;
  34. MC_HOST_INTERFACE_PROTOCOL_RECORD *ProtocolRecord;
  35. VOID *ProtocolRecords;
  36. VOID *NewProtocolRecords;
  37. UINT8 ProtocolCount;
  38. UINT8 CurrentProtocolsDataLength;
  39. UINT8 NewProtocolsDataLength;
  40. UINT8 ProtocolDataSize;
  41. SMBIOS_TABLE_TYPE42 *Type42Record;
  42. EFI_SMBIOS_PROTOCOL *Smbios;
  43. EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
  44. //
  45. // Get platform Redfish host interface device type descriptor data.
  46. //
  47. Status = RedfishPlatformHostInterfaceDeviceDescriptor (&DeviceType, &DeviceDescriptor);
  48. if (EFI_ERROR (Status)) {
  49. if (Status == EFI_NOT_FOUND) {
  50. DEBUG ((DEBUG_ERROR, "%a: No Redfish host interface descriptor is provided on this platform.", __FUNCTION__));
  51. return EFI_NOT_FOUND;
  52. }
  53. DEBUG ((DEBUG_ERROR, "%a: Fail to get device descriptor, %r.", __FUNCTION__, Status));
  54. return Status;
  55. }
  56. if ((DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) &&
  57. (DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2)
  58. )
  59. {
  60. DEBUG ((DEBUG_ERROR, "%a: Only support either protocol type 04h or 05h as Redfish host interface.", __FUNCTION__));
  61. return EFI_UNSUPPORTED;
  62. }
  63. if (DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
  64. DeviceDataLength = DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.Length;
  65. } else {
  66. DeviceDataLength = DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.Length;
  67. }
  68. //
  69. // Loop to get platform Redfish host interface protocol type data.
  70. //
  71. ProtocolRecord = NULL;
  72. ProtocolRecords = NULL;
  73. NewProtocolRecords = NULL;
  74. Type42Record = NULL;
  75. ProtocolCount = 0;
  76. CurrentProtocolsDataLength = 0;
  77. NewProtocolsDataLength = 0;
  78. while (TRUE) {
  79. Status = RedfishPlatformHostInterfaceProtocolData (&ProtocolRecord, ProtocolCount);
  80. if (Status == EFI_NOT_FOUND) {
  81. break;
  82. }
  83. if (EFI_ERROR (Status)) {
  84. DEBUG ((DEBUG_ERROR, "%a: Fail to get Redfish host interafce protocol type data.", __FUNCTION__));
  85. if (ProtocolRecords != NULL) {
  86. FreePool (ProtocolRecords);
  87. }
  88. if (ProtocolRecord != NULL) {
  89. FreePool (ProtocolRecord);
  90. }
  91. return Status;
  92. }
  93. ProtocolDataSize = sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - sizeof (ProtocolRecord->ProtocolTypeData) + ProtocolRecord->ProtocolTypeDataLen;
  94. NewProtocolsDataLength += ProtocolDataSize;
  95. if (ProtocolRecords == NULL) {
  96. ProtocolRecords = AllocateZeroPool (NewProtocolsDataLength);
  97. if (ProtocolRecords == NULL) {
  98. FreePool (ProtocolRecord);
  99. return EFI_OUT_OF_RESOURCES;
  100. }
  101. CopyMem ((VOID *)ProtocolRecords, (VOID *)ProtocolRecord, ProtocolDataSize);
  102. NewProtocolRecords = ProtocolRecords;
  103. } else {
  104. NewProtocolRecords = ReallocatePool (CurrentProtocolsDataLength, NewProtocolsDataLength, (VOID *)ProtocolRecords);
  105. if (NewProtocolRecords == NULL) {
  106. DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for Redfish host interface protocol data.", __FUNCTION__));
  107. FreePool (ProtocolRecords);
  108. FreePool (ProtocolRecord);
  109. return EFI_OUT_OF_RESOURCES;
  110. }
  111. CopyMem (
  112. (VOID *)((UINT8 *)NewProtocolRecords + CurrentProtocolsDataLength),
  113. (VOID *)ProtocolRecord,
  114. ProtocolDataSize
  115. );
  116. }
  117. FreePool (ProtocolRecord);
  118. CurrentProtocolsDataLength = NewProtocolsDataLength;
  119. ProtocolCount++;
  120. }
  121. if (ProtocolCount == 0) {
  122. goto ON_EXIT;
  123. }
  124. //
  125. // Construct SMBIOS Type 42h for Redfish host inteface.
  126. //
  127. // SMBIOS type 42 Record for Redfish Interface
  128. // 00h Type BYTE 42 Management Controller Host Interface structure indicator
  129. // 01h Length BYTE Varies Length of the structure, a minimum of 09h
  130. // 02h Handle WORD Varies
  131. // 04h Interface Type BYTE Varies Management Controller Interface Type.
  132. // 05h Interface Specific Data Length (n)
  133. // 06h Interface Specific data
  134. // 06h+n number of protocols defined for the host interface (typically 1)
  135. // 07h+n Include a Protocol Record for each protocol supported.
  136. //
  137. Type42Record = (SMBIOS_TABLE_TYPE42 *)AllocateZeroPool (
  138. sizeof (SMBIOS_TABLE_TYPE42) - 4
  139. + DeviceDataLength
  140. + 1 /// For Protocol Record Count
  141. + CurrentProtocolsDataLength
  142. + 2 /// Double NULL terminator/
  143. );
  144. if (Type42Record == NULL) {
  145. Status = EFI_OUT_OF_RESOURCES;
  146. goto ON_EXIT;
  147. }
  148. Type42Record->Hdr.Type = EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE;
  149. Type42Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE42) - 4
  150. + DeviceDataLength
  151. + 1
  152. + CurrentProtocolsDataLength;
  153. Type42Record->Hdr.Handle = 0;
  154. Type42Record->InterfaceType = MCHostInterfaceTypeNetworkHostInterface; // Network Host Interface
  155. //
  156. // Fill in InterfaceTypeSpecificDataLength field
  157. //
  158. Type42Record->InterfaceTypeSpecificDataLength = DeviceDataLength;
  159. //
  160. // Fill in InterfaceTypeSpecificData field
  161. //
  162. CopyMem (Type42Record->InterfaceTypeSpecificData, DeviceDescriptor, DeviceDataLength);
  163. FreePool (DeviceDescriptor);
  164. DeviceDescriptor = NULL;
  165. //
  166. // Fill in InterfaceTypeSpecificData Protocol Count field
  167. //
  168. *(Type42Record->InterfaceTypeSpecificData + DeviceDataLength) = ProtocolCount;
  169. //
  170. // Fill in Redfish Protocol Data
  171. //
  172. CopyMem (
  173. Type42Record->InterfaceTypeSpecificData + DeviceDataLength + 1,
  174. NewProtocolRecords,
  175. CurrentProtocolsDataLength
  176. );
  177. //
  178. // 5. Add Redfish interface data record to SMBIOS table 42
  179. //
  180. Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);
  181. if (EFI_ERROR (Status)) {
  182. goto ON_EXIT;
  183. }
  184. MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
  185. Status = Smbios->Add (
  186. Smbios,
  187. NULL,
  188. &MemArrayMappedAddrSmbiosHandle,
  189. (EFI_SMBIOS_TABLE_HEADER *)Type42Record
  190. );
  191. DEBUG ((DEBUG_INFO, "RedfishPlatformDxe: Smbios->Add() - %r\n", Status));
  192. if (EFI_ERROR (Status)) {
  193. goto ON_EXIT;
  194. }
  195. Status = EFI_SUCCESS;
  196. ON_EXIT:
  197. if (DeviceDescriptor != NULL) {
  198. FreePool (DeviceDescriptor);
  199. }
  200. if (NewProtocolRecords != NULL) {
  201. FreePool (NewProtocolRecords);
  202. }
  203. if (Type42Record != NULL) {
  204. FreePool (Type42Record);
  205. }
  206. return Status;
  207. }
  208. /**
  209. Main entry for this driver.
  210. @param ImageHandle Image handle this driver.
  211. @param SystemTable Pointer to SystemTable.
  212. @retval EFI_SUCCESS This function always complete successfully.
  213. **/
  214. EFI_STATUS
  215. EFIAPI
  216. RedfishHostInterfaceDxeEntryPoint (
  217. IN EFI_HANDLE ImageHandle,
  218. IN EFI_SYSTEM_TABLE *SystemTable
  219. )
  220. {
  221. //
  222. // Create SMBIOS type 42 record.
  223. //
  224. return RedfishCreateSmbiosTable42 ();
  225. }