Merge changes from topic "ffa_el3_spmc" into integration
* changes: feat(spmc): add helper to obtain a partitions FF-A version feat(spmd): enable SPMD to forward FFA_VERSION to EL3 SPMC feat(spmc): enable handling FFA_VERSION ABI feat(spmc): add helper function to obtain endpoint mailbox feat(spmc): add helper function to obtain hyp structure feat(spmc): enable parsing of messaging methods from manifest
This commit is contained in:
commit
3d70568089
|
@ -38,6 +38,7 @@
|
|||
#define FFA_VERSION_MINOR_SHIFT 0
|
||||
#define FFA_VERSION_MINOR_MASK U(0xFFFF)
|
||||
#define FFA_VERSION_BIT31_MASK U(0x1u << 31)
|
||||
#define FFA_VERSION_MASK U(0xFFFFFFFF)
|
||||
|
||||
|
||||
#define MAKE_FFA_VERSION(major, minor) \
|
||||
|
|
|
@ -221,4 +221,10 @@ bool is_ffa_secure_id_valid(uint16_t partition_id);
|
|||
*/
|
||||
struct el3_lp_desc *get_el3_lp_array(void);
|
||||
|
||||
/*
|
||||
* Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
|
||||
* or OS kernel in the normal world or the last SP that was run.
|
||||
*/
|
||||
struct mailbox *spmc_get_mbox_desc(bool secure_origin);
|
||||
|
||||
#endif /* SPMC_H */
|
||||
|
|
|
@ -72,7 +72,7 @@ struct sp_exec_ctx *spmc_get_sp_ec(struct secure_partition_desc *sp)
|
|||
/* Helper function to get pointer to SP context from its ID. */
|
||||
struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id)
|
||||
{
|
||||
/* Check for SWd Partitions. */
|
||||
/* Check for Secure World Partitions. */
|
||||
for (unsigned int i = 0U; i < SECURE_PARTITION_COUNT; i++) {
|
||||
if (sp_desc[i].sp_id == id) {
|
||||
return &(sp_desc[i]);
|
||||
|
@ -81,6 +81,29 @@ struct secure_partition_desc *spmc_get_sp_ctx(uint16_t id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to obtain the descriptor of the Hypervisor or OS kernel.
|
||||
* We assume that the first descriptor is reserved for this entity.
|
||||
*/
|
||||
struct ns_endpoint_desc *spmc_get_hyp_ctx(void)
|
||||
{
|
||||
return &(ns_ep_desc[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function to obtain the RX/TX buffer pair descriptor of the Hypervisor
|
||||
* or OS kernel in the normal world or the last SP that was run.
|
||||
*/
|
||||
struct mailbox *spmc_get_mbox_desc(bool secure_origin)
|
||||
{
|
||||
/* Obtain the RX/TX buffer pair descriptor. */
|
||||
if (secure_origin) {
|
||||
return &(spmc_get_current_sp_ctx()->mailbox);
|
||||
} else {
|
||||
return &(spmc_get_hyp_ctx()->mailbox);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* This function returns to the place where spmc_sp_synchronous_entry() was
|
||||
* called originally.
|
||||
|
@ -491,6 +514,59 @@ static uint64_t ffa_error_handler(uint32_t smc_fid,
|
|||
return spmc_ffa_error_return(handle, FFA_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
static uint64_t ffa_version_handler(uint32_t smc_fid,
|
||||
bool secure_origin,
|
||||
uint64_t x1,
|
||||
uint64_t x2,
|
||||
uint64_t x3,
|
||||
uint64_t x4,
|
||||
void *cookie,
|
||||
void *handle,
|
||||
uint64_t flags)
|
||||
{
|
||||
uint32_t requested_version = x1 & FFA_VERSION_MASK;
|
||||
|
||||
if (requested_version & FFA_VERSION_BIT31_MASK) {
|
||||
/* Invalid encoding, return an error. */
|
||||
SMC_RET1(handle, FFA_ERROR_NOT_SUPPORTED);
|
||||
/* Execution stops here. */
|
||||
}
|
||||
|
||||
/* Determine the caller to store the requested version. */
|
||||
if (secure_origin) {
|
||||
/*
|
||||
* Ensure that the SP is reporting the same version as
|
||||
* specified in its manifest. If these do not match there is
|
||||
* something wrong with the SP.
|
||||
* TODO: Should we abort the SP? For now assert this is not
|
||||
* case.
|
||||
*/
|
||||
assert(requested_version ==
|
||||
spmc_get_current_sp_ctx()->ffa_version);
|
||||
} else {
|
||||
/*
|
||||
* If this is called by the normal world, record this
|
||||
* information in its descriptor.
|
||||
*/
|
||||
spmc_get_hyp_ctx()->ffa_version = requested_version;
|
||||
}
|
||||
|
||||
SMC_RET1(handle, MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
|
||||
FFA_VERSION_MINOR));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Helper function to obtain the FF-A version of the calling partition.
|
||||
******************************************************************************/
|
||||
uint32_t get_partition_ffa_version(bool secure_origin)
|
||||
{
|
||||
if (secure_origin) {
|
||||
return spmc_get_current_sp_ctx()->ffa_version;
|
||||
} else {
|
||||
return spmc_get_hyp_ctx()->ffa_version;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* This function will parse the Secure Partition Manifest. From manifest, it
|
||||
* will fetch details for preparing Secure partition image context and secure
|
||||
|
@ -544,6 +620,23 @@ static int sp_manifest_parse(void *sp_manifest, int offset,
|
|||
|
||||
sp->execution_state = config_32;
|
||||
|
||||
ret = fdt_read_uint32(sp_manifest, node,
|
||||
"messaging-method", &config_32);
|
||||
if (ret != 0) {
|
||||
ERROR("Missing Secure Partition messaging method.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Validate this entry, we currently only support direct messaging. */
|
||||
if ((config_32 & ~(FFA_PARTITION_DIRECT_REQ_RECV |
|
||||
FFA_PARTITION_DIRECT_REQ_SEND)) != 0U) {
|
||||
WARN("Invalid Secure Partition messaging method (0x%x)\n",
|
||||
config_32);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sp->properties = config_32;
|
||||
|
||||
ret = fdt_read_uint32(sp_manifest, node,
|
||||
"execution-ctx-count", &config_32);
|
||||
|
||||
|
@ -866,6 +959,10 @@ uint64_t spmc_smc_handler(uint32_t smc_fid,
|
|||
{
|
||||
switch (smc_fid) {
|
||||
|
||||
case FFA_VERSION:
|
||||
return ffa_version_handler(smc_fid, secure_origin, x1, x2, x3,
|
||||
x4, cookie, handle, flags);
|
||||
|
||||
case FFA_MSG_SEND_DIRECT_REQ_SMC32:
|
||||
case FFA_MSG_SEND_DIRECT_REQ_SMC64:
|
||||
return direct_req_smc_handler(smc_fid, secure_origin, x1, x2,
|
||||
|
|
|
@ -626,7 +626,8 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
|
|||
* If caller is secure and SPMC was initialized,
|
||||
* return FFA_VERSION of SPMD.
|
||||
* If caller is non secure and SPMC was initialized,
|
||||
* return SPMC's version.
|
||||
* forward to the EL3 SPMC if enabled, otherwise return
|
||||
* the SPMC version if implemented at a lower EL.
|
||||
* Sanity check to "input_version".
|
||||
* If the EL3 SPMC is enabled, ignore the SPMC state as
|
||||
* this is not used.
|
||||
|
@ -635,6 +636,17 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
|
|||
(!is_spmc_at_el3() && (ctx->state == SPMC_STATE_RESET))) {
|
||||
ret = FFA_ERROR_NOT_SUPPORTED;
|
||||
} else if (!secure_origin) {
|
||||
if (is_spmc_at_el3()) {
|
||||
/*
|
||||
* Forward the call directly to the EL3 SPMC, if
|
||||
* enabled, as we don't need to wrap the call in
|
||||
* a direct request.
|
||||
*/
|
||||
return spmd_smc_forward(smc_fid, secure_origin,
|
||||
x1, x2, x3, x4, cookie,
|
||||
handle, flags);
|
||||
}
|
||||
|
||||
gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
|
||||
uint64_t rc;
|
||||
|
||||
|
|
Loading…
Reference in New Issue