Add libfdt external component

Create external component to download the libfdt sources. After download
libfdt is patched to enable using libfdt's implementation of strnlen().
This is necessary because newlib doesn't export strnlen() for ISO C
sources (we build SPs as ISO C99).

Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Change-Id: Iac5fc19086c57aee409d2c0661cb498713b750e5
diff --git a/external/libfdt/fix-strnlen.patch b/external/libfdt/fix-strnlen.patch
new file mode 100644
index 0000000..7a7bb7d
--- /dev/null
+++ b/external/libfdt/fix-strnlen.patch
@@ -0,0 +1,30 @@
+This patch enables using libfdt's strlen() implementation.
+
+diff --git i/libfdt/libfdt_env.h w/libfdt/libfdt_env.h
+index 73b6d40..3a2d38c 100644
+--- i/libfdt/libfdt_env.h
++++ w/libfdt/libfdt_env.h
+@@ -66,13 +66,6 @@ static inline fdt64_t cpu_to_fdt64(uint64_t x)
+ #undef CPU_TO_FDT16
+ #undef EXTRACT_BYTE
+
+-#ifdef __APPLE__
+-#include <AvailabilityMacros.h>
+-
+-/* strnlen() is not available on Mac OS < 10.7 */
+-# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \
+-                                         MAC_OS_X_VERSION_10_7)
+-
+ #define strnlen fdt_strnlen
+
+ /*
+@@ -88,9 +81,4 @@ static inline size_t fdt_strnlen(const char *string, size_t max_count)
+     return p ? p - string : max_count;
+ }
+
+-#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED <
+-          MAC_OS_X_VERSION_10_7) */
+-
+-#endif /* __APPLE__ */
+-
+ #endif /* LIBFDT_ENV_H */
diff --git a/external/libfdt/libfdt.cmake b/external/libfdt/libfdt.cmake
new file mode 100644
index 0000000..9da9bba
--- /dev/null
+++ b/external/libfdt/libfdt.cmake
@@ -0,0 +1,57 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+# Use libfdt path from the environment if defined
+if (DEFINED ENV{TS_LIBFDT_PATH})
+	set(LIBFDT_PATH $ENV{TS_LIBFDT_PATH} CACHE PATH "Location of libfdt" FORCE)
+endif()
+
+# Otherwise clone the dtc repo (which contains libfdt)
+set(DTC_URL "https://github.com/dgibson/dtc" CACHE STRING "dtc repository URL")
+set(DTC_REFSPEC "v1.6.1" CACHE STRING "dtc git refspec")
+set(DTC_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/dtc-src" CACHE PATH "Location of dtc source")
+
+set(GIT_OPTIONS
+	GIT_REPOSITORY ${DTC_URL}
+	GIT_TAG ${DTC_REFSPEC}
+	PATCH_COMMAND git stash COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/fix-strnlen.patch
+)
+
+include(${TS_ROOT}/tools/cmake/common/LazyFetch.cmake REQUIRED)
+LazyFetch_MakeAvailable(
+	DEP_NAME dtc
+	FETCH_OPTIONS "${GIT_OPTIONS}"
+	SOURCE_DIR ${DTC_SOURCE_DIR}
+)
+
+find_path(LIBFDT_PATH
+	NAMES fdt.c
+	PATHS ${DTC_SOURCE_DIR}/libfdt
+	NO_DEFAULT_PATH
+	REQUIRED
+	DOC "Location of libfdt"
+)
+
+# Add libfdt source files to the target
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+	"${LIBFDT_PATH}/fdt.c"
+	"${LIBFDT_PATH}/fdt_ro.c"
+	"${LIBFDT_PATH}/fdt_wip.c"
+	"${LIBFDT_PATH}/fdt_sw.c"
+	"${LIBFDT_PATH}/fdt_rw.c"
+	"${LIBFDT_PATH}/fdt_strerror.c"
+	"${LIBFDT_PATH}/fdt_empty_tree.c"
+	"${LIBFDT_PATH}/fdt_addresses.c"
+	"${LIBFDT_PATH}/fdt_overlay.c"
+	"${LIBFDT_PATH}/fdt_check.c"
+)
+
+target_include_directories(${TGT} PRIVATE ${LIBFDT_PATH})