Merge "feat(ff-a): forward FFA_VERSION from SPMD to SPMC" into integration

This commit is contained in:
Olivier Deprez 2022-03-04 13:22:45 +01:00 committed by TrustedFirmware Code Review
commit b298d4df5e
3 changed files with 83 additions and 21 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -90,6 +90,21 @@ static uint64_t spmd_smc_forward(uint32_t smc_fid,
uint64_t x4,
void *handle);
/******************************************************************************
* Builds an SPMD to SPMC direct message request.
*****************************************************************************/
void spmd_build_spmc_message(gp_regs_t *gpregs, uint8_t target_func,
unsigned long long message)
{
write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
write_ctx_reg(gpregs, CTX_GPREG_X1,
(SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) |
spmd_spmc_id_get());
write_ctx_reg(gpregs, CTX_GPREG_X2, BIT(31) | target_func);
write_ctx_reg(gpregs, CTX_GPREG_X3, message);
}
/*******************************************************************************
* This function takes an SPMC context pointer and performs a synchronous
* SPMC entry.
@ -543,8 +558,59 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
(ctx->state == SPMC_STATE_RESET)) {
ret = FFA_ERROR_NOT_SUPPORTED;
} else if (!secure_origin) {
ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
spmc_attrs.minor_version);
gp_regs_t *gpregs = get_gpregs_ctx(&ctx->cpu_ctx);
uint64_t rc;
if (spmc_attrs.major_version == 1 &&
spmc_attrs.minor_version == 0) {
ret = MAKE_FFA_VERSION(spmc_attrs.major_version,
spmc_attrs.minor_version);
SMC_RET8(handle, (uint32_t)ret,
FFA_TARGET_INFO_MBZ,
FFA_TARGET_INFO_MBZ,
FFA_PARAM_MBZ, FFA_PARAM_MBZ,
FFA_PARAM_MBZ, FFA_PARAM_MBZ,
FFA_PARAM_MBZ);
break;
}
/* Save non-secure system registers context */
cm_el1_sysregs_context_save(NON_SECURE);
#if SPMD_SPM_AT_SEL2
cm_el2_sysregs_context_save(NON_SECURE);
#endif
/*
* The incoming request has FFA_VERSION as X0 smc_fid
* and requested version in x1. Prepare a direct request
* from SPMD to SPMC with FFA_VERSION framework function
* identifier in X2 and requested version in X3.
*/
spmd_build_spmc_message(gpregs,
SPMD_FWK_MSG_FFA_VERSION_REQ,
input_version);
rc = spmd_spm_core_sync_entry(ctx);
if ((rc != 0ULL) ||
(SMC_GET_GP(gpregs, CTX_GPREG_X0) !=
FFA_MSG_SEND_DIRECT_RESP_SMC32) ||
(SMC_GET_GP(gpregs, CTX_GPREG_X2) !=
(SPMD_FWK_MSG_BIT |
SPMD_FWK_MSG_FFA_VERSION_RESP))) {
ERROR("Failed to forward FFA_VERSION\n");
ret = FFA_ERROR_NOT_SUPPORTED;
} else {
ret = SMC_GET_GP(gpregs, CTX_GPREG_X3);
}
/*
* Return here after SPMC has handled FFA_VERSION.
* The returned SPMC version is held in X3.
* Forward this version in X0 to the non-secure caller.
*/
return spmd_smc_forward(ret, true, FFA_PARAM_MBZ,
FFA_PARAM_MBZ, FFA_PARAM_MBZ,
FFA_PARAM_MBZ, gpregs);
} else {
ret = MAKE_FFA_VERSION(FFA_VERSION_MAJOR,
FFA_VERSION_MINOR);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -19,21 +19,6 @@ static struct {
spinlock_t lock;
} g_spmd_pm;
/*******************************************************************************
* spmd_build_spmc_message
*
* Builds an SPMD to SPMC direct message request.
******************************************************************************/
static void spmd_build_spmc_message(gp_regs_t *gpregs, unsigned long long message)
{
write_ctx_reg(gpregs, CTX_GPREG_X0, FFA_MSG_SEND_DIRECT_REQ_SMC32);
write_ctx_reg(gpregs, CTX_GPREG_X1,
(SPMD_DIRECT_MSG_ENDPOINT_ID << FFA_DIRECT_MSG_SOURCE_SHIFT) |
spmd_spmc_id_get());
write_ctx_reg(gpregs, CTX_GPREG_X2, FFA_PARAM_MBZ);
write_ctx_reg(gpregs, CTX_GPREG_X3, message);
}
/*******************************************************************************
* spmd_pm_secondary_ep_register
******************************************************************************/
@ -137,7 +122,8 @@ static int32_t spmd_cpu_off_handler(u_register_t unused)
assert(ctx->state != SPMC_STATE_OFF);
/* Build an SPMD to SPMC direct message request. */
spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx), PSCI_CPU_OFF);
spmd_build_spmc_message(get_gpregs_ctx(&ctx->cpu_ctx),
SPMD_FWK_MSG_PSCI, PSCI_CPU_OFF);
rc = spmd_spm_core_sync_entry(ctx);
if (rc != 0ULL) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019-2021, ARM Limited and Contributors. All rights reserved.
* Copyright (c) 2019-2022, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -64,6 +64,16 @@ typedef struct spmd_spm_core_context {
#define SPMD_DIRECT_MSG_ENDPOINT_ID U(FFA_ENDPOINT_ID_MAX - 1)
/* Define SPMD target function IDs for framework messages to the SPMC */
#define SPMD_FWK_MSG_BIT BIT(31)
#define SPMD_FWK_MSG_PSCI U(0)
#define SPMD_FWK_MSG_FFA_VERSION_REQ U(0x8)
#define SPMD_FWK_MSG_FFA_VERSION_RESP U(0x9)
/* Function to build SPMD to SPMC message */
void spmd_build_spmc_message(gp_regs_t *gpregs, uint8_t target,
unsigned long long message);
/* Functions used to enter/exit SPMC synchronously */
uint64_t spmd_spm_core_sync_entry(spmd_spm_core_context_t *ctx);
__dead2 void spmd_spm_core_sync_exit(uint64_t rc);