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

Abner Chang abner.chang at hpe.com
Wed Apr 7 06:30:58 UTC 2021


it was created before. I just revised the title to EDKII Redfish Config Handler Protocol instead of using EFI as the prefix.
https://bugzilla.tianocore.org/show_bug.cgi?id=2911

Will add BZ# to the commit message.
Thanks


> -----Original Message-----
> From: gaoliming [mailto:gaoliming at byosoft.com.cn]
> Sent: Wednesday, April 7, 2021 1:21 PM
> To: devel at edk2.groups.io; Chang, Abner (HPS SW/FW Technologist)
> <abner.chang at hpe.com>
> Cc: Wang, Nickle (HPS SW) <nickle.wang at hpe.com>
> Subject: 回复: [edk2-devel] [PATCH] RedfishPkg/RedfishConfigHandler:
> EDKII RedfishConfigHandler Protocol
> 
> Abner:
>   This is a new feature. Can you submit one BZ for it?
> 
> Thanks
> Liming
> > -----邮件原件-----
> > 发件人: devel at edk2.groups.io <devel at edk2.groups.io> 代表 Abner
> Chang
> > 发送时间: 2021年3月26日 13:55
> > 收件人: devel at edk2.groups.io
> > 抄送: Nickle Wang <nickle.wang at hpe.com>
> > 主题: [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 (#73765): https://edk2.groups.io/g/devel/message/73765
Mute This Topic: https://groups.io/mt/81909867/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