[edk2-devel] [PATCH] RedfishPkg/RedfishConfigHandler: EDKII RedfishConfigHandler Protocol

Nickle Wang nickle.wang at hpe.com
Mon Apr 12 06:26:44 UTC 2021


Reviewed-by: Nickle Wang <nickle.wang at hpe.com>

Got it. Thanks Abner.

Nickle

-----Original Message-----
From: Chang, Abner (HPS SW/FW Technologist) <abner.chang at hpe.com> 
Sent: Monday, April 12, 2021 12:20 PM
To: Wang, Nickle (HPS SW) <nickle.wang at hpe.com>; devel at edk2.groups.io
Subject: RE: [edk2-devel] [PATCH] RedfishPkg/RedfishConfigHandler: EDKII RedfishConfigHandler Protocol

Ah, yes. I will revise the copyrights in Redfish.fdf.inc and RedfishComponents.dsc.inc when merge it.
Thanks for catching this.

Abner

> -----Original Message-----
> From: Wang, Nickle (HPS SW)
> Sent: Monday, April 12, 2021 11:53 AM
> To: devel at edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang at hpe.com>
> Subject: RE: [edk2-devel] [PATCH] RedfishPkg/RedfishConfigHandler: EDKII
> RedfishConfigHandler Protocol
> 
> Looks good to me. But for the copyright, I think it would be "2020-2021", right?
> For example:
> 
> -# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> 
> Thanks,
> Nickle
> 
> -----Original Message-----
> From: devel at edk2.groups.io <devel at edk2.groups.io> On Behalf Of Abner
> Chang
> Sent: Friday, March 26, 2021 1:55 PM
> To: devel at edk2.groups.io
> Cc: Wang, Nickle (HPS SW) <nickle.wang at hpe.com>
> Subject: [edk2-devel] [PATCH] RedfishPkg/RedfishConfigHandler: EDKII
> RedfishConfigHandler Protocol
> 
> The driver is used to manage EDK2 Redfish Configuration Handler
> Protocol installed by EDK2 Redfish feature drivers.
> This is the EDK2 Redfish client driver written based on the EDK2
> Redfish foundation to initialize EDK2 Redfish feature drivers.
> 
> EDK2 Redfish feature drivers are used to provision/consume/update
> the firmware owns Redfish properties during system power on
> initialization.
> 
> RedfishConfigHandlerCommon.c has the common code for the driver
> instances used in different EDK2 boot phases or used by different
> driver models in the future contribution.
> 
> Signed-off-by: Jiaxin Wu <jiaxin.wu at intel.com>
> Signed-off-by: Siyuan Fu <siyuan.fu at intel.com>
> Signed-off-by: Fan Wang <fan.wang at intel.com>
> Signed-off-by: Abner Chang <abner.chang at hpe.com>
> 
> Cc: Nickle Wang <nickle.wang at hpe.com>
> ---
>  RedfishPkg/RedfishComponents.dsc.inc          |   3 +-
>  RedfishPkg/Redfish.fdf.inc                    |   3 +-
>  .../RedfishConfigHandlerDriver.inf            |  60 ++
>  .../RedfishConfigHandlerCommon.h              | 101 +++
>  .../RedfishConfigHandlerDriver.h              | 159 +++++
>  .../RedfishConfigHandlerCommon.c              | 265 ++++++++
>  .../RedfishConfigHandlerDriver.c              | 587 ++++++++++++++++++
>  7 files changed, 1176 insertions(+), 2 deletions(-)
>  create mode 100644
> RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf
>  create mode 100644
> RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.h
>  create mode 100644
> RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.h
>  create mode 100644
> RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.c
>  create mode 100644
> RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
> 
> diff --git a/RedfishPkg/RedfishComponents.dsc.inc
> b/RedfishPkg/RedfishComponents.dsc.inc
> index 08f1d3bc32..d0116f065c 100644
> --- a/RedfishPkg/RedfishComponents.dsc.inc
> +++ b/RedfishPkg/RedfishComponents.dsc.inc
> @@ -6,7 +6,7 @@
>  # of EDKII Redfish drivers according to the value of flags described in
>  # "RedfishDefines.dsc.inc".
>  #
> -# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
>  #
>  #    SPDX-License-Identifier: BSD-2-Clause-Patent
>  #
> @@ -17,4 +17,5 @@
>    RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf
>    RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf
>    RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf
> +  RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf
>  !endif
> diff --git a/RedfishPkg/Redfish.fdf.inc b/RedfishPkg/Redfish.fdf.inc
> index a64fd119a9..9673246b3f 100644
> --- a/RedfishPkg/Redfish.fdf.inc
> +++ b/RedfishPkg/Redfish.fdf.inc
> @@ -5,7 +5,7 @@
>  # by using "!include RedfishPkg/RedfisLibs.fdf.inc" to specify the module
> instances
>  # to be built in the firmware volume.
>  #
> -# (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
> +# (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
>  #
>  #    SPDX-License-Identifier: BSD-2-Clause-Patent
>  #
> @@ -15,4 +15,5 @@
>    INF RedfishPkg/RedfishHostInterfaceDxe/RedfishHostInterfaceDxe.inf
>    INF RedfishPkg/RedfishRestExDxe/RedfishRestExDxe.inf
>    INF RedfishPkg/RedfishCredentialDxe/RedfishCredentialDxe.inf
> +  INF RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf
>  !endif
> diff --git a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf
> b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf
> new file mode 100644
> index 0000000000..def91c7531
> --- /dev/null
> +++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.inf
> @@ -0,0 +1,60 @@
> +## @file
> +#  INF file for the UEFI driver model Redfish Configuration Handler
> +#  Driver.
> +#
> +#  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION               = 0x0001000b
> +  BASE_NAME                 = RedfishConfigHandlerDriver
> +  FILE_GUID                 = 6e881000-5749-11e8-9bf0-8cdcd426c973
> +  MODULE_TYPE               = UEFI_DRIVER
> +  VERSION_STRING            = 1.0
> +  ENTRY_POINT               = RedfishConfigHandlerDriverEntryPoint
> +  UNLOAD_IMAGE              = RedfishConfigHandlerDriverUnload
> +
> +#
> +#  VALID_ARCHITECTURES      = IA32 X64 ARM AARCH64 RISCV64
> +#
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  NetworkPkg/NetworkPkg.dec
> +  RedfishPkg/RedfishPkg.dec
> +
> +[Sources]
> +  RedfishConfigHandlerDriver.h
> +  RedfishConfigHandlerDriver.c
> +  RedfishConfigHandlerCommon.h
> +  RedfishConfigHandlerCommon.c
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  UefiLib
> +  MemoryAllocationLib
> +  NetLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiRedfishDiscoverProtocolGuid         ## CONSUMES
> +  gEfiRestExServiceBindingProtocolGuid
> +  gEfiRestExProtocolGuid                  ## CONSUMES
> +  gEdkIIRedfishCredentialProtocolGuid     ## CONSUMES
> +  gEdkIIRedfishConfigHandlerProtocolGuid  ## CONSUMES
> +
> +[Guids]
> +  gEfiEventExitBootServicesGuid           ## CONSUMES ## Event
> +  gEfiEndOfDxeEventGroupGuid              ## CONSUMES ## Event
> +
> +[Depex]
> +  TRUE
> +
> diff --git
> a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.h
> b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.h
> new file mode 100644
> index 0000000000..5e46c42219
> --- /dev/null
> +++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.h
> @@ -0,0 +1,101 @@
> +/** @file
> +  Common Header file for Redfish Configuration Handler UEFI driver
> +  and DXE driver.
> +
> +  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EFI_REDFISH_CONFIG_HANDLER_COMMON_H_
> +#define EFI_REDFISH_CONFIG_HANDLER_COMMON_H_
> +
> +#include <Uefi.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/NetLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +
> +//
> +// Consumed Protocols
> +//
> +#include <Protocol/EdkIIRedfishCredential.h>
> +#include <Protocol/EdkIIRedfishConfigHandler.h>
> +
> +//
> +// Driver Version
> +//
> +#define REDFISH_CONFIG_VERSION  0x00000001
> +
> +///
> +///  Internal structure used by Redfish Config DXE driver.
> +///
> +typedef struct {
> +  UINT32        CallerId;  ///< Caller ID used to indicate Redfish Config Handler
> +                           ///< has been initiated
> +  EFI_HANDLE    Image;     ///< Image handle of Redfish Config Driver
> +  EFI_EVENT     Event;     ///< Event for the notification of
> EFI_REDFISH_CONFIG_HANDLER_PROTOCOL
> +  REDFISH_CONFIG_SERVICE_INFORMATION RedfishServiceInfo; ///
> Redfish Service information discovered
> +} REDFISH_CONFIG_DRIVER_DATA;
> +
> +/**
> +  Common code of unloading image for both UEFI/DXE Redfish
> Configuration drivers.
> +
> +  @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
> +  );
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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
> +);
> +
> +/**
> +  Callback function executed when a Redfish Config Handler Protocol is
> installed
> +  by EDK2 Redfish Feature Drivers.
> +
> +**/
> +VOID
> +RedfishConfigHandlerInitialization (
> +  VOID
> +  );
> +
> +#endif
> diff --git a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.h
> b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.h
> new file mode 100644
> index 0000000000..58202c41e2
> --- /dev/null
> +++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.h
> @@ -0,0 +1,159 @@
> +/** @file
> +  Header file of Redfish Configuration Handler UEFI driver.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EFI_REDFISH_CONFIG_HANDLER_DRIVER_H_
> +#define EFI_REDFISH_CONFIG_HANDLER_DRIVER_H_
> +
> +#include "RedfishConfigHandlerCommon.h"
> +
> +//
> +// UEFI Driver Model Protocols
> +//
> +
> +#include <Protocol/DriverBinding.h>
> +#include <Protocol/RedfishDiscover.h>
> +#include <Protocol/RestEx.h>
> +
> +//
> +// Protocol instances
> +//
> +extern EFI_DRIVER_BINDING_PROTOCOL  gRedfishConfigDriverBinding;
> +
> +extern REDFISH_CONFIG_DRIVER_DATA        gRedfishConfigData;
> +extern EDKII_REDFISH_CREDENTIAL_PROTOCOL *gCredential;
> +extern EFI_EVENT                         gEndOfDxeEvent;
> +extern EFI_EVENT                         gExitBootServiceEvent;
> +
> +/**
> +  Tests to see if this driver supports a given controller. If a child device is
> provided,
> +  it further tests to see if this driver supports creating a handle for the
> specified child device.
> +
> +  This function checks to see if the driver specified by This supports the
> device specified by
> +  ControllerHandle. Drivers will typically use the device path attached to
> +  ControllerHandle and/or the services from the bus I/O abstraction
> attached to
> +  ControllerHandle to determine if the driver supports ControllerHandle.
> This function
> +  may be called many times during platform initialization. In order to reduce
> boot times, the tests
> +  performed by this function must be very small, and take as little time as
> possible to execute. This
> +  function must not change the state of any hardware devices, and this
> function must be aware that the
> +  device specified by ControllerHandle may already be managed by the
> same driver or a
> +  different driver. This function must match its calls to AllocatePages() with
> FreePages(),
> +  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
> +  Because ControllerHandle may have been previously started by the same
> driver, if a protocol is
> +  already in the opened state, then it must not be closed with
> CloseProtocol(). This is required
> +  to guarantee the state of ControllerHandle is not modified by this function.
> +
> +  @param[in]  This                 A pointer to the
> EFI_DRIVER_BINDING_PROTOCOL instance.
> +  @param[in]  ControllerHandle     The handle of the controller to test. This
> handle
> +                                   must support a protocol interface that supplies
> +                                   an I/O abstraction to the driver.
> +  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a
> device path.  This
> +                                   parameter is ignored by device drivers, and is optional for
> bus
> +                                   drivers. For bus drivers, if this parameter is not NULL, then
> +                                   the bus driver must determine if the bus controller
> specified
> +                                   by ControllerHandle and the child controller specified
> +                                   by RemainingDevicePath are both supported by this
> +                                   bus driver.
> +
> +  @retval EFI_SUCCESS              The device specified by ControllerHandle and
> +                                   RemainingDevicePath is supported by the driver specified
> by This.
> +  @retval EFI_ALREADY_STARTED      The device specified by
> ControllerHandle and
> +                                   RemainingDevicePath is already being managed by the
> driver
> +                                   specified by This.
> +  @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle
> and
> +                                   RemainingDevicePath is already being managed by a
> different
> +                                   driver or an application that requires exclusive access.
> +                                   Currently not implemented.
> +  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle
> and
> +                                   RemainingDevicePath is not supported by the driver
> specified by This.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishConfigDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   ControllerHandle,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
> +  );
> +
> +/**
> +  Starts a device controller or a bus controller.
> +
> +  The Start() function is designed to be invoked from the EFI boot service
> ConnectController().
> +  As a result, much of the error checking on the parameters to Start() has
> been moved into this
> +  common boot service. It is legal to call Start() from other locations,
> +  but the following calling restrictions must be followed, or the system
> behavior will not be deterministic.
> +  1. ControllerHandle must be a valid EFI_HANDLE.
> +  2. If RemainingDevicePath is not NULL, then it must be a pointer to a
> naturally aligned
> +     EFI_DEVICE_PATH_PROTOCOL.
> +  3. Prior to calling Start(), the Supported() function for the driver specified
> by This must
> +     have been called with the same calling parameters, and Supported()
> must have returned EFI_SUCCESS.
> +
> +  @param[in]  This                 A pointer to the
> EFI_DRIVER_BINDING_PROTOCOL instance.
> +  @param[in]  ControllerHandle     The handle of the controller to start. This
> handle
> +                                   must support a protocol interface that supplies
> +                                   an I/O abstraction to the driver.
> +  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a
> device path.  This
> +                                   parameter is ignored by device drivers, and is optional for
> bus
> +                                   drivers. For a bus driver, if this parameter is NULL, then
> handles
> +                                   for all the children of Controller are created by this driver.
> +                                   If this parameter is not NULL and the first Device Path
> Node is
> +                                   not the End of Device Path Node, then only the handle for
> the
> +                                   child device specified by the first Device Path Node of
> +                                   RemainingDevicePath is created by this driver.
> +                                   If the first Device Path Node of RemainingDevicePath is
> +                                   the End of Device Path Node, no child handle is created by
> this
> +                                   driver.
> +
> +  @retval EFI_SUCCESS              The driver is started.
> +  @retval EFI_ALREADY_STARTED      The driver was already started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishConfigDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   ControllerHandle,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
> +  );
> +
> +/**
> +  Stops a device controller or a bus controller.
> +
> +  The Stop() function is designed to be invoked from the EFI boot service
> DisconnectController().
> +  As a result, much of the error checking on the parameters to Stop() has
> been moved
> +  into this common boot service. It is legal to call Stop() from other locations,
> +  but the following calling restrictions must be followed, or the system
> behavior will not be deterministic.
> +  1. ControllerHandle must be a valid EFI_HANDLE that was used on a
> previous call to this
> +     same driver's Start() function.
> +  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a
> valid
> +     EFI_HANDLE. In addition, all of these handles must have been created in
> this driver's
> +     Start() function, and the Start() function must have called OpenProtocol()
> on
> +     ControllerHandle with an Attribute of
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
> +
> +  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL
> instance.
> +  @param[in]  ControllerHandle  A handle to the device being stopped. The
> handle must
> +                                support a bus specific I/O protocol for the driver
> +                                to use to stop the device.
> +  @param[in]  NumberOfChildren  The number of child device handles in
> ChildHandleBuffer.
> +  @param[in]  ChildHandleBuffer An array of child handles to be freed. May
> be NULL
> +                                if NumberOfChildren is 0.
> +
> +  @retval EFI_SUCCESS           The device was stopped.
> +  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a
> device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishConfigDriverBindingStop (
> +  IN  EFI_DRIVER_BINDING_PROTOCOL *This,
> +  IN  EFI_HANDLE                  ControllerHandle,
> +  IN  UINTN                       NumberOfChildren,
> +  IN  EFI_HANDLE                  *ChildHandleBuffer OPTIONAL
> +  );
> +#endif
> diff --git
> a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.c
> b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.c
> new file mode 100644
> index 0000000000..ff465d9ff3
> --- /dev/null
> +++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerCommon.c
> @@ -0,0 +1,265 @@
> +/** @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);
> +  }
> +}
> diff --git a/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
> b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
> new file mode 100644
> index 0000000000..51378dff4f
> --- /dev/null
> +++ b/RedfishPkg/RedfishConfigHandler/RedfishConfigHandlerDriver.c
> @@ -0,0 +1,587 @@
> +/** @file
> +  The UEFI driver model driver which is responsible for locating the
> +  Redfish service through Redfish host interface and executing EDKII
> +  Redfish feature drivers.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RedfishConfigHandlerDriver.h"
> +
> +EFI_EVENT  gEfiRedfishDiscoverProtocolEvent = NULL;
> +
> +//
> +// Variables for using RFI Redfish Discover Protocol
> +//
> +VOID                             *gEfiRedfishDiscoverRegistration;
> +EFI_HANDLE                       gEfiRedfishDiscoverControllerHandle = NULL;
> +EFI_REDFISH_DISCOVER_PROTOCOL    *gEfiRedfishDiscoverProtocol = NULL;
> +BOOLEAN                          gRedfishDiscoverActivated = FALSE;
> +BOOLEAN                          gRedfishServiceDiscovered = FALSE;
> +//
> +// Network interfaces discovered by EFI Redfish Discover Protocol.
> +//
> +UINTN                                   gNumberOfNetworkInterfaces;
> +EFI_REDFISH_DISCOVER_NETWORK_INTERFACE
> *gNetworkInterfaceInstances = NULL;
> +EFI_REDFISH_DISCOVERED_TOKEN            *gRedfishDiscoveredToken = NULL;
> +
> +///
> +/// Driver Binding Protocol instance
> +///
> +EFI_DRIVER_BINDING_PROTOCOL gRedfishConfigDriverBinding = {
> +  RedfishConfigDriverBindingSupported,
> +  RedfishConfigDriverBindingStart,
> +  RedfishConfigDriverBindingStop,
> +  REDFISH_CONFIG_VERSION,
> +  NULL,
> +  NULL
> +};
> +
> +/**
> +  Stop acquiring Redfish service.
> +
> +**/
> +VOID
> +RedfishConfigStopRedfishDiscovery (
> +  VOID
> +)
> +{
> +  if (gRedfishDiscoverActivated) {
> +    //
> +    // No more EFI Discover Protocol.
> +    //
> +    if (gEfiRedfishDiscoverProtocolEvent != NULL) {
> +      gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
> +    }
> +    //
> +    // Stop Redfish service discovery.
> +    //
> +    gEfiRedfishDiscoverProtocol->AbortAcquireRedfishService (
> +                                   gEfiRedfishDiscoverProtocol,
> +                                   gNetworkInterfaceInstances
> +                                   );
> +    gEfiRedfishDiscoverControllerHandle = NULL;
> +    gEfiRedfishDiscoverProtocol = NULL;
> +    gRedfishDiscoverActivated = FALSE;
> +    gRedfishServiceDiscovered = FALSE;
> +  }
> +}
> +
> +/**
> +  Callback function executed when a Redfish Config Handler Protocol is
> installed.
> +
> +  @param[in]  Event    Event whose notification function is being invoked.
> +  @param[in]  Context  Pointer to the REDFISH_CONFIG_DRIVER_DATA
> buffer.
> +
> +**/
> +VOID
> +EFIAPI
> +RedfishConfigHandlerInstalledCallback (
> +  IN EFI_EVENT  Event,
> +  IN VOID       *Context
> +  )
> +{
> +  if (!gRedfishDiscoverActivated) {
> +    //
> +    // No Redfish service is discovered yet.
> +    //
> +    return;
> +  }
> +
> +  RedfishConfigHandlerInitialization ();
> +}
> +
> +/**
> +  Tests to see if this driver supports a given controller. If a child device is
> provided,
> +  it further tests to see if this driver supports creating a handle for the
> specified child device.
> +
> +  This function checks to see if the driver specified by This supports the
> device specified by
> +  ControllerHandle. Drivers will typically use the device path attached to
> +  ControllerHandle and/or the services from the bus I/O abstraction
> attached to
> +  ControllerHandle to determine if the driver supports ControllerHandle.
> This function
> +  may be called many times during platform initialization. In order to reduce
> boot times, the tests
> +  performed by this function must be very small, and take as little time as
> possible to execute. This
> +  function must not change the state of any hardware devices, and this
> function must be aware that the
> +  device specified by ControllerHandle may already be managed by the
> same driver or a
> +  different driver. This function must match its calls to AllocatePages() with
> FreePages(),
> +  AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
> +  Because ControllerHandle may have been previously started by the same
> driver, if a protocol is
> +  already in the opened state, then it must not be closed with
> CloseProtocol(). This is required
> +  to guarantee the state of ControllerHandle is not modified by this function.
> +
> +  @param[in]  This                 A pointer to the
> EFI_DRIVER_BINDING_PROTOCOL instance.
> +  @param[in]  ControllerHandle     The handle of the controller to test. This
> handle
> +                                   must support a protocol interface that supplies
> +                                   an I/O abstraction to the driver.
> +  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a
> device path.  This
> +                                   parameter is ignored by device drivers, and is optional for
> bus
> +                                   drivers. For bus drivers, if this parameter is not NULL, then
> +                                   the bus driver must determine if the bus controller
> specified
> +                                   by ControllerHandle and the child controller specified
> +                                   by RemainingDevicePath are both supported by this
> +                                   bus driver.
> +
> +  @retval EFI_SUCCESS              The device specified by ControllerHandle and
> +                                   RemainingDevicePath is supported by the driver specified
> by This.
> +  @retval EFI_UNSUPPORTED          The device specified by ControllerHandle
> and
> +                                   RemainingDevicePath is not supported by the driver
> specified by This.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishConfigDriverBindingSupported (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   ControllerHandle,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
> +  )
> +{
> +  EFI_REST_EX_PROTOCOL             *RestEx;
> +  EFI_STATUS                       Status;
> +  EFI_HANDLE                       ChildHandle;
> +
> +  ChildHandle = NULL;
> +
> +  //
> +  // Check if REST EX is ready. This just makes sure
> +  // the network stack is brought up.
> +  //
> +  Status = NetLibCreateServiceChild (
> +             ControllerHandle,
> +             This->ImageHandle,
> +             &gEfiRestExServiceBindingProtocolGuid,
> +             &ChildHandle
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Test if REST EX protocol is ready.
> +  //
> +  Status = gBS->OpenProtocol(
> +                  ChildHandle,
> +                  &gEfiRestExProtocolGuid,
> +                  (VOID**) &RestEx,
> +                  This->DriverBindingHandle,
> +                  ControllerHandle,
> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    Status = EFI_UNSUPPORTED;
> +  }
> +  NetLibDestroyServiceChild (
> +    ControllerHandle,
> +    This->ImageHandle,
> +    &gEfiRestExServiceBindingProtocolGuid,
> +    ChildHandle
> +    );
> +  return Status;
> +}
> +
> +/**
> +  Starts a device controller or a bus controller.
> +
> +  The Start() function is designed to be invoked from the EFI boot service
> ConnectController().
> +  As a result, much of the error checking on the parameters to Start() has
> been moved into this
> +  common boot service. It is legal to call Start() from other locations,
> +  but the following calling restrictions must be followed, or the system
> behavior will not be deterministic.
> +  1. ControllerHandle must be a valid EFI_HANDLE.
> +  2. If RemainingDevicePath is not NULL, then it must be a pointer to a
> naturally aligned
> +     EFI_DEVICE_PATH_PROTOCOL.
> +  3. Prior to calling Start(), the Supported() function for the driver specified
> by This must
> +     have been called with the same calling parameters, and Supported()
> must have returned EFI_SUCCESS.
> +
> +  @param[in]  This                 A pointer to the
> EFI_DRIVER_BINDING_PROTOCOL instance.
> +  @param[in]  ControllerHandle     The handle of the controller to start. This
> handle
> +                                   must support a protocol interface that supplies
> +                                   an I/O abstraction to the driver.
> +  @param[in]  RemainingDevicePath  A pointer to the remaining portion of a
> device path.  This
> +                                   parameter is ignored by device drivers, and is optional for
> bus
> +                                   drivers. For a bus driver, if this parameter is NULL, then
> handles
> +                                   for all the children of Controller are created by this driver.
> +                                   If this parameter is not NULL and the first Device Path
> Node is
> +                                   not the End of Device Path Node, then only the handle for
> the
> +                                   child device specified by the first Device Path Node of
> +                                   RemainingDevicePath is created by this driver.
> +                                   If the first Device Path Node of RemainingDevicePath is
> +                                   the End of Device Path Node, no child handle is created by
> this
> +                                   driver.
> +
> +  @retval EFI_SUCCESS              The driver is started.
> +  @retval EFI_ALREADY_STARTED      The driver was already started.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishConfigDriverBindingStart (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   ControllerHandle,
> +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
> +  )
> +{
> +  VOID *ConfigHandlerRegistration;
> +
> +  if (gRedfishConfigData.Event != NULL) {
> +    return EFI_ALREADY_STARTED;
> +  }
> +
> +  gRedfishConfigData.Event = EfiCreateProtocolNotifyEvent (
> +                                &gEdkIIRedfishConfigHandlerProtocolGuid,
> +                                TPL_CALLBACK,
> +                                RedfishConfigHandlerInstalledCallback,
> +                                (VOID *)&gRedfishConfigData,
> +                                &ConfigHandlerRegistration
> +                                );
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Stops a device controller or a bus controller.
> +
> +  The Stop() function is designed to be invoked from the EFI boot service
> DisconnectController().
> +  As a result, much of the error checking on the parameters to Stop() has
> been moved
> +  into this common boot service. It is legal to call Stop() from other locations,
> +  but the following calling restrictions must be followed, or the system
> behavior will not be deterministic.
> +  1. ControllerHandle must be a valid EFI_HANDLE that was used on a
> previous call to this
> +     same driver's Start() function.
> +  2. The first NumberOfChildren handles of ChildHandleBuffer must all be a
> valid
> +     EFI_HANDLE. In addition, all of these handles must have been created in
> this driver's
> +     Start() function, and the Start() function must have called OpenProtocol()
> on
> +     ControllerHandle with an Attribute of
> EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
> +
> +  @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL
> instance.
> +  @param[in]  ControllerHandle  A handle to the device being stopped. The
> handle must
> +                                support a bus specific I/O protocol for the driver
> +                                to use to stop the device.
> +  @param[in]  NumberOfChildren  The number of child device handles in
> ChildHandleBuffer.
> +  @param[in]  ChildHandleBuffer An array of child handles to be freed. May
> be NULL
> +                                if NumberOfChildren is 0.
> +
> +  @retval EFI_SUCCESS           The device was stopped.
> +  @retval EFI_DEVICE_ERROR      The device could not be stopped due to a
> device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishConfigDriverBindingStop (
> +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> +  IN EFI_HANDLE                   ControllerHandle,
> +  IN UINTN                        NumberOfChildren,
> +  IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  if (ControllerHandle == gEfiRedfishDiscoverControllerHandle) {
> +    RedfishConfigStopRedfishDiscovery ();
> +  }
> +  gBS->CloseProtocol (
> +         ControllerHandle,
> +         &gEfiRedfishDiscoverProtocolGuid,
> +         gRedfishConfigData.Image,
> +         gRedfishConfigData.Image
> +         );
> +
> +  Status = RedfishConfigCommonStop ();
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (gRedfishConfigData.Event != NULL) {
> +    gBS->CloseEvent (gRedfishConfigData.Event);
> +    gRedfishConfigData.Event = NULL;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Callback function when Redfish service is discovered.
> +
> +  @param[in]   Event    Event whose notification function is being invoked.
> +  @param[out]  Context  Pointer to the Context buffer
> +
> +**/
> +VOID
> +EFIAPI
> +RedfishServiceDiscoveredCallback (
> +  IN  EFI_EVENT  Event,
> +  OUT VOID       *Context
> +  )
> +{
> +  EFI_REDFISH_DISCOVERED_TOKEN *RedfishDiscoveredToken;
> +  EFI_REDFISH_DISCOVERED_INSTANCE *RedfishInstance;
> +
> +  if (gRedfishServiceDiscovered) {
> +    //
> +    // Only support one Redfish service on platform.
> +    //
> +    return;
> +  }
> +
> +  RedfishDiscoveredToken = (EFI_REDFISH_DISCOVERED_TOKEN *)Context;
> +  RedfishInstance = RedfishDiscoveredToken-
> >DiscoverList.RedfishInstances;
> +  //
> +  // Only pick up the first found Redfish service.
> +  //
> +  if (RedfishInstance->Status == EFI_SUCCESS) {
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceRestExHandle =
> RedfishInstance->Information.RedfishRestExHandle;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceVersion      =
> RedfishInstance->Information.RedfishVersion;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceLocation     =
> RedfishInstance->Information.Location;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceUuid         =
> RedfishInstance->Information.Uuid;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceOs           =
> RedfishInstance->Information.Os;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceOsVersion    =
> RedfishInstance->Information.OsVersion;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceProduct      =
> RedfishInstance->Information.Product;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceProductVer   =
> RedfishInstance->Information.ProductVer;
> +    gRedfishConfigData.RedfishServiceInfo.RedfishServiceUseHttps     =
> RedfishInstance->Information.UseHttps;
> +    gRedfishServiceDiscovered = TRUE;
> +  }
> +
> +  //
> +  // Invoke RedfishConfigHandlerInstalledCallback to execute
> +  // the initialization of Redfish Configure Handler instance.
> +  //
> +  RedfishConfigHandlerInstalledCallback (gRedfishConfigData.Event,
> &gRedfishConfigData);
> +}
> +
> +/**
> +  Callback function executed when the EFI_REDFISH_DISCOVER_PROTOCOL
> +  protocol interface is installed.
> +
> +  @param[in]   Event    Event whose notification function is being invoked.
> +  @param[out]  Context  Pointer to the Context buffer
> +
> +**/
> +VOID
> +EFIAPI
> +RedfishDiscoverProtocolInstalled (
> +  IN  EFI_EVENT  Event,
> +  OUT VOID       *Context
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINTN BufferSize;
> +  EFI_HANDLE HandleBuffer;
> +  UINTN NetworkInterfaceIndex;
> +  EFI_REDFISH_DISCOVER_NETWORK_INTERFACE *ThisNetworkInterface;
> +  EFI_REDFISH_DISCOVERED_TOKEN           *ThisRedfishDiscoveredToken;
> +
> +  DEBUG((DEBUG_INFO, "%a: New network interface is installed on system
> by EFI Redfish discover driver.\n", __FUNCTION__));
> +
> +  BufferSize = sizeof (EFI_HANDLE);
> +  Status = gBS->LocateHandle (
> +                  ByRegisterNotify,
> +                  NULL,
> +                  gEfiRedfishDiscoverRegistration,
> +                  &BufferSize,
> +                  &HandleBuffer
> +                );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG((DEBUG_ERROR, "%a: Can't locate handle with
> EFI_REDFISH_DISCOVER_PROTOCOL installed.\n", __FUNCTION__));
> +  }
> +  gRedfishDiscoverActivated = TRUE;
> +  if (gEfiRedfishDiscoverProtocol == NULL) {
> +     gEfiRedfishDiscoverControllerHandle = HandleBuffer;
> +    //
> +    // First time to open EFI_REDFISH_DISCOVER_PROTOCOL.
> +    //
> +    Status = gBS->OpenProtocol(
> +                      gEfiRedfishDiscoverControllerHandle,
> +                      &gEfiRedfishDiscoverProtocolGuid,
> +                      (VOID **)&gEfiRedfishDiscoverProtocol,
> +                      gRedfishConfigData.Image,
> +                      gRedfishConfigData.Image,
> +                      EFI_OPEN_PROTOCOL_BY_DRIVER
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      gEfiRedfishDiscoverProtocol = NULL;
> +      gRedfishDiscoverActivated = FALSE;
> +      DEBUG((DEBUG_ERROR, "%a: Can't locate
> EFI_REDFISH_DISCOVER_PROTOCOL.\n", __FUNCTION__));
> +      return;
> +    }
> +  }
> +  //
> +  // Check the new found network interface.
> +  //
> +  if (gNetworkInterfaceInstances != NULL) {
> +    FreePool (gNetworkInterfaceInstances);
> +  }
> +  Status = gEfiRedfishDiscoverProtocol->GetNetworkInterfaceList(
> +                                          gEfiRedfishDiscoverProtocol,
> +                                          gRedfishConfigData.Image,
> +                                          &gNumberOfNetworkInterfaces,
> +                                          &gNetworkInterfaceInstances
> +                                          );
> +  if (EFI_ERROR (Status) || gNumberOfNetworkInterfaces == 0) {
> +    DEBUG((DEBUG_ERROR, "%a: No network interfaces found on the
> handle.\n", __FUNCTION__));
> +    return;
> +  }
> +
> +  gRedfishDiscoveredToken = AllocateZeroPool
> (gNumberOfNetworkInterfaces * sizeof
> (EFI_REDFISH_DISCOVERED_TOKEN));
> +  if (gRedfishDiscoveredToken == NULL) {
> +    DEBUG((DEBUG_ERROR, "%a: Not enough memory for
> EFI_REDFISH_DISCOVERED_TOKEN.\n", __FUNCTION__));
> +    return;
> +  }
> +
> +  ThisNetworkInterface = gNetworkInterfaceInstances;
> +  ThisRedfishDiscoveredToken = gRedfishDiscoveredToken;
> +  //
> +  // Loop to discover Redfish service on each network interface.
> +  //
> +  for (NetworkInterfaceIndex = 0; NetworkInterfaceIndex <
> gNumberOfNetworkInterfaces; NetworkInterfaceIndex ++) {
> +    //
> +    // Initial this Redfish Discovered Token
> +    //
> +    Status = gBS->CreateEvent (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_CALLBACK,
> +                    RedfishServiceDiscoveredCallback,
> +                    (VOID *)ThisRedfishDiscoveredToken,
> +                    &ThisRedfishDiscoveredToken->Event
> +                  );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG((DEBUG_ERROR, "%a: Failed to create event for Redfish
> discovered token.\n", __FUNCTION__));
> +      goto ErrorReturn;
> +    }
> +    ThisRedfishDiscoveredToken->Signature =
> REDFISH_DISCOVER_TOKEN_SIGNATURE;
> +    ThisRedfishDiscoveredToken->DiscoverList.NumberOfServiceFound = 0;
> +    ThisRedfishDiscoveredToken->DiscoverList.RedfishInstances = NULL;
> +    //
> +    // Acquire for Redfish service which is reported by
> +    // Redfish Host Interface.
> +    //
> +    Status = gEfiRedfishDiscoverProtocol->AcquireRedfishService(
> +                                             gEfiRedfishDiscoverProtocol,
> +                                             gRedfishConfigData.Image,
> +                                             ThisNetworkInterface,
> +                                             EFI_REDFISH_DISCOVER_HOST_INTERFACE,
> +                                             ThisRedfishDiscoveredToken
> +                                             );
> +    ThisNetworkInterface ++;
> +    ThisRedfishDiscoveredToken ++;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    DEBUG((DEBUG_ERROR, "%a: Acquire Redfish service fail.\n",
> __FUNCTION__));
> +    goto ErrorReturn;
> +  }
> +  return;
> +
> +ErrorReturn:
> +  if (gRedfishDiscoveredToken != NULL) {
> +    FreePool(gRedfishDiscoveredToken);
> +  }
> +}
> +
> +/**
> +  Unloads an image.
> +
> +  @param[in]  ImageHandle       Handle that identifies the image to be
> unloaded.
> +
> +  @retval EFI_SUCCESS           The image has been unloaded.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishConfigHandlerDriverUnload (
> +  IN EFI_HANDLE  ImageHandle
> +  )
> +{
> +  EFI_REDFISH_DISCOVERED_TOKEN *ThisRedfishDiscoveredToken;
> +  UINTN NumberOfNetworkInterfacesIndex;
> +
> +  RedfishConfigDriverCommonUnload (ImageHandle);
> +
> +  RedfishConfigStopRedfishDiscovery ();
> +  if (gRedfishDiscoveredToken != NULL) {
> +    ThisRedfishDiscoveredToken = gRedfishDiscoveredToken;
> +    for (NumberOfNetworkInterfacesIndex = 0;
> NumberOfNetworkInterfacesIndex < gNumberOfNetworkInterfaces;
> NumberOfNetworkInterfacesIndex ++) {
> +      if (ThisRedfishDiscoveredToken->Event != NULL) {
> +        gBS->CloseEvent (ThisRedfishDiscoveredToken->Event);
> +      }
> +      FreePool (ThisRedfishDiscoveredToken);
> +      ThisRedfishDiscoveredToken ++;
> +    }
> +    gRedfishDiscoveredToken = NULL;
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This is the declaration of an EFI image entry point. This entry point is
> +  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> +  both device drivers and bus drivers.
> +
> +  @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
> +EFIAPI
> +RedfishConfigHandlerDriverEntryPoint (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  ZeroMem ((VOID *)&gRedfishConfigData, sizeof
> (REDFISH_CONFIG_DRIVER_DATA));
> +  gRedfishConfigData.Image = ImageHandle;
> +  //
> +  // Register event for EFI_REDFISH_DISCOVER_PROTOCOL protocol install
> +  // notification.
> +  //
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  RedfishDiscoverProtocolInstalled,
> +                  NULL,
> +                  &gEfiRedfishDiscoverProtocolGuid,
> +                  &gEfiRedfishDiscoverProtocolEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the installation of
> EFI_REDFISH_DISCOVER_PROTOCOL.", __FUNCTION__));
> +    return Status;
> +  }
> +  Status = gBS->RegisterProtocolNotify (
> +                  &gEfiRedfishDiscoverProtocolGuid,
> +                  gEfiRedfishDiscoverProtocolEvent,
> +                  &gEfiRedfishDiscoverRegistration
> +                );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the installation of
> EFI_REDFISH_DISCOVER_PROTOCOL.", __FUNCTION__));
> +    return Status;
> +  }
> +
> +  Status = RedfishConfigCommonInit (ImageHandle, SystemTable);
> +  if (EFI_ERROR (Status)) {
> +    gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
> +    gEfiRedfishDiscoverProtocolEvent = NULL;
> +    return Status;
> +  }
> +
> +  //
> +  // Install UEFI Driver Model protocol(s).
> +  //
> +  Status = EfiLibInstallDriverBinding (
> +             ImageHandle,
> +             SystemTable,
> +             &gRedfishConfigDriverBinding,
> +             ImageHandle
> +             );
> +  if (EFI_ERROR (Status)) {
> +    gBS->CloseEvent (gEndOfDxeEvent);
> +    gEndOfDxeEvent = NULL;
> +    gBS->CloseEvent (gExitBootServiceEvent);
> +    gExitBootServiceEvent = NULL;
> +    gBS->CloseEvent (gEfiRedfishDiscoverProtocolEvent);
> +    gEfiRedfishDiscoverProtocolEvent = NULL;
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI Binding Protocol of EFI
> Redfish Config driver.", __FUNCTION__));
> +    return Status;
> +  }
> +  return Status;
> +}
> +
> --
> 2.17.1
> 
> 
> 
> 
> 



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#73936): https://edk2.groups.io/g/devel/message/73936
Mute This Topic: https://groups.io/mt/81622326/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list