mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-30 07:39:24 +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
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -57,8 +57,8 @@
|
||||||
<< FFA_MSG_SEND_ATTRS_BLK_SHIFT)
|
<< FFA_MSG_SEND_ATTRS_BLK_SHIFT)
|
||||||
|
|
||||||
/* Defines for FF-A framework messages exchanged using direct messages. */
|
/* Defines for FF-A framework messages exchanged using direct messages. */
|
||||||
#define FFA_FWK_MSG_BIT BIT(31)
|
#define FFA_FWK_MSG_BIT BIT_32(31)
|
||||||
#define FFA_FWK_MSG_MASK 0xFF
|
#define FFA_FWK_MSG_MASK U(0xFF)
|
||||||
#define FFA_FWK_MSG_PSCI U(0x0)
|
#define FFA_FWK_MSG_PSCI U(0x0)
|
||||||
|
|
||||||
/* Defines for FF-A power management messages framework messages. */
|
/* 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
|
* return back to the SPMD logical partition so the error can be
|
||||||
* consumed.
|
* 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);
|
assert(secure_origin);
|
||||||
spmd_spm_core_sync_exit(0ULL);
|
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
|
* 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();
|
spmd_spm_core_context_t *ctx = spmd_get_context();
|
||||||
unsigned int linear_id = plat_my_core_pos();
|
unsigned int linear_id = plat_my_core_pos();
|
||||||
int64_t rc;
|
int64_t rc;
|
||||||
|
uint32_t ffa_resp_func_id, msg_flags;
|
||||||
|
int status;
|
||||||
|
|
||||||
assert(ctx != NULL);
|
assert(ctx != NULL);
|
||||||
assert(ctx->state != SPMC_STATE_OFF);
|
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_X16, 0);
|
||||||
write_ctx_reg(gpregs, CTX_GPREG_X17, 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);
|
rc = spmd_spm_core_sync_entry(ctx);
|
||||||
|
|
||||||
if (rc != 0ULL) {
|
if (rc != 0ULL) {
|
||||||
ERROR("%s failed (%" PRIu64 ") on CPU%u\n", __func__, rc, linear_id);
|
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. */
|
/* 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);
|
CTX_GPREG_X0);
|
||||||
if (ffa_resp_func != FFA_MSG_SEND_DIRECT_RESP_SMC32) {
|
|
||||||
ERROR("%s invalid SPMC response (%lx).\n",
|
/*
|
||||||
__func__, ffa_resp_func);
|
* Retrieve flags indicating framework message and power management
|
||||||
return -EINVAL;
|
* 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;
|
ctx->state = SPMC_STATE_OFF;
|
||||||
|
|
||||||
VERBOSE("CPU %u off!\n", linear_id);
|
|
||||||
|
|
||||||
return 0;
|
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
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -52,6 +52,7 @@ typedef struct spmd_spm_core_context {
|
||||||
cpu_context_t cpu_ctx;
|
cpu_context_t cpu_ctx;
|
||||||
spmc_state_t state;
|
spmc_state_t state;
|
||||||
bool secure_interrupt_ongoing;
|
bool secure_interrupt_ongoing;
|
||||||
|
bool psci_operation_ongoing;
|
||||||
#if ENABLE_SPMD_LP
|
#if ENABLE_SPMD_LP
|
||||||
uint8_t spmd_lp_sync_req_ongoing;
|
uint8_t spmd_lp_sync_req_ongoing;
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Reference in a new issue