Update the RPC layer
This commit merges the 'tforg/topics/ts-rpc' into integration. The
change overhauls the RPC layer implement the following changes:
- allow RPC compatibility check be adding versioning to the RPC layer
- allow multiple memory shares between FF-A endpoints. (This was a
concerning limitation for NWd endpoints where multiple clients
may operate).
- add service discovery support. After this change all SPs use the
same FF-A UUID. This means the FF-A UUID identifies the protocol and
not the service as before. As a result, to locate a service further
discovery is needed on top of FF-A discovery. This is implemented
in the RPC layer for performance reasons.
- update discovery implementation and add the new discovery step
needed after service locator locates the SP.
- change protocol encoding types to be represented as dedicated
interfaces of an SP. This removes encoding type identifiers and
replaces these with service UUIDs.
- add RPC ABI documentation
Change-Id: I7fbb28b17d44b04578595c8725674624297f01a0
Signed-off-by: Gyorgy Szing <Gyorgy.Szing@arm.com>
diff --git a/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp b/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp
index aaa8fd3..310899a 100644
--- a/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp
@@ -44,13 +44,20 @@
explicit fmp(fwu_client *m_fwu_client)
: client(m_fwu_client)
, is_staging(false)
+ , payload_max_size(0)
, img_info(NULL)
, num_images(0)
- , payload_max_size(0)
+
{
parse_img_directory();
}
+ ~fmp()
+ {
+ if (img_info)
+ delete[] img_info;
+ }
+
int get_image_info(uint64_t *ImageInfoSize, EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
uint32_t *DescriptorVersion, uint8_t *DescriptorCount,
uint64_t *DescriptorSize, uint32_t *PackageVersion,
diff --git a/components/service/secure_storage/backend/mock_store/mock_store.c b/components/service/secure_storage/backend/mock_store/mock_store.c
index 5e43d5f..23c336e 100644
--- a/components/service/secure_storage/backend/mock_store/mock_store.c
+++ b/components/service/secure_storage/backend/mock_store/mock_store.c
@@ -6,6 +6,7 @@
#include "mock_store.h"
#include <protocols/service/psa/packed-c/status.h>
+#include "util.h"
#include <stdlib.h>
#include <string.h>
@@ -29,17 +30,24 @@
/* Check length limit */
if (data_length > MOCK_STORE_ITEM_SIZE_LIMIT) return psa_status;
+ if (!uid)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
/* Replace existing or add new item */
struct mock_store_slot *slot = find_slot(this_context, uid);
- if (slot) free_slot(slot);
- else slot = find_empty_slot(this_context);
+ if (slot) {
+ if (slot->flags & PSA_STORAGE_FLAG_WRITE_ONCE)
+ return PSA_ERROR_NOT_PERMITTED;
+
+ free_slot(slot);
+ } else {
+ slot = find_empty_slot(this_context);
+ }
if (slot) {
-
slot->item = malloc(data_length);
if (slot->item) {
-
slot->uid = uid;
slot->flags = create_flags;
slot->len = slot->capacity = data_length;
@@ -60,22 +68,26 @@
void *p_data,
size_t *p_data_length)
{
- (void)client_id;
- (void)data_offset;
-
- psa_status_t psa_status = PSA_ERROR_DOES_NOT_EXIST;
struct mock_store *this_context = (struct mock_store*)context;
+ (void)client_id;
+
+ if (!uid)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
/* Find the item */
struct mock_store_slot *slot = find_slot(this_context, uid);
- if (slot && (slot->len <= data_size)) {
- memcpy(p_data, slot->item, slot->len);
- *p_data_length = slot->len;
- psa_status = PSA_SUCCESS;
- }
+ if (!slot)
+ return PSA_ERROR_DOES_NOT_EXIST;
- return psa_status;
+ if (slot->len < data_offset)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
+ *p_data_length = MIN(slot->len - data_offset, data_size);
+ memcpy(p_data, slot->item + data_offset, *p_data_length);
+
+ return PSA_SUCCESS;
}
static psa_status_t mock_store_get_info(void *context,
@@ -88,6 +100,9 @@
psa_status_t psa_status = PSA_ERROR_DOES_NOT_EXIST;
struct mock_store *this_context = (struct mock_store*)context;
+ if (!uid)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
/* Find item to get info about */
struct mock_store_slot *slot = find_slot(this_context, uid);
@@ -115,12 +130,19 @@
psa_status_t psa_status = PSA_ERROR_DOES_NOT_EXIST;
struct mock_store *this_context = (struct mock_store*)context;
+ if (!uid)
+ return PSA_ERROR_INVALID_ARGUMENT;
+
/* Find and remove the item */
struct mock_store_slot *slot = find_slot(this_context, uid);
if (slot) {
- free_slot(slot);
- psa_status = PSA_SUCCESS;
+ if (!(slot->flags & PSA_STORAGE_FLAG_WRITE_ONCE)) {
+ free_slot(slot);
+ psa_status = PSA_SUCCESS;
+ } else {
+ psa_status = PSA_ERROR_NOT_PERMITTED;
+ }
}
return psa_status;
diff --git a/components/service/spm_test/sp.c b/components/service/spm_test/sp.c
index 5bbc545..663e29b 100644
--- a/components/service/spm_test/sp.c
+++ b/components/service/spm_test/sp.c
@@ -54,7 +54,8 @@
EP_SP_MEM_SHARING_MULTI,
EP_SP_MEM_SHARING_EXC,
EP_SP_MEM_INCORRECT_ACCESS,
- EP_SP_NOP
+ EP_SP_NOP,
+ EP_TEST_SP_COMMUNICATION_RESPONSE,
};
const char* sp_test_str[]= {
@@ -281,34 +282,144 @@
static void test_communication(struct ffa_direct_msg *msg)
{
struct ffa_direct_msg sp_msg = {0};
+ uint16_t caller = msg->source_id;
+ uint16_t src = msg->destination_id;
uint16_t dst = (uint16_t)msg->args.args64[1];
ffa_result res = FFA_OK;
+ struct ffa_params raw_params = { 0 };
sp_msg.args.args64[1] = 0x55;
sp_msg.args.args64[2] = 0xAA;
sp_msg.args.args64[3] = 0xBB;
sp_msg.args.args64[4] = 0xCC;
- res = ffa_msg_send_direct_req_64(msg->destination_id, dst,
+ res = ffa_msg_send_direct_req_64(src, dst,
EP_TEST_SP_INCREASE,0x55, 0xAA, 0xBB,
0xCC, &sp_msg);
-
if (res != FFA_OK) {
EMSG("error % in %s:%d"PRId32, res, __FILE__, __LINE__);
- return_error((uint32_t)ERR_SP_SHARE, msg);
- return;
+ goto err;
}
- if (sp_msg.args.args64[1] == 0x56 && sp_msg.args.args64[2] == 0xAB &&
- sp_msg.args.args64[3] == 0xBC &&sp_msg.args.args64[4] == 0xCD) {
- return_ok(msg);
- } else {
+ if (sp_msg.args.args64[1] != 0x56 || sp_msg.args.args64[2] != 0xAB ||
+ sp_msg.args.args64[3] != 0xBC || sp_msg.args.args64[4] != 0xCD) {
DMSG("Failed SP communication %lx %lx %lx %lx",
sp_msg.args.args64[1], sp_msg.args.args64[2],
sp_msg.args.args64[3], sp_msg.args.args64[4]);
-
- return_error(ERR_SP_COMMUNICATION, msg);
+ goto err;
}
+
+ /* Non-null flags (W2) register */
+ ffa_svc(FFA_MSG_SEND_DIRECT_REQ_64, (uint32_t)(src << 16 | 0x1000), 1, 0, 0, 0, 0, 0,
+ &raw_params);
+ if (raw_params.a0 != FFA_ERROR || (uint32_t)raw_params.a2 != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %ld", FFA_INVALID_PARAMETERS, raw_params.a2);
+ goto err;
+ }
+
+ /* Testing non-matching source ID */
+ res = ffa_msg_send_direct_req_64(src + 1, dst, 0, 0, 0, 0, 0, &sp_msg);
+ if (res != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %d", FFA_INVALID_PARAMETERS, res);
+ goto err;
+ }
+
+ /* Sending message to own ID */
+ res = ffa_msg_send_direct_req_64(src, src, 0, 0, 0, 0, 0, &sp_msg);
+ if (res != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %d", FFA_INVALID_PARAMETERS, res);
+ goto err;
+ }
+
+ /* Sending message to normal world */
+ res = ffa_msg_send_direct_req_64(src, 0, 0, 0, 0, 0, 0, &sp_msg);
+ if (res != FFA_NOT_SUPPORTED) {
+ EMSG("Unexpected error code: %d != %d", FFA_NOT_SUPPORTED, res);
+ goto err;
+ }
+
+ /* Sending message for starting direct message response test */
+ if (!caller) {
+ res = ffa_msg_send_direct_req_64(src, dst, EP_TEST_SP_COMMUNICATION_RESPONSE, 0, 0,
+ 0, 0, &sp_msg);
+ if (res != FFA_OK) {
+ EMSG("Unexpected error code: %d != %d", FFA_OK, res);
+ goto err;
+ }
+
+ if (sp_msg.args.args64[0] != SP_TEST_OK) {
+ EMSG("Unexpected test result: %d != %ld", SP_TEST_OK, sp_msg.args.args64[0]);
+ goto err;
+ }
+ }
+
+ return_ok(msg);
+ return;
+
+err:
+ return_error(ERR_SP_COMMUNICATION, msg);
+}
+
+static void test_communication_response(struct ffa_direct_msg *msg)
+{
+ struct ffa_direct_msg sp_msg = {0};
+ uint16_t caller = msg->source_id;
+ uint16_t src = msg->destination_id;
+ ffa_result res = FFA_OK;
+ struct ffa_params raw_params = { 0 };
+
+ /* Non-null flags (W2) register */
+ ffa_svc(FFA_MSG_SEND_DIRECT_RESP_64, (uint32_t)(src << 16 | 0x1000), 1, 0, 0, 0, 0, 1,
+ &raw_params);
+ if (raw_params.a0 != FFA_ERROR || (uint32_t)raw_params.a2 != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %ld", FFA_INVALID_PARAMETERS, raw_params.a2);
+ goto err;
+ }
+
+ /* Testing non-matching source ID */
+ res = ffa_msg_send_direct_resp_64(src + 1, caller, 0, 0, 0, 0, 2, &sp_msg);
+ if (res != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %d", FFA_INVALID_PARAMETERS, res);
+ goto err;
+ }
+
+ /* Sending message to own ID */
+ res = ffa_msg_send_direct_resp_64(src, src, 0, 0, 0, 0, 3, &sp_msg);
+ if (res != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %d", FFA_INVALID_PARAMETERS, res);
+ goto err;
+ }
+
+ /* Sending message request to caller SP which is busy */
+ if (caller) {
+ /* Sending message to normal world */
+ res = ffa_msg_send_direct_resp_64(src, 0, 0, 0, 0, 0, 4, &sp_msg);
+ if (res != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %d", FFA_INVALID_PARAMETERS, res);
+ goto err;
+ }
+
+ /* Sending message to invalid SP */
+ res = ffa_msg_send_direct_resp_64(src, 0x1000, 0, 0, 0, 0, 5, &sp_msg);
+ if (res != FFA_INVALID_PARAMETERS) {
+ EMSG("Unexpected error code: %d != %d", FFA_INVALID_PARAMETERS, res);
+ goto err;
+ }
+
+ /* Sending message request to caller SP which is busy */
+ res = ffa_msg_send_direct_req_64(src, caller, 0, 0, 0, 0, 6, &sp_msg);
+ if (res != FFA_BUSY) {
+ EMSG("Unexpected error code: %d != %d", FFA_BUSY, res);
+ goto err;
+ }
+ }
+
+ ffa_msg_send_direct_resp_64(src, caller, SP_TEST_OK, 0, 0, 0, 0, msg);
+ return;
+
+err:
+ ffa_msg_send_direct_resp_64(src, caller, ERR_SP_COMMUNICATION, 0, 0, 0, 0, msg);
+
}
static void test_internal_sp(struct ffa_direct_msg *msg)
@@ -793,6 +904,9 @@
case EP_TEST_SP_COMMUNICATION:
test_communication(&msg);
break;
+ case EP_TEST_SP_COMMUNICATION_RESPONSE:
+ test_communication_response(&msg);
+ break;
case EP_TEST_SP_INCREASE:
test_increase(&msg);
break;
diff --git a/tools/cmake/common/LazyFetch.cmake b/tools/cmake/common/LazyFetch.cmake
index 68e790e..0c00bce 100644
--- a/tools/cmake/common/LazyFetch.cmake
+++ b/tools/cmake/common/LazyFetch.cmake
@@ -16,6 +16,24 @@
#[===[.rst:
Common fetch interface for external dependencies.
-------------------------------------------------
+
+The following variables can be set in cmake or in the environment to configure various aspect of
+building and external component.
+Note: <DEP_NAME> is the name of the dependency as set int the cmake files with all characters
+converted to uppercase.
+
+``<DEP_NAME>_VERBOSE_CONFIG``
+ Global variable or environment variable.
+ Pass `--trace-expand` to cmake if set.
+
+``<DEP_NAME>_VERBOSE_BUILD``
+ Global variable or environment variable.
+ Turn the build step to verbose mode if set.
+
+``<DEP_NAME>_GENERATOR``
+ Global variable or environment variable.
+ Set the cmake generator to a specific value. If not set, the value of CMAKE_GENERATOR
+ will be used.
#]===]
#[===[.rst:
@@ -68,6 +86,12 @@
can be used to pass variables to the external project.
``INSTALL_DIR``
Install path. If not set, the install step will be skipped.
+ ``<DEP_NAME>_VERBOSE_CONFIG``
+ Global variable or environment variable.
+ Pass `--trace-expand` to cmake if set.
+ ``<DEP_NAME>_VERBOSE_BUILD``
+ Global variable or environment variable.
+ Turn the build step to verbose mode if set.
#]===]
function(LazyFetch_ConfigAndBuild)
@@ -87,13 +111,27 @@
"component specific. Pleas refer to the upstream documentation for more information.")
endif()
+ if (DEFINED ${UC_DEP_NAME}_VERBOSE_CONFIG OR DEFINED ENV{${UC_DEP_NAME}_VERBOSE_CONFIG})
+ set(_CMAKE_VERBOSE_CFG_FLAG "--trace-expand")
+ endif()
+
+ if(NOT DEFINED ${UC_DEP_NAME}_GENERATOR)
+ if(DEFINED ENV{${UC_DEP_NAME}_GENERATOR})
+ set(${UC_DEP_NAME}_GENERATOR ENV{${UC_DEP_NAME}_GENERATOR} CACHE STRING "CMake generator used for ${UC_DEP_NAME}.")
+ else()
+ set(${UC_DEP_NAME}_GENERATOR ${CMAKE_GENERATOR} CACHE STRING "CMake generator used for ${UC_DEP_NAME}.")
+ endif()
+ endif()
+
execute_process(COMMAND
${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
${CMAKE_COMMAND}
"-C${CONFIGURED_CACHE_FILE}"
-DCMAKE_BUILD_TYPE=${${UC_DEP_NAME}_BUILD_TYPE}
+ -G${${UC_DEP_NAME}_GENERATOR}
-S ${BUILD_SRC_DIR}
-B ${BUILD_BIN_DIR}
+ ${_CMAKE_VERBOSE_CFG_FLAG}
RESULT_VARIABLE
_exec_error
)
@@ -101,6 +139,10 @@
message(FATAL_ERROR "Configuring ${BUILD_DEP_NAME} build failed. `${_exec_error}`")
endif()
+ if (DEFINED ${UC_DEP_NAME}_VERBOSE_BUILD OR DEFINED ENV{${UC_DEP_NAME}_VERBOSE_BUILD})
+ set(_CMAKE_VERBOSE_CFG_FLAG "--verbose")
+ endif()
+
if (BUILD_INSTALL_DIR)
execute_process(COMMAND
${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
@@ -108,6 +150,7 @@
--build ${BUILD_BIN_DIR}
--parallel ${PROCESSOR_COUNT}
--target install
+ ${_CMAKE_VERBOSE_BLD_FLAG}
RESULT_VARIABLE
_exec_error
)
@@ -117,6 +160,7 @@
${CMAKE_COMMAND}
--build ${BUILD_BIN_DIR}
--parallel ${PROCESSOR_COUNT}
+ ${_CMAKE_VERBOSE_BLD_FLAG}
RESULT_VARIABLE
_exec_error
)
@@ -153,6 +197,12 @@
``SOURCE_SUBDIR``
A subdirectory relative to the top level directory of the fetched component, where the CMakeLists.txt file
can be found.
+ ``<DEP_NAME>_VERBOSE_CONFIG``
+ Global variable or environment variable.
+ Pass `--trace-expand` to cmake if set.
+ ``<DEP_NAME>_VERBOSE_BUILD``
+ Global variable or environment variable.
+ Turn the build step to verbose mode if set.
#]===]
macro(LazyFetch_MakeAvailable)
@@ -167,6 +217,8 @@
# FetchContent* functions use this form
string(TOLOWER ${MY_DEP_NAME} MY_LC_DEP_NAME)
+ # We also need the upper case version
+ string(TOUPPER ${MY_DEP_NAME} MY_UC_DEP_NAME)
# Look for name collision. We can collide with project() commands, other external components defined with
# LazyFetch, FetchCOntent or ExternalProject.
@@ -221,12 +273,17 @@
)
endif()
elseif(DEFINED MY_INSTALL_DIR)
+ if(DEFINED ${MY_UC_DEP_NAME}_VERBOSE_BUILD OR DEFINED ENV{${MY_UC_DEP_NAME}_VERBOSE_BUILD})
+ set(_CMAKE_VERBOSE_BLD_FLAG "--verbose")
+ endif()
+
execute_process(COMMAND
${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
${CMAKE_COMMAND}
--build ${${MY_LC_DEP_NAME}_BINARY_DIR}
--parallel ${PROCESSOR_COUNT}
--target install
+ ${_CMAKE_VERBOSE_BLD_FLAG}
RESULT_VARIABLE
_exec_error
)