public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v6 0/3] Support FDT library.
@ 2023-05-04  5:57 Benny Lin
  2023-05-04  5:57 ` [PATCH v6 1/3] Tianocore: " Benny Lin
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Benny Lin @ 2023-05-04  5:57 UTC (permalink / raw)
  To: devel
  Cc: Benny Lin, Michael D Kinney, Liming Gao, Zhiguang Liu,
	Sean Brogan, Michael Kubacki, Pedro Falcato

From: Benny Lin <benny.lin@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4392
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 <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Acked-by: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Benny Lin <benny.lin@intel.com>

Benny Lin (3):
  Tianocore: Support FDT library.
  MdePkg: Support FDT library.
  .pytool: Support FDT library.

 .gitmodules                               |   3 +
 .pytool/CISettings.py                     |   2 +
 MdePkg/Include/Library/FdtLib.h           | 396 +++++++++++++++++++
 MdePkg/Library/BaseFdtLib/BaseFdtLib.inf  |  62 +++
 MdePkg/Library/BaseFdtLib/BaseFdtLib.uni  |  14 +
 MdePkg/Library/BaseFdtLib/FdtLib.c        | 404 ++++++++++++++++++++
 MdePkg/Library/BaseFdtLib/LibFdtSupport.h |  99 +++++
 MdePkg/Library/BaseFdtLib/LibFdtWrapper.c | 173 +++++++++
 MdePkg/Library/BaseFdtLib/libfdt          |   1 +
 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 +
 ReadMe.rst                                |   1 +
 19 files changed, 1234 insertions(+), 1 deletion(-)
 create mode 100644 MdePkg/Include/Library/FdtLib.h
 create mode 100644 MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
 create mode 100644 MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
 create mode 100644 MdePkg/Library/BaseFdtLib/FdtLib.c
 create mode 100644 MdePkg/Library/BaseFdtLib/LibFdtSupport.h
 create mode 100644 MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
 create mode 160000 MdePkg/Library/BaseFdtLib/libfdt
 create mode 100644 MdePkg/Library/BaseFdtLib/limits.h
 create mode 100644 MdePkg/Library/BaseFdtLib/stdbool.h
 create mode 100644 MdePkg/Library/BaseFdtLib/stddef.h
 create mode 100644 MdePkg/Library/BaseFdtLib/stdint.h
 create mode 100644 MdePkg/Library/BaseFdtLib/stdlib.h
 create mode 100644 MdePkg/Library/BaseFdtLib/string.h

-- 
2.39.1.windows.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v6 1/3] Tianocore: Support FDT library.
  2023-05-04  5:57 [PATCH v6 0/3] Support FDT library Benny Lin
@ 2023-05-04  5:57 ` Benny Lin
  2023-05-04  5:57 ` [PATCH v6 2/3] MdePkg: " Benny Lin
  2023-05-04  5:57 ` [PATCH v6 3/3] .pytool: " Benny Lin
  2 siblings, 0 replies; 6+ messages in thread
From: Benny Lin @ 2023-05-04  5:57 UTC (permalink / raw)
  To: devel; +Cc: Benny Lin, Leif Lindholm, Michael D Kinney, Andrew Fish

From: Benny Lin <benny.lin@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4392
Add FDT support in EDK2 by submodule 3rd party libfdt
(https://github.com/devicetree-org/pylibfdt/tree/main/libfdt)

Add submodule libfdt and update ReadMe for the licence.

Reviewed-by: Leif Lindholm <quic_llindhol@quicinc.com>
Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Andrew Fish <afish@apple.com>
Cc: Leif Lindholm <quic_llindhol@quicinc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Benny Lin <benny.lin@intel.com>
---
 .gitmodules                      | 3 +++
 MdePkg/Library/BaseFdtLib/libfdt | 1 +
 ReadMe.rst                       | 1 +
 3 files changed, 5 insertions(+)

diff --git a/.gitmodules b/.gitmodules
index fe8a43be93..b1888c3488 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -26,3 +26,6 @@
 [submodule "UnitTestFrameworkPkg/Library/SubhookLib/subhook"]
 	path = UnitTestFrameworkPkg/Library/SubhookLib/subhook
 	url = https://github.com/Zeex/subhook.git
+[submodule "MdePkg/Library/BaseFdtLib/libfdt"]
+	path = MdePkg/Library/BaseFdtLib/libfdt
+	url = https://github.com/devicetree-org/pylibfdt.git
diff --git a/MdePkg/Library/BaseFdtLib/libfdt b/MdePkg/Library/BaseFdtLib/libfdt
new file mode 160000
index 0000000000..cfff805481
--- /dev/null
+++ b/MdePkg/Library/BaseFdtLib/libfdt
@@ -0,0 +1 @@
+Subproject commit cfff805481bdea27f900c32698171286542b8d3c
diff --git a/ReadMe.rst b/ReadMe.rst
index 91b9cf3c5e..d46c534229 100644
--- a/ReadMe.rst
+++ b/ReadMe.rst
@@ -96,6 +96,7 @@ that are covered by additional licenses.
 -  `UnitTestFrameworkPkg/Library/GoogleTestLib/googletest <https://github.com/google/googletest/blob/86add13493e5c881d7e4ba77fb91c1f57752b3a4/LICENSE>`__
 -  `UnitTestFrameworkPkg/Library/SubhookLib/subhook <https://github.com/Zeex/subhook/blob/83d4e1ebef3588fae48b69a7352cc21801cb70bc/LICENSE.txt>`__
 -  `RedfishPkg/Library/JsonLib/jansson <https://github.com/akheron/jansson/blob/2882ead5bb90cf12a01b07b2c2361e24960fae02/LICENSE>`__
+-  `MdePkg/Library/BaseFdtLib/libfdt <https://github.com/devicetree-org/pylibfdt/blob/f39368a217496d32c4091a2dba4045b60649e3a5/BSD-2-Clause>`__
 
 The EDK II Project is composed of packages. The maintainers for each package
 are listed in `Maintainers.txt <Maintainers.txt>`__.
-- 
2.39.1.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v6 2/3] MdePkg: Support FDT library.
  2023-05-04  5:57 [PATCH v6 0/3] Support FDT library Benny Lin
  2023-05-04  5:57 ` [PATCH v6 1/3] Tianocore: " Benny Lin
@ 2023-05-04  5:57 ` Benny Lin
  2023-05-04 18:01   ` Michael D Kinney
  2023-05-04  5:57 ` [PATCH v6 3/3] .pytool: " Benny Lin
  2 siblings, 1 reply; 6+ messages in thread
From: Benny Lin @ 2023-05-04  5:57 UTC (permalink / raw)
  To: devel; +Cc: Benny Lin, Michael D Kinney, Liming Gao, Zhiguang Liu,
	Pedro Falcato

From: Benny Lin <benny.lin@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4392
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 <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Acked-by: Pedro Falcato <pedro.falcato@gmail.com>
Signed-off-by: Benny Lin <benny.lin@intel.com>
---
 MdePkg/Include/Library/FdtLib.h           | 396 +++++++++++++++++++
 MdePkg/Library/BaseFdtLib/BaseFdtLib.inf  |  62 +++
 MdePkg/Library/BaseFdtLib/BaseFdtLib.uni  |  14 +
 MdePkg/Library/BaseFdtLib/FdtLib.c        | 404 ++++++++++++++++++++
 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, 1227 insertions(+), 1 deletion(-)

