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