Add ftpm SP deplyoment

Create a new deployment which implemets an fTPM using TPM CRB over FF-A
frontend and ms-tpm-20-ref TPM implementation using MbedTLS crypto
backend. The functionality is currently limited, locality handling is
partially implemented, Locality 4 is not supported.

Signed-off-by: Balint Dobszay <balint.dobszay@arm.com>
Change-Id: I09769cfe84190736cce1a261d7fb6de62b2b0d09
diff --git a/deployments/ftpm/config/default-opteesp/CMakeLists.txt b/deployments/ftpm/config/default-opteesp/CMakeLists.txt
new file mode 100644
index 0000000..9043c13
--- /dev/null
+++ b/deployments/ftpm/config/default-opteesp/CMakeLists.txt
@@ -0,0 +1,95 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+
+# Set default platform.
+set(TS_PLATFORM "arm/fvp/fvp_base_revc-2xaemv8a" CACHE STRING "Target platform location.")
+
+# Set default build type to MinSizWithDebInfo to avoid running ouf of secure memory on low resource
+# IoT platforms.
+if (NOT DEFINED CMAKE_BUILD_TYPE)
+	set(CMAKE_BUILD_TYPE "MinSizWithDebInfo" CACHE STRING "Build type.")
+endif()
+
+include(../../../deployment.cmake REQUIRED)
+
+include(${TS_ROOT}/environments/opteesp/env.cmake)
+project(trusted-services LANGUAGES C ASM)
+add_executable(ftpm)
+target_include_directories(ftpm PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+set(SP_BIN_UUID_CANON "17b862a4-1806-4faf-86b3-089a58353861")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
+set(SP_HEAP_SIZE "128 * 1024" CACHE STRING "SP heap size in bytes")
+set(SP_BOOT_ORDER "10" CACHE STRING "Boot order of the SP")
+set(TRACE_PREFIX "FTPM" CACHE STRING "Trace prefix")
+
+set(TPM_CRB_NS_ADDRESS "0x84000000" CACHE STRING "Address of non-secure TPM CRB")
+set(TPM_CRB_NS_PAGE_COUNT "4" CACHE STRING "Size of non-secure TPM CRB in 4k pages")
+set(TPM_CRB_S_ADDRESS "0x07900000" CACHE STRING "Address of secure TPM CRB")
+set(TPM_CRB_S_PAGE_COUNT "1" CACHE STRING "Size of secure TPM CRB in 4k pages")
+
+# Convert to format used in the SP manifest DT
+uint64_split(VALUE ${TPM_CRB_NS_ADDRESS} OUT_PREFIX CRB_NS_ADDR)
+uint64_split(VALUE ${TPM_CRB_S_ADDRESS} OUT_PREFIX CRB_S_ADDR)
+
+target_include_directories(ftpm PRIVATE
+	${CMAKE_CURRENT_LIST_DIR}
+)
+
+#-------------------------------------------------------------------------------
+#  Set target platform to provide drivers needed by the deployment
+#
+#-------------------------------------------------------------------------------
+add_platform(TARGET "ftpm")
+
+add_components(TARGET "ftpm"
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS environments/opteesp
+)
+
+include(../../env/commonsp/ftpm_sp.cmake REQUIRED)
+include(../../ftpm.cmake REQUIRED)
+include(../../infra/ms_tpm_backend.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+#  Deployment specific build options
+#
+#-------------------------------------------------------------------------------
+target_compile_definitions(ftpm PRIVATE
+	ARM64=1
+	TPM_CRB_NS_PA=${TPM_CRB_NS_ADDRESS}
+	TPM_CRB_S_PA=${TPM_CRB_S_ADDRESS}
+)
+
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+	target_compile_options(ftpm PRIVATE
+		-std=c99
+	)
+endif()
+
+#-------------------------------------------------------------------------------
+#  Deployment specific install options
+#
+#-------------------------------------------------------------------------------
+if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
+endif()
+install(TARGETS ftpm
+	PUBLIC_HEADER DESTINATION ${TS_ENV}/include
+	RUNTIME DESTINATION ${TS_ENV}/bin
+)
+
+include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake)
+export_sp(
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
+	SP_BOOT_ORDER ${SP_BOOT_ORDER}
+	SP_NAME "ftpm"
+	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_ftpm.dts.in
+	JSON_IN ${TS_ROOT}/environments/opteesp/sp_pkg.json.in
+)
diff --git a/deployments/ftpm/config/default-opteesp/default_ftpm.dts.in b/deployments/ftpm/config/default-opteesp/default_ftpm.dts.in
new file mode 100644
index 0000000..15b32ed
--- /dev/null
+++ b/deployments/ftpm/config/default-opteesp/default_ftpm.dts.in
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+@DTS_TAG@
+
+@DTS_NODE@ {
+	compatible = "arm,ffa-manifest-1.0";
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <@EXPORT_SP_UUID_DT@>;
+	description = "fTPM SP";
+	execution-ctx-count = <1>;
+	exception-level = <1>; /* S-EL0 */
+	execution-state = <0>; /* AArch64 */
+	xlat-granule = <0>; /* 4KiB */
+	boot-order = /bits/ 16 <@EXPORT_SP_BOOT_ORDER@>;
+	messaging-method = <3>; /* Direct messaging only */
+	ns-interrupts-action = <2>; /* Non-secure interrupts are signaled */
+	elf-format = <1>;
+
+	device-regions {
+		compatible = "arm,ffa-manifest-device-regions";
+
+		tpm-crb-ns {
+			base-address = <@CRB_NS_ADDR_HI@ @CRB_NS_ADDR_LO@>;
+			pages-count = <@TPM_CRB_NS_PAGE_COUNT@>;
+			attributes = <0xb>; /* ns access-read-write */
+		};
+
+		tpm-crb-s {
+			base-address = <@CRB_S_ADDR_HI@ @CRB_S_ADDR_LO@>;
+			pages-count = <@TPM_CRB_S_PAGE_COUNT@>;
+			attributes = <0x3>; /* read-write */
+		};
+
+		trng {
+			/* Armv8-A Base Platform values */
+			base-address = <0x00000000 0x7fe60000>;
+			pages-count = <1>;
+			attributes = <0x3>; /* read-write */
+		};
+	};
+};
diff --git a/deployments/ftpm/config/default-opteesp/optee_sp_user_defines.h b/deployments/ftpm/config/default-opteesp/optee_sp_user_defines.h
new file mode 100644
index 0000000..e50aae4
--- /dev/null
+++ b/deployments/ftpm/config/default-opteesp/optee_sp_user_defines.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef OPTEE_SP_USER_DEFINES_H
+#define OPTEE_SP_USER_DEFINES_H
+
+#define OPTEE_SP_FLAGS		0
+#define OPTEE_SP_STACK_SIZE	(64 * 1024)
+
+#endif /* SP_HEADER_DEFINES_H */
diff --git a/deployments/ftpm/config/default-sp/CMakeLists.txt b/deployments/ftpm/config/default-sp/CMakeLists.txt
new file mode 100644
index 0000000..b34e36c
--- /dev/null
+++ b/deployments/ftpm/config/default-sp/CMakeLists.txt
@@ -0,0 +1,102 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+
+# Set default platform.
+set(TS_PLATFORM "arm/fvp/fvp_base_revc-2xaemv8a" CACHE STRING "Target platform location.")
+
+# Set default build type to MinSizWithDebInfo to avoid running ouf of secure memory on low resource
+# IoT platforms.
+if (NOT DEFINED CMAKE_BUILD_TYPE)
+	set(CMAKE_BUILD_TYPE "MinSizWithDebInfo" CACHE STRING "Build type.")
+endif()
+
+include(../../../deployment.cmake REQUIRED)
+
+include(${TS_ROOT}/environments/sp/env.cmake)
+set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type")
+project(trusted-services LANGUAGES C ASM)
+add_executable(ftpm)
+target_include_directories(ftpm PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+set(SP_NAME "ftpm")
+set(SP_BIN_UUID_CANON "17b862a4-1806-4faf-86b3-089a58353861")
+set(SP_FFA_UUID_CANON "${SP_BIN_UUID_CANON}")
+set(SP_STACK_SIZE "64 * 1024" CACHE STRING "Stack size")
+set(SP_HEAP_SIZE "128 * 1024" CACHE STRING "Heap size")
+set(SP_BOOT_ORDER "10" CACHE STRING "Boot order of the SP")
+set(TRACE_PREFIX "FTPM" CACHE STRING "Trace prefix")
+
+set(TPM_CRB_NS_ADDRESS "0x84000000" CACHE STRING "Address of non-secure TPM CRB")
+set(TPM_CRB_NS_PAGE_COUNT "4" CACHE STRING "Size of non-secure TPM CRB in 4k pages")
+set(TPM_CRB_S_ADDRESS "0x07900000" CACHE STRING "Address of secure TPM CRB")
+set(TPM_CRB_S_PAGE_COUNT "1" CACHE STRING "Size of secure TPM CRB in 4k pages")
+
+# Convert to format used in the SP manifest DT
+uint64_split(VALUE ${TPM_CRB_NS_ADDRESS} OUT_PREFIX CRB_NS_ADDR)
+uint64_split(VALUE ${TPM_CRB_S_ADDRESS} OUT_PREFIX CRB_S_ADDR)
+
+#-------------------------------------------------------------------------------
+#  Set target platform to provide drivers needed by the deployment
+#
+#-------------------------------------------------------------------------------
+add_platform(TARGET "ftpm")
+
+add_components(TARGET "ftpm"
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS environments/sp
+)
+
+include(../../env/commonsp/ftpm_sp.cmake REQUIRED)
+include(../../ftpm.cmake REQUIRED)
+include(../../infra/ms_tpm_backend.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+#  Deployment specific build options
+#
+#-------------------------------------------------------------------------------
+target_compile_definitions(ftpm PRIVATE
+	ARM64=1
+	TPM_CRB_NS_PA=${TPM_CRB_NS_ADDRESS}
+	TPM_CRB_S_PA=${TPM_CRB_S_ADDRESS}
+)
+
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
+	target_compile_options(ftpm PRIVATE
+		-std=c99
+	)
+
+endif()
+
+compiler_generate_binary_output(TARGET ftpm NAME "${SP_BIN_UUID_CANON}.bin" SP_BINARY)
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${SP_BIN_UUID_CANON}.bin DESTINATION ${TS_ENV}/bin)
+
+include(${TS_ROOT}/tools/cmake/common/ExportMemoryRegionsToManifest.cmake REQUIRED)
+export_memory_regions_to_manifest(TARGET ftpm NAME "${SP_BIN_UUID_CANON}_memory_regions.dtsi" RES EXPORT_MEMORY_REGIONS_DTSI)
+
+#-------------------------------------------------------------------------------
+#  Deployment specific install options
+#
+#-------------------------------------------------------------------------------
+if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
+	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
+endif()
+install(TARGETS ftpm
+	PUBLIC_HEADER DESTINATION ${TS_ENV}/include
+	RUNTIME DESTINATION ${TS_ENV}/bin
+)
+
+include(${TS_ROOT}/tools/cmake/common/ExportSp.cmake REQUIRED)
+export_sp(
+	SP_FFA_UUID_CANON ${SP_FFA_UUID_CANON}
+	SP_BIN_UUID_CANON ${SP_BIN_UUID_CANON}
+	SP_BOOT_ORDER ${SP_BOOT_ORDER}
+	SP_NAME ${SP_NAME}
+	DTS_IN ${CMAKE_CURRENT_LIST_DIR}/default_${SP_NAME}.dts.in
+	DTS_MEM_REGIONS ${SP_BIN_UUID_CANON}_memory_regions.dtsi
+	JSON_IN ${TS_ROOT}/environments/sp/sp_pkg.json.in
+)
diff --git a/deployments/ftpm/config/default-sp/default_ftpm.dts.in b/deployments/ftpm/config/default-sp/default_ftpm.dts.in
new file mode 100644
index 0000000..b0a6237
--- /dev/null
+++ b/deployments/ftpm/config/default-sp/default_ftpm.dts.in
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+@DTS_TAG@
+
+@DTS_NODE@ {
+	compatible = "arm,ffa-manifest-1.0";
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <@EXPORT_SP_UUID_DT@>;
+	description = "fTPM SP";
+	execution-ctx-count = <1>;
+	exception-level = <1>; /* S-EL0 */
+	execution-state = <0>; /* AArch64 */
+	xlat-granule = <0>; /* 4KiB */
+	boot-order = /bits/ 16 <@EXPORT_SP_BOOT_ORDER@>;
+	messaging-method = <3>; /* Direct messaging only */
+	ns-interrupts-action = <2>; /* Non-secure interrupts are signaled */
+
+	memory-regions {
+		compatible = "arm,ffa-manifest-memory-regions";
+
+		#include "@EXPORT_DTS_MEM_REGIONS@"
+	};
+
+	device-regions {
+		compatible = "arm,ffa-manifest-device-regions";
+
+		tpm-crb-ns {
+			base-address = <@CRB_NS_ADDR_HI@ @CRB_NS_ADDR_LO@>;
+			pages-count = <@TPM_CRB_NS_PAGE_COUNT@>;
+			attributes = <0xb>; /* ns access-read-write */
+		};
+
+		tpm-crb-s {
+			base-address = <@CRB_S_ADDR_HI@ @CRB_S_ADDR_LO@>;
+			pages-count = <@TPM_CRB_S_PAGE_COUNT@>;
+			attributes = <0x3>; /* read-write */
+		};
+
+		trng {
+			/* Armv8-A Base Platform values */
+			base-address = <0x00000000 0x7fe60000>;
+			pages-count = <1>;
+			attributes = <0x3>; /* read-write */
+		};
+	};
+};
diff --git a/deployments/ftpm/env/commonsp/ftpm_sp.c b/deployments/ftpm/env/commonsp/ftpm_sp.c
new file mode 100644
index 0000000..a8cf25e
--- /dev/null
+++ b/deployments/ftpm/env/commonsp/ftpm_sp.c
@@ -0,0 +1,183 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include "common/trace/include/trace.h"
+#include "config/ramstore/config_ramstore.h"
+#include "config/interface/config_store.h"
+#include "config/loader/sp/sp_config_loader.h"
+#include "platform/interface/device_region.h"
+#include "rpc/common/endpoint/rpc_service_interface.h"
+#include "rpc/tpm_crb_ffa/endpoint/sp/tpm_crb_ffa_endpoint.h"
+#include "service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h"
+#include "service/log/factory/log_factory.h"
+#include "service/secure_storage/factory/storage_factory.h"
+#include "service/secure_storage/frontend/psa/ps/ps_frontend.h"
+#include "service/tpm/backend/ms_tpm/ms_tpm_backend.h"
+#include "service/tpm/provider/tpm_crb_provider.h"
+#include "service_locator.h"
+#include "sp_api.h"
+#include "sp_discovery.h"
+#include "sp_messaging.h"
+#include "sp_rxtx.h"
+
+#include "ftpm_sp.h"
+
+#define CONFIG_NAME_TPM_CRB_NS_REGION "tpm-crb-ns"
+#define CONFIG_NAME_TPM_CRB_S_REGION "tpm-crb-s"
+
+static uint8_t tx_buffer[4096] __aligned(4096);
+static uint8_t rx_buffer[4096] __aligned(4096);
+
+void __noreturn sp_main(union ffa_boot_info *boot_info)
+{
+	struct tpm_crb_provider service_provider = { 0 };
+	struct device_region tpm_crb_ns_region = { 0 };
+	struct device_region tpm_crb_s_region = { 0 };
+	struct tpm_crb_ffa_ep rpc_endpoint = { 0 };
+	struct rpc_service_interface *service_iface = NULL;
+	struct storage_backend *storage_backend = NULL;
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
+	struct sp_msg resp_msg = { 0 };
+	struct sp_msg req_msg = { 0 };
+	uint16_t own_id = 0;
+
+	/* Boot phase */
+	sp_res = sp_rxtx_buffer_map(tx_buffer, rx_buffer, sizeof(rx_buffer));
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("Failed to map RXTX buffers: %d", sp_res);
+		goto fatal_error;
+	}
+
+	IMSG("Start discovering logging service");
+	if (log_factory_create()) {
+		IMSG("Logging service discovery successful");
+	} else {
+		EMSG("Logging service discovery failed, falling back to console log");
+	}
+
+	sp_res = sp_discovery_own_id_get(&own_id);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("Failed to query own ID: %d", sp_res);
+		goto fatal_error;
+	}
+
+	config_ramstore_init();
+
+	if (!sp_config_load(boot_info)) {
+		EMSG("Failed to load SP config");
+		goto fatal_error;
+	}
+
+	if (!config_store_query(CONFIG_CLASSIFIER_DEVICE_REGION, CONFIG_NAME_TPM_CRB_NS_REGION, 0,
+				&tpm_crb_ns_region, sizeof(tpm_crb_ns_region))) {
+		EMSG(CONFIG_NAME_TPM_CRB_NS_REGION " is not set in SP configuration");
+		goto fatal_error;
+	}
+
+	DMSG("Found TPM CRB NS careveout with address: 0x%lx, size: %ld",
+		tpm_crb_ns_region.base_addr, tpm_crb_ns_region.io_region_size);
+
+	if (!config_store_query(CONFIG_CLASSIFIER_DEVICE_REGION, CONFIG_NAME_TPM_CRB_S_REGION, 0,
+				&tpm_crb_s_region, sizeof(tpm_crb_s_region))) {
+		EMSG(CONFIG_NAME_TPM_CRB_S_REGION " is not set in SP configuration");
+		goto fatal_error;
+	}
+
+	DMSG("Found TPM CRB S careveout with address: 0x%lx, size: %ld",
+		tpm_crb_s_region.base_addr, tpm_crb_s_region.io_region_size);
+
+	/* Create a storage backend for persistent key storage - prefer PS */
+	storage_backend = storage_factory_create(storage_factory_security_class_PROTECTED);
+	if (!storage_backend) {
+		EMSG("Failed to create storage factory");
+		goto fatal_error;
+	}
+
+	status = psa_ps_frontend_init(storage_backend);
+	if (status != PSA_SUCCESS) {
+		EMSG("Failed to init protected storage frontend: %d", status);
+		goto fatal_error;
+	}
+
+	/* Initialize TRNG */
+	status = trng_adapter_init(0);
+	if (status != PSA_SUCCESS) {
+		EMSG("Failed to init TRNG adapter: %d", status);
+		goto fatal_error;
+	}
+
+	if (!ms_tpm_backend_init()) {
+		EMSG("ms_tpm backend init failed");
+		goto fatal_error;
+	}
+
+	service_iface = tpm_provider_init(&service_provider,
+					  (uint8_t *)tpm_crb_ns_region.base_addr,
+					  tpm_crb_ns_region.io_region_size,
+					  (uint8_t *)tpm_crb_s_region.base_addr,
+					  tpm_crb_s_region.io_region_size);
+	if (!service_iface) {
+		EMSG("Failed to init service provider");
+		goto fatal_error;
+	}
+
+	if (!tpm_crb_ffa_endpoint_init(&rpc_endpoint)) {
+		EMSG("Failed to initialize RPC endpoint");
+		goto fatal_error;
+	}
+
+	if (!tpm_crb_ffa_endpoint_add_service(&rpc_endpoint, service_iface)) {
+		EMSG("Failed to add service to RPC endpoint");
+		goto fatal_error;
+	}
+
+	/* End of boot phase */
+
+	sp_res = sp_msg_wait(&req_msg);
+	if (sp_res != SP_RESULT_OK) {
+		EMSG("Failed to send message wait %d", sp_res);
+		goto fatal_error;
+	}
+
+	while (1) {
+		tpm_crb_ffa_endpoint_receive(&rpc_endpoint, &req_msg, &resp_msg);
+
+		sp_res = sp_msg_send_direct_resp(&resp_msg, &req_msg);
+		if (sp_res != SP_RESULT_OK) {
+			EMSG("Failed to send direct response %d", sp_res);
+			sp_res = sp_msg_wait(&req_msg);
+			if (sp_res != SP_RESULT_OK) {
+				EMSG("Failed to send message wait %d", sp_res);
+				goto fatal_error;
+			}
+		}
+	}
+
+fatal_error:
+	EMSG("fTPM SP error");
+	while (1) {}
+}
+
+void sp_interrupt_handler(uint32_t interrupt_id)
+{
+	(void)interrupt_id;
+}
+
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
diff --git a/deployments/ftpm/env/commonsp/ftpm_sp.cmake b/deployments/ftpm/env/commonsp/ftpm_sp.cmake
new file mode 100644
index 0000000..6c14cb2
--- /dev/null
+++ b/deployments/ftpm/env/commonsp/ftpm_sp.cmake
@@ -0,0 +1,29 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+set(FFA_DIRECT_MSG_ROUTING_EXTENSION OFF CACHE BOOL "Enable FF-A direct message routing extension")
+
+add_components(TARGET "ftpm"
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/common/fdt"
+		"components/common/trace"
+		"components/common/utils"
+		"components/common/uuid"
+		"components/config/ramstore"
+		"components/config/loader/sp"
+		"components/messaging/ffa/libsp"
+		"components/rpc/common/endpoint"
+		"components/rpc/tpm_crb_ffa/common"
+		"components/rpc/tpm_crb_ffa/endpoint/sp"
+		"components/service/log/factory"
+		"components/service/log/client"
+)
+
+target_sources(ftpm PRIVATE
+	${CMAKE_CURRENT_LIST_DIR}/ftpm_sp.c
+)
diff --git a/deployments/ftpm/env/commonsp/ftpm_sp.h b/deployments/ftpm/env/commonsp/ftpm_sp.h
new file mode 100644
index 0000000..22043c9
--- /dev/null
+++ b/deployments/ftpm/env/commonsp/ftpm_sp.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef FTPM_SP_H
+#define FTPM_SP_H
+
+#endif /* FTPM_SP_H */
diff --git a/deployments/ftpm/ftpm.cmake b/deployments/ftpm/ftpm.cmake
new file mode 100644
index 0000000..c64a251
--- /dev/null
+++ b/deployments/ftpm/ftpm.cmake
@@ -0,0 +1,16 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+add_components(TARGET ftpm
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/rpc/common/interface"
+		"components/rpc/common/endpoint"
+		"components/service/common/include"
+		"components/service/common/provider"
+		"components/service/tpm/provider"
+)
diff --git a/deployments/ftpm/infra/ms_tpm_backend.cmake b/deployments/ftpm/infra/ms_tpm_backend.cmake
new file mode 100644
index 0000000..b1b1073
--- /dev/null
+++ b/deployments/ftpm/infra/ms_tpm_backend.cmake
@@ -0,0 +1,35 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+add_components(TARGET "ftpm"
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/rpc/common/caller"
+		"components/rpc/ts_rpc/common"
+		"components/rpc/ts_rpc/caller/sp"
+		"components/service/common/client"
+		"components/service/crypto/backend/mbedcrypto/trng_adapter/platform"
+		"components/service/locator"
+		"components/service/locator/interface"
+		"components/service/locator/sp"
+		"components/service/locator/sp/ffa"
+		"components/service/secure_storage/include"
+		"components/service/secure_storage/frontend/psa/ps"
+		"components/service/secure_storage/backend/null_store"
+		"components/service/secure_storage/backend/secure_storage_client"
+		"components/service/secure_storage/factory/sp/rot_store"
+		"components/service/tpm/backend/ms_tpm"
+)
+
+#-------------------------------------------------------------------------------
+#  This infrastructure depends on platform specific drivers
+#
+#-------------------------------------------------------------------------------
+add_platform(TARGET "ftpm")
+
+include(${TS_ROOT}/external/ms_tpm/ms_tpm.cmake)
+target_link_libraries(ftpm PRIVATE ms_tpm::tpm)
diff --git a/tools/b-test/test_data.yaml b/tools/b-test/test_data.yaml
index c70961e..6396a7a 100644
--- a/tools/b-test/test_data.yaml
+++ b/tools/b-test/test_data.yaml
@@ -74,6 +74,14 @@
       src: "$TS_ROOT/deployments/env-test/config/n1sdp-opteesp"
       params:
             - "-GUnix Makefiles"
+    - name: "ftpm-default-opteesp"
+      src: "$TS_ROOT/deployments/ftpm/config/default-opteesp"
+      params:
+            - "-GUnix Makefiles"
+    - name: "ftpm-default-sp"
+      src: "$TS_ROOT/deployments/ftpm/config/default-sp"
+      params:
+            - "-GUnix Makefiles"
     - name: "fwu-tool-linux-pc"
       src: "$TS_ROOT/deployments/fwu-tool/linux-pc"
       os_id : "GNU/Linux"