| /** @file | |
| The common code of EDKII Redfish Configuration Handler driver. | |
| (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> | |
| Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "RedfishConfigHandlerCommon.h" | |
| REDFISH_CONFIG_DRIVER_DATA gRedfishConfigData; // Only one Redfish service supported | |
| // on platform for the BIOS | |
| // Redfish configuration. | |
| EFI_EVENT gEndOfDxeEvent = NULL; | |
| EFI_EVENT gExitBootServiceEvent = NULL; | |
| EDKII_REDFISH_CREDENTIAL_PROTOCOL *gCredential = NULL; | |
| /** | |
| Callback function executed when the EndOfDxe event group is signaled. | |
| @param[in] Event Event whose notification function is being invoked. | |
| @param[out] Context Pointer to the Context buffer. | |
| **/ | |
| VOID | |
| EFIAPI | |
| RedfishConfigOnEndOfDxe ( | |
| IN EFI_EVENT Event, | |
| OUT VOID *Context | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = gCredential->StopService (gCredential, ServiceStopTypeSecureBootDisabled); | |
| if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) { | |
| DEBUG ((DEBUG_ERROR, "Redfish credential protocol failed to stop service on EndOfDxe: %r", Status)); | |
| } | |
| // | |
| // Close event, so it will not be invoked again. | |
| // | |
| gBS->CloseEvent (gEndOfDxeEvent); | |
| gEndOfDxeEvent = NULL; | |
| } | |
| /** | |
| Callback function executed when the ExitBootService event group is signaled. | |
| @param[in] Event Event whose notification function is being invoked. | |
| @param[out] Context Pointer to the Context buffer | |
| **/ | |
| VOID | |
| EFIAPI | |
| RedfishConfigOnExitBootService ( | |
| IN EFI_EVENT Event, | |
| OUT VOID *Context | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = gCredential->StopService (gCredential, ServiceStopTypeExitBootService); | |
| if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) { | |
| DEBUG ((DEBUG_ERROR, "Redfish credential protocol failed to stop service on ExitBootService: %r", Status)); | |
| } | |
| } | |
| /** | |
| Unloads an image. | |
| @param[in] ImageHandle Handle that identifies the image to be unloaded. | |
| @retval EFI_SUCCESS The image has been unloaded. | |
| **/ | |
| EFI_STATUS | |
| RedfishConfigDriverCommonUnload ( | |
| IN EFI_HANDLE ImageHandle | |
| ) | |
| { | |
| if (gEndOfDxeEvent != NULL) { | |
| gBS->CloseEvent (gEndOfDxeEvent); | |
| gEndOfDxeEvent = NULL; | |
| } | |
| if (gExitBootServiceEvent != NULL) { | |
| gBS->CloseEvent (gExitBootServiceEvent); | |
| gExitBootServiceEvent = NULL; | |
| } | |
| if (gRedfishConfigData.Event != NULL) { | |
| gBS->CloseEvent (gRedfishConfigData.Event); | |
| gRedfishConfigData.Event = NULL; | |
| } | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| This is the common code for Redfish configuration UEFI and DXE driver | |
| initialization. | |
| @param[in] ImageHandle The firmware allocated handle for the UEFI image. | |
| @param[in] SystemTable A pointer to the EFI System Table. | |
| @retval EFI_SUCCESS The operation completed successfully. | |
| @retval Others An unexpected error occurred. | |
| **/ | |
| EFI_STATUS | |
| RedfishConfigCommonInit ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| // | |
| // Locate Redfish Credential Protocol to get credential for | |
| // accessing to Redfish service. | |
| // | |
| Status = gBS->LocateProtocol (&gEdkIIRedfishCredentialProtocolGuid, NULL, (VOID **)&gCredential); | |
| if (EFI_ERROR (Status)) { | |
| DEBUG ((DEBUG_ERROR, "%a: No Redfish Credential Protocol is installed on system.", __func__)); | |
| return Status; | |
| } | |
| // | |
| // Create EndOfDxe Event. | |
| // | |
| Status = gBS->CreateEventEx ( | |
| EVT_NOTIFY_SIGNAL, | |
| TPL_CALLBACK, | |
| RedfishConfigOnEndOfDxe, | |
| NULL, | |
| &gEfiEndOfDxeEventGroupGuid, | |
| &gEndOfDxeEvent | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| DEBUG ((DEBUG_ERROR, "%a: Fail to register End Of DXE event.", __func__)); | |
| return Status; | |
| } | |
| // | |
| // Create Exit Boot Service event. | |
| // | |
| Status = gBS->CreateEventEx ( | |
| EVT_NOTIFY_SIGNAL, | |
| TPL_CALLBACK, | |
| RedfishConfigOnExitBootService, | |
| NULL, | |
| &gEfiEventExitBootServicesGuid, | |
| &gExitBootServiceEvent | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| gBS->CloseEvent (gEndOfDxeEvent); | |
| gEndOfDxeEvent = NULL; | |
| DEBUG ((DEBUG_ERROR, "%a: Fail to register Exit Boot Service event.", __func__)); | |
| return Status; | |
| } | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| This is the common code to stop EDK2 Redfish feature driver. | |
| @retval EFI_SUCCESS All EDK2 Redfish feature drivers are | |
| stopped. | |
| @retval Others An unexpected error occurred. | |
| **/ | |
| EFI_STATUS | |
| RedfishConfigCommonStop ( | |
| VOID | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_HANDLE *HandleBuffer; | |
| UINTN NumberOfHandles; | |
| UINTN Index; | |
| EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *ConfigHandler; | |
| Status = gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| &gEdkIIRedfishConfigHandlerProtocolGuid, | |
| NULL, | |
| &NumberOfHandles, | |
| &HandleBuffer | |
| ); | |
| if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) { | |
| return Status; | |
| } | |
| Status = EFI_SUCCESS; | |
| for (Index = 0; Index < NumberOfHandles; Index++) { | |
| Status = gBS->HandleProtocol ( | |
| HandleBuffer[Index], | |
| &gEdkIIRedfishConfigHandlerProtocolGuid, | |
| (VOID **)&ConfigHandler | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = ConfigHandler->Stop (ConfigHandler); | |
| if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) { | |
| DEBUG ((DEBUG_ERROR, "ERROR: Failed to stop Redfish config handler %p.\n", ConfigHandler)); | |
| break; | |
| } | |
| } | |
| return Status; | |
| } | |
| /** | |
| Callback function executed when a Redfish Config Handler Protocol is installed | |
| by EDK2 Redfish Feature Drivers. | |
| **/ | |
| VOID | |
| RedfishConfigHandlerInitialization ( | |
| VOID | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_HANDLE *HandleBuffer; | |
| UINTN NumberOfHandles; | |
| EDKII_REDFISH_CONFIG_HANDLER_PROTOCOL *ConfigHandler; | |
| UINTN Index; | |
| UINT32 *Id; | |
| Status = gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| &gEdkIIRedfishConfigHandlerProtocolGuid, | |
| NULL, | |
| &NumberOfHandles, | |
| &HandleBuffer | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return; | |
| } | |
| for (Index = 0; Index < NumberOfHandles; Index++) { | |
| Status = gBS->HandleProtocol ( | |
| HandleBuffer[Index], | |
| &gEfiCallerIdGuid, | |
| (VOID **)&Id | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| continue; | |
| } | |
| Status = gBS->HandleProtocol ( | |
| HandleBuffer[Index], | |
| &gEdkIIRedfishConfigHandlerProtocolGuid, | |
| (VOID **)&ConfigHandler | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = ConfigHandler->Init (ConfigHandler, &gRedfishConfigData.RedfishServiceInfo); | |
| if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) { | |
| DEBUG ((DEBUG_ERROR, "ERROR: Failed to init Redfish config handler %p.\n", ConfigHandler)); | |
| continue; | |
| } | |
| // | |
| // Install caller ID to indicate Redfish Configure Handler is initialized. | |
| // | |
| Status = gBS->InstallProtocolInterface ( | |
| &HandleBuffer[Index], | |
| &gEfiCallerIdGuid, | |
| EFI_NATIVE_INTERFACE, | |
| (VOID *)&gRedfishConfigData.CallerId | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| } | |
| } |