/** @file The common code of EDKII Redfish Configuration Handler driver. (C) Copyright 2021 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "RedfishConfigHandlerCommon.h" REDFISH_CONFIG_DRIVER_DATA gRedfishConfigData; // Only one Redfish service supproted // 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 faied 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 faied 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_INFO, "%a: No Redfish Credential Protocol is installed on system.", __FUNCTION__)); 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.", __FUNCTION__)); 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.", __FUNCTION__)); 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)); } // // 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); } }