Add first version of CMake framework code

This commit adds the core elements of the framework and documentation:
 - Map utility: store key-value pairs.
 - Group utility: store build configuration options.
 - STGT API: describe the targets.
 - Compiler abstraction functions for GCC.
 - Other helper functions.
 - New CMake system type called "Embedded", using correct output file
   prefixes and extensions.
 - Sphinx based documentation which includes:
    - licensing information
    - version numbering policy
    - documentation on how-to build the documentation

In addition the following utility files are added:
  - .editorconfig
  - .gitignore

Change-Id: If19a171ef066775d3544fba82f1cc70a5fb0e7d7
Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Co-authored-by: Gyorgy Szing <gyorgy.szing@arm.com>
Co-authored-by: Bence Szépkúti <bence.szepkuti@arm.com>
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..bae13be
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Trusted Firmware-A CMake Framework Coding Style spec for editors.
+
+# References:
+# [EC]          http://editorconfig.org/
+# [CONT]        contributing.rst
+
+root = true
+
+#CMake specific settings
+[*.cmake]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = tab
+insert_final_newline = false
+max_line_length = 128
+trim_trailing_whitespace = true
+
+#Documentation
+[*.{rst,md}]
+charset = utf-8
+end_of_line = lf
+indent_size = 2
+indent_style = space
+insert_final_newline = false
+max_line_length = 128
+tab_width = 4
+trim_trailing_whitespace = true
+
+# Python code
+[*.py]
+charset = utf-8
+end_of_line = lf
+indent_style = space
+indent_size = 2
+insert_final_newline = false
+max_line_length = 180
+tab_width = 4
+trim_trailing_whitespace = true
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d17fd90
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,20 @@
+#
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+#Ignore all build directories.
+*build*/
+
+#Python specific intermediate files
+# Byte-compiled / optimised / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+#Ignore Eclipse project files
+.project
+.cproject
+.settings
+.pydevproject
diff --git a/Common/Group.cmake b/Common/Group.cmake
new file mode 100644
index 0000000..a76eb1d
--- /dev/null
+++ b/Common/Group.cmake
@@ -0,0 +1,292 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#[===[.rst:
+Group utility file
+------------------
+Group is an unordered collection of interrelated :cmake:module:`map`\s.
+
+The main purpose of this utility is to pack a set of coherent configuration data
+description into one unit, which can be applied on a target in one step. This
+means e.g. defines, compiler flags, include paths, etc.
+
+Internally the utility uses global properties and maps. Global property
+``GROUPS.<name of group>`` is defined to indicate that the group is defined, and
+for each element in the :cmake:variable:`GROUPS_VALID_TYPES`:
+
+  * a map is created, using ``<name of group>.<type>`` as name,
+  * a global property ``GROUPS.<name of group>.<type>`` is defined to indicate
+    that the type is valid in the group.
+
+.. todo:: Investigate alternatives to global properties (name collision possible).
+.. todo:: Investigate if import/export group functions would be necessary.
+
+#]===]
+
+include_guard(DIRECTORY)
+include(Common/Map)
+include(Common/Utils)
+
+#[===[.rst:
+.. cmake:variable:: GROUPS_VALID_TYPES
+
+  List of configuration data types that can be stored in a group. The
+  implementation of :cmake:command:`group_new` creates a map for each of these
+  types automatically.
+
+#]===]
+set(GROUPS_VALID_TYPES "CONFIG;DEFINE;CFLAG;ASFLAG;LDFLAG;INCLUDE")
+
+#[===[.rst:
+.. cmake:command:: group_new
+
+  .. code-block:: cmake
+
+    group_new(NAME foo)
+
+  Create a new group.
+
+  Inputs:
+
+  ``NAME``
+    Name of the new group, use |C identifier like string|. The name must be
+    unique within the global namespace, otherwise an error is generated.
+
+#]===]
+function(group_new)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(group_new NAME)
+
+	group_is_defined(NAME ${_MY_PARAMS_NAME} RET _is_defined)
+	if(_is_defined)
+		message(FATAL_ERROR "group_new(): '${_MY_PARAMS_NAME}' is already defined.")
+	endif()
+
+	set(_null " ")
+	define_property(GLOBAL PROPERTY GROUPS.${_MY_PARAMS_NAME} BRIEF_DOCS ${_null} FULL_DOCS ${_null})
+
+	foreach(_type IN LISTS GROUPS_VALID_TYPES)
+		define_property(GLOBAL PROPERTY GROUPS.${_MY_PARAMS_NAME}.${_type} BRIEF_DOCS ${_null} FULL_DOCS ${_null})
+		map_new(NAME ${_MY_PARAMS_NAME}.${_type})
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: group_is_defined
+
+  .. code-block:: cmake
+
+    group_is_defined(NAME foo RET ret)
+
+  Helper function to check if a group has been defined.
+
+  Inputs:
+
+  ``NAME``
+    Name of the group.
+
+  Outputs:
+
+  ``RET``
+    Name of the variable in the parent scope, where the return value is written.
+
+#]===]
+function(group_is_defined)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME RET)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(group_is_defined NAME RET)
+
+	get_property(_is_defined GLOBAL PROPERTY GROUPS.${_MY_PARAMS_NAME} DEFINED)
+	set(${_MY_PARAMS_RET} ${_is_defined} PARENT_SCOPE)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: group_add
+
+  .. code-block:: cmake
+
+    group_add(NAME foo TYPE type KEY one VAL 1)
+
+  Add new key-value pair to the map called ``type`` within a group. Multiple
+  types can be defined in one function call, the key-value pair will be added to
+  each of those types.
+
+  Inputs:
+
+  ``NAME``
+    Name of the group. Trying to add to a non-existing group generates an error.
+
+  ``TYPE`` (multi)
+    Type can be one or more of the values defined in
+    :cmake:variable:`GROUPS_VALID_TYPES`.
+
+  ``KEY``
+    New key to add. Same constraints apply as described in
+    :cmake:command:`map_add`.
+
+  ``VAL`` (optional)
+    Value for new key. Same constraints apply as described in
+    :cmake:command:`map_add`.
+
+#]===]
+function(group_add)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME KEY VAL)
+	set(_MULTI_VALUE_ARGS TYPE)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(group_add NAME TYPE KEY)
+
+	group_is_defined(NAME ${_MY_PARAMS_NAME} RET _is_group_defined)
+	if(NOT _is_group_defined)
+		message(FATAL_ERROR "group_add(): '${_MY_PARAMS_NAME}' group is not defined.")
+	endif()
+
+	if(DEFINED _MY_PARAMS_VAL)
+		if(DEFINED CFG_${_MY_PARAMS_KEY})
+			set(_val ${CFG_${_MY_PARAMS_KEY}})
+			message(STATUS "group_add(): '${_MY_PARAMS_KEY}' in group '${_MY_PARAMS_NAME}' is
+							overwritten by command line parameter.")
+		else()
+			set(_val ${_MY_PARAMS_VAL})
+		endif()
+	else()
+		set(_val " ")
+	endif()
+
+	foreach(_type IN LISTS _MY_PARAMS_TYPE)
+		get_property(_is_type_defined GLOBAL PROPERTY GROUPS.${_MY_PARAMS_NAME}.${_type} DEFINED)
+		if(NOT _is_type_defined)
+			message(FATAL_ERROR "group_add(): '${_type}' type is invalid.")
+		endif()
+
+		map_add(NAME ${_MY_PARAMS_NAME}.${_type} KEY ${_MY_PARAMS_KEY} VAL ${_val})
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: group_apply
+
+  .. code-block:: cmake
+
+    group_apply(NAME foo TARGETS target1 target2)
+
+  Apply a group onto the selected target(s). All settings contained in the group
+  will be added to the targets. Use this function only for the build targets
+  created with :cmake:command:`stgt_create`.
+
+  Inputs:
+
+  ``NAME``
+    Name of the group.
+
+  ``TARGETS`` (multi)
+    Name of the targets.
+
+  .. todo:: Move this to STGT?
+  .. todo:: Revise implementation for INCLUDE type.
+
+#]===]
+function(group_apply)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS TARGETS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(group_apply NAME TARGETS)
+
+	group_is_defined(NAME ${_MY_PARAMS_NAME} RET _is_defined)
+	if(NOT _is_defined)
+		message(FATAL_ERROR "group_apply(): '${_MY_PARAMS_NAME}' group is not defined.")
+	endif()
+
+	foreach(_target IN LISTS _MY_PARAMS_TARGETS)
+		if(NOT TARGET ${_target})
+			message(FATAL_ERROR "group_apply(): target '${_target}' is not defined.")
+		endif()
+
+		map_read(NAME ${_MY_PARAMS_NAME}.CONFIG KEYS _keys VALS _vals)
+		if(_keys AND _vals)
+			list(LENGTH _keys _count)
+			math(EXPR _count "${_count}-1")
+
+			foreach(i RANGE ${_count})
+				list(GET _keys ${i} _key)
+				list(GET _vals ${i} _val)
+				set_property(TARGET ${_target} PROPERTY ${_key} ${_val})
+			endforeach()
+		endif()
+
+		map_read(NAME ${_MY_PARAMS_NAME}.DEFINE KEYS _keys VALS _vals)
+		if(_keys AND _vals)
+			map_to_list(KEYS ${_keys} VALS ${_vals} OUT _defines)
+			target_compile_definitions(${_target} PRIVATE ${_defines})
+		endif()
+
+		map_read(NAME ${_MY_PARAMS_NAME}.CFLAG KEYS _keys VALS _vals)
+		if(_keys AND _vals)
+			map_to_list(KEYS ${_keys} VALS ${_vals} OUT _cflags)
+			target_compile_options(${_target} PRIVATE ${_cflags})
+		endif()
+
+		map_read(NAME ${_MY_PARAMS_NAME}.ASFLAG KEYS _keys VALS _vals)
+		if(_keys AND _vals)
+			map_to_list(KEYS ${_keys} VALS ${_vals} OUT _asflags)
+			target_compile_options(${_target} PRIVATE $<$<COMPILE_LANGUAGE:ASM>:${_asflags}>)
+		endif()
+
+		map_read(NAME ${_MY_PARAMS_NAME}.LDFLAG KEYS _keys VALS _vals)
+		if(_keys AND _vals)
+			map_to_list(KEYS ${_keys} VALS ${_vals} OUT _ldflags)
+			target_link_options(${_target} PRIVATE ${_ldflags})
+		endif()
+
+		map_read(NAME ${_MY_PARAMS_NAME}.INCLUDE KEYS _keys VALS _vals)
+		if(_keys)
+			stgt_add_inc_param(NAME ${_target} KEY ARCH INC ${_keys})
+		endif()
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: group_print
+
+  .. code-block:: cmake
+
+    group_print(NAME foo)
+
+  Print contents of the group, for debug purposes.
+
+  Inputs:
+
+  ``NAME``
+    Name of the group.
+
+#]===]
+function(group_print)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	if (NOT DEFINED _MY_PARAMS_NAME)
+		message(FATAL_ERROR "group_print(): mandatory parameter 'NAME' missing.")
+	endif()
+
+	message("\n====Group '${_MY_PARAMS_NAME}'====")
+	foreach(_type IN LISTS GROUPS_VALID_TYPES)
+		map_print(NAME ${_MY_PARAMS_NAME}.${_type})
+	endforeach()
+	message("====Group '${_MY_PARAMS_NAME}' end====\n")
+endfunction()
\ No newline at end of file
diff --git a/Common/Map.cmake b/Common/Map.cmake
new file mode 100644
index 0000000..710f9b3
--- /dev/null
+++ b/Common/Map.cmake
@@ -0,0 +1,306 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#[===[.rst:
+Map utility file
+----------------
+Map is a key-value pair storage (also known as associative array)
+implementation. It can hold multiple key-value pairs, the keys have to be unique
+in a map. Trying to add a new pair whose key already exists in the map will
+cause an error. Keys and values have a one-to-one relation, i.e. a key has
+exactly one value associated to it, which cannot be empty. If an empty/null
+value is needed, use a single space character instead. The value associated to a
+key cannot be overwritten, however it is possible to remove a key-value pair
+from the map then add the same key again with a new value.
+
+The main purpose of this utility is to store configuration data for the project,
+i.e. build options, compiler flags, etc.
+
+Internally the utility uses global properties to store the data. The global
+property ``MAPS.<name of map>`` is created as an indicator that the map is
+defined, while global properties ``MAPS.<name of map>.KEYS`` and ``MAPS.<name of
+map>.VALS`` hold the corresponding data as lists. A value for a key is
+identified by having the same index in the VALS lists, as the key has in the
+KEYS list.
+
+.. todo:: Investigate alternatives to global properties (name collision possible).
+
+#]===]
+
+include_guard(DIRECTORY)
+include(Common/Utils)
+
+#[===[.rst:
+.. cmake:command:: map_new
+
+  .. code-block:: cmake
+
+    map_new(NAME foo)
+
+  Create a new named set of key-value pairs.
+
+  Inputs:
+
+  ``NAME``
+    Name of the new map, use |C identifier like string|. The name must be unique
+    within the global namespace, otherwise an error is generated.
+
+#]===]
+function(map_new)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(map_new NAME)
+
+	get_property(is_defined GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME} DEFINED)
+	if(is_defined)
+		message(FATAL_ERROR "map_new(): '${_MY_PARAMS_NAME}' is already defined.")
+	endif()
+
+	set(_null " ")
+	define_property(GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME} BRIEF_DOCS ${_null} FULL_DOCS ${_null})
+	define_property(GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.KEYS BRIEF_DOCS ${_null} FULL_DOCS ${_null})
+	define_property(GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.VALS BRIEF_DOCS ${_null} FULL_DOCS ${_null})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: map_add
+
+  .. code-block:: cmake
+
+    map_add(NAME foo KEY one VAL 1)
+
+  Add new key-value pair to a map.
+
+  ``KEY`` and ``VAL`` are stored as CMake properties (string list) which permit
+  a broad, but not clearly defined set of characters. Semicolons must be escaped
+  as ``\;`` in all cases. To minimize the amount of possible bugs, both ``KEY``
+  and ``VAL`` should use |C identifier like string|. Exceptions are e.g. when a
+  path is stored as the value.
+
+  Inputs:
+
+  ``NAME``
+    Name of the map. Trying to add to a non-existing map generates an error.
+
+  ``KEY``
+    New key to add. Key must be unique, trying to add a new pair whose key
+    already exists in the map will cause an error.
+
+  ``VAL``
+    Value for new key.
+
+#]===]
+function(map_add)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME KEY VAL)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(map_add NAME KEY VAL)
+
+	get_property(_is_defined GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME} DEFINED)
+	if(NOT _is_defined)
+		message(FATAL_ERROR "map_add(): '${_MY_PARAMS_NAME}' is not defined.")
+	endif()
+
+	get_property(_keys GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.KEYS)
+	get_property(_vals GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.VALS)
+
+	if(${_MY_PARAMS_KEY} IN_LIST _keys)
+		message(FATAL_ERROR "map_add(): key '${_MY_PARAMS_KEY}' is already defined.")
+	else()
+		list(APPEND _keys ${_MY_PARAMS_KEY})
+		list(APPEND _vals ${_MY_PARAMS_VAL})
+
+		set_property(GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.KEYS ${_keys})
+		set_property(GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.VALS ${_vals})
+	endif()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: map_remove
+
+  .. code-block:: cmake
+
+    map_remove(NAME foo KEY one)
+
+  Remove existing key-value pair from a map.
+
+  Inputs:
+
+  ``NAME``
+    Name of the map. Trying to remove from a non-existing map generates an
+    error.
+
+  ``KEY``
+    Key to remove. Trying to remove a non-existing key generates an error.
+
+#]===]
+function(map_remove)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME KEY)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(map_remove NAME KEY)
+
+	get_property(_is_defined GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME} DEFINED)
+	if(NOT _is_defined)
+		message(FATAL_ERROR "map_remove(): '${_MY_PARAMS_NAME}' is not defined.")
+	endif()
+
+	get_property(_keys GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.KEYS)
+	get_property(_vals GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.VALS)
+
+	list(FIND _keys ${_MY_PARAMS_KEY} _index)
+	if(_index EQUAL -1)
+		message(FATAL_ERROR "map_remove(): key '${_MY_PARAMS_KEY}' does not exist.")
+	endif()
+
+	list(REMOVE_AT _keys ${_index})
+	list(REMOVE_AT _vals ${_index})
+
+	set_property(GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.KEYS ${_keys})
+	set_property(GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.VALS ${_vals})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: map_read
+
+  .. code-block:: cmake
+
+    map_read(NAME foo KEYS _keys VALS _vals)
+
+  Read the keys and the values of the map into two separate lists in the parent
+  scope.
+
+  Inputs:
+
+  ``NAME``
+    Name of the map. Trying to read a non-existing map generates an error.
+
+  Outputs:
+
+  ``KEYS``
+    Read the keys list of the map into this variable of the parent scope.
+
+  ``VALS``
+    Read the values list of the map into this variable of the parent scope.
+
+#]===]
+function(map_read)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME KEYS VALS)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(map_read NAME KEYS VALS)
+
+	get_property(_is_defined GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME} DEFINED)
+	if(NOT _is_defined)
+		message(FATAL_ERROR "map_read(): '${_MY_PARAMS_NAME}' is not defined.")
+	endif()
+
+	get_property(_keys GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.KEYS)
+	get_property(_vals GLOBAL PROPERTY MAPS.${_MY_PARAMS_NAME}.VALS)
+
+	set(${_MY_PARAMS_KEYS} ${_keys} PARENT_SCOPE)
+	set(${_MY_PARAMS_VALS} ${_vals} PARENT_SCOPE)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: map_to_list
+
+  .. code-block:: cmake
+
+    map_to_list(KEYS ${_keys} VALS ${_vals} OUT _combined)
+
+  Combine the keys and values list of a map (provided by
+  :cmake:command:`map_read` function) into a single list in the parent scope.
+
+  * If a key 'FOO' has the value 'BAR', in the combined list it will be
+    'FOO=BAR'.
+  * If a key 'FOO' has a single space character value, in the combined list it
+    will be 'FOO'.
+
+  Inputs:
+
+  ``KEYS``
+    Keys list of a map.
+
+  ``VALS``
+    Values list of a map.
+
+  Outputs:
+
+  ``OUT``
+    Write the combined list of key-value pairs into this variable of the parent
+    scope.
+
+#]===]
+function(map_to_list)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS OUT)
+	set(_MULTI_VALUE_ARGS KEYS VALS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(map_to_list KEYS VALS OUT)
+
+	list(LENGTH _MY_PARAMS_KEYS _count)
+	math(EXPR _count "${_count}-1")
+	foreach(i RANGE ${_count})
+		list(GET _MY_PARAMS_KEYS ${i} _key)
+		list(GET _MY_PARAMS_VALS ${i} _val)
+
+		if(${_val} STREQUAL " ")
+			list(APPEND _out "${_key}")
+		else()
+			list(APPEND _out "${_key}=${_val}")
+		endif()
+	endforeach()
+
+	set(${_MY_PARAMS_OUT} ${_out} PARENT_SCOPE)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: map_print
+
+  .. code-block:: cmake
+
+    map_print(NAME foo)
+
+  Print each key-value pair in a map, for debug purposes.
+
+  Inputs:
+
+  ``NAME``
+    Name of the map to print.
+
+#]===]
+function(map_print)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(map_print NAME)
+
+	map_read(NAME ${_MY_PARAMS_NAME} KEYS _keys VALS _vals)
+
+	message("====Map '${_MY_PARAMS_NAME}'====")
+	list(LENGTH _keys _count)
+	math(EXPR _count "${_count}-1")
+	foreach(i RANGE ${_count})
+		list(GET _keys ${i} _key)
+		list(GET _vals ${i} _val)
+		message("[${_key}]: ${_val}")
+	endforeach()
+	message("====Map '${_MY_PARAMS_NAME}' end====\n")
+endfunction()
\ No newline at end of file
diff --git a/Common/STGT.cmake b/Common/STGT.cmake
new file mode 100644
index 0000000..b7705fd
--- /dev/null
+++ b/Common/STGT.cmake
@@ -0,0 +1,717 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#[===[.rst:
+STGT utility file
+-----------------
+The STGT ("simple target") API is a collection of functions which wrap the CMake
+target functions and extend the built-in functionality. The main purpose of this
+utility is to connect the :cmake:module:`group`\s and the build targets. It
+handles the creation of new build targets, collecting the groups that will be
+applied on the target, and setting the target type. Also it provides functions
+to add source files and include paths in view of the properties already applied
+to the target, assign a linker script to the target, etc.
+
+After the configuration step, the targets created by STGT are the same, in the
+end, as normal CMake binary targets. However, the concept of STGT is to have
+"virtual" targets when collecting the setting groups, etc. and only "tie" them
+to a CMake target at the end of setup. This provides more flexibilty and
+expandabilty for the future, without additional complexity to the user, because
+the functionality is hidden behind the API.
+
+Internally the utility uses global properties and groups. Global property
+``STGT.<name of target>`` is defined to indicate that the target is defined.
+Global property ``STGT.<name of target>.GROUPS`` stores the list of groups added
+to the target. Adding a group to a target only results in modifying this list,
+the parameters stored in the group are actually applied only by the
+:cmake:command:`stgt_set_target` function. This function creates a normal CMake
+binary target for the STGT target and calls :cmake:command:`group_apply`, which
+transfers all the parameters stored in the groups selected for the STGT target
+into normal CMake target properties (compile flags, defines, etc.).
+
+.. todo:: How to include compiler file?
+
+#]===]
+
+include_guard(DIRECTORY)
+include(Common/Group)
+include(Common/Utils)
+
+#[===[.rst:
+.. cmake:command:: stgt_create
+
+  .. code-block:: cmake
+
+    stgt_create(NAME foo)
+
+  Create new target.
+
+  Inputs:
+
+  ``NAME``
+    Name of the new target, use |C identifier like string|. The name must be
+    unique within the global namespace, otherwise an error is generated.
+
+  .. todo:: TYPE and SRCS properties unused.
+
+#]===]
+function(stgt_create)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_create NAME)
+
+	set(_null " ")
+	define_property(GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME} BRIEF_DOCS ${_null} FULL_DOCS ${_null})
+	foreach(_type IN ITEMS GROUPS TYPE SRCS)
+		define_property(GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.${_type} BRIEF_DOCS ${_null} FULL_DOCS ${_null})
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_is_defined
+
+  .. code-block:: cmake
+
+    stgt_is_defined(NAME foo RET ret)
+
+  Helper function to check if a target has been defined.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  Outputs:
+
+  ``RET``
+    Name of the variable in the parent scope, where the return value is written.
+
+#]===]
+function(stgt_is_defined)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME RET)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_is_defined NAME RET)
+
+	get_property(_is_defined GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME} DEFINED)
+	set(${_MY_PARAMS_RET} ${_is_defined} PARENT_SCOPE)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_add_setting
+
+  .. code-block:: cmake
+
+    stgt_add_setting(NAME foo GROUPS group1 group2)
+
+  Add setting groups to a target. The groups are not applied yet, only collected
+  to the group list of the target. Multiple groups can be added in one call.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``GROUPS`` (multi)
+    Name of the groups.
+
+#]===]
+function(stgt_add_setting)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS GROUPS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_setting NAME GROUPS)
+
+	stgt_is_defined(NAME ${_MY_PARAMS_NAME} RET _is_stgt_defined)
+	if(NOT _is_stgt_defined)
+		message(FATAL_ERROR "stgt_add_setting(): '${_MY_PARAMS_NAME}' stgt is not defined.")
+	endif()
+
+	foreach(_group IN LISTS _MY_PARAMS_GROUPS)
+		group_is_defined(NAME ${_group} RET _is_group_defined)
+		if(NOT _is_group_defined)
+			message(FATAL_ERROR "stgt_add_setting(): '${_group}' group is not defined.")
+		endif()
+	endforeach()
+
+	get_property(_groups GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.GROUPS)
+	list(APPEND _groups "${_MY_PARAMS_GROUPS}")
+	set_property(GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.GROUPS ${_groups})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_set_target
+
+  .. code-block:: cmake
+
+    stgt_set_target(NAME foo TYPE lib [ARGS arg1 ...])
+
+  Set target type. This function creates a normal CMake binary target, and
+  applies the list of groups previously associated to the target.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``TYPE``
+    Type can be EXE, LIB, OBJLIB.
+
+  ``ARGS`` (multi)
+    Additional arguments to pass through to add_executable or add_library
+
+  .. todo:: New functionality might be needed to handle situations when order of
+            include paths matters.
+
+#]===]
+function(stgt_set_target)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME TYPE)
+	set(_MULTI_VALUE_ARGS ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_set_target NAME TYPE)
+
+	string(TOUPPER ${_MY_PARAMS_TYPE} _type)
+	if(_type STREQUAL "EXE")
+		add_executable(${_MY_PARAMS_NAME} ${_MY_PARAMS_ARGS})
+	elseif(_type STREQUAL "LIB")
+		add_library(${_MY_PARAMS_NAME} STATIC ${_MY_PARAMS_ARGS})
+	elseif(_type STREQUAL "OBJLIB")
+		add_library(${_MY_PARAMS_NAME} OBJECT ${_MY_PARAMS_ARGS})
+	else()
+		message(FATAL_ERROR "stgt_set_target(): '${_MY_PARAMS_TYPE}' target type is invalid.")
+	endif()
+
+	get_property(_groups GLOBAL PROPERTY STGT.${_MY_PARAMS_NAME}.GROUPS)
+	foreach(_group IN LISTS _groups)
+		group_apply(NAME ${_group} TARGETS ${_MY_PARAMS_NAME})
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_get_param
+
+  .. code-block:: cmake
+
+    stgt_get_param(NAME foo KEY one RET ret)
+
+  Get the value of a property on a specific target.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``KEY``
+    Which property to read.
+
+  Outputs:
+
+  ``RET``
+    Name of the variable in the parent scope, where the return value is written.
+
+#]===]
+function(stgt_get_param)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME KEY RET)
+	set(_MULTI_VALUE_ARGS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_get_param NAME KEY RET)
+
+	stgt_is_defined(NAME ${_MY_PARAMS_NAME} RET _is_stgt_defined)
+	if(NOT _is_stgt_defined)
+		message(FATAL_ERROR "stgt_get_param(): '${_MY_PARAMS_NAME}' stgt is not defined.")
+	endif()
+
+	get_target_property(_val ${_MY_PARAMS_NAME} ${_MY_PARAMS_KEY})
+	if(_val MATCHES ".*-NOTFOUND")
+		message(FATAL_ERROR "stgt_get_param(): parameter '${_MY_PARAMS_KEY}' of target
+							'${_MY_PARAMS_NAME}' is missing.")
+	endif()
+
+	set(${_MY_PARAMS_RET} ${_val} PARENT_SCOPE)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_add_src
+
+  .. code-block:: cmake
+
+    stgt_add_src(NAME foo SRC main.c)
+
+  Add source files to a target. Multiple source files can be added to multiple
+  targets in one call.
+
+  Inputs:
+
+  ``NAME`` (multi)
+    Name of the targets.
+
+  ``SRC`` (multi)
+    Source files to add.
+
+#]===]
+function(stgt_add_src)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS)
+	set(_MULTI_VALUE_ARGS NAME SRC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_src NAME SRC)
+
+	foreach(_target IN LISTS _MY_PARAMS_NAME)
+		if(NOT TARGET ${_target})
+			message(FATAL_ERROR "stgt_add_src(): '${_target}' target is not defined.")
+		endif()
+
+		get_property(_object_lib TARGET "${_target}" PROPERTY "OBJECT_LIB")
+		if(_object_lib)
+			target_sources(${_object_lib} PRIVATE ${_MY_PARAMS_SRC})
+		else()
+			target_sources(${_target} PRIVATE ${_MY_PARAMS_SRC})
+		endif()
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_add_src_cond
+
+  .. code-block:: cmake
+
+    stgt_add_src_cond(NAME foo bar SRC uart.c spi.c KEY one VAL 1)
+    stgt_add_src_cond(NAME foo bar SRC uart.c spi.c KEY one VAL 1 OPTIONAL true)
+
+  Add source files to a target based on a condition: if value of KEY property on
+  the target equals VAL, the source files will be added. Multiple source files
+  can be added to multiple targets in one call. In this case the condition is
+  evaluated for each target separately. If the KEY property is not defined for
+  the target and OPTIONAL is not true, an error will be generated.
+
+  Inputs:
+
+  ``NAME`` (multi)
+    Name of the targets.
+
+  ``SRC`` (multi)
+    Source files to add.
+
+  ``KEY``
+    Which property to read.
+
+  ``VAL``
+    Condition is true if value of KEY equals this value.
+
+  ``OPTIONAL`` (bool)
+    If true, no error will be generated if KEY is not defined for the target.
+    Can be omitted, default value is false.
+
+#]===]
+function(stgt_add_src_cond)
+	set(_OPTIONS_ARGS OPTIONAL)
+	set(_ONE_VALUE_ARGS KEY VAL)
+	set(_MULTI_VALUE_ARGS NAME SRC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_src_cond NAME KEY VAL SRC)
+
+	foreach(_target IN LISTS _MY_PARAMS_NAME)
+		get_target_property(_val ${_target} ${_MY_PARAMS_KEY})
+		if((_val MATCHES ".*-NOTFOUND") AND (NOT _MY_PARAMS_OPTIONAL))
+			message(FATAL_ERROR "stgt_add_src_cond: mandatory parameter '${_MY_PARAMS_KEY}'
+								of target '${_target}' is missing.")
+		endif()
+
+		if(${_val} STREQUAL ${_MY_PARAMS_VAL})
+			stgt_add_src(NAME ${_target} SRC ${_MY_PARAMS_SRC})
+		endif()
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_add_src_param
+
+  .. code-block:: cmake
+
+    stgt_add_src_param(NAME foo bar SRC ../@prop_name@/uart.c KEY prop_name)
+
+  Add source files to a target using a parameter dependent path. The name of KEY
+  can be used in the path of the source file with the @prop_name@ syntax. This
+  field will be replaced by the value of the property on the target. Multiple
+  source files can be added to multiple targets in one call. In this case the
+  parameter value is evaluated for each target separately.
+
+  Inputs:
+
+  ``NAME`` (multi)
+    Name of the targets.
+
+  ``SRC`` (multi)
+    Source files to add.
+
+  ``KEY``
+    Which property to read.
+
+  .. todo:: Fix syntax highlight warning.
+
+#]===]
+function(stgt_add_src_param)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS KEY)
+	set(_MULTI_VALUE_ARGS NAME SRC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_src_param NAME KEY SRC)
+
+	foreach(_target IN LISTS _MY_PARAMS_NAME)
+		get_target_property(_val ${_target} ${_MY_PARAMS_KEY})
+		if(_val MATCHES ".*-NOTFOUND")
+			message(FATAL_ERROR "stgt_add_src_param: mandatory parameter '${_MY_PARAMS_KEY}'
+								of target '${_target}' is missing.")
+		endif()
+
+		set(_src ${_MY_PARAMS_SRC})
+		list(TRANSFORM _src REPLACE @${_MY_PARAMS_KEY}@ ${_val})
+		stgt_add_src(NAME ${_target} SRC ${_src})
+	endforeach()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_add_inc
+
+  .. code-block:: cmake
+
+    stgt_add_inc(NAME foo INC ${ROOT_DIR}/include)
+
+  Add include paths to a target. Multiple paths can be added to a target in one
+  call.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``INC`` (multi)
+    Include paths to add.
+
+#]===]
+function(stgt_add_inc)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS INC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_inc NAME INC)
+
+	if(NOT TARGET ${_MY_PARAMS_NAME})
+		message(FATAL_ERROR "stgt_add_inc(): '${_MY_PARAMS_NAME}' target is not defined.")
+	endif()
+
+	target_include_directories(${_MY_PARAMS_NAME} PRIVATE ${_MY_PARAMS_INC})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_add_inc_cond
+
+  .. code-block:: cmake
+
+    stgt_add_inc_cond(NAME foo INC ${ROOT_DIR}/include KEY one VAL 1)
+    stgt_add_inc_cond(NAME foo INC ${ROOT_DIR}/include KEY one VAL 1 OPTIONAL true)
+
+  Add include paths to a target based on a condition: if value of KEY property
+  on the target equals VAL, the include paths will be added. Multiple paths can
+  be added in one call. If the KEY property is not defined for the target and
+  OPTIONAL is not true, an error will be generated.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``INC`` (multi)
+    Include paths to add.
+
+  ``KEY``
+    Which property to read.
+
+  ``VAL``
+    Condition is true if value of KEY equals this value.
+
+  ``OPTIONAL`` (bool)
+    If true, no error will be generated if KEY is not defined for the target.
+    Can be omitted, default value is false.
+
+#]===]
+function(stgt_add_inc_cond)
+	set(_OPTIONS_ARGS OPTIONAL)
+	set(_ONE_VALUE_ARGS NAME KEY VAL)
+	set(_MULTI_VALUE_ARGS INC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_inc_cond NAME KEY VAL INC)
+
+	get_target_property(_val ${_MY_PARAMS_NAME} ${_MY_PARAMS_KEY})
+	if(NOT (_val OR _MY_PARAMS_OPTIONAL))
+		message(FATAL_ERROR "stgt_add_inc_cond: mandatory parameter '${_MY_PARAMS_KEY}'
+							of target '${_MY_PARAMS_NAME}' is missing.")
+	endif()
+
+	if(${_val} STREQUAL ${_MY_PARAMS_VAL})
+		stgt_add_inc(NAME ${_MY_PARAMS_NAME} INC ${_MY_PARAMS_INC})
+	endif()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_add_inc_param
+
+  .. code-block:: cmake
+
+    stgt_add_inc_param(NAME foo INC ../@prop_name@/include KEY prop_name)
+
+  Add include paths to a target using a parameter dependent path. The name of
+  KEY can be used in the include path with the @prop_name@ syntax. This field
+  will be replaced by the value of the property on the target. Multiple paths
+  can be added in one call.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``INC`` (multi)
+    Include paths to add.
+
+  ``KEY``
+    Which property to read.
+
+  .. todo:: Fix syntax highlight warning.
+
+#]===]
+function(stgt_add_inc_param)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME KEY)
+	set(_MULTI_VALUE_ARGS INC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_inc_param NAME KEY INC)
+
+	get_target_property(_val ${_MY_PARAMS_NAME} ${_MY_PARAMS_KEY})
+	if(NOT _val)
+		message(FATAL_ERROR "stgt_add_inc_param: mandatory parameter '${_MY_PARAMS_KEY}'
+							of target '${_MY_PARAMS_NAME}' is missing.")
+	endif()
+
+	list(TRANSFORM _MY_PARAMS_INC REPLACE @${_MY_PARAMS_KEY}@ ${_val})
+	stgt_add_inc(NAME ${_MY_PARAMS_NAME} INC ${_MY_PARAMS_INC})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_link_libraries
+
+  .. code-block:: cmake
+
+    stgt_link_libraries(NAME foo LIBS lib1 lib2)
+
+  Link libraries to target. Multiple libraries can be linked in one call.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``LIBS`` (multi)
+    Libraries to link.
+
+#]===]
+function(stgt_link_libraries)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS LIBS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_link_libraries NAME LIBS)
+
+	target_link_libraries(${_MY_PARAMS_NAME} PRIVATE ${_MY_PARAMS_LIBS})
+
+	get_property(_object_lib TARGET "${_MY_PARAMS_NAME}" PROPERTY "OBJECT_LIB")
+	if(_object_lib)
+		get_property(_sources TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES")
+		set_property(TARGET "${_object_lib}" APPEND PROPERTY "SOURCES" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},${_sources}>")
+		set_property(TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES" "")
+
+		set(_deps "${_MY_PARAMS_LIBS}")
+		foreach(_lib ${_MY_PARAMS_LIBS})
+			get_target_property(_type "${_lib}" "TYPE")
+			if(_type STREQUAL "OBJECT_LIBRARY")
+				list(APPEND _deps "$<TARGET_OBJECTS:${_lib}>")
+			else()
+				list(APPEND _deps "$<TARGET_FILE:${_lib}>")
+			endif()
+		endforeach()
+
+		get_property(_build_messages TARGET "${_MY_PARAMS_NAME}" PROPERTY "BUILD_MESSAGES")
+		foreach(_message ${_build_messages})
+			set_property(TARGET "${_message}" APPEND PROPERTY "BUILD_MESSAGE_DEPENDS" "${_deps}")
+		endforeach()
+	endif()
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_link_build_messages
+
+  .. code-block:: cmake
+
+    stgt_link_build_messages(NAME target LIBS msg1 [msg2 ...])
+
+  Link one or more object libraries to the target, treating them as "build messages".
+  This function configures the libraries as order-only dependencies of the target,
+  and appends the list of all (non-build message) libraries linked to the target,
+  as well as their output files to the property named BUILD_MESSAGE_DEPENDS, found
+  on the build message libraries.
+
+  This property can be used with add_custom_command to cause the build message to rebuild
+  if any of these linker-input files are modified in the following way:
+
+  .. code-block:: cmake
+
+    add_custom_command([...] DEPENDS "$<TARGET_GENEX_EVAL:msg1,$<TARGET_PROPERTY:msg1,BUILD_MESSAGE_DEPENDS>>")
+
+  Calling this function on a target causes it to be split into two targets behind the scenes:
+  an object library, which compiles all the source files, and the original target, which
+  performs the linking step.
+
+  The practical implication of this is that the SOURCES property on the original target will
+  appear empty. Please refrain from updating this property directly, or using native
+  CMake commands that update this variable. Use the equivalent STGT functions instead.
+
+  If you need to use the value of the SOURCES property, you can check for the presence
+  of the OBJECT_LIB property. This will contain the name of the object library target, which
+  will have its SOURCES property populated normally.
+
+  With generator expressions you would acomplish this in the following way:
+
+  .. code-block:: cmake
+
+    set(foo_src_tgt "$<IF:$<BOOL:$<TARGET_PROPERTY:foo,OBJECT_LIB>>,$<TARGET_PROPERTY:foo,OBJECT_LIB>,foo>")
+    $<TARGET_GENEX_EVAL:${foo_src_tgt},$<TARGET_PROPERTY:${foo_src_tgt},SOURCES>>
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``LIBS`` (multi)
+    Libraries to link.
+
+#]===]
+function(stgt_link_build_messages)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME)
+	set(_MULTI_VALUE_ARGS LIBS)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_add_build_message NAME LIBS)
+
+	get_property(_OBJECT_LIB TARGET "${_MY_PARAMS_NAME}" PROPERTY "OBJECT_LIB")
+	if(NOT _OBJECT_LIB)
+		set(_OBJECT_LIB "${_MY_PARAMS_NAME}_o")
+		set_property(TARGET "${_MY_PARAMS_NAME}" PROPERTY "OBJECT_LIB" "${_OBJECT_LIB}")
+
+		stgt_create(NAME "${_OBJECT_LIB}")
+		stgt_set_target(NAME "${_OBJECT_LIB}" TYPE objlib ARGS EXCLUDE_FROM_ALL)
+
+		get_property(_sources TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES")
+		set_property(TARGET "${_OBJECT_LIB}" PROPERTY "SOURCES" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},${_sources}>")
+		set_property(TARGET "${_MY_PARAMS_NAME}" PROPERTY "SOURCES" "")
+
+		foreach(_prop "COMPILE_DEFINITIONS" "COMPILE_OPTIONS" "LINK_OPTIONS" "INCLUDE_DIRECTORIES")
+			set_property(TARGET "${_OBJECT_LIB}" PROPERTY "${_prop}" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},$<TARGET_PROPERTY:${_MY_PARAMS_NAME},${_prop}>>")
+		endforeach()
+
+		stgt_link_libraries(NAME "${_MY_PARAMS_NAME}" LIBS "${_OBJECT_LIB}")
+	endif()
+
+	set_property(TARGET "${_MY_PARAMS_NAME}" APPEND PROPERTY "BUILD_MESSAGES" "${_MY_PARAMS_LIBS}")
+
+	get_property(_libs TARGET "${_MY_PARAMS_NAME}" PROPERTY "LINK_LIBRARIES")
+	set(_deps "${_libs}" "$<TARGET_GENEX_EVAL:${_MY_PARAMS_NAME},$<TARGET_PROPERTY:${_MY_PARAMS_NAME},LINK_DEPENDS>>")
+	foreach(_lib ${_libs})
+		get_target_property(_type "${_lib}" "TYPE")
+		if(_type STREQUAL "OBJECT_LIBRARY")
+			list(APPEND _deps "$<TARGET_OBJECTS:${_lib}>")
+		else()
+			list(APPEND _deps "$<TARGET_FILE:${_lib}>")
+		endif()
+	endforeach()
+
+	foreach(_message ${_MY_PARAMS_LIBS})
+		set_property(TARGET "${_message}" APPEND PROPERTY "BUILD_MESSAGE_DEPENDS" "${_deps}")
+		target_link_options("${_MY_PARAMS_NAME}" PRIVATE "$<TARGET_OBJECTS:${_message}>")
+	endforeach()
+
+	add_dependencies("${_MY_PARAMS_NAME}" ${_MY_PARAMS_LIBS})
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: stgt_set_linker_script
+
+  .. code-block:: cmake
+
+    stgt_set_linker_script(NAME foo FILE foo.ld)
+    stgt_set_linker_script(NAME foo FILE foo.ld.S DEF RAM_SIZE=1024 INC include/mem)
+
+  Set linker file for target. FILE will be assigned to the target as linker
+  script. The function uses the compiler_set_linker_script() function call,
+  therefore the compiler abstraction API should be included. DEF and INC are
+  also passed to this function, which should use them when preprocessing the
+  linker script. The compiler_set_linker_script() function should add an LDFLAG
+  using the toolchain specific syntax to the TARGET_linker_script group.
+
+  Inputs:
+
+  ``NAME``
+    Name of the target.
+
+  ``FILE``
+    Linker script file for the target.
+
+  ``DEF`` (multi, optional)
+    Defines for the linker script preprocessor.
+
+  ``INC`` (multi, optional)
+    Include paths for the linker script preprocessor.
+
+#]===]
+function(stgt_set_linker_script)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS NAME FILE)
+	set(_MULTI_VALUE_ARGS DEF INC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(stgt_set_linker_script NAME FILE)
+
+	if(NOT TARGET ${_MY_PARAMS_NAME})
+		message(FATAL_ERROR "stgt_set_linker_script(): '${_MY_PARAMS_NAME}' target is not defined.")
+	endif()
+
+	group_new(NAME "${_MY_PARAMS_NAME}_linker_script")
+	compiler_set_linker_script(
+		TARGET "${_MY_PARAMS_NAME}"
+		FILE "${_MY_PARAMS_FILE}"
+		DEF "${_MY_PARAMS_DEF}"
+		INC "${_MY_PARAMS_INC}"
+	)
+	group_apply(NAME "${_MY_PARAMS_NAME}_linker_script" TARGETS "${_MY_PARAMS_NAME}")
+endfunction()
\ No newline at end of file
diff --git a/Common/Utils.cmake b/Common/Utils.cmake
new file mode 100644
index 0000000..d93dcee
--- /dev/null
+++ b/Common/Utils.cmake
@@ -0,0 +1,37 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#[===[.rst:
+Misc utilities
+--------------
+#]===]
+
+include_guard(DIRECTORY)
+
+#[===[.rst:
+.. cmake:command:: check_args
+
+  .. code-block:: cmake
+
+    check_args(func_name REQ_ARG1 REQ_ARG2)
+
+  Helper macro for argument checking in functions. First argument *func_name* is
+  the name of the function, other arguments are the names of the required
+  arguments to that function. The macro iterates through the list, and prints
+  and error message if not all arguments are defined.
+
+#]===]
+macro(check_args)
+	set(_argv "${ARGV}")
+	list(SUBLIST _argv 0 1 _func)
+	list(SUBLIST _argv 1 -1 _args)
+	foreach(_arg IN LISTS _args)
+		if (NOT DEFINED _MY_PARAMS_${_arg})
+			message(FATAL_ERROR "${_func}(): mandatory parameter '${_arg}' missing.")
+		endif()
+	endforeach()
+endmacro()
diff --git a/Compiler/GCC.cmake b/Compiler/GCC.cmake
new file mode 100644
index 0000000..c773613
--- /dev/null
+++ b/Compiler/GCC.cmake
@@ -0,0 +1,159 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#[===[.rst:
+Compiler abstraction for GCC
+----------------------------
+#]===]
+
+include_guard(DIRECTORY)
+
+if(NOT DEFINED CROSS_COMPILE AND NOT DEFINED ENV{CROSS_COMPILE})
+	message(FATAL_ERROR "'CROSS_COMPILE' is not defined.")
+endif()
+
+set(CROSS_COMPILE $ENV{CROSS_COMPILE} CACHE STRING "Prefix of the cross-compiler commands")
+
+find_program(_cross_compile_gcc NAMES ${CROSS_COMPILE}gcc ${CROSS_COMPILE}gcc.exe REQUIRED)
+set(CMAKE_C_COMPILER ${_cross_compile_gcc})
+
+#Official solution to disable compiler checks
+set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
+
+#[===[.rst:
+.. cmake:command:: compiler_preprocess_file
+
+  .. code-block:: cmake
+
+    compiler_preprocess_file(SRC file.c DST file_pp.c)
+    compiler_preprocess_file(SRC file.c DST file_pp.c
+                             DEFINES USE_LIB INCLUDES include/lib)
+
+  Run the preprocessor on a file and save the output to another file. Optionally
+  provide defines and include paths to the preprocessor.
+
+  Inputs:
+
+  ``SRC``
+    Name of the source file to preprocess.
+
+  ``DST``
+    Where to write the preprocessed output.
+
+  ``DEFINES`` (multi, optional)
+    Definitions for the preprocessor.
+
+  ``INCLUDES`` (multi, optional)
+    Include paths for the preprocessor.
+
+#]===]
+function(compiler_preprocess_file)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS SRC DST)
+	set(_MULTI_VALUE_ARGS DEFINES INCLUDES)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(compiler_preprocess_file SRC DST)
+
+	set(_flags "")
+	if(_MY_PARAMS_DEFINES)
+		list(TRANSFORM _MY_PARAMS_DEFINES PREPEND -D)
+		list(APPEND _flags ${_MY_PARAMS_DEFINES})
+	endif()
+	if(_MY_PARAMS_INCLUDES)
+		list(TRANSFORM _MY_PARAMS_INCLUDES PREPEND -I)
+		list(APPEND _flags ${_MY_PARAMS_INCLUDES})
+	endif()
+
+	add_custom_command(
+		DEPENDS ${_MY_PARAMS_SRC} OUTPUT ${_MY_PARAMS_DST}
+		COMMAND ${CMAKE_C_COMPILER} -E -P -x assembler-with-cpp ${_flags}
+				${_MY_PARAMS_SRC} -o ${_MY_PARAMS_DST}
+	)
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: compiler_set_linker_script
+
+  .. code-block:: cmake
+
+    compiler_set_linker_script(TARGET foo FILE foo.ld.S)
+    compiler_set_linker_script(TARGET foo FILE foo.ld.S DEF USE_LIB INC include/lib)
+
+  Set linker script for a target. The function adds an LDFLAG using the
+  toolchain specific syntax to the TARGET_linker_script group, which is applied
+  onto the target by the caller function. FILE will be preprocessed, optionally
+  defines and/or includes can be provided using DEF/INC arguments.
+
+  Inputs:
+
+  ``TARGET``
+    Name of the target.
+
+  ``FILE``
+    Linker script file for the target.
+
+  ``DEF`` (multi, optional)
+    Defines for the linker script preprocessor.
+
+  ``INC`` (multi, optional)
+    Include paths for the linker script preprocessor.
+
+#]===]
+function(compiler_set_linker_script)
+	set(_OPTIONS_ARGS)
+	set(_ONE_VALUE_ARGS TARGET FILE)
+	set(_MULTI_VALUE_ARGS DEF INC)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN})
+
+	check_args(compiler_set_linker_script TARGET FILE)
+
+	get_filename_component(_src "${_MY_PARAMS_FILE}" ABSOLUTE)
+	get_filename_component(_src_ext "${_MY_PARAMS_FILE}" EXT)
+	set(_dst "${CMAKE_BINARY_DIR}/${_MY_PARAMS_TARGET}.ld")
+
+	if(NOT ("${_src_ext}" STREQUAL ".ld" OR "${_src_ext}" STREQUAL ".ld.S"))
+		message(WARNING "compiler_set_linker_script(): extension mismatch '${_src}'")
+	endif()
+
+	compiler_preprocess_file(
+		SRC ${_src}
+		DST ${_dst}
+		DEFINES ${_MY_PARAMS_DEF} __LINKER__
+		INCLUDES ${_MY_PARAMS_INC}
+	)
+
+	add_custom_target("${_MY_PARAMS_TARGET}_ld" DEPENDS "${_dst}")
+	add_dependencies("${_MY_PARAMS_TARGET}" "${_MY_PARAMS_TARGET}_ld")
+
+	group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE CONFIG KEY "LINK_DEPENDS" VAL "${_dst}")
+	group_add(NAME "${_MY_PARAMS_TARGET}_linker_script" TYPE LDFLAG KEY "-Wl,--script" VAL "${_dst}")
+endfunction()
+
+#[===[.rst:
+.. cmake:command:: compiler_generate_binary_output
+
+  .. code-block:: cmake
+
+    compiler_generate_binary_output(TARGET foo)
+
+  Generate binary output for the target. The function converts the output
+  executable into bin file using toolchain specific syntax.
+
+  Inputs:
+
+  ``TARGET``
+    Name of the target.
+
+#]===]
+function(compiler_generate_binary_output TARGET)
+	add_custom_command(
+		TARGET ${TARGET} POST_BUILD
+		COMMAND ${CMAKE_OBJCOPY} -O binary
+				$<TARGET_FILE:${TARGET}>
+				$<TARGET_FILE_DIR:${TARGET}>/${TARGET}.bin)
+endfunction()
\ No newline at end of file
diff --git a/Platform/Embedded-GNU-ASM.cmake b/Platform/Embedded-GNU-ASM.cmake
new file mode 100644
index 0000000..6794df1
--- /dev/null
+++ b/Platform/Embedded-GNU-ASM.cmake
@@ -0,0 +1,9 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(CMAKE_ASM_OUTPUT_EXTENSION ".o")
+set(CMAKE_ASM_OUTPUT_EXTENSION_REPLACE 1)
diff --git a/Platform/Embedded-GNU-C.cmake b/Platform/Embedded-GNU-C.cmake
new file mode 100644
index 0000000..f253e3c
--- /dev/null
+++ b/Platform/Embedded-GNU-C.cmake
@@ -0,0 +1,9 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(CMAKE_C_OUTPUT_EXTENSION ".o")
+set(CMAKE_C_OUTPUT_EXTENSION_REPLACE 1)
diff --git a/Platform/Embedded.cmake b/Platform/Embedded.cmake
new file mode 100644
index 0000000..f86251a
--- /dev/null
+++ b/Platform/Embedded.cmake
@@ -0,0 +1,10 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(CMAKE_EXECUTABLE_SUFFIX ".elf")
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+set(CMAKE_STATIC_LIBRARY_SUFFIX ".a")
diff --git a/TFACMFConfig.cmake b/TFACMFConfig.cmake
new file mode 100644
index 0000000..c414941
--- /dev/null
+++ b/TFACMFConfig.cmake
@@ -0,0 +1,15 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Extend the module path with the location of the framework.
+function(_tfacmf_extend_module_path)
+	get_filename_component(_TMP ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
+	list(APPEND CMAKE_MODULE_PATH ${_TMP})
+	set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" PARENT_SCOPE)
+endfunction()
+
+_tfacmf_extend_module_path()
diff --git a/TFACMFConfigVersion.cmake b/TFACMFConfigVersion.cmake
new file mode 100644
index 0000000..2387aa2
--- /dev/null
+++ b/TFACMFConfigVersion.cmake
@@ -0,0 +1,38 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Read the version.txt file
+get_filename_component(_MY_LOC ${CMAKE_CURRENT_LIST_FILE} DIRECTORY)
+file(READ "${_MY_LOC}/version.txt" _VER_STRING)
+
+#Extract the version number
+string(REGEX MATCH "([0-9]+)\.([0-9]+)\.([0-9]+)" PACKAGE_VERSION ${_VER_STRING})
+
+#Set some meta-data
+set(TFACMF_VENDOR "Arm")
+set(TFACMF_DESCRIPTION_SUMMARY "CMake framework for TF-A.")
+set(PACKAGE_VERSION_MAJOR ${CMAKE_MATCH_1})
+set(PACKAGE_VERSION_MINOR ${CMAKE_MATCH_2})
+set(PACKAGE_VERSION_PATCH ${CMAKE_MATCH_3})
+set(CPACK_RESOURCE_FILE_LICENSE "${_MY_LOC}/license.rst")
+set(CPACK_RESOURCE_FILE_README "${_MY_LOC}/readme.rst")
+
+#Compare requested version with ours and report result to find_package()
+set(PACKAGE_VERSION_COMPATIBLE FALSE)
+set(PACKAGE_VERSION_EXACT FALSE)
+
+#Compare requested version to ours
+if(PACKAGE_FIND_VERSION_MAJOR EQUAL PACKAGE_VERSION_MAJOR)
+    set(_FIND_MP_VER "${PACKAGE_FIND_VERSION_MINOR}.${PACKAGE_FIND_VERSION_PATCH}")
+    set(_MY_MP_VER "${PACKAGE_VERSION_MINOR}.${PACKAGE_VERSION_PATCH}")
+
+    if (_FIND_MP_VER VERSION_EQUAL _MY_MP_VER)
+       set(PACKAGE_VERSION_EXACT TRUE)
+    elseif(_FIND_MP_VER VERSION_LESS _MY_MP_VER)
+        set(PACKAGE_VERSION_COMPATIBLE TRUE)
+    endif()
+endif()
diff --git a/dco.txt b/dco.txt
new file mode 100644
index 0000000..8201f99
--- /dev/null
+++ b/dco.txt
@@ -0,0 +1,37 @@
+Developer Certificate of Origin
+Version 1.1
+
+Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
+1 Letterman Drive
+Suite D4700
+San Francisco, CA, 94129
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+
+Developer's Certificate of Origin 1.1
+
+By making a contribution to this project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+    have the right to submit it under the open source license
+    indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the best
+    of my knowledge, is covered under an appropriate open source
+    license and I have the right under that license to submit that
+    work with modifications, whether created in whole or in part
+    by me, under the same open source license (unless I am
+    permitted to submit under a different license), as indicated
+    in the file; or
+
+(c) The contribution was provided directly to me by some other
+    person who certified (a), (b) or (c) and I have not modified
+    it.
+
+(d) I understand and agree that this project and the contribution
+    are public and that a record of the contribution (including all
+    personal information I submit with it, including my sign-off) is
+    maintained indefinitely and may be redistributed consistent with
+    this project or the open source license(s) involved.
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..f23d058
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/doc/change-log.rst b/doc/change-log.rst
new file mode 100644
index 0000000..76c979a
--- /dev/null
+++ b/doc/change-log.rst
@@ -0,0 +1,30 @@
+Change Log & Release Notes
+==========================
+
+This document contains a summary of the new features, changes, fixes and known
+issues in each release of Trusted Firmware-A CMake Framework.
+
+Version 0.1.0
+-------------
+
+New Features
+^^^^^^^^^^^^
+First release.
+
+Changes
+^^^^^^^
+None.
+
+Resolved Issues
+^^^^^^^^^^^^^^^
+None.
+
+Deprecations
+^^^^^^^^^^^^
+None.
+
+--------------
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/coding-guidelines.rst b/doc/coding-guidelines.rst
new file mode 100644
index 0000000..cda68bc
--- /dev/null
+++ b/doc/coding-guidelines.rst
@@ -0,0 +1,36 @@
+Coding Style & Guidelines
+=========================
+
+The following sections contain |TFACMF| coding guidelines. They are continually
+evolving and should not be considered "set in stone". Feel free to question them
+and provide feedback.
+
+Rules
+-----
+
+#. CMake file names use `CamelCase`_ formating.
+#. Indent with tabs and otherwise use spaces. Use 4 spaces for tab size.
+#. Use LF as line end in CMake files.
+#. Remove trailing whitespace.
+#. When complicated functionality is needed prefer CMake scripting over
+   other languages.
+#. Prefix local variables with `_`.
+#. Use functions to prevent global name-space pollution.
+#. Use `snake_case`_ for function and variable names.
+#. Use the ``include_guard()`` CMake function when creating new modules, to
+   prevent multiple inclusion.
+#. Use self contained modules, i.e. include direct dependencies of the module.
+#. Use the Sphinx CMake domain for in-line documentation of CMake scripts.
+   For details please refer to the `CMake Documentation`_.
+
+.. todo:: Explain CMake return values and parent scope concept in more detail.
+
+--------------
+
+.. _`CamelCase`: https://hu.wikipedia.org/wiki/CamelCase
+.. _`snake_case`: https://en.wikipedia.org/wiki/Snake_case
+.. _`CMake Documentation`: https://github.com/Kitware/CMake/blob/master/Help/dev/documentation.rst
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/conf.py b/doc/conf.py
new file mode 100644
index 0000000..31885eb
--- /dev/null
+++ b/doc/conf.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+# -- Metadata about this file ------------------------------------------------
+__copyright__ = "Copyright (c) 2019-2020 Arm Limited"
+__license__ = "SPDX-License-Identifier: BSD-3-Clause"
+
+# Configuration file for the Sphinx documentation builder.
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+# -- Project information -----------------------------------------------------
+project = 'CMake Framework'
+
+# The full version, including alpha/beta/rc tags
+with open('../version.txt', 'r') as f:
+  release = f.read()
+  f.close()
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = ['sphinx.ext.autosectionlabel', 'sphinxcontrib.plantuml',
+              'sphinxcontrib.moderncmakedomain', 'sphinx.ext.todo']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+source_suffix = '.rst'
+
+# The master toctree document.
+master_doc = 'index'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# Load the contents of the global substitutions file into the 'rst_prolog'
+# variable. This ensures that the substitutions are all inserted into each page.
+with open('global_substitutions.txt', 'r') as subs:
+  rst_prolog = subs.read()
+# Minimum version of sphinx required
+needs_sphinx = '2.0'
+
+# -- Options for HTML output -------------------------------------------------
+
+# Don't show the "Built with Sphinx" footer
+html_show_sphinx = False
+
+# Don't show copyright info in the footer (we have this content in the page)
+html_show_copyright = False
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = "sphinx_rtd_theme"
+
+# The logo to display in the sidebar
+# html_logo = ''
+
+# Options for the "sphinx-rtd-theme" theme
+html_theme_options = {
+  'collapse_navigation': False,  # Can expand and collapse sidebar entries
+  'prev_next_buttons_location': 'both',  # Top and bottom of the page
+  'style_external_links': True  # Display an icon next to external links
+}
+
+# -- Options for autosectionlabel --------------------------------------------
+
+# Only generate automatic section labels for document titles
+autosectionlabel_maxdepth = 1
+
+# -- Options for plantuml ----------------------------------------------------
+
+plantuml_output_format = 'svg_img'
+
+# -- Options for todo extension ----------------------------------------------
+
+# Display todos
+todo_include_todos = True
diff --git a/doc/contributing.rst b/doc/contributing.rst
new file mode 100644
index 0000000..a2d3398
--- /dev/null
+++ b/doc/contributing.rst
@@ -0,0 +1,107 @@
+Contributing
+============
+
+
+Getting Started
+---------------
+
+-  Make sure you have a Github account and you are logged on
+   `developer.trustedfirmware.org`_.
+-  Send an email to the |TFACMF-MAIL-LIST| about your work. This gives
+   everyone visibility of whether others are working on something similar.
+-  Clone the `TFACMF repository`_ on your own machine as suggested in the
+   :ref:`User Guide`.
+-  Create a local topic branch based on the `TFACMF repository`_ ``master``
+   branch.
+
+Making Changes
+--------------
+
+-  Make commits of logical units. See these general `Git guidelines`_ for
+   contributing to a project.
+-  Follow the :ref:`Coding Style & Guidelines`.
+-  Keep the commits on topic. If you need to fix another bug or make another
+   enhancement, please create a separate change.
+-  Avoid long commit series. If you do have a long series, consider whether
+   some commits should be squashed together or addressed in a separate topic.
+-  Make sure your commit messages are in the proper format.
+-  Where appropriate, please update the documentation.
+
+   -  Consider whether the :ref:`User Guide` or other in-source documentation
+      needs updating.
+   -  Ensure that each changed file has the correct copyright and license
+      information. Files that entirely consist of contributions to this
+      project should have a copyright notice and BSD-3-Clause SPDX license
+      identifier of the form as shown in :ref:`license`. Files that contain
+      changes to imported Third Party IP files should retain their original
+      copyright and license notices. For significant contributions you may
+      add your own copyright notice in following format:
+
+      ::
+
+          Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
+
+      where XXXX is the year of first contribution (if different to YYYY) and
+      YYYY is the year of most recent contribution. <OWNER> is your name or
+      your company name.
+   -  If you are submitting new files that you intend to be the technical
+      sub-maintainer for (for example, a new platform port), then also update
+      the :ref:`maintainers` file.
+   -  For topics with multiple commits, you should make all documentation
+      changes (and nothing else) in the last commit of the series. Otherwise,
+      include the documentation changes within the single commit.
+
+-  Please test your changes.
+
+Submitting Changes
+------------------
+
+-  Ensure that each commit in the series has at least one ``Signed-off-by:``
+   line, using your real name and email address. The names in the
+   ``Signed-off-by:`` and ``Author:`` lines must match. If anyone else
+   contributes to the commit, they must also add their own ``Signed-off-by:``
+   line. By adding this line the contributor certifies the contribution is made
+   under the terms of the
+   :download:`Developer Certificate of Origin <../dco.txt>`.
+
+   More details may be found in the `Gerrit Signed-off-by Lines guidelines`_.
+
+-  Ensure that each commit also has a unique ``Change-Id:`` line. If you have
+   cloned the repository with the "`Clone with commit-msg hook`" clone method
+   (as advised on the :ref:`User Guide`), this should already be the case.
+
+   More details may be found in the `Gerrit Change-Ids documentation`_.
+
+-  Submit your changes for review at https://review.trustedfirmware.org
+   targeting the ``integration`` branch.
+
+   -  The changes will then undergo further review and testing by the
+      :ref:`maintainers`. Any review comments will be made directly on your
+      patch. This may require you to do some rework.
+
+   Refer to the `Gerrit Uploading Changes documentation`_ for more details.
+
+-  When the changes are accepted, the :ref:`maintainers` will integrate them.
+
+   -  Typically, the :ref:`maintainers` will merge the changes into the
+      ``integration`` branch.
+   -  If the changes are not based on a sufficiently-recent commit, or if they
+      cannot be automatically rebased, then the :ref:`maintainers` may rebase it
+      on the ``master`` branch or ask you to do so.
+   -  After final integration testing, the changes will make their way into the
+      ``master`` branch. If a problem is found during integration, the merge
+      commit will be removed from the ``integration`` branch and the
+      :ref:`maintainers` will ask you to create a new patch set to resolve the
+      problem.
+
+--------------
+
+.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
+.. _Git guidelines: http://git-scm.com/book/ch5-2.html
+.. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
+.. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
+.. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/docs-build.rst b/doc/docs-build.rst
new file mode 100644
index 0000000..7ef059e
--- /dev/null
+++ b/doc/docs-build.rst
@@ -0,0 +1,77 @@
+Building Documentation
+======================
+
+To create a rendered copy of this documentation locally you can use the
+`Sphinx`_ tool to build and package the plain-text documents into HTML-formatted
+pages.
+
+If you are building the documentation for the first time then you will need to
+check that you have the required software packages, as described in the
+*Prerequisites* section that follows.
+
+Prerequisites
+-------------
+
+For building a local copy of the |TFACMF| documentation you will need, at minimum:
+
+- GNUMake
+- Python 3 (3.5 or later)
+- PlantUML (1.2017.15 or later)
+
+You must also install the Python modules that are specified in the
+``requirements.txt`` file in the root of the ``docs`` directory. These modules
+can be installed using ``pip3`` (the Python Package Installer). Passing this
+requirements file as an argument to ``pip3`` automatically installs the specific
+module versions required.
+
+Example environment
+-------------------
+
+An example set of installation commands for Linux with the following assumptions:
+    #. OS and version: Ubuntu 18.04 LTS
+    #. `virtualenv` is used to separate the python dependencies
+    #. pip is used for python dependency management
+    #. `bash` is used as the shell.
+
+.. code:: shell
+
+    sudo apt install make python3 python3-pip virtualenv python3-virtualenv plantuml
+    virtualenv -p python3 ~/tfacmf-venv
+    . ~/tfacmf-venv/bin/activate
+    pip3 install -r requirements.txt
+    deactivate
+
+.. note::
+   More advanced usage instructions for *pip* are beyond the scope of this
+   document but you can refer to the `pip homepage`_ for detailed guides.
+
+.. note::
+   For more information on Virtualenv please refer to the `Virtualenv documentation`_
+
+Building rendered documentation
+-------------------------------
+
+From the ``docs`` directory of the project, run the following commands.
+
+.. code:: shell
+
+   . ~/tfacmf-venv/bin/activate
+   make clean
+   make SPHINXOPTS=-W html
+   deactivate
+
+Output from the build process will be placed in:
+
+::
+
+   <tf-a CMF root>/docs/_build/html/
+
+--------------
+
+.. _Sphinx: http://www.sphinx-doc.org/en/master/
+.. _pip homepage: https://pip.pypa.io/en/stable/
+.. _`Virtualenv documentation`: https://virtualenv.pypa.io/en/latest/
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/gcc.rst b/doc/gcc.rst
new file mode 100644
index 0000000..58d9ba3
--- /dev/null
+++ b/doc/gcc.rst
@@ -0,0 +1,7 @@
+.. cmake-module:: ../Compiler/GCC.cmake
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/global_substitutions.txt b/doc/global_substitutions.txt
new file mode 100644
index 0000000..0d00064
--- /dev/null
+++ b/doc/global_substitutions.txt
@@ -0,0 +1,17 @@
+.. |TF-A| replace:: :term:`TF-A`
+.. |TFACMF| replace:: :term:`TFACMF`
+
+.. |C identifier like string| replace:: :term:`C identifier like string`
+
+.. |TFACMF-MAIL-LIST| replace:: `TF-A Mailing List`_
+.. |TFACMF_REPO| replace:: `TFACMF repository`_
+
+.. _`TF-A Mailing List`: https://lists.trustedfirmware.org/mailman/listinfo/tf-a
+.. _`TFACMF repository`: https://review.trustedfirmware.org/TF-A/cmake-framework.git
+
+..
+   --------------
+
+   *Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+   SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/glossary.rst b/doc/glossary.rst
new file mode 100644
index 0000000..78e8723
--- /dev/null
+++ b/doc/glossary.rst
@@ -0,0 +1,28 @@
+Glossary
+========
+
+This glossary provides definitions for terms and abbreviations used in the TF-A
+documentation.
+
+You can find additional definitions in the `Arm Glossary`_.
+
+.. glossary::
+   :sorted:
+
+   TF-A
+      Trusted Firmware-A
+
+   TFACMF
+      Trusted Firmware-A CMake Framework
+
+   C identifier like string
+      A name which uses only alphanumeric characters and underscores and the
+      first character is not a digit.
+
+--------------
+
+.. _`Arm Glossary`: https://developer.arm.com/support/arm-glossary
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/group.rst b/doc/group.rst
new file mode 100644
index 0000000..7c6543c
--- /dev/null
+++ b/doc/group.rst
@@ -0,0 +1,7 @@
+.. cmake-module:: ../Common/Group.cmake
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/index.rst b/doc/index.rst
new file mode 100644
index 0000000..d57d815
--- /dev/null
+++ b/doc/index.rst
@@ -0,0 +1,43 @@
+Welcome to TF-A CMake Framework's documentation!
+================================================
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents:
+
+   Home<self>
+   license
+   change-log
+   contributing
+   coding-guidelines
+   maintainers
+   user_guide
+   map
+   group
+   stgt
+   gcc
+   utils
+   docs-build
+   software_requirements
+   versioning_policy
+   glossary
+   todo
+
+The CMake Framework is a set of CMake functions organised into logical modules,
+adding missing features to CMake and standardizing the usage of existing ones.
+The framework's primary purpose is to simplify creating cross-compiled, embedded
+projects.
+
+The current version of the framework is version |release|. For details about
+changes between versions please refer to the :ref:`Change Log & Release Notes`.
+
+For information on planned changes and issues to be addressed please refer to
+:ref:`TODO list`.
+
+.. todo:: Expand general description of the framework.
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/license.rst b/doc/license.rst
new file mode 100644
index 0000000..2c44ee2
--- /dev/null
+++ b/doc/license.rst
@@ -0,0 +1,37 @@
+License
+=======
+
+Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+-  Redistributions of source code must retain the above copyright notice, this
+   list of conditions and the following disclaimer.
+-  Redistributions in binary form must reproduce the above copyright notice, this
+   list of conditions and the following disclaimer in the documentation and/or
+   other materials provided with the distribution.
+-  Neither the name of ARM nor the names of its contributors may be used to
+   endorse or promote products derived from this software without specific prior
+   written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------
+
+*Note*:
+Individual files contain the following tag instead of the full license text.
+
+    SPDX-License-Identifier:    BSD-3-Clause
+
+This enables machine processing of license information based on the SPDX
+License Identifiers that are here available: http://spdx.org/licenses/
\ No newline at end of file
diff --git a/doc/maintainers.rst b/doc/maintainers.rst
new file mode 100644
index 0000000..b87f4a0
--- /dev/null
+++ b/doc/maintainers.rst
@@ -0,0 +1,38 @@
+Maintainers
+===========
+
+|TFACMF| is an Arm maintained project. All contributions are ultimately merged
+by the maintainers listed below. Technical ownership of some parts of the
+codebase is delegated to the sub-maintainers listed below. An acknowledgement
+from these sub-maintainers may be required before the maintainers merge
+a contribution.
+
+This file follows the format of the Linux Maintainers file. For details on the
+meaning of tags below please refer to the `Linux Maintainers file`_.
+
+Main maintainers
+----------------
+:M: Dan Handley <dan.handley@arm.com>
+:G: `danh-arm`_
+:M: Bálint Dobszay <balint.dobszay@arm.com>
+:G: `balintdobszay`_
+:M: György Szing <gyorgy.szing@arm.com>
+:G: `gyuri-szing`_
+:L: |TFACMF-MAIL-LIST|
+
+Sub-maintainers
+--------------------
+
+Currently none.
+
+--------------
+
+.. _danh-arm: https://github.com/danh-arm
+.. _gyuri-szing: https://github.com/gyuri-szing
+.. _balintdobszay: https://github.com/balintdobszay
+
+.. _`Linux Maintainers file`: https://github.com/torvalds/linux/blob/master/MAINTAINERS#L80
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/map.rst b/doc/map.rst
new file mode 100644
index 0000000..a737b2e
--- /dev/null
+++ b/doc/map.rst
@@ -0,0 +1,7 @@
+.. cmake-module:: ../Common/Map.cmake
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/requirements.txt b/doc/requirements.txt
new file mode 100644
index 0000000..ff3a3f6
--- /dev/null
+++ b/doc/requirements.txt
@@ -0,0 +1,11 @@
+#

+# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.

+#

+# SPDX-License-Identifier: BSD-3-Clause

+#

+# Python dependencies for building the documentation.

+

+Sphinx==2.3.1

+sphinx-rtd-theme==0.4.3

+sphinxcontrib-moderncmakedomain==3.13

+sphinxcontrib-plantuml==0.18

diff --git a/doc/software_requirements.rst b/doc/software_requirements.rst
new file mode 100644
index 0000000..6d36e67
--- /dev/null
+++ b/doc/software_requirements.rst
@@ -0,0 +1,17 @@
+Software Requirements
+=====================
+
+The following applications and modules are required to use the framework:
+
+  * CMake, version 3.13 or newer
+  * GNU Make, version 4.2 or newer
+
+To build the documentation, please refer to :ref:`Building Documentation`.
+
+.. todo:: Describe cross-compiler requirements.
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/stgt.rst b/doc/stgt.rst
new file mode 100644
index 0000000..0858e4c
--- /dev/null
+++ b/doc/stgt.rst
@@ -0,0 +1,7 @@
+.. cmake-module:: ../Common/STGT.cmake
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/todo.rst b/doc/todo.rst
new file mode 100644
index 0000000..06e3666
--- /dev/null
+++ b/doc/todo.rst
@@ -0,0 +1,22 @@
+TODO list
+=========
+
+This file collects information on planned future changes and issues to be
+addressed. For managing the TODO list below, the `Sphinx TODO extension`_ is
+used.
+
+.. todo:: Find a solution to make the rendering of TODO entries less intrusive
+          at their original location.
+
+List of TODO entries in the project
+-----------------------------------
+
+.. todolist::
+
+--------------
+
+.. _`Sphinx TODO extension`: https://www.sphinx-doc.org/en/master/usage/extensions/todo.html
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
\ No newline at end of file
diff --git a/doc/user_guide.rst b/doc/user_guide.rst
new file mode 100644
index 0000000..d4e87e4
--- /dev/null
+++ b/doc/user_guide.rst
@@ -0,0 +1,180 @@
+User Guide
+==========
+
+This guide describes how the framework features are supposed to be used, through
+an example implementation for the |TF-A| project. Please refer to the `TF-A
+repository`_ for the code.
+
+Root CMakeLists file
+--------------------
+
+The root CMakeLists file contains the following sections:
+
+#. Set required CMake version
+
+     This is mandatory at the start of every CMake project. The framework
+     requires version 3.13 or newer.
+
+#. Set default build type
+
+     Set the default value for ``CMAKE_BUILD_TYPE`` as a cache entry. This
+     ensures that the variable will have a value when it is not specified as a
+     command line argument.
+
+#. Set project root dir
+
+     This is not strictly necessary, but makes referring to project relative
+     paths easier. Using ``CMAKE_CURRENT_LIST_DIR`` is recommended, it contains
+     the absolute path to the directory containing the currently processed file.
+
+#. Find the framework
+
+     The framework is written as a CMake module, which can be used by
+     :cmake:command:`find_package`. This will take care of the version matching
+     and adding the framework dir to the module path.
+
+     In the example, we try to find the framework at the parent directory of the
+     TF-A project dir and inside the TF-A project. If the framework is not
+     found, we clone the git repository using :cmake:module:`FetchContent`. The
+     path to the framework can also be provided as a command line option to
+     CMake, using ``-DTFACMF_DIR=<path to framework>``.
+
+#. Add project specific paths
+
+     There are some CMake modules which are specific to the project, so cannot
+     be part of the generic framework (e.g. find fiptool). These should also be
+     added to the module path.
+
+#. Set CMake system parameters
+
+     The framework provides a new platform called ``Embedded``. The project
+     should set :cmake:variable:`CMAKE_SYSTEM_NAME` to ``Embedded`` in order to
+     use the platform. This is an important step as this method is the only way
+     in CMake to ensure the correct output extension, library name
+     prefix/suffix, etc.
+
+     :cmake:variable:`CMAKE_SYSTEM_PROCESSOR` should be set to ``arm``. This has
+     no particular effect, but it indicates that the project is cross-compiled.
+
+#. Include framework files
+
+     It is more convenient to include the framework files here. The config and
+     target files included later will inherit the environment.
+
+#. Start CMake project
+
+     The start of a CMake project, ``C`` and ``ASM`` languages should be
+     selected.
+
+#. Find platform module
+
+     Currently for finding platform related config a minimal
+     :cmake:command:`find_package` module is implemented. These module files
+     describing the platform are located in the ``<TF-A root>/cmake/HwPlat``
+     directory, which is added to :cmake:variable:`CMAKE_MODULE_PATH` in the
+     project specific paths section.
+
+     A platform description file contains more :cmake:command:`find_package`
+     calls to find other external tools which are needed by the platform, and
+     sets the following global variables:
+
+       * :cmake:variable:`HW_PLAT_CONFIG`: path to config file which contains
+         the :cmake:module:`group` for the platform options,
+       * :cmake:variable:`HW_PLAT_TARGET`: path to target file which contains
+         target creation, adding source files, etc. for the platform,
+       * :cmake:variable:`HW_PLAT_IMAGE`: path to file which describes the steps
+         of packaging the compiled binaries into an image (e.g. fiptool usage).
+
+     The files indicated by these variables should be included in the relevant
+     sections of the root CMakeLists file, as described below.
+
+#. Include config files
+
+     All the config files containing the settings groups have to be included.
+     These create and fill the groups with content, so in the target files we
+     can select which group to apply on which target. This means including the
+     :cmake:variable:`HW_PLAT_CONFIG` too.
+
+#. Include target files
+
+     The target files selected for the current build have to be included. These
+     create the target and add source files, includes, etc. to the target.
+     Include :cmake:variable:`HW_PLAT_TARGET` in this section.
+
+     Currently there is no solution provided to select which targets are
+     necessary, except adding/removing the include command in this section. A
+     better solution would be to decide based on the current build configuration
+     (from Kconfig?) so targets can be selected without modifying the CMakeLists
+     file.
+
+#. Include image files
+
+     The files describing how to package the output binaries into an image can
+     be included here. Since this is platform specific, only
+     :cmake:variable:`HW_PLAT_IMAGE` should be used.
+
+Config file
+-----------
+
+The config files are located in the ``<TF-A root>/configs`` directory. Each
+config file creates a :cmake:module:`group` using :cmake:command:`group_new` and
+fills the group with content using :cmake:command:`group_add`.
+
+An important topic in the example is the difference between the ``CONFIG`` and
+``DEFINE`` types in a group. The idea is, that ``CONFIG`` is a parameter that
+affects the build, i.e. what sources are necessary for a given target, etc.
+while ``DEFINE`` is a simple C language define. Often a build option falls into
+both categories, but not necessarily. For example,
+
+* ``ENABLE_AMU`` is a config, because it affects the build, it determines
+  whether ``amu.c`` is added to ``BL31`` or not. It is a define too, because
+  there is ``#if ENABLE_AMU`` conditional compilation in the C source,
+
+* ``FVP_MAX_PE_PER_CPU`` is a define only, because it does not affect the list
+  of files necessary for the build,
+
+* ``ENABLE_STACK_PROTECTOR`` is a config only, because it is never used in the
+  source code.
+
+Target file
+-----------
+
+A target file can be one of two types, ``CMakeLists.txt`` or ``<module
+name>.cmake``. The former is for a module which is likely to be reused in other
+projects and can be built stand-alone, the latter is a module which only has
+meaning as part of the project. A ``CMakeLists.txt`` must contain a
+:cmake:command:`project` command and has to be included using
+:cmake:command:`add_subdirectory`, while a ``<module name>.cmake`` cannot start
+a new project and the file is simply included with the :cmake:command:`include`
+command.
+
+A target file uses the :cmake:module:`STGT` functions to create a target, add
+groups to the target, add source files, etc. Please check the example code in
+TF-A, e.g.:
+
+* ``bl*/bl*.cmake``
+* ``plat/arm/board/fvp/platform.cmake``
+* ``plat/arm/common/arm_common.cmake``
+* ``lib/libc/CMakeLists.txt``
+* etc.
+
+Image file
+----------
+
+The purpose of this file is to package the output binaries into an image, using
+the platform specific tools. The recommendation is to use
+:cmake:command:`add_custom_target` which depends on the targets/files packaged
+into the image. It is likely that ``ALL`` should be added to the command
+options, since usually this image is the final output of the build, so no other
+targets will depend on this therefore it would not be built without ``ALL``.
+Please check the example in ``plat/arm/board/fvp/image.cmake``.
+
+.. todo:: Add support for ``install`` feature of CMake.
+
+--------------
+
+.. _`TF-A repository`: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/utils.rst b/doc/utils.rst
new file mode 100644
index 0000000..f0eee13
--- /dev/null
+++ b/doc/utils.rst
@@ -0,0 +1,7 @@
+.. cmake-module:: ../Common/Utils.cmake
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/doc/versioning_policy.rst b/doc/versioning_policy.rst
new file mode 100644
index 0000000..83f45c7
--- /dev/null
+++ b/doc/versioning_policy.rst
@@ -0,0 +1,50 @@
+Versioning policy
+==================
+
+This document captures information about how the version identifier of the
+|TFACMF| is built up, what is the meaning of each part, where the version
+information is captured and how it is managed.
+
+Summary
+-------
+
+The version identifier identifies the feature set supported by a specific
+release of the |TFACMF|, and captures compatibility information to other
+releases.
+
+This project uses "Semantic Versioning v2.0". For details please refer to
+|SMVC| v2.0.
+
+In general the version number is constructed from three numbers. The `MAJOR`
+number is changed when incompatible API changes are introduced, the `MINOR`
+version when you functionality is added in a backward compatible manner, and
+the `PATCH` version when backwards compatible bug fixes are added.
+
+Each release will get a unique release id assigned. When a release is made, the
+version number will get incremented in accordance with the compatibility rules
+mentioned above.
+
+This project is only using the core version and will not use pre-release or
+build specific metadata extension.
+
+Storage and format
+------------------
+
+The version number of each release will be stored at two locations:
+  #. In a tag of the version control system in the form of "vX.Y.Z" where X Y
+     and Z are the major, minor and patch version numbers.
+  #. In a file called version.txt. This file uses ASCII encoding and will
+     contain the version number as "X.Y.Z"  where X Y and Z are the major,
+     minor and patch version numbers.
+
+.. note:: The version id is independent from version identifiers of the
+          versioning system used to store the |TFACMF| (i.e. git).
+
+--------------
+
+.. |SMVC| replace:: `Semantic Versioning`_
+.. _`Semantic Versioning`: https://semver.org/spec/v2.0.0.html
+
+*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/license.rst b/license.rst
new file mode 100644
index 0000000..3ec3b74
--- /dev/null
+++ b/license.rst
@@ -0,0 +1 @@
+See docs/license.rst
diff --git a/readme.rst b/readme.rst
new file mode 100644
index 0000000..7178b4a
--- /dev/null
+++ b/readme.rst
@@ -0,0 +1,26 @@
+CMake Framework
+===============
+
+This repository holds the CMake Framework designed for the Trusted Firmware-A
+project.
+
+The full documentation of this project is `Sphinx`_ based, lives in the *doc*
+sub-directory and is captured in reStructuredText_ format.
+
+For licensing information please refer to `license.rst`_
+
+Contributed content is accepted under the
+`Developer Certificate of Origin (DCO)`_ and commit messages shall follow
+specific formatting  rules (for details please refer to the
+*Contributing* sections of the full documentation).
+
+.. _reStructuredText: http://docutils.sourceforge.net/rst.html
+.. _Sphinx: http://www.sphinx-doc.org/en/master/
+.. _`license.rst`: ./license.rst
+.. _`Developer Certificate of Origin (DCO)`: ./dco.txt
+
+--------------
+
+*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/version.txt b/version.txt
new file mode 100644
index 0000000..6c6aa7c
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+0.1.0
\ No newline at end of file