aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImre Kis <imre.kis@arm.com>2020-11-23 03:15:45 +0100
committerGyorgy Szing <Gyorgy.Szing@arm.com>2020-11-25 15:56:04 +0100
commit9fcf8413d8ff419dbf9a60f9764daf8289bcc44e (patch)
tree1a919946310da5eafc411cc2e6e8c440c3c2d1d6
parent3b32e7ba9791eef6575a688dd8bed95c76eed6c5 (diff)
downloadtrusted-services-9fcf8413d8ff419dbf9a60f9764daf8289bcc44e.tar.gz
libsp: Introduce FF-A support.
libsp is intended to provide a common set of features for SEL-0 secure partitions. This includes the FF-A ABI and higher level functions. In this commit the minimal set of FF-A calls is implemented to provide compliance. Signed-off-by: Imre Kis <imre.kis@arm.com> Change-Id: I5420a11a7dc75b228d0d0d58059dea86e5f927ee
-rw-r--r--components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S27
-rw-r--r--components/messaging/ffa/libsp/component.cmake32
-rw-r--r--components/messaging/ffa/libsp/ffa.c278
-rw-r--r--components/messaging/ffa/libsp/ffa_interrupt_handler.c13
-rw-r--r--components/messaging/ffa/libsp/include/ffa_api.h174
-rw-r--r--components/messaging/ffa/libsp/include/ffa_api_defines.h123
-rw-r--r--components/messaging/ffa/libsp/include/ffa_api_types.h86
-rw-r--r--components/messaging/ffa/libsp/include/ffa_internal_api.h53
-rw-r--r--components/messaging/ffa/libsp/include/sp_api.h33
-rw-r--r--components/messaging/ffa/libsp/include/sp_api_defines.h25
-rw-r--r--components/messaging/ffa/libsp/include/sp_api_types.h16
11 files changed, 860 insertions, 0 deletions
diff --git a/components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S b/components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S
new file mode 100644
index 000000000..6ffeb0bff
--- /dev/null
+++ b/components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include <asm.S>
+
+ .section .text
+
+ /*
+ * The C function prototype is defined in ffa_internal_api.h
+ *
+ * void ffa_svc(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3,
+ * uint64_t a4, uint64_t a5, uint64_t a6, uint64_t a7,
+ * struct ffa_params *result);
+ */
+
+ FUNC ffa_svc , :
+ svc #0
+ /* Store ERET args to struct ffa_params ptr */
+ ldr x8, [sp]
+ stp x0, x1, [x8, #0]
+ stp x2, x3, [x8, #16]
+ stp x4, x5, [x8, #32]
+ stp x6, x7, [x8, #48]
+ ret
+ END_FUNC ffa_svc
diff --git a/components/messaging/ffa/libsp/component.cmake b/components/messaging/ffa/libsp/component.cmake
new file mode 100644
index 000000000..c20f8999b
--- /dev/null
+++ b/components/messaging/ffa/libsp/component.cmake
@@ -0,0 +1,32 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+ message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+ "${CMAKE_CURRENT_LIST_DIR}/aarch64/ffa_syscalls_a64.S"
+ "${CMAKE_CURRENT_LIST_DIR}/ffa.c"
+ "${CMAKE_CURRENT_LIST_DIR}/ffa_interrupt_handler.c"
+ )
+
+set_property(TARGET ${TGT} PROPERTY PUBLIC_HEADER
+ ${CMAKE_CURRENT_LIST_DIR}/include/ffa_api_defines.h
+ ${CMAKE_CURRENT_LIST_DIR}/include/ffa_api_types.h
+ ${CMAKE_CURRENT_LIST_DIR}/include/ffa_api.h
+ ${CMAKE_CURRENT_LIST_DIR}/include/ffa_internal_api.h
+ ${CMAKE_CURRENT_LIST_DIR}/include/sp_api_defines.h
+ ${CMAKE_CURRENT_LIST_DIR}/include/sp_api_types.h
+ ${CMAKE_CURRENT_LIST_DIR}/include/sp_api.h
+ )
+
+
+target_include_directories(${TGT}
+ PUBLIC
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
+ "$<INSTALL_INTERFACE:include>"
+ )
diff --git a/components/messaging/ffa/libsp/ffa.c b/components/messaging/ffa/libsp/ffa.c
new file mode 100644
index 000000000..011d94188
--- /dev/null
+++ b/components/messaging/ffa/libsp/ffa.c
@@ -0,0 +1,278 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include <assert.h> // for assert
+#include <stddef.h> // for size_t
+#include <stdint.h> // for uint32_t, uint16_t, uintptr_t, U
+#include "ffa_api.h" // for FFA_OK, ffa_interrupt_handler, ffa_fea...
+#include "ffa_api_defines.h" // for FFA_PARAM_MBZ, FFA_OK, FFA_ERROR, FFA_...
+#include "ffa_api_types.h" // for ffa_result, ffa_direct_msg, ffa_uuid
+#include "ffa_internal_api.h" // for ffa_params, ffa_svc
+#include "util.h" // for GENMASK_32, SHIFT_U32, BIT
+
+/*
+ * Unpacks the error code from the FFA_ERROR message. It is a signed 32 bit
+ * value in an unsigned 64 bit field so proper casting must be used to avoid
+ * compiler dependent behavior.
+ */
+static inline ffa_result ffa_get_errorcode(struct ffa_params *result)
+{
+ uint32_t raw_value = result->a2;
+
+ return *(ffa_result *)(&raw_value);
+}
+
+/*
+ * Unpacks the content of the SVC result into an ffa_direct_msg structure.
+ */
+static inline void ffa_unpack_direct_msg(struct ffa_params *svc_result,
+ struct ffa_direct_msg *msg)
+{
+ msg->function_id = svc_result->a0;
+ msg->source_id = (svc_result->a1 >> 16);
+ msg->destination_id = svc_result->a1;
+ msg->args[0] = svc_result->a3;
+ msg->args[1] = svc_result->a4;
+ msg->args[2] = svc_result->a5;
+ msg->args[3] = svc_result->a6;
+ msg->args[4] = svc_result->a7;
+}
+
+/*
+ * The end of the interrupt handler is indicated by an FFA_MSG_WAIT call.
+ */
+static inline void ffa_return_from_interrupt(struct ffa_params *result)
+{
+ ffa_svc(FFA_MSG_WAIT, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ result);
+}
+
+static inline void ffa_uuid_to_abi_format(const struct ffa_uuid *uuid,
+ uint32_t *result)
+{
+ size_t i = 0;
+
+ for (i = 0; i < 4; i++) {
+ result[i] = uuid->uuid[4 * i];
+ result[i] |= SHIFT_U32(uuid->uuid[4 * i + 1], 8);
+ result[i] |= SHIFT_U32(uuid->uuid[4 * i + 2], 16);
+ result[i] |= SHIFT_U32(uuid->uuid[4 * i + 3], 24);
+ }
+}
+
+ffa_result ffa_version(uint32_t *version)
+{
+ struct ffa_params result = {0};
+ uint32_t self_version = 0;
+
+ self_version = (FFA_VERSION_MAJOR << FFA_VERSION_MAJOR_SHIFT) |
+ (FFA_VERSION_MINOR << FFA_VERSION_MINOR);
+
+ ffa_svc(FFA_VERSION, self_version, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ &result);
+
+ if (result.a0 & BIT(31)) {
+ uint32_t raw_error = result.a0;
+
+ *version = 0;
+
+ return *(ffa_result *)(&raw_error);
+ }
+
+ *version = result.a0;
+ return FFA_OK;
+}
+
+ffa_result ffa_features(uint32_t ffa_function_id,
+ struct ffa_interface_properties *interface_properties)
+{
+ struct ffa_params result = {0};
+
+ ffa_svc(FFA_FEATURES, ffa_function_id, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ &result);
+
+ if (result.a0 == FFA_ERROR) {
+ interface_properties->interface_properties[0] = 0;
+ interface_properties->interface_properties[1] = 0;
+ return ffa_get_errorcode(&result);
+ }
+
+ assert(result.a0 == FFA_SUCCESS_32);
+ interface_properties->interface_properties[0] = result.a2;
+ interface_properties->interface_properties[1] = result.a3;
+ return FFA_OK;
+}
+
+ffa_result ffa_rx_release(void)
+{
+ struct ffa_params result = {0};
+
+ ffa_svc(FFA_RX_RELEASE, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ &result);
+
+ if (result.a0 == FFA_ERROR)
+ return ffa_get_errorcode(&result);
+
+ assert(result.a0 == FFA_SUCCESS_32);
+ return FFA_OK;
+}
+
+ffa_result ffa_rxtx_map(const void *tx_buffer, const void *rx_buffer,
+ uint32_t page_count)
+{
+ struct ffa_params result = {0};
+
+ assert(page_count <= FFA_RXTX_MAP_PAGE_COUNT_MAX);
+
+ page_count = SHIFT_U32(page_count & FFA_RXTX_MAP_PAGE_COUNT_MASK,
+ FFA_RXTX_MAP_PAGE_COUNT_SHIFT);
+
+ ffa_svc(FFA_RXTX_MAP_32, (uintptr_t)tx_buffer, (uintptr_t)rx_buffer,
+ page_count, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, &result);
+
+ if (result.a0 == FFA_ERROR)
+ return ffa_get_errorcode(&result);
+
+ assert(result.a0 == FFA_SUCCESS_32);
+ return FFA_OK;
+}
+
+ffa_result ffa_rxtx_unmap(uint16_t id)
+{
+ struct ffa_params result = {0};
+
+ ffa_svc(FFA_RXTX_UNMAP, SHIFT_U32(id, FFA_RXTX_UNMAP_ID_SHIFT),
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, &result);
+
+ if (result.a0 == FFA_ERROR)
+ return ffa_get_errorcode(&result);
+
+ assert(result.a0 == FFA_SUCCESS_32);
+ return FFA_OK;
+}
+
+ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t *count)
+{
+ struct ffa_params result = {0};
+ uint32_t abi_uuid[4] = {0};
+
+ ffa_uuid_to_abi_format(uuid, abi_uuid);
+
+ ffa_svc(FFA_PARTITION_INFO_GET, abi_uuid[0], abi_uuid[1], abi_uuid[2],
+ abi_uuid[3], FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ &result);
+
+ if (result.a0 == FFA_ERROR) {
+ *count = UINT32_C(0);
+ return ffa_get_errorcode(&result);
+ }
+
+ assert(result.a0 == FFA_SUCCESS_32);
+ *count = result.a2;
+ return FFA_OK;
+}
+
+ffa_result ffa_id_get(uint16_t *id)
+{
+ struct ffa_params result = {0};
+
+ ffa_svc(FFA_ID_GET, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ &result);
+
+ if (result.a0 == FFA_ERROR) {
+ *id = FFA_ID_GET_ID_MASK;
+ return ffa_get_errorcode(&result);
+ }
+
+ assert(result.a0 == FFA_SUCCESS_32);
+ *id = (result.a2 >> FFA_ID_GET_ID_SHIFT) & FFA_ID_GET_ID_MASK;
+ return FFA_OK;
+}
+
+ffa_result ffa_msg_wait(struct ffa_direct_msg *msg)
+{
+ struct ffa_params result = {0};
+
+ ffa_svc(FFA_MSG_WAIT, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+ &result);
+
+ while (result.a0 == FFA_INTERRUPT) {
+ ffa_interrupt_handler(result.a2);
+ ffa_return_from_interrupt(&result);
+ }
+
+ if (result.a0 == FFA_ERROR) {
+ return ffa_get_errorcode(&result);
+ } else if (result.a0 == FFA_MSG_SEND_DIRECT_REQ_32) {
+ ffa_unpack_direct_msg(&result, msg);
+ } else {
+ assert(result.a0 == FFA_SUCCESS_32);
+ *msg = (struct ffa_direct_msg){.function_id = result.a0};
+ }
+
+ return FFA_OK;
+}
+
+ffa_result ffa_msg_send_direct_req(uint16_t source, uint16_t dest, uint32_t a0,
+ uint32_t a1, uint32_t a2, uint32_t a3,
+ uint32_t a4, struct ffa_direct_msg *msg)
+{
+ struct ffa_params result = {0};
+
+ ffa_svc(FFA_MSG_SEND_DIRECT_REQ_32,
+ SHIFT_U32(source, FFA_MSG_SEND_DIRECT_REQ_SOURCE_ID_SHIFT) |
+ dest, FFA_PARAM_MBZ, a0, a1, a2, a3, a4, &result);
+
+ while (result.a0 == FFA_INTERRUPT) {
+ ffa_interrupt_handler(result.a2);
+ ffa_return_from_interrupt(&result);
+ }
+
+ if (result.a0 == FFA_ERROR) {
+ return ffa_get_errorcode(&result);
+ } else if (result.a0 == FFA_MSG_SEND_DIRECT_RESP_32) {
+ ffa_unpack_direct_msg(&result, msg);
+ } else {
+ assert(result.a0 == FFA_SUCCESS_32);
+ *msg = (struct ffa_direct_msg){.function_id = result.a0};
+ }
+
+ return FFA_OK;
+}
+
+ffa_result ffa_msg_send_direct_resp(uint16_t source, uint16_t dest, uint32_t a0,
+ uint32_t a1, uint32_t a2, uint32_t a3,
+ uint32_t a4, struct ffa_direct_msg *msg)
+{
+ struct ffa_params result = {0};
+
+ ffa_svc(FFA_MSG_SEND_DIRECT_RESP_32,
+ SHIFT_U32(source, FFA_MSG_SEND_DIRECT_RESP_SOURCE_ID_SHIFT) |
+ dest, FFA_PARAM_MBZ, a0, a1, a2, a3, a4, &result);
+
+ while (result.a0 == FFA_INTERRUPT) {
+ ffa_interrupt_handler(result.a2);
+ ffa_return_from_interrupt(&result);
+ }
+
+ if (result.a0 == FFA_ERROR) {
+ return ffa_get_errorcode(&result);
+ } else if (result.a0 == FFA_MSG_SEND_DIRECT_REQ_32) {
+ ffa_unpack_direct_msg(&result, msg);
+ } else {
+ assert(result.a0 == FFA_SUCCESS_32);
+ *msg = (struct ffa_direct_msg){.function_id = result.a0};
+ }
+
+ return FFA_OK;
+}
diff --git a/components/messaging/ffa/libsp/ffa_interrupt_handler.c b/components/messaging/ffa/libsp/ffa_interrupt_handler.c
new file mode 100644
index 000000000..a165cc4ef
--- /dev/null
+++ b/components/messaging/ffa/libsp/ffa_interrupt_handler.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include <stdint.h> // for uint32_t
+#include "ffa_api.h" // for ffa_interrupt_handler
+#include "sp_api.h" // for sp_interrupt_handler
+
+void ffa_interrupt_handler(uint32_t interrupt_id)
+{
+ sp_interrupt_handler(interrupt_id);
+}
diff --git a/components/messaging/ffa/libsp/include/ffa_api.h b/components/messaging/ffa/libsp/include/ffa_api.h
new file mode 100644
index 000000000..ac7a7b330
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/ffa_api.h
@@ -0,0 +1,174 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_FFA_API_H_
+#define LIBSP_INCLUDE_FFA_API_H_
+
+/**
+ * @file ffa_api.h
+ * @brief The file contains wrapper functions around the FF-A interfaces
+ * described in sections 7-11 of the specification.
+ */
+
+#include "ffa_api_types.h"
+#include "ffa_api_defines.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Setup and discovery interfaces
+ */
+
+/**
+ * @brief Queries the version of the Firmware Framework implementation at
+ * the FF-A instance.
+ *
+ * @param[out] version Version number of the FF-A implementation
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_version(uint32_t *version);
+
+/**
+ * @brief Queries whether the FF-A interface is implemented of the
+ * component at the higher EL and if it implements any optional
+ * features. The meaning of the interface_properties structure
+ * depends on the queried FF-A function and it is described in
+ * section 8.2 of the FF-A standard (v1.0).
+ *
+ * @param[in] ffa_function_id The function id of the queried FF-A
+ * function
+ * @param[out] interface_properties Used to encode any optional features
+ * implemented or any implementation details
+ * exported by the queried interface
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_features(uint32_t ffa_function_id,
+ struct ffa_interface_properties *interface_properties);
+
+/**
+ * @brief Relinquishes the ownership of the RX buffer after reading a
+ * message from it.
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_rx_release(void);
+
+/**
+ * @brief Maps the RX/TX buffer pair in the callee's translation regime.
+ *
+ * @param[in] tx_buffer Base address of the TX buffer
+ * @param[in] rx_buffer Base address of the RX buffer
+ * @param[in] page_count Number of contiguous 4K pages allocated for each
+ * buffer
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_rxtx_map(const void *tx_buffer, const void *rx_buffer,
+ uint32_t page_count);
+
+/**
+ * @brief Unmaps the RX/TX buffer pair in the callee's translation regime.
+ *
+ * @param[in] id ID of FF-A component that allocated the RX/TX buffer
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_rxtx_unmap(uint16_t id);
+
+/**
+ * @brief Requests the SPM to return information about the partition of
+ * the system. Nil UUID can be used to return information about all
+ * the SPs of the system. The information is returned in the RX
+ * buffer of the caller as an array of ffa_partition_information
+ * structures.
+ *
+ * @param[in] uuid The uuid
+ * @param[out] count Count of partition information descriptors populated in
+ * RX buffer of caller
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t *count);
+
+/**
+ * @brief Returns the 16 bit ID of the calling FF-A component
+ *
+ * @param id ID of the caller
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_id_get(uint16_t *id);
+
+/**
+ * CPU cycle management interfaces
+ */
+
+/**
+ * @brief Blocks the caller until a message is available or until an
+ * interrupt happens. It is also used to indicate the completion of
+ * the boot phase and the end of the interrupt handling.
+ * @note The ffa_interrupt_handler function can be called during the
+ * execution of this function.
+ *
+ * @param[out] msg The incoming message
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_msg_wait(struct ffa_direct_msg *msg);
+
+/** Messaging interfaces */
+
+/**
+ * @brief Sends a partition message in parameter registers as a request and
+ * blocks until the response is available.
+ * @note The ffa_interrupt_handler function can be called during the
+ * execution of this function
+ *
+ * @param[in] source Source endpoint ID
+ * @param[in] dest Destination endpoint ID
+ * @param[in] a0,a1,a2,a3,a4 Implementation defined message values
+ * @param[out] msg The response message
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_msg_send_direct_req(uint16_t source, uint16_t dest, uint32_t a0,
+ uint32_t a1, uint32_t a2, uint32_t a3,
+ uint32_t a4, struct ffa_direct_msg *msg);
+
+/**
+ * @brief Sends a partition message in parameter registers as a response
+ * and blocks until the response is available.
+ * @note The ffa_interrupt_handler function can be called during the
+ * execution of this function
+ *
+ * @param[in] source Source endpoint ID
+ * @param[in] dest Destination endpoint ID
+ * @param[in] a0,a1,a2,a3,a4 Implementation defined message values
+ * @param[out] msg The response message
+ *
+ * @return The FF-A error status code
+ */
+ffa_result ffa_msg_send_direct_resp(uint16_t source, uint16_t dest, uint32_t a0,
+ uint32_t a1, uint32_t a2, uint32_t a3,
+ uint32_t a4, struct ffa_direct_msg *msg);
+
+/**
+ * @brief Interrupt handler prototype. Must be implemented by another
+ * component.
+ *
+ * @param[in] interrupt_id The interrupt identifier
+ */
+void ffa_interrupt_handler(uint32_t interrupt_id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBSP_INCLUDE_FFA_API_H_ */
diff --git a/components/messaging/ffa/libsp/include/ffa_api_defines.h b/components/messaging/ffa/libsp/include/ffa_api_defines.h
new file mode 100644
index 000000000..5a7f8f447
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/ffa_api_defines.h
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_FFA_API_DEFINES_H_
+#define LIBSP_INCLUDE_FFA_API_DEFINES_H_
+
+#include <stdint.h>
+#include "util.h"
+
+/* Status codes */
+#define FFA_OK (0)
+#define FFA_NOT_SUPPORTED (-1)
+#define FFA_INVALID_PARAMETERS (-2)
+#define FFA_NO_MEMORY (-3)
+#define FFA_BUSY (-4)
+#define FFA_INTERRUPTED (-5)
+#define FFA_DENIED (-6)
+#define FFA_RETRY (-7)
+#define FFA_ABORTED (-8)
+
+/* Function IDs */
+#define FFA_ERROR UINT32_C(0x84000060)
+#define FFA_SUCCESS_32 UINT32_C(0x84000061)
+#define FFA_SUCCESS_64 UINT32_C(0xC4000061)
+#define FFA_INTERRUPT UINT32_C(0x84000062)
+#define FFA_VERSION UINT32_C(0x84000063)
+#define FFA_FEATURES UINT32_C(0x84000064)
+#define FFA_RX_RELEASE UINT32_C(0x84000065)
+#define FFA_RXTX_MAP_32 UINT32_C(0x84000066)
+#define FFA_RXTX_MAP_64 UINT32_C(0xC4000066)
+#define FFA_RXTX_UNMAP UINT32_C(0x84000067)
+#define FFA_PARTITION_INFO_GET UINT32_C(0x84000068)
+#define FFA_ID_GET UINT32_C(0x84000069)
+#define FFA_MSG_WAIT UINT32_C(0x8400006B)
+#define FFA_MSG_YIELD UINT32_C(0x8400006C)
+#define FFA_MSG_RUN UINT32_C(0x8400006D)
+#define FFA_MSG_SEND UINT32_C(0x8400006E)
+#define FFA_MSG_SEND_DIRECT_REQ_32 UINT32_C(0x8400006F)
+#define FFA_MSG_SEND_DIRECT_REQ_64 UINT32_C(0xC400006F)
+#define FFA_MSG_SEND_DIRECT_RESP_32 UINT32_C(0x84000070)
+#define FFA_MSG_SEND_DIRECT_RESP_64 UINT32_C(0xC4000070)
+#define FFA_MSG_POLL UINT32_C(0x8400006A)
+#define FFA_MEM_DONATE_32 UINT32_C(0x84000071)
+#define FFA_MEM_DONATE_64 UINT32_C(0xC4000071)
+#define FFA_MEM_LEND_32 UINT32_C(0x84000072)
+#define FFA_MEM_LEND_64 UINT32_C(0xC4000072)
+#define FFA_MEM_SHARE_32 UINT32_C(0x84000073)
+#define FFA_MEM_SHARE_64 UINT32_C(0xC4000073)
+#define FFA_MEM_RETRIEVE_REQ_32 UINT32_C(0x84000074)
+#define FFA_MEM_RETRIEVE_REQ_64 UINT32_C(0xC4000074)
+#define FFA_MEM_RETRIEVE_RESP UINT32_C(0x84000075)
+#define FFA_MEM_RELINQUISH UINT32_C(0x84000076)
+#define FFA_MEM_RECLAIM UINT32_C(0x84000077)
+#define FFA_MEM_FRAG_RX UINT32_C(0x8400007A)
+#define FFA_MEM_FRAG_TX UINT32_C(0x8400007B)
+
+/* Special value for MBZ parameters */
+#define FFA_PARAM_MBZ UINT32_C(0x0)
+
+/* FFA_VERSION */
+#define FFA_VERSION_MAJOR UINT32_C(1)
+#define FFA_VERSION_MAJOR_SHIFT UINT32_C(16)
+#define FFA_VERSION_MAJOR_MASK GENMASK_32(14, 0)
+#define FFA_VERSION_MINOR UINT32_C(0)
+#define FFA_VERSION_MINOR_SHIFT UINT32_C(0)
+#define FFA_VERSION_MINOR_MASK GENMASK_32(15, 0)
+
+/* FFA_FEATURES */
+
+/* Features of FFA_RXTX_MAP */
+#define FFA_FEATURES_RXTX_MAP_GRANULARITY_INDEX UINT32_C(0)
+#define FFA_FEATURES_RXTX_MAP_GRANULARITY_SHIFT UINT32_C(0)
+#define FFA_FEATURES_RXTX_MAP_GRANULARITY_MASK GENMASK_32(1, 0)
+
+#define FFA_FEATURES_RXTX_MAP_GRANULARITY_4K UINT32_C(0x00)
+#define FFA_FEATURES_RXTX_MAP_GRANULARITY_64K UINT32_C(0x01)
+#define FFA_FEATURES_RXTX_MAP_GRANULARITY_16K UINT32_C(0x02)
+
+/* Features of FFA_MEM_DONATE, FFA_MEM_LEND, FFA_MEM_SHARE */
+#define FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT_INDEX UINT32_C(0)
+#define FFA_FEATURES_MEM_DYNAMIC_BUFFER_SUPPORT BIT32(0)
+
+/* Features of FFA_MEM_RETRIEVE_REQ */
+#define FFA_FEATURES_MEM_RETRIEVE_REQ_RETRIEVALS_INDEX UINT32_C(0)
+#define FFA_FEATURES_MEM_RETRIEVE_REQ_RETRIEVALS_SHIFT UINT32_C(0)
+#define FFA_FEATURES_MEM_RETRIEVE_REQ_RETRIEVALS_MASK GENMASK_32(7, 0)
+
+/* FFA_RXTX_MAP */
+#define FFA_RXTX_MAP_PAGE_COUNT_SHIFT UINT32_C(0)
+#define FFA_RXTX_MAP_PAGE_COUNT_MASK GENMASK_32(5, 0)
+#define FFA_RXTX_MAP_PAGE_COUNT_MAX FFA_RXTX_MAP_PAGE_COUNT_MASK
+#define FFA_RXTX_MAP_PAGE_SIZE UINT32_C(4096)
+
+/* FFA_RXTX_UNMAP */
+#define FFA_RXTX_UNMAP_ID_SHIFT UINT32_C(16)
+#define FFA_RXTX_UNMAP_ID_MASK GENMASK_32(15, 0)
+
+/* FFA_PARTITION_INFO_GET */
+#define FFA_PARTITION_SUPPORTS_DIRECT_REQUESTS BIT32(0)
+#define FFA_PARTITION_CAN_SEND_DIRECT_REQUESTS BIT32(1)
+#define FFA_PARTITION_SUPPORTS_INDIRECT_REQUESTS BIT32(2)
+
+/* FFA_ID_GET */
+#define FFA_ID_GET_ID_SHIFT UINT32_C(0)
+#define FFA_ID_GET_ID_MASK GENMASK_32(15, 0)
+
+/* FFA_MSG_SEND_DIRECT_REQ */
+#define FFA_MSG_SEND_DIRECT_REQ_SOURCE_ID_MASK GENMASK_32(15, 0)
+#define FFA_MSG_SEND_DIRECT_REQ_SOURCE_ID_SHIFT UINT32_C(16)
+
+#define FFA_MSG_SEND_DIRECT_REQ_DEST_ID_MASK GENMASK_32(15, 0)
+#define FFA_MSG_SEND_DIRECT_REQ_DEST_ID_SHIFT UINT32_C(0)
+
+/* FFA_MSG_SEND_DIRECT_RESP */
+#define FFA_MSG_SEND_DIRECT_RESP_SOURCE_ID_MASK GENMASK_32(15, 0)
+#define FFA_MSG_SEND_DIRECT_RESP_SOURCE_ID_SHIFT UINT32_C(16)
+
+#define FFA_MSG_SEND_DIRECT_RESP_DEST_ID_MASK GENMASK_32(15, 0)
+#define FFA_MSG_SEND_DIRECT_RESP_DEST_ID_SHIFT UINT32_C(0)
+
+#endif /* LIBSP_INCLUDE_FFA_API_DEFINES_H_ */
diff --git a/components/messaging/ffa/libsp/include/ffa_api_types.h b/components/messaging/ffa/libsp/include/ffa_api_types.h
new file mode 100644
index 000000000..94845ae4c
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/ffa_api_types.h
@@ -0,0 +1,86 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_FFA_API_TYPES_H_
+#define LIBSP_INCLUDE_FFA_API_TYPES_H_
+
+#include "compiler.h"
+#include <stddef.h>
+#include <stdint.h>
+
+/**
+ * Init info
+ */
+
+/**
+ * @brief Boot protocol name-value pairs
+ */
+struct ffa_name_value_pair {
+ uint32_t name[4]; /**< Name of the item */
+ uintptr_t value; /**< Value of the item */
+ size_t size; /**< Size of the referenced value */
+};
+
+/**
+ * @brief Structure for passing boot protocol data
+ */
+struct ffa_init_info {
+ uint32_t magic; /**< FF-A */
+ uint32_t count; /**< Count of name value size pairs */
+ struct ffa_name_value_pair nvp[]; /**< Array of name value size pairs */
+};
+
+/**
+ * @brief FF-A error status code type
+ */
+typedef int32_t ffa_result;
+
+/**
+ * FF-A features types
+ */
+
+/**
+ * @brief Used to encode any optional features implemented or any implementation
+ * details exported by the queried interface.
+ */
+struct ffa_interface_properties {
+ uint32_t interface_properties[2];
+};
+
+/**
+ * Partition information types
+ */
+
+/**
+ * @brief UUID descriptor structure
+ */
+struct ffa_uuid {
+ uint8_t uuid[16];
+};
+
+/**
+ * @brief Table 8.25: Partition information descriptor
+ */
+struct ffa_partition_information {
+ uint16_t partition_id;
+ uint16_t execution_context_count;
+ uint32_t partition_properties;
+} __packed;
+
+/**
+ * Direct message type
+ */
+
+/**
+ * @brief Direct message type
+ */
+struct ffa_direct_msg {
+ uint32_t function_id;
+ uint16_t source_id;
+ uint16_t destination_id;
+ uint32_t args[5];
+};
+
+#endif /* LIBSP_INCLUDE_FFA_API_TYPES_H_ */
diff --git a/components/messaging/ffa/libsp/include/ffa_internal_api.h b/components/messaging/ffa/libsp/include/ffa_internal_api.h
new file mode 100644
index 000000000..bfd4415f2
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/ffa_internal_api.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_FFA_INTERNAL_API_H_
+#define LIBSP_INCLUDE_FFA_INTERNAL_API_H_
+
+/**
+ * @file ffa_internal_api.h
+ * @brief The file contains the definition of the bottom layer of the SEL-0 FF-A
+ * implementation which SVC caller function.
+ */
+
+#include <stdint.h>
+
+#ifdef ARM32
+struct ffa_params {
+ uint32_t a0; /**< Function ID */
+ uint32_t a1; /**< Parameter */
+ uint32_t a2; /**< Parameter */
+ uint32_t a3; /**< Parameter */
+ uint32_t a4; /**< Parameter */
+ uint32_t a5; /**< Parameter */
+ uint32_t a6; /**< Parameter */
+ uint32_t a7; /**< Parameter */
+};
+#endif /* ARM32 */
+
+#ifdef ARM64
+struct ffa_params {
+ uint64_t a0; /**< Function ID */
+ uint64_t a1; /**< Parameter */
+ uint64_t a2; /**< Parameter */
+ uint64_t a3; /**< Parameter */
+ uint64_t a4; /**< Parameter */
+ uint64_t a5; /**< Parameter */
+ uint64_t a6; /**< Parameter */
+ uint64_t a7; /**< Parameter */
+};
+#endif /* ARM64 */
+
+/**
+ * @brief SVC conduit caller function
+ * @param[in] a0, a1, a2, a3, a4, a5, a6, a7 Register values of the request
+ * @param[out] result Register values of the response
+ */
+#ifdef ARM64
+void ffa_svc(uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4,
+ uint64_t a5, uint64_t a6, uint64_t a7, struct ffa_params *result);
+#endif /* ARM64 */
+
+#endif /* LIBSP_INCLUDE_FFA_INTERNAL_API_H_ */
diff --git a/components/messaging/ffa/libsp/include/sp_api.h b/components/messaging/ffa/libsp/include/sp_api.h
new file mode 100644
index 000000000..e18856072
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/sp_api.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_SP_API_H_
+#define LIBSP_INCLUDE_SP_API_H_
+
+#include <stdint.h> // for uint32_t
+#include "compiler.h" // for __noreturn
+#include "ffa_api.h"
+
+/**
+ * Interface for the SP implementation
+ */
+
+/**
+ * @brief Interrupt handler of the SP. It is called by the implementation
+ * of ffa_interrupt_handler. SPs must implement this function.
+ *
+ * @param[in] interrupt_id The interrupt identifier
+ */
+void sp_interrupt_handler(uint32_t interrupt_id);
+
+/**
+ * @brief Entry point of the SP's application code. SPs must implement this
+ * function.
+ *
+ * @param init_info The boot info
+ */
+void __noreturn sp_main(struct ffa_init_info *init_info);
+
+#endif /* LIBSP_INCLUDE_SP_API_H_ */
diff --git a/components/messaging/ffa/libsp/include/sp_api_defines.h b/components/messaging/ffa/libsp/include/sp_api_defines.h
new file mode 100644
index 000000000..c1426ee9b
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/sp_api_defines.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_SP_API_DEFINES_H_
+#define LIBSP_INCLUDE_SP_API_DEFINES_H_
+
+/**
+ * SP result values are integers where the zero value indicates success and
+ * negative values are error codes. The first part of the error code range is
+ * mapped directly to the FF-A error code range so the SP result type is able
+ * to propagate FF-A error codes. The second part of the range is for SP layer
+ * specific error codes. This ranges starts immediately after the value of the
+ * last (lowest value) FF-A error code.
+ */
+
+#define SP_RESULT_OFFSET (FFA_ABORTED)
+#define SP_RESULT_CREATE(x) (SP_RESULT_OFFSET + (x))
+
+/** SP API call result codes */
+#define SP_RESULT_OK (0)
+#define SP_RESULT_FFA(res) (res)
+
+#endif /* LIBSP_INCLUDE_SP_API_DEFINES_H_ */
diff --git a/components/messaging/ffa/libsp/include/sp_api_types.h b/components/messaging/ffa/libsp/include/sp_api_types.h
new file mode 100644
index 000000000..10ab2934b
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/sp_api_types.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_SP_API_TYPES_H_
+#define LIBSP_INCLUDE_SP_API_TYPES_H_
+
+#include <stdint.h>
+
+/**
+ * SP API call result
+ */
+typedef int32_t sp_result;
+
+#endif /* LIBSP_INCLUDE_SP_API_TYPES_H_ */