diff --git a/MdePkg/Include/Library/FdtLib.h b/MdePkg/Include/Library/FdtLib.h
new file mode 100644
index 0000000000..4b428eb5d1
--- /dev/null
+++ b/MdePkg/Include/Library/FdtLib.h
@@ -0,0 +1,396 @@
+/** @file
+  Flattened Device Tree Library.
+
+  All structure data are in big-endian format. Need to call SwapBytes**
+  function to convert between little-endia and big-endian.
+  For example, pushing data to FDT blob need convert to big-endian with SwapByte**.
+  For retrieving data from FDT blob need convert to little-endian with SwapByte**.
+  Refer to FDT specification: https://www.devicetree.org/specifications/
+
+  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FDT_LIB_H_
+#define FDT_LIB_H_
+
+/**
+  Flattened Device Tree definition
+
+  The Devicetree Blob (DTB) format is a binary encoding with big-endian.
+  When producing or consuming the blob data, must convert with SwapBytesXX
+  provided by edk2 BaseLib between big-endian and little-endian.
+**/
+typedef struct {
+  UINT32    Magic;               /* magic word FDT_MAGIC */
+  UINT32    TotalSize;           /* total size of DT block */
+  UINT32    OffsetDtStruct;      /* offset to structure */
+  UINT32    OffsetDtStrings;     /* offset to strings */
+  UINT32    OffsetMemRsvmap;     /* offset to memory reserve map */
+  UINT32    Version;             /* format version */
+  UINT32    LastCompVersion;     /* last compatible version */
+
+  /* version 2 fields below */
+  UINT32    BootCpuidPhys;       /* Which physical CPU id we're
+                                    booting on */
+  /* version 3 fields below */
+  UINT32    SizeDtStrings;       /* size of the strings block */
+
+  /* version 17 fields below */
+  UINT32    SizeDtStruct;        /* size of the structure block */
+} FDT_HEADER;
+
+typedef struct {
+  UINT64    Address;
+  UINT64    Size;
+} FDT_RESERVE_ENTRY;
+
+typedef struct {
+  UINT32    Tag;
+  CHAR8     Name[];
+} FDT_NODE_HEADER;
+
+typedef struct {
+  UINT32    Tag;
+  UINT32    Length;
+  UINT32    NameOffset;
+  CHAR8     Data[];
+} FDT_PROPERTY;
+
+/**
+  Convert UINT16 data of the FDT blob to little-endian
+
+  @param[in] Value            The value to the blob data.
+
+  @return The value to be converted to little-endian.
+
+**/
+UINT16
+EFIAPI
+Fdt16ToCpu (
+  IN UINT16  Value
+  );
+
+/**
+  Convert UINT16 data to big-endian for aligned with the FDT blob
+
+  @param[in] Value            The value to align with the FDT blob.
+
+  @return The value to be converted to big-endian.
+
+**/
+UINT16
+EFIAPI
+CpuToFdt16 (
+  IN UINT16  Value
+  );
+
+/**
+  Convert UINT32 data of the FDT blob to little-endian
+
+  @param[in] Value            The value to the blob data.
+
+  @return The value to be converted to little-endian.
+
+**/
+UINT32
+EFIAPI
+Fdt32ToCpu (
+  IN UINT32  Value
+  );
+
+/**
+  Convert UINT32 data to big-endian for aligned with the FDT blob
+
+  @param[in] Value            The value to align with the FDT blob.
+
+  @return The value to be converted to big-endian.
+
+**/
+UINT32
+EFIAPI
+CpuToFdt32 (
+  IN UINT32  Value
+  );
+
+/**
+  Convert UINT64 data of the FDT blob to little-endian
+
+  @param[in] Value            The value to the blob data.
+
+  @return The value to be converted to little-endian.
+
+**/
+UINT64
+EFIAPI
+Fdt64ToCpu (
+  IN UINT64  Value
+  );
+
+/**
+  Convert UINT64 data to big-endian for aligned with the FDT blob
+
+  @param[in] Value            The value to align with the FDT blob.
+
+  @return The value to be converted to big-endian.
+
+**/
+UINT64
+EFIAPI
+CpuToFdt64 (
+  IN UINT64  Value
+  );
+
+/**
+  Verify the header of the Flattened Device Tree
+
+  @param[in] Fdt            The pointer to FDT blob.
+
+  @return Zero for successfully, otherwise failed.
+
+**/
+INT32
+EFIAPI
+FdtCheckHeader (
+  IN CONST VOID  *Fdt
+  );
+
+/**
+  Create a empty Flattened Device Tree.
+
+  @param[in] Buffer         The pointer to allocate a pool for FDT blob.
+  @param[in] BufferSize     The BufferSize to the pool size.
+
+  @return Zero for successfully, otherwise failed.
+
+**/
+INT32
+EFIAPI
+FdtCreateEmptyTree (
+  IN VOID    *Buffer,
+  IN UINT32  BufferSize
+  );
+
+/**
+  Returns a offset of next node from the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous node.
+  @param[in] Depth          The depth to the level of tree hierarchy.
+
+  @return The offset to next node offset.
+
+**/
+INT32
+EFIAPI
+FdtNextNode (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset,
+  IN INT32       *Depth
+  );
+
+/**
+  Returns a offset of first node under the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous node.
+
+  @return The offset to next node offset.
+
+**/
+INT32
+EFIAPI
+FdtFirstSubnode (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset
+  );
+
+/**
+  Returns a offset of next node from the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous node.
+
+  @return The offset to next node offset.
+
+**/
+INT32
+EFIAPI
+FdtNextSubnode (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset
+  );
+
+/**
+  Returns a offset of first node which includes the given name.
+
+  @param[in] Fdt             The pointer to FDT blob.
+  @param[in] ParentOffset    The offset to the node which start find under.
+  @param[in] Name            The name to search the node with the name.
+  @param[in] NameLength      The length of the name to check only.
+
+  @return The offset to node offset with given node name.
+
+**/
+INT32
+EFIAPI
+FdtSubnodeOffsetNameLen (
+  IN CONST VOID   *Fdt,
+  IN INT32        ParentOffset,
+  IN CONST CHAR8  *Name,
+  IN INT32        NameLength
+  );
+
+/**
+  Returns a offset of first node which includes the given property name and value.
+
+  @param[in] Fdt             The pointer to FDT blob.
+  @param[in] StartOffset     The offset to the starting node to find.
+  @param[in] PropertyName    The property name to search the node including the named property.
+  @param[in] PropertyValue   The property value (big-endian) to check the same property value.
+  @param[in] PropertyLength  The length of the value in PropertValue.
+
+  @return The offset to node offset with given property.
+
+**/
+INT32
+EFIAPI
+FdtNodeOffsetByPropValue (
+  IN CONST VOID   *Fdt,
+  IN INT32        StartOffset,
+  IN CONST CHAR8  *PropertyName,
+  IN CONST VOID   *PropertyValue,
+  IN INT32        PropertyLength
+  );
+
+/**
+  Returns a property with the given name from the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] NodeOffset     The offset to the given node.
+  @param[in] Name           The name to the property which need be searched
+  @param[in] Length         The length to the size of the property found.
+
+  @return The property to the structure of the found property. Since the data
+          come from FDT blob, it's encoding with big-endian.
+
+**/
+CONST FDT_PROPERTY *
+EFIAPI
+FdtGetProperty (
+  IN CONST VOID   *Fdt,
+  IN INT32        NodeOffset,
+  IN CONST CHAR8  *Name,
+  IN INT32        *Length
+  );
+
+/**
+  Returns a offset of first property in the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] NodeOffset     The offset to the node which need be searched.
+
+  @return The offset to first property offset in the given node.
+
+**/
+INT32
+EFIAPI
+FdtFirstPropertyOffset (
+  IN CONST VOID  *Fdt,
+  IN INT32       NodeOffset
+  );
+
+/**
+  Returns a offset of next property from the given property.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous property.
+
+  @return The offset to next property offset.
+
+**/
+INT32
+EFIAPI
+FdtNextPropertyOffset (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset
+  );
+
+/**
+  Returns a property from the given offset of the property.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to the given offset of the property.
+  @param[in] Length         The length to the size of the property found.
+
+  @return The property to the structure of the given property offset.
+
+**/
+CONST FDT_PROPERTY *
+EFIAPI
+FdtGetPropertyByOffset (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset,
+  IN INT32       *Length
+  );
+
+/**
+  Returns a string by the given string offset.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] StrOffset      The offset to the location in the strings block of FDT.
+  @param[in] Length         The length to the size of string which need be retrieved.
+
+  @return The string to the given string offset.
+
+**/
+CONST CHAR8 *
+EFIAPI
+FdtGetString (
+  IN CONST VOID  *Fdt,
+  IN INT32       StrOffset,
+  IN INT32       *Length        OPTIONAL
+  );
+
+/**
+  Add a new node to the FDT.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] ParentOffset   The offset to the node offset which want to add in.
+  @param[in] Name           The name to name the node.
+
+  @return  The offset to the new node.
+
+**/
+INT32
+EFIAPI
+FdtAddSubnode (
+  IN VOID         *Fdt,
+  IN INT32        ParentOffset,
+  IN CONST CHAR8  *Name
+  );
+
+/**
+  Add or modify a property in the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] NodeOffset     The offset to the node offset which want to add in.
+  @param[in] Name           The name to name the property.
+  @param[in] Value          The value (big-endian) to the property value.
+  @param[in] Length         The length to the size of the property.
+
+  @return  Zero for successfully, otherwise failed.
+
+**/
+INT32
+EFIAPI
+FdtSetProp (
+  IN VOID         *Fdt,
+  IN INT32        NodeOffset,
+  IN CONST CHAR8  *Name,
+  IN CONST VOID   *Value,
+  IN UINT32       Length
+  );
+
+#endif /* FDT_LIB_H_ */
diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
new file mode 100644
index 0000000000..730e568ff6
--- /dev/null
+++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Flattened Device Tree Library.
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BaseFdtLib
+  MODULE_UNI_FILE                = BaseFdtLib.uni
+  FILE_GUID                      = C64DCB01-B037-4FF6-9CF3-E8CEC206DE04
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FdtLib
+
+  DEFINE FDT_LIB_PATH            = libfdt/libfdt
+
+#
+#  VALID_ARCHITECTURES           = IA32 X64
+#
+
+[Sources]
+  FdtLib.c
+  LibFdtWrapper.c
+  # header Wrapper files
+  limits.h
+  stdbool.h
+  stddef.h
+  stdint.h
+  stdlib.h
+  string.h
+
+  $(FDT_LIB_PATH)/fdt.c
+  $(FDT_LIB_PATH)/fdt.h
+  $(FDT_LIB_PATH)/fdt_addresses.c
+  $(FDT_LIB_PATH)/fdt_check.c
+  $(FDT_LIB_PATH)/fdt_empty_tree.c
+  $(FDT_LIB_PATH)/fdt_overlay.c
+  $(FDT_LIB_PATH)/fdt_ro.c
+  $(FDT_LIB_PATH)/fdt_rw.c
+  $(FDT_LIB_PATH)/fdt_strerror.c
+  $(FDT_LIB_PATH)/fdt_sw.c
+  $(FDT_LIB_PATH)/fdt_wip.c
+  $(FDT_LIB_PATH)/libfdt.h
+  $(FDT_LIB_PATH)/libfdt_env.h
+  $(FDT_LIB_PATH)/libfdt_internal.h
+
+[Packages]
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+
+[BuildOptions]
+  MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245
+  MSFT:*_*_X64_CC_FLAGS  = /wd4146 /wd4244 /wd4245 /wd4267
+
diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni b/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
new file mode 100644
index 0000000000..3f7e45ea6f
--- /dev/null
+++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
@@ -0,0 +1,14 @@
+// /** @file
+// Flattened Device Tree Library.
+//
+// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Instance of FDT Library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This module provides FDT Library implementation."
+
diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c b/MdePkg/Library/BaseFdtLib/FdtLib.c
new file mode 100644
index 0000000000..090b0b3fd4
--- /dev/null
+++ b/MdePkg/Library/BaseFdtLib/FdtLib.c
@@ -0,0 +1,404 @@
+/** @file
+  Flattened Device Tree Library.
+
+  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <libfdt/libfdt/libfdt.h>
+
+/**
+  Convert UINT16 data of the FDT blob to little-endian
+
+  @param[in] Value            The value to the blob data.
+
+  @return The value to be converted to little-endian.
+
+**/
+UINT16
+EFIAPI
+Fdt16ToCpu (
+  IN UINT16  Value
+  )
+{
+  return fdt16_to_cpu (Value);
+}
+
+/**
+  Convert UINT16 data to big-endian for aligned with the FDT blob
+
+  @param[in] Value            The value to align with the FDT blob.
+
+  @return The value to be converted to big-endian.
+
+**/
+UINT16
+EFIAPI
+CpuToFdt16 (
+  IN UINT16  Value
+  )
+{
+  return cpu_to_fdt16 (Value);
+}
+
+/**
+  Convert UINT32 data of the FDT blob to little-endian
+
+  @param[in] Value            The value to the blob data.
+
+  @return The value to be converted to little-endian.
+
+**/
+UINT32
+EFIAPI
+Fdt32ToCpu (
+  IN UINT32  Value
+  )
+{
+  return fdt32_to_cpu (Value);
+}
+
+/**
+  Convert UINT32 data to big-endian for aligned with the FDT blob
+
+  @param[in] Value            The value to align with the FDT blob.
+
+  @return The value to be converted to big-endian.
+
+**/
+UINT32
+EFIAPI
+CpuToFdt32 (
+  IN UINT32  Value
+  )
+{
+  return cpu_to_fdt32 (Value);
+}
+
+/**
+  Convert UINT64 data of the FDT blob to little-endian
+
+  @param[in] Value            The value to the blob data.
+
+  @return The value to be converted to little-endian.
+
+**/
+UINT64
+EFIAPI
+Fdt64ToCpu (
+  IN UINT64  Value
+  )
+{
+  return fdt64_to_cpu (Value);
+}
+
+/**
+  Convert UINT64 data to big-endian for aligned with the FDT blob
+
+  @param[in] Value            The value to align with the FDT blob.
+
+  @return The value to be converted to big-endian.
+
+**/
+UINT64
+EFIAPI
+CpuToFdt64 (
+  IN UINT64  Value
+  )
+{
+  return cpu_to_fdt64 (Value);
+}
+
+/**
+  Verify the header of the Flattened Device Tree
+
+  @param[in] Fdt            The pointer to FDT blob.
+
+  @return Zero for successfully, otherwise failed.
+
+**/
+INT32
+EFIAPI
+FdtCheckHeader (
+  IN CONST VOID  *Fdt
+  )
+{
+  return fdt_check_header (Fdt);
+}
+
+/**
+  Create a empty Flattened Device Tree.
+
+  @param[in] Buffer         The pointer to allocate a pool for FDT blob.
+  @param[in] BufferSize     The BufferSize to the pool size.
+
+  @return Zero for successfully, otherwise failed.
+
+**/
+INT32
+EFIAPI
+FdtCreateEmptyTree (
+  IN VOID    *Buffer,
+  IN UINT32  BufferSize
+  )
+{
+  return fdt_create_empty_tree (Buffer, (int)BufferSize);
+}
+
+/**
+  Returns a offset of next node from the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous node.
+  @param[in] Depth          The depth to the level of tree hierarchy.
+
+  @return The offset to next node offset.
+
+**/
+INT32
+EFIAPI
+FdtNextNode (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset,
+  IN INT32       *Depth
+  )
+{
+  return fdt_next_node (Fdt, Offset, Depth);
+}
+
+/**
+  Returns a offset of first node under the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous node.
+
+  @return The offset to next node offset.
+
+**/
+INT32
+EFIAPI
+FdtFirstSubnode (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset
+  )
+{
+  return fdt_first_subnode (Fdt, Offset);
+}
+
+/**
+  Returns a offset of next node from the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous node.
+
+  @return The offset to next node offset.
+
+**/
+INT32
+EFIAPI
+FdtNextSubnode (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset
+  )
+{
+  return fdt_next_subnode (Fdt, Offset);
+}
+
+/**
+  Returns a offset of first node which includes the given name.
+
+  @param[in] Fdt             The pointer to FDT blob.
+  @param[in] ParentOffset    The offset to the node which start find under.
+  @param[in] Name            The name to search the node with the name.
+  @param[in] NameLength      The length of the name to check only.
+
+  @return The offset to node offset with given node name.
+
+**/
+INT32
+EFIAPI
+FdtSubnodeOffsetNameLen (
+  IN CONST VOID   *Fdt,
+  IN INT32        ParentOffset,
+  IN CONST CHAR8  *Name,
+  IN INT32        NameLength
+  )
+{
+  return fdt_subnode_offset_namelen (Fdt, ParentOffset, Name, NameLength);
+}
+
+/**
+  Returns a offset of first node which includes the given property name and value.
+
+  @param[in] Fdt             The pointer to FDT blob.
+  @param[in] StartOffset     The offset to the starting node to find.
+  @param[in] PropertyName    The property name to search the node including the named property.
+  @param[in] PropertyValue   The property value (big-endian) to check the same property value.
+  @param[in] PropertyLength  The length of the value in PropertValue.
+
+  @return The offset to node offset with given property.
+
+**/
+INT32
+EFIAPI
+FdtNodeOffsetByPropValue (
+  IN CONST VOID   *Fdt,
+  IN INT32        StartOffset,
+  IN CONST CHAR8  *PropertyName,
+  IN CONST VOID   *PropertyValue,
+  IN INT32        PropertyLength
+  )
+{
+  return fdt_node_offset_by_prop_value (Fdt, StartOffset, PropertyName, PropertyValue, PropertyLength);
+}
+
+/**
+  Returns a property with the given name from the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] NodeOffset     The offset to the given node.
+  @param[in] Name           The name to the property which need be searched
+  @param[in] Length         The length to the size of the property found.
+
+  @return The property to the structure of the found property. Since the data
+          come from FDT blob, it's encoding with big-endian.
+
+**/
+CONST struct fdt_property *
+EFIAPI
+FdtGetProperty (
+  IN CONST VOID   *Fdt,
+  IN INT32        NodeOffset,
+  IN CONST CHAR8  *Name,
+  IN INT32        *Length
+  )
+{
+  return fdt_get_property (Fdt, NodeOffset, Name, Length);
+}
+
+/**
+  Returns a offset of first property in the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] NodeOffset     The offset to the node which need be searched.
+
+  @return The offset to first property offset in the given node.
+
+**/
+INT32
+EFIAPI
+FdtFirstPropertyOffset (
+  IN CONST VOID  *Fdt,
+  IN INT32       NodeOffset
+  )
+{
+  return fdt_first_property_offset (Fdt, NodeOffset);
+}
+
+/**
+  Returns a offset of next property from the given property.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to previous property.
+
+  @return The offset to next property offset.
+
+**/
+INT32
+EFIAPI
+FdtNextPropertyOffset (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset
+  )
+{
+  return fdt_next_property_offset (Fdt, Offset);
+}
+
+/**
+  Returns a property from the given offset of the property.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] Offset         The offset to the given offset of the property.
+  @param[in] Length         The length to the size of the property found.
+
+  @return The property to the structure of the given property offset.
+
+**/
+CONST struct fdt_property *
+EFIAPI
+FdtGetPropertyByOffset (
+  IN CONST VOID  *Fdt,
+  IN INT32       Offset,
+  IN INT32       *Length
+  )
+{
+  return fdt_get_property_by_offset (Fdt, Offset, Length);
+}
+
+/**
+  Returns a string by the given string offset.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] StrOffset      The offset to the location in the strings block of FDT.
+  @param[in] Length         The length to the size of string which need be retrieved.
+
+  @return The string to the given string offset.
+
+**/
+CONST CHAR8 *
+EFIAPI
+FdtGetString (
+  IN CONST VOID  *Fdt,
+  IN INT32       StrOffset,
+  IN INT32       *Length        OPTIONAL
+  )
+{
+  return fdt_get_string (Fdt, StrOffset, Length);
+}
+
+/**
+  Add a new node to the FDT.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] ParentOffset   The offset to the node offset which want to add in.
+  @param[in] Name           The name to name the node.
+
+  @return  The offset to the new node.
+
+**/
+INT32
+EFIAPI
+FdtAddSubnode (
+  IN VOID         *Fdt,
+  IN INT32        ParentOffset,
+  IN CONST CHAR8  *Name
+  )
+{
+  return fdt_add_subnode (Fdt, ParentOffset, Name);
+}
+
+/**
+  Add or modify a property in the given node.
+
+  @param[in] Fdt            The pointer to FDT blob.
+  @param[in] NodeOffset     The offset to the node offset which want to add in.
+  @param[in] Name           The name to name the property.
+  @param[in] Value          The value (big-endian) to the property value.
+  @param[in] Length         The length to the size of the property.
+
+  @return  Zero for successfully, otherwise failed.
+
+**/
+INT32
+EFIAPI
+FdtSetProp (
+  IN VOID         *Fdt,
+  IN INT32        NodeOffset,
+  IN CONST CHAR8  *Name,
+  IN CONST VOID   *Value,
+  IN UINT32       Length
+  )
+{
+  return fdt_setprop (Fdt, NodeOffset, Name, Value, (int)Length);
+}
diff --git a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
new file mode 100644
index 0000000000..393019324b
--- /dev/null
+++ b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
@@ -0,0 +1,99 @@
+/** @file
+  Root include file of C runtime library to support building the third-party
+  libfdt library.
+
+  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FDT_LIB_SUPPORT_H_
+#define FDT_LIB_SUPPORT_H_
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+
+typedef UINT8    uint8_t;
+typedef UINT16   uint16_t;
+typedef INT32    int32_t;
+typedef UINT32   uint32_t;
+typedef UINT64   uint64_t;
+typedef UINTN    uintptr_t;
+typedef UINTN    size_t;
+typedef BOOLEAN  bool;
+
+#define true   (1 == 1)
+#define false  (1 == 0)
+
+//
+// Definitions for global constants used by libfdt library routines
+//
+#define INT_MAX     0x7FFFFFFF           /* Maximum (signed) int value */
+#define INT32_MAX   0x7FFFFFFF           /* Maximum (signed) int32 value */
+#define UINT32_MAX  0xFFFFFFFF           /* Maximum unsigned int32 value */
+
+//
+// Function prototypes of libfdt Library routines
+//
+void *
+memset     (
+  void *,
+  int,
+  size_t
+  );
+
+int
+memcmp      (
+  const void *,
+  const void *,
+  size_t
+  );
+
+int
+strcmp      (
+  const char *,
+  const char *
+  );
+
+char *
+strchr     (
+  const char *,
+  int
+  );
+
+char *
+strrchr    (
+  const char *,
+  int
+  );
+
+unsigned long
+strtoul     (
+  const char *,
+  char **,
+  int
+  );
+
+char *
+strcpy (
+  char        *strDest,
+  const char  *strSource
+  );
+
+//
+// Macros that directly map functions to BaseLib, BaseMemoryLib, and DebugLib functions
+//
+#define memcpy(dest, source, count)         CopyMem(dest,source, (UINTN)(count))
+#define memset(dest, ch, count)             SetMem(dest, (UINTN)(count),(UINT8)(ch))
+#define memchr(buf, ch, count)              ScanMem8(buf, (UINTN)(count),(UINT8)ch)
+#define memcmp(buf1, buf2, count)           (int)(CompareMem(buf1, buf2, (UINTN)(count)))
+#define memmove(dest, source, count)        CopyMem(dest, source, (UINTN)(count))
+#define strlen(str)                         (size_t)(AsciiStrLen(str))
+#define strnlen(str, count)                 (size_t)(AsciiStrnLenS(str, count))
+#define strncpy(strDest, strSource, count)  AsciiStrnCpyS(strDest, MAX_STRING_SIZE, strSource, (UINTN)count)
+#define strcat(strDest, strSource)          AsciiStrCatS(strDest, MAX_STRING_SIZE, strSource)
+#define strcmp(string1, string2, count)     (int)(AsciiStrCmp(string1, string2))
+#define strncmp(string1, string2, count)    (int)(AsciiStrnCmp(string1, string2, (UINTN)(count)))
+
+#endif /* FDT_LIB_SUPPORT_H_ */
diff --git a/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c b/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
new file mode 100644
index 0000000000..ef6452914f
--- /dev/null
+++ b/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
@@ -0,0 +1,173 @@
+/** @file
+  ISO C implementations of strchr, strrchr and strtoul.
+
+  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2023 Pedro Falcato All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+
+#define ULONG_MAX  0xFFFFFFFF            /* Maximum unsigned long value */
+
+// Very quick notes:
+// We only go through the string once for both functions
+// They are minimal implementations (not speed optimized) of ISO C semantics
+// strchr and strrchr also include the null terminator as part of the string
+// so the code gets a bit clunky to handle that case specifically.
+
+char *
+strchr (
+  const char  *Str,
+  int         Char
+  )
+{
+  char  *S;
+
+  S = (char *)Str;
+
+  for ( ; ; S++) {
+    if (*S == Char) {
+      return S;
+    }
+
+    if (*S == '\0') {
+      return NULL;
+    }
+  }
+}
+
+char *
+strrchr (
+  const char  *Str,
+  int         Char
+  )
+{
+  char  *S, *last;
+
+  S    = (char *)Str;
+  last = NULL;
+
+  for ( ; ; S++) {
+    if (*S == Char) {
+      last = S;
+    }
+
+    if (*S == '\0') {
+      return last;
+    }
+  }
+}
+
+STATIC
+int
+__isspace (
+  int  ch
+  )
+{
+  // basic ASCII ctype.h:isspace(). Not efficient
+  return ch == '\r' || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f';
+}
+
+unsigned long
+strtoul (
+  const char  *Nptr,
+  char        **EndPtr,
+  int         Base
+  )
+{
+  BOOLEAN        Negate;
+  BOOLEAN        Overflow;
+  unsigned long  Val;
+
+  Negate   = FALSE;
+  Overflow = FALSE;
+  Val      = 0;
+
+  // Reject bad numeric bases
+  if ((Base < 0) || (Base == 1) || (Base > 36)) {
+    return 0;
+  }
+
+  // Skip whitespace
+  while (__isspace (*Nptr)) {
+    Nptr++;
+  }
+
+  // Check for + or - prefixes
+  if (*Nptr == '-') {
+    Negate = TRUE;
+    Nptr++;
+  } else if (*Nptr == '+') {
+    Nptr++;
+  }
+
+  // Consume the start, autodetecting base if needed
+  if ((Nptr[0] == '0') && ((Nptr[1] == 'x') || (Nptr[1] == 'X')) && ((Base == 0) || (Base == 16))) {
+    // Hex
+    Nptr += 2;
+    Base  = 16;
+  } else if ((Nptr[0] == '0') && ((Nptr[1] == 'b') || (Nptr[1] == 'B')) && ((Base == 0) || (Base == 2))) {
+    // Binary (standard pending C23)
+    Nptr += 2;
+    Base  = 2;
+  } else if ((Nptr[0] == '0') && ((Base == 0) || (Base == 8))) {
+    // Octal
+    Nptr++;
+    Base = 8;
+  } else {
+    if (Base == 0) {
+      // Assume decimal
+      Base = 10;
+    }
+  }
+
+  while (TRUE) {
+    int            Digit;
+    char           C;
+    unsigned long  NewVal;
+
+    C     = *Nptr;
+    Digit = -1;
+
+    if ((C >= '0') && (C <= '9')) {
+      Digit = C - '0';
+    } else if ((C >= 'a') && (C <= 'z')) {
+      Digit = C - 'a' + 10;
+    } else if ((C >= 'A') && (C <= 'Z')) {
+      Digit = C - 'A' + 10;
+    }
+
+    if ((Digit == -1) || (Digit >= Base)) {
+      // Note that this case also handles the \0
+      if (EndPtr) {
+        *EndPtr = (char *)Nptr;
+      }
+
+      break;
+    }
+
+    NewVal = Val * Base + Digit;
+
+    if (NewVal < Val) {
+      // Overflow
+      Overflow = TRUE;
+    }
+
+    Val = NewVal;
+
+    Nptr++;
+  }
+
+  if (Negate) {
+    Val = -Val;
+  }
+
+  if (Overflow) {
+    Val = ULONG_MAX;
+  }
+
+  // TODO: We're lacking errno here.
+  return Val;
+}
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
+  Include file to support building the third-party libfdt library.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <LibFdtSupport.h>
+
diff --git a/MdePkg/Library/BaseFdtLib/stdbool.h b/MdePkg/Library/BaseFdtLib/stdbool.h
new file mode 100644
index 0000000000..f6cf8d5702
--- /dev/null
+++ b/MdePkg/Library/BaseFdtLib/stdbool.h
@@ -0,0 +1,10 @@
+/** @file
+  Include file to support building the third-party libfdt library.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <LibFdtSupport.h>
+
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
+  Include file to support building the third-party libfdt library.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <LibFdtSupport.h>
+
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
+  Include file to support building the third-party libfdt library.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <LibFdtSupport.h>
+
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
+  Include file to support building the third-party libfdt library.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <LibFdtSupport.h>
+
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
+  Include file to support building the third-party libfdt library.
+
+Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <LibFdtSupport.h>
+
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",
             "Include/Library/SafeIntLib.h",
             "Include/Protocol/DebugSupport.h",
-            "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c"
+            "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c",
+            "Library/BaseFdtLib"
         ]
     },
     ## options defined ci/Plugin/CompilerPlugin
@@ -164,5 +165,17 @@
         "ExtendWords": [],           # words to extend to the dictionary for this package
         "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should be ignore
         "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards supported)
+    },
+    # options defined in .pytool/Plugin/UncrustifyCheck
+    "UncrustifyCheck": {
+        "IgnoreFiles": [
+            "Library/BaseFdtLib/libfdt",
+            "Library/BaseFdtLib/limits.h",
+            "Library/BaseFdtLib/stdbool.h",
+            "Library/BaseFdtLib/stddef.h",
+            "Library/BaseFdtLib/stdint.h",
+            "Library/BaseFdtLib/stdlib.h",
+            "Library/BaseFdtLib/string.h"
+        ]
     }
 }
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 @@
   #
   ArmTrngLib|Include/Library/ArmTrngLib.h
 
+  ##  @libraryclass  Provides APIs for third-party library libfdt.
+  #
+  FdtLib|Include/Library/FdtLib.h
+
 [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]
   ##  @libraryclass  Provides services to generate random number.
   #
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
 
   MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf
+  MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
 
 [Components.IA32, Components.X64, Components.ARM, Components.AARCH64]
   #
-- 
2.39.1.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v6 3/3] .pytool: Support FDT library.
  2023-05-04  5:57 [PATCH v6 0/3] Support FDT library Benny Lin
  2023-05-04  5:57 ` [PATCH v6 1/3] Tianocore: " Benny Lin
  2023-05-04  5:57 ` [PATCH v6 2/3] MdePkg: " Benny Lin
@ 2023-05-04  5:57 ` Benny Lin
  2 siblings, 0 replies; 6+ messages in thread
From: Benny Lin @ 2023-05-04  5:57 UTC (permalink / raw)
  To: devel; +Cc: Benny Lin, Michael D Kinney, Sean Brogan, Michael Kubacki,
	Liming Gao

From: Benny Lin <benny.lin@intel.com>

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4392
Add FDT support in EDK2 by submodule 3rd party libfdt
(https://github.com/devicetree-org/pylibfdt/tree/main/libfdt)

Add RequiredSubmodule object for CI setting.

Reviewed-by: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael Kubacki <mikuback@linux.microsoft.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Benny Lin <benny.lin@intel.com>
---
 .pytool/CISettings.py | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.pytool/CISettings.py b/.pytool/CISettings.py
index e3f44add58..2fb99f2a17 100644
--- a/.pytool/CISettings.py
+++ b/.pytool/CISettings.py
@@ -195,6 +195,8 @@ class Settings(CiBuildSettingsManager, UpdateSettingsManager, SetupSettingsManag
             "RedfishPkg/Library/JsonLib/jansson", False))
         rs.append(RequiredSubmodule(
             "UnitTestFrameworkPkg/Library/SubhookLib/subhook", False))
+        rs.append(RequiredSubmodule(
+            "MdePkg/Library/BaseFdtLib/libfdt", False))
         return rs
 
     def GetName(self):
-- 
2.39.1.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v6 2/3] MdePkg: Support FDT library.
  2023-05-04  5:57 ` [PATCH v6 2/3] MdePkg: " Benny Lin
@ 2023-05-04 18:01   ` Michael D Kinney
  2023-05-04 23:02     ` [edk2-devel] " Chiu, Chasel
  0 siblings, 1 reply; 6+ messages in thread
From: Michael D Kinney @ 2023-05-04 18:01 UTC (permalink / raw)
  To: Lin, Benny, devel@edk2.groups.io
  Cc: Gao, Liming, Liu, Zhiguang, Pedro Falcato, Kinney, Michael D

Hi Benny,

A couple comments below.

Mike

> -----Original Message-----
> From: Lin, Benny <benny.lin@intel.com>
> Sent: Wednesday, May 3, 2023 10:57 PM
> To: devel@edk2.groups.io
> Cc: Lin, Benny <benny.lin@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Liu,
> Zhiguang <zhiguang.liu@intel.com>; Pedro Falcato
> <pedro.falcato@gmail.com>
> Subject: [PATCH v6 2/3] MdePkg: Support FDT library.
> 
> From: Benny Lin <benny.lin@intel.com>
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4392
> 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 <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> Acked-by: Pedro Falcato <pedro.falcato@gmail.com>
> Signed-off-by: Benny Lin <benny.lin@intel.com>
> ---
>  MdePkg/Include/Library/FdtLib.h           | 396 +++++++++++++++++++
>  MdePkg/Library/BaseFdtLib/BaseFdtLib.inf  |  62 +++
>  MdePkg/Library/BaseFdtLib/BaseFdtLib.uni  |  14 +
>  MdePkg/Library/BaseFdtLib/FdtLib.c        | 404 ++++++++++++++++++++
>  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, 1227 insertions(+), 1 deletion(-)
> 
> diff --git a/MdePkg/Include/Library/FdtLib.h
> b/MdePkg/Include/Library/FdtLib.h
> new file mode 100644
> index 0000000000..4b428eb5d1
> --- /dev/null
> +++ b/MdePkg/Include/Library/FdtLib.h
> @@ -0,0 +1,396 @@
> +/** @file
> 
> +  Flattened Device Tree Library.
> 
> +
> 
> +  All structure data are in big-endian format. Need to call SwapBytes**
> 
> +  function to convert between little-endia and big-endian.

I would remove all references to SwapBytes in this lib class header and
Instead mention that the FdtToCpu and CpuToFdt services are provided
To support conversion between big endian FDT format and the CPUs
native endian format.

> 
> +  For example, pushing data to FDT blob need convert to big-endian with
> SwapByte**.
> 
> +  For retrieving data from FDT blob need convert to little-endian with
> SwapByte**.
> 
> +  Refer to FDT specification: https://www.devicetree.org/specifications/
> 
> +
> 
> +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#ifndef FDT_LIB_H_
> 
> +#define FDT_LIB_H_
> 
> +
> 
> +/**
> 
> +  Flattened Device Tree definition
> 
> +
> 
> +  The Devicetree Blob (DTB) format is a binary encoding with big-endian.
> 
> +  When producing or consuming the blob data, must convert with
> SwapBytesXX
> 
> +  provided by edk2 BaseLib between big-endian and little-endian.
> 
> +**/
> 
> +typedef struct {
> 
> +  UINT32    Magic;               /* magic word FDT_MAGIC */
> 
> +  UINT32    TotalSize;           /* total size of DT block */
> 
> +  UINT32    OffsetDtStruct;      /* offset to structure */
> 
> +  UINT32    OffsetDtStrings;     /* offset to strings */
> 
> +  UINT32    OffsetMemRsvmap;     /* offset to memory reserve map */
> 
> +  UINT32    Version;             /* format version */
> 
> +  UINT32    LastCompVersion;     /* last compatible version */
> 
> +
> 
> +  /* version 2 fields below */
> 
> +  UINT32    BootCpuidPhys;       /* Which physical CPU id we're
> 
> +                                    booting on */
> 
> +  /* version 3 fields below */
> 
> +  UINT32    SizeDtStrings;       /* size of the strings block */
> 
> +
> 
> +  /* version 17 fields below */
> 
> +  UINT32    SizeDtStruct;        /* size of the structure block */
> 
> +} FDT_HEADER;
> 
> +
> 
> +typedef struct {
> 
> +  UINT64    Address;
> 
> +  UINT64    Size;
> 
> +} FDT_RESERVE_ENTRY;
> 
> +
> 
> +typedef struct {
> 
> +  UINT32    Tag;
> 
> +  CHAR8     Name[];
> 
> +} FDT_NODE_HEADER;
> 
> +
> 
> +typedef struct {
> 
> +  UINT32    Tag;
> 
> +  UINT32    Length;
> 
> +  UINT32    NameOffset;
> 
> +  CHAR8     Data[];
> 
> +} FDT_PROPERTY;
> 
> +
> 
> +/**
> 
> +  Convert UINT16 data of the FDT blob to little-endian
> 
> +
> 
> +  @param[in] Value            The value to the blob data.
> 
> +
> 
> +  @return The value to be converted to little-endian.
> 
> +
> 
> +**/
> 
> +UINT16
> 
> +EFIAPI
> 
> +Fdt16ToCpu (
> 
> +  IN UINT16  Value
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Convert UINT16 data to big-endian for aligned with the FDT blob
> 
> +
> 
> +  @param[in] Value            The value to align with the FDT blob.
> 
> +
> 
> +  @return The value to be converted to big-endian.
> 
> +
> 
> +**/
> 
> +UINT16
> 
> +EFIAPI
> 
> +CpuToFdt16 (
> 
> +  IN UINT16  Value
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Convert UINT32 data of the FDT blob to little-endian
> 
> +
> 
> +  @param[in] Value            The value to the blob data.
> 
> +
> 
> +  @return The value to be converted to little-endian.
> 
> +
> 
> +**/
> 
> +UINT32
> 
> +EFIAPI
> 
> +Fdt32ToCpu (
> 
> +  IN UINT32  Value
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Convert UINT32 data to big-endian for aligned with the FDT blob
> 
> +
> 
> +  @param[in] Value            The value to align with the FDT blob.
> 
> +
> 
> +  @return The value to be converted to big-endian.
> 
> +
> 
> +**/
> 
> +UINT32
> 
> +EFIAPI
> 
> +CpuToFdt32 (
> 
> +  IN UINT32  Value
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Convert UINT64 data of the FDT blob to little-endian
> 
> +
> 
> +  @param[in] Value            The value to the blob data.
> 
> +
> 
> +  @return The value to be converted to little-endian.
> 
> +
> 
> +**/
> 
> +UINT64
> 
> +EFIAPI
> 
> +Fdt64ToCpu (
> 
> +  IN UINT64  Value
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Convert UINT64 data to big-endian for aligned with the FDT blob
> 
> +
> 
> +  @param[in] Value            The value to align with the FDT blob.
> 
> +
> 
> +  @return The value to be converted to big-endian.
> 
> +
> 
> +**/
> 
> +UINT64
> 
> +EFIAPI
> 
> +CpuToFdt64 (
> 
> +  IN UINT64  Value
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Verify the header of the Flattened Device Tree
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +
> 
> +  @return Zero for successfully, otherwise failed.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtCheckHeader (
> 
> +  IN CONST VOID  *Fdt
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Create a empty Flattened Device Tree.
> 
> +
> 
> +  @param[in] Buffer         The pointer to allocate a pool for FDT blob.
> 
> +  @param[in] BufferSize     The BufferSize to the pool size.
> 
> +
> 
> +  @return Zero for successfully, otherwise failed.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtCreateEmptyTree (
> 
> +  IN VOID    *Buffer,
> 
> +  IN UINT32  BufferSize
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a offset of next node from the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous node.
> 
> +  @param[in] Depth          The depth to the level of tree hierarchy.
> 
> +
> 
> +  @return The offset to next node offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNextNode (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset,
> 
> +  IN INT32       *Depth
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a offset of first node under the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous node.
> 
> +
> 
> +  @return The offset to next node offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtFirstSubnode (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a offset of next node from the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous node.
> 
> +
> 
> +  @return The offset to next node offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNextSubnode (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a offset of first node which includes the given name.
> 
> +
> 
> +  @param[in] Fdt             The pointer to FDT blob.
> 
> +  @param[in] ParentOffset    The offset to the node which start find under.
> 
> +  @param[in] Name            The name to search the node with the name.
> 
> +  @param[in] NameLength      The length of the name to check only.
> 
> +
> 
> +  @return The offset to node offset with given node name.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtSubnodeOffsetNameLen (
> 
> +  IN CONST VOID   *Fdt,
> 
> +  IN INT32        ParentOffset,
> 
> +  IN CONST CHAR8  *Name,
> 
> +  IN INT32        NameLength
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a offset of first node which includes the given property name and
> value.
> 
> +
> 
> +  @param[in] Fdt             The pointer to FDT blob.
> 
> +  @param[in] StartOffset     The offset to the starting node to find.
> 
> +  @param[in] PropertyName    The property name to search the node
> including the named property.
> 
> +  @param[in] PropertyValue   The property value (big-endian) to check the
> same property value.
> 
> +  @param[in] PropertyLength  The length of the value in PropertValue.
> 
> +
> 
> +  @return The offset to node offset with given property.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNodeOffsetByPropValue (
> 
> +  IN CONST VOID   *Fdt,
> 
> +  IN INT32        StartOffset,
> 
> +  IN CONST CHAR8  *PropertyName,
> 
> +  IN CONST VOID   *PropertyValue,
> 
> +  IN INT32        PropertyLength
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a property with the given name from the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] NodeOffset     The offset to the given node.
> 
> +  @param[in] Name           The name to the property which need be searched
> 
> +  @param[in] Length         The length to the size of the property found.
> 
> +
> 
> +  @return The property to the structure of the found property. Since the
> data
> 
> +          come from FDT blob, it's encoding with big-endian.
> 
> +
> 
> +**/
> 
> +CONST FDT_PROPERTY *
> 
> +EFIAPI
> 
> +FdtGetProperty (
> 
> +  IN CONST VOID   *Fdt,
> 
> +  IN INT32        NodeOffset,
> 
> +  IN CONST CHAR8  *Name,
> 
> +  IN INT32        *Length
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a offset of first property in the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] NodeOffset     The offset to the node which need be searched.
> 
> +
> 
> +  @return The offset to first property offset in the given node.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtFirstPropertyOffset (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       NodeOffset
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a offset of next property from the given property.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous property.
> 
> +
> 
> +  @return The offset to next property offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNextPropertyOffset (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a property from the given offset of the property.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to the given offset of the property.
> 
> +  @param[in] Length         The length to the size of the property found.
> 
> +
> 
> +  @return The property to the structure of the given property offset.
> 
> +
> 
> +**/
> 
> +CONST FDT_PROPERTY *
> 
> +EFIAPI
> 
> +FdtGetPropertyByOffset (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset,
> 
> +  IN INT32       *Length
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Returns a string by the given string offset.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] StrOffset      The offset to the location in the strings block of
> FDT.
> 
> +  @param[in] Length         The length to the size of string which need be
> retrieved.
> 
> +
> 
> +  @return The string to the given string offset.
> 
> +
> 
> +**/
> 
> +CONST CHAR8 *
> 
> +EFIAPI
> 
> +FdtGetString (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       StrOffset,
> 
> +  IN INT32       *Length        OPTIONAL
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Add a new node to the FDT.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] ParentOffset   The offset to the node offset which want to add
> in.
> 
> +  @param[in] Name           The name to name the node.
> 
> +
> 
> +  @return  The offset to the new node.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtAddSubnode (
> 
> +  IN VOID         *Fdt,
> 
> +  IN INT32        ParentOffset,
> 
> +  IN CONST CHAR8  *Name
> 
> +  );
> 
> +
> 
> +/**
> 
> +  Add or modify a property in the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] NodeOffset     The offset to the node offset which want to add
> in.
> 
> +  @param[in] Name           The name to name the property.
> 
> +  @param[in] Value          The value (big-endian) to the property value.
> 
> +  @param[in] Length         The length to the size of the property.
> 
> +
> 
> +  @return  Zero for successfully, otherwise failed.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtSetProp (
> 
> +  IN VOID         *Fdt,
> 
> +  IN INT32        NodeOffset,
> 
> +  IN CONST CHAR8  *Name,
> 
> +  IN CONST VOID   *Value,
> 
> +  IN UINT32       Length
> 
> +  );
> 
> +
> 
> +#endif /* FDT_LIB_H_ */
> 
> diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> new file mode 100644
> index 0000000000..730e568ff6
> --- /dev/null
> +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> @@ -0,0 +1,62 @@
> +## @file
> 
> +# Flattened Device Tree Library.
> 
> +#
> 
> +# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +#
> 
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +#
> 
> +#
> 
> +##
> 
> +
> 
> +[Defines]
> 
> +  INF_VERSION                    = 0x0001001B
> 
> +  BASE_NAME                      = BaseFdtLib
> 
> +  MODULE_UNI_FILE                = BaseFdtLib.uni
> 
> +  FILE_GUID                      = C64DCB01-B037-4FF6-9CF3-E8CEC206DE04
> 
> +  MODULE_TYPE                    = BASE
> 
> +  VERSION_STRING                 = 1.0
> 
> +  LIBRARY_CLASS                  = FdtLib
> 
> +
> 
> +  DEFINE FDT_LIB_PATH            = libfdt/libfdt
> 
> +
> 
> +#
> 
> +#  VALID_ARCHITECTURES           = IA32 X64
> 
> +#
> 
> +
> 
> +[Sources]
> 
> +  FdtLib.c
> 
> +  LibFdtWrapper.c
> 
> +  # header Wrapper files
> 
> +  limits.h
> 
> +  stdbool.h
> 
> +  stddef.h
> 
> +  stdint.h
> 
> +  stdlib.h
> 
> +  string.h
> 
> +
> 
> +  $(FDT_LIB_PATH)/fdt.c
> 
> +  $(FDT_LIB_PATH)/fdt.h
> 
> +  $(FDT_LIB_PATH)/fdt_addresses.c
> 
> +  $(FDT_LIB_PATH)/fdt_check.c
> 
> +  $(FDT_LIB_PATH)/fdt_empty_tree.c
> 
> +  $(FDT_LIB_PATH)/fdt_overlay.c
> 
> +  $(FDT_LIB_PATH)/fdt_ro.c
> 
> +  $(FDT_LIB_PATH)/fdt_rw.c
> 
> +  $(FDT_LIB_PATH)/fdt_strerror.c
> 
> +  $(FDT_LIB_PATH)/fdt_sw.c
> 
> +  $(FDT_LIB_PATH)/fdt_wip.c
> 
> +  $(FDT_LIB_PATH)/libfdt.h
> 
> +  $(FDT_LIB_PATH)/libfdt_env.h
> 
> +  $(FDT_LIB_PATH)/libfdt_internal.h
> 
> +
> 
> +[Packages]
> 
> +  MdePkg/MdePkg.dec
> 
> +
> 
> +[LibraryClasses]
> 
> +  BaseLib
> 
> +  BaseMemoryLib
> 
> +
> 
> +[BuildOptions]
> 
> +  MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245
> 
> +  MSFT:*_*_X64_CC_FLAGS  = /wd4146 /wd4244 /wd4245 /wd4267
> 
> +
> 
> diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
> b/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
> new file mode 100644
> index 0000000000..3f7e45ea6f
> --- /dev/null
> +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
> @@ -0,0 +1,14 @@
> +// /** @file
> 
> +// Flattened Device Tree Library.
> 
> +//
> 
> +// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +//
> 
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +//
> 
> +// **/
> 
> +
> 
> +
> 
> +#string STR_MODULE_ABSTRACT             #language en-US "Instance of FDT
> Library"
> 
> +
> 
> +#string STR_MODULE_DESCRIPTION          #language en-US "This module
> provides FDT Library implementation."
> 
> +
> 
> diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c
> b/MdePkg/Library/BaseFdtLib/FdtLib.c
> new file mode 100644
> index 0000000000..090b0b3fd4
> --- /dev/null
> +++ b/MdePkg/Library/BaseFdtLib/FdtLib.c
> @@ -0,0 +1,404 @@
> +/** @file
> 
> +  Flattened Device Tree Library.
> 
> +
> 
> +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <libfdt/libfdt/libfdt.h>
> 
> +
> 
> +/**
> 
> +  Convert UINT16 data of the FDT blob to little-endian
> 
> +
> 
> +  @param[in] Value            The value to the blob data.
> 
> +
> 
> +  @return The value to be converted to little-endian.
> 
> +
> 
> +**/
> 
> +UINT16
> 
> +EFIAPI
> 
> +Fdt16ToCpu (
> 
> +  IN UINT16  Value
> 
> +  )
> 
> +{
> 
> +  return fdt16_to_cpu (Value);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Convert UINT16 data to big-endian for aligned with the FDT blob
> 
> +
> 
> +  @param[in] Value            The value to align with the FDT blob.
> 
> +
> 
> +  @return The value to be converted to big-endian.
> 
> +
> 
> +**/
> 
> +UINT16
> 
> +EFIAPI
> 
> +CpuToFdt16 (
> 
> +  IN UINT16  Value
> 
> +  )
> 
> +{
> 
> +  return cpu_to_fdt16 (Value);

I think the implementation of these APIs should just use the BaseLib
SwapBytesxx() APIs.  Is there a reason this approach was selected?

> 
> +}
> 
> +
> 
> +/**
> 
> +  Convert UINT32 data of the FDT blob to little-endian
> 
> +
> 
> +  @param[in] Value            The value to the blob data.
> 
> +
> 
> +  @return The value to be converted to little-endian.
> 
> +
> 
> +**/
> 
> +UINT32
> 
> +EFIAPI
> 
> +Fdt32ToCpu (
> 
> +  IN UINT32  Value
> 
> +  )
> 
> +{
> 
> +  return fdt32_to_cpu (Value);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Convert UINT32 data to big-endian for aligned with the FDT blob
> 
> +
> 
> +  @param[in] Value            The value to align with the FDT blob.
> 
> +
> 
> +  @return The value to be converted to big-endian.
> 
> +
> 
> +**/
> 
> +UINT32
> 
> +EFIAPI
> 
> +CpuToFdt32 (
> 
> +  IN UINT32  Value
> 
> +  )
> 
> +{
> 
> +  return cpu_to_fdt32 (Value);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Convert UINT64 data of the FDT blob to little-endian
> 
> +
> 
> +  @param[in] Value            The value to the blob data.
> 
> +
> 
> +  @return The value to be converted to little-endian.
> 
> +
> 
> +**/
> 
> +UINT64
> 
> +EFIAPI
> 
> +Fdt64ToCpu (
> 
> +  IN UINT64  Value
> 
> +  )
> 
> +{
> 
> +  return fdt64_to_cpu (Value);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Convert UINT64 data to big-endian for aligned with the FDT blob
> 
> +
> 
> +  @param[in] Value            The value to align with the FDT blob.
> 
> +
> 
> +  @return The value to be converted to big-endian.
> 
> +
> 
> +**/
> 
> +UINT64
> 
> +EFIAPI
> 
> +CpuToFdt64 (
> 
> +  IN UINT64  Value
> 
> +  )
> 
> +{
> 
> +  return cpu_to_fdt64 (Value);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Verify the header of the Flattened Device Tree
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +
> 
> +  @return Zero for successfully, otherwise failed.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtCheckHeader (
> 
> +  IN CONST VOID  *Fdt
> 
> +  )
> 
> +{
> 
> +  return fdt_check_header (Fdt);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Create a empty Flattened Device Tree.
> 
> +
> 
> +  @param[in] Buffer         The pointer to allocate a pool for FDT blob.
> 
> +  @param[in] BufferSize     The BufferSize to the pool size.
> 
> +
> 
> +  @return Zero for successfully, otherwise failed.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtCreateEmptyTree (
> 
> +  IN VOID    *Buffer,
> 
> +  IN UINT32  BufferSize
> 
> +  )
> 
> +{
> 
> +  return fdt_create_empty_tree (Buffer, (int)BufferSize);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a offset of next node from the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous node.
> 
> +  @param[in] Depth          The depth to the level of tree hierarchy.
> 
> +
> 
> +  @return The offset to next node offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNextNode (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset,
> 
> +  IN INT32       *Depth
> 
> +  )
> 
> +{
> 
> +  return fdt_next_node (Fdt, Offset, Depth);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a offset of first node under the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous node.
> 
> +
> 
> +  @return The offset to next node offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtFirstSubnode (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset
> 
> +  )
> 
> +{
> 
> +  return fdt_first_subnode (Fdt, Offset);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a offset of next node from the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous node.
> 
> +
> 
> +  @return The offset to next node offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNextSubnode (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset
> 
> +  )
> 
> +{
> 
> +  return fdt_next_subnode (Fdt, Offset);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a offset of first node which includes the given name.
> 
> +
> 
> +  @param[in] Fdt             The pointer to FDT blob.
> 
> +  @param[in] ParentOffset    The offset to the node which start find under.
> 
> +  @param[in] Name            The name to search the node with the name.
> 
> +  @param[in] NameLength      The length of the name to check only.
> 
> +
> 
> +  @return The offset to node offset with given node name.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtSubnodeOffsetNameLen (
> 
> +  IN CONST VOID   *Fdt,
> 
> +  IN INT32        ParentOffset,
> 
> +  IN CONST CHAR8  *Name,
> 
> +  IN INT32        NameLength
> 
> +  )
> 
> +{
> 
> +  return fdt_subnode_offset_namelen (Fdt, ParentOffset, Name,
> NameLength);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a offset of first node which includes the given property name and
> value.
> 
> +
> 
> +  @param[in] Fdt             The pointer to FDT blob.
> 
> +  @param[in] StartOffset     The offset to the starting node to find.
> 
> +  @param[in] PropertyName    The property name to search the node
> including the named property.
> 
> +  @param[in] PropertyValue   The property value (big-endian) to check the
> same property value.
> 
> +  @param[in] PropertyLength  The length of the value in PropertValue.
> 
> +
> 
> +  @return The offset to node offset with given property.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNodeOffsetByPropValue (
> 
> +  IN CONST VOID   *Fdt,
> 
> +  IN INT32        StartOffset,
> 
> +  IN CONST CHAR8  *PropertyName,
> 
> +  IN CONST VOID   *PropertyValue,
> 
> +  IN INT32        PropertyLength
> 
> +  )
> 
> +{
> 
> +  return fdt_node_offset_by_prop_value (Fdt, StartOffset, PropertyName,
> PropertyValue, PropertyLength);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a property with the given name from the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] NodeOffset     The offset to the given node.
> 
> +  @param[in] Name           The name to the property which need be searched
> 
> +  @param[in] Length         The length to the size of the property found.
> 
> +
> 
> +  @return The property to the structure of the found property. Since the
> data
> 
> +          come from FDT blob, it's encoding with big-endian.
> 
> +
> 
> +**/
> 
> +CONST struct fdt_property *
> 
> +EFIAPI
> 
> +FdtGetProperty (
> 
> +  IN CONST VOID   *Fdt,
> 
> +  IN INT32        NodeOffset,
> 
> +  IN CONST CHAR8  *Name,
> 
> +  IN INT32        *Length
> 
> +  )
> 
> +{
> 
> +  return fdt_get_property (Fdt, NodeOffset, Name, Length);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a offset of first property in the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] NodeOffset     The offset to the node which need be searched.
> 
> +
> 
> +  @return The offset to first property offset in the given node.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtFirstPropertyOffset (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       NodeOffset
> 
> +  )
> 
> +{
> 
> +  return fdt_first_property_offset (Fdt, NodeOffset);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a offset of next property from the given property.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to previous property.
> 
> +
> 
> +  @return The offset to next property offset.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtNextPropertyOffset (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset
> 
> +  )
> 
> +{
> 
> +  return fdt_next_property_offset (Fdt, Offset);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a property from the given offset of the property.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] Offset         The offset to the given offset of the property.
> 
> +  @param[in] Length         The length to the size of the property found.
> 
> +
> 
> +  @return The property to the structure of the given property offset.
> 
> +
> 
> +**/
> 
> +CONST struct fdt_property *
> 
> +EFIAPI
> 
> +FdtGetPropertyByOffset (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       Offset,
> 
> +  IN INT32       *Length
> 
> +  )
> 
> +{
> 
> +  return fdt_get_property_by_offset (Fdt, Offset, Length);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Returns a string by the given string offset.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] StrOffset      The offset to the location in the strings block of
> FDT.
> 
> +  @param[in] Length         The length to the size of string which need be
> retrieved.
> 
> +
> 
> +  @return The string to the given string offset.
> 
> +
> 
> +**/
> 
> +CONST CHAR8 *
> 
> +EFIAPI
> 
> +FdtGetString (
> 
> +  IN CONST VOID  *Fdt,
> 
> +  IN INT32       StrOffset,
> 
> +  IN INT32       *Length        OPTIONAL
> 
> +  )
> 
> +{
> 
> +  return fdt_get_string (Fdt, StrOffset, Length);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Add a new node to the FDT.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] ParentOffset   The offset to the node offset which want to add
> in.
> 
> +  @param[in] Name           The name to name the node.
> 
> +
> 
> +  @return  The offset to the new node.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtAddSubnode (
> 
> +  IN VOID         *Fdt,
> 
> +  IN INT32        ParentOffset,
> 
> +  IN CONST CHAR8  *Name
> 
> +  )
> 
> +{
> 
> +  return fdt_add_subnode (Fdt, ParentOffset, Name);
> 
> +}
> 
> +
> 
> +/**
> 
> +  Add or modify a property in the given node.
> 
> +
> 
> +  @param[in] Fdt            The pointer to FDT blob.
> 
> +  @param[in] NodeOffset     The offset to the node offset which want to add
> in.
> 
> +  @param[in] Name           The name to name the property.
> 
> +  @param[in] Value          The value (big-endian) to the property value.
> 
> +  @param[in] Length         The length to the size of the property.
> 
> +
> 
> +  @return  Zero for successfully, otherwise failed.
> 
> +
> 
> +**/
> 
> +INT32
> 
> +EFIAPI
> 
> +FdtSetProp (
> 
> +  IN VOID         *Fdt,
> 
> +  IN INT32        NodeOffset,
> 
> +  IN CONST CHAR8  *Name,
> 
> +  IN CONST VOID   *Value,
> 
> +  IN UINT32       Length
> 
> +  )
> 
> +{
> 
> +  return fdt_setprop (Fdt, NodeOffset, Name, Value, (int)Length);
> 
> +}
> 
> diff --git a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
> b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
> new file mode 100644
> index 0000000000..393019324b
> --- /dev/null
> +++ b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
> @@ -0,0 +1,99 @@
> +/** @file
> 
> +  Root include file of C runtime library to support building the third-party
> 
> +  libfdt library.
> 
> +
> 
> +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#ifndef FDT_LIB_SUPPORT_H_
> 
> +#define FDT_LIB_SUPPORT_H_
> 
> +
> 
> +#include <Base.h>
> 
> +#include <Library/BaseLib.h>
> 
> +#include <Library/BaseMemoryLib.h>
> 
> +
> 
> +typedef UINT8    uint8_t;
> 
> +typedef UINT16   uint16_t;
> 
> +typedef INT32    int32_t;
> 
> +typedef UINT32   uint32_t;
> 
> +typedef UINT64   uint64_t;
> 
> +typedef UINTN    uintptr_t;
> 
> +typedef UINTN    size_t;
> 
> +typedef BOOLEAN  bool;
> 
> +
> 
> +#define true   (1 == 1)
> 
> +#define false  (1 == 0)
> 
> +
> 
> +//
> 
> +// Definitions for global constants used by libfdt library routines
> 
> +//
> 
> +#define INT_MAX     0x7FFFFFFF           /* Maximum (signed) int value */
> 
> +#define INT32_MAX   0x7FFFFFFF           /* Maximum (signed) int32 value */
> 
> +#define UINT32_MAX  0xFFFFFFFF           /* Maximum unsigned int32 value */
> 
> +
> 
> +//
> 
> +// Function prototypes of libfdt Library routines
> 
> +//
> 
> +void *
> 
> +memset     (
> 
> +  void *,
> 
> +  int,
> 
> +  size_t
> 
> +  );
> 
> +
> 
> +int
> 
> +memcmp      (
> 
> +  const void *,
> 
> +  const void *,
> 
> +  size_t
> 
> +  );
> 
> +
> 
> +int
> 
> +strcmp      (
> 
> +  const char *,
> 
> +  const char *
> 
> +  );
> 
> +
> 
> +char *
> 
> +strchr     (
> 
> +  const char *,
> 
> +  int
> 
> +  );
> 
> +
> 
> +char *
> 
> +strrchr    (
> 
> +  const char *,
> 
> +  int
> 
> +  );
> 
> +
> 
> +unsigned long
> 
> +strtoul     (
> 
> +  const char *,
> 
> +  char **,
> 
> +  int
> 
> +  );
> 
> +
> 
> +char *
> 
> +strcpy (
> 
> +  char        *strDest,
> 
> +  const char  *strSource
> 
> +  );
> 
> +
> 
> +//
> 
> +// Macros that directly map functions to BaseLib, BaseMemoryLib, and
> DebugLib functions
> 
> +//
> 
> +#define memcpy(dest, source, count)         CopyMem(dest,source,
> (UINTN)(count))
> 
> +#define memset(dest, ch, count)             SetMem(dest,
> (UINTN)(count),(UINT8)(ch))
> 
> +#define memchr(buf, ch, count)              ScanMem8(buf,
> (UINTN)(count),(UINT8)ch)
> 
> +#define memcmp(buf1, buf2, count)           (int)(CompareMem(buf1, buf2,
> (UINTN)(count)))
> 
> +#define memmove(dest, source, count)        CopyMem(dest, source,
> (UINTN)(count))
> 
> +#define strlen(str)                         (size_t)(AsciiStrLen(str))
> 
> +#define strnlen(str, count)                 (size_t)(AsciiStrnLenS(str, count))
> 
> +#define strncpy(strDest, strSource, count)  AsciiStrnCpyS(strDest,
> MAX_STRING_SIZE, strSource, (UINTN)count)
> 
> +#define strcat(strDest, strSource)          AsciiStrCatS(strDest,
> MAX_STRING_SIZE, strSource)
> 
> +#define strcmp(string1, string2, count)     (int)(AsciiStrCmp(string1, string2))
> 
> +#define strncmp(string1, string2, count)    (int)(AsciiStrnCmp(string1, string2,
> (UINTN)(count)))
> 
> +
> 
> +#endif /* FDT_LIB_SUPPORT_H_ */
> 
> diff --git a/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
> b/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
> new file mode 100644
> index 0000000000..ef6452914f
> --- /dev/null
> +++ b/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
> @@ -0,0 +1,173 @@
> +/** @file
> 
> +  ISO C implementations of strchr, strrchr and strtoul.
> 
> +
> 
> +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +  Copyright (c) 2023 Pedro Falcato All rights reserved.
> 
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <Base.h>
> 
> +
> 
> +#define ULONG_MAX  0xFFFFFFFF            /* Maximum unsigned long value */
> 
> +
> 
> +// Very quick notes:
> 
> +// We only go through the string once for both functions
> 
> +// They are minimal implementations (not speed optimized) of ISO C
> semantics
> 
> +// strchr and strrchr also include the null terminator as part of the string
> 
> +// so the code gets a bit clunky to handle that case specifically.
> 
> +
> 
> +char *
> 
> +strchr (
> 
> +  const char  *Str,
> 
> +  int         Char
> 
> +  )
> 
> +{
> 
> +  char  *S;
> 
> +
> 
> +  S = (char *)Str;
> 
> +
> 
> +  for ( ; ; S++) {
> 
> +    if (*S == Char) {
> 
> +      return S;
> 
> +    }
> 
> +
> 
> +    if (*S == '\0') {
> 
> +      return NULL;
> 
> +    }
> 
> +  }
> 
> +}
> 
> +
> 
> +char *
> 
> +strrchr (
> 
> +  const char  *Str,
> 
> +  int         Char
> 
> +  )
> 
> +{
> 
> +  char  *S, *last;
> 
> +
> 
> +  S    = (char *)Str;
> 
> +  last = NULL;
> 
> +
> 
> +  for ( ; ; S++) {
> 
> +    if (*S == Char) {
> 
> +      last = S;
> 
> +    }
> 
> +
> 
> +    if (*S == '\0') {
> 
> +      return last;
> 
> +    }
> 
> +  }
> 
> +}
> 
> +
> 
> +STATIC
> 
> +int
> 
> +__isspace (
> 
> +  int  ch
> 
> +  )
> 
> +{
> 
> +  // basic ASCII ctype.h:isspace(). Not efficient
> 
> +  return ch == '\r' || ch == '\n' || ch == ' ' || ch == '\t' || ch == '\v' || ch == '\f';
> 
> +}
> 
> +
> 
> +unsigned long
> 
> +strtoul (
> 
> +  const char  *Nptr,
> 
> +  char        **EndPtr,
> 
> +  int         Base
> 
> +  )
> 
> +{
> 
> +  BOOLEAN        Negate;
> 
> +  BOOLEAN        Overflow;
> 
> +  unsigned long  Val;
> 
> +
> 
> +  Negate   = FALSE;
> 
> +  Overflow = FALSE;
> 
> +  Val      = 0;
> 
> +
> 
> +  // Reject bad numeric bases
> 
> +  if ((Base < 0) || (Base == 1) || (Base > 36)) {
> 
> +    return 0;
> 
> +  }
> 
> +
> 
> +  // Skip whitespace
> 
> +  while (__isspace (*Nptr)) {
> 
> +    Nptr++;
> 
> +  }
> 
> +
> 
> +  // Check for + or - prefixes
> 
> +  if (*Nptr == '-') {
> 
> +    Negate = TRUE;
> 
> +    Nptr++;
> 
> +  } else if (*Nptr == '+') {
> 
> +    Nptr++;
> 
> +  }
> 
> +
> 
> +  // Consume the start, autodetecting base if needed
> 
> +  if ((Nptr[0] == '0') && ((Nptr[1] == 'x') || (Nptr[1] == 'X')) && ((Base == 0) ||
> (Base == 16))) {
> 
> +    // Hex
> 
> +    Nptr += 2;
> 
> +    Base  = 16;
> 
> +  } else if ((Nptr[0] == '0') && ((Nptr[1] == 'b') || (Nptr[1] == 'B')) && ((Base ==
> 0) || (Base == 2))) {
> 
> +    // Binary (standard pending C23)
> 
> +    Nptr += 2;
> 
> +    Base  = 2;
> 
> +  } else if ((Nptr[0] == '0') && ((Base == 0) || (Base == 8))) {
> 
> +    // Octal
> 
> +    Nptr++;
> 
> +    Base = 8;
> 
> +  } else {
> 
> +    if (Base == 0) {
> 
> +      // Assume decimal
> 
> +      Base = 10;
> 
> +    }
> 
> +  }
> 
> +
> 
> +  while (TRUE) {
> 
> +    int            Digit;
> 
> +    char           C;
> 
> +    unsigned long  NewVal;
> 
> +
> 
> +    C     = *Nptr;
> 
> +    Digit = -1;
> 
> +
> 
> +    if ((C >= '0') && (C <= '9')) {
> 
> +      Digit = C - '0';
> 
> +    } else if ((C >= 'a') && (C <= 'z')) {
> 
> +      Digit = C - 'a' + 10;
> 
> +    } else if ((C >= 'A') && (C <= 'Z')) {
> 
> +      Digit = C - 'A' + 10;
> 
> +    }
> 
> +
> 
> +    if ((Digit == -1) || (Digit >= Base)) {
> 
> +      // Note that this case also handles the \0
> 
> +      if (EndPtr) {
> 
> +        *EndPtr = (char *)Nptr;
> 
> +      }
> 
> +
> 
> +      break;
> 
> +    }
> 
> +
> 
> +    NewVal = Val * Base + Digit;
> 
> +
> 
> +    if (NewVal < Val) {
> 
> +      // Overflow
> 
> +      Overflow = TRUE;
> 
> +    }
> 
> +
> 
> +    Val = NewVal;
> 
> +
> 
> +    Nptr++;
> 
> +  }
> 
> +
> 
> +  if (Negate) {
> 
> +    Val = -Val;
> 
> +  }
> 
> +
> 
> +  if (Overflow) {
> 
> +    Val = ULONG_MAX;
> 
> +  }
> 
> +
> 
> +  // TODO: We're lacking errno here.
> 
> +  return Val;
> 
> +}
> 
> 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
> 
> +  Include file to support building the third-party libfdt library.
> 
> +
> 
> +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <LibFdtSupport.h>
> 
> +
> 
> diff --git a/MdePkg/Library/BaseFdtLib/stdbool.h
> b/MdePkg/Library/BaseFdtLib/stdbool.h
> new file mode 100644
> index 0000000000..f6cf8d5702
> --- /dev/null
> +++ b/MdePkg/Library/BaseFdtLib/stdbool.h
> @@ -0,0 +1,10 @@
> +/** @file
> 
> +  Include file to support building the third-party libfdt library.
> 
> +
> 
> +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <LibFdtSupport.h>
> 
> +
> 
> 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
> 
> +  Include file to support building the third-party libfdt library.
> 
> +
> 
> +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <LibFdtSupport.h>
> 
> +
> 
> 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
> 
> +  Include file to support building the third-party libfdt library.
> 
> +
> 
> +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <LibFdtSupport.h>
> 
> +
> 
> 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
> 
> +  Include file to support building the third-party libfdt library.
> 
> +
> 
> +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <LibFdtSupport.h>
> 
> +
> 
> 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
> 
> +  Include file to support building the third-party libfdt library.
> 
> +
> 
> +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> 
> +SPDX-License-Identifier: BSD-2-Clause-Patent
> 
> +
> 
> +**/
> 
> +
> 
> +#include <LibFdtSupport.h>
> 
> +
> 
> 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",
> 
>              "Include/Library/SafeIntLib.h",
> 
>              "Include/Protocol/DebugSupport.h",
> 
> -            "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c"
> 
> +            "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c",
> 
> +            "Library/BaseFdtLib"
> 
>          ]
> 
>      },
> 
>      ## options defined ci/Plugin/CompilerPlugin
> 
> @@ -164,5 +165,17 @@
>          "ExtendWords": [],           # words to extend to the dictionary for this
> package
> 
>          "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should
> be ignore
> 
>          "AdditionalIncludePaths": [] # Additional paths to spell check (wildcards
> supported)
> 
> +    },
> 
> +    # options defined in .pytool/Plugin/UncrustifyCheck
> 
> +    "UncrustifyCheck": {
> 
> +        "IgnoreFiles": [
> 
> +            "Library/BaseFdtLib/libfdt",
> 
> +            "Library/BaseFdtLib/limits.h",
> 
> +            "Library/BaseFdtLib/stdbool.h",
> 
> +            "Library/BaseFdtLib/stddef.h",
> 
> +            "Library/BaseFdtLib/stdint.h",
> 
> +            "Library/BaseFdtLib/stdlib.h",
> 
> +            "Library/BaseFdtLib/string.h"
> 
> +        ]
> 
>      }
> 
>  }
> 
> 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 @@
>    #
> 
>    ArmTrngLib|Include/Library/ArmTrngLib.h
> 
> 
> 
> +  ##  @libraryclass  Provides APIs for third-party library libfdt.
> 
> +  #
> 
> +  FdtLib|Include/Library/FdtLib.h
> 
> +
> 
>  [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]
> 
>    ##  @libraryclass  Provides services to generate random number.
> 
>    #
> 
> 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
> 
> 
> 
>    MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf
> 
> +  MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> 
> 
> 
>  [Components.IA32, Components.X64, Components.ARM,
> Components.AARCH64]
> 
>    #
> 
> --
> 2.39.1.windows.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [edk2-devel] [PATCH v6 2/3] MdePkg: Support FDT library.
  2023-05-04 18:01   ` Michael D Kinney
@ 2023-05-04 23:02     ` Chiu, Chasel
  0 siblings, 0 replies; 6+ messages in thread
From: Chiu, Chasel @ 2023-05-04 23:02 UTC (permalink / raw)
  To: devel@edk2.groups.io, Kinney, Michael D, Lin, Benny
  Cc: Gao, Liming, Liu, Zhiguang, Pedro Falcato


Hi Mike,

Please see my reply below inline.

Thanks,
Chasel


> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Michael D
> Kinney
> Sent: Thursday, May 4, 2023 11:02 AM
> To: Lin, Benny <benny.lin@intel.com>; devel@edk2.groups.io
> Cc: Gao, Liming <gaoliming@byosoft.com.cn>; Liu, Zhiguang
> <zhiguang.liu@intel.com>; Pedro Falcato <pedro.falcato@gmail.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>
> Subject: Re: [edk2-devel] [PATCH v6 2/3] MdePkg: Support FDT library.
> 
> Hi Benny,
> 
> A couple comments below.
> 
> Mike
> 
> > -----Original Message-----
> > From: Lin, Benny <benny.lin@intel.com>
> > Sent: Wednesday, May 3, 2023 10:57 PM
> > To: devel@edk2.groups.io
> > Cc: Lin, Benny <benny.lin@intel.com>; Kinney, Michael D
> > <michael.d.kinney@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>;
> > Liu, Zhiguang <zhiguang.liu@intel.com>; Pedro Falcato
> > <pedro.falcato@gmail.com>
> > Subject: [PATCH v6 2/3] MdePkg: Support FDT library.
> >
> > From: Benny Lin <benny.lin@intel.com>
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4392
> > 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 <michael.d.kinney@intel.com>
> > Cc: Liming Gao <gaoliming@byosoft.com.cn>
> > Cc: Zhiguang Liu <zhiguang.liu@intel.com>
> > Acked-by: Pedro Falcato <pedro.falcato@gmail.com>
> > Signed-off-by: Benny Lin <benny.lin@intel.com>
> > ---
> >  MdePkg/Include/Library/FdtLib.h           | 396 +++++++++++++++++++
> >  MdePkg/Library/BaseFdtLib/BaseFdtLib.inf  |  62 +++
> > MdePkg/Library/BaseFdtLib/BaseFdtLib.uni  |  14 +
> >  MdePkg/Library/BaseFdtLib/FdtLib.c        | 404 ++++++++++++++++++++
> >  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, 1227 insertions(+), 1 deletion(-)
> >
> > diff --git a/MdePkg/Include/Library/FdtLib.h
> > b/MdePkg/Include/Library/FdtLib.h new file mode 100644 index
> > 0000000000..4b428eb5d1
> > --- /dev/null
> > +++ b/MdePkg/Include/Library/FdtLib.h
> > @@ -0,0 +1,396 @@
> > +/** @file
> >
> > +  Flattened Device Tree Library.
> >
> > +
> >
> > +  All structure data are in big-endian format. Need to call
> > + SwapBytes**
> >
> > +  function to convert between little-endia and big-endian.
> 
> I would remove all references to SwapBytes in this lib class header and Instead
> mention that the FdtToCpu and CpuToFdt services are provided To support
> conversion between big endian FDT format and the CPUs native endian format.


We will replace SwapBytes*() in comments with CpuToFdt*()/Fdt*ToCpu()


> 
> >
> > +  For example, pushing data to FDT blob need convert to big-endian
> > + with
> > SwapByte**.
> >
> > +  For retrieving data from FDT blob need convert to little-endian
> > + with
> > SwapByte**.
> >
> > +  Refer to FDT specification:
> > + https://www.devicetree.org/specifications/
> >
> > +
> >
> > +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#ifndef FDT_LIB_H_
> >
> > +#define FDT_LIB_H_
> >
> > +
> >
> > +/**
> >
> > +  Flattened Device Tree definition
> >
> > +
> >
> > +  The Devicetree Blob (DTB) format is a binary encoding with big-endian.
> >
> > +  When producing or consuming the blob data, must convert with
> > SwapBytesXX
> >
> > +  provided by edk2 BaseLib between big-endian and little-endian.
> >
> > +**/
> >
> > +typedef struct {
> >
> > +  UINT32    Magic;               /* magic word FDT_MAGIC */
> >
> > +  UINT32    TotalSize;           /* total size of DT block */
> >
> > +  UINT32    OffsetDtStruct;      /* offset to structure */
> >
> > +  UINT32    OffsetDtStrings;     /* offset to strings */
> >
> > +  UINT32    OffsetMemRsvmap;     /* offset to memory reserve map */
> >
> > +  UINT32    Version;             /* format version */
> >
> > +  UINT32    LastCompVersion;     /* last compatible version */
> >
> > +
> >
> > +  /* version 2 fields below */
> >
> > +  UINT32    BootCpuidPhys;       /* Which physical CPU id we're
> >
> > +                                    booting on */
> >
> > +  /* version 3 fields below */
> >
> > +  UINT32    SizeDtStrings;       /* size of the strings block */
> >
> > +
> >
> > +  /* version 17 fields below */
> >
> > +  UINT32    SizeDtStruct;        /* size of the structure block */
> >
> > +} FDT_HEADER;
> >
> > +
> >
> > +typedef struct {
> >
> > +  UINT64    Address;
> >
> > +  UINT64    Size;
> >
> > +} FDT_RESERVE_ENTRY;
> >
> > +
> >
> > +typedef struct {
> >
> > +  UINT32    Tag;
> >
> > +  CHAR8     Name[];
> >
> > +} FDT_NODE_HEADER;
> >
> > +
> >
> > +typedef struct {
> >
> > +  UINT32    Tag;
> >
> > +  UINT32    Length;
> >
> > +  UINT32    NameOffset;
> >
> > +  CHAR8     Data[];
> >
> > +} FDT_PROPERTY;
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT16 data of the FDT blob to little-endian
> >
> > +
> >
> > +  @param[in] Value            The value to the blob data.
> >
> > +
> >
> > +  @return The value to be converted to little-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT16
> >
> > +EFIAPI
> >
> > +Fdt16ToCpu (
> >
> > +  IN UINT16  Value
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT16 data to big-endian for aligned with the FDT blob
> >
> > +
> >
> > +  @param[in] Value            The value to align with the FDT blob.
> >
> > +
> >
> > +  @return The value to be converted to big-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT16
> >
> > +EFIAPI
> >
> > +CpuToFdt16 (
> >
> > +  IN UINT16  Value
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT32 data of the FDT blob to little-endian
> >
> > +
> >
> > +  @param[in] Value            The value to the blob data.
> >
> > +
> >
> > +  @return The value to be converted to little-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT32
> >
> > +EFIAPI
> >
> > +Fdt32ToCpu (
> >
> > +  IN UINT32  Value
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT32 data to big-endian for aligned with the FDT blob
> >
> > +
> >
> > +  @param[in] Value            The value to align with the FDT blob.
> >
> > +
> >
> > +  @return The value to be converted to big-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT32
> >
> > +EFIAPI
> >
> > +CpuToFdt32 (
> >
> > +  IN UINT32  Value
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT64 data of the FDT blob to little-endian
> >
> > +
> >
> > +  @param[in] Value            The value to the blob data.
> >
> > +
> >
> > +  @return The value to be converted to little-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT64
> >
> > +EFIAPI
> >
> > +Fdt64ToCpu (
> >
> > +  IN UINT64  Value
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT64 data to big-endian for aligned with the FDT blob
> >
> > +
> >
> > +  @param[in] Value            The value to align with the FDT blob.
> >
> > +
> >
> > +  @return The value to be converted to big-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT64
> >
> > +EFIAPI
> >
> > +CpuToFdt64 (
> >
> > +  IN UINT64  Value
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Verify the header of the Flattened Device Tree
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +
> >
> > +  @return Zero for successfully, otherwise failed.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtCheckHeader (
> >
> > +  IN CONST VOID  *Fdt
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Create a empty Flattened Device Tree.
> >
> > +
> >
> > +  @param[in] Buffer         The pointer to allocate a pool for FDT blob.
> >
> > +  @param[in] BufferSize     The BufferSize to the pool size.
> >
> > +
> >
> > +  @return Zero for successfully, otherwise failed.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtCreateEmptyTree (
> >
> > +  IN VOID    *Buffer,
> >
> > +  IN UINT32  BufferSize
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of next node from the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous node.
> >
> > +  @param[in] Depth          The depth to the level of tree hierarchy.
> >
> > +
> >
> > +  @return The offset to next node offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNextNode (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset,
> >
> > +  IN INT32       *Depth
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first node under the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous node.
> >
> > +
> >
> > +  @return The offset to next node offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtFirstSubnode (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of next node from the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous node.
> >
> > +
> >
> > +  @return The offset to next node offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNextSubnode (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first node which includes the given name.
> >
> > +
> >
> > +  @param[in] Fdt             The pointer to FDT blob.
> >
> > +  @param[in] ParentOffset    The offset to the node which start find under.
> >
> > +  @param[in] Name            The name to search the node with the name.
> >
> > +  @param[in] NameLength      The length of the name to check only.
> >
> > +
> >
> > +  @return The offset to node offset with given node name.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtSubnodeOffsetNameLen (
> >
> > +  IN CONST VOID   *Fdt,
> >
> > +  IN INT32        ParentOffset,
> >
> > +  IN CONST CHAR8  *Name,
> >
> > +  IN INT32        NameLength
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first node which includes the given property
> > + name and
> > value.
> >
> > +
> >
> > +  @param[in] Fdt             The pointer to FDT blob.
> >
> > +  @param[in] StartOffset     The offset to the starting node to find.
> >
> > +  @param[in] PropertyName    The property name to search the node
> > including the named property.
> >
> > +  @param[in] PropertyValue   The property value (big-endian) to check the
> > same property value.
> >
> > +  @param[in] PropertyLength  The length of the value in PropertValue.
> >
> > +
> >
> > +  @return The offset to node offset with given property.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNodeOffsetByPropValue (
> >
> > +  IN CONST VOID   *Fdt,
> >
> > +  IN INT32        StartOffset,
> >
> > +  IN CONST CHAR8  *PropertyName,
> >
> > +  IN CONST VOID   *PropertyValue,
> >
> > +  IN INT32        PropertyLength
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a property with the given name from the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] NodeOffset     The offset to the given node.
> >
> > +  @param[in] Name           The name to the property which need be searched
> >
> > +  @param[in] Length         The length to the size of the property found.
> >
> > +
> >
> > +  @return The property to the structure of the found property. Since
> > + the
> > data
> >
> > +          come from FDT blob, it's encoding with big-endian.
> >
> > +
> >
> > +**/
> >
> > +CONST FDT_PROPERTY *
> >
> > +EFIAPI
> >
> > +FdtGetProperty (
> >
> > +  IN CONST VOID   *Fdt,
> >
> > +  IN INT32        NodeOffset,
> >
> > +  IN CONST CHAR8  *Name,
> >
> > +  IN INT32        *Length
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first property in the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] NodeOffset     The offset to the node which need be searched.
> >
> > +
> >
> > +  @return The offset to first property offset in the given node.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtFirstPropertyOffset (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       NodeOffset
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of next property from the given property.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous property.
> >
> > +
> >
> > +  @return The offset to next property offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNextPropertyOffset (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a property from the given offset of the property.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to the given offset of the property.
> >
> > +  @param[in] Length         The length to the size of the property found.
> >
> > +
> >
> > +  @return The property to the structure of the given property offset.
> >
> > +
> >
> > +**/
> >
> > +CONST FDT_PROPERTY *
> >
> > +EFIAPI
> >
> > +FdtGetPropertyByOffset (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset,
> >
> > +  IN INT32       *Length
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Returns a string by the given string offset.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] StrOffset      The offset to the location in the strings block of
> > FDT.
> >
> > +  @param[in] Length         The length to the size of string which need be
> > retrieved.
> >
> > +
> >
> > +  @return The string to the given string offset.
> >
> > +
> >
> > +**/
> >
> > +CONST CHAR8 *
> >
> > +EFIAPI
> >
> > +FdtGetString (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       StrOffset,
> >
> > +  IN INT32       *Length        OPTIONAL
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Add a new node to the FDT.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] ParentOffset   The offset to the node offset which want to add
> > in.
> >
> > +  @param[in] Name           The name to name the node.
> >
> > +
> >
> > +  @return  The offset to the new node.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtAddSubnode (
> >
> > +  IN VOID         *Fdt,
> >
> > +  IN INT32        ParentOffset,
> >
> > +  IN CONST CHAR8  *Name
> >
> > +  );
> >
> > +
> >
> > +/**
> >
> > +  Add or modify a property in the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] NodeOffset     The offset to the node offset which want to add
> > in.
> >
> > +  @param[in] Name           The name to name the property.
> >
> > +  @param[in] Value          The value (big-endian) to the property value.
> >
> > +  @param[in] Length         The length to the size of the property.
> >
> > +
> >
> > +  @return  Zero for successfully, otherwise failed.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtSetProp (
> >
> > +  IN VOID         *Fdt,
> >
> > +  IN INT32        NodeOffset,
> >
> > +  IN CONST CHAR8  *Name,
> >
> > +  IN CONST VOID   *Value,
> >
> > +  IN UINT32       Length
> >
> > +  );
> >
> > +
> >
> > +#endif /* FDT_LIB_H_ */
> >
> > diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> > b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> > new file mode 100644
> > index 0000000000..730e568ff6
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> > @@ -0,0 +1,62 @@
> > +## @file
> >
> > +# Flattened Device Tree Library.
> >
> > +#
> >
> > +# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +#
> >
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +#
> >
> > +#
> >
> > +##
> >
> > +
> >
> > +[Defines]
> >
> > +  INF_VERSION                    = 0x0001001B
> >
> > +  BASE_NAME                      = BaseFdtLib
> >
> > +  MODULE_UNI_FILE                = BaseFdtLib.uni
> >
> > +  FILE_GUID                      = C64DCB01-B037-4FF6-9CF3-E8CEC206DE04
> >
> > +  MODULE_TYPE                    = BASE
> >
> > +  VERSION_STRING                 = 1.0
> >
> > +  LIBRARY_CLASS                  = FdtLib
> >
> > +
> >
> > +  DEFINE FDT_LIB_PATH            = libfdt/libfdt
> >
> > +
> >
> > +#
> >
> > +#  VALID_ARCHITECTURES           = IA32 X64
> >
> > +#
> >
> > +
> >
> > +[Sources]
> >
> > +  FdtLib.c
> >
> > +  LibFdtWrapper.c
> >
> > +  # header Wrapper files
> >
> > +  limits.h
> >
> > +  stdbool.h
> >
> > +  stddef.h
> >
> > +  stdint.h
> >
> > +  stdlib.h
> >
> > +  string.h
> >
> > +
> >
> > +  $(FDT_LIB_PATH)/fdt.c
> >
> > +  $(FDT_LIB_PATH)/fdt.h
> >
> > +  $(FDT_LIB_PATH)/fdt_addresses.c
> >
> > +  $(FDT_LIB_PATH)/fdt_check.c
> >
> > +  $(FDT_LIB_PATH)/fdt_empty_tree.c
> >
> > +  $(FDT_LIB_PATH)/fdt_overlay.c
> >
> > +  $(FDT_LIB_PATH)/fdt_ro.c
> >
> > +  $(FDT_LIB_PATH)/fdt_rw.c
> >
> > +  $(FDT_LIB_PATH)/fdt_strerror.c
> >
> > +  $(FDT_LIB_PATH)/fdt_sw.c
> >
> > +  $(FDT_LIB_PATH)/fdt_wip.c
> >
> > +  $(FDT_LIB_PATH)/libfdt.h
> >
> > +  $(FDT_LIB_PATH)/libfdt_env.h
> >
> > +  $(FDT_LIB_PATH)/libfdt_internal.h
> >
> > +
> >
> > +[Packages]
> >
> > +  MdePkg/MdePkg.dec
> >
> > +
> >
> > +[LibraryClasses]
> >
> > +  BaseLib
> >
> > +  BaseMemoryLib
> >
> > +
> >
> > +[BuildOptions]
> >
> > +  MSFT:*_*_IA32_CC_FLAGS = /wd4146 /wd4245
> >
> > +  MSFT:*_*_X64_CC_FLAGS  = /wd4146 /wd4244 /wd4245 /wd4267
> >
> > +
> >
> > diff --git a/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
> > b/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
> > new file mode 100644
> > index 0000000000..3f7e45ea6f
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseFdtLib/BaseFdtLib.uni
> > @@ -0,0 +1,14 @@
> > +// /** @file
> >
> > +// Flattened Device Tree Library.
> >
> > +//
> >
> > +// Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +//
> >
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +//
> >
> > +// **/
> >
> > +
> >
> > +
> >
> > +#string STR_MODULE_ABSTRACT             #language en-US "Instance of FDT
> > Library"
> >
> > +
> >
> > +#string STR_MODULE_DESCRIPTION          #language en-US "This module
> > provides FDT Library implementation."
> >
> > +
> >
> > diff --git a/MdePkg/Library/BaseFdtLib/FdtLib.c
> > b/MdePkg/Library/BaseFdtLib/FdtLib.c
> > new file mode 100644
> > index 0000000000..090b0b3fd4
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseFdtLib/FdtLib.c
> > @@ -0,0 +1,404 @@
> > +/** @file
> >
> > +  Flattened Device Tree Library.
> >
> > +
> >
> > +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <libfdt/libfdt/libfdt.h>
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT16 data of the FDT blob to little-endian
> >
> > +
> >
> > +  @param[in] Value            The value to the blob data.
> >
> > +
> >
> > +  @return The value to be converted to little-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT16
> >
> > +EFIAPI
> >
> > +Fdt16ToCpu (
> >
> > +  IN UINT16  Value
> >
> > +  )
> >
> > +{
> >
> > +  return fdt16_to_cpu (Value);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT16 data to big-endian for aligned with the FDT blob
> >
> > +
> >
> > +  @param[in] Value            The value to align with the FDT blob.
> >
> > +
> >
> > +  @return The value to be converted to big-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT16
> >
> > +EFIAPI
> >
> > +CpuToFdt16 (
> >
> > +  IN UINT16  Value
> >
> > +  )
> >
> > +{
> >
> > +  return cpu_to_fdt16 (Value);
> 
> I think the implementation of these APIs should just use the BaseLib
> SwapBytesxx() APIs.  Is there a reason this approach was selected?


We would like to reuse original libfdt functions and this also can eliminate BaseLib.h inclusion from the file.


> 
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT32 data of the FDT blob to little-endian
> >
> > +
> >
> > +  @param[in] Value            The value to the blob data.
> >
> > +
> >
> > +  @return The value to be converted to little-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT32
> >
> > +EFIAPI
> >
> > +Fdt32ToCpu (
> >
> > +  IN UINT32  Value
> >
> > +  )
> >
> > +{
> >
> > +  return fdt32_to_cpu (Value);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT32 data to big-endian for aligned with the FDT blob
> >
> > +
> >
> > +  @param[in] Value            The value to align with the FDT blob.
> >
> > +
> >
> > +  @return The value to be converted to big-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT32
> >
> > +EFIAPI
> >
> > +CpuToFdt32 (
> >
> > +  IN UINT32  Value
> >
> > +  )
> >
> > +{
> >
> > +  return cpu_to_fdt32 (Value);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT64 data of the FDT blob to little-endian
> >
> > +
> >
> > +  @param[in] Value            The value to the blob data.
> >
> > +
> >
> > +  @return The value to be converted to little-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT64
> >
> > +EFIAPI
> >
> > +Fdt64ToCpu (
> >
> > +  IN UINT64  Value
> >
> > +  )
> >
> > +{
> >
> > +  return fdt64_to_cpu (Value);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Convert UINT64 data to big-endian for aligned with the FDT blob
> >
> > +
> >
> > +  @param[in] Value            The value to align with the FDT blob.
> >
> > +
> >
> > +  @return The value to be converted to big-endian.
> >
> > +
> >
> > +**/
> >
> > +UINT64
> >
> > +EFIAPI
> >
> > +CpuToFdt64 (
> >
> > +  IN UINT64  Value
> >
> > +  )
> >
> > +{
> >
> > +  return cpu_to_fdt64 (Value);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Verify the header of the Flattened Device Tree
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +
> >
> > +  @return Zero for successfully, otherwise failed.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtCheckHeader (
> >
> > +  IN CONST VOID  *Fdt
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_check_header (Fdt);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Create a empty Flattened Device Tree.
> >
> > +
> >
> > +  @param[in] Buffer         The pointer to allocate a pool for FDT blob.
> >
> > +  @param[in] BufferSize     The BufferSize to the pool size.
> >
> > +
> >
> > +  @return Zero for successfully, otherwise failed.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtCreateEmptyTree (
> >
> > +  IN VOID    *Buffer,
> >
> > +  IN UINT32  BufferSize
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_create_empty_tree (Buffer, (int)BufferSize);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of next node from the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous node.
> >
> > +  @param[in] Depth          The depth to the level of tree hierarchy.
> >
> > +
> >
> > +  @return The offset to next node offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNextNode (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset,
> >
> > +  IN INT32       *Depth
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_next_node (Fdt, Offset, Depth);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first node under the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous node.
> >
> > +
> >
> > +  @return The offset to next node offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtFirstSubnode (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_first_subnode (Fdt, Offset);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of next node from the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous node.
> >
> > +
> >
> > +  @return The offset to next node offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNextSubnode (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_next_subnode (Fdt, Offset);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first node which includes the given name.
> >
> > +
> >
> > +  @param[in] Fdt             The pointer to FDT blob.
> >
> > +  @param[in] ParentOffset    The offset to the node which start find under.
> >
> > +  @param[in] Name            The name to search the node with the name.
> >
> > +  @param[in] NameLength      The length of the name to check only.
> >
> > +
> >
> > +  @return The offset to node offset with given node name.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtSubnodeOffsetNameLen (
> >
> > +  IN CONST VOID   *Fdt,
> >
> > +  IN INT32        ParentOffset,
> >
> > +  IN CONST CHAR8  *Name,
> >
> > +  IN INT32        NameLength
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_subnode_offset_namelen (Fdt, ParentOffset, Name,
> > NameLength);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first node which includes the given property
> > + name and
> > value.
> >
> > +
> >
> > +  @param[in] Fdt             The pointer to FDT blob.
> >
> > +  @param[in] StartOffset     The offset to the starting node to find.
> >
> > +  @param[in] PropertyName    The property name to search the node
> > including the named property.
> >
> > +  @param[in] PropertyValue   The property value (big-endian) to check the
> > same property value.
> >
> > +  @param[in] PropertyLength  The length of the value in PropertValue.
> >
> > +
> >
> > +  @return The offset to node offset with given property.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNodeOffsetByPropValue (
> >
> > +  IN CONST VOID   *Fdt,
> >
> > +  IN INT32        StartOffset,
> >
> > +  IN CONST CHAR8  *PropertyName,
> >
> > +  IN CONST VOID   *PropertyValue,
> >
> > +  IN INT32        PropertyLength
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_node_offset_by_prop_value (Fdt, StartOffset,
> > + PropertyName,
> > PropertyValue, PropertyLength);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a property with the given name from the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] NodeOffset     The offset to the given node.
> >
> > +  @param[in] Name           The name to the property which need be searched
> >
> > +  @param[in] Length         The length to the size of the property found.
> >
> > +
> >
> > +  @return The property to the structure of the found property. Since
> > + the
> > data
> >
> > +          come from FDT blob, it's encoding with big-endian.
> >
> > +
> >
> > +**/
> >
> > +CONST struct fdt_property *
> >
> > +EFIAPI
> >
> > +FdtGetProperty (
> >
> > +  IN CONST VOID   *Fdt,
> >
> > +  IN INT32        NodeOffset,
> >
> > +  IN CONST CHAR8  *Name,
> >
> > +  IN INT32        *Length
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_get_property (Fdt, NodeOffset, Name, Length);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of first property in the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] NodeOffset     The offset to the node which need be searched.
> >
> > +
> >
> > +  @return The offset to first property offset in the given node.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtFirstPropertyOffset (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       NodeOffset
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_first_property_offset (Fdt, NodeOffset);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a offset of next property from the given property.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to previous property.
> >
> > +
> >
> > +  @return The offset to next property offset.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtNextPropertyOffset (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_next_property_offset (Fdt, Offset);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a property from the given offset of the property.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] Offset         The offset to the given offset of the property.
> >
> > +  @param[in] Length         The length to the size of the property found.
> >
> > +
> >
> > +  @return The property to the structure of the given property offset.
> >
> > +
> >
> > +**/
> >
> > +CONST struct fdt_property *
> >
> > +EFIAPI
> >
> > +FdtGetPropertyByOffset (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       Offset,
> >
> > +  IN INT32       *Length
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_get_property_by_offset (Fdt, Offset, Length);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Returns a string by the given string offset.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] StrOffset      The offset to the location in the strings block of
> > FDT.
> >
> > +  @param[in] Length         The length to the size of string which need be
> > retrieved.
> >
> > +
> >
> > +  @return The string to the given string offset.
> >
> > +
> >
> > +**/
> >
> > +CONST CHAR8 *
> >
> > +EFIAPI
> >
> > +FdtGetString (
> >
> > +  IN CONST VOID  *Fdt,
> >
> > +  IN INT32       StrOffset,
> >
> > +  IN INT32       *Length        OPTIONAL
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_get_string (Fdt, StrOffset, Length);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Add a new node to the FDT.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] ParentOffset   The offset to the node offset which want to add
> > in.
> >
> > +  @param[in] Name           The name to name the node.
> >
> > +
> >
> > +  @return  The offset to the new node.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtAddSubnode (
> >
> > +  IN VOID         *Fdt,
> >
> > +  IN INT32        ParentOffset,
> >
> > +  IN CONST CHAR8  *Name
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_add_subnode (Fdt, ParentOffset, Name);
> >
> > +}
> >
> > +
> >
> > +/**
> >
> > +  Add or modify a property in the given node.
> >
> > +
> >
> > +  @param[in] Fdt            The pointer to FDT blob.
> >
> > +  @param[in] NodeOffset     The offset to the node offset which want to add
> > in.
> >
> > +  @param[in] Name           The name to name the property.
> >
> > +  @param[in] Value          The value (big-endian) to the property value.
> >
> > +  @param[in] Length         The length to the size of the property.
> >
> > +
> >
> > +  @return  Zero for successfully, otherwise failed.
> >
> > +
> >
> > +**/
> >
> > +INT32
> >
> > +EFIAPI
> >
> > +FdtSetProp (
> >
> > +  IN VOID         *Fdt,
> >
> > +  IN INT32        NodeOffset,
> >
> > +  IN CONST CHAR8  *Name,
> >
> > +  IN CONST VOID   *Value,
> >
> > +  IN UINT32       Length
> >
> > +  )
> >
> > +{
> >
> > +  return fdt_setprop (Fdt, NodeOffset, Name, Value, (int)Length);
> >
> > +}
> >
> > diff --git a/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
> > b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
> > new file mode 100644
> > index 0000000000..393019324b
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseFdtLib/LibFdtSupport.h
> > @@ -0,0 +1,99 @@
> > +/** @file
> >
> > +  Root include file of C runtime library to support building the
> > + third-party
> >
> > +  libfdt library.
> >
> > +
> >
> > +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#ifndef FDT_LIB_SUPPORT_H_
> >
> > +#define FDT_LIB_SUPPORT_H_
> >
> > +
> >
> > +#include <Base.h>
> >
> > +#include <Library/BaseLib.h>
> >
> > +#include <Library/BaseMemoryLib.h>
> >
> > +
> >
> > +typedef UINT8    uint8_t;
> >
> > +typedef UINT16   uint16_t;
> >
> > +typedef INT32    int32_t;
> >
> > +typedef UINT32   uint32_t;
> >
> > +typedef UINT64   uint64_t;
> >
> > +typedef UINTN    uintptr_t;
> >
> > +typedef UINTN    size_t;
> >
> > +typedef BOOLEAN  bool;
> >
> > +
> >
> > +#define true   (1 == 1)
> >
> > +#define false  (1 == 0)
> >
> > +
> >
> > +//
> >
> > +// Definitions for global constants used by libfdt library routines
> >
> > +//
> >
> > +#define INT_MAX     0x7FFFFFFF           /* Maximum (signed) int value */
> >
> > +#define INT32_MAX   0x7FFFFFFF           /* Maximum (signed) int32 value */
> >
> > +#define UINT32_MAX  0xFFFFFFFF           /* Maximum unsigned int32 value */
> >
> > +
> >
> > +//
> >
> > +// Function prototypes of libfdt Library routines
> >
> > +//
> >
> > +void *
> >
> > +memset     (
> >
> > +  void *,
> >
> > +  int,
> >
> > +  size_t
> >
> > +  );
> >
> > +
> >
> > +int
> >
> > +memcmp      (
> >
> > +  const void *,
> >
> > +  const void *,
> >
> > +  size_t
> >
> > +  );
> >
> > +
> >
> > +int
> >
> > +strcmp      (
> >
> > +  const char *,
> >
> > +  const char *
> >
> > +  );
> >
> > +
> >
> > +char *
> >
> > +strchr     (
> >
> > +  const char *,
> >
> > +  int
> >
> > +  );
> >
> > +
> >
> > +char *
> >
> > +strrchr    (
> >
> > +  const char *,
> >
> > +  int
> >
> > +  );
> >
> > +
> >
> > +unsigned long
> >
> > +strtoul     (
> >
> > +  const char *,
> >
> > +  char **,
> >
> > +  int
> >
> > +  );
> >
> > +
> >
> > +char *
> >
> > +strcpy (
> >
> > +  char        *strDest,
> >
> > +  const char  *strSource
> >
> > +  );
> >
> > +
> >
> > +//
> >
> > +// Macros that directly map functions to BaseLib, BaseMemoryLib, and
> > DebugLib functions
> >
> > +//
> >
> > +#define memcpy(dest, source, count)         CopyMem(dest,source,
> > (UINTN)(count))
> >
> > +#define memset(dest, ch, count)             SetMem(dest,
> > (UINTN)(count),(UINT8)(ch))
> >
> > +#define memchr(buf, ch, count)              ScanMem8(buf,
> > (UINTN)(count),(UINT8)ch)
> >
> > +#define memcmp(buf1, buf2, count)           (int)(CompareMem(buf1, buf2,
> > (UINTN)(count)))
> >
> > +#define memmove(dest, source, count)        CopyMem(dest, source,
> > (UINTN)(count))
> >
> > +#define strlen(str)                         (size_t)(AsciiStrLen(str))
> >
> > +#define strnlen(str, count)                 (size_t)(AsciiStrnLenS(str, count))
> >
> > +#define strncpy(strDest, strSource, count)  AsciiStrnCpyS(strDest,
> > MAX_STRING_SIZE, strSource, (UINTN)count)
> >
> > +#define strcat(strDest, strSource)          AsciiStrCatS(strDest,
> > MAX_STRING_SIZE, strSource)
> >
> > +#define strcmp(string1, string2, count)     (int)(AsciiStrCmp(string1, string2))
> >
> > +#define strncmp(string1, string2, count)    (int)(AsciiStrnCmp(string1, string2,
> > (UINTN)(count)))
> >
> > +
> >
> > +#endif /* FDT_LIB_SUPPORT_H_ */
> >
> > diff --git a/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
> > b/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
> > new file mode 100644
> > index 0000000000..ef6452914f
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseFdtLib/LibFdtWrapper.c
> > @@ -0,0 +1,173 @@
> > +/** @file
> >
> > +  ISO C implementations of strchr, strrchr and strtoul.
> >
> > +
> >
> > +  Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +  Copyright (c) 2023 Pedro Falcato All rights reserved.
> >
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <Base.h>
> >
> > +
> >
> > +#define ULONG_MAX  0xFFFFFFFF            /* Maximum unsigned long value */
> >
> > +
> >
> > +// Very quick notes:
> >
> > +// We only go through the string once for both functions
> >
> > +// They are minimal implementations (not speed optimized) of ISO C
> > semantics
> >
> > +// strchr and strrchr also include the null terminator as part of the
> > +string
> >
> > +// so the code gets a bit clunky to handle that case specifically.
> >
> > +
> >
> > +char *
> >
> > +strchr (
> >
> > +  const char  *Str,
> >
> > +  int         Char
> >
> > +  )
> >
> > +{
> >
> > +  char  *S;
> >
> > +
> >
> > +  S = (char *)Str;
> >
> > +
> >
> > +  for ( ; ; S++) {
> >
> > +    if (*S == Char) {
> >
> > +      return S;
> >
> > +    }
> >
> > +
> >
> > +    if (*S == '\0') {
> >
> > +      return NULL;
> >
> > +    }
> >
> > +  }
> >
> > +}
> >
> > +
> >
> > +char *
> >
> > +strrchr (
> >
> > +  const char  *Str,
> >
> > +  int         Char
> >
> > +  )
> >
> > +{
> >
> > +  char  *S, *last;
> >
> > +
> >
> > +  S    = (char *)Str;
> >
> > +  last = NULL;
> >
> > +
> >
> > +  for ( ; ; S++) {
> >
> > +    if (*S == Char) {
> >
> > +      last = S;
> >
> > +    }
> >
> > +
> >
> > +    if (*S == '\0') {
> >
> > +      return last;
> >
> > +    }
> >
> > +  }
> >
> > +}
> >
> > +
> >
> > +STATIC
> >
> > +int
> >
> > +__isspace (
> >
> > +  int  ch
> >
> > +  )
> >
> > +{
> >
> > +  // basic ASCII ctype.h:isspace(). Not efficient
> >
> > +  return ch == '\r' || ch == '\n' || ch == ' ' || ch == '\t' || ch ==
> > + '\v' || ch == '\f';
> >
> > +}
> >
> > +
> >
> > +unsigned long
> >
> > +strtoul (
> >
> > +  const char  *Nptr,
> >
> > +  char        **EndPtr,
> >
> > +  int         Base
> >
> > +  )
> >
> > +{
> >
> > +  BOOLEAN        Negate;
> >
> > +  BOOLEAN        Overflow;
> >
> > +  unsigned long  Val;
> >
> > +
> >
> > +  Negate   = FALSE;
> >
> > +  Overflow = FALSE;
> >
> > +  Val      = 0;
> >
> > +
> >
> > +  // Reject bad numeric bases
> >
> > +  if ((Base < 0) || (Base == 1) || (Base > 36)) {
> >
> > +    return 0;
> >
> > +  }
> >
> > +
> >
> > +  // Skip whitespace
> >
> > +  while (__isspace (*Nptr)) {
> >
> > +    Nptr++;
> >
> > +  }
> >
> > +
> >
> > +  // Check for + or - prefixes
> >
> > +  if (*Nptr == '-') {
> >
> > +    Negate = TRUE;
> >
> > +    Nptr++;
> >
> > +  } else if (*Nptr == '+') {
> >
> > +    Nptr++;
> >
> > +  }
> >
> > +
> >
> > +  // Consume the start, autodetecting base if needed
> >
> > +  if ((Nptr[0] == '0') && ((Nptr[1] == 'x') || (Nptr[1] == 'X')) &&
> > + ((Base == 0) ||
> > (Base == 16))) {
> >
> > +    // Hex
> >
> > +    Nptr += 2;
> >
> > +    Base  = 16;
> >
> > +  } else if ((Nptr[0] == '0') && ((Nptr[1] == 'b') || (Nptr[1] ==
> > + 'B')) && ((Base ==
> > 0) || (Base == 2))) {
> >
> > +    // Binary (standard pending C23)
> >
> > +    Nptr += 2;
> >
> > +    Base  = 2;
> >
> > +  } else if ((Nptr[0] == '0') && ((Base == 0) || (Base == 8))) {
> >
> > +    // Octal
> >
> > +    Nptr++;
> >
> > +    Base = 8;
> >
> > +  } else {
> >
> > +    if (Base == 0) {
> >
> > +      // Assume decimal
> >
> > +      Base = 10;
> >
> > +    }
> >
> > +  }
> >
> > +
> >
> > +  while (TRUE) {
> >
> > +    int            Digit;
> >
> > +    char           C;
> >
> > +    unsigned long  NewVal;
> >
> > +
> >
> > +    C     = *Nptr;
> >
> > +    Digit = -1;
> >
> > +
> >
> > +    if ((C >= '0') && (C <= '9')) {
> >
> > +      Digit = C - '0';
> >
> > +    } else if ((C >= 'a') && (C <= 'z')) {
> >
> > +      Digit = C - 'a' + 10;
> >
> > +    } else if ((C >= 'A') && (C <= 'Z')) {
> >
> > +      Digit = C - 'A' + 10;
> >
> > +    }
> >
> > +
> >
> > +    if ((Digit == -1) || (Digit >= Base)) {
> >
> > +      // Note that this case also handles the \0
> >
> > +      if (EndPtr) {
> >
> > +        *EndPtr = (char *)Nptr;
> >
> > +      }
> >
> > +
> >
> > +      break;
> >
> > +    }
> >
> > +
> >
> > +    NewVal = Val * Base + Digit;
> >
> > +
> >
> > +    if (NewVal < Val) {
> >
> > +      // Overflow
> >
> > +      Overflow = TRUE;
> >
> > +    }
> >
> > +
> >
> > +    Val = NewVal;
> >
> > +
> >
> > +    Nptr++;
> >
> > +  }
> >
> > +
> >
> > +  if (Negate) {
> >
> > +    Val = -Val;
> >
> > +  }
> >
> > +
> >
> > +  if (Overflow) {
> >
> > +    Val = ULONG_MAX;
> >
> > +  }
> >
> > +
> >
> > +  // TODO: We're lacking errno here.
> >
> > +  return Val;
> >
> > +}
> >
> > 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
> >
> > +  Include file to support building the third-party libfdt library.
> >
> > +
> >
> > +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <LibFdtSupport.h>
> >
> > +
> >
> > diff --git a/MdePkg/Library/BaseFdtLib/stdbool.h
> > b/MdePkg/Library/BaseFdtLib/stdbool.h
> > new file mode 100644
> > index 0000000000..f6cf8d5702
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseFdtLib/stdbool.h
> > @@ -0,0 +1,10 @@
> > +/** @file
> >
> > +  Include file to support building the third-party libfdt library.
> >
> > +
> >
> > +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <LibFdtSupport.h>
> >
> > +
> >
> > 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
> >
> > +  Include file to support building the third-party libfdt library.
> >
> > +
> >
> > +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <LibFdtSupport.h>
> >
> > +
> >
> > 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
> >
> > +  Include file to support building the third-party libfdt library.
> >
> > +
> >
> > +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <LibFdtSupport.h>
> >
> > +
> >
> > 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
> >
> > +  Include file to support building the third-party libfdt library.
> >
> > +
> >
> > +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <LibFdtSupport.h>
> >
> > +
> >
> > 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
> >
> > +  Include file to support building the third-party libfdt library.
> >
> > +
> >
> > +Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
> >
> > +SPDX-License-Identifier: BSD-2-Clause-Patent
> >
> > +
> >
> > +**/
> >
> > +
> >
> > +#include <LibFdtSupport.h>
> >
> > +
> >
> > 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",
> >
> >              "Include/Library/SafeIntLib.h",
> >
> >              "Include/Protocol/DebugSupport.h",
> >
> > -            "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c"
> >
> > +
> > + "Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafeIntLib.c",
> >
> > +            "Library/BaseFdtLib"
> >
> >          ]
> >
> >      },
> >
> >      ## options defined ci/Plugin/CompilerPlugin
> >
> > @@ -164,5 +165,17 @@
> >          "ExtendWords": [],           # words to extend to the dictionary for this
> > package
> >
> >          "IgnoreStandardPaths": [],   # Standard Plugin defined paths that should
> > be ignore
> >
> >          "AdditionalIncludePaths": [] # Additional paths to spell
> > check (wildcards
> > supported)
> >
> > +    },
> >
> > +    # options defined in .pytool/Plugin/UncrustifyCheck
> >
> > +    "UncrustifyCheck": {
> >
> > +        "IgnoreFiles": [
> >
> > +            "Library/BaseFdtLib/libfdt",
> >
> > +            "Library/BaseFdtLib/limits.h",
> >
> > +            "Library/BaseFdtLib/stdbool.h",
> >
> > +            "Library/BaseFdtLib/stddef.h",
> >
> > +            "Library/BaseFdtLib/stdint.h",
> >
> > +            "Library/BaseFdtLib/stdlib.h",
> >
> > +            "Library/BaseFdtLib/string.h"
> >
> > +        ]
> >
> >      }
> >
> >  }
> >
> > 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 @@
> >    #
> >
> >    ArmTrngLib|Include/Library/ArmTrngLib.h
> >
> >
> >
> > +  ##  @libraryclass  Provides APIs for third-party library libfdt.
> >
> > +  #
> >
> > +  FdtLib|Include/Library/FdtLib.h
> >
> > +
> >
> >  [LibraryClasses.IA32, LibraryClasses.X64, LibraryClasses.AARCH64]
> >
> >    ##  @libraryclass  Provides services to generate random number.
> >
> >    #
> >
> > 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
> >
> >
> >
> >    MdePkg/Library/JedecJep106Lib/JedecJep106Lib.inf
> >
> > +  MdePkg/Library/BaseFdtLib/BaseFdtLib.inf
> >
> >
> >
> >  [Components.IA32, Components.X64, Components.ARM,
> Components.AARCH64]
> >
> >    #
> >
> > --
> > 2.39.1.windows.1
> 
> 
> 
> 
> 


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2023-05-04 23:03 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-05-04  5:57 [PATCH v6 0/3] Support FDT library Benny Lin
2023-05-04  5:57 ` [PATCH v6 1/3] Tianocore: " Benny Lin
2023-05-04  5:57 ` [PATCH v6 2/3] MdePkg: " Benny Lin
2023-05-04 18:01   ` Michael D Kinney
2023-05-04 23:02     ` [edk2-devel] " Chiu, Chasel
2023-05-04  5:57 ` [PATCH v6 3/3] .pytool: " Benny Lin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox