mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: ffa: move common things to ffa_private.h
Prepare to separate ffa.c into modules by moving common things into the new internal header file ffa_private.h. Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Bertrand Marquis <bertrand.marquis@arm.com>
This commit is contained in:
1 parent
b21cbaf6ba
commit
bb584ec036
2 files changed
+319
-297
No files matched your search
+1
-297
@@ -63,204 +63,7 @@
|
||||
#include <asm/tee/ffa.h>
|
||||
#include <asm/tee/tee.h>
|
||||
|
||||
/* Error codes */
|
||||
#define FFA_RET_OK 0
|
||||
#define FFA_RET_NOT_SUPPORTED -1
|
||||
#define FFA_RET_INVALID_PARAMETERS -2
|
||||
#define FFA_RET_NO_MEMORY -3
|
||||
#define FFA_RET_BUSY -4
|
||||
#define FFA_RET_INTERRUPTED -5
|
||||
#define FFA_RET_DENIED -6
|
||||
#define FFA_RET_RETRY -7
|
||||
#define FFA_RET_ABORTED -8
|
||||
|
||||
/* FFA_VERSION helpers */
|
||||
#define FFA_VERSION_MAJOR_SHIFT 16U
|
||||
#define FFA_VERSION_MAJOR_MASK 0x7FFFU
|
||||
#define FFA_VERSION_MINOR_SHIFT 0U
|
||||
#define FFA_VERSION_MINOR_MASK 0xFFFFU
|
||||
#define MAKE_FFA_VERSION(major, minor) \
|
||||
((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \
|
||||
((minor) & FFA_VERSION_MINOR_MASK))
|
||||
|
||||
#define FFA_VERSION_1_0 MAKE_FFA_VERSION(1, 0)
|
||||
#define FFA_VERSION_1_1 MAKE_FFA_VERSION(1, 1)
|
||||
/* The minimal FF-A version of the SPMC that can be supported */
|
||||
#define FFA_MIN_SPMC_VERSION FFA_VERSION_1_1
|
||||
|
||||
/*
|
||||
* This is the version we want to use in communication with guests and SPs.
|
||||
* During negotiation with a guest or a SP we may need to lower it for
|
||||
* that particular guest or SP.
|
||||
*/
|
||||
#define FFA_MY_VERSION_MAJOR 1U
|
||||
#define FFA_MY_VERSION_MINOR 1U
|
||||
#define FFA_MY_VERSION MAKE_FFA_VERSION(FFA_MY_VERSION_MAJOR, \
|
||||
FFA_MY_VERSION_MINOR)
|
||||
|
||||
/*
|
||||
* The FF-A specification explicitly works with 4K pages as a measure of
|
||||
* memory size, for example, FFA_RXTX_MAP takes one parameter "RX/TX page
|
||||
* count" which is the number of contiguous 4K pages allocated. Xen may use
|
||||
* a different page size depending on the configuration to avoid confusion
|
||||
* with PAGE_SIZE use a special define when it's a page size as in the FF-A
|
||||
* specification.
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
* Limit the number of pages RX/TX buffers guests can map.
|
||||
* TODO support a larger number.
|
||||
*/
|
||||
#define FFA_MAX_RXTX_PAGE_COUNT 1
|
||||
|
||||
/*
|
||||
* Limit for shared buffer size. Please note that this define limits
|
||||
* number of pages.
|
||||
*
|
||||
* FF-A doesn't have any direct requirements on GlobalPlatform or vice
|
||||
* versa, but an implementation can very well use FF-A in order to provide
|
||||
* a GlobalPlatform interface on top.
|
||||
*
|
||||
* Global Platform specification for TEE requires that any TEE
|
||||
* implementation should allow to share buffers with size of at least
|
||||
* 512KB, defined in TEEC-1.0C page 24, Table 4-1,
|
||||
* TEEC_CONFIG_SHAREDMEM_MAX_SIZE.
|
||||
* Due to overhead which can be hard to predict exactly, double this number
|
||||
* to give a safe margin.
|
||||
*/
|
||||
#define FFA_MAX_SHM_PAGE_COUNT (2 * SZ_512K / FFA_PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* Limits the number of shared buffers that guest can have at once. This
|
||||
* is to prevent case, when guests trick XEN into exhausting its own
|
||||
* memory by allocating many small buffers. This value has been chosen
|
||||
* arbitrarily.
|
||||
*/
|
||||
#define FFA_MAX_SHM_COUNT 32
|
||||
|
||||
/*
|
||||
* The time we wait until trying to tear down a domain again if it was
|
||||
* blocked initially.
|
||||
*/
|
||||
#define FFA_CTX_TEARDOWN_DELAY SECONDS(1)
|
||||
|
||||
/* FF-A-1.1-REL0 section 10.9.2 Memory region handle, page 167 */
|
||||
#define FFA_HANDLE_HYP_FLAG BIT(63, ULL)
|
||||
#define FFA_HANDLE_INVALID 0xffffffffffffffffULL
|
||||
|
||||
/*
|
||||
* Memory attributes: Normal memory, Write-Back cacheable, Inner shareable
|
||||
* Defined in FF-A-1.1-REL0 Table 10.18 at page 175.
|
||||
*/
|
||||
#define FFA_NORMAL_MEM_REG_ATTR 0x2fU
|
||||
/*
|
||||
* Memory access permissions: Read-write
|
||||
* Defined in FF-A-1.1-REL0 Table 10.15 at page 168.
|
||||
*/
|
||||
#define FFA_MEM_ACC_RW 0x2U
|
||||
|
||||
/* FF-A-1.1-REL0 section 10.11.4 Flags usage, page 184-187 */
|
||||
/* Clear memory before mapping in receiver */
|
||||
#define FFA_MEMORY_REGION_FLAG_CLEAR BIT(0, U)
|
||||
/* Relayer may time slice this operation */
|
||||
#define FFA_MEMORY_REGION_FLAG_TIME_SLICE BIT(1, U)
|
||||
/* Clear memory after receiver relinquishes it */
|
||||
#define FFA_MEMORY_REGION_FLAG_CLEAR_RELINQUISH BIT(2, U)
|
||||
/* Share memory transaction */
|
||||
#define FFA_MEMORY_REGION_TRANSACTION_TYPE_SHARE (1U << 3)
|
||||
|
||||
/*
|
||||
* Flags and field values used for the MSG_SEND_DIRECT_REQ/RESP:
|
||||
* BIT(31): Framework or partition message
|
||||
* BIT(7-0): Message type for frameworks messages
|
||||
*/
|
||||
#define FFA_MSG_FLAG_FRAMEWORK BIT(31, U)
|
||||
#define FFA_MSG_TYPE_MASK 0xFFU;
|
||||
#define FFA_MSG_PSCI 0x0U
|
||||
#define FFA_MSG_SEND_VM_CREATED 0x4U
|
||||
#define FFA_MSG_RESP_VM_CREATED 0x5U
|
||||
#define FFA_MSG_SEND_VM_DESTROYED 0x6U
|
||||
#define FFA_MSG_RESP_VM_DESTROYED 0x7U
|
||||
|
||||
/*
|
||||
* Flags to determine partition properties in FFA_PARTITION_INFO_GET return
|
||||
* message:
|
||||
* BIT(0): Supports receipt of direct requests
|
||||
* BIT(1): Can send direct requests
|
||||
* BIT(2): Can send and receive indirect messages
|
||||
* BIT(3): Supports receipt of notifications
|
||||
* BIT(4-5): Partition ID is a PE endpoint ID
|
||||
* BIT(6): Partition must be informed about each VM that is created by
|
||||
* the Hypervisor
|
||||
* BIT(7): Partition must be informed about each VM that is destroyed by
|
||||
* the Hypervisor
|
||||
* BIT(8): Partition runs in the AArch64 execution state else AArch32
|
||||
* execution state
|
||||
*/
|
||||
#define FFA_PART_PROP_DIRECT_REQ_RECV BIT(0, U)
|
||||
#define FFA_PART_PROP_DIRECT_REQ_SEND BIT(1, U)
|
||||
#define FFA_PART_PROP_INDIRECT_MSGS BIT(2, U)
|
||||
#define FFA_PART_PROP_RECV_NOTIF BIT(3, U)
|
||||
#define FFA_PART_PROP_IS_TYPE_MASK (3U << 4)
|
||||
#define FFA_PART_PROP_IS_PE_ID (0U << 4)
|
||||
#define FFA_PART_PROP_IS_SEPID_INDEP (1U << 4)
|
||||
#define FFA_PART_PROP_IS_SEPID_DEP (2U << 4)
|
||||
#define FFA_PART_PROP_IS_AUX_ID (3U << 4)
|
||||
#define FFA_PART_PROP_NOTIF_CREATED BIT(6, U)
|
||||
#define FFA_PART_PROP_NOTIF_DESTROYED BIT(7, U)
|
||||
#define FFA_PART_PROP_AARCH64_STATE BIT(8, U)
|
||||
|
||||
/*
|
||||
* Flag used as parameter to FFA_PARTITION_INFO_GET to return partition
|
||||
* count only.
|
||||
*/
|
||||
#define FFA_PARTITION_INFO_GET_COUNT_FLAG BIT(0, U)
|
||||
|
||||
/* Function IDs */
|
||||
#define FFA_ERROR 0x84000060U
|
||||
#define FFA_SUCCESS_32 0x84000061U
|
||||
#define FFA_SUCCESS_64 0xC4000061U
|
||||
#define FFA_INTERRUPT 0x84000062U
|
||||
#define FFA_VERSION 0x84000063U
|
||||
#define FFA_FEATURES 0x84000064U
|
||||
#define FFA_RX_ACQUIRE 0x84000084U
|
||||
#define FFA_RX_RELEASE 0x84000065U
|
||||
#define FFA_RXTX_MAP_32 0x84000066U
|
||||
#define FFA_RXTX_MAP_64 0xC4000066U
|
||||
#define FFA_RXTX_UNMAP 0x84000067U
|
||||
#define FFA_PARTITION_INFO_GET 0x84000068U
|
||||
#define FFA_ID_GET 0x84000069U
|
||||
#define FFA_SPM_ID_GET 0x84000085U
|
||||
#define FFA_MSG_WAIT 0x8400006BU
|
||||
#define FFA_MSG_YIELD 0x8400006CU
|
||||
#define FFA_RUN 0x8400006DU
|
||||
#define FFA_MSG_SEND2 0x84000086U
|
||||
#define FFA_MSG_SEND_DIRECT_REQ_32 0x8400006FU
|
||||
#define FFA_MSG_SEND_DIRECT_REQ_64 0xC400006FU
|
||||
#define FFA_MSG_SEND_DIRECT_RESP_32 0x84000070U
|
||||
#define FFA_MSG_SEND_DIRECT_RESP_64 0xC4000070U
|
||||
#define FFA_MEM_DONATE_32 0x84000071U
|
||||
#define FFA_MEM_DONATE_64 0xC4000071U
|
||||
#define FFA_MEM_LEND_32 0x84000072U
|
||||
#define FFA_MEM_LEND_64 0xC4000072U
|
||||
#define FFA_MEM_SHARE_32 0x84000073U
|
||||
#define FFA_MEM_SHARE_64 0xC4000073U
|
||||
#define FFA_MEM_RETRIEVE_REQ_32 0x84000074U
|
||||
#define FFA_MEM_RETRIEVE_REQ_64 0xC4000074U
|
||||
#define FFA_MEM_RETRIEVE_RESP 0x84000075U
|
||||
#define FFA_MEM_RELINQUISH 0x84000076U
|
||||
#define FFA_MEM_RECLAIM 0x84000077U
|
||||
#define FFA_MEM_FRAG_RX 0x8400007AU
|
||||
#define FFA_MEM_FRAG_TX 0x8400007BU
|
||||
#define FFA_MSG_SEND 0x8400006EU
|
||||
#define FFA_MSG_POLL 0x8400006AU
|
||||
#include "ffa_private.h"
|
||||
|
||||
/*
|
||||
* Structs below ending with _1_0 are defined in FF-A-1.0-REL and
|
||||
@@ -382,39 +185,6 @@ struct ffa_endpoint_rxtx_descriptor_1_1 {
|
||||
uint32_t tx_region_offs;
|
||||
};
|
||||
|
||||
struct ffa_ctx {
|
||||
void *rx;
|
||||
const void *tx;
|
||||
struct page_info *rx_pg;
|
||||
struct page_info *tx_pg;
|
||||
/* Number of 4kB pages in each of rx/rx_pg and tx/tx_pg */
|
||||
unsigned int page_count;
|
||||
/* FF-A version used by the guest */
|
||||
uint32_t guest_vers;
|
||||
bool rx_is_free;
|
||||
/* Used shared memory objects, struct ffa_shm_mem */
|
||||
struct list_head shm_list;
|
||||
/* Number of allocated shared memory object */
|
||||
unsigned int shm_count;
|
||||
/*
|
||||
* tx_lock is used to serialize access to tx
|
||||
* rx_lock is used to serialize access to rx
|
||||
* lock is used for the rest in this struct
|
||||
*/
|
||||
spinlock_t tx_lock;
|
||||
spinlock_t rx_lock;
|
||||
spinlock_t lock;
|
||||
/* Used if domain can't be torn down immediately */
|
||||
struct domain *teardown_d;
|
||||
struct list_head teardown_list;
|
||||
s_time_t teardown_expire;
|
||||
/*
|
||||
* Used for ffa_domain_teardown() to keep track of which SPs should be
|
||||
* notified that this guest is being destroyed.
|
||||
*/
|
||||
unsigned long vm_destroy_bitmap[];
|
||||
};
|
||||
|
||||
struct ffa_shm_mem {
|
||||
struct list_head list;
|
||||
uint16_t sender_id;
|
||||
@@ -473,40 +243,6 @@ static bool ffa_get_version(uint32_t *vers)
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t ffa_get_ret_code(const struct arm_smccc_1_2_regs *resp)
|
||||
{
|
||||
switch ( resp->a0 )
|
||||
{
|
||||
case FFA_ERROR:
|
||||
if ( resp->a2 )
|
||||
return resp->a2;
|
||||
else
|
||||
return FFA_RET_NOT_SUPPORTED;
|
||||
case FFA_SUCCESS_32:
|
||||
case FFA_SUCCESS_64:
|
||||
return FFA_RET_OK;
|
||||
default:
|
||||
return FFA_RET_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t ffa_simple_call(uint32_t fid, register_t a1, register_t a2,
|
||||
register_t a3, register_t a4)
|
||||
{
|
||||
const struct arm_smccc_1_2_regs arg = {
|
||||
.a0 = fid,
|
||||
.a1 = a1,
|
||||
.a2 = a2,
|
||||
.a3 = a3,
|
||||
.a4 = a4,
|
||||
};
|
||||
struct arm_smccc_1_2_regs resp;
|
||||
|
||||
arm_smccc_1_2_smc(&arg, &resp);
|
||||
|
||||
return ffa_get_ret_code(&resp);
|
||||
}
|
||||
|
||||
static int32_t ffa_features(uint32_t id)
|
||||
{
|
||||
return ffa_simple_call(FFA_FEATURES, id, 0, 0, 0);
|
||||
@@ -654,38 +390,6 @@ static int32_t ffa_direct_req_send_vm(uint16_t sp_id, uint16_t vm_id,
|
||||
return res;
|
||||
}
|
||||
|
||||
static uint16_t ffa_get_vm_id(const struct domain *d)
|
||||
{
|
||||
/* +1 since 0 is reserved for the hypervisor in FF-A */
|
||||
return d->domain_id + 1;
|
||||
}
|
||||
|
||||
static void ffa_set_regs(struct cpu_user_regs *regs, register_t v0,
|
||||
register_t v1, register_t v2, register_t v3,
|
||||
register_t v4, register_t v5, register_t v6,
|
||||
register_t v7)
|
||||
{
|
||||
set_user_reg(regs, 0, v0);
|
||||
set_user_reg(regs, 1, v1);
|
||||
set_user_reg(regs, 2, v2);
|
||||
set_user_reg(regs, 3, v3);
|
||||
set_user_reg(regs, 4, v4);
|
||||
set_user_reg(regs, 5, v5);
|
||||
set_user_reg(regs, 6, v6);
|
||||
set_user_reg(regs, 7, v7);
|
||||
}
|
||||
|
||||
static void ffa_set_regs_error(struct cpu_user_regs *regs, uint32_t error_code)
|
||||
{
|
||||
ffa_set_regs(regs, FFA_ERROR, 0, error_code, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void ffa_set_regs_success(struct cpu_user_regs *regs, uint32_t w2,
|
||||
uint32_t w3)
|
||||
{
|
||||
ffa_set_regs(regs, FFA_SUCCESS_32, 0, w2, w3, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static void handle_version(struct cpu_user_regs *regs)
|
||||
{
|
||||
struct domain *d = current->domain;
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (C) 2023 Linaro Limited
|
||||
*/
|
||||
|
||||
#ifndef __FFA_PRIVATE_H__
|
||||
#define __FFA_PRIVATE_H__
|
||||
|
||||
#include <xen/const.h>
|
||||
#include <xen/sizes.h>
|
||||
#include <xen/types.h>
|
||||
#include <xen/mm.h>
|
||||
#include <xen/list.h>
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/time.h>
|
||||
|
||||
/* Error codes */
|
||||
#define FFA_RET_OK 0
|
||||
#define FFA_RET_NOT_SUPPORTED -1
|
||||
#define FFA_RET_INVALID_PARAMETERS -2
|
||||
#define FFA_RET_NO_MEMORY -3
|
||||
#define FFA_RET_BUSY -4
|
||||
#define FFA_RET_INTERRUPTED -5
|
||||
#define FFA_RET_DENIED -6
|
||||
#define FFA_RET_RETRY -7
|
||||
#define FFA_RET_ABORTED -8
|
||||
|
||||
/* FFA_VERSION helpers */
|
||||
#define FFA_VERSION_MAJOR_SHIFT 16U
|
||||
#define FFA_VERSION_MAJOR_MASK 0x7FFFU
|
||||
#define FFA_VERSION_MINOR_SHIFT 0U
|
||||
#define FFA_VERSION_MINOR_MASK 0xFFFFU
|
||||
#define MAKE_FFA_VERSION(major, minor) \
|
||||
((((major) & FFA_VERSION_MAJOR_MASK) << FFA_VERSION_MAJOR_SHIFT) | \
|
||||
((minor) & FFA_VERSION_MINOR_MASK))
|
||||
|
||||
#define FFA_VERSION_1_0 MAKE_FFA_VERSION(1, 0)
|
||||
#define FFA_VERSION_1_1 MAKE_FFA_VERSION(1, 1)
|
||||
/* The minimal FF-A version of the SPMC that can be supported */
|
||||
#define FFA_MIN_SPMC_VERSION FFA_VERSION_1_1
|
||||
|
||||
/*
|
||||
* This is the version we want to use in communication with guests and SPs.
|
||||
* During negotiation with a guest or a SP we may need to lower it for
|
||||
* that particular guest or SP.
|
||||
*/
|
||||
#define FFA_MY_VERSION_MAJOR 1U
|
||||
#define FFA_MY_VERSION_MINOR 1U
|
||||
#define FFA_MY_VERSION MAKE_FFA_VERSION(FFA_MY_VERSION_MAJOR, \
|
||||
FFA_MY_VERSION_MINOR)
|
||||
|
||||
/*
|
||||
* The FF-A specification explicitly works with 4K pages as a measure of
|
||||
* memory size, for example, FFA_RXTX_MAP takes one parameter "RX/TX page
|
||||
* count" which is the number of contiguous 4K pages allocated. Xen may use
|
||||
* a different page size depending on the configuration to avoid confusion
|
||||
* with PAGE_SIZE use a special define when it's a page size as in the FF-A
|
||||
* specification.
|
||||
*/
|
||||
#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
|
||||
|
||||
/*
|
||||
* Limit the number of pages RX/TX buffers guests can map.
|
||||
* TODO support a larger number.
|
||||
*/
|
||||
#define FFA_MAX_RXTX_PAGE_COUNT 1
|
||||
|
||||
/*
|
||||
* Limit for shared buffer size. Please note that this define limits
|
||||
* number of pages.
|
||||
*
|
||||
* FF-A doesn't have any direct requirements on GlobalPlatform or vice
|
||||
* versa, but an implementation can very well use FF-A in order to provide
|
||||
* a GlobalPlatform interface on top.
|
||||
*
|
||||
* Global Platform specification for TEE requires that any TEE
|
||||
* implementation should allow to share buffers with size of at least
|
||||
* 512KB, defined in TEEC-1.0C page 24, Table 4-1,
|
||||
* TEEC_CONFIG_SHAREDMEM_MAX_SIZE.
|
||||
* Due to overhead which can be hard to predict exactly, double this number
|
||||
* to give a safe margin.
|
||||
*/
|
||||
#define FFA_MAX_SHM_PAGE_COUNT (2 * SZ_512K / FFA_PAGE_SIZE)
|
||||
|
||||
/*
|
||||
* Limits the number of shared buffers that guest can have at once. This
|
||||
* is to prevent case, when guests trick XEN into exhausting its own
|
||||
* memory by allocating many small buffers. This value has been chosen
|
||||
* arbitrarily.
|
||||
*/
|
||||
#define FFA_MAX_SHM_COUNT 32
|
||||
|
||||
/*
|
||||
* The time we wait until trying to tear down a domain again if it was
|
||||
* blocked initially.
|
||||
*/
|
||||
#define FFA_CTX_TEARDOWN_DELAY SECONDS(1)
|
||||
|
||||
/* FF-A-1.1-REL0 section 10.9.2 Memory region handle, page 167 */
|
||||
#define FFA_HANDLE_HYP_FLAG BIT(63, ULL)
|
||||
#define FFA_HANDLE_INVALID 0xffffffffffffffffULL
|
||||
|
||||
/*
|
||||
* Memory attributes: Normal memory, Write-Back cacheable, Inner shareable
|
||||
* Defined in FF-A-1.1-REL0 Table 10.18 at page 175.
|
||||
*/
|
||||
#define FFA_NORMAL_MEM_REG_ATTR 0x2fU
|
||||
/*
|
||||
* Memory access permissions: Read-write
|
||||
* Defined in FF-A-1.1-REL0 Table 10.15 at page 168.
|
||||
*/
|
||||
#define FFA_MEM_ACC_RW 0x2U
|
||||
|
||||
/* FF-A-1.1-REL0 section 10.11.4 Flags usage, page 184-187 */
|
||||
/* Clear memory before mapping in receiver */
|
||||
#define FFA_MEMORY_REGION_FLAG_CLEAR BIT(0, U)
|
||||
/* Relayer may time slice this operation */
|
||||
#define FFA_MEMORY_REGION_FLAG_TIME_SLICE BIT(1, U)
|
||||
/* Clear memory after receiver relinquishes it */
|
||||
#define FFA_MEMORY_REGION_FLAG_CLEAR_RELINQUISH BIT(2, U)
|
||||
/* Share memory transaction */
|
||||
#define FFA_MEMORY_REGION_TRANSACTION_TYPE_SHARE (1U << 3)
|
||||
|
||||
/*
|
||||
* Flags and field values used for the MSG_SEND_DIRECT_REQ/RESP:
|
||||
* BIT(31): Framework or partition message
|
||||
* BIT(7-0): Message type for frameworks messages
|
||||
*/
|
||||
#define FFA_MSG_FLAG_FRAMEWORK BIT(31, U)
|
||||
#define FFA_MSG_TYPE_MASK 0xFFU;
|
||||
#define FFA_MSG_PSCI 0x0U
|
||||
#define FFA_MSG_SEND_VM_CREATED 0x4U
|
||||
#define FFA_MSG_RESP_VM_CREATED 0x5U
|
||||
#define FFA_MSG_SEND_VM_DESTROYED 0x6U
|
||||
#define FFA_MSG_RESP_VM_DESTROYED 0x7U
|
||||
|
||||
/*
|
||||
* Flags to determine partition properties in FFA_PARTITION_INFO_GET return
|
||||
* message:
|
||||
* BIT(0): Supports receipt of direct requests
|
||||
* BIT(1): Can send direct requests
|
||||
* BIT(2): Can send and receive indirect messages
|
||||
* BIT(3): Supports receipt of notifications
|
||||
* BIT(4-5): Partition ID is a PE endpoint ID
|
||||
* BIT(6): Partition must be informed about each VM that is created by
|
||||
* the Hypervisor
|
||||
* BIT(7): Partition must be informed about each VM that is destroyed by
|
||||
* the Hypervisor
|
||||
* BIT(8): Partition runs in the AArch64 execution state else AArch32
|
||||
* execution state
|
||||
*/
|
||||
#define FFA_PART_PROP_DIRECT_REQ_RECV BIT(0, U)
|
||||
#define FFA_PART_PROP_DIRECT_REQ_SEND BIT(1, U)
|
||||
#define FFA_PART_PROP_INDIRECT_MSGS BIT(2, U)
|
||||
#define FFA_PART_PROP_RECV_NOTIF BIT(3, U)
|
||||
#define FFA_PART_PROP_IS_TYPE_MASK (3U << 4)
|
||||
#define FFA_PART_PROP_IS_PE_ID (0U << 4)
|
||||
#define FFA_PART_PROP_IS_SEPID_INDEP (1U << 4)
|
||||
#define FFA_PART_PROP_IS_SEPID_DEP (2U << 4)
|
||||
#define FFA_PART_PROP_IS_AUX_ID (3U << 4)
|
||||
#define FFA_PART_PROP_NOTIF_CREATED BIT(6, U)
|
||||
#define FFA_PART_PROP_NOTIF_DESTROYED BIT(7, U)
|
||||
#define FFA_PART_PROP_AARCH64_STATE BIT(8, U)
|
||||
|
||||
/*
|
||||
* Flag used as parameter to FFA_PARTITION_INFO_GET to return partition
|
||||
* count only.
|
||||
*/
|
||||
#define FFA_PARTITION_INFO_GET_COUNT_FLAG BIT(0, U)
|
||||
|
||||
/* Function IDs */
|
||||
#define FFA_ERROR 0x84000060U
|
||||
#define FFA_SUCCESS_32 0x84000061U
|
||||
#define FFA_SUCCESS_64 0xC4000061U
|
||||
#define FFA_INTERRUPT 0x84000062U
|
||||
#define FFA_VERSION 0x84000063U
|
||||
#define FFA_FEATURES 0x84000064U
|
||||
#define FFA_RX_ACQUIRE 0x84000084U
|
||||
#define FFA_RX_RELEASE 0x84000065U
|
||||
#define FFA_RXTX_MAP_32 0x84000066U
|
||||
#define FFA_RXTX_MAP_64 0xC4000066U
|
||||
#define FFA_RXTX_UNMAP 0x84000067U
|
||||
#define FFA_PARTITION_INFO_GET 0x84000068U
|
||||
#define FFA_ID_GET 0x84000069U
|
||||
#define FFA_SPM_ID_GET 0x84000085U
|
||||
#define FFA_MSG_WAIT 0x8400006BU
|
||||
#define FFA_MSG_YIELD 0x8400006CU
|
||||
#define FFA_RUN 0x8400006DU
|
||||
#define FFA_MSG_SEND2 0x84000086U
|
||||
#define FFA_MSG_SEND_DIRECT_REQ_32 0x8400006FU
|
||||
#define FFA_MSG_SEND_DIRECT_REQ_64 0xC400006FU
|
||||
#define FFA_MSG_SEND_DIRECT_RESP_32 0x84000070U
|
||||
#define FFA_MSG_SEND_DIRECT_RESP_64 0xC4000070U
|
||||
#define FFA_MEM_DONATE_32 0x84000071U
|
||||
#define FFA_MEM_DONATE_64 0xC4000071U
|
||||
#define FFA_MEM_LEND_32 0x84000072U
|
||||
#define FFA_MEM_LEND_64 0xC4000072U
|
||||
#define FFA_MEM_SHARE_32 0x84000073U
|
||||
#define FFA_MEM_SHARE_64 0xC4000073U
|
||||
#define FFA_MEM_RETRIEVE_REQ_32 0x84000074U
|
||||
#define FFA_MEM_RETRIEVE_REQ_64 0xC4000074U
|
||||
#define FFA_MEM_RETRIEVE_RESP 0x84000075U
|
||||
#define FFA_MEM_RELINQUISH 0x84000076U
|
||||
#define FFA_MEM_RECLAIM 0x84000077U
|
||||
#define FFA_MEM_FRAG_RX 0x8400007AU
|
||||
#define FFA_MEM_FRAG_TX 0x8400007BU
|
||||
#define FFA_MSG_SEND 0x8400006EU
|
||||
#define FFA_MSG_POLL 0x8400006AU
|
||||
|
||||
struct ffa_ctx {
|
||||
void *rx;
|
||||
const void *tx;
|
||||
struct page_info *rx_pg;
|
||||
struct page_info *tx_pg;
|
||||
/* Number of 4kB pages in each of rx/rx_pg and tx/tx_pg */
|
||||
unsigned int page_count;
|
||||
/* FF-A version used by the guest */
|
||||
uint32_t guest_vers;
|
||||
bool rx_is_free;
|
||||
/* Used shared memory objects, struct ffa_shm_mem */
|
||||
struct list_head shm_list;
|
||||
/* Number of allocated shared memory object */
|
||||
unsigned int shm_count;
|
||||
/*
|
||||
* tx_lock is used to serialize access to tx
|
||||
* rx_lock is used to serialize access to rx
|
||||
* lock is used for the rest in this struct
|
||||
*/
|
||||
spinlock_t tx_lock;
|
||||
spinlock_t rx_lock;
|
||||
spinlock_t lock;
|
||||
/* Used if domain can't be torn down immediately */
|
||||
struct domain *teardown_d;
|
||||
struct list_head teardown_list;
|
||||
s_time_t teardown_expire;
|
||||
/*
|
||||
* Used for ffa_domain_teardown() to keep track of which SPs should be
|
||||
* notified that this guest is being destroyed.
|
||||
*/
|
||||
unsigned long vm_destroy_bitmap[];
|
||||
};
|
||||
|
||||
static inline uint16_t ffa_get_vm_id(const struct domain *d)
|
||||
{
|
||||
/* +1 since 0 is reserved for the hypervisor in FF-A */
|
||||
return d->domain_id + 1;
|
||||
}
|
||||
|
||||
static inline void ffa_set_regs(struct cpu_user_regs *regs, register_t v0,
|
||||
register_t v1, register_t v2, register_t v3,
|
||||
register_t v4, register_t v5, register_t v6,
|
||||
register_t v7)
|
||||
{
|
||||
set_user_reg(regs, 0, v0);
|
||||
set_user_reg(regs, 1, v1);
|
||||
set_user_reg(regs, 2, v2);
|
||||
set_user_reg(regs, 3, v3);
|
||||
set_user_reg(regs, 4, v4);
|
||||
set_user_reg(regs, 5, v5);
|
||||
set_user_reg(regs, 6, v6);
|
||||
set_user_reg(regs, 7, v7);
|
||||
}
|
||||
|
||||
static inline void ffa_set_regs_error(struct cpu_user_regs *regs,
|
||||
uint32_t error_code)
|
||||
{
|
||||
ffa_set_regs(regs, FFA_ERROR, 0, error_code, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static inline void ffa_set_regs_success(struct cpu_user_regs *regs,
|
||||
uint32_t w2, uint32_t w3)
|
||||
{
|
||||
ffa_set_regs(regs, FFA_SUCCESS_32, 0, w2, w3, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
static inline int32_t ffa_get_ret_code(const struct arm_smccc_1_2_regs *resp)
|
||||
{
|
||||
switch ( resp->a0 )
|
||||
{
|
||||
case FFA_ERROR:
|
||||
if ( resp->a2 )
|
||||
return resp->a2;
|
||||
else
|
||||
return FFA_RET_NOT_SUPPORTED;
|
||||
case FFA_SUCCESS_32:
|
||||
case FFA_SUCCESS_64:
|
||||
return FFA_RET_OK;
|
||||
default:
|
||||
return FFA_RET_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int32_t ffa_simple_call(uint32_t fid, register_t a1,
|
||||
register_t a2, register_t a3,
|
||||
register_t a4)
|
||||
{
|
||||
const struct arm_smccc_1_2_regs arg = {
|
||||
.a0 = fid,
|
||||
.a1 = a1,
|
||||
.a2 = a2,
|
||||
.a3 = a3,
|
||||
.a4 = a4,
|
||||
};
|
||||
struct arm_smccc_1_2_regs resp;
|
||||
|
||||
arm_smccc_1_2_smc(&arg, &resp);
|
||||
|
||||
return ffa_get_ret_code(&resp);
|
||||
}
|
||||
|
||||
#endif /*__FFA_PRIVATE_H__*/
|
||||