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
diff --git a/components/rpc/common/caller/rpc_caller.c b/components/rpc/common/caller/rpc_caller.c
index 4fd1e5a..00b559c 100644
--- a/components/rpc/common/caller/rpc_caller.c
+++ b/components/rpc/common/caller/rpc_caller.c
@@ -1,11 +1,25 @@
 /*
- * 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
  */
 
 #include <rpc_caller.h>
 #include <stdint.h>
+#include <protocols/rpc/common/packed-c/encoding.h>
+
+void rpc_caller_init(struct rpc_caller *s, void *context)
+{
+	s->context = context;
+
+	/* The default encoding scheme - may be overridden by a client */
+	s->encoding = TS_RPC_ENCODING_PACKED_C;
+}
+
+void rpc_caller_set_encoding_scheme(struct rpc_caller *s, uint32_t encoding)
+{
+	s->encoding = encoding;
+}
 
 rpc_call_handle rpc_caller_begin(struct rpc_caller *s,
 								uint8_t **req_buf, size_t req_len)
diff --git a/components/rpc/common/endpoint/call_ep.h b/components/rpc/common/endpoint/rpc_interface.h
similarity index 65%
rename from components/rpc/common/endpoint/call_ep.h
rename to components/rpc/common/endpoint/rpc_interface.h
index 1b5d03d..44e5783 100644
--- a/components/rpc/common/endpoint/call_ep.h
+++ b/components/rpc/common/endpoint/rpc_interface.h
@@ -1,11 +1,11 @@
 /*
- * 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
  */
 
-#ifndef CALL_EP_H
-#define CALL_EP_H
+#ifndef RPC_INTERFACE_H
+#define RPC_INTERFACE_H
 
 #include <stddef.h>
 #include <stdint.h>
@@ -51,16 +51,6 @@
 	return v;
 }
 
-/** \brief Serializer for handling call parameters
- *
- * An abstract serializer pointer, used for attaching a concrete
- * serializer to a call request for serializing/deserializing call
- * parameters.  The strategy for selecting an appropriate serializer
- * could be hard-coded or dynamic, based on a content type identifier
- * carried by a concrete rpc.
- */
-typedef const void* call_param_serializer_ptr;
-
 /** \brief Call request
  *
  * A call request object represents a request from a client that will
@@ -68,9 +58,10 @@
  */
 struct call_req {
 	uint32_t caller_id;
+	uint32_t interface_id;
 	uint32_t opcode;
+	uint32_t encoding;
 	int opstatus;
-	call_param_serializer_ptr serializer;
 	struct call_param_buf req_buf;
 	struct call_param_buf resp_buf;
 };
@@ -80,11 +71,21 @@
 	return req->caller_id;
 }
 
+static inline uint32_t call_req_get_interface_id(const struct call_req *req)
+{
+	return req->interface_id;
+}
+
 static inline uint32_t call_req_get_opcode(const struct call_req *req)
 {
 	return req->opcode;
 }
 
+static inline uint32_t call_req_get_encoding(const struct call_req *req)
+{
+	return req->encoding;
+}
+
 static inline int call_req_get_opstatus(const struct call_req *req)
 {
 	return req->opstatus;
@@ -95,11 +96,6 @@
 	req->opstatus = opstatus;
 }
 
-static inline call_param_serializer_ptr call_req_get_serializer(const struct call_req *req)
-{
-    return req->serializer;
-}
-
 static inline struct call_param_buf *call_req_get_req_buf(struct call_req *req)
 {
 	return &req->req_buf;
@@ -110,25 +106,25 @@
 	return &req->resp_buf;
 }
 
-/** \brief Call endpoint
+/** \brief RPC interface
  *
- * A generalized call endpoint.  Provides a standard interface for a
+ * A generalized RPC interface.  Provides a standard interface for a
  * call endpoint that handles incoming call requests.
  */
-struct call_ep
+struct rpc_interface
 {
 	void *context;
-	rpc_status_t (*receive)(struct call_ep *ep, struct call_req *req);
+	rpc_status_t (*receive)(struct rpc_interface *iface, struct call_req *req);
 };
 
