diff options
author | Imre Kis <imre.kis@arm.com> | 2020-11-23 03:15:45 +0100 |
---|---|---|
committer | Gyorgy Szing <Gyorgy.Szing@arm.com> | 2020-11-25 15:56:04 +0100 |
commit | 9fcf8413d8ff419dbf9a60f9764daf8289bcc44e (patch) | |
tree | 1a919946310da5eafc411cc2e6e8c440c3c2d1d6 | |
parent | 3b32e7ba9791eef6575a688dd8bed95c76eed6c5 (diff) | |
download | trusted-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.S | 27 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/component.cmake | 32 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/ffa.c | 278 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/ffa_interrupt_handler.c | 13 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/ffa_api.h | 174 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/ffa_api_defines.h | 123 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/ffa_api_types.h | 86 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/ffa_internal_api.h | 53 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/sp_api.h | 33 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/sp_api_defines.h | 25 | ||||
-rw-r--r-- | components/messaging/ffa/libsp/include/sp_api_types.h | 16 |
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_ */ |