+marcin.s.woj...@gmail.com Hi Narinder,
czw., 21 gru 2023 o 01:54 Narinder Dhillon <ndhil...@marvell.com> napisaĆ(a): > > 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..aa4f773458 > --- /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 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 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 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 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 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 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 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 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 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 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 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 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 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 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, > + &gFdtClientProtocolGuid, > &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..23bcf8810f > --- /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] > + gFdtClientProtocolGuid ## 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..dd9af0bf8f > --- /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 _FDT_CLIENT_PROTOCOL FDT_CLIENT_PROTOCOL; > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_NODE_PROPERTY) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN FDT_HANDLE Node, > + IN CONST CHAR8 *PropertyName, > + OUT CONST VOID **Prop, > + OUT UINT32 *PropSize OPTIONAL > + ); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_SET_NODE_PROPERTY) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN FDT_HANDLE Node, > + IN CONST CHAR8 *PropertyName, > + IN CONST VOID *Prop, > + IN UINT32 PropSize > + ); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_FIND_COMPATIBLE_NODE) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN CONST CHAR8 *CompatibleString, > + IN FDT_HANDLE PrevNode, > + OUT FDT_HANDLE *Node > + ); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_FIND_COMPATIBLE_NODE_PROPERTY) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN CONST CHAR8 *CompatibleString, > + IN CONST CHAR8 *PropertyName, > + OUT CONST VOID **Prop, > + OUT UINT32 *PropSize OPTIONAL > + ); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE) ( > + IN FDT_CLIENT_PROTOCOL *This, > + OUT FDT_HANDLE *Node > + ); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_NODE_DEPTH) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN FDT_HANDLE Node, > + OUT FDT_HANDLE *Depth > +); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_PARENT_NODE) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN FDT_HANDLE Node, > + OUT FDT_HANDLE *Parent > +); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_NODE) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN CONST CHAR8 *Path, > + OUT FDT_HANDLE *Node > +); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_NODE_PATH) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN CONST FDT_HANDLE Node, > + OUT CHAR8 *Path, > + IN INT32 Size > +); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE) ( > + IN 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 *FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE) ( > + IN 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 *FDT_CLIENT_GET_NODE_BY_PHANDLE) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN CONST FDT_HANDLE PHandle, > + OUT FDT_HANDLE *Node > +); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_FIRST_SUBNODE) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN CONST FDT_HANDLE Parent, > + OUT FDT_HANDLE *Node > + ); > + > +typedef > +EFI_STATUS > +(EFIAPI *FDT_CLIENT_GET_NEXT_SUBNODE) ( > + IN FDT_CLIENT_PROTOCOL *This, > + IN CONST FDT_HANDLE Subnode, > + OUT FDT_HANDLE *Next > + ); > + > +struct _FDT_CLIENT_PROTOCOL { > + FDT_CLIENT_GET_NODE_PROPERTY GetNodeProperty; > + FDT_CLIENT_SET_NODE_PROPERTY SetNodeProperty; > + > + FDT_CLIENT_FIND_COMPATIBLE_NODE FindCompatibleNode; > + > + FDT_CLIENT_GET_OR_INSERT_CHOSEN_NODE GetOrInsertChosenNode; > + > + FDT_CLIENT_GET_NODE_DEPTH GetNodeDepth; > + FDT_CLIENT_GET_PARENT_NODE GetParentNode; > + FDT_CLIENT_GET_NODE GetNode; > + FDT_CLIENT_GET_NODE_PATH GetNodePath; > + FDT_CLIENT_GET_NODE_BY_PROPERTY_VALUE GetNodeByPropertyValue; > + FDT_CLIENT_GET_SUBNODE_BY_PROPERTY_VALUE GetSubnodeByPropertyValue; > + FDT_CLIENT_GET_NODE_BY_PHANDLE GetNodeByPHandle; > + FDT_CLIENT_GET_FIRST_SUBNODE GetFirstSubnode; > + FDT_CLIENT_GET_NEXT_SUBNODE GetNextSubnode; > + Please make the namespace less generic, and use MARVELL_/MV_ prefixes - see other Silicon/Marvell/MarvellSiliconPkg/Include/Protocol/*.h for reference. Best regards, Marcin -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#113724): https://edk2.groups.io/g/devel/message/113724 Mute This Topic: https://groups.io/mt/103292514/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-