From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web10.52882.1682346294099117054 for ; Mon, 24 Apr 2023 07:24:54 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=FpXb4mAI; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: benny.lin@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1682346294; x=1713882294; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cmFf68bmYnUr64J2tXxlxD4TTmjLXJS2dfC+NW3W9W0=; b=FpXb4mAIkBrMcBFFR2gyxpYPUfZlPgMFV15fuo79ycLMOVkyXV2cM5v0 uDRKpM9FEOtQzFIizhcCEcLOVioNcseQ//chR7UvIiB8W2AK1xyW82HbP DNt0BWE73U2+4aDlgxjIpZjlX+eHZOZHnp8M49SlKAbcaN2CRXwnNXBeh 7Ow2dpFvqPp/tshx341rGe2JU0GJ6hQzd6tbXHD2be1UvbBfX3d99CM96 7NPmV7gPzGXACWM4Omp+Jtz2tLm2jzLrOEw2eQemMLxoGlByy6nmg4uBW QoG9CUhLIksaFqt86bs/sTDbzN6sgJNrpRDCCjFo3L/x3UbfAPQ0x9c4M g==; X-IronPort-AV: E=McAfee;i="6600,9927,10690"; a="345218029" X-IronPort-AV: E=Sophos;i="5.99,222,1677571200"; d="scan'208";a="345218029" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2023 07:24:40 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10690"; a="939348557" X-IronPort-AV: E=Sophos;i="5.99,222,1677571200"; d="scan'208";a="939348557" Received: from bennyli1-mobl2.gar.corp.intel.com ([10.252.191.74]) by fmsmga006-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 24 Apr 2023 07:24:39 -0700 From: "Benny Lin" To: devel@edk2.groups.io Cc: Benny Lin , Michael D Kinney , Liming Gao , Zhiguang Liu , Pedro Falcato Subject: [PATCH v4 2/3] MdePkg: Support FDT library. Date: Mon, 24 Apr 2023 22:24:26 +0800 Message-Id: <20230424142427.397-3-benny.lin@intel.com> X-Mailer: git-send-email 2.39.1.windows.1 In-Reply-To: <20230424142427.397-1-benny.lin@intel.com> References: <20230424142427.397-1-benny.lin@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Benny Lin REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4392 Add FDT support in EDK2 by submodule 3rd party libfdt (https://github.com/devicetree-org/pylibfdt/tree/main/libfdt) and refer to LibcLib implementation by Pedro. Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Acked-by: Pedro Falcato Signed-off-by: Benny Lin --- MdePkg/Include/Library/FdtLib.h | 305 ++++++++++++++++++++ MdePkg/Library/BaseFdtLib/BaseFdtLib.inf | 62 ++++ MdePkg/Library/BaseFdtLib/BaseFdtLib.uni | 14 + MdePkg/Library/BaseFdtLib/FdtLib.c | 301 +++++++++++++++++++ MdePkg/Library/BaseFdtLib/LibFdtSupport.h | 99 +++++++ MdePkg/Library/BaseFdtLib/LibFdtWrapper.c | 173 +++++++++++ MdePkg/Library/BaseFdtLib/limits.h | 10 + MdePkg/Library/BaseFdtLib/stdbool.h | 10 + MdePkg/Library/BaseFdtLib/stddef.h | 10 + MdePkg/Library/BaseFdtLib/stdint.h | 10 + MdePkg/Library/BaseFdtLib/stdlib.h | 10 + MdePkg/Library/BaseFdtLib/string.h | 10 + MdePkg/MdePkg.ci.yaml | 15 +- MdePkg/MdePkg.dec | 4 + MdePkg/MdePkg.dsc | 1 + 15 files changed, 1033 insertions(+), 1 deletion(-) diff --git a/MdePkg/Include/Library/FdtLib.h b/MdePkg/Include/Library/FdtLi= b.h new file mode 100644 index 0000000000..8c540b2b1d --- /dev/null +++ b/MdePkg/Include/Library/FdtLib.h @@ -0,0 +1,305 @@ +/** @file=0D + Flattened Device Tree Library.=0D +=0D + Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef FDT_LIB_H_=0D +#define FDT_LIB_H_=0D +=0D +/**=0D + Flattened Device Tree definition=0D +=0D + The Devicetree Blob (DTB) format is a binary encoding with big-endian.=0D + When producing or consuming the blob data, must translate with SwapBytes= XX=0D + provided by edk2 BaseLib between big-endian and little-endian.=0D +**/=0D +typedef struct {=0D + UINT32 Magic; /* magic word FDT_MAGIC */=0D + UINT32 TotalSize; /* total size of DT block */=0D + UINT32 OffsetDtStruct; /* offset to structure */=0D + UINT32 OffsetDtStrings; /* offset to strings */=0D + UINT32 OffsetMemRsvmap; /* offset to memory reserve map */=0D + UINT32 Version; /* format version */=0D + UINT32 LastCompVersion; /* last compatible version */=0D +=0D + /* version 2 fields below */=0D + UINT32 BootCpuidPhys; /* Which physical CPU id we're=0D + booting on */=0D + /* version 3 fields below */=0D + UINT32 SizeDtStrings; /* size of the strings block */=0D +=0D + /* version 17 fields below */=0D + UINT32 SizeDtStruct; /* size of the structure block */=0D +} FDT_HEADER;=0D +=0D +typedef struct {=0D + UINT64 Address;=0D + UINT64 Size;=0D +} FDT_RESERVE_ENTRY;=0D +=0D +typedef struct {=0D + UINT32 Tag;=0D + CHAR8 Name[];=0D +} FDT_NODE_HEADER;=0D +=0D +typedef struct {=0D + UINT32 Tag;=0D + UINT32 Length;=0D + UINT32 NameOffset;=0D + CHAR8 Data[];=0D +} FDT_PROPERTY;=0D +=0D +/**=0D + Verify the header of the Flattened Device Tree=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D +=0D + @return Zero for successfully, otherwise failed.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtCheckHeader (=0D + IN CONST VOID *Fdt=0D + );=0D +=0D +/**=0D + Create a empty Flattened Device Tree.=0D +=0D + @param[in] Buffer The pointer to allocate a pool for FDT blob.=0D + @param[in] BufferSize The BufferSize to the pool size.=0D +=0D + @return Zero for successfully, otherwise failed.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +FdtCreateEmptyTree (=0D + IN VOID *Buffer,=0D + IN UINTN BufferSize=0D + );=0D +=0D +/**=0D + Returns a offset of next node from the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous node.=0D + @param[in] Depth The depth to the level of tree hierarchy.=0D +=0D + @return The offset to next node offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNextNode (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset,=0D + IN INT32 *Depth=0D + );=0D +=0D +/**=0D + Returns a offset of first node under the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous node.=0D +=0D + @return The offset to next node offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtFirstSubnode (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset=0D + );=0D +=0D +/**=0D + Returns a offset of next node from the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous node.=0D +=0D + @return The offset to next node offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNextSubnode (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset=0D + );=0D +=0D +/**=0D + Returns a offset of first node which includes the given name.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] ParentOffset The offset to the node which start find under= .=0D + @param[in] Name The name to search the node with the name.=0D + @param[in] NameLength The length of the name to check only.=0D +=0D + @return The offset to node offset with given node name.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtSubnodeOffsetNameLen (=0D + IN CONST VOID *Fdt,=0D + IN INT32 ParentOffset,=0D + IN CONST CHAR8 *Name,=0D + IN INT32 NameLength=0D + );=0D +=0D +/**=0D + Returns a offset of first node which includes the given property name an= d value.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] StartOffset The offset to the starting node to find.=0D + @param[in] PropertyName The property name to search the node includin= g the named property.=0D + @param[in] PropertyValue The property value to check the same property= value.=0D + @param[in] PropertyLength The length of the value in PropertValue.=0D +=0D + @return The offset to node offset with given property.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNodeOffsetByPropValue (=0D + IN CONST VOID *Fdt,=0D + IN INT32 StartOffset,=0D + IN CONST CHAR8 *PropertyName,=0D + IN CONST VOID *PropertyValue,=0D + IN INT32 PropertyLength=0D + );=0D +=0D +/**=0D + Returns a property with the given name from the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] NodeOffset The offset to the given node.=0D + @param[in] Name The name to the property which need be searche= d=0D + @param[in] Length The length to the size of the property found.= =0D +=0D + @return The property to the structure of the found property.=0D +=0D +**/=0D +CONST FDT_PROPERTY *=0D +EFIAPI=0D +FdtGetProperty (=0D + IN CONST VOID *Fdt,=0D + IN INT32 NodeOffset,=0D + IN CONST CHAR8 *Name,=0D + IN INT32 *Length=0D + );=0D +=0D +/**=0D + Returns a offset of first property in the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to the node which need be searched.= =0D +=0D + @return The offset to first property offset in the given node.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtFirstPropertyOffset (=0D + IN CONST VOID *Fdt,=0D + IN INT32 NodeOffset=0D + );=0D +=0D +/**=0D + Returns a offset of next property from the given property.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous property.=0D +=0D + @return The offset to next property offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNextPropertyOffset (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset=0D + );=0D +=0D +/**=0D + Returns a property from the given offset of the property.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to the given offset of the property= .=0D + @param[in] Length The length to the size of the property found.= =0D +=0D + @return The property to the structure of the given property offset.=0D +=0D +**/=0D +CONST FDT_PROPERTY *=0D +EFIAPI=0D +FdtGetPropertyByOffset (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset,=0D + IN INT32 *Length=0D + );=0D +=0D +/**=0D + Returns a string by the given string offset.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] StrOffset The offset to the location in the strings bloc= k of FDT.=0D + @param[in] Length The length to the size of string which need be= retrieved.=0D +=0D + @return The string to the given string offset.=0D +=0D +**/=0D +CONST CHAR8 *=0D +EFIAPI=0D +FdtGetString (=0D + IN CONST VOID *Fdt,=0D + IN INT32 StrOffset,=0D + IN INT32 *Length OPTIONAL=0D + );=0D +=0D +/**=0D + Add a new node to the FDT.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] ParentOffset The offset to the node offset which want to ad= d in.=0D + @param[in] Name The name to name the node.=0D +=0D + @return The offset to the new node.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtAddSubnode (=0D + IN VOID *Fdt,=0D + IN INT32 ParentOffset,=0D + IN CONST CHAR8 *Name=0D + );=0D +=0D +/**=0D + Add or modify a property in the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] NodeOffset The offset to the node offset which want to ad= d in.=0D + @param[in] Name The name to name the property.=0D + @param[in] Value The value to the property value.=0D + @param[in] Length The length to the size of the property.=0D +=0D + @return Zero for successfully, otherwise failed.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtSetProp (=0D + IN VOID *Fdt,=0D + IN INT32 NodeOffset,=0D + IN CONST CHAR8 *Name,=0D + IN CONST VOID *Value,=0D + IN UINT32 Length=0D + );=0D +=0D +#endif /* FDT_LIB_H_ */=0D diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf b/MdePkg/Library/Base= FdtLib/BaseFdtLib.inf new file mode 100644 index 0000000000..730e568ff6 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf @@ -0,0 +1,62 @@ +## @file=0D +# Flattened Device Tree Library.=0D +#=0D +# Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 0x0001001B=0D + BASE_NAME =3D BaseFdtLib=0D + MODULE_UNI_FILE =3D BaseFdtLib.uni=0D + FILE_GUID =3D C64DCB01-B037-4FF6-9CF3-E8CEC206DE04= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D FdtLib=0D +=0D + DEFINE FDT_LIB_PATH =3D libfdt/libfdt=0D +=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64=0D +#=0D +=0D +[Sources]=0D + FdtLib.c=0D + LibFdtWrapper.c=0D + # header Wrapper files=0D + limits.h=0D + stdbool.h=0D + stddef.h=0D + stdint.h=0D + stdlib.h=0D + string.h=0D +=0D + $(FDT_LIB_PATH)/fdt.c=0D + $(FDT_LIB_PATH)/fdt.h=0D + $(FDT_LIB_PATH)/fdt_addresses.c=0D + $(FDT_LIB_PATH)/fdt_check.c=0D + $(FDT_LIB_PATH)/fdt_empty_tree.c=0D + $(FDT_LIB_PATH)/fdt_overlay.c=0D + $(FDT_LIB_PATH)/fdt_ro.c=0D + $(FDT_LIB_PATH)/fdt_rw.c=0D + $(FDT_LIB_PATH)/fdt_strerror.c=0D + $(FDT_LIB_PATH)/fdt_sw.c=0D + $(FDT_LIB_PATH)/fdt_wip.c=0D + $(FDT_LIB_PATH)/libfdt.h=0D + $(FDT_LIB_PATH)/libfdt_env.h=0D + $(FDT_LIB_PATH)/libfdt_internal.h=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + BaseMemoryLib=0D +=0D +[BuildOptions]=0D + MSFT:*_*_IA32_CC_FLAGS =3D /wd4146 /wd4245=0D + MSFT:*_*_X64_CC_FLAGS =3D /wd4146 /wd4244 /wd4245 /wd4267=0D +=0D diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni b/MdePkg/Library/Base= FdtLib/BaseFdtLib.uni new file mode 100644 index 0000000000..3f7e45ea6f --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni @@ -0,0 +1,14 @@ +// /** @file=0D +// Flattened Device Tree Library.=0D +//=0D +// Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +//=0D +// SPDX-License-Identifier: BSD-2-Clause-Patent=0D +//=0D +// **/=0D +=0D +=0D +#string STR_MODULE_ABSTRACT #language en-US "Instance of FDT L= ibrary"=0D +=0D +#string STR_MODULE_DESCRIPTION #language en-US "This module provi= des FDT Library implementation."=0D +=0D diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c b/MdePkg/Library/BaseFdtLib= /FdtLib.c new file mode 100644 index 0000000000..ba95b41007 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/FdtLib.c @@ -0,0 +1,301 @@ +/** @file=0D + Flattened Device Tree Library.=0D +=0D + Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D +/**=0D + Verify the header of the Flattened Device Tree=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D +=0D + @return Zero for successfully, otherwise failed.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtCheckHeader (=0D + IN CONST VOID *Fdt=0D + )=0D +{=0D + return fdt_check_header (Fdt);=0D +}=0D +=0D +/**=0D + Create a empty Flattened Device Tree.=0D +=0D + @param[in] Buffer The pointer to allocate a pool for FDT blob.=0D + @param[in] BufferSize The BufferSize to the pool size.=0D +=0D + @return Zero for successfully, otherwise failed.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtCreateEmptyTree (=0D + IN VOID *Buffer,=0D + IN UINT32 BufferSize=0D + )=0D +{=0D + return fdt_create_empty_tree (Buffer, (int)BufferSize);=0D +}=0D +=0D +/**=0D + Returns a offset of next node from the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous node.=0D + @param[in] Depth The depth to the level of tree hierarchy.=0D +=0D + @return The offset to next node offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNextNode (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset,=0D + IN INT32 *Depth=0D + )=0D +{=0D + return fdt_next_node (Fdt, Offset, Depth);=0D +}=0D +=0D +/**=0D + Returns a offset of first node under the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous node.=0D +=0D + @return The offset to next node offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtFirstSubnode (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset=0D + )=0D +{=0D + return fdt_first_subnode (Fdt, Offset);=0D +}=0D +=0D +/**=0D + Returns a offset of next node from the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous node.=0D +=0D + @return The offset to next node offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNextSubnode (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset=0D + )=0D +{=0D + return fdt_next_subnode (Fdt, Offset);=0D +}=0D +=0D +/**=0D + Returns a offset of first node which includes the given name.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] ParentOffset The offset to the node which start find under= .=0D + @param[in] Name The name to search the node with the name.=0D + @param[in] NameLength The length of the name to check only.=0D +=0D + @return The offset to node offset with given node name.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtSubnodeOffsetNameLen (=0D + IN CONST VOID *Fdt,=0D + IN INT32 ParentOffset,=0D + IN CONST CHAR8 *Name,=0D + IN INT32 NameLength=0D + )=0D +{=0D + return fdt_subnode_offset_namelen (Fdt, ParentOffset, Name, NameLength);= =0D +}=0D +=0D +/**=0D + Returns a offset of first node which includes the given property name an= d value.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] StartOffset The offset to the starting node to find.=0D + @param[in] PropertyName The property name to search the node includin= g the named property.=0D + @param[in] PropertyValue The property value to check the same property= value.=0D + @param[in] PropertyLength The length of the value in PropertValue.=0D +=0D + @return The offset to node offset with given property.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNodeOffsetByPropValue (=0D + IN CONST VOID *Fdt,=0D + IN INT32 StartOffset,=0D + IN CONST CHAR8 *PropertyName,=0D + IN CONST VOID *PropertyValue,=0D + IN INT32 PropertyLength=0D + )=0D +{=0D + return fdt_node_offset_by_prop_value (Fdt, StartOffset, PropertyName, Pr= opertyValue, PropertyLength);=0D +}=0D +=0D +/**=0D + Returns a property with the given name from the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] NodeOffset The offset to the given node.=0D + @param[in] Name The name to the property which need be searche= d=0D + @param[in] Length The length to the size of the property found.= =0D +=0D + @return The property to the structure of the found property.=0D +=0D +**/=0D +CONST struct fdt_property *=0D +EFIAPI=0D +FdtGetProperty (=0D + IN CONST VOID *Fdt,=0D + IN INT32 NodeOffset,=0D + IN CONST CHAR8 *Name,=0D + IN INT32 *Length=0D + )=0D +{=0D + return fdt_get_property (Fdt, NodeOffset, Name, Length);=0D +}=0D +=0D +/**=0D + Returns a offset of first property in the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] NodeOffset The offset to the node which need be searched.= =0D +=0D + @return The offset to first property offset in the given node.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtFirstPropertyOffset (=0D + IN CONST VOID *Fdt,=0D + IN INT32 NodeOffset=0D + )=0D +{=0D + return fdt_first_property_offset (Fdt, NodeOffset);=0D +}=0D +=0D +/**=0D + Returns a offset of next property from the given property.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to previous property.=0D +=0D + @return The offset to next property offset.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtNextPropertyOffset (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset=0D + )=0D +{=0D + return fdt_next_property_offset (Fdt, Offset);=0D +}=0D +=0D +/**=0D + Returns a property from the given offset of the property.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] Offset The offset to the given offset of the property= .=0D + @param[in] Length The length to the size of the property found.= =0D +=0D + @return The property to the structure of the given property offset.=0D +=0D +**/=0D +CONST struct fdt_property *=0D +EFIAPI=0D +FdtGetPropertyByOffset (=0D + IN CONST VOID *Fdt,=0D + IN INT32 Offset,=0D + IN INT32 *Length=0D + )=0D +{=0D + return fdt_get_property_by_offset (Fdt, Offset, Length);=0D +}=0D +=0D +/**=0D + Returns a string by the given string offset.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] StrOffset The offset to the location in the strings bloc= k of FDT.=0D + @param[in] Length The length to the size of string which need be= retrieved.=0D +=0D + @return The string to the given string offset.=0D +=0D +**/=0D +CONST CHAR8 *=0D +EFIAPI=0D +FdtGetString (=0D + IN CONST VOID *Fdt,=0D + IN INT32 StrOffset,=0D + IN INT32 *Length OPTIONAL=0D + )=0D +{=0D + return fdt_get_string (Fdt, StrOffset, Length);=0D +}=0D +=0D +/**=0D + Add a new node to the FDT.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] ParentOffset The offset to the node offset which want to ad= d in.=0D + @param[in] Name The name to name the node.=0D +=0D + @return The offset to the new node.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtAddSubnode (=0D + IN VOID *Fdt,=0D + IN INT32 ParentOffset,=0D + IN CONST CHAR8 *Name=0D + )=0D +{=0D + return fdt_add_subnode (Fdt, ParentOffset, Name);=0D +}=0D +=0D +/**=0D + Add or modify a property in the given node.=0D +=0D + @param[in] Fdt The pointer to FDT blob.=0D + @param[in] NodeOffset The offset to the node offset which want to ad= d in.=0D + @param[in] Name The name to name the property.=0D + @param[in] Value The value to the property value.=0D + @param[in] Length The length to the size of the property.=0D +=0D + @return Zero for successfully, otherwise failed.=0D +=0D +**/=0D +INT32=0D +EFIAPI=0D +FdtSetProp (=0D + IN VOID *Fdt,=0D + IN INT32 NodeOffset,=0D + IN CONST CHAR8 *Name,=0D + IN CONST VOID *Value,=0D + IN UINT32 Length=0D + )=0D +{=0D + return fdt_setprop (Fdt, NodeOffset, Name, Value, (int)Length);=0D +}=0D diff --git a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h b/MdePkg/Library/Bas= eFdtLib/LibFdtSupport.h new file mode 100644 index 0000000000..393019324b --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h @@ -0,0 +1,99 @@ +/** @file=0D + Root include file of C runtime library to support building the third-par= ty=0D + libfdt library.=0D +=0D + Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef FDT_LIB_SUPPORT_H_=0D +#define FDT_LIB_SUPPORT_H_=0D +=0D +#include =0D +#include =0D +#include =0D +=0D +typedef UINT8 uint8_t;=0D +typedef UINT16 uint16_t;=0D +typedef INT32 int32_t;=0D +typedef UINT32 uint32_t;=0D +typedef UINT64 uint64_t;=0D +typedef UINTN uintptr_t;=0D +typedef UINTN size_t;=0D +typedef BOOLEAN bool;=0D +=0D +#define true (1 =3D=3D 1)=0D +#define false (1 =3D=3D 0)=0D +=0D +//=0D +// Definitions for global constants used by libfdt library routines=0D +//=0D +#define INT_MAX 0x7FFFFFFF /* Maximum (signed) int value */= =0D +#define INT32_MAX 0x7FFFFFFF /* Maximum (signed) int32 value *= /=0D +#define UINT32_MAX 0xFFFFFFFF /* Maximum unsigned int32 value *= /=0D +=0D +//=0D +// Function prototypes of libfdt Library routines=0D +//=0D +void *=0D +memset (=0D + void *,=0D + int,=0D + size_t=0D + );=0D +=0D +int=0D +memcmp (=0D + const void *,=0D + const void *,=0D + size_t=0D + );=0D +=0D +int=0D +strcmp (=0D + const char *,=0D + const char *=0D + );=0D +=0D +char *=0D +strchr (=0D + const char *,=0D + int=0D + );=0D +=0D +char *=0D +strrchr (=0D + const char *,=0D + int=0D + );=0D +=0D +unsigned long=0D +strtoul (=0D + const char *,=0D + char **,=0D + int=0D + );=0D +=0D +char *=0D +strcpy (=0D + char *strDest,=0D + const char *strSource=0D + );=0D +=0D +//=0D +// Macros that directly map functions to BaseLib, BaseMemoryLib, and Debug= Lib functions=0D +//=0D +#define memcpy(dest, source, count) CopyMem(dest,source, (UINTN)(c= ount))=0D +#define memset(dest, ch, count) SetMem(dest, (UINTN)(count),(U= INT8)(ch))=0D +#define memchr(buf, ch, count) ScanMem8(buf, (UINTN)(count),(= UINT8)ch)=0D +#define memcmp(buf1, buf2, count) (int)(CompareMem(buf1, buf2, (= UINTN)(count)))=0D +#define memmove(dest, source, count) CopyMem(dest, source, (UINTN)(= count))=0D +#define strlen(str) (size_t)(AsciiStrLen(str))=0D +#define strnlen(str, count) (size_t)(AsciiStrnLenS(str, co= unt))=0D +#define strncpy(strDest, strSource, count) AsciiStrnCpyS(strDest, MAX_STR= ING_SIZE, strSource, (UINTN)count)=0D +#define strcat(strDest, strSource) AsciiStrCatS(strDest, MAX_STRI= NG_SIZE, strSource)=0D +#define strcmp(string1, string2, count) (int)(AsciiStrCmp(string1, str= ing2))=0D +#define strncmp(string1, string2, count) (int)(AsciiStrnCmp(string1, st= ring2, (UINTN)(count)))=0D +=0D +#endif /* FDT_LIB_SUPPORT_H_ */=0D diff --git a/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c b/MdePkg/Library/Bas= eFdtLib/LibFdtWrapper.c new file mode 100644 index 0000000000..ef6452914f --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c @@ -0,0 +1,173 @@ +/** @file=0D + ISO C implementations of strchr, strrchr and strtoul.=0D +=0D + Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D + Copyright (c) 2023 Pedro Falcato All rights reserved.=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D +#define ULONG_MAX 0xFFFFFFFF /* Maximum unsigned long value */= =0D +=0D +// Very quick notes:=0D +// We only go through the string once for both functions=0D +// They are minimal implementations (not speed optimized) of ISO C semanti= cs=0D +// strchr and strrchr also include the null terminator as part of the stri= ng=0D +// so the code gets a bit clunky to handle that case specifically.=0D +=0D +char *=0D +strchr (=0D + const char *Str,=0D + int Char=0D + )=0D +{=0D + char *S;=0D +=0D + S =3D (char *)Str;=0D +=0D + for ( ; ; S++) {=0D + if (*S =3D=3D Char) {=0D + return S;=0D + }=0D +=0D + if (*S =3D=3D '\0') {=0D + return NULL;=0D + }=0D + }=0D +}=0D +=0D +char *=0D +strrchr (=0D + const char *Str,=0D + int Char=0D + )=0D +{=0D + char *S, *last;=0D +=0D + S =3D (char *)Str;=0D + last =3D NULL;=0D +=0D + for ( ; ; S++) {=0D + if (*S =3D=3D Char) {=0D + last =3D S;=0D + }=0D +=0D + if (*S =3D=3D '\0') {=0D + return last;=0D + }=0D + }=0D +}=0D +=0D +STATIC=0D +int=0D +__isspace (=0D + int ch=0D + )=0D +{=0D + // basic ASCII ctype.h:isspace(). Not efficient=0D + return ch =3D=3D '\r' || ch =3D=3D '\n' || ch =3D=3D ' ' || ch =3D=3D '\= t' || ch =3D=3D '\v' || ch =3D=3D '\f';=0D +}=0D +=0D +unsigned long=0D +strtoul (=0D + const char *Nptr,=0D + char **EndPtr,=0D + int Base=0D + )=0D +{=0D + BOOLEAN Negate;=0D + BOOLEAN Overflow;=0D + unsigned long Val;=0D +=0D + Negate =3D FALSE;=0D + Overflow =3D FALSE;=0D + Val =3D 0;=0D +=0D + // Reject bad numeric bases=0D + if ((Base < 0) || (Base =3D=3D 1) || (Base > 36)) {=0D + return 0;=0D + }=0D +=0D + // Skip whitespace=0D + while (__isspace (*Nptr)) {=0D + Nptr++;=0D + }=0D +=0D + // Check for + or - prefixes=0D + if (*Nptr =3D=3D '-') {=0D + Negate =3D TRUE;=0D + Nptr++;=0D + } else if (*Nptr =3D=3D '+') {=0D + Nptr++;=0D + }=0D +=0D + // Consume the start, autodetecting base if needed=0D + if ((Nptr[0] =3D=3D '0') && ((Nptr[1] =3D=3D 'x') || (Nptr[1] =3D=3D 'X'= )) && ((Base =3D=3D 0) || (Base =3D=3D 16))) {=0D + // Hex=0D + Nptr +=3D 2;=0D + Base =3D 16;=0D + } else if ((Nptr[0] =3D=3D '0') && ((Nptr[1] =3D=3D 'b') || (Nptr[1] =3D= =3D 'B')) && ((Base =3D=3D 0) || (Base =3D=3D 2))) {=0D + // Binary (standard pending C23)=0D + Nptr +=3D 2;=0D + Base =3D 2;=0D + } else if ((Nptr[0] =3D=3D '0') && ((Base =3D=3D 0) || (Base =3D=3D 8)))= {=0D + // Octal=0D + Nptr++;=0D + Base =3D 8;=0D + } else {=0D + if (Base =3D=3D 0) {=0D + // Assume decimal=0D + Base =3D 10;=0D + }=0D + }=0D +=0D + while (TRUE) {=0D + int Digit;=0D + char C;=0D + unsigned long NewVal;=0D +=0D + C =3D *Nptr;=0D + Digit =3D -1;=0D +=0D + if ((C >=3D '0') && (C <=3D '9')) {=0D + Digit =3D C - '0';=0D + } else if ((C >=3D 'a') && (C <=3D 'z')) {=0D + Digit =3D C - 'a' + 10;=0D + } else if ((C >=3D 'A') && (C <=3D 'Z')) {=0D + Digit =3D C - 'A' + 10;=0D + }=0D +=0D + if ((Digit =3D=3D -1) || (Digit >=3D Base)) {=0D + // Note that this case also handles the \0=0D + if (EndPtr) {=0D + *EndPtr =3D (char *)Nptr;=0D + }=0D +=0D + break;=0D + }=0D +=0D + NewVal =3D Val * Base + Digit;=0D +=0D + if (NewVal < Val) {=0D + // Overflow=0D + Overflow =3D TRUE;=0D + }=0D +=0D + Val =3D NewVal;=0D +=0D + Nptr++;=0D + }=0D +=0D + if (Negate) {=0D + Val =3D -Val;=0D + }=0D +=0D + if (Overflow) {=0D + Val =3D ULONG_MAX;=0D + }=0D +=0D + // TODO: We're lacking errno here.=0D + return Val;=0D +}=0D diff --git a/MdePkg/Library/BaseFdtLib/limits.h b/MdePkg/Library/BaseFdtLib= /limits.h new file mode 100644 index 0000000000..f6cf8d5702 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/limits.h @@ -0,0 +1,10 @@ +/** @file=0D + Include file to support building the third-party libfdt library.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D diff --git a/MdePkg/Library/BaseFdtLib/stdbool.h b/MdePkg/Library/BaseFdtLi= b/stdbool.h new file mode 100644 index 0000000000..f6cf8d5702 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/stdbool.h @@ -0,0 +1,10 @@ +/** @file=0D + Include file to support building the third-party libfdt library.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D diff --git a/MdePkg/Library/BaseFdtLib/stddef.h b/MdePkg/Library/BaseFdtLib= /stddef.h new file mode 100644 index 0000000000..f6cf8d5702 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/stddef.h @@ -0,0 +1,10 @@ +/** @file=0D + Include file to support building the third-party libfdt library.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D diff --git a/MdePkg/Library/BaseFdtLib/stdint.h b/MdePkg/Library/BaseFdtLib= /stdint.h new file mode 100644 index 0000000000..f6cf8d5702 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/stdint.h @@ -0,0 +1,10 @@ +/** @file=0D + Include file to support building the third-party libfdt library.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D diff --git a/MdePkg/Library/BaseFdtLib/stdlib.h b/MdePkg/Library/BaseFdtLib= /stdlib.h new file mode 100644 index 0000000000..f6cf8d5702 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/stdlib.h @@ -0,0 +1,10 @@ +/** @file=0D + Include file to support building the third-party libfdt library.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D diff --git a/MdePkg/Library/BaseFdtLib/string.h b/MdePkg/Library/BaseFdtLib= /string.h new file mode 100644 index 0000000000..f6cf8d5702 --- /dev/null +++ b/MdePkg/Library/BaseFdtLib/string.h @@ -0,0 +1,10 @@ +/** @file=0D + Include file to support building the third-party libfdt library.=0D +=0D +Copyright (c) 2023, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include =0D +=0D diff --git a/MdePkg/MdePkg.ci.yaml b/MdePkg/MdePkg.ci.yaml index 6ba85ebe61..035c34b3ad 100644 --- a/MdePkg/MdePkg.ci.yaml +++ b/MdePkg/MdePkg.ci.yaml @@ -67,7 +67,8 @@ "Include/Library/PcdLib.h",=0D "Include/Library/SafeIntLib.h",=0D "Include/Protocol/DebugSupport.h",=0D - "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c"=0D + "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c",=0D + "Library/BaseFdtLib"=0D ]=0D },=0D ## options defined ci/Plugin/CompilerPlugin=0D @@ -164,5 +165,17 @@ "ExtendWords": [], # words to extend to the dictionary f= or this package=0D "IgnoreStandardPaths": [], # Standard Plugin defined paths that = should be ignore=0D "AdditionalIncludePaths": [] # Additional paths to spell check (wi= ldcards supported)=0D + },=0D + # options defined in .pytool/Plugin/UncrustifyCheck=0D + "UncrustifyCheck": {=0D + "IgnoreFiles": [=0D + "Library/BaseFdtLib/libfdt",=0D + "Library/BaseFdtLib/limits.h",=0D + "Library/BaseFdtLib/stdbool.h",=0D + "Library/BaseFdtLib/stddef.h",=0D + "Library/BaseFdtLib/stdint.h",=0D + "Library/BaseFdtLib/stdlib.h",=0D + "Library/BaseFdtLib/string.h"=0D + ]=0D }=0D }=0D diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index e70182bf7f..9804a7a6bd 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -289,6 +289,10 @@ #=0D ArmTrngLib|Include/Library/ArmTrngLib.h=0D =0D + ## @libraryclass Provides APIs for third-party library libfdt.=0D + #=0D + FdtLib|Include/Library/FdtLib.h=0D +=0D [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]=0D ## @libraryclass Provides services to generate random number.=0D #=0D diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc index 152c02991a..b38c863812 100644 --- a/MdePkg/MdePkg.dsc +++ b/MdePkg/MdePkg.dsc @@ -137,6 +137,7 @@ MdePkg/Library/SmmCpuRendezvousLibNull/SmmCpuRendezvousLibNull.inf=0D =0D MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf=0D + MdePkg/Library/BaseFdtLib/BaseFdtLib.inf=0D =0D [Components.IA32, Components.X64, Components.ARM, Components.AARCH64]=0D #=0D --=20 2.39.1.windows.1