* [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
* 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
* [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
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