[edk2-devel] [edk2-redfish-client][PATCH] RedfishClientPkg/RedfishFeatureCoreDxe: Redfish Feature Core DXE driver

Chang, Abner via groups.io posted 1 patch 11 months, 3 weeks ago
Failed in applying to current master (apply log)
RedfishClientPkg/RedfishClientPkg.dec         |  13 +-
.../RedfishClientComponents.dsc.inc           |   2 +
RedfishClientPkg/RedfishClient.fdf.inc        |   1 +
.../RedfishFeatureCoreDxe.inf                 |  49 +++
.../Include/Protocol/EdkIIRedfishFeature.h    | 117 +++++
.../RedfishFeatureCoreDxe.h                   |  45 ++
.../RedfishFeatureCoreDxe.c                   | 403 ++++++++++++++++++
RedfishClientPkg/Readme.md                    |  36 ++
8 files changed, 665 insertions(+), 1 deletion(-)
create mode 100644 RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
create mode 100644 RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
create mode 100644 RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
create mode 100644 RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
[edk2-devel] [edk2-redfish-client][PATCH] RedfishClientPkg/RedfishFeatureCoreDxe: Redfish Feature Core DXE driver
Posted by Chang, Abner via groups.io 11 months, 3 weeks ago
From: Abner Chang <abner.chang@amd.com>

EDKII Redfish Feature Core DXE driver provides the
protocol interface to the auto-generated Redfish
feature driver to register itself for the Redfish
resource URI it manages.

Refer to the Readme.md for the details.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Cc: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>
---
 RedfishClientPkg/RedfishClientPkg.dec         |  13 +-
 .../RedfishClientComponents.dsc.inc           |   2 +
 RedfishClientPkg/RedfishClient.fdf.inc        |   1 +
 .../RedfishFeatureCoreDxe.inf                 |  49 +++
 .../Include/Protocol/EdkIIRedfishFeature.h    | 117 +++++
 .../RedfishFeatureCoreDxe.h                   |  45 ++
 .../RedfishFeatureCoreDxe.c                   | 403 ++++++++++++++++++
 RedfishClientPkg/Readme.md                    |  36 ++
 8 files changed, 665 insertions(+), 1 deletion(-)
 create mode 100644 RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
 create mode 100644 RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
 create mode 100644 RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
 create mode 100644 RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c

diff --git a/RedfishClientPkg/RedfishClientPkg.dec b/RedfishClientPkg/RedfishClientPkg.dec
index 4038a47bd5..6da0468e65 100644
--- a/RedfishClientPkg/RedfishClientPkg.dec
+++ b/RedfishClientPkg/RedfishClientPkg.dec
@@ -15,10 +15,21 @@
 [Includes]
   Include
 
-
 [LibraryClasses]
 
 [Protocols]
+  ## Include/Protocol/EdkIIRedfishFeature.h
+  gEdkIIRedfishFeatureProtocolGuid = { 0x785CC694, 0x4930, 0xEFBF, { 0x2A, 0xCB, 0xA4, 0xB6, 0xA1, 0xCC, 0xAA, 0x34 } }
 
 [Guids]
   gEfiRedfishClientPkgTokenSpaceGuid    = { 0x8c444dae, 0x728b, 0x48ee, { 0x9e, 0x19, 0x8f, 0x0a, 0x3d, 0x4e, 0x9c, 0xc8 } }
+
+[PcdsFixedAtBuild]
+  gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize|32|UINT32|0x10000001
+  gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize|8|UINT32|0x10000002
+  #
+  # gEfiEventReadyToBootGuid is the default event to startup Redfish feature drivers.
+  # { 0x7CE88FB3, 0x4BD7, 0x4679, { 0x87, 0xA8, 0xA8, 0xD8, 0xDE, 0xE5, 0x0D, 0x2B }}
+  #
+  gEfiRedfishClientPkgTokenSpaceGuid.PcdEdkIIRedfishFeatureDriverStartupEventGuid|{0xB3, 0x8F, 0xE8, 0x7C, 0xD7, 0x4B, 0x79, 0x46, 0x87, 0xA8, 0xA8, 0xD8, 0xDE, 0xE5, 0x0D, 0x2B}|VOID*|0x10000003
+
diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc b/RedfishClientPkg/RedfishClientComponents.dsc.inc
index 0648fa9d54..e4e2619bfb 100644
--- a/RedfishClientPkg/RedfishClientComponents.dsc.inc
+++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc
@@ -13,4 +13,6 @@
 ##
 
 !if $(REDFISH_CLIENT) == TRUE
+  RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
 !endif
+
diff --git a/RedfishClientPkg/RedfishClient.fdf.inc b/RedfishClientPkg/RedfishClient.fdf.inc
index 4f0714004e..d4c5874787 100644
--- a/RedfishClientPkg/RedfishClient.fdf.inc
+++ b/RedfishClientPkg/RedfishClient.fdf.inc
@@ -11,4 +11,5 @@
 #
 ##
 !if $(REDFISH_CLIENT) == TRUE
+  INF RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
 !endif
diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
new file mode 100644
index 0000000000..5a2cd7fecc
--- /dev/null
+++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
@@ -0,0 +1,49 @@
+## @file
+#  RedfishFeatureCoreDxe is the DXE driver which provides
+#  EdkIIRedfishFeatureCoreProtocol to EDK2 Redfish Feature
+#  drivers for the registration.
+#
+#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001000b
+  BASE_NAME                      = RedfishFeatureCoreDxe
+  FILE_GUID                      = 1E01A624-4161-F1F1-25BC-D28E77420D8E
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = RedfishFeatureCoreEntryPoint
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 RISCV64
+#
+
+[Sources]
+  RedfishFeatureCoreDxe.c
+  RedfishFeatureCoreDxe.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  RedfishClientPkg/RedfishClientPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  PrintLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEdkIIRedfishFeatureProtocolGuid    ## BY_START
+
+[Pcd]
+  gEfiRedfishClientPkgTokenSpaceGuid.PcdEdkIIRedfishFeatureDriverStartupEventGuid
+
+[Depex]
+  TRUE
diff --git a/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h b/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
new file mode 100644
index 0000000000..04b65a06a3
--- /dev/null
+++ b/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
@@ -0,0 +1,117 @@
+/** @file
+  This file defines the EDKII_REDFISH_FEATURE_PROTOCOL interface.
+
+  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_FEATURE_H_
+#define EDKII_REDFISH_FEATURE_H_
+
+typedef struct _EDKII_REDFISH_FEATURE_PROTOCOL EDKII_REDFISH_FEATURE_PROTOCOL;
+
+#define EDKII_REDFISH_FEATURE_PROTOCOL_GUID \
+    {  \
+      0x785CC694, 0x4930, 0xEFBF, { 0x2A, 0xCB, 0xA4, 0xB6, 0xA1, 0xCC, 0xAA, 0x34 }  \
+    }
+
+typedef enum {
+  CallbackActionNone = 0,       ///< Invalid action
+  CallbackActionStartOperation, ///< Start the operations on Redfish resource
+  CallbackActionMax
+} FEATURE_CALLBACK_ACTION;
+
+typedef enum {
+  InformationTypeNone = 0,            ///< Invalid information.
+  InformationTypeCollectionMemberUri, ///< URI to the new created collection member.
+  InformationTypeMax
+} FEATURE_RETURNED_INFORMATION_TYPE;
+
+typedef struct {
+  FEATURE_RETURNED_INFORMATION_TYPE    Type;
+} FEATURE_RETURNED_INFORMATION;
+
+/**
+  The callback function provided by Redfish Feature driver.
+
+  @param[in]     This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL instance.
+  @param[in]     FeatureAction       The action Redfish feature driver should take.
+  @param[in]     Context             The context of Redfish feature driver.
+  @param[in,out] InformationReturned The pointer to retrive the pointer to
+                                     FEATURE_RETURNED_INFOMATION. The memory block of this
+                                     information should be freed by caller.
+
+  @retval EFI_SUCCESS              Redfish feature driver callback is executed successfully.
+  @retval Others                   Some errors happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_FEATURE_CALLBACK)(
+  IN     EDKII_REDFISH_FEATURE_PROTOCOL *This,
+  IN     FEATURE_CALLBACK_ACTION        FeatureAction,
+  IN     VOID                           *Context,
+  IN OUT FEATURE_RETURNED_INFORMATION   **InformationReturned
+  );
+
+/**
+  The registration function for the Redfish Feature driver.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL instance.
+  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of the Redfish
+                                   resource in the entire Redfish data model that managed
+                                   by Redfish feature driver . Each node in the hierarchy
+                                   path is the property name defined in the schema of the
+                                   resource.
+  @param[in]   Callback            Callback routine associated with this registration that
+                                   provided by Redfish feature driver to execute the action
+                                   on Redfish resource which is managed by this Redfish
+                                   feature driver.
+  @param[in]   Context             The context of the registering feature driver. The pointer
+                                   to the conext is delivered through callback function.
+  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
+  @retval Others                   Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_FEATURE_REGISTER)(
+  IN     EDKII_REDFISH_FEATURE_PROTOCOL  *This,
+  IN     EFI_STRING                      FeatureManagedUri,
+  IN     REDFISH_FEATURE_CALLBACK        Callback,
+  IN     VOID                            *Context
+  );
+
+/**
+  The unregistration function for the Redfish Feature driver.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL instance.
+  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of the Redfish
+                                   resource in the entire Redfish data model that managed
+                                   by Redfish feature driver . Each node in the hierarchy
+                                   path is the property name defined in the schema of the
+                                   resource.
+  @param[in]   Context             The context used for the previous feature driver
+                                   registration.
+  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
+  @retval Others                   Some error happened.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *REDFISH_FEATURE_UNREGISTER)(
+  IN     EDKII_REDFISH_FEATURE_PROTOCOL  *This,
+  IN     EFI_STRING                      FeatureManagedUri,
+  IN     VOID                            *Context
+  );
+
+struct _EDKII_REDFISH_FEATURE_PROTOCOL {
+  REDFISH_FEATURE_REGISTER      Register;
+  REDFISH_FEATURE_UNREGISTER    Unregister;
+};
+
+extern EFI_GUID  gEdkIIRedfishFeatureProtocolGuid;
+
+#endif
diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
new file mode 100644
index 0000000000..71432a1aa9
--- /dev/null
+++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
@@ -0,0 +1,45 @@
+/** @file
+  Definitions of RedfishFeatureCoreDxe
+
+  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef EDKII_REDFISH_FEATURE_CORE_DXE_H_
+#define EDKII_REDFISH_FEATURE_CORE_DXE_H_
+
+#include <Protocol/EdkIIRedfishFeature.h>
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#define MaxNodeNameLength             64
+#define NodeSeperator                 L'/'
+#define NodeIsCollectionLeftBracket   '{'
+#define NodeIsCollectionRightBracket  '}'
+
+typedef struct _REDFISH_FEATURE_INTERNAL_DATA REDFISH_FEATURE_INTERNAL_DATA;
+struct _REDFISH_FEATURE_INTERNAL_DATA {
+  REDFISH_FEATURE_INTERNAL_DATA    *SiblingList;         ///< Next same level in hierarchy of resource URI.
+  REDFISH_FEATURE_INTERNAL_DATA    *ChildList;           ///< Next level in hierarchy of resource URI.
+  EFI_STRING                       NodeName;             ///< Name of the node in hierarchy of resource URI.
+  REDFISH_FEATURE_CALLBACK         Callback;             ///< Callback function of Redfish feature driver.
+  VOID                             *Context;             ///< Context of feature driver.
+  FEATURE_RETURNED_INFORMATION     *ReturnedInformation; ///< Information returned from Redfish feature driver.
+  UINT32                           Flags;
+};
+
+#define REDFISH_FEATURE_INTERNAL_DATA_IS_COLLECTION  0x00000001
+
+typedef struct {
+  EDKII_REDFISH_FEATURE_PROTOCOL    *This;
+  FEATURE_CALLBACK_ACTION           Action;
+} REDFISH_FEATURE_STARTUP_CONTEXT;
+#endif
diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
new file mode 100644
index 0000000000..5cd89872c1
--- /dev/null
+++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
@@ -0,0 +1,403 @@
+/** @file
+  RedfishFeatureCoreDxe produces EdkIIRedfishFeatureCoreProtocol
+  for EDK2 Redfish Feature driver registration.
+
+  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <RedfishFeatureCoreDxe.h>
+
+EFI_EVENT                        mEdkIIRedfishFeatureDriverStartupEvent;
+REDFISH_FEATURE_STARTUP_CONTEXT  mFeatureDriverStartupContext;
+REDFISH_FEATURE_INTERNAL_DATA    *ResourceUriNodeList;
+
+/**
+  Startup child feature drivers and it's sibing feature drivers.
+
+  @param[in]  ThisFeatureDriverList This feature driver list.
+  @param[in]  StartupContext        Start up information
+
+**/
+VOID
+StartUpFeatureDriver (
+  IN REDFISH_FEATURE_INTERNAL_DATA    *ThisFeatureDriverList,
+  IN REDFISH_FEATURE_STARTUP_CONTEXT  *StartupContext
+  )
+{
+  EFI_STATUS                     Status;
+  REDFISH_FEATURE_INTERNAL_DATA  *ThisList;
+
+  ThisList = ThisFeatureDriverList;
+  while (TRUE) {
+    if (ThisList->Callback != NULL) {
+      Status = ThisList->Callback (
+                           StartupContext->This,
+                           StartupContext->Action,
+                           ThisList->Context,
+                           &ThisList->ReturnedInformation
+                           );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a: Callback to EDK2 Redfish feature driver fail.", __func__));
+      }
+    }
+
+    if (ThisList->ChildList != NULL) {
+      StartUpFeatureDriver (ThisList->ChildList, StartupContext);
+    }
+
+    //
+    // Check sibling Redfish feature driver.
+    //
+    if (ThisList->SiblingList == NULL) {
+      break;
+    }
+
+    //
+    // Go next sibling Redfish feature driver.
+    //
+    ThisList = ThisList->SiblingList;
+  }
+}
+
+/**
+  Callback routine when mEdkIIRedfishFeatureDriverStartupEvent
+  is signaled.
+
+  @param[in]  Event                 Event whose notification function is being invoked.
+  @param[in]  Context               The pointer to the notification function's context,
+                                    which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+RedfishFeatureDriverStartup (
+  IN  EFI_EVENT  Event,
+  IN  VOID       *Context
+  )
+{
+  REDFISH_FEATURE_STARTUP_CONTEXT  *StartupContext;
+
+  StartupContext = (REDFISH_FEATURE_STARTUP_CONTEXT *)Context;
+  //
+  // Invoke EDK2 Redfish feature driver callback to start up
+  // the Redfish operations.
+  //
+  if (ResourceUriNodeList == NULL) {
+    return;
+  }
+
+  //
+  // Invoke the callback by the hierarchy level
+  //
+  StartUpFeatureDriver (ResourceUriNodeList, StartupContext);
+}
+
+/**
+  Create new internal data instance.
+
+  @param[in,out] PtrToNewInternalData  Pointer to receive new instance of
+                                       REDFISH_FEATURE_INTERNAL_DATA.
+  @param[in]     NodeName              Name of URI node.
+
+  @retval EFI_SUCCESS              New entry is inserted successfully.
+  @retval EFI_INVALID_PARAMETER    Improper given parameters.
+  @retval EFI_OUT_OF_RESOURCES     Lack of memory for the internal data structure.
+
+**/
+EFI_STATUS
+NewInternalInstance (
+  IN OUT REDFISH_FEATURE_INTERNAL_DATA  **PtrToNewInternalData,
+  IN EFI_STRING                         NodeName
+  )
+{
+  REDFISH_FEATURE_INTERNAL_DATA  *NewInternalData;
+
+  if ((PtrToNewInternalData == NULL) || (NodeName == NULL)) {
+    DEBUG ((DEBUG_ERROR, "%a: Inproper given parameters\n", __func__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *PtrToNewInternalData = NULL;
+  NewInternalData       = AllocateZeroPool (sizeof (REDFISH_FEATURE_INTERNAL_DATA));
+  if (NewInternalData == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: No memory for REDFISH_FEATURE_INTERNAL_DATA\n", __func__));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  NewInternalData->NodeName = AllocateZeroPool (StrSize (NodeName));
+  StrnCpyS (NewInternalData->NodeName, StrSize (NodeName), (CONST CHAR16 *)NodeName, StrLen (NodeName));
+  NewInternalData->SiblingList = NULL;
+  NewInternalData->ChildList   = NULL;
+  if ((NodeName[0] == (UINT16)NodeIsCollectionLeftBracket) &&
+      (NodeName[StrLen (NodeName) - 1] == (UINT16)NodeIsCollectionRightBracket))
+  {
+    NewInternalData->Flags |= REDFISH_FEATURE_INTERNAL_DATA_IS_COLLECTION;
+  }
+
+  *PtrToNewInternalData = NewInternalData;
+  return EFI_SUCCESS;
+}
+
+/**
+  Insert the URI node into internal data structure
+
+  @param[in]        HeadEntryToInsert  The head entry to start the searching.
+  @param[in]        NodeName           Name of URI node.
+  @param[in, out]   NextNodeEntry      Pointer to receive the pointer of next head
+                                       entry for inserting the follow up nodes.
+                                       The returned LIST_ENTRY is the address of
+                                       ChildList link list.
+  @retval EFI_SUCCESS              New entry is inserted successfully.
+  @retval EFI_INVALID_PARAMETER    Improper given parameters.
+  @retval EFI_OUT_OF_RESOURCES     Lack of memory for the internal data structure.
+
+**/
+EFI_STATUS
+InsertRedfishFeatureUriNode (
+  IN REDFISH_FEATURE_INTERNAL_DATA      *HeadEntryToInsert,
+  IN EFI_STRING                         NodeName,
+  IN OUT REDFISH_FEATURE_INTERNAL_DATA  **NextNodeEntry
+  )
+{
+  EFI_STATUS                     Status;
+  REDFISH_FEATURE_INTERNAL_DATA  *NewInternalData;
+  REDFISH_FEATURE_INTERNAL_DATA  *ThisInternalData;
+  REDFISH_FEATURE_INTERNAL_DATA  *SiblingList;
+
+  if (NodeName == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: Node name is NULL.\n", __func__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (NextNodeEntry == NULL) {
+    DEBUG ((DEBUG_ERROR, "%a: NextNodeEntry can't be NULL.\n", __func__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((HeadEntryToInsert == NULL) || (HeadEntryToInsert->ChildList == NULL)) {
+    Status = NewInternalInstance (&NewInternalData, NodeName);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if (HeadEntryToInsert == NULL) {
+      ResourceUriNodeList = NewInternalData;
+    } else {
+      HeadEntryToInsert->ChildList = NewInternalData;
+    }
+
+    *NextNodeEntry = NewInternalData;
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Go through sibling list to find the entry.
+  //
+  ThisInternalData = HeadEntryToInsert;
+  SiblingList      = ThisInternalData->SiblingList;
+  while (TRUE) {
+    if (StrCmp ((CONST CHAR16 *)ThisInternalData->NodeName, (CONST CHAR16 *)NodeName) == 0) {
+      *NextNodeEntry = ThisInternalData->ChildList;
+      return EFI_SUCCESS;
+    }
+
+    //
+    // If sibing exist?
+    //
+    if (SiblingList == NULL) {
+      Status = NewInternalInstance (&NewInternalData, NodeName);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+
+      ThisInternalData->SiblingList = NewInternalData;
+      *NextNodeEntry                = NewInternalData->ChildList;
+      return EFI_SUCCESS;
+    }
+
+    SiblingList = SiblingList->SiblingList;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The registration function for the Redfish Feature driver.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL instance.
+  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of the Redfish
+                                   resource in the entire Redfish data model that managed
+                                   by Redfish feature driver . Each node in the hierarchy
+                                   path is the property name defined in the schema of the
+                                   resource.
+                                   e.g. "ServiceRoot/" - Managed by ServiceRoot feature driver
+                                        "ServiceRoot/Systems[]/" - Managed by ComputerSystemCollection feature driver
+                                        "ServiceRoot/Systems[1]/" - Managed by ComputerSystem feature driver
+                                        "ServiceRoot/Systems[2]/Bios/" - Managed by Bios feature driver
+  @param[in]   Callback            Callback routine associated with this registration that
+                                   provided by Redfish feature driver to execute the action
+                                   on Redfish resource which is managed by this Redfish
+                                   feature driver.
+  @param[in]   Context             The context of the registering feature driver. The pointer
+                                   to the conext is delivered through callback function.
+  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
+  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
+  @retval EFI_INVALID_PARAMETER    Improper given parameters or fail to register
+                                   feature driver.
+  @retval EFI_OUT_OF_RESOURCES     Lack of memory for the internal data structure.
+  @retval Others                   Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishFeatureRegister (
+  IN EDKII_REDFISH_FEATURE_PROTOCOL  *This,
+  IN EFI_STRING                      FeatureManagedUri,
+  IN REDFISH_FEATURE_CALLBACK        Callback,
+  IN VOID                            *Context
+  )
+{
+  CHAR16                         NodeName[MaxNodeNameLength];
+  EFI_STATUS                     Status;
+  UINTN                          Index;
+  UINTN                          AnchorIndex;
+  UINTN                          UriLength;
+  REDFISH_FEATURE_INTERNAL_DATA  *ThisUriNode;
+
+  if ((FeatureManagedUri == NULL) || (Callback == NULL)) {
+    DEBUG ((DEBUG_ERROR, "%a: The given parameter is invalid\n", __func__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Walk through URI which managed by this EDK2 Redfish feature driver.
+  //
+  UriLength   = StrLen (FeatureManagedUri) + 1; // Add one NULL for the last node.
+  Index       = 0;
+  AnchorIndex = 0;
+  ThisUriNode = ResourceUriNodeList;
+  do {
+    if ((Index - AnchorIndex + 1) >= MaxNodeNameLength) {
+      // Increase one for the NULL terminator
+      DEBUG ((DEBUG_ERROR, "%a: the length of node name is >= MaxNodeNameLength\n", __func__));
+      ASSERT (FALSE);
+    }
+
+    NodeName[Index - AnchorIndex] = *(FeatureManagedUri + Index);
+    if ((NodeName[Index - AnchorIndex] == NodeSeperator) || (NodeName[Index - AnchorIndex] == (CHAR16)0)) {
+      NodeName[Index - AnchorIndex] = 0;
+      AnchorIndex                   = Index + 1;
+      //
+      // Insert node
+      //
+      if (StrLen (NodeName) != 0) {
+        Status = InsertRedfishFeatureUriNode (ThisUriNode, NodeName, &ThisUriNode);
+        if (EFI_ERROR (Status)) {
+          return Status;
+        }
+      }
+    }
+
+    Index++;
+  } while ((Index < UriLength));
+
+  if (ThisUriNode == NULL) {
+    //
+    // No URI node was created
+    //
+    DEBUG ((DEBUG_ERROR, "%a: No URI node is added\n", __func__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Add feature driver info to internal data instance.
+  //
+  ThisUriNode->Callback = Callback;
+  ThisUriNode->Context  = Context;
+  return EFI_SUCCESS;
+}
+
+/**
+  The unregistration function for the Redfish Feature driver.
+
+  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL instance.
+  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of the Redfish
+                                   resource in the entire Redfish data model that managed
+                                   by Redfish feature driver . Each node in the hierarchy
+                                   path is the property name defined in the schema of the
+                                   resource.
+  @param[in]   Context             The context used for the previous feature driver
+                                   registration.
+  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
+  @retval Others                   Some error happened.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishFeatureUnregister (
+  IN     EDKII_REDFISH_FEATURE_PROTOCOL  *This,
+  IN     EFI_STRING                      FeatureManagedUri,
+  IN     VOID                            *Context
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EDKII_REDFISH_FEATURE_PROTOCOL  mRedfishFeatureProtocol = {
+  RedfishFeatureRegister,
+  RedfishFeatureUnregister
+};
+
+/**
+  Main entry for this driver.
+
+  @param[in] ImageHandle     Image handle this driver.
+  @param[in] SystemTable     Pointer to SystemTable.
+
+  @retval EFI_SUCESS     This function always complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+RedfishFeatureCoreEntryPoint (
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_HANDLE  Handle;
+  EFI_GUID    *EventGuid;
+
+  Handle              = NULL;
+  ResourceUriNodeList = NULL;
+  EventGuid           = (EFI_GUID *)PcdGetPtr (PcdEdkIIRedfishFeatureDriverStartupEventGuid);
+
+  ZeroMem ((VOID *)&mFeatureDriverStartupContext, sizeof (REDFISH_FEATURE_STARTUP_CONTEXT));
+  mFeatureDriverStartupContext.This = &mRedfishFeatureProtocol;
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  RedfishFeatureDriverStartup,
+                  (CONST VOID *)&mFeatureDriverStartupContext,
+                  EventGuid,
+                  &mEdkIIRedfishFeatureDriverStartupEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Install the RedfishCredentialProtocol onto Handle.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEdkIIRedfishFeatureProtocolGuid,
+                  &mRedfishFeatureProtocol,
+                  NULL
+                  );
+  return Status;
+}
diff --git a/RedfishClientPkg/Readme.md b/RedfishClientPkg/Readme.md
index 9e56fb9039..18a27633cf 100644
--- a/RedfishClientPkg/Readme.md
+++ b/RedfishClientPkg/Readme.md
@@ -119,6 +119,42 @@ struct _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {
 For those Non-EDK2 HII-based platform configuration formats, the driver instance
 can provide its own implementation to get or set the platform configurations.
 
+### EDKII Redfish Feature Core DXE Driver ***[[12]](#[0])***
+EDKII Redfish Feature Core DXE driver provides the protocol interface to
+the auto-generated Redfish feature driver to register itself for the
+Redfish resource URI it manages.
+
+```C
+struct _EDKII_REDFISH_FEATURE_PROTOCOL {
+  REDFISH_FEATURE_REGISTER      Register;
+  REDFISH_FEATURE_UNREGISTER    Unregister;
+};
+```
+
+Redfish Feature Core DXE driver records the
+URI according to the URI hierarchy, and then it starts up the Redfish
+feature drivers based on the hierarchy when the particular event
+***[[11]](#[0])*** is triggered. This makes sure the upper-level Redfish
+resource is built up before the lower-level resource. For example,
+ComputerSystem resource must be ready before the Memory resource managed
+by MemoryCollection because the Memory resource is part of ComputerSystem
+resource.
+
+### Start-Up Event to Trigger EDKII Redfish Feature Core ***[[11]](#[0])***
+This is an EFI event for triggering EDKII Redfish Feature Core to travel
+URIs in the database and execute the callback that registered by Redfish feature
+drivers. The event GUID is defined in below PCD and is default set to
+**gEfiEventReadyToBootGuid**.
+
+```C
+PcdEdkIIRedfishFeatureDriverStartupEventGuid
+```
+
+This PCD can be overridden to any events based on the platform
+implementation. EDKII Redfish Feature Core can be triggered earlier,
+for example before the BDS or in the early DXE phase if the platform provides
+the EFI REST EX protocol which is available before the BDS phase.
+
 ### EDK2 HII VFR Form ***[[8]](#[0])***
 According to **UEFI spec 2.9 section 35.6 Form Browser Protocol**,
 **EFI_HII_REST_STYLE_FORMSET_GUID** is used on HII form to indicate that HII
-- 
2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103889): https://edk2.groups.io/g/devel/message/103889
Mute This Topic: https://groups.io/mt/98657046/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Re: [edk2-devel] [edk2-redfish-client][PATCH] RedfishClientPkg/RedfishFeatureCoreDxe: Redfish Feature Core DXE driver
Posted by Nickle Wang via groups.io 11 months, 3 weeks ago
Reviewed-by: Nickle Wang <nicklew@nvidia.com>

Regards,
Nickle

> -----Original Message-----
> From: abner.chang@amd.com <abner.chang@amd.com>
> Sent: Wednesday, May 3, 2023 3:49 PM
> To: devel@edk2.groups.io
> Cc: Nickle Wang <nicklew@nvidia.com>; Igor Kulchytskyy <igork@ami.com>
> Subject: [edk2-redfish-client][PATCH] RedfishClientPkg/RedfishFeatureCoreDxe:
> Redfish Feature Core DXE driver
> 
> External email: Use caution opening links or attachments
> 
> 
> From: Abner Chang <abner.chang@amd.com>
> 
> EDKII Redfish Feature Core DXE driver provides the protocol interface to the
> auto-generated Redfish feature driver to register itself for the Redfish resource
> URI it manages.
> 
> Refer to the Readme.md for the details.
> 
> Signed-off-by: Abner Chang <abner.chang@amd.com>
> Cc: Nickle Wang <nicklew@nvidia.com>
> Cc: Igor Kulchytskyy <igork@ami.com>
> ---
>  RedfishClientPkg/RedfishClientPkg.dec         |  13 +-
>  .../RedfishClientComponents.dsc.inc           |   2 +
>  RedfishClientPkg/RedfishClient.fdf.inc        |   1 +
>  .../RedfishFeatureCoreDxe.inf                 |  49 +++
>  .../Include/Protocol/EdkIIRedfishFeature.h    | 117 +++++
>  .../RedfishFeatureCoreDxe.h                   |  45 ++
>  .../RedfishFeatureCoreDxe.c                   | 403 ++++++++++++++++++
>  RedfishClientPkg/Readme.md                    |  36 ++
>  8 files changed, 665 insertions(+), 1 deletion(-)  create mode 100644
> RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
>  create mode 100644 RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
>  create mode 100644
> RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
>  create mode 100644
> RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
> 
> diff --git a/RedfishClientPkg/RedfishClientPkg.dec
> b/RedfishClientPkg/RedfishClientPkg.dec
> index 4038a47bd5..6da0468e65 100644
> --- a/RedfishClientPkg/RedfishClientPkg.dec
> +++ b/RedfishClientPkg/RedfishClientPkg.dec
> @@ -15,10 +15,21 @@
>  [Includes]
>    Include
> 
> -
>  [LibraryClasses]
> 
>  [Protocols]
> +  ## Include/Protocol/EdkIIRedfishFeature.h
> +  gEdkIIRedfishFeatureProtocolGuid = { 0x785CC694, 0x4930, 0xEFBF, {
> + 0x2A, 0xCB, 0xA4, 0xB6, 0xA1, 0xCC, 0xAA, 0x34 } }
> 
>  [Guids]
>    gEfiRedfishClientPkgTokenSpaceGuid    = { 0x8c444dae, 0x728b, 0x48ee, { 0x9e,
> 0x19, 0x8f, 0x0a, 0x3d, 0x4e, 0x9c, 0xc8 } }
> +
> +[PcdsFixedAtBuild]
> +
> +gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaStringSize|32|UIN
> +T32|0x10000001
> +
> +gEfiRedfishClientPkgTokenSpaceGuid.PcdMaxRedfishSchemaVersionSize|8|UI
> N
> +T32|0x10000002
> +  #
> +  # gEfiEventReadyToBootGuid is the default event to startup Redfish feature
> drivers.
> +  # { 0x7CE88FB3, 0x4BD7, 0x4679, { 0x87, 0xA8, 0xA8, 0xD8, 0xDE, 0xE5,
> +0x0D, 0x2B }}
> +  #
> +
> +gEfiRedfishClientPkgTokenSpaceGuid.PcdEdkIIRedfishFeatureDriverStartupE
> +ventGuid|{0xB3, 0x8F, 0xE8, 0x7C, 0xD7, 0x4B, 0x79, 0x46, 0x87, 0xA8,
> +0xA8, 0xD8, 0xDE, 0xE5, 0x0D, 0x2B}|VOID*|0x10000003
> +
> diff --git a/RedfishClientPkg/RedfishClientComponents.dsc.inc
> b/RedfishClientPkg/RedfishClientComponents.dsc.inc
> index 0648fa9d54..e4e2619bfb 100644
> --- a/RedfishClientPkg/RedfishClientComponents.dsc.inc
> +++ b/RedfishClientPkg/RedfishClientComponents.dsc.inc
> @@ -13,4 +13,6 @@
>  ##
> 
>  !if $(REDFISH_CLIENT) == TRUE
> +  RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
>  !endif
> +
> diff --git a/RedfishClientPkg/RedfishClient.fdf.inc
> b/RedfishClientPkg/RedfishClient.fdf.inc
> index 4f0714004e..d4c5874787 100644
> --- a/RedfishClientPkg/RedfishClient.fdf.inc
> +++ b/RedfishClientPkg/RedfishClient.fdf.inc
> @@ -11,4 +11,5 @@
>  #
>  ##
>  !if $(REDFISH_CLIENT) == TRUE
> +  INF RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
>  !endif
> diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
> b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
> new file mode 100644
> index 0000000000..5a2cd7fecc
> --- /dev/null
> +++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.inf
> @@ -0,0 +1,49 @@
> +## @file
> +#  RedfishFeatureCoreDxe is the DXE driver which provides #
> +EdkIIRedfishFeatureCoreProtocol to EDK2 Redfish Feature #  drivers for
> +the registration.
> +#
> +#  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001000b
> +  BASE_NAME                      = RedfishFeatureCoreDxe
> +  FILE_GUID                      = 1E01A624-4161-F1F1-25BC-D28E77420D8E
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = RedfishFeatureCoreEntryPoint
> +
> +#
> +#  VALID_ARCHITECTURES           = IA32 X64 ARM AARCH64 RISCV64
> +#
> +
> +[Sources]
> +  RedfishFeatureCoreDxe.c
> +  RedfishFeatureCoreDxe.h
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  RedfishClientPkg/RedfishClientPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +  PrintLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEdkIIRedfishFeatureProtocolGuid    ## BY_START
> +
> +[Pcd]
> +
> +gEfiRedfishClientPkgTokenSpaceGuid.PcdEdkIIRedfishFeatureDriverStartupE
> +ventGuid
> +
> +[Depex]
> +  TRUE
> diff --git a/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
> b/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
> new file mode 100644
> index 0000000000..04b65a06a3
> --- /dev/null
> +++ b/RedfishClientPkg/Include/Protocol/EdkIIRedfishFeature.h
> @@ -0,0 +1,117 @@
> +/** @file
> +  This file defines the EDKII_REDFISH_FEATURE_PROTOCOL interface.
> +
> +  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_FEATURE_H_
> +#define EDKII_REDFISH_FEATURE_H_
> +
> +typedef struct _EDKII_REDFISH_FEATURE_PROTOCOL
> +EDKII_REDFISH_FEATURE_PROTOCOL;
> +
> +#define EDKII_REDFISH_FEATURE_PROTOCOL_GUID \
> +    {  \
> +      0x785CC694, 0x4930, 0xEFBF, { 0x2A, 0xCB, 0xA4, 0xB6, 0xA1, 0xCC, 0xAA,
> 0x34 }  \
> +    }
> +
> +typedef enum {
> +  CallbackActionNone = 0,       ///< Invalid action
> +  CallbackActionStartOperation, ///< Start the operations on Redfish
> +resource
> +  CallbackActionMax
> +} FEATURE_CALLBACK_ACTION;
> +
> +typedef enum {
> +  InformationTypeNone = 0,            ///< Invalid information.
> +  InformationTypeCollectionMemberUri, ///< URI to the new created collection
> member.
> +  InformationTypeMax
> +} FEATURE_RETURNED_INFORMATION_TYPE;
> +
> +typedef struct {
> +  FEATURE_RETURNED_INFORMATION_TYPE    Type;
> +} FEATURE_RETURNED_INFORMATION;
> +
> +/**
> +  The callback function provided by Redfish Feature driver.
> +
> +  @param[in]     This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL
> instance.
> +  @param[in]     FeatureAction       The action Redfish feature driver should take.
> +  @param[in]     Context             The context of Redfish feature driver.
> +  @param[in,out] InformationReturned The pointer to retrive the pointer to
> +                                     FEATURE_RETURNED_INFOMATION. The memory block of
> this
> +                                     information should be freed by caller.
> +
> +  @retval EFI_SUCCESS              Redfish feature driver callback is executed
> successfully.
> +  @retval Others                   Some errors happened.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *REDFISH_FEATURE_CALLBACK)(
> +  IN     EDKII_REDFISH_FEATURE_PROTOCOL *This,
> +  IN     FEATURE_CALLBACK_ACTION        FeatureAction,
> +  IN     VOID                           *Context,
> +  IN OUT FEATURE_RETURNED_INFORMATION   **InformationReturned
> +  );
> +
> +/**
> +  The registration function for the Redfish Feature driver.
> +
> +  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL
> instance.
> +  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of
> the Redfish
> +                                   resource in the entire Redfish data model that managed
> +                                   by Redfish feature driver . Each node in the hierarchy
> +                                   path is the property name defined in the schema of the
> +                                   resource.
> +  @param[in]   Callback            Callback routine associated with this registration
> that
> +                                   provided by Redfish feature driver to execute the action
> +                                   on Redfish resource which is managed by this Redfish
> +                                   feature driver.
> +  @param[in]   Context             The context of the registering feature driver. The
> pointer
> +                                   to the conext is delivered through callback function.
> +  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *REDFISH_FEATURE_REGISTER)(
> +  IN     EDKII_REDFISH_FEATURE_PROTOCOL  *This,
> +  IN     EFI_STRING                      FeatureManagedUri,
> +  IN     REDFISH_FEATURE_CALLBACK        Callback,
> +  IN     VOID                            *Context
> +  );
> +
> +/**
> +  The unregistration function for the Redfish Feature driver.
> +
> +  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL
> instance.
> +  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of
> the Redfish
> +                                   resource in the entire Redfish data model that managed
> +                                   by Redfish feature driver . Each node in the hierarchy
> +                                   path is the property name defined in the schema of the
> +                                   resource.
> +  @param[in]   Context             The context used for the previous feature driver
> +                                   registration.
> +  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *REDFISH_FEATURE_UNREGISTER)(
> +  IN     EDKII_REDFISH_FEATURE_PROTOCOL  *This,
> +  IN     EFI_STRING                      FeatureManagedUri,
> +  IN     VOID                            *Context
> +  );
> +
> +struct _EDKII_REDFISH_FEATURE_PROTOCOL {
> +  REDFISH_FEATURE_REGISTER      Register;
> +  REDFISH_FEATURE_UNREGISTER    Unregister;
> +};
> +
> +extern EFI_GUID  gEdkIIRedfishFeatureProtocolGuid;
> +
> +#endif
> diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
> b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
> new file mode 100644
> index 0000000000..71432a1aa9
> --- /dev/null
> +++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.h
> @@ -0,0 +1,45 @@
> +/** @file
> +  Definitions of RedfishFeatureCoreDxe
> +
> +  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef EDKII_REDFISH_FEATURE_CORE_DXE_H_ #define
> +EDKII_REDFISH_FEATURE_CORE_DXE_H_
> +
> +#include <Protocol/EdkIIRedfishFeature.h>
> +
> +#include <Base.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h> #include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#define MaxNodeNameLength             64
> +#define NodeSeperator                 L'/'
> +#define NodeIsCollectionLeftBracket   '{'
> +#define NodeIsCollectionRightBracket  '}'
> +
> +typedef struct _REDFISH_FEATURE_INTERNAL_DATA
> +REDFISH_FEATURE_INTERNAL_DATA; struct
> _REDFISH_FEATURE_INTERNAL_DATA {
> +  REDFISH_FEATURE_INTERNAL_DATA    *SiblingList;         ///< Next same level
> in hierarchy of resource URI.
> +  REDFISH_FEATURE_INTERNAL_DATA    *ChildList;           ///< Next level in
> hierarchy of resource URI.
> +  EFI_STRING                       NodeName;             ///< Name of the node in
> hierarchy of resource URI.
> +  REDFISH_FEATURE_CALLBACK         Callback;             ///< Callback function of
> Redfish feature driver.
> +  VOID                             *Context;             ///< Context of feature driver.
> +  FEATURE_RETURNED_INFORMATION     *ReturnedInformation; ///<
> Information returned from Redfish feature driver.
> +  UINT32                           Flags;
> +};
> +
> +#define REDFISH_FEATURE_INTERNAL_DATA_IS_COLLECTION  0x00000001
> +
> +typedef struct {
> +  EDKII_REDFISH_FEATURE_PROTOCOL    *This;
> +  FEATURE_CALLBACK_ACTION           Action;
> +} REDFISH_FEATURE_STARTUP_CONTEXT;
> +#endif
> diff --git a/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
> b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
> new file mode 100644
> index 0000000000..5cd89872c1
> --- /dev/null
> +++ b/RedfishClientPkg/RedfishFeatureCoreDxe/RedfishFeatureCoreDxe.c
> @@ -0,0 +1,403 @@
> +/** @file
> +  RedfishFeatureCoreDxe produces EdkIIRedfishFeatureCoreProtocol
> +  for EDK2 Redfish Feature driver registration.
> +
> +  (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <RedfishFeatureCoreDxe.h>
> +
> +EFI_EVENT                        mEdkIIRedfishFeatureDriverStartupEvent;
> +REDFISH_FEATURE_STARTUP_CONTEXT  mFeatureDriverStartupContext;
> +REDFISH_FEATURE_INTERNAL_DATA    *ResourceUriNodeList;
> +
> +/**
> +  Startup child feature drivers and it's sibing feature drivers.
> +
> +  @param[in]  ThisFeatureDriverList This feature driver list.
> +  @param[in]  StartupContext        Start up information
> +
> +**/
> +VOID
> +StartUpFeatureDriver (
> +  IN REDFISH_FEATURE_INTERNAL_DATA    *ThisFeatureDriverList,
> +  IN REDFISH_FEATURE_STARTUP_CONTEXT  *StartupContext
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  REDFISH_FEATURE_INTERNAL_DATA  *ThisList;
> +
> +  ThisList = ThisFeatureDriverList;
> +  while (TRUE) {
> +    if (ThisList->Callback != NULL) {
> +      Status = ThisList->Callback (
> +                           StartupContext->This,
> +                           StartupContext->Action,
> +                           ThisList->Context,
> +                           &ThisList->ReturnedInformation
> +                           );
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((DEBUG_ERROR, "%a: Callback to EDK2 Redfish feature driver
> fail.", __func__));
> +      }
> +    }
> +
> +    if (ThisList->ChildList != NULL) {
> +      StartUpFeatureDriver (ThisList->ChildList, StartupContext);
> +    }
> +
> +    //
> +    // Check sibling Redfish feature driver.
> +    //
> +    if (ThisList->SiblingList == NULL) {
> +      break;
> +    }
> +
> +    //
> +    // Go next sibling Redfish feature driver.
> +    //
> +    ThisList = ThisList->SiblingList;
> +  }
> +}
> +
> +/**
> +  Callback routine when mEdkIIRedfishFeatureDriverStartupEvent
> +  is signaled.
> +
> +  @param[in]  Event                 Event whose notification function is being
> invoked.
> +  @param[in]  Context               The pointer to the notification function's context,
> +                                    which is implementation-dependent.
> +
> +**/
> +VOID
> +EFIAPI
> +RedfishFeatureDriverStartup (
> +  IN  EFI_EVENT  Event,
> +  IN  VOID       *Context
> +  )
> +{
> +  REDFISH_FEATURE_STARTUP_CONTEXT  *StartupContext;
> +
> +  StartupContext = (REDFISH_FEATURE_STARTUP_CONTEXT *)Context;  //  //
> + Invoke EDK2 Redfish feature driver callback to start up  // the
> + Redfish operations.
> +  //
> +  if (ResourceUriNodeList == NULL) {
> +    return;
> +  }
> +
> +  //
> +  // Invoke the callback by the hierarchy level
> +  //
> +  StartUpFeatureDriver (ResourceUriNodeList, StartupContext); }
> +
> +/**
> +  Create new internal data instance.
> +
> +  @param[in,out] PtrToNewInternalData  Pointer to receive new instance of
> +                                       REDFISH_FEATURE_INTERNAL_DATA.
> +  @param[in]     NodeName              Name of URI node.
> +
> +  @retval EFI_SUCCESS              New entry is inserted successfully.
> +  @retval EFI_INVALID_PARAMETER    Improper given parameters.
> +  @retval EFI_OUT_OF_RESOURCES     Lack of memory for the internal data
> structure.
> +
> +**/
> +EFI_STATUS
> +NewInternalInstance (
> +  IN OUT REDFISH_FEATURE_INTERNAL_DATA  **PtrToNewInternalData,
> +  IN EFI_STRING                         NodeName
> +  )
> +{
> +  REDFISH_FEATURE_INTERNAL_DATA  *NewInternalData;
> +
> +  if ((PtrToNewInternalData == NULL) || (NodeName == NULL)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Inproper given parameters\n", __func__));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *PtrToNewInternalData = NULL;
> +  NewInternalData       = AllocateZeroPool (sizeof
> (REDFISH_FEATURE_INTERNAL_DATA));
> +  if (NewInternalData == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: No memory for
> REDFISH_FEATURE_INTERNAL_DATA\n", __func__));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  NewInternalData->NodeName = AllocateZeroPool (StrSize (NodeName));
> + StrnCpyS (NewInternalData->NodeName, StrSize (NodeName), (CONST
> CHAR16
> + *)NodeName, StrLen (NodeName));  NewInternalData->SiblingList = NULL;
> +  NewInternalData->ChildList   = NULL;
> +  if ((NodeName[0] == (UINT16)NodeIsCollectionLeftBracket) &&
> +      (NodeName[StrLen (NodeName) - 1] ==
> + (UINT16)NodeIsCollectionRightBracket))
> +  {
> +    NewInternalData->Flags |=
> + REDFISH_FEATURE_INTERNAL_DATA_IS_COLLECTION;
> +  }
> +
> +  *PtrToNewInternalData = NewInternalData;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Insert the URI node into internal data structure
> +
> +  @param[in]        HeadEntryToInsert  The head entry to start the searching.
> +  @param[in]        NodeName           Name of URI node.
> +  @param[in, out]   NextNodeEntry      Pointer to receive the pointer of next
> head
> +                                       entry for inserting the follow up nodes.
> +                                       The returned LIST_ENTRY is the address of
> +                                       ChildList link list.
> +  @retval EFI_SUCCESS              New entry is inserted successfully.
> +  @retval EFI_INVALID_PARAMETER    Improper given parameters.
> +  @retval EFI_OUT_OF_RESOURCES     Lack of memory for the internal data
> structure.
> +
> +**/
> +EFI_STATUS
> +InsertRedfishFeatureUriNode (
> +  IN REDFISH_FEATURE_INTERNAL_DATA      *HeadEntryToInsert,
> +  IN EFI_STRING                         NodeName,
> +  IN OUT REDFISH_FEATURE_INTERNAL_DATA  **NextNodeEntry
> +  )
> +{
> +  EFI_STATUS                     Status;
> +  REDFISH_FEATURE_INTERNAL_DATA  *NewInternalData;
> +  REDFISH_FEATURE_INTERNAL_DATA  *ThisInternalData;
> +  REDFISH_FEATURE_INTERNAL_DATA  *SiblingList;
> +
> +  if (NodeName == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Node name is NULL.\n", __func__));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (NextNodeEntry == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: NextNodeEntry can't be NULL.\n", __func__));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if ((HeadEntryToInsert == NULL) || (HeadEntryToInsert->ChildList == NULL)) {
> +    Status = NewInternalInstance (&NewInternalData, NodeName);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    if (HeadEntryToInsert == NULL) {
> +      ResourceUriNodeList = NewInternalData;
> +    } else {
> +      HeadEntryToInsert->ChildList = NewInternalData;
> +    }
> +
> +    *NextNodeEntry = NewInternalData;
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Go through sibling list to find the entry.
> +  //
> +  ThisInternalData = HeadEntryToInsert;
> +  SiblingList      = ThisInternalData->SiblingList;
> +  while (TRUE) {
> +    if (StrCmp ((CONST CHAR16 *)ThisInternalData->NodeName, (CONST
> CHAR16 *)NodeName) == 0) {
> +      *NextNodeEntry = ThisInternalData->ChildList;
> +      return EFI_SUCCESS;
> +    }
> +
> +    //
> +    // If sibing exist?
> +    //
> +    if (SiblingList == NULL) {
> +      Status = NewInternalInstance (&NewInternalData, NodeName);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +
> +      ThisInternalData->SiblingList = NewInternalData;
> +      *NextNodeEntry                = NewInternalData->ChildList;
> +      return EFI_SUCCESS;
> +    }
> +
> +    SiblingList = SiblingList->SiblingList;  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The registration function for the Redfish Feature driver.
> +
> +  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL
> instance.
> +  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of
> the Redfish
> +                                   resource in the entire Redfish data model that managed
> +                                   by Redfish feature driver . Each node in the hierarchy
> +                                   path is the property name defined in the schema of the
> +                                   resource.
> +                                   e.g. "ServiceRoot/" - Managed by ServiceRoot feature
> driver
> +                                        "ServiceRoot/Systems[]/" - Managed by
> ComputerSystemCollection feature driver
> +                                        "ServiceRoot/Systems[1]/" - Managed by
> ComputerSystem feature driver
> +                                        "ServiceRoot/Systems[2]/Bios/" - Managed by Bios
> feature driver
> +  @param[in]   Callback            Callback routine associated with this registration
> that
> +                                   provided by Redfish feature driver to execute the action
> +                                   on Redfish resource which is managed by this Redfish
> +                                   feature driver.
> +  @param[in]   Context             The context of the registering feature driver. The
> pointer
> +                                   to the conext is delivered through callback function.
> +  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
> +  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
> +  @retval EFI_INVALID_PARAMETER    Improper given parameters or fail to
> register
> +                                   feature driver.
> +  @retval EFI_OUT_OF_RESOURCES     Lack of memory for the internal data
> structure.
> +  @retval Others                   Some error happened.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishFeatureRegister (
> +  IN EDKII_REDFISH_FEATURE_PROTOCOL  *This,
> +  IN EFI_STRING                      FeatureManagedUri,
> +  IN REDFISH_FEATURE_CALLBACK        Callback,
> +  IN VOID                            *Context
> +  )
> +{
> +  CHAR16                         NodeName[MaxNodeNameLength];
> +  EFI_STATUS                     Status;
> +  UINTN                          Index;
> +  UINTN                          AnchorIndex;
> +  UINTN                          UriLength;
> +  REDFISH_FEATURE_INTERNAL_DATA  *ThisUriNode;
> +
> +  if ((FeatureManagedUri == NULL) || (Callback == NULL)) {
> +    DEBUG ((DEBUG_ERROR, "%a: The given parameter is invalid\n", __func__));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Walk through URI which managed by this EDK2 Redfish feature driver.
> +  //
> +  UriLength   = StrLen (FeatureManagedUri) + 1; // Add one NULL for the last
> node.
> +  Index       = 0;
> +  AnchorIndex = 0;
> +  ThisUriNode = ResourceUriNodeList;
> +  do {
> +    if ((Index - AnchorIndex + 1) >= MaxNodeNameLength) {
> +      // Increase one for the NULL terminator
> +      DEBUG ((DEBUG_ERROR, "%a: the length of node name is >=
> MaxNodeNameLength\n", __func__));
> +      ASSERT (FALSE);
> +    }
> +
> +    NodeName[Index - AnchorIndex] = *(FeatureManagedUri + Index);
> +    if ((NodeName[Index - AnchorIndex] == NodeSeperator) ||
> (NodeName[Index - AnchorIndex] == (CHAR16)0)) {
> +      NodeName[Index - AnchorIndex] = 0;
> +      AnchorIndex                   = Index + 1;
> +      //
> +      // Insert node
> +      //
> +      if (StrLen (NodeName) != 0) {
> +        Status = InsertRedfishFeatureUriNode (ThisUriNode, NodeName,
> &ThisUriNode);
> +        if (EFI_ERROR (Status)) {
> +          return Status;
> +        }
> +      }
> +    }
> +
> +    Index++;
> +  } while ((Index < UriLength));
> +
> +  if (ThisUriNode == NULL) {
> +    //
> +    // No URI node was created
> +    //
> +    DEBUG ((DEBUG_ERROR, "%a: No URI node is added\n", __func__));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Add feature driver info to internal data instance.
> +  //
> +  ThisUriNode->Callback = Callback;
> +  ThisUriNode->Context  = Context;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The unregistration function for the Redfish Feature driver.
> +
> +  @param[in]   This                Pointer to EDKII_REDFISH_FEATURE_PROTOCOL
> instance.
> +  @param[in]   FeatureManagedUri   The URI represents the hierarchy path of
> the Redfish
> +                                   resource in the entire Redfish data model that managed
> +                                   by Redfish feature driver . Each node in the hierarchy
> +                                   path is the property name defined in the schema of the
> +                                   resource.
> +  @param[in]   Context             The context used for the previous feature driver
> +                                   registration.
> +  @retval EFI_SUCCESS              Redfish feature driver is registered successfully.
> +  @retval Others                   Some error happened.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishFeatureUnregister (
> +  IN     EDKII_REDFISH_FEATURE_PROTOCOL  *This,
> +  IN     EFI_STRING                      FeatureManagedUri,
> +  IN     VOID                            *Context
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EDKII_REDFISH_FEATURE_PROTOCOL  mRedfishFeatureProtocol = {
> +  RedfishFeatureRegister,
> +  RedfishFeatureUnregister
> +};
> +
> +/**
> +  Main entry for this driver.
> +
> +  @param[in] ImageHandle     Image handle this driver.
> +  @param[in] SystemTable     Pointer to SystemTable.
> +
> +  @retval EFI_SUCESS     This function always complete successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RedfishFeatureCoreEntryPoint (
> +  IN EFI_HANDLE        ImageHandle,
> +  IN EFI_SYSTEM_TABLE  *SystemTable
> +  )
> +{
> +  EFI_STATUS  Status;
> +  EFI_HANDLE  Handle;
> +  EFI_GUID    *EventGuid;
> +
> +  Handle              = NULL;
> +  ResourceUriNodeList = NULL;
> +  EventGuid           = (EFI_GUID *)PcdGetPtr
> (PcdEdkIIRedfishFeatureDriverStartupEventGuid);
> +
> +  ZeroMem ((VOID *)&mFeatureDriverStartupContext, sizeof
> + (REDFISH_FEATURE_STARTUP_CONTEXT));
> +  mFeatureDriverStartupContext.This = &mRedfishFeatureProtocol;
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  RedfishFeatureDriverStartup,
> +                  (CONST VOID *)&mFeatureDriverStartupContext,
> +                  EventGuid,
> +                  &mEdkIIRedfishFeatureDriverStartupEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Install the RedfishCredentialProtocol onto Handle.
> +  //
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gEdkIIRedfishFeatureProtocolGuid,
> +                  &mRedfishFeatureProtocol,
> +                  NULL
> +                  );
> +  return Status;
> +}
> diff --git a/RedfishClientPkg/Readme.md b/RedfishClientPkg/Readme.md index
> 9e56fb9039..18a27633cf 100644
> --- a/RedfishClientPkg/Readme.md
> +++ b/RedfishClientPkg/Readme.md
> @@ -119,6 +119,42 @@ struct
> _EDKII_REDFISH_PLATFORM_CONFIG_PROTOCOL {  For those Non-EDK2 HII-
> based platform configuration formats, the driver instance  can provide its own
> implementation to get or set the platform configurations.
> 
> +### EDKII Redfish Feature Core DXE Driver ***[[12]](#[0])*** EDKII
> +Redfish Feature Core DXE driver provides the protocol interface to the
> +auto-generated Redfish feature driver to register itself for the
> +Redfish resource URI it manages.
> +
> +```C
> +struct _EDKII_REDFISH_FEATURE_PROTOCOL {
> +  REDFISH_FEATURE_REGISTER      Register;
> +  REDFISH_FEATURE_UNREGISTER    Unregister;
> +};
> +```
> +
> +Redfish Feature Core DXE driver records the URI according to the URI
> +hierarchy, and then it starts up the Redfish feature drivers based on
> +the hierarchy when the particular event
> +***[[11]](#[0])*** is triggered. This makes sure the upper-level
> +Redfish resource is built up before the lower-level resource. For
> +example, ComputerSystem resource must be ready before the Memory
> +resource managed by MemoryCollection because the Memory resource is
> +part of ComputerSystem resource.
> +
> +### Start-Up Event to Trigger EDKII Redfish Feature Core
> +***[[11]](#[0])*** This is an EFI event for triggering EDKII Redfish
> +Feature Core to travel URIs in the database and execute the callback
> +that registered by Redfish feature drivers. The event GUID is defined
> +in below PCD and is default set to **gEfiEventReadyToBootGuid**.
> +
> +```C
> +PcdEdkIIRedfishFeatureDriverStartupEventGuid
> +```
> +
> +This PCD can be overridden to any events based on the platform
> +implementation. EDKII Redfish Feature Core can be triggered earlier,
> +for example before the BDS or in the early DXE phase if the platform
> +provides the EFI REST EX protocol which is available before the BDS phase.
> +
>  ### EDK2 HII VFR Form ***[[8]](#[0])***  According to **UEFI spec 2.9 section
> 35.6 Form Browser Protocol**,
>  **EFI_HII_REST_STYLE_FORMSET_GUID** is used on HII form to indicate that
> HII
> --
> 2.37.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103891): https://edk2.groups.io/g/devel/message/103891
Mute This Topic: https://groups.io/mt/98657046/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-