From: Narinder Dhillon <ndhil...@marvell.com>

This patch adds a device tree driver that is used to read board
configuration information from a device tree.

Signed-off-by: Narinder Dhillon <ndhil...@marvell.com>
---
 .../Drivers/Fdt/FdtClientDxe/FdtClientDxe.c   | 382 ++++++++++++++++++
 .../Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf |  43 ++
 .../Include/Protocol/FdtClient.h              | 180 +++++++++
 3 files changed, 605 insertions(+)
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c
 create mode 100644 Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
 create mode 100644 
Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h

diff --git a/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c 
b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c
new file mode 100644
index 0000000000..8741a41e46
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.c
@@ -0,0 +1,382 @@
+/** @file
+*  FDT client driver
+*
+*  Copyright (c) 2016, Cavium Inc. All rights reserved.<BR>
+*  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <libfdt.h>
+
+#include <Guid/FdtHob.h>
+
+#include <Protocol/FdtClient.h>
+
+STATIC VOID  *mDeviceTreeBase;
+
+STATIC
+EFI_STATUS
+GetNodeProperty (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  IN  CONST CHAR8               *PropertyName,
+  OUT CONST VOID                **Prop,
+  OUT UINT32                    *PropSize OPTIONAL
+  )
+{
+  INT32 Len;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Prop != NULL);
+
+  *Prop = fdt_getprop (mDeviceTreeBase, Node, PropertyName, &Len);
+  if (*Prop == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (PropSize != NULL) {
+    *PropSize = Len;
+  }
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SetNodeProperty (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  IN  CONST CHAR8               *PropertyName,
+  IN  CONST VOID                *Prop,
+  IN  UINT32                    PropSize
+  )
+{
+  INT32 Ret;
+
+  ASSERT (mDeviceTreeBase != NULL);
+
+  Ret = fdt_setprop (mDeviceTreeBase, Node, PropertyName, Prop, PropSize);
+  if (Ret != 0) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+EFIAPI
+FindCompatibleNode (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST CHAR8               *CompatibleString,
+  IN  FDT_HANDLE                PrevNode,
+  OUT FDT_HANDLE                *Node
+  )
+{
+  FDT_HANDLE  Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_node_offset_by_compatible (mDeviceTreeBase, PrevNode, 
CompatibleString);
+
+  if (Offset < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetOrInsertChosenNode (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  OUT INT32                     *Node
+  )
+{
+  INT32 NewNode;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  NewNode = fdt_path_offset (mDeviceTreeBase, "/chosen");
+
+  if (NewNode < 0) {
+    NewNode = fdt_add_subnode (mDeviceTreeBase, 0, "/chosen");
+  }
+
+  if (NewNode < 0) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *Node = NewNode;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNodeDepth (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  OUT INT32                     *Depth
+)
+{
+  *Depth = fdt_node_depth (mDeviceTreeBase, Node);
+
+  if (*Depth < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetParentNode (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  OUT FDT_HANDLE                *Parent
+)
+{
+  *Parent = fdt_parent_offset (mDeviceTreeBase, Node);
+
+  if (*Parent < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNode (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST CHAR8               *Path,
+  OUT FDT_HANDLE                *Node
+)
+{
+  *Node = fdt_path_offset (mDeviceTreeBase, Path);
+
+  if (*Node < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNodePath (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Node,
+  OUT CHAR8                     *Path,
+  IN  INT32                     Size
+)
+{
+  INT32 Result;
+
+  Result = fdt_get_path (mDeviceTreeBase, Node, Path, Size);
+
+  if (Result < 0) {
+    return EFI_NOT_FOUND;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNodeByPropertyValue (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          StartNode,
+  IN  CHAR8                     *Property,
+  IN  VOID                      *Value,
+  IN  INT32                     Size,
+  OUT FDT_HANDLE                *Node
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_node_offset_by_prop_value (mDeviceTreeBase, StartNode,
+                                          Property, Value,
+                                          Size);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetSubnodeByPropertyValue(
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Parent,
+  IN  CHAR8                     *PropertyName,
+  IN  VOID                      *PropertyValue,
+  IN  INT32                     PropertyLength,
+  OUT FDT_HANDLE                *Node
+)
+{
+  INT32          Offset;
+  CONST VOID     *Property;
+  INT32          Length;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_first_subnode (mDeviceTreeBase, Parent);
+
+  while (Offset > 0) {
+    Property = fdt_getprop (mDeviceTreeBase, Offset, PropertyName, &Length);
+
+    if ((Property != NULL) &&
+        (PropertyLength == Length) &&
+        (CompareMem (Property, PropertyValue, Length) == 0)) {
+      *Node = Offset;
+      return EFI_SUCCESS;
+    }
+
+    Offset = fdt_next_subnode(mDeviceTreeBase, Offset);
+  }
+
+  return EFI_NOT_FOUND;
+}
+
+STATIC
+EFI_STATUS
+GetNodeByPHandle (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          PHandle,
+  OUT FDT_HANDLE                *Node
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_node_offset_by_phandle (mDeviceTreeBase, PHandle);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetFirstSubnode (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Parent,
+  OUT FDT_HANDLE                *Node
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Node != NULL);
+
+  Offset = fdt_first_subnode (mDeviceTreeBase, Parent);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Node = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+GetNextSubnode (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Subnode,
+  OUT FDT_HANDLE                *Next
+)
+{
+  INT32          Offset;
+
+  ASSERT (mDeviceTreeBase != NULL);
+  ASSERT (Next != NULL);
+
+  Offset = fdt_next_subnode (mDeviceTreeBase, Subnode);
+
+  if (Offset < 0) {
+    DEBUG ((DEBUG_ERROR, "Result: %d\n", Offset));
+    return EFI_NOT_FOUND;
+  }
+
+  *Next = Offset;
+
+  return EFI_SUCCESS;
+}
+
+STATIC MRVL_FDT_CLIENT_PROTOCOL mFdtClientProtocol = {
+  GetNodeProperty,
+  SetNodeProperty,
+  FindCompatibleNode,
+  GetOrInsertChosenNode,
+  GetNodeDepth,
+  GetParentNode,
+  GetNode,
+  GetNodePath,
+  GetNodeByPropertyValue,
+  GetSubnodeByPropertyValue,
+  GetNodeByPHandle,
+  GetFirstSubnode,
+  GetNextSubnode
+};
+
+EFI_STATUS
+EFIAPI
+InitializeFdtClientDxe (
+  IN EFI_HANDLE           ImageHandle,
+  IN EFI_SYSTEM_TABLE     *SystemTable
+  )
+{
+  VOID              *Hob;
+  VOID              *DeviceTreeBase;
+
+  Hob = GetFirstGuidHob (&gFdtHobGuid);
+
+  if (Hob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+
+  DeviceTreeBase = GET_GUID_HOB_DATA (Hob);
+  mDeviceTreeBase = (VOID *)*(UINT64 *)DeviceTreeBase;
+  if (fdt_check_header (mDeviceTreeBase)) {
+    DEBUG ((DEBUG_ERROR, "No DTB found @ 0x%p\n", DeviceTreeBase));
+    return EFI_NOT_FOUND;
+  }
+
+  DEBUG ((DEBUG_INFO, "DTB @ 0x%p\n", mDeviceTreeBase));
+
+  return gBS->InstallMultipleProtocolInterfaces (&ImageHandle,
+                                        &gMrvlFdtClientProtocolGuid, 
&mFdtClientProtocol,
+                                        NULL);
+}
diff --git a/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf 
b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
new file mode 100644
index 0000000000..26362344f7
--- /dev/null
+++ b/Silicon/Marvell/Drivers/Fdt/FdtClientDxe/FdtClientDxe.inf
@@ -0,0 +1,43 @@
+## @file
+#  FDT client driver
+#
+#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = FdtClientDxe
+  FILE_GUID                      = 9A871B00-1C16-4F61-8D2C-93B6654B5AD6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeFdtClientDxe
+
+[Sources]
+  FdtClientDxe.c
+
+[Packages]
+  Silicon/Marvell/MarvellSiliconPkg/MarvellSiliconPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  FdtLib
+  HobLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gMrvlFdtClientProtocolGuid                  ## PRODUCES
+
+[Guids]
+  gFdtHobGuid
+  gFdtTableGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h 
b/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h
new file mode 100644
index 0000000000..38480c8831
--- /dev/null
+++ b/Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/FdtClient.h
@@ -0,0 +1,180 @@
+/** @file
+
+  DISCLAIMER: the FDT_CLIENT_PROTOCOL introduced here is a work in progress,
+  and should not be used outside of the EDK II tree.
+
+  Copyright (C) 2023 Marvell
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FDT_CLIENT_H__
+#define __FDT_CLIENT_H__
+
+#define FDT_CLIENT_PROTOCOL_GUID { \
+  0xE11FACA0, 0x4710, 0x4C8E, {0xA7, 0xA2, 0x01, 0xBA, 0xA2, 0x59, 0x1B, 0x4C} 
\
+  }
+
+#define FdtToCpu32(Value) SwapBytes32(Value)
+#define CpuToFdt32(Value) SwapBytes32(Value)
+
+#define FdtToCpu64(Value) SwapBytes64(Value)
+#define CpuToFdt64(Value) SwapBytes64(Value)
+
+//
+// Protocol interface structure
+//
+typedef int FDT_HANDLE;
+#define FDT_START_HANDLE -1
+typedef struct _MRVL_FDT_CLIENT_PROTOCOL MRVL_FDT_CLIENT_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_NODE_PROPERTY) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  IN  CONST CHAR8               *PropertyName,
+  OUT CONST VOID                **Prop,
+  OUT UINT32                    *PropSize OPTIONAL
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_SET_NODE_PROPERTY) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  IN  CONST CHAR8               *PropertyName,
+  IN  CONST VOID                *Prop,
+  IN  UINT32                    PropSize
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_FIND_COMPATIBLE_NODE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST CHAR8               *CompatibleString,
+  IN  FDT_HANDLE                PrevNode,
+  OUT FDT_HANDLE                *Node
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_FIND_COMPATIBLE_NODE_PROPERTY) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST CHAR8               *CompatibleString,
+  IN  CONST CHAR8               *PropertyName,
+  OUT CONST VOID                **Prop,
+  OUT UINT32                    *PropSize OPTIONAL
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  OUT FDT_HANDLE                *Node
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_NODE_DEPTH) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  OUT FDT_HANDLE                *Depth
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_PARENT_NODE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  FDT_HANDLE                Node,
+  OUT FDT_HANDLE                *Parent
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_NODE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST CHAR8               *Path,
+  OUT FDT_HANDLE                *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_NODE_PATH) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Node,
+  OUT CHAR8                     *Path,
+  IN  INT32                     Size
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          StartNode,
+  IN  CHAR8                     *Property,
+  IN  VOID                      *Value,
+  IN  INT32                     Size,
+  OUT FDT_HANDLE                *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Parent,
+  IN  CHAR8                     *PropertyName,
+  IN  VOID                      *PropertyValue,
+  IN  INT32                     PropertyLength,
+  OUT FDT_HANDLE                *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_NODE_BY_PHANDLE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          PHandle,
+  OUT FDT_HANDLE                *Node
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_FIRST_SUBNODE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Parent,
+  OUT FDT_HANDLE                *Node
+  );
+
+typedef
+EFI_STATUS
+(EFIAPI *MRVL_FDT_CLIENT_GET_NEXT_SUBNODE) (
+  IN  MRVL_FDT_CLIENT_PROTOCOL  *This,
+  IN  CONST FDT_HANDLE          Subnode,
+  OUT FDT_HANDLE                *Next
+  );
+
+struct _MRVL_FDT_CLIENT_PROTOCOL {
+  MRVL_FDT_CLIENT_GET_NODE_PROPERTY             GetNodeProperty;
+  MRVL_FDT_CLIENT_SET_NODE_PROPERTY             SetNodeProperty;
+
+  MRVL_FDT_CLIENT_FIND_COMPATIBLE_NODE          FindCompatibleNode;
+
+  MRVL_FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE     GetOrInsertChosenNode;
+
+  MRVL_FDT_CLIENT_GET_NODE_DEPTH                GetNodeDepth;
+  MRVL_FDT_CLIENT_GET_PARENT_NODE               GetParentNode;
+  MRVL_FDT_CLIENT_GET_NODE                      GetNode;
+  MRVL_FDT_CLIENT_GET_NODE_PATH                 GetNodePath;
+  MRVL_FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE    GetNodeByPropertyValue;
+  MRVL_FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE GetSubnodeByPropertyValue;
+  MRVL_FDT_CLIENT_GET_NODE_BY_PHANDLE           GetNodeByPHandle;
+  MRVL_FDT_CLIENT_GET_FIRST_SUBNODE             GetFirstSubnode;
+  MRVL_FDT_CLIENT_GET_NEXT_SUBNODE              GetNextSubnode;
+
+};
+
+extern EFI_GUID gMrvlFdtClientProtocolGuid;
+
+#endif
-- 
2.34.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118572): https://edk2.groups.io/g/devel/message/118572
Mute This Topic: https://groups.io/mt/105913429/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to