blob: c3a7efd796a58b7e70ae686e97acb4a07a842419 [file] [log] [blame]
/** @file
The common code of EDKII Redfish Configuration Handler driver.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
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);
}
}