@@ -12,6 +12,7 @@
#include <xen/errno.h>
#include <xen/init.h>
#include <xen/lib.h>
+#include <xen/mm.h>
#include <xen/sched.h>
#include <xen/sizes.h>
#include <xen/types.h>
@@ -67,6 +68,12 @@
*/
#define FFA_PAGE_SIZE SZ_4K
+/*
+ * The number of pages used for each of the RX and TX buffers shared with
+ * the SPMC.
+ */
+#define FFA_RXTX_PAGE_COUNT 1
+
/*
* Flags and field values used for the MSG_SEND_DIRECT_REQ/RESP:
* BIT(31): Framework or partition message
@@ -161,6 +168,13 @@ struct ffa_ctx {
/* Negotiated FF-A version to use with the SPMC */
static uint32_t ffa_version __ro_after_init;
+/*
+ * Our rx/tx buffers shared with the SPMC. FFA_RXTX_PAGE_COUNT is the
+ * number of pages used in each of these buffers.
+ */
+static void *ffa_rx __read_mostly;
+static void *ffa_tx __read_mostly;
+
static bool ffa_get_version(uint32_t *vers)
{
const struct arm_smccc_1_2_regs arg = {
@@ -231,6 +245,12 @@ static bool check_mandatory_feature(uint32_t id)
return !ret;
}
+static int32_t ffa_rxtx_map(paddr_t tx_addr, paddr_t rx_addr,
+ uint32_t page_count)
+{
+ return ffa_simple_call(FFA_RXTX_MAP_64, tx_addr, rx_addr, page_count, 0);
+}
+
static uint16_t get_vm_id(const struct domain *d)
{
/* +1 since 0 is reserved for the hypervisor in FF-A */
@@ -389,6 +409,7 @@ static int ffa_relinquish_resources(struct domain *d)
static bool ffa_probe(void)
{
uint32_t vers;
+ int e;
unsigned int major_vers;
unsigned int minor_vers;
@@ -435,12 +456,39 @@ static bool ffa_probe(void)
* TODO save result of checked features and use that information to
* accept or reject requests from guests.
*/
- if ( !check_mandatory_feature(FFA_MSG_SEND_DIRECT_REQ_32) )
+ if (
+ !check_mandatory_feature(FFA_RXTX_MAP_64) ||
+ !check_mandatory_feature(FFA_RXTX_UNMAP) ||
+ !check_mandatory_feature(FFA_MSG_SEND_DIRECT_REQ_32) )
+ return false;
+
+ ffa_rx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), 0);
+ if ( !ffa_rx )
return false;
+ ffa_tx = alloc_xenheap_pages(get_order_from_pages(FFA_RXTX_PAGE_COUNT), 0);
+ if ( !ffa_tx )
+ goto err_free_ffa_rx;
+
+ e = ffa_rxtx_map(__pa(ffa_tx), __pa(ffa_rx), FFA_RXTX_PAGE_COUNT);
+ if ( e )
+ {
+ printk(XENLOG_ERR "ffa: Failed to map rxtx: error %d\n", e);
+ goto err_free_ffa_tx;
+ }
ffa_version = vers;
return true;
+
+err_free_ffa_tx:
+ free_xenheap_pages(ffa_tx, 0);
+ ffa_tx = NULL;
+err_free_ffa_rx:
+ free_xenheap_pages(ffa_rx, 0);
+ ffa_rx = NULL;
+ ffa_version = 0;
+
+ return false;
}
static const struct tee_mediator_ops ffa_ops =
When initializing the FF-A mediator map the RX and TX buffers shared with the SPMC. These buffer are later used to to transmit data that cannot be passed in registers only. Adds a check that the SP supports the needed FF-A features FFA_RXTX_MAP_64 and FFA_RXTX_UNMAP. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> --- xen/arch/arm/tee/ffa.c | 50 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)