cmake: enhance UUID handling

Before this change SP_UUID_LE was needed as an input parameter for
export_ep(). SP_UUID_LE is used in manifest files and was set with
different methods in opteesp and sp deployments. The former used cmake
code to generate it from the SP_UUID while the latter used hand defined
values.
This change makes the two deployment types work the same way. For
this the following is done:
  - UUID manipulation routines are moved to a dedicated cmake file
  - export_sp is changed to generate the LE UUID format internally using
    the new UUID services mentioned above
  - TargetCompileDefinitions.cmake is changed to use the new UUID
    services, and to stop setting the SP_UUID_LE variable.

Change-Id: I18f4b97bb560e1ebbce3acb8aed8c3912ab05a3f
Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
diff --git a/tools/cmake/common/Uuid.cmake b/tools/cmake/common/Uuid.cmake
new file mode 100644
index 0000000..d66a7a3
--- /dev/null
+++ b/tools/cmake/common/Uuid.cmake
@@ -0,0 +1,166 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+include_guard()
+
+#[===[.rst:
+RFC 4122 compatible UUID manipulation routines
+---------------------------------------------
+
+The functionality in this file allows manipulating (which mostly means conversion) of UUID strings
+to various formats used in the TS build system.
+
+#]===]
+
+#[===[.rst:
+.. cmake:command:: uuid_canon_to_octets
+
+  .. code-block:: cmake
+
+    uuid_canon_to_octets(UUID <canonical UUID string> RES <output variable name>)
+
+	Convert a canonical UUID string to list of bytes, where each byte is represented as a two digit
+	hex octet without any prefix of suffix. Order of bytes will match the order of octets in the
+	canonical string left to right.
+
+	INPUTS:
+
+	``UUID``
+	Canonical UUID string.
+
+    OUTPUTS:
+
+	``RES``
+	Name of variable to store the result to. The result is a list of strings, where each list item
+	is a two digit hex digit, without any prefix or suffix.
+
+#]===]
+function(uuid_canon_to_octets)
+	set(options)
+	set(oneValueArgs UUID RES)
+	set(multiValueArgs)
+	cmake_parse_arguments(_MY_PARAMS "${options}" "${oneValueArgs}"
+		"${multiValueArgs}" ${ARGN} )
+
+	check_args(UUID RES)
+
+	string(REGEX MATCHALL "([A-Za-z0-9][A-Za-z0-9])" _hex_bytes "${_MY_PARAMS_UUID}")
+	list(LENGTH _hex_bytes _len)
+	if(NOT _len EQUAL 16)
+		message(FATAL_ERROR "Failed to convert UUID \"${_MY_PARAMS_UUID}\" to bytes. Failed to get exactly 16 octets.")
+	endif()
+	set(${_MY_PARAMS_RES} ${_hex_bytes} PARENT_SCOPE)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: uuid_canon_to_fields
+
+  .. code-block:: cmake
+
+    uuid_canon_to_fields(UUID <canonical UUIdD string> TIME_LOW <output variable name> TIME_MID <output variable name>
+					TIME_HI_AND_VER <output variable name> CLOCK_AND_SEQ <output variable name>)
+
+	Convert a canonical UUID string to UUID fields. Each field is a
+
+	INPUTS:
+
+	``UUID``
+	Canonical UUID string.
+
+    OUTPUTS:
+    ``TIME_LOW``
+    Name of variable to store the time low filed.
+
+    ``TIME_MID``
+    Name of variable to store the time mid filed.
+
+    ``TIME_HI_AND_VER``
+    Name of variable to store the time hi and version filed.
+
+    ``CLOCK_AND_SEQ``
+    Name of variable to store the clock and sequence filed.
+
+#]===]
+function(uuid_canon_to_fields)
+	set(options)
+	set(oneValueArgs UUID TIME_LOW TIME_MID TIME_HI_AND_VER CLOCK_AND_SEQ)
+	set(multiValueArgs)
+	cmake_parse_arguments(_MY_PARAMS "${options}" "${oneValueArgs}"
+		"${multiValueArgs}" ${ARGN} )
+
+	check_args(UUID TIME_LOW TIME_MID TIME_HI_AND_VER CLOCK_AND_SEQ)
+	uuid_canon_to_octets(UUID ${_MY_PARAMS_UUID} RES _uuid_octets)
+
+	#Split the list of bytes in to the struct fields
+	list(SUBLIST _uuid_octets 0 4 _uuid_timeLow)
+	list(JOIN _uuid_timeLow "" _uuid_timeLow)
+
+	list(SUBLIST _uuid_octets 4 2 _uuid_timeMid)
+	list(JOIN _uuid_timeMid "" _uuid_timeMid)
+
+	list(SUBLIST _uuid_octets 6 2 _uuid_timeHiAndVersion)
+	list(JOIN _uuid_timeHiAndVersion "" _uuid_timeHiAndVersion)
+
+	list(SUBLIST _uuid_octets 8 8 _uuid_clockSeqAndNode)
+	list(JOIN _uuid_clockSeqAndNode "" _uuid_clockSeqAndNode)
+
+	set(${_MY_PARAMS_TIME_LOW} ${_uuid_timeLow} PARENT_SCOPE)
+	set(${_MY_PARAMS_TIME_MID} ${_uuid_timeMid} PARENT_SCOPE)
+	set(${_MY_PARAMS_TIME_HI_AND_VER} ${_uuid_timeHiAndVersion} PARENT_SCOPE)
+	set(${_MY_PARAMS_CLOCK_AND_SEQ} ${_uuid_clockSeqAndNode} PARENT_SCOPE)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: uuid_canon_to_le_words
+
+  .. code-block:: cmake
+
+    uuid_canon_to_le_words(UUID <canonical UUID string> RES <output variable name>)
+
+	Convert a canonical UUID string to list of 32bit wide little-endian numbers represented
+	as hex strings.
+
+	INPUTS:
+
+	``UUID``
+	Canonical UUID string.
+
+	``RES``
+	Name of variable to store the result to.
+
+#]===]
+function(uuid_canon_to_le_words)
+	set(options)
+	set(oneValueArgs UUID RES)
+	set(multiValueArgs)
+	cmake_parse_arguments(_MY_PARAMS "${options}" "${oneValueArgs}"
+		"${multiValueArgs}" ${ARGN} )
+
+	check_args(UUID RES)
+	uuid_canon_to_octets(UUID ${_MY_PARAMS_UUID} RES _uuid_octets)
+
+    # Separate 32 bit chunks
+	list(SUBLIST _uuid_octets 0 4 _word1)
+	list(SUBLIST _uuid_octets 4 4 _word2)
+	list(SUBLIST _uuid_octets 8 4 _word3)
+	list(SUBLIST _uuid_octets 12 4 _word4)
+
+    # Reverse octet order each word
+	list(REVERSE _word1)
+	list(REVERSE _word2)
+	list(REVERSE _word3)
+	list(REVERSE _word4)
+
+    # Concatenate octets of each word to a single string
+    list(JOIN _word1 "" _word1)
+    list(JOIN _word2 "" _word2)
+    list(JOIN _word3 "" _word3)
+    list(JOIN _word4 "" _word4)
+
+    # Return the result
+	set(${_MY_PARAMS_RES} "${_word1}" "${_word2}" "${_word3}" "${_word4}" PARENT_SCOPE)
+endfunction()