aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorImre Kis <imre.kis@arm.com>2020-11-23 03:15:47 +0100
committerGyorgy Szing <Gyorgy.Szing@arm.com>2020-11-25 15:56:04 +0100
commit6447693b40777083329d516b497c1ca676ced038 (patch)
tree8cfc0a2aaf93db910d971a51bef1986c3c05908c
parente3112e05c3a0b984df214331965ccdc2f566251d (diff)
downloadtrusted-services-6447693b40777083329d516b497c1ca676ced038.tar.gz
libsp: Add high level RXTX buffer handling interface.
This layer provides functions for mapping, unmapping and accessing FF-A RXTX buffers. It allows other high level interfaces (like memory management) to use the RXTX buffers internally without the need for forwarding the RXTX buffer information externally by the user. Signed-off-by: Imre Kis <imre.kis@arm.com> Change-Id: I946bcbf818599b2eb12f6ff029f9fc429ccb12b7
-rw-r--r--components/messaging/ffa/libsp/component.cmake2
-rw-r--r--components/messaging/ffa/libsp/include/sp_api_defines.h3
-rw-r--r--components/messaging/ffa/libsp/include/sp_rxtx.h76
-rw-r--r--components/messaging/ffa/libsp/sp_rxtx.c160
4 files changed, 241 insertions, 0 deletions
diff --git a/components/messaging/ffa/libsp/component.cmake b/components/messaging/ffa/libsp/component.cmake
index c20f899..60bc507 100644
--- a/components/messaging/ffa/libsp/component.cmake
+++ b/components/messaging/ffa/libsp/component.cmake
@@ -12,6 +12,7 @@ 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"
+ "${CMAKE_CURRENT_LIST_DIR}/sp_rxtx.c"
)
set_property(TARGET ${TGT} PROPERTY PUBLIC_HEADER
@@ -22,6 +23,7 @@ set_property(TARGET ${TGT} PROPERTY PUBLIC_HEADER
${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
+ ${CMAKE_CURRENT_LIST_DIR}/include/sp_rxtx.h
)
diff --git a/components/messaging/ffa/libsp/include/sp_api_defines.h b/components/messaging/ffa/libsp/include/sp_api_defines.h
index c1426ee..9a80559 100644
--- a/components/messaging/ffa/libsp/include/sp_api_defines.h
+++ b/components/messaging/ffa/libsp/include/sp_api_defines.h
@@ -21,5 +21,8 @@
/** SP API call result codes */
#define SP_RESULT_OK (0)
#define SP_RESULT_FFA(res) (res)
+#define SP_RESULT_INTERNAL_ERROR SP_RESULT_CREATE(-1)
+#define SP_RESULT_INVALID_PARAMETERS SP_RESULT_CREATE(-2)
+#define SP_RESULT_INVALID_STATE SP_RESULT_CREATE(-3)
#endif /* LIBSP_INCLUDE_SP_API_DEFINES_H_ */
diff --git a/components/messaging/ffa/libsp/include/sp_rxtx.h b/components/messaging/ffa/libsp/include/sp_rxtx.h
new file mode 100644
index 0000000..a5b0f6a
--- /dev/null
+++ b/components/messaging/ffa/libsp/include/sp_rxtx.h
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBSP_INCLUDE_SP_RXTX_H_
+#define LIBSP_INCLUDE_SP_RXTX_H_
+
+/**
+ * @file sp_rxtx.h
+ * @brief The functions of this file provide a higher API for the FF-A RXTX
+ * buffer handling.
+ */
+
+#include "sp_api_defines.h"
+#include "sp_api_types.h"
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Maps the RX/TX buffer pair in the callee's translation regime.
+ *
+ * @param[in] tx_buffer The transmit buffer
+ * @param[in] rx_buffer The receive buffer
+ * @param[in] size The buffer size
+ *
+ * @return The SP API result
+ */
+sp_result sp_rxtx_buffer_map(void *tx_buffer, const void *rx_buffer,
+ size_t size);
+
+/**
+ * @brief Unmaps the RX/TX buffer pair in the callee's translation regime.
+ *
+ * @return The SP API result
+ */
+sp_result sp_rxtx_buffer_unmap(void);
+
+/**
+ * @brief Queries the required alignment boundary of the RXTX buffers.
+ *
+ * @param[out] alignment The minimal buffer size and alignment boundary
+ *
+ * @return The SP API result
+ */
+sp_result sp_rxtx_buffer_alignment_boundary_get(uintptr_t *alignment);
+
+/**
+ * @brief Queries the RX buffer's address and size.
+ *
+ * @param[out] buffer The buffer address
+ * @param[out] size The buffer size
+ *
+ * @return The SP API result
+ */
+sp_result sp_rxtx_buffer_rx_get(const void **buffer, size_t *size);
+
+/**
+ * @brief Queries the TX buffer's address and size.
+ *
+ * @param buffer The buffer address
+ * @param size The buffer size
+ *
+ * @return The SP API result
+ */
+sp_result sp_rxtx_buffer_tx_get(void **buffer, size_t *size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBSP_INCLUDE_SP_RXTX_H_ */
diff --git a/components/messaging/ffa/libsp/sp_rxtx.c b/components/messaging/ffa/libsp/sp_rxtx.c
new file mode 100644
index 0000000..a3de270
--- /dev/null
+++ b/components/messaging/ffa/libsp/sp_rxtx.c
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include "sp_rxtx.h"
+#include "ffa_api.h"
+#include <assert.h>
+#include <stdlib.h>
+#include <stdlib.h>
+
+void *ffa_tx_buffer;
+const void *ffa_rx_buffer;
+size_t ffa_rxtx_size;
+
+sp_result sp_rxtx_buffer_map(void *tx_buffer, const void *rx_buffer,
+ size_t size)
+{
+ uintptr_t alignment_mask = 0;
+ sp_result sp_res = SP_RESULT_OK;
+ ffa_result result = FFA_OK;
+ uint32_t page_count = 0;
+
+ /* Checking for invalid parameters*/
+ if (!tx_buffer || !rx_buffer || !size)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ /* Checking if the buffers are already mapped */
+ if (ffa_rxtx_size)
+ return SP_RESULT_INVALID_STATE;
+
+ /* Querying alignment size */
+ sp_res = sp_rxtx_buffer_alignment_boundary_get(&alignment_mask);
+ if (sp_res != SP_RESULT_OK)
+ return sp_res;
+
+ /* Creating a binary mask from the size */
+ alignment_mask = alignment_mask - 1;
+
+ /* Checking buffer and size alignment */
+ if (((uintptr_t)tx_buffer & alignment_mask) != 0 ||
+ ((uintptr_t)rx_buffer & alignment_mask) != 0 ||
+ (size & alignment_mask) != 0)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ /* Checking max page count for RXTX buffers */
+ page_count = size / FFA_RXTX_MAP_PAGE_SIZE;
+ if (page_count >= FFA_RXTX_MAP_PAGE_COUNT_MAX)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ /* Mapping the buffers */
+ result = ffa_rxtx_map(tx_buffer, rx_buffer, page_count);
+ if (result != FFA_OK)
+ return SP_RESULT_FFA(result);
+
+ /* Storing the buffer pointers and size internally */
+ ffa_tx_buffer = tx_buffer;
+ ffa_rx_buffer = rx_buffer;
+ ffa_rxtx_size = size;
+
+ return SP_RESULT_OK;
+}
+
+sp_result sp_rxtx_buffer_unmap(void)
+{
+ ffa_result result = FFA_OK;
+ uint16_t id = 0;
+
+ /* Checking if the buffers are not yet mapped */
+ if (!ffa_rxtx_size)
+ return SP_RESULT_INVALID_STATE;
+
+ result = ffa_id_get(&id);
+ if (result != FFA_OK)
+ return SP_RESULT_FFA(result);
+
+ /* Unmapping the buffers */
+ result = ffa_rxtx_unmap(id);
+ if (result != FFA_OK)
+ return SP_RESULT_FFA(result);
+
+ /* Clearing internally stored buffer pointers and size */
+ ffa_tx_buffer = NULL;
+ ffa_rx_buffer = NULL;
+ ffa_rxtx_size = 0;
+
+ return SP_RESULT_OK;
+}
+
+sp_result sp_rxtx_buffer_alignment_boundary_get(uintptr_t *alignment)
+{
+ struct ffa_interface_properties interface_props = {0};
+ uint32_t *props = NULL;
+ ffa_result result = FFA_OK;
+ uint32_t granularity = 0;
+
+ /* Checking for invalid parameters */
+ if (!alignment)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ /* Querying FFX_RXTX_MAP features */
+ result = ffa_features(FFA_RXTX_MAP_32, &interface_props);
+ if (result != FFA_OK) {
+ *alignment = 0;
+ return SP_RESULT_FFA(result);
+ }
+
+ props = interface_props.interface_properties;
+ granularity = props[FFA_FEATURES_RXTX_MAP_GRANULARITY_INDEX];
+ granularity = (granularity >> FFA_FEATURES_RXTX_MAP_GRANULARITY_SHIFT) &
+ FFA_FEATURES_RXTX_MAP_GRANULARITY_MASK;
+
+ switch (granularity) {
+ case FFA_FEATURES_RXTX_MAP_GRANULARITY_4K:
+ *alignment = 4 * 1024;
+ break;
+
+ case FFA_FEATURES_RXTX_MAP_GRANULARITY_64K:
+ *alignment = 64 * 1024;
+ break;
+
+ case FFA_FEATURES_RXTX_MAP_GRANULARITY_16K:
+ *alignment = 16 * 1024;
+ break;
+
+ default:
+ *alignment = 0;
+ return SP_RESULT_INTERNAL_ERROR;
+ }
+
+ return SP_RESULT_OK;
+}
+
+sp_result sp_rxtx_buffer_rx_get(const void **buffer, size_t *size)
+{
+ if (!buffer || !size)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ if (!ffa_rxtx_size)
+ return SP_RESULT_INVALID_STATE;
+
+ *buffer = ffa_rx_buffer;
+ *size = ffa_rxtx_size;
+
+ return SP_RESULT_OK;
+}
+
+sp_result sp_rxtx_buffer_tx_get(void **buffer, size_t *size)
+{
+ if (!buffer || !size)
+ return SP_RESULT_INVALID_PARAMETERS;
+
+ if (!ffa_rxtx_size)
+ return SP_RESULT_INVALID_STATE;
+
+ *buffer = ffa_tx_buffer;
+ *size = ffa_rxtx_size;
+
+ return SP_RESULT_OK;
+}