Doc: Add support for Sphinx documentation build.

Technical documentation of TF-M is captured in GitHub flavored
markdown files. This change add support for building HTML and
PDF output of these files using the Sphinx tool.

Change-Id: I8be11256f2c654c248b1974974a5de6190ca0fc3
Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
diff --git a/cmake/Common/BuildDoxygenDoc.cmake b/cmake/Common/BuildDoxygenDoc.cmake
index 6f9c6c7..f98c0f9 100644
--- a/cmake/Common/BuildDoxygenDoc.cmake
+++ b/cmake/Common/BuildDoxygenDoc.cmake
@@ -56,7 +56,7 @@
 		set(DOXYGEN_EXECUTABLE "${DOXYGEN_EXECUTABLE}" PARENT_SCOPE)
 		set(DOXYGEN_DOT_EXECUTABLE "${DOXYGEN_DOT_EXECUTABLE}" PARENT_SCOPE)
 		set(PLANTUML_JAR_PATH "${PLANTUML_JAR_PATH}" PARENT_SCOPE)
-		set(_NODOC False PARENT_SCOPE)
+		set(NODOC False PARENT_SCOPE)
 	else()
 		message(WARNING "Some tools are missing for document generation. Document generation target is not created.")
 		set(NODOC True PARENT_SCOPE)
@@ -85,7 +85,7 @@
 	#Version ID of TF-M.
 	#TODO: this shall not be hard-coded here. A process need to defined for
 	#      versioning the document (and TF-M).
-	set(DOXYCFG_TFM_VERSION "v0.01")
+	set(DOXYCFG_TFM_VERSION "v1.0.0-Beta")
 
 	#Using add_custom_command allows CMake to generate proper clean commands
 	#for document generation.