-static inline rpc_status_t call_ep_receive(struct call_ep *ep,
+static inline rpc_status_t rpc_interface_receive(struct rpc_interface *iface,
 					  struct call_req *req)
 {
-	return ep->receive(ep, req);
+	return iface->receive(iface, req);
 }
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* CALL_EP_H */
+#endif /* RPC_INTERFACE_H */
diff --git a/components/rpc/common/interface/rpc_caller.h b/components/rpc/common/interface/rpc_caller.h
index a75bdd9..879d2cb 100644
--- a/components/rpc/common/interface/rpc_caller.h
+++ b/components/rpc/common/interface/rpc_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
  */
@@ -36,6 +36,7 @@
 struct rpc_caller
 {
 	void *context;
+	uint32_t encoding;
 
 	/* A concrete rpc_caller implements these methods */
 	rpc_call_handle (*call_begin)(void *context, uint8_t **req_buf, size_t req_len);
@@ -47,6 +48,19 @@
 };
 
 /*
+ * Called by a concrete rpc_caller to initialise the base rpc_caller.
+ */
+void rpc_caller_init(struct rpc_caller *s, void *context);
+
+/*
+ * Allows a client to specify the parameter encoding scheme that the client
+ * intends to use during an RPC session.  It is the client's responsiblity
+ * to choose an encoding scheme that is supported by the remote interface.
+ */
+RPC_CALLER_EXPORTED void rpc_caller_set_encoding_scheme(struct rpc_caller *s,
+			uint32_t encoding);
+
+/*
  * Starts a call transaction. The returned handle is an identifier for the
  * transaction and must be passed as a parameter to call_invoke() and
  * call_end(). A concrete rpc_caller may perform resource allocation during
diff --git a/components/rpc/direct/direct_caller.c b/components/rpc/direct/direct_caller.c
index 001ee7c..14f1a91 100644
--- a/components/rpc/direct/direct_caller.c
+++ b/components/rpc/direct/direct_caller.c
@@ -1,11 +1,11 @@
 /*
- * 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
  */
 
 #include "direct_caller.h"
-#include <rpc/common/endpoint/call_ep.h>
+#include <rpc/common/endpoint/rpc_interface.h>
 #include <protocols/rpc/common/packed-c/status.h>
 #include <stdlib.h>
 
@@ -18,17 +18,17 @@
 static void call_end(void *context, rpc_call_handle handle);
 
 
-struct rpc_caller *direct_caller_init(struct direct_caller *s, struct call_ep *ep,
+struct rpc_caller *direct_caller_init(struct direct_caller *s, struct rpc_interface *iface,
                         size_t req_buf_size, size_t resp_buf_size)
 {
     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 = ep;
+    s->rpc_interface = iface;
     s->caller_id = 0;
     s->is_call_transaction_in_progess = false;
     s->req_len = 0;
@@ -47,10 +47,10 @@
     return base;
 }
 
-struct rpc_caller *direct_caller_init_default(struct direct_caller *s, struct call_ep *ep)
+struct rpc_caller *direct_caller_init_default(struct direct_caller *s, struct rpc_interface *iface)
 {
     /* Initialise with default buffer sizes */
-    return direct_caller_init(s, ep,
+    return direct_caller_init(s, iface,
         DIRECT_CALLER_DEFAULT_REQ_BUF_SIZE,
         DIRECT_CALLER_DEFAULT_RESP_BUF_SIZE);
 }
@@ -94,7 +94,9 @@
 
         struct call_req req;
 
+        req.interface_id = 0;
         req.opcode = opcode;
+        req.encoding = this_context->rpc_caller.encoding;
         req.caller_id = this_context->caller_id;
         req.opstatus = 0;
         req.req_buf = call_param_buf_init_full(this_context->req_buf,
@@ -102,7 +104,7 @@
         req.resp_buf = call_param_buf_init_empty(this_context->resp_buf,
                             this_context->resp_buf_size);
 
-        status = call_ep_receive(this_context->call_ep, &req);
+        status = rpc_interface_receive(this_context->rpc_interface, &req);
 
         *resp_buf = this_context->resp_buf;
         *resp_len = call_req_get_resp_buf(&req)->data_len;
diff --git a/components/rpc/direct/direct_caller.h b/components/rpc/direct/direct_caller.h
index 0f51845..fe5ac08 100644
--- a/components/rpc/direct/direct_caller.h
+++ b/components/rpc/direct/direct_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,7 @@
 extern "C" {
 #endif
 
-struct call_ep;
+struct rpc_interface;
 
 /** An rpc_caller that calls methods associated with a specific endpoint
  *  directly.  Used when the caller and endpoint are running in the same
@@ -25,7 +25,7 @@
 struct direct_caller
 {
     struct rpc_caller rpc_caller;
-    struct call_ep *call_ep;
+    struct rpc_interface *rpc_interface;
     uint32_t caller_id;
     bool is_call_transaction_in_progess;
     size_t req_len;
@@ -35,10 +35,10 @@
     uint8_t *resp_buf;
 };
 
-struct rpc_caller *direct_caller_init(struct direct_caller *s, struct call_ep *ep,
+struct rpc_caller *direct_caller_init(struct direct_caller *s, struct rpc_interface *iface,
                         size_t req_buf_size, size_t resp_buf_size);
 
-struct rpc_caller *direct_caller_init_default(struct direct_caller *s, struct call_ep *ep);
+struct rpc_caller *direct_caller_init_default(struct direct_caller *s, struct rpc_interface *iface);
 
 void direct_caller_deinit(struct direct_caller *s);
 
diff --git a/components/rpc/dummy/dummy_caller.c b/components/rpc/dummy/dummy_caller.c
index 6d40b80..f55b418 100644
--- a/components/rpc/dummy/dummy_caller.c
+++ b/components/rpc/dummy/dummy_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
  */
@@ -18,7 +18,7 @@
 {
     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;
diff --git a/components/rpc/dummy/dummy_caller.h b/components/rpc/dummy/dummy_caller.h
index 215d293..27fe68a 100644
--- a/components/rpc/dummy/dummy_caller.h
+++ b/components/rpc/dummy/dummy_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
  */
diff --git a/components/rpc/ffarpc/caller/linux/ffarpc_caller.c b/components/rpc/ffarpc/caller/linux/ffarpc_caller.c
index 70d6ca3..ac628a9 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 *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 @@
 		}
 	}
 
-    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 @@
 
 			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 @@
 		}
 	}
 
-    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 @@
 	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 ((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 (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));
+		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;
+			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;
 
-            kernel_op_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
+			/* 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;
 
-            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];
+			kernel_op_status = ioctl(s->fd, FFA_IOC_MSG_SEND, &direct_msg);
 
-                if (s->resp_len > 0) {
-                    s->resp_buf = malloc(s->resp_len);
+			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_buf) {
-                        kernel_op_status = kernel_read_resp_buf(s);
+				if (s->resp_len > 0) {
+					s->resp_buf = malloc(s->resp_len);
 
-                        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 (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 @@
 
 	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 7e846ba..c81382e 100644
--- a/components/rpc/ffarpc/caller/linux/ffarpc_caller.h
+++ b/components/rpc/ffarpc/caller/linux/ffarpc_caller.h
@@ -24,7 +24,8 @@
 	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 @@
 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 9d98512..07a2dca 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 @@
 		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 @@
 }
 
 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 @@
 	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 @@
 		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 *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 @@
 	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 @@
 
 	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 @@
 	}
 
 	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 @@
 	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 @@
 		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 ba810e9..a6c2fba 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 @@
 
 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 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 402e4f5..fbe7320 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 @@
  * 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 bb40cf3..1139e73 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 @@
 	 * 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 @@
 		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 @@
 		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 @@
 	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 @@
 	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_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 @@
 		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 @@
 	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 @@
 		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 b4bcdd6..cc67f6e 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 @@
 #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 3f14fc7..de22678 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 @@
 #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
 }