aboutsummaryrefslogtreecommitdiff
path: root/components/rpc/ffarpc
diff options
context:
space:
mode:
authorjulhal01 <julian.hall@arm.com>2020-12-15 13:39:01 +0000
committerGyorgy Szing <Gyorgy.Szing@arm.com>2021-04-14 16:59:03 +0200
commitc3f4e9a7550ee4fddf2d24127ef33ca514351806 (patch)
treee61b25f7a93ea4ed2f26363186cc236aba06dd24 /components/rpc/ffarpc
parent35c6d643b5f0c0387702e22bf742dd4878ca5ddd (diff)
downloadtrusted-services-c3f4e9a7550ee4fddf2d24127ef33ca514351806.tar.gz
Extend RPC parameters
The RPC model is extended to include parameters for identifying an RPC interface instance at an endpoint and another for identifying the parameter encoding. The interface ID parameter allows multiple service interfaces to be co-located. The encoding parameter allows clients to use different parameter serialization schemes and to specify the format in each RPC request. Signed-off-by: julhal01 <julian.hall@arm.com> Change-Id: I201b3417dc0e9f655113b9931db3494e41f1d74b
Diffstat (limited to 'components/rpc/ffarpc')
-rw-r--r--components/rpc/ffarpc/caller/linux/ffarpc_caller.c272
-rw-r--r--components/rpc/ffarpc/caller/linux/ffarpc_caller.h5
-rw-r--r--components/rpc/ffarpc/caller/sp/ffarpc_caller.c69
-rw-r--r--components/rpc/ffarpc/caller/sp/ffarpc_caller.h7
-rw-r--r--components/rpc/ffarpc/endpoint/ffarpc_call_args.h14
-rw-r--r--components/rpc/ffarpc/endpoint/ffarpc_call_ep.c39
-rw-r--r--components/rpc/ffarpc/endpoint/ffarpc_call_ep.h8
-rw-r--r--components/rpc/ffarpc/endpoint/ffarpc_call_ops.h16
8 files changed, 240 insertions, 190 deletions
diff --git a/components/rpc/ffarpc/caller/linux/ffarpc_caller.c b/components/rpc/ffarpc/caller/linux/ffarpc_caller.c
index 70d6ca30b..ac628a951 100644
--- a/components/rpc/ffarpc/caller/linux/ffarpc_caller.c
+++ b/components/rpc/ffarpc/caller/linux/ffarpc_caller.c
@@ -21,7 +21,7 @@
static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len);
static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
- int *opstatus, uint8_t **resp_buf, size_t *resp_len);
+ int *opstatus, uint8_t **resp_buf, size_t *resp_len);
static void call_end(void *context, rpc_call_handle handle);
static int kernel_write_req_buf(struct ffarpc_caller *s);
@@ -35,14 +35,15 @@ struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *s, const char *devic
{
struct rpc_caller *base = &s->rpc_caller;
- base->context = s;
+ rpc_caller_init(base, s);
base->call_begin = call_begin;
base->call_invoke = call_invoke;
base->call_end = call_end;
s->device_path = device_path;
s->fd = -1;
- s->call_ep_id = 0;
+ s->dest_partition_id = 0;
+ s->dest_iface_id = 0;
s->shared_mem_handle = 0;
s->shared_mem_required_size = DEFAULT_SHMEM_BUF_SIZE;
s->req_buf = NULL;
@@ -93,12 +94,12 @@ size_t ffarpc_caller_discover(const struct ffarpc_caller *s, const struct uuid_c
}
}
- return discover_count;
+ return discover_count;
}
-int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id)
+int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t dest_partition_id, uint16_t dest_iface_id)
{
- int ioctl_status = -1;
+ int ioctl_status = -1;
if (s->device_path) {
@@ -110,7 +111,8 @@ int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id)
if (ioctl_status == 0) {
/* Session successfully opened */
- s->call_ep_id = call_ep_id;
+ s->dest_partition_id = dest_partition_id;
+ s->dest_iface_id = dest_iface_id;
ioctl_status = share_mem_with_partition(s);
}
@@ -122,23 +124,23 @@ int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id)
}
}
- return ioctl_status;
+ return ioctl_status;
}
int ffarpc_caller_close(struct ffarpc_caller *s)
{
- int ioctl_status = -1;
+ int ioctl_status = -1;
- if (s->fd >= 0) {
+ if (s->fd >= 0) {
- unshare_mem_with_partition(s);
- ioctl_status = ioctl(s->fd, FFA_IOC_SHM_DEINIT);
- close(s->fd);
- s->fd = -1;
- s->call_ep_id = 0;
- }
+ unshare_mem_with_partition(s);
+ ioctl_status = ioctl(s->fd, FFA_IOC_SHM_DEINIT);
+ close(s->fd);
+ s->fd = -1;
+ s->dest_partition_id = 0;
+ }
- return ioctl_status;
+ return ioctl_status;
}
static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_len)
@@ -146,96 +148,104 @@ static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_l
rpc_call_handle handle = NULL;
struct ffarpc_caller *s = (struct ffarpc_caller*)context;
- if (!s->is_call_transaction_in_progess) {
+ if (!s->is_call_transaction_in_progess) {
- s->is_call_transaction_in_progess = true;
- handle = s;
+ s->is_call_transaction_in_progess = true;
+ handle = s;
- if (req_len > 0) {
+ if (req_len > 0) {
- s->req_buf = malloc(req_len);
+ s->req_buf = malloc(req_len);
- if (s->req_buf) {
+ if (s->req_buf) {
- *req_buf = s->req_buf;
- s->req_len = req_len;
- }
- else {
- /* Failed to allocate req buffer */
- handle = NULL;
- s->is_call_transaction_in_progess = false;
- }
- }
- else {
+ *req_buf = s->req_buf;
+ s->req_len = req_len;
+ }
+ else {
+ /* Failed to allocate req buffer */
+ handle = NULL;
+ s->is_call_transaction_in_progess = false;
+ }
+ }
+ else {
- *req_buf = NULL;
- s->req_buf = NULL;
- s->req_len = req_len;
- }
- }
+ *req_buf = NULL;
+ s->req_buf = NULL;
+ s->req_len = req_len;
+ }
+ }
- return handle;
+ return handle;
}
static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
- int *opstatus, uint8_t **resp_buf, size_t *resp_len)
+ int *opstatus, uint8_t **resp_buf, size_t *resp_len)
{
- rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
+ rpc_status_t rpc_status = TS_RPC_ERROR_INTERNAL;
struct ffarpc_caller *s = (struct ffarpc_caller*)context;
- if ((handle == s) && s->is_call_transaction_in_progess) {
- int kernel_op_status = 0;
-
- if (s->req_len > 0) {
- kernel_op_status = kernel_write_req_buf(s);
- }
-
- if (kernel_op_status == 0) {
- /* Make direct call to send the request */
- struct ffa_ioctl_msg_args direct_msg;
- memset(&direct_msg, 0, sizeof(direct_msg));
-
- direct_msg.dst_id = s->call_ep_id;
- direct_msg.args[FFA_CALL_ARGS_OPCODE] = (uint64_t)opcode;
- direct_msg.args[FFA_CALL_ARGS_REQ_DATA_LEN] = (uint64_t)s->req_len;
-
- kernel_op_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
-
- if (kernel_op_status == 0) {
- /* Send completed normally - ffa return args in msg_args struct */
- s->resp_len = (size_t)direct_msg.args[FFA_CALL_ARGS_RESP_DATA_LEN];
- rpc_status = (int)direct_msg.args[FFA_CALL_ARGS_RESP_RPC_STATUS];
- *opstatus = (int)direct_msg.args[FFA_CALL_ARGS_RESP_OP_STATUS];
-
- if (s->resp_len > 0) {
- s->resp_buf = malloc(s->resp_len);
-
- if (s->resp_buf) {
- kernel_op_status = kernel_read_resp_buf(s);
-
- if (kernel_op_status != 0) {
- /* Failed to read response buffer */
- rpc_status = TS_RPC_ERROR_INTERNAL;
- }
- }
- else {
- /* Failed to allocate response buffer */
- s->resp_len = 0;
- rpc_status = TS_RPC_ERROR_INTERNAL;
- }
- }
- else {
+ if ((handle == s) && s->is_call_transaction_in_progess) {
+ int kernel_op_status = 0;
+
+ if (s->req_len > 0) {
+ kernel_op_status = kernel_write_req_buf(s);
+ }
+
+ if (kernel_op_status == 0) {
+ /* Make direct call to send the request */
+ struct ffa_ioctl_msg_args direct_msg;
+ memset(&direct_msg, 0, sizeof(direct_msg));
+
+ direct_msg.dst_id = s->dest_partition_id;
+ direct_msg.args[FFA_CALL_ARGS_IFACE_ID_OPCODE] =
+ FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(s->dest_partition_id, opcode);
+ direct_msg.args[FFA_CALL_ARGS_REQ_DATA_LEN] = (uint64_t)s->req_len;
+ direct_msg.args[FFA_CALL_ARGS_ENCODING] = s->rpc_caller.encoding;
+
+ /* Initialise the caller ID. Depending on the call path, this may
+ * be overridden by a higher privilege execution level, based on its
+ * perspective of the caller identity.
+ */
+ direct_msg.args[FFA_CALL_ARGS_CALLER_ID] = 0;
+
+ kernel_op_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
+
+ if (kernel_op_status == 0) {
+ /* Send completed normally - ffa return args in msg_args struct */
+ s->resp_len = (size_t)direct_msg.args[FFA_CALL_ARGS_RESP_DATA_LEN];
+ rpc_status = (int)direct_msg.args[FFA_CALL_ARGS_RESP_RPC_STATUS];
+ *opstatus = (int)direct_msg.args[FFA_CALL_ARGS_RESP_OP_STATUS];
+
+ if (s->resp_len > 0) {
+ s->resp_buf = malloc(s->resp_len);
+
+ if (s->resp_buf) {
+ kernel_op_status = kernel_read_resp_buf(s);
+
+ if (kernel_op_status != 0) {
+ /* Failed to read response buffer */
+ rpc_status = TS_RPC_ERROR_INTERNAL;
+ }
+ }
+ else {
+ /* Failed to allocate response buffer */
+ s->resp_len = 0;
+ rpc_status = TS_RPC_ERROR_INTERNAL;
+ }
+ }
+ else {
/* No response parameters */
- s->resp_buf = NULL;
- }
+ s->resp_buf = NULL;
+ }
- *resp_len = s->resp_len;
- *resp_buf = s->resp_buf;
- }
- }
+ *resp_len = s->resp_len;
+ *resp_buf = s->resp_buf;
+ }
+ }
}
- return rpc_status;
+ return rpc_status;
}
static void call_end(void *context, rpc_call_handle handle)
@@ -244,73 +254,75 @@ static void call_end(void *context, rpc_call_handle handle)
if ((handle == s) && s->is_call_transaction_in_progess) {
- /* Call transaction complete so free resource */
- free(s->req_buf);
- s->req_buf = NULL;
- s->req_len = 0;
+ /* Call transaction complete so free resource */
+ free(s->req_buf);
+ s->req_buf = NULL;
+ s->req_len = 0;
- free(s->resp_buf);
- s->resp_buf = NULL;
- s->resp_len = 0;
+ free(s->resp_buf);
+ s->resp_buf = NULL;
+ s->resp_len = 0;
- s->is_call_transaction_in_progess = false;
- }
+ s->is_call_transaction_in_progess = false;
+ }
}
static int kernel_write_req_buf(struct ffarpc_caller *s) {
- int ioctl_status;
- struct ffa_ioctl_buf_desc req_descr;
+ int ioctl_status;
+ struct ffa_ioctl_buf_desc req_descr;
- req_descr.buf_ptr = (uintptr_t)s->req_buf;
- req_descr.buf_len = s->req_len;
- ioctl_status = ioctl(s->fd, FFA_IOC_SHM_WRITE, &req_descr);
+ req_descr.buf_ptr = (uintptr_t)s->req_buf;
+ req_descr.buf_len = s->req_len;
+ ioctl_status = ioctl(s->fd, FFA_IOC_SHM_WRITE, &req_descr);
- return ioctl_status;
+ return ioctl_status;
}
static int kernel_read_resp_buf(struct ffarpc_caller *s) {
- int ioctl_status;
- struct ffa_ioctl_buf_desc resp_descr;
+ int ioctl_status;
+ struct ffa_ioctl_buf_desc resp_descr;
- resp_descr.buf_ptr = (uintptr_t)s->resp_buf;
- resp_descr.buf_len = s->resp_len;
- ioctl_status = ioctl(s->fd, FFA_IOC_SHM_READ, &resp_descr);
+ resp_descr.buf_ptr = (uintptr_t)s->resp_buf;
+ resp_descr.buf_len = s->resp_len;
+ ioctl_status = ioctl(s->fd, FFA_IOC_SHM_READ, &resp_descr);
- return ioctl_status;
+ return ioctl_status;
}
static int share_mem_with_partition(struct ffarpc_caller *s) {
- int ioctl_status;
- struct ffa_ioctl_msg_args direct_msg;
- memset(&direct_msg, 0, sizeof(direct_msg));
+ int ioctl_status;
+ struct ffa_ioctl_msg_args direct_msg;
+ memset(&direct_msg, 0, sizeof(direct_msg));
- direct_msg.dst_id = s->call_ep_id;
- direct_msg.args[FFA_CALL_ARGS_OPCODE] = (uint64_t)FFA_CALL_OPCODE_SHARE_BUF;
- direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = (uint32_t)s->shared_mem_handle;
- direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = (uint32_t)(s->shared_mem_handle >> 32);
- direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_SIZE] = (uint64_t)s->shared_mem_required_size;
+ direct_msg.dst_id = s->dest_partition_id;
+ direct_msg.args[FFA_CALL_ARGS_IFACE_ID_OPCODE] =
+ FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(FFA_CALL_MGMT_IFACE_ID, FFA_CALL_OPCODE_SHARE_BUF);
+ direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = (uint32_t)s->shared_mem_handle;
+ direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = (uint32_t)(s->shared_mem_handle >> 32);
+ direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_SIZE] = (uint64_t)s->shared_mem_required_size;
- ioctl_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
+ ioctl_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
- return ioctl_status;
+ return ioctl_status;
}
static int unshare_mem_with_partition(struct ffarpc_caller *s) {
- int ioctl_status;
- struct ffa_ioctl_msg_args direct_msg;
- memset(&direct_msg, 0, sizeof(direct_msg));
+ int ioctl_status;
+ struct ffa_ioctl_msg_args direct_msg;
+ memset(&direct_msg, 0, sizeof(direct_msg));
- direct_msg.dst_id = s->call_ep_id;
- direct_msg.args[FFA_CALL_ARGS_OPCODE] = (uint64_t)FFA_CALL_OPCODE_UNSHARE_BUF;
- direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = (uint32_t)s->shared_mem_handle;
- direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = (uint32_t)(s->shared_mem_handle >> 32);
+ direct_msg.dst_id = s->dest_partition_id;
+ direct_msg.args[FFA_CALL_ARGS_IFACE_ID_OPCODE] =
+ FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(FFA_CALL_MGMT_IFACE_ID, FFA_CALL_OPCODE_UNSHARE_BUF);
+ direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = (uint32_t)s->shared_mem_handle;
+ direct_msg.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = (uint32_t)(s->shared_mem_handle >> 32);
- ioctl_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
+ ioctl_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
- return ioctl_status;
+ return ioctl_status;
}
diff --git a/components/rpc/ffarpc/caller/linux/ffarpc_caller.h b/components/rpc/ffarpc/caller/linux/ffarpc_caller.h
index 7e846ba92..c81382e6a 100644
--- a/components/rpc/ffarpc/caller/linux/ffarpc_caller.h
+++ b/components/rpc/ffarpc/caller/linux/ffarpc_caller.h
@@ -24,7 +24,8 @@ struct ffarpc_caller {
struct rpc_caller rpc_caller;
int fd;
const char *device_path;
- uint16_t call_ep_id;
+ uint16_t dest_partition_id;
+ uint16_t dest_iface_id;
uint64_t shared_mem_handle;
size_t shared_mem_required_size;
uint8_t *req_buf;
@@ -38,7 +39,7 @@ struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *s, const char *devic
void ffarpc_caller_deinit(struct ffarpc_caller *s);
size_t ffarpc_caller_discover(const struct ffarpc_caller *s, const struct uuid_canonical *uuid,
uint16_t *partition_ids, size_t discover_limit);
-int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id);
+int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t dest_partition_id, uint16_t dest_iface_id);
int ffarpc_caller_close(struct ffarpc_caller *s);
#ifdef __cplusplus
diff --git a/components/rpc/ffarpc/caller/sp/ffarpc_caller.c b/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
index 9d98512af..07a2dcaab 100644
--- a/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
+++ b/components/rpc/ffarpc/caller/sp/ffarpc_caller.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -13,6 +13,7 @@
#include <sp_rxtx.h>
#include <trace.h>
#include <stdbool.h>
+#include <stdint.h>
#include <stdio.h>
uint8_t shared_buffer[4096] __aligned(4096);
@@ -33,6 +34,11 @@ static rpc_call_handle call_begin(void *context, uint8_t **req_buf, size_t req_l
goto out;
}
+ if (req_len > UINT32_MAX) {
+ EMSG("call_begin(): req_len too big");
+ goto out;
+ }
+
this_context->is_call_transaction_in_progess = true;
handle = this_context;
@@ -50,7 +56,7 @@ out:
}
static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t opcode,
- int *opstatus, uint8_t **resp_buf, size_t *resp_len)
+ int *opstatus, uint8_t **resp_buf, size_t *resp_len)
{
struct ffarpc_caller *this_context = (struct ffarpc_caller *)context;
ffa_result res = FFA_OK;
@@ -59,7 +65,7 @@ static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t
rpc_status_t status = TS_RPC_ERROR_INTERNAL;
if (handle != this_context || opstatus == NULL ||
- resp_buf == NULL || resp_len == NULL) {
+ resp_buf == NULL || resp_len == NULL) {
EMSG("call_invoke(): invalid arguments");
status = TS_RPC_ERROR_INVALID_PARAMETER;
goto out;
@@ -71,16 +77,24 @@ static rpc_status_t call_invoke(void *context, rpc_call_handle handle, uint32_t
goto out;
}
- req.destination_id = this_context->call_ep_id;
+ req.destination_id = this_context->dest_partition_id;
req.source_id = own_id;
- req.args[FFA_CALL_ARGS_OPCODE] = opcode;
+ req.args[FFA_CALL_ARGS_IFACE_ID_OPCODE] =
+ FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(this_context->dest_partition_id, opcode);
//TODO: downcast problem?
req.args[FFA_CALL_ARGS_REQ_DATA_LEN] = (uint32_t)this_context->req_len;
+ req.args[FFA_CALL_ARGS_ENCODING] = this_context->rpc_caller.encoding;
+
+ /* Initialise the caller ID. Depending on the call path, this may
+ * be overridden by a higher privilege execution level, based on its
+ * perspective of the caller identity.
+ */
+ req.args[FFA_CALL_ARGS_CALLER_ID] = 0;
res = ffa_msg_send_direct_req(req.source_id, req.destination_id,
- req.args[0], req.args[1],
- req.args[2], req.args[3],
- req.args[4], &resp);
+ req.args[0], req.args[1],
+ req.args[2], req.args[3],
+ req.args[4], &resp);
if (res != FFA_OK) {
EMSG("ffa_msg_send_direct_req(): error %"PRId32, res);
@@ -123,12 +137,13 @@ struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *s)
{
struct rpc_caller *base = &s->rpc_caller;
- base->context = s;
+ rpc_caller_init(base, s);
base->call_begin = call_begin;
base->call_invoke = call_invoke;
base->call_end = call_end;
- s->call_ep_id = 0;
+ s->dest_partition_id = 0;
+ s->dest_iface_id = 0;
s->shared_mem_handle = 0;
s->shared_mem_required_size = sizeof(shared_buffer);
s->req_buf = NULL;
@@ -191,7 +206,7 @@ out:
return sp_cnt;
}
-int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id)
+int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t dest_partition_id, uint16_t dest_iface_id)
{
//TODO: revise return type, error handling
ffa_result ffa_res;
@@ -212,7 +227,7 @@ int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id)
acc_desc.data_access = sp_data_access_read_write;
acc_desc.instruction_access = sp_instruction_access_not_executable;
- acc_desc.receiver_id = call_ep_id;
+ acc_desc.receiver_id = dest_partition_id;
region.address = shared_buffer;
region.page_count = 1;
@@ -224,23 +239,25 @@ int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id)
}
req.source_id = own_id;
- req.destination_id = call_ep_id;
- req.args[FFA_CALL_ARGS_OPCODE] = FFA_CALL_OPCODE_SHARE_BUF;
- req.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = (uint32_t)(handle & 0xffff);
+ req.destination_id = dest_partition_id;
+ req.args[FFA_CALL_ARGS_IFACE_ID_OPCODE] =
+ FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(FFA_CALL_MGMT_IFACE_ID, FFA_CALL_OPCODE_SHARE_BUF);
+ req.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = (uint32_t)(handle & UINT32_MAX);
req.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = (uint32_t)(handle >> 32);
//TODO: downcast
req.args[FFA_CALL_ARGS_SHARE_MEM_SIZE] = (uint32_t)(s->shared_mem_required_size);
ffa_res = ffa_msg_send_direct_req(req.source_id, req.destination_id,
- req.args[0], req.args[1],
- req.args[2], req.args[3],
- req.args[4], &resp);
+ req.args[0], req.args[1],
+ req.args[2], req.args[3],
+ req.args[4], &resp);
if (ffa_res != FFA_OK) {
EMSG("ffa_msg_send_direct_req(): error %"PRId32, ffa_res);
return -1;
}
- s->call_ep_id = call_ep_id;
+ s->dest_partition_id = dest_partition_id;
+ s->dest_iface_id = dest_iface_id;
s->shared_mem_handle = handle;
return 0;
@@ -260,15 +277,16 @@ int ffarpc_caller_close(struct ffarpc_caller *s)
handle_hi = (uint32_t)(s->shared_mem_handle >> 32);
req.source_id = own_id;
- req.destination_id = s->call_ep_id;
- req.args[FFA_CALL_ARGS_OPCODE] = FFA_CALL_OPCODE_UNSHARE_BUF;
+ req.destination_id = s->dest_partition_id;
+ req.args[FFA_CALL_ARGS_IFACE_ID_OPCODE] =
+ FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(FFA_CALL_MGMT_IFACE_ID, FFA_CALL_OPCODE_UNSHARE_BUF);
req.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_LSW] = handle_lo;
req.args[FFA_CALL_ARGS_SHARE_MEM_HANDLE_MSW] = handle_hi;
ffa_res = ffa_msg_send_direct_req(req.source_id, req.destination_id,
- req.args[0], req.args[1],
- req.args[2], req.args[3],
- req.args[4], &resp);
+ req.args[0], req.args[1],
+ req.args[2], req.args[3],
+ req.args[4], &resp);
if (ffa_res != FFA_OK) {
EMSG("ffa_msg_send_direct_req(): error %"PRId32, ffa_res);
return -1;
@@ -280,7 +298,8 @@ int ffarpc_caller_close(struct ffarpc_caller *s)
return -1;
}
- s->call_ep_id = 0;
+ s->dest_partition_id = 0;
+ s->dest_iface_id = 0;
s->shared_mem_handle = 0;
return 0;
diff --git a/components/rpc/ffarpc/caller/sp/ffarpc_caller.h b/components/rpc/ffarpc/caller/sp/ffarpc_caller.h
index ba810e9f3..a6c2fba53 100644
--- a/components/rpc/ffarpc/caller/sp/ffarpc_caller.h
+++ b/components/rpc/ffarpc/caller/sp/ffarpc_caller.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,7 +16,8 @@ extern "C" {
struct ffarpc_caller {
struct rpc_caller rpc_caller;
- uint16_t call_ep_id;
+ uint16_t dest_partition_id;
+ uint16_t dest_iface_id;
uint64_t shared_mem_handle;
size_t shared_mem_required_size;
uint8_t *req_buf;
@@ -29,7 +30,7 @@ struct ffarpc_caller {
struct rpc_caller *ffarpc_caller_init(struct ffarpc_caller *s);
void ffarpc_caller_deinit(struct ffarpc_caller *s);
uint32_t ffarpc_caller_discover(const uint8_t *uuid, uint16_t *sp_ids, uint32_t sp_max_cnt);
-int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t call_ep_id);
+int ffarpc_caller_open(struct ffarpc_caller *s, uint16_t dest_partition_id, uint16_t dest_iface_id);
int ffarpc_caller_close(struct ffarpc_caller *s);
#ifdef __cplusplus
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_args.h b/components/rpc/ffarpc/endpoint/ffarpc_call_args.h
index 402e4f5d3..fbe7320be 100644
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_args.h
+++ b/components/rpc/ffarpc/endpoint/ffarpc_call_args.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,11 +17,21 @@ extern "C" {
* normal world RPC caller and the RPC listener in the SP.
*/
+/* Macros for parameters carried in a single register */
+#define FFA_CALL_ARGS_COMBINE_IFACE_ID_OPCODE(i, o) \
+ (((i) << 16) | ((o) & 0xffff))
+#define FFA_CALL_ARGS_EXTRACT_IFACE(reg) \
+ ((reg) >> 16)
+#define FFA_CALL_ARGS_EXTRACT_OPCODE(reg) \
+ ((reg) & 0xffff)
+
/* Common req & resp arg offests into msg_args structure */
-#define FFA_CALL_ARGS_OPCODE (0)
+#define FFA_CALL_ARGS_IFACE_ID_OPCODE (0)
/* Req arg offsets */
#define FFA_CALL_ARGS_REQ_DATA_LEN (1)
+#define FFA_CALL_ARGS_CALLER_ID (2)
+#define FFA_CALL_ARGS_ENCODING (3)
/* Resp arg offsets */
#define FFA_CALL_ARGS_RESP_DATA_LEN (1)
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
index bb40cf37e..1139e73bc 100644
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
+++ b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,16 +16,16 @@
/* TODO: remove this when own ID will be available in libsp */
extern uint16_t own_id;
-static void set_resp_args(uint32_t *resp_args, uint32_t opcode, uint32_t data_len,
+static void set_resp_args(uint32_t *resp_args, uint32_t ifaceid_opcode, uint32_t data_len,
rpc_status_t rpc_status, uint32_t opstatus)
{
- resp_args[FFA_CALL_ARGS_OPCODE] = opcode;
+ resp_args[FFA_CALL_ARGS_IFACE_ID_OPCODE] = ifaceid_opcode;
resp_args[FFA_CALL_ARGS_RESP_DATA_LEN] = data_len;
resp_args[FFA_CALL_ARGS_RESP_RPC_STATUS] = rpc_status;
resp_args[FFA_CALL_ARGS_RESP_OP_STATUS] = opstatus;
}
-static void set_mgmt_resp_args(uint32_t *resp_args, uint32_t opcode,
+static void set_mgmt_resp_args(uint32_t *resp_args, uint32_t ifaceid_opcode,
rpc_status_t rpc_status)
{
/*
@@ -33,7 +33,7 @@ static void set_mgmt_resp_args(uint32_t *resp_args, uint32_t opcode,
* rather than from a higher layer service. These responses are not
* associated with a shared buffer for any additional message payload.
*/
- set_resp_args(resp_args, opcode, 0, rpc_status, 0);
+ set_resp_args(resp_args, ifaceid_opcode, 0, rpc_status, 0);
}
static void init_shmem_buf(struct ffa_call_ep *call_ep, uint16_t source_id,
@@ -68,7 +68,7 @@ static void init_shmem_buf(struct ffa_call_ep *call_ep, uint16_t source_id,
EMSG("memory retrieve error: %d", sp_res);
}
- set_mgmt_resp_args(resp_args, req_args[FFA_CALL_ARGS_OPCODE], rpc_status);
+ set_mgmt_resp_args(resp_args, req_args[FFA_CALL_ARGS_IFACE_ID_OPCODE], rpc_status);
}
static void deinit_shmem_buf(struct ffa_call_ep *call_ep, const uint32_t *req_args,
@@ -94,7 +94,7 @@ static void deinit_shmem_buf(struct ffa_call_ep *call_ep, const uint32_t *req_ar
EMSG("memory relinquish error: %d", sp_res);
}
- set_mgmt_resp_args(resp_args, req_args[FFA_CALL_ARGS_OPCODE], rpc_status);
+ set_mgmt_resp_args(resp_args, req_args[FFA_CALL_ARGS_IFACE_ID_OPCODE], rpc_status);
}
static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
@@ -103,8 +103,12 @@ static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
rpc_status_t rpc_status;
struct call_req call_req;
+ uint32_t ifaceid_opcode = req_args[FFA_CALL_ARGS_IFACE_ID_OPCODE];
+
call_req.caller_id = source_id;
- call_req.opcode = req_args[FFA_CALL_ARGS_OPCODE];
+ call_req.interface_id = FFA_CALL_ARGS_EXTRACT_IFACE(ifaceid_opcode);
+ call_req.opcode = FFA_CALL_ARGS_EXTRACT_OPCODE(ifaceid_opcode);
+ call_req.encoding = req_args[FFA_CALL_ARGS_ENCODING];
call_req.req_buf.data = call_ep->shmem_buf;
call_req.req_buf.data_len = req_args[FFA_CALL_ARGS_REQ_DATA_LEN];
@@ -114,10 +118,10 @@ static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
call_req.resp_buf.data_len = 0;
call_req.resp_buf.size = call_ep->shmem_buf_size;
- rpc_status = call_ep_receive(call_ep->call_ep, &call_req);
+ rpc_status = rpc_interface_receive(call_ep->iface, &call_req);
set_resp_args(resp_args,
- call_req.opcode,
+ ifaceid_opcode,
call_req.resp_buf.data_len,
rpc_status,
call_req.opstatus);
@@ -126,7 +130,8 @@ static void handle_service_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
static void handle_mgmt_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
const uint32_t *req_args, uint32_t *resp_args)
{
- uint32_t opcode = req_args[FFA_CALL_ARGS_OPCODE];
+ uint32_t ifaceid_opcode = req_args[FFA_CALL_ARGS_IFACE_ID_OPCODE];
+ uint32_t opcode = FFA_CALL_ARGS_EXTRACT_OPCODE(ifaceid_opcode);
/*
* TODO: shouldn't this be used to keep track of multiple
@@ -142,14 +147,14 @@ static void handle_mgmt_msg(struct ffa_call_ep *call_ep, uint16_t source_id,
deinit_shmem_buf(call_ep, req_args, resp_args);
break;
default:
- set_mgmt_resp_args(resp_args, opcode, TS_RPC_ERROR_INVALID_OPCODE);
+ set_mgmt_resp_args(resp_args, ifaceid_opcode, TS_RPC_ERROR_INVALID_OPCODE);
break;
}
}
-void ffa_call_ep_init(struct ffa_call_ep *ffa_call_ep, struct call_ep *call_ep)
+void ffa_call_ep_init(struct ffa_call_ep *ffa_call_ep, struct rpc_interface *iface)
{
- ffa_call_ep->call_ep = call_ep;
+ ffa_call_ep->iface = iface;
ffa_call_ep->shmem_buf_handle = 0;
ffa_call_ep->shmem_buf_size = 0;
ffa_call_ep->shmem_buf = NULL;
@@ -163,9 +168,9 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
uint32_t *resp_args = resp_msg->args;
uint16_t source_id = req_msg->source_id;
- uint32_t opcode = req_args[FFA_CALL_ARGS_OPCODE];
+ uint32_t ifaceid_opcode = req_args[FFA_CALL_ARGS_IFACE_ID_OPCODE];
- if (FFA_CALL_OPCODE_IS_MGMT(opcode)) {
+ if (FFA_CALL_ARGS_EXTRACT_IFACE(ifaceid_opcode) == FFA_CALL_MGMT_IFACE_ID) {
/* It's an RPC layer management request */
handle_mgmt_msg(call_ep, source_id, req_args, resp_args);
} else {
@@ -177,6 +182,6 @@ void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
if (call_ep->shmem_buf)
handle_service_msg(call_ep, source_id, req_args, resp_args);
else
- set_mgmt_resp_args(resp_args, opcode, TS_RPC_ERROR_NOT_READY);
+ set_mgmt_resp_args(resp_args, ifaceid_opcode, TS_RPC_ERROR_NOT_READY);
}
}
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.h b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.h
index b4bcdd6f2..cc67f6ed9 100644
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ep.h
+++ b/components/rpc/ffarpc/endpoint/ffarpc_call_ep.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,7 +8,7 @@
#define FFA_CALL_EP_H
#include <ffa_api.h>
-#include <components/rpc/common/endpoint/call_ep.h>
+#include <components/rpc/common/endpoint/rpc_interface.h>
#include <stddef.h>
#include <stdint.h>
@@ -17,13 +17,13 @@ extern "C" {
#endif
struct ffa_call_ep {
- struct call_ep *call_ep;
+ struct rpc_interface *iface;
unsigned long shmem_buf_handle;
volatile uint8_t *shmem_buf;
size_t shmem_buf_size;
};
-void ffa_call_ep_init(struct ffa_call_ep *ffa_call_ep, struct call_ep *call_ep);
+void ffa_call_ep_init(struct ffa_call_ep *ffa_call_ep, struct rpc_interface *iface);
void ffa_call_ep_receive(struct ffa_call_ep *call_ep,
const struct ffa_direct_msg *req_msg,
struct ffa_direct_msg *resp_msg);
diff --git a/components/rpc/ffarpc/endpoint/ffarpc_call_ops.h b/components/rpc/ffarpc/endpoint/ffarpc_call_ops.h
index 3f14fc7d3..de22678e6 100644
--- a/components/rpc/ffarpc/endpoint/ffarpc_call_ops.h
+++ b/components/rpc/ffarpc/endpoint/ffarpc_call_ops.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -12,13 +12,15 @@ extern "C" {
#endif
/* Common opcodes used by the FFA based RPC layer for management operations */
-#define FFA_CALL_OPCODE_BASE (0x10)
-#define FFA_CALL_OPCODE_SHARE_BUF (FFA_CALL_OPCODE_BASE + 0)
-#define FFA_CALL_OPCODE_UNSHARE_BUF (FFA_CALL_OPCODE_BASE + 1)
-#define FFA_CALL_OPCODE_LIMIT (FFA_CALL_OPCODE_BASE + 2)
+enum
+{
+ FFA_CALL_OPCODE_SHARE_BUF = 0,
+ FFA_CALL_OPCODE_UNSHARE_BUF = 1,
+ FFA_CALL_OPCODE_LIMIT
+};
-#define FFA_CALL_OPCODE_IS_MGMT(opcode) \
- ((opcode >= FFA_CALL_OPCODE_BASE) && (opcode < FFA_CALL_OPCODE_LIMIT))
+/* Interface ID for FFA management interface */
+#define FFA_CALL_MGMT_IFACE_ID (0x1000)
#ifdef __cplusplus
}