diff --git a/cmake/Common/BuildSphinxDoc.cmake b/cmake/Common/BuildSphinxDoc.cmake
new file mode 100644
index 0000000..7287d05
--- /dev/null
+++ b/cmake/Common/BuildSphinxDoc.cmake
@@ -0,0 +1,169 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#This file adds build and install targets to build the Sphinx documentation
+#for TF-M. This currently means the "User Guide". Further documentation
+#builds may be added in the future.
+
+Include(CMakeParseArguments)
+
+#This function will find the location of tools needed to build the
+#documentation. These are:
+#   - Mandatory:
+#        - Sphinx 1.9.0 or higher
+#        - PlantUML and it's dependencies
+#   - Optional
+#        - LateX/PDFLateX
+#
+#Inputs:
+#   none (some global variables might be used by FindXXX modules used. For
+#         details please check the modules used.)
+#Outputs:
+#   SPHINX_NODOC - will be defined and set to true is any mandatory tool is
+#                  missing.
+#   PDFLATEX_COMPILER - path to pdflatex executable
+#   SPHINX_EXECUTABLE - path to sphinx-build
+#   PLANTUML_JAR_PATH - path to PlantUML
+
+#Examples
+#   SphinxFindTools()
+#
+function(SphinxFindTools)
+	find_package(Sphinx)
+
+	#Find additional needed python dependencies.
+	find_package(PythonModules COMPONENTS m2r sphinx-rtd-theme)
+
+	#Find plantUML
+	find_package(PlantUML)
+
+	#Find tools needed for PDF generation.
+	find_package(LATEX COMPONENTS PDFLATEX)
+	if (LATEX_PDFLATEX_FOUND)
+		set (PDFLATEX_COMPILER "${PDFLATEX_COMPILER}" PARENT_SCOPE)
+	endif()
+
+	if (SPHINX_FOUND AND PLANTUML_FOUND AND PY_M2R_FOUND
+			AND PY_SPHINX-RTD-THEME_FOUND)
+		#Export executable locations to global scope.
+		set(SPHINX_EXECUTABLE "${SPHINX_EXECUTABLE}" PARENT_SCOPE)
+		set(PLANTUML_JAR_PATH "${PLANTUML_JAR_PATH}" PARENT_SCOPE)
+		set(SPHINX_NODOC False PARENT_SCOPE)
+	else()
+		message(WARNING "Some tools are missing for Sphinx document generation. Document generation target is not created.")
+		set(SPHINX_NODOC True PARENT_SCOPE)
+	endif()
+endfunction()
+
+#Find the needed tools.
+SphinxFindTools()
+
+#If mandatory tools are missing, skip creating document generation targets.
+#This means missing documentation tools is not a critical error, and building
+#TF-M is still possible.
+if (NOT SPHINX_NODOC)
+	#The Sphinx configuration file needs some project specific configuration.
+	#Variables with SPHINXCFG_ prefix are setting values related to that.
+	#This is where Sphinx output will be written
+	set(SPHINXCFG_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/doc_sphinx")
+
+	set(SPHINX_TMP_DOC_DIR "${CMAKE_CURRENT_BINARY_DIR}/doc_sphinx_in")
+
+	set(SPHINXCFG_TEMPLATE_FILE "${TFM_ROOT_DIR}/docs/Conf.py.in")
+	set(SPHINXCFG_CONFIGURED_FILE "${SPHINXCFG_OUTPUT_PATH}/Conf.py")
+
+
+	#Version ID of TF-M.
+	#TODO: this shall not be hard-coded here. We need a process to define the
+	#      version number of the document (and TF-M).
+	set(SPHINXCFG_TFM_VERSION "1.0.0-Beta")
+	set(SPHINXCFG_TFM_VERSION_FULL "Version 1.0.0-Beta")
+
+	#Using add_custom_command allows CMake to generate proper clean commands
+	#for document generation.
+	add_custom_command(OUTPUT "${SPHINX_TMP_DOC_DIR}"
+		COMMAND "${CMAKE_COMMAND}" -D TFM_ROOT_DIR=${TFM_ROOT_DIR} -D DST_DIR=${SPHINX_TMP_DOC_DIR} -P "${TFM_ROOT_DIR}/cmake/SphinxCopyDoc.cmake"
+		WORKING_DIRECTORY "${TFM_ROOT_DIR}"
+		VERBATIM
+		)
+
+	add_custom_command(OUTPUT "${SPHINXCFG_OUTPUT_PATH}/html"
+		COMMAND "${SPHINX_EXECUTABLE}" -c "${SPHINXCFG_OUTPUT_PATH}" -b html "${SPHINX_TMP_DOC_DIR}" "${SPHINXCFG_OUTPUT_PATH}/html"
+		WORKING_DIRECTORY "${TFM_ROOT_DIR}"
+		DEPENDS "${SPHINX_TMP_DOC_DIR}"
+		COMMENT "Running Sphinx to generate user guide (HTML)."
+		VERBATIM
+		)
+
+	#Create build target to generate HTML documentation.
+	add_custom_target(doc_userguide
+		COMMENT "Generating User Guide with Sphinx..."
+		#Copy document files from the top level dir to docs
+		SOURCES "${SPHINXCFG_OUTPUT_PATH}/html"
+		)
+
+	#Add the HTML documentation to install content
+	install(DIRECTORY ${SPHINXCFG_OUTPUT_PATH}/html DESTINATION doc/user_guide
+		EXCLUDE_FROM_ALL
+		COMPONENT user_guide
+		PATTERN .buildinfo EXCLUDE
+		)
+
+	#If PDF documentation is being made.
+	if (PDFLATEX_COMPILER)
+		set(_PDF_FILE "${SPHINXCFG_OUTPUT_PATH}/latex/tf-m.pdf")
+
+		add_custom_command(OUTPUT "${SPHINXCFG_OUTPUT_PATH}/latex"
+			COMMAND "${SPHINX_EXECUTABLE}" -c "${SPHINXCFG_OUTPUT_PATH}" -b latex "${SPHINX_TMP_DOC_DIR}" "${SPHINXCFG_OUTPUT_PATH}/latex"
+			WORKING_DIRECTORY "${TFM_ROOT_DIR}"
+			DEPENDS "${SPHINX_TMP_DOC_DIR}"
+			COMMENT "Running Sphinx to generate user guide (LaTeX)."
+			VERBATIM
+			)
+
+		add_custom_command(OUTPUT "${_PDF_FILE}"
+			COMMAND "${CMAKE_MAKE_PROGRAM}" all-pdf
+			WORKING_DIRECTORY ${SPHINXCFG_OUTPUT_PATH}/latex
+			DEPENDS "${SPHINXCFG_OUTPUT_PATH}/latex"
+			COMMENT "Generating PDF version of User Guide..."
+			VERBATIM
+			)
+
+		#We do not use the add_custom_command trick here to get proper clean
+		#command since the clean rules "added" above will remove the entire
+		#doc directory, and thus clean the PDF output too.
+		add_custom_target(doc_userguide_pdf
+			COMMENT "Generating PDF version of TF-M User Guide..."
+			SOURCES "${_PDF_FILE}"
+			VERBATIM)
+
+		#Add the pdf documentation to install content
+		install(FILES "${_PDF_FILE}" DESTINATION "doc/user_guide"
+			RENAME "tf-m_user_guide.pdf"
+			COMPONENT user_guide
+			EXCLUDE_FROM_ALL)
+	else()
+		message(WARNING "PDF generation tools are missing. PDF document generation target is not created.")
+	endif()
+
+	#Generate build target which installs the documentation.
+	if (TARGET doc_userguide_pdf)
+		add_custom_target(install_userguide
+			DEPENDS doc_userguide doc_userguide_pdf
+			COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=user_guide
+			-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
+	else()
+		add_custom_target(install_userguide
+			DEPENDS doc_userguide
+			COMMAND "${CMAKE_COMMAND}" -DCMAKE_INSTALL_COMPONENT=user_guide
+			-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
+	endif()
+
+	#Now instantiate a Sphinx configuration file from the template.
+	message(STATUS "Writing Sphinx configuration...")
+	configure_file(${SPHINXCFG_TEMPLATE_FILE} ${SPHINXCFG_CONFIGURED_FILE} @ONLY)
+endif()
diff --git a/cmake/Common/Utils.cmake b/cmake/Common/Utils.cmake
index 0c3b0d0..452d0bf 100644
--- a/cmake/Common/Utils.cmake
+++ b/cmake/Common/Utils.cmake
@@ -1,31 +1,41 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2017, Arm Limited. All rights reserved.
+# Copyright (c) 2017-2019, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 #-------------------------------------------------------------------------------
 
-# Append a value to a string if not already present
+
+#Print a message and exit with failure
 #
-# Append an item to a string if no item with matching key is already on the string.
-# This function's intended purpose is to append unique flags to command line switches.
+#Examples:
+#   failure("Something is wrong!")
+
+function(failure)
+	message(FATAL_ERROR "${ARGN}")
+endfunction()
+
+#Append a value to a string if not already present
 #
-# Examples:
-#  string_append_unique_item(STRING C_FLAGS KEY "--target" VAL "--target=armv8m-arm-none-eabi")
+#Append an item to a string if no item with matching key is already on the string.
+#This function's intended purpose is to append unique flags to command line switches.
 #
-# INPUTS:
-#    STRING  - (mandatory) - name of the string to operate on
-#    KEY   - (mandatory) - string to look for
-#    VAL   - (mandatory) - value to put be added to the string
+#Examples:
+#   string_append_unique_item(STRING C_FLAGS KEY "--target" VAL "--target=armv8m-arm-none-eabi")
 #
-# OUTPUTS
-#    STRING is modified as needed.
+#INPUTS:
+#   STRING  - (mandatory) - name of the string to operate on
+#   KEY     - (mandatory) - string to look for
+#   VAL     - (mandatory) - value to put be added to the string
+#
+#OUTPUTS
+#   STRING is modified as needed.
 #
 function(string_append_unique_item)
 	#Parse our arguments
-	set( _OPTIONS_ARGS )					#No option (on/off) arguments (e.g. IGNORE_CASE)
-	set( _ONE_VALUE_ARGS  STRING KEY VAL)	#Single option arguments (e.g. PATH "./foo/bar")
-	set( _MULTI_VALUE_ARGS )		 		#List arguments (e.g. LANGUAGES C ASM CXX)
+	set( _OPTIONS_ARGS )                    #No option (on/off) arguments (e.g. IGNORE_CASE)
+	set( _ONE_VALUE_ARGS  STRING KEY VAL)   #Single option arguments (e.g. PATH "./foo/bar")
+	set( _MULTI_VALUE_ARGS )                #List arguments (e.g. LANGUAGES C ASM CXX)
 	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
 
 	#Check mandatory parameters
@@ -42,11 +52,54 @@
 	if(NOT _MY_PARAMS_VAL)
 		failure("string_append_unique_item(): Missing VAL parameter!")
 	endif()
-    set(_VAL ${_MY_PARAMS_VAL})
+	set(_VAL ${_MY_PARAMS_VAL})
 
-    #Scan the string.
-    STRING(REGEX MATCH "( |^) *${_KEY}" _FOUND "${${_STRING}}")
-    if("${_FOUND}" STREQUAL "")
+	#Scan the string.
+	STRING(REGEX MATCH "( |^) *${_KEY}" _FOUND "${${_STRING}}")
+	if("${_FOUND}" STREQUAL "")
 		set(${_STRING} "${${_STRING}}  ${_VAL}" PARENT_SCOPE)
-    endif()
+	endif()
+endfunction()
+
+
+#Convert \ directory separators to / on windows systems
+#
+#Convert the directory separators to forward slash on windows. Avoid
+#conversion if path contains any forward slashes to avoid mixing up cygwin or
+#mingw paths where an extra caharacter is escaped (i.e. "/c/Program\ Files/")
+#
+#Examples:
+#   set(MY_PATH "C:\foo\bar")
+#   win_fix_dir_sep(PATH MY_PATH)
+#
+#INPUTS:
+#   PATH  - (mandatory) - name of the string variable to operate on
+#
+#OUTPUTS
+#   PATH is modified as needed.
+#
+function(win_fix_dir_sep)
+	#Parse our arguments
+	set( _OPTIONS_ARGS )            #No option (on/off) arguments (e.g. IGNORE_CASE)
+	set( _ONE_VALUE_ARGS  PATH )    #Single option arguments (e.g. PATH "./foo/bar")
+	set( _MULTI_VALUE_ARGS )        #List arguments (e.g. LANGUAGES C ASM CXX)
+	cmake_parse_arguments(_MY_PARAMS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} )
+
+	#Check mandatory parameters
+	if(NOT _MY_PARAMS_PATH)
+		failure("win_fix_dir_sep(): Missing mandatory parameter PATH!")
+	endif()
+	set(_PATH ${_MY_PARAMS_PATH})
+
+	#To avoid trouble on windows change directory separator.
+	if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+		#Do not convert directory separator if there are forward slashes
+		#present. This is to avoid mixing up escaped characters in cygwin
+		#or mingw paths (i.e. c:/Program\ Files/something)
+		string(FIND "${${_PATH}}" "/" _is_found)
+		if (_is_found LESS 0)
+			string(REPLACE "\\" "/" ${_PATH} "${${_PATH}}")
+			set(${_PATH} "${${_PATH}}" PARENT_SCOPE)
+		endif()
+	endif()
 endfunction()
diff --git a/cmake/FindPlantUML.cmake b/cmake/FindPlantUML.cmake
index a55774c..ae61be7 100644
--- a/cmake/FindPlantUML.cmake
+++ b/cmake/FindPlantUML.cmake
@@ -5,30 +5,30 @@
 #
 #-------------------------------------------------------------------------------
 
-# FindPlantuml
-# -----------
-# PlantUML is a diagram generation tool. It can generate various UML and non-UML
-# diagrams. See: http://plantuml.com/
+#FindPlantuml
+#-----------
+#PlantUML is a diagram generation tool. It can generate various UML and non-UML
+#diagrams. See: http://plantuml.com/
 #
-# This module checks PlantUML availability and checks if the Java runtime is
-# available.
-# For Windows PlantUML is distributed as a jar archive and thus there is no
-# standard install location where it could be searched for.
-# Most Linux distributions come with a proper PlantUML package which installs
-# a shell script to easy starting PlantUML, but the location of the .jar file
-# is hidden.
-# Thus there is no standard location to search for the .jar file and this module
-# depends on user input.
+#This module checks PlantUML availability and checks if the Java runtime is
+#available.
+#For Windows PlantUML is distributed as a jar archive and thus there is no
+#standard install location where it could be searched for.
+#Most Linux distributions come with a proper PlantUML package which installs
+#a shell script to easy starting PlantUML, but the location of the .jar file
+#is hidden.
+#Thus there is no standard location to search for the .jar file and this module
+#depends on user input.
 #
-# This module has the following parameters:
-#    PLANTUML_JAR_PATH   = variable specifying where the PlantUML java archive
-#                          (plantuml.jar) can be found. If it is not defined,
-#                          the environment variable with the same name is used.
-#                          If both is missing, that is an error.
+#This module has the following parameters:
+#   PLANTUML_JAR_PATH   = variable specifying where the PlantUML java archive
+#                         (plantuml.jar) can be found. If it is not defined,
+#                         the environment variable with the same name is used.
+#                         If both is missing, that is an error.
 #
-# This module defines the following variables:
-#    PLANTUML_VERSION        = The version reported by "plantuml.jar -version"
-#    PLANTUML_FOUND          = Was the .jar file found and sucesfuly executed.
+#This module defines the following variables:
+#   PLANTUML_VERSION        = The version reported by "plantuml.jar -version"
+#   PLANTUML_FOUND          = Was the .jar file found and sucesfuly executed.
 #
 
 find_package(Java 1.8 COMPONENTS Runtime)
@@ -44,17 +44,7 @@
 	if (NOT DEFINED PLANTUML_JAR_PATH)
 		message(STATUS "PLANTUML_JAR_PATH variable is missing, PlantUML jar location is unknown.")
 	else()
-		#To avoid trouble on windows change directory separator.
-		if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
-			#Do not convert directory separator if there are forward slashes
-			#present. This is to avoid mixing up escaped characters in cygwin
-			#or mingw paths (i.e. c:/Program\ Files/something)
-			string(FIND "${PLANTUML_JAR_PATH}" "/" _is_found)
-			if (_is_found LESS 0)
-				string(REPLACE "\\" "/" PLANTUML_JAR_PATH "${PLANTUML_JAR_PATH}")
-			endif()
-		endif()
-
+		win_fix_dir_sep(PATH PLANTUML_JAR_PATH)
 		#Get plantuml version
 		execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" "-jar" "${PLANTUML_JAR_PATH}" "-version" OUTPUT_VARIABLE _PLANTUML_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
 		#Parse plantuml output
diff --git a/cmake/FindPythonModules.cmake b/cmake/FindPythonModules.cmake
new file mode 100644
index 0000000..bb8d4fb
--- /dev/null
+++ b/cmake/FindPythonModules.cmake
@@ -0,0 +1,64 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#FindPythonModules
+#-----------
+#This module checks availability of Python modules.
+#
+#This module has the following parameters:
+#   PYTHON_EXECUTABLE - Location of python interpreter.
+#   COMPONENTS        - List of python modules to look for.
+#
+#This module defines the following variables:
+#   PY_XXX       - Cached string variable with the location of the module.
+#   PY_XXX_FOUND - Set if the module is available.
+#
+#   Where XXX is the upper case name of the module.
+#
+#Examples
+#   To look for m2r and report error if not found
+#       find_module(PythonModules COMPONENTS m2r)
+#       if (PY_M2R_FOUND)
+#           do something
+#       endif()
+#
+#   To look for m2r and do not report error if not found
+#       find_module(PythonModules OPTIONAL_COMPONENTS m2r)
+#       if (PY_M2R_FOUND)
+#           do something
+#       endif()
+
+if(NOT DEFINED PYTHON_EXECUTABLE)
+	message(FATAL_ERROR "FindPythonModules: mandatory parameter PYTHON_EXECUTABLE is missing.")
+endif()
+
+include(Common/Utils)
+
+foreach(_mod ${PythonModules_FIND_COMPONENTS})
+	string(TOUPPER ${_mod} _mod_upper)
+	string(REPLACE "-" "_" _modname "${_mod}")
+	if (NOT PY_${_mod_upper})
+		#Execute python and try to include the module.
+		execute_process(
+			COMMAND ${PYTHON_EXECUTABLE} -c "import ${_modname}; print(${_modname}.__file__);"
+			RESULT_VARIABLE ${_mod}_status
+			OUTPUT_VARIABLE ${_mod}_path
+			ERROR_QUIET
+			OUTPUT_STRIP_TRAILING_WHITESPACE)
+		#If suceeded
+		if(NOT ${_mod}_status)
+			#Avoid trouble with directory separator on windows.
+			win_fix_dir_sep(PATH ${_mod}_path)
+			set("PY_${_mod_upper}" "${${_mod}_path}" CACHE STRING
+				"Location of Python module ${_mod}")
+		endif()
+	endif()
+	find_package_handle_standard_args(PY_${_mod_upper}
+		FOUND_VAR PY_${_mod_upper}_FOUND
+		REQUIRED_VARS PY_${_mod_upper}
+		FAIL_MESSAGE "Can not find Python module ${_mod}")
+endforeach()
diff --git a/cmake/FindSphinx.cmake b/cmake/FindSphinx.cmake
new file mode 100644
index 0000000..8e3925e
--- /dev/null
+++ b/cmake/FindSphinx.cmake
@@ -0,0 +1,92 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#FindSphinx
+#-----------
+#Sphinx is a document generation tool written in Python.
+#See http://www.sphinx-doc.org/en/master/
+#
+#This module checks availability of the Sphinx document generator
+#(sphinx-build) and it's dependences (Python).
+#Sphinx is distributed as pip package or on Linux as a distribution specific
+#package (i.e. python-sphinx for Ubuntu). Independent of the distribution
+#method this module expects sphix-build to be either available on the PATH,
+#or to be located in a host OS specific standard location.
+#
+#This modules has the following parameters:
+#   SPHINX_PATH   = variable specifying where sphinx-build can be found.
+#                         If it is not defined the environment variable with
+#                         the same name is used. If that is also undefined,
+#                         then OS specific standard locations will be
+#                         searched.
+#
+# This modules defines the following variables:
+#   SPHINX_VERSION   = The version reported by "sphinx-build --version"
+#   SPHINX_FOUND     = True is sphinx-build was found and executed fine
+#
+
+Include(CMakeParseArguments)
+
+#Sphinx needs Python.
+find_package(PythonInterp 3)
+if (NOT PYTHONINTERP_FOUND)
+	message(STATUS "Can not find Python3.x interpreter. Pyhton3 must be installed and available on the PATH.")
+	message(STATUS "Sphinx documentation targets will not be created.")
+	return()
+endif()
+
+if (NOT DEFINED SPHINX_PATH)
+	if (DEFINED $ENV{SPHINX_PATH})
+	set(SPHINX_PATH $ENV{SPHINX_PATH})
+	endif()
+endif()
+
+
+if (DEFINED SPHINX_PATH)
+	#Find the Sphinx executable. Search only at SPHINX_PATH.
+	find_program(SPHINX_EXECUTABLE
+		NAMES sphinx-build
+		DOC "Sphinx Documentation Builder (sphinx-doc.org)"
+		PATH ${SPHINX_PATH}
+		NO_DEFAULT_PATH
+		NO_CMAKE_ENVIRONMENT_PATH
+		NO_CMAKE_PATH
+		NO_SYSTEM_ENVIRONMENT_PATH
+		NO_CMAKE_SYSTEM_PATH
+		NO_CMAKE_FIND_ROOT_PATH
+	)
+	if (SPHINX_EXECUTABLE-NOTFOUND)
+		message(STATUS "Failed to find sphinx-build at ${SPHINX_PATH}.")
+		message(STATUS "Sphinx documentation targets will not be created.")
+		return()
+	endif()
+else()
+	#Find the Sphinx executable. Search OS specific default locations.
+	find_program(SPHINX_EXECUTABLE
+	  NAMES sphinx-build
+	  DOC "Sphinx Documentation Builder (sphinx-doc.org)"
+	)
+
+	if (SPHINX_EXECUTABLE-NOTFOUND)
+		message(STATUS "Failed to find sphinx-build at OS specific default locations.")
+		message(STATUS "Sphinx documentation targets will not be created.")
+		return()
+	endif()
+endif()
+
+#Get Sphinx version
+execute_process(COMMAND "${SPHINX_EXECUTABLE}" "--version" OUTPUT_VARIABLE _SPHINX_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+#Parse output
+if(_SPHINX_VERSION)
+	if(_SPHINX_VERSION MATCHES ".*sphinx-build ([0-9.]+).*")
+		string(REGEX REPLACE ".*sphinx-build ([0-9.]+).*" "\\1" SPHINX_VERSION "${_SPHINX_VERSION}")
+	endif()
+endif()
+
+#Set "standard" find module return values
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Sphinx REQUIRED_VARS SPHINX_EXECUTABLE SPHINX_VERSION VERSION_VAR SPHINX_VERSION)
diff --git a/cmake/SphinxCopyDoc.cmake b/cmake/SphinxCopyDoc.cmake
new file mode 100644
index 0000000..c1f7731
--- /dev/null
+++ b/cmake/SphinxCopyDoc.cmake
@@ -0,0 +1,57 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Sphinx needs all document files to be under a single directory. This script
+#copies all document files to a temporary directory while keeping the original
+#directory tree (relative location of files) except "docs/index.rst" which is
+#moved to the top level of the new tree.
+#
+#  i.e.:
+#    <DST_DIR>
+#    |   All documents from <TFM_ROOT_DIR> plus <TFM_ROOT_DIR>/docs/index.rst
+#    |
+#    +---docs
+#    |   |
+#        \- all documents from <TFM_ROOT_DIR>/docs except index.rst
+#    |
+#    +---lib
+#    |   |
+#    |   \- All document from <TFM_ROOT_DIR>/lib keeping reativle location
+#    ...
+#    |
+#
+#Usage:
+#   cmake -DDST_RIR=<path to destination> -DTFM_ROOT_DIR=<path to tf-m root> \
+#          -P SphinxCopyDoc.cmake
+
+#Check input parameters
+foreach(_PARAM IN ITEMS TFM_ROOT_DIR DST_DIR)
+	if (NOT DEFINED ${_PARAM})
+		message(FATAL_ERROR "Variable ${_PARAM} is undefined. Please add -D${_PARAM}=<...> when calling this script.")
+	endif()
+endforeach()
+
+message(STATUS "Creating document tree for Sphinx under ${DST_DIR}")
+
+#List all document files.
+file(GLOB_RECURSE _COPY_FILES
+		LIST_DIRECTORIES false
+		RELATIVE "${TFM_ROOT_DIR}"
+		"${TFM_ROOT_DIR}/*.md"
+		"${TFM_ROOT_DIR}/*.rst")
+
+#Subtract exluded files from copy files
+list(REMOVE_ITEM _COPY_FILES "docs/index.rst")
+
+#Copy files with directory tree.
+foreach(_FILE ${_COPY_FILES})
+	get_filename_component(_DIR ${_FILE} DIRECTORY)
+	file(COPY ${_FILE} DESTINATION "${DST_DIR}/${_DIR}")
+endforeach()
+
+#Copy index.rst to the top level
+file(COPY "${TFM_ROOT_DIR}/docs/index.rst" DESTINATION "${DST_DIR}")
diff --git a/docs/conf.py.in b/docs/conf.py.in
new file mode 100644
index 0000000..1caebb2
--- /dev/null
+++ b/docs/conf.py.in
@@ -0,0 +1,168 @@
+# -*- coding: utf-8 -*-
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------#
+
+# Configuration file for the Sphinx documentation builder.
+#
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- 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('..'))
+sys.path.insert(0, os.path.abspath('../docs'))
+
+# -- Project information -----------------------------------------------------
+
+project = 'TF-M'
+copyright = '2017-2019, ARM CE-OSS'
+author = 'ARM CE-OSS'
+title = 'TF-M user Guide'
+
+# The short X.Y version
+version = '@SPHINXCFG_TFM_VERSION@'
+# The full version, including alpha/beta/rc tags
+release = '@SPHINXCFG_TFM_VERSION_FULL@'
+
+
+# -- General configuration ---------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
+
+# 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.imgmath',
+    'm2r',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+source_suffix = ['.rst', '.md']
+
+# 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'
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself.  Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
+# html_sidebars = {}
+
+#Disable adding conf.py copyright notice to HTML output
+html_show_copyright = False
+
+# -- Options for HTMLHelp output ---------------------------------------------
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'TF-M doc'
+
+
+# -- Options for LaTeX output ------------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    #
+    # 'papersize': 'letterpaper',
+
+    # The font size ('10pt', '11pt' or '12pt').
+    #
+    # 'pointsize': '10pt',
+
+    # Additional stuff for the LaTeX preamble.
+    #
+    # 'preamble': '',
+
+    # Latex figure (float) alignment
+    #
+    # 'figure_align': 'htbp',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
+latex_documents = [
+    (master_doc, 'TF-M.tex', title,
+     author, 'manual'),
+]
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+#man_pages = [
+#    (master_doc, 'tf-m', title,
+#     [author], 7)
+#]
+
+
+# -- Options for Texinfo output ----------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+#texinfo_documents = [
+#    (master_doc, 'TF-M', title,
+#     author, 'TF-M', 'Trusted Firmware for Cortex-M',
+#     'Miscellaneous'),
+#]
+
+
+# -- Extension configuration -------------------------------------------------
diff --git a/docs/index.rst b/docs/index.rst
new file mode 100644
index 0000000..f88134a
--- /dev/null
+++ b/docs/index.rst
@@ -0,0 +1,81 @@
+:Page authors: Gyorgy Szing <gyorgy.szing@arm.com>
+
+..
+   The build-system will copy all documents into a temporary directory tree
+   before the documentation is built.
+   This fill will be copied to the top level and thus please use relative paths
+   as if this file would be in <TFM_ROOT_DIR>.
+
+Welcome to TF-M's documentation!
+================================
+
+.. toctree::
+    :maxdepth: 2
+    :glob:
+    :hidden:
+    
+    contributing.md
+    glossary.md
+    maintainers.md
+    docs/user_guides/tfm_sw_requirement.md
+    docs/user_guides/tfm_build_instruction.md
+    docs/coding_guide.md
+    docs/user_guides/tfm_user_guide.md
+    docs/user_guides/os_migration_guide_armv8m.md
+    docs/user_guides/tfm_integration_guide.md
+    docs/user_guides/tfm_ns_client_identification.md
+    docs/user_guides/tfm_secure_boot.md
+    
+.. toctree::
+    :maxdepth: 2
+    :caption: Secure services
+    :glob:
+    :hidden:
+    
+    docs/user_guides/services/*
+    
+.. toctree::
+    :maxdepth: 2
+    :caption: Components
+    :glob:
+    :hidden:
+    
+    lib/**
+    
+.. toctree::
+    :maxdepth: 2
+    :caption: Target platforms
+    :glob:
+    :hidden:
+    
+    platform/**
+    
+.. toctree::
+    :caption: Design documents
+    :maxdepth: 2
+    :glob:
+    :hidden:
+    
+    docs/design_documents/*
+    
+.. toctree::
+    :caption: Draft design documents
+    :maxdepth: 2
+    :glob:
+    :hidden:
+    
+    docs/design_documents/drafts/*
+    
+.. toctree::
+    :caption: Rejected design documents
+    :maxdepth: 2
+    :glob:
+    :hidden:
+    
+    docs/design_documents/rejected/*
+
+.. mdinclude:: readme.md
+
+-----------
+
+:Copyright: Copyright (c) 2019, Arm Limited. All rights reserved.
diff --git a/docs/user_guides/tfm_build_instruction.md b/docs/user_guides/tfm_build_instruction.md
index 3e2d5f5..368557a 100644
--- a/docs/user_guides/tfm_build_instruction.md
+++ b/docs/user_guides/tfm_build_instruction.md
@@ -155,7 +155,27 @@
 
 The documentation files will be available under the directory:
 ~~~
-<cmake_doc>/install/doc/reference_manual
+cmake_doc/install/doc/reference_manual
+~~~
+
+## Building the User Guide
+Please ensure the dependencies for building the firmware and the documentation
+are installed as explained in the [software requirements](tfm_sw_requirement.md).
+
+*Note* For building the documentation all tools needed to build the firmware
+must be available.
+
+~~~
+cd <TF-M base folder>
+mkdir cmake_doc
+cd cmake_doc
+cmake ../ -G"Unix Makefiles" -DTARGET_PLATFORM=AN521 -DCOMPILER=ARMCLANG
+cmake --build ./ -- install_userguide
+~~~
+
+The documentation files will be available under the directory:
+~~~
+cmake_doc/install/doc/user_guide
 ~~~
 
 --------------
diff --git a/docs/user_guides/tfm_sw_requirement.md b/docs/user_guides/tfm_sw_requirement.md
index 8380ca6..d474770 100644
--- a/docs/user_guides/tfm_sw_requirement.md
+++ b/docs/user_guides/tfm_sw_requirement.md
@@ -73,11 +73,11 @@
 CMake generators other than "Unix Makefiles" may work, but are not officially
 supported.
 
-# Example setups
+## Example setups
 This section lists dependencies and some exact and tested steps to set-up a
 TF-M-m build environment under various OSes.
 
-## Ubuntu
+### Ubuntu
 - DS-5 v5.27.1.
 - Git tools v2.10.0
 - CMake (see the "Supported CMake versions" chapter)
@@ -90,7 +90,7 @@
   - sudo apt-get install python3-crypto python3-pyasn1 python3-yaml python3-jinja2
 - SRecord v1.58 (for Musca test chip boards)
 
-### Setup a shell to enable compiler toolchain and CMake after installation.
+#### Setup a shell to enable compiler toolchain and CMake after installation.
 
 To import Arm Compiler v6.7.1 in your bash shell console:
 
@@ -113,7 +113,7 @@
 export PATH=<GNU_ARM_PATH>/bin:$PATH
 ~~~
 
-## Windows + Cygwin
+### Windows + Cygwin
 - uVision v5.24.1 or DS-5 v5.27.1 (DS-5 Ultimate Edition) which provides the
   Arm Compiler v6.7.1 compiler or GNU Arm compiler v6.3.1.
 - Git client latest version (https://git-scm.com/download/win)
@@ -129,7 +129,7 @@
 - Python3 pip
 - [SRecord v1.63](https://sourceforge.net/projects/srecord/) (for Musca test chip boards)
 
-### Setup Cygwin to enable a compiler toolchain and CMake after installation.
+#### Setup Cygwin to enable a compiler toolchain and CMake after installation.
 
 If applicable, import Arm Compiler v6.7.1 in your shell console. To make this
 change permanent, add the command line into ~/.bashrc
@@ -179,7 +179,17 @@
 export PATH=/cygdrive/c/<CMAKE_PATH>/bin:$PATH
 ~~~
 
-## To compile the TF-M Reference Manual
+### Building documentation
+The build system is prepared to support generation of two documents. The
+Reference Manual which is Doxygen based, and the User Guide which is Sphinx
+based.
+Both document can be generated in HTML and PDF format.
+
+*Note* support for document generation in the build environment is not
+mandatory. Missing document generation tools will not block building the TF-M
+firmware.
+
+#### To compile the TF-M Reference Manual
 The following additional tools are needed:
 - Doxygen v1.8.0 or later
 - Graphviz dot v2.38.0 or later
@@ -190,20 +200,16 @@
 - LaTeX
 - PdfLaTeX
 
-*Note* support for document generation in the build environment is not
-mandatory. Missing document generation tools will not block building the TF-M
-firmware.
+##### Set-up the needed tools
 
-###Set-up the needed tools
-
-#### Linux
+###### Linux
 - sudo apt-get install -y doxygen graphviz default-jre
 - mkdir ~/plantuml; curl -L http://sourceforge.net/projects/plantuml/files/plantuml.jar/download --output ~/plantuml/plantuml.jar
 
 For PDF generation:
 - sudo apt-get install -y doxygen-latex
 
-#### Windows
+###### Windows
 - [Doxygen 1.8.8](https://sourceforge.net/projects/doxygen/files/snapshots/doxygen-1.8-svn/windows/doxygenw20140924_1_8_8.zip/download)
 - [Graphviz 2.38](https://graphviz.gitlab.io/_pages/Download/windows/graphviz-2.38.msi)
 - The Java runtime is part of the DS5 installation or can be
@@ -217,14 +223,71 @@
 installing missing LaTeX components. Please allow the MikTeX package manager to
 set-up these.
 
-### Configure the shell
+###### Configure the shell
 
-#### Linux
+####### Linux
 ~~~
 export PLANTUML_JAR_PATH="~/plantuml/plantuml.jar"
 ~~~
 
-#### Windows + Cygwin
+####### Windows + Cygwin
+Assumptions for the settings below:
+- plantuml.jar is available at c:\plantuml\plantuml.jar
+- doxygen, dot, and MikTeX binaries are available on the PATH.
+
+~~~
+export PLANTUML_JAR_PATH="c:/plantuml/plantuml.jar"
+export PATH=$PATH:/cygdrive/c/<DS-5 path>/sw/java/bin
+~~~
+
+#### To compile the TF-M User Guide
+The following additional tools are needed:
+- Python3 and the following modules:
+    - Sphinx v1.7.9
+    - m2r v0.2.0
+- Graphviz dot v2.38.0 or later
+- PlantUML v1.2018.11 or later
+- Java runtime environment 1.8 or later (for running PlantUML)
+
+For PDF generation the following tools are needed in addition to the above list:
+- LaTeX
+- PdfLaTeX
+
+##### Set-up the needed tools
+
+###### Linux
+- sudo apt-get install -y python3 graphviz default-jre
+- pip --user install m2r Sphinx sphinx-rtd-theme
+- mkdir ~/plantuml; curl -L http://sourceforge.net/projects/plantuml/files/plantuml.jar/download --output ~/plantuml/plantuml.jar
+
+For PDF generation:
+- sudo apt-get install -y doxygen-latex
+
+###### Windows
+- Python3 [(native Windows version)](https://www.python.org/downloads/)
+- pip --user install m2r Sphinx sphinx-rtd-theme
+- [Graphviz 2.38](https://graphviz.gitlab.io/_pages/Download/windows/graphviz-2.38.msi)
+- The Java runtime is part of the DS5 installation or can be
+  [downloaded from here](https://www.java.com/en/download/)
+- [PlantUML](http://sourceforge.net/projects/plantuml/files/plantuml.jar/download)
+
+For PDF generation:
+- [MikTeX](https://miktex.org/download)
+
+*Note* When building the documentation the first time, MikTeX might prompt for
+installing missing LaTeX components. Please allow the MikTeX package manager to
+set-up these.
+
+##### Configure the shell
+
+###### Linux
+
+~~~
+export PLANTUML_JAR_PATH="~/plantuml/plantuml.jar"
+~~~
+
+###### Windows + Cygwin
+
 Assumptions for the settings below:
 - plantuml.jar is available at c:\plantuml\plantuml.jar
 - doxygen, dot, and MikTeX binaries are available on the PATH.
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 3199204..61a33d7 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -15,6 +15,7 @@
 
 #Include functionality to enable building the documentation.
 include("Common/BuildDoxygenDoc")
+include("Common/BuildSphinxDoc")
 
 #Start an embedded project.
 embedded_project_start(CONFIG "${CMAKE_CURRENT_LIST_DIR}/../ConfigDefault.cmake")