mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
Merge "fix(spmd): check pwr mgmt status for SPMC framework response" into integration
This commit is contained in:
commit
8ed1e20b70
4 changed files with 57 additions and 14 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2024, Arm Limited. All rights reserved.
|
||||
* Copyright (c) 2020-2025, Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -57,8 +57,8 @@
|
|||
<< FFA_MSG_SEND_ATTRS_BLK_SHIFT)
|
||||
|
||||
/* Defines for FF-A framework messages exchanged using direct messages. */
|
||||
#define FFA_FWK_MSG_BIT BIT(31)
|
||||
#define FFA_FWK_MSG_MASK 0xFF
|
||||
#define FFA_FWK_MSG_BIT BIT_32(31)
|
||||
#define FFA_FWK_MSG_MASK U(0xFF)
|
||||
#define FFA_FWK_MSG_PSCI U(0x0)
|
||||
|
||||
/* Defines for FF-A power management messages framework messages. */
|
||||
|
|
|
@ -888,11 +888,15 @@ uint64_t spmd_smc_handler(uint32_t smc_fid,
|
|||
}
|
||||
|
||||
/*
|
||||
* If there was an SPMD logical partition direct request on-going,
|
||||
* Perform a synchronous exit:
|
||||
* 1. If there was an SPMD logical partition direct request on-going,
|
||||
* return back to the SPMD logical partition so the error can be
|
||||
* consumed.
|
||||
* 2. SPMC sent FFA_ERROR in response to a power management
|
||||
* operation sent through direct request.
|
||||
*/
|
||||
if (is_spmd_logical_sp_dir_req_in_progress(ctx)) {
|
||||
if (is_spmd_logical_sp_dir_req_in_progress(ctx) ||
|
||||
ctx->psci_operation_ongoing) {
|
||||
assert(secure_origin);
|
||||
spmd_spm_core_sync_exit(0ULL);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2020-2022, ARM Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2020-2025, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -117,6 +117,8 @@ static int32_t spmd_cpu_off_handler(u_register_t unused)
|
|||
spmd_spm_core_context_t *ctx = spmd_get_context();
|
||||
unsigned int linear_id = plat_my_core_pos();
|
||||
int64_t rc;
|
||||
uint32_t ffa_resp_func_id, msg_flags;
|
||||
int status;
|
||||
|
||||
assert(ctx != NULL);
|
||||
assert(ctx->state != SPMC_STATE_OFF);
|
||||
|
@ -137,24 +139,60 @@ static int32_t spmd_cpu_off_handler(u_register_t unused)
|
|||
write_ctx_reg(gpregs, CTX_GPREG_X16, 0);
|
||||
write_ctx_reg(gpregs, CTX_GPREG_X17, 0);
|
||||
|
||||
/* Mark current core as processing a PSCI operation. */
|
||||
ctx->psci_operation_ongoing = true;
|
||||
|
||||
rc = spmd_spm_core_sync_entry(ctx);
|
||||
|
||||
if (rc != 0ULL) {
|
||||
ERROR("%s failed (%" PRIu64 ") on CPU%u\n", __func__, rc, linear_id);
|
||||
}
|
||||
|
||||
ctx->psci_operation_ongoing = false;
|
||||
|
||||
/* Expect a direct message response from the SPMC. */
|
||||
u_register_t ffa_resp_func = read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
|
||||
ffa_resp_func_id = (uint32_t)read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
|
||||
CTX_GPREG_X0);
|
||||
if (ffa_resp_func != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
|
||||
ERROR("%s invalid SPMC response (%lx).\n",
|
||||
__func__, ffa_resp_func);
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Retrieve flags indicating framework message and power management
|
||||
* response.
|
||||
*/
|
||||
msg_flags = (uint32_t)read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
|
||||
CTX_GPREG_X2);
|
||||
|
||||
/* Retrieve error code indicating status of power management operation. */
|
||||
status = (int)read_ctx_reg(get_gpregs_ctx(&ctx->cpu_ctx),
|
||||
CTX_GPREG_X3);
|
||||
|
||||
if (ffa_resp_func_id == FFA_ERROR) {
|
||||
/*
|
||||
* It is likely that SPMC does not support receiving PSCI
|
||||
* operation through framework message. SPMD takes an
|
||||
* implementation defined choice to not treat it as a fatal
|
||||
* error. Consequently, SPMD ignores the error and continues
|
||||
* with power management operation.
|
||||
*/
|
||||
VERBOSE("SPMC ignored PSCI CPU_OFF framework message\n");
|
||||
} else if (ffa_resp_func_id != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
|
||||
ERROR("%s invalid SPMC response (%x).\n",
|
||||
__func__, ffa_resp_func_id);
|
||||
panic();
|
||||
} else if (((msg_flags & FFA_FWK_MSG_BIT) == 0U) ||
|
||||
((msg_flags & FFA_FWK_MSG_MASK) != FFA_PM_MSG_PM_RESP)) {
|
||||
ERROR("SPMC failed to send framework message response for power"
|
||||
" management operation, message flags = (%x)\n",
|
||||
msg_flags);
|
||||
panic();
|
||||
} else if (status != PSCI_E_SUCCESS) {
|
||||
ERROR("SPMC denied CPU_OFF power management request\n");
|
||||
panic();
|
||||
} else {
|
||||
VERBOSE("CPU %u off!\n", linear_id);
|
||||
}
|
||||
|
||||
ctx->state = SPMC_STATE_OFF;
|
||||
|
||||
VERBOSE("CPU %u off!\n", linear_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
|
||||
* Copyright (c) 2019-2025, Arm Limited and Contributors. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
@ -52,6 +52,7 @@ typedef struct spmd_spm_core_context {
|
|||
cpu_context_t cpu_ctx;
|
||||
spmc_state_t state;
|
||||
bool secure_interrupt_ongoing;
|
||||
bool psci_operation_ongoing;
|
||||
#if ENABLE_SPMD_LP
|
||||
uint8_t spmd_lp_sync_req_ongoing;
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue