TianoCore EDK2 master
Loading...
Searching...
No Matches
RedfishHostInterfaceDxe.c
Go to the documentation of this file.
1
16#include <Uefi.h>
17#include <Library/BaseLib.h>
19#include <Library/DebugLib.h>
21#include <Library/PrintLib.h>
23#include <Library/UefiLib.h>
26
27static EFI_EVENT mPlatformHostInterfaceReadylEvent = NULL;
28static VOID *mPlatformHostInterfaceReadyRegistration = NULL;
29
39 VOID
40 )
41{
42 REDFISH_INTERFACE_DATA *DeviceDescriptor;
43 UINT8 DeviceDataLength;
44 UINT8 DeviceType;
45 EFI_STATUS Status;
47 VOID *ProtocolRecords;
48 VOID *NewProtocolRecords;
49 UINT8 ProtocolCount;
50 UINT8 CurrentProtocolsDataLength;
51 UINT8 NewProtocolsDataLength;
52 UINT8 ProtocolDataSize;
53 SMBIOS_TABLE_TYPE42 *Type42Record;
54 EFI_SMBIOS_PROTOCOL *Smbios;
55 EFI_SMBIOS_HANDLE MemArrayMappedAddrSmbiosHandle;
56 EFI_HANDLE Handle;
57
58 Handle = NULL;
59 //
60 // Get platform Redfish host interface device type descriptor data.
61 //
62 Status = RedfishPlatformHostInterfaceDeviceDescriptor (&DeviceType, &DeviceDescriptor);
63 if (EFI_ERROR (Status)) {
64 if (Status == EFI_NOT_FOUND) {
65 DEBUG ((DEBUG_ERROR, "%a: No Redfish host interface descriptor is provided on this platform.\n", __func__));
66 return EFI_NOT_FOUND;
67 }
68
69 DEBUG ((DEBUG_ERROR, "%a: Fail to get device descriptor, %r.", __func__, Status));
70 return Status;
71 }
72
73 if ((DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2) &&
74 (DeviceType != REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2)
75 )
76 {
77 DEBUG ((DEBUG_ERROR, "%a: Only support either protocol type 04h or 05h as Redfish host interface.", __func__));
78 return EFI_UNSUPPORTED;
79 }
80
81 if (DeviceType == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
82 DeviceDataLength = DeviceDescriptor->DeviceDescriptor.PciPcieDeviceV2.Length;
83 } else {
84 DeviceDataLength = DeviceDescriptor->DeviceDescriptor.UsbDeviceV2.Length;
85 }
86
87 //
88 // Loop to get platform Redfish host interface protocol type data.
89 //
90 ProtocolRecord = NULL;
91 ProtocolRecords = NULL;
92 NewProtocolRecords = NULL;
93 Type42Record = NULL;
94 ProtocolCount = 0;
95 CurrentProtocolsDataLength = 0;
96 NewProtocolsDataLength = 0;
97 while (TRUE) {
98 Status = RedfishPlatformHostInterfaceProtocolData (&ProtocolRecord, ProtocolCount);
99 if (Status == EFI_NOT_FOUND) {
100 break;
101 }
102
103 if (EFI_ERROR (Status)) {
104 DEBUG ((DEBUG_ERROR, "%a: Fail to get Redfish host interafce protocol type data.", __func__));
105 if (ProtocolRecords != NULL) {
106 FreePool (ProtocolRecords);
107 }
108
109 if (ProtocolRecord != NULL) {
110 FreePool (ProtocolRecord);
111 }
112
113 return Status;
114 }
115
116 ProtocolDataSize = sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - sizeof (ProtocolRecord->ProtocolTypeData) + ProtocolRecord->ProtocolTypeDataLen;
117 NewProtocolsDataLength += ProtocolDataSize;
118 if (ProtocolRecords == NULL) {
119 ProtocolRecords = AllocateZeroPool (NewProtocolsDataLength);
120 if (ProtocolRecords == NULL) {
121 FreePool (ProtocolRecord);
122 return EFI_OUT_OF_RESOURCES;
123 }
124
125 CopyMem ((VOID *)ProtocolRecords, (VOID *)ProtocolRecord, ProtocolDataSize);
126 NewProtocolRecords = ProtocolRecords;
127 } else {
128 NewProtocolRecords = ReallocatePool (CurrentProtocolsDataLength, NewProtocolsDataLength, (VOID *)ProtocolRecords);
129 if (NewProtocolRecords == NULL) {
130 DEBUG ((DEBUG_ERROR, "%a: Fail to allocate memory for Redfish host interface protocol data.", __func__));
131 FreePool (ProtocolRecords);
132 FreePool (ProtocolRecord);
133 return EFI_OUT_OF_RESOURCES;
134 }
135
136 CopyMem (
137 (VOID *)((UINT8 *)NewProtocolRecords + CurrentProtocolsDataLength),
138 (VOID *)ProtocolRecord,
139 ProtocolDataSize
140 );
141 }
142
143 FreePool (ProtocolRecord);
144 CurrentProtocolsDataLength = NewProtocolsDataLength;
145 ProtocolCount++;
146 }
147
148 if (ProtocolCount == 0) {
149 goto ON_EXIT;
150 }
151
152 //
153 // Construct SMBIOS Type 42h for Redfish host inteface.
154 //
155 // SMBIOS type 42 Record for Redfish Interface
156 // 00h Type BYTE 42 Management Controller Host Interface structure indicator
157 // 01h Length BYTE Varies Length of the structure, a minimum of 09h
158 // 02h Handle WORD Varies
159 // 04h Interface Type BYTE Varies Management Controller Interface Type.
160 // 05h Interface Specific Data Length (n)
161 // 06h Interface Specific data
162 // 06h+n number of protocols defined for the host interface (typically 1)
163 // 07h+n Include a Protocol Record for each protocol supported.
164 //
165 Type42Record = (SMBIOS_TABLE_TYPE42 *)AllocateZeroPool (
166 sizeof (SMBIOS_TABLE_TYPE42) - 4
167 + DeviceDataLength
168 + 1
169 + CurrentProtocolsDataLength
170 + 2
171 );
172 if (Type42Record == NULL) {
173 Status = EFI_OUT_OF_RESOURCES;
174 goto ON_EXIT;
175 }
176
177 Type42Record->Hdr.Type = EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE;
178 Type42Record->Hdr.Length = sizeof (SMBIOS_TABLE_TYPE42) - 4
179 + DeviceDataLength
180 + 1
181 + CurrentProtocolsDataLength;
182 Type42Record->Hdr.Handle = 0;
183 Type42Record->InterfaceType = MCHostInterfaceTypeNetworkHostInterface; // Network Host Interface
184
185 //
186 // Fill in InterfaceTypeSpecificDataLength field
187 //
188 Type42Record->InterfaceTypeSpecificDataLength = DeviceDataLength;
189
190 //
191 // Fill in InterfaceTypeSpecificData field
192 //
193 CopyMem (Type42Record->InterfaceTypeSpecificData, DeviceDescriptor, DeviceDataLength);
194 FreePool (DeviceDescriptor);
195 DeviceDescriptor = NULL;
196
197 //
198 // Fill in InterfaceTypeSpecificData Protocol Count field
199 //
200 *(Type42Record->InterfaceTypeSpecificData + DeviceDataLength) = ProtocolCount;
201
202 //
203 // Fill in Redfish Protocol Data
204 //
205 CopyMem (
206 Type42Record->InterfaceTypeSpecificData + DeviceDataLength + 1,
207 NewProtocolRecords,
208 CurrentProtocolsDataLength
209 );
210
211 //
212 // 5. Add Redfish interface data record to SMBIOS table 42
213 //
214 Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&Smbios);
215 if (EFI_ERROR (Status)) {
216 goto ON_EXIT;
217 }
218
219 MemArrayMappedAddrSmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
220 Status = Smbios->Add (
221 Smbios,
222 NULL,
223 &MemArrayMappedAddrSmbiosHandle,
224 (EFI_SMBIOS_TABLE_HEADER *)Type42Record
225 );
226 DEBUG ((DEBUG_MANAGEABILITY, "RedfishPlatformDxe: Smbios->Add() - %r\n", Status));
227 if (EFI_ERROR (Status)) {
228 goto ON_EXIT;
229 }
230
231 //
232 // Install Redfish Host Interface ready protocol.
233 //
234 Status = gBS->InstallProtocolInterface (
235 &Handle,
236 &gEdkIIRedfishHostInterfaceReadyProtocolGuid,
238 (VOID *)NULL
239 );
240 if (EFI_ERROR (Status)) {
241 DEBUG ((DEBUG_ERROR, "Failed to install gEdkIIRedfishHostInterfaceReadyProtocolGuid.\n"));
242 DEBUG ((DEBUG_ERROR, "PlatformConfigHandler driver may not be triggered to acquire Redfish service.\n"));
243 }
244
245 // Set Status to EFI_SUCCESS that indicates SMBIOS 42 record was installed
246 // on the platform sucessfully.
247 Status = EFI_SUCCESS;
248
249ON_EXIT:
250 if (DeviceDescriptor != NULL) {
251 FreePool (DeviceDescriptor);
252 }
253
254 if (NewProtocolRecords != NULL) {
255 FreePool (NewProtocolRecords);
256 }
257
258 if (Type42Record != NULL) {
259 FreePool (Type42Record);
260 }
261
262 return Status;
263}
264
273VOID
274EFIAPI
276 IN EFI_EVENT Event,
277 IN VOID *Context
278 )
279{
280 DEBUG ((DEBUG_MANAGEABILITY, "%a: Platform Redfish Host Interface informtion is ready\n", __func__));
281
283
284 //
285 // Close event so we don't create multiple type 42 records
286 //
287 gBS->CloseEvent (Event);
288 mPlatformHostInterfaceReadylEvent = NULL;
289
290 return;
291}
292
303EFIAPI
305 IN EFI_HANDLE ImageHandle,
306 IN EFI_SYSTEM_TABLE *SystemTable
307 )
308{
309 EFI_STATUS Status;
310 EFI_GUID *ReadyGuid;
311
312 DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n.", __func__));
313
314 //
315 // Check if the Redfish Host Interface depends on
316 // the specific protocol installation.
317 //
318 Status = RedfishPlatformHostInterfaceNotification (&ReadyGuid);
319 if (Status == EFI_SUCCESS) {
320 DEBUG ((DEBUG_MANAGEABILITY, " Create protocol install notification to know the installation of platform Redfish host interface readiness\n"));
321 DEBUG ((DEBUG_MANAGEABILITY, " Protocol GUID: %g\n", ReadyGuid));
322 //
323 // Register event for ReadyGuid protocol installed by
324 // platform Redfish host interface library.
325 //
326 Status = gBS->CreateEvent (
327 EVT_NOTIFY_SIGNAL,
328 TPL_CALLBACK,
330 NULL,
331 &mPlatformHostInterfaceReadylEvent
332 );
333 if (EFI_ERROR (Status)) {
334 DEBUG ((DEBUG_ERROR, " Fail to create event for the installation of platform Redfish host interface readiness.\n"));
335 return Status;
336 }
337
338 Status = gBS->RegisterProtocolNotify (
339 ReadyGuid,
340 mPlatformHostInterfaceReadylEvent,
341 &mPlatformHostInterfaceReadyRegistration
342 );
343 if (EFI_ERROR (Status)) {
344 DEBUG ((DEBUG_ERROR, " Fail to register event for the installation of platform Redfish host interface readiness.\n"));
345 return Status;
346 }
347
348 return EFI_SUCCESS;
349 }
350
351 if ((Status == EFI_UNSUPPORTED) || (Status == EFI_ALREADY_STARTED)) {
352 Status = RedfishCreateSmbiosTable42 ();
353 }
354
355 // Return other erros.
356 return Status;
357}
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ReallocatePool(IN UINTN OldSize, IN UINTN NewSize, IN VOID *OldBuffer OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define SMBIOS_HANDLE_PI_RESERVED
Definition: SmBios.h:29
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS RedfishCreateSmbiosTable42(VOID)
EFI_STATUS EFIAPI RedfishHostInterfaceDxeEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID EFIAPI PlatformHostInterfaceInformationReady(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS RedfishPlatformHostInterfaceNotification(OUT EFI_GUID **InformationReadinessGuid)
EFI_STATUS RedfishPlatformHostInterfaceDeviceDescriptor(OUT UINT8 *DeviceType, OUT REDFISH_INTERFACE_DATA **DeviceDescriptor)
EFI_STATUS RedfishPlatformHostInterfaceProtocolData(OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord, IN UINT8 IndexOfProtocolData)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
Definition: Base.h:213
UINT8 Length
Length of the structure, including Device Type and Length fields.
Device descriptor data formated based on Device Type.
DEVICE_DESCRITOR DeviceDescriptor
The Device descriptor.
UINT8 InterfaceType
The enumeration value from MC_HOST_INTERFACE_TYPE.
Definition: SmBios.h:2753
UINT8 InterfaceTypeSpecificData[4]
This field has a minimum of four bytes.
Definition: SmBios.h:2755
PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 PciPcieDeviceV2
Device type PCI/PCIe V2 device discriptor.
USB_INTERFACE_DEVICE_DESCRIPTOR_V2 UsbDeviceV2
Device type USB V2 device discriptor.