summaryrefslogtreecommitdiff
path: root/services/std_svc/lfa/lfa_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'services/std_svc/lfa/lfa_main.c')
-rw-r--r--services/std_svc/lfa/lfa_main.c99
1 files changed, 44 insertions, 55 deletions
diff --git a/services/std_svc/lfa/lfa_main.c b/services/std_svc/lfa/lfa_main.c
index 819b169a7..0022e0331 100644
--- a/services/std_svc/lfa/lfa_main.c
+++ b/services/std_svc/lfa/lfa_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2025, Arm Limited. All rights reserved.
+ * Copyright (c) 2025-2026, Arm Limited. All rights reserved.
* Copyright (c) 2025, NVIDIA Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
@@ -32,7 +32,6 @@ void lfa_reset_activation(void)
{
current_activation.component_id = LFA_INVALID_COMPONENT;
current_activation.prime_status = PRIME_NONE;
- current_activation.cpu_rendezvous_required = false;
}
static int convert_to_lfa_error(int ret)
@@ -54,8 +53,7 @@ static bool lfa_initialize_components(void)
lfa_component_count = plat_lfa_get_components(&lfa_components);
if (lfa_component_count == 0U || lfa_components == NULL) {
- /* unlikely to reach here */
- ERROR("Invalid LFA component setup: count = 0 or components are NULL");
+ ERROR("Could not retrieve LFA components.\n");
return false;
}
@@ -64,8 +62,7 @@ static bool lfa_initialize_components(void)
static uint64_t get_fw_activation_flags(uint32_t fw_seq_id)
{
- const plat_lfa_component_info_t *comp =
- &lfa_components[fw_seq_id];
+ const plat_lfa_component_info_t *comp = &lfa_components[fw_seq_id];
uint64_t flags = 0ULL;
flags |= ((comp->activator == NULL ? 0ULL : 1ULL)
@@ -86,6 +83,7 @@ static uint64_t get_fw_activation_flags(uint32_t fw_seq_id)
static int lfa_cancel(uint32_t component_id)
{
int ret = LFA_SUCCESS;
+ struct lfa_component_ops *activator;
if (lfa_component_count == 0U) {
return LFA_WRONG_STATE;
@@ -97,6 +95,14 @@ static int lfa_cancel(uint32_t component_id)
return LFA_INVALID_PARAMETERS;
}
+ activator = lfa_components[component_id].activator;
+ if (activator->cancel != NULL) {
+ ret = activator->cancel(&current_activation);
+ if (ret != LFA_SUCCESS) {
+ return LFA_BUSY;
+ }
+ }
+
ret = plat_lfa_cancel(component_id);
if (ret != LFA_SUCCESS) {
return LFA_BUSY;
@@ -120,13 +126,13 @@ static int lfa_activate(uint32_t component_id, uint64_t flags,
return LFA_COMPONENT_WRONG_STATE;
}
- /* Check if fw_seq_id is in range. */
if ((component_id >= lfa_component_count) ||
(current_activation.component_id != component_id)) {
return LFA_INVALID_PARAMETERS;
}
- if (lfa_components[component_id].activator == NULL) {
+ activator = lfa_components[component_id].activator;
+ if (activator == NULL) {
return LFA_NOT_SUPPORTED;
}
@@ -135,35 +141,20 @@ static int lfa_activate(uint32_t component_id, uint64_t flags,
return LFA_ACTIVATION_FAILED;
}
- activator = lfa_components[component_id].activator;
- if (activator->activate != NULL) {
- /*
- * Pass skip_cpu_rendezvous (flag[0]) only if flag[0]==1
- * & CPU_RENDEZVOUS is not required.
- */
- if (flags & LFA_SKIP_CPU_RENDEZVOUS_BIT) {
- if (!activator->cpu_rendezvous_required) {
- INFO("Skipping rendezvous requested by caller.\n");
- current_activation.cpu_rendezvous_required = false;
- }
- /*
- * Return error if caller tries to skip rendezvous when
- * it is required.
- */
- else {
- ERROR("CPU Rendezvous is required, can't skip.\n");
- return LFA_INVALID_PARAMETERS;
- }
+ /* If caller requests it, see if we can skip CPU rendezvous. */
+ if (flags & LFA_SKIP_CPU_RENDEZVOUS_BIT) {
+ if (!activator->cpu_rendezvous_required) {
+ INFO("Caller requested skip CPU rendezvous.\n");
+ current_activation.cpu_rendezvous = false;
+ } else {
+ ERROR("CPU rendezvous cannot be skipped!\n");
+ return LFA_INVALID_PARAMETERS;
}
-
- ret = activator->activate(&current_activation, ep_address,
- context_id);
}
- /*
- * Update the activation pending flag only if the activation was
- * successful.
- */
+ ret = activator->activate(&current_activation, ep_address, context_id);
+
+ /* Clear pending flag on successful activation. */
if (ret == LFA_SUCCESS) {
lfa_components[component_id].activation_pending = false;
}
@@ -225,7 +216,13 @@ static int lfa_prime(uint32_t component_id, uint64_t *flags)
}
}
+ /*
+ * Update current activation status fields. CPU rendezvous is enabled
+ * by default but can be disabled if requested and allowed.
+ */
+ current_activation.cpu_rendezvous = true;
current_activation.prime_status = PRIME_COMPLETE;
+ current_activation.reset = lfa_components[component_id].activator->may_reset_cpu;
}
/*
@@ -268,8 +265,9 @@ uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
u_register_t x3, u_register_t x4, void *cookie,
void *handle, u_register_t flags)
{
- uint64_t retx1, retx2;
- uint64_t lfa_flags;
+ uint64_t retx1;
+ uint64_t retx2;
+ uint64_t lfa_flags = 0;
uint8_t *uuid_p;
uint32_t fw_seq_id = (uint32_t)x1;
int ret;
@@ -292,9 +290,9 @@ uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
break;
case LFA_GET_INFO:
- /**
+ /*
* The current specification limits this input parameter to be zero for
- * version 1.0 of LFA
+ * version 1.0 of LFA.
*/
if (x1 == 0ULL) {
SMC_RET3(handle, LFA_SUCCESS, lfa_component_count, 0);
@@ -309,29 +307,27 @@ uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
}
/*
- * Check if fw_seq_id is in range. LFA_GET_INFO must be called first to scan
- * platform firmware and create a valid number of firmware components.
+ * Check if fw_seq_id is in range. LFA_GET_INFO must be called
+ * first to scan platform firmware and create a valid number of
+ * firmware components.
*/
if (fw_seq_id >= lfa_component_count) {
SMC_RET1(handle, LFA_INVALID_PARAMETERS);
}
- /*
- * grab the UUID of asked fw_seq_id and set the return UUID
- * variables
- */
+ /* Get the UUID of requested fw_seq_id. */
uuid_p = (uint8_t *)&lfa_components[fw_seq_id].uuid;
memcpy(&retx1, uuid_p, sizeof(uint64_t));
memcpy(&retx2, uuid_p + sizeof(uint64_t), sizeof(uint64_t));
/*
- * check the given fw_seq_id's update available
- * and accordingly set the active_pending flag
+ * Check the given fw_seq_id update available and accordingly
+ * set the active_pending flag.
*/
lfa_components[fw_seq_id].activation_pending =
is_plat_lfa_activation_pending(fw_seq_id);
- INFO("Component %lu %s live activation:\n", x1,
+ INFO("Component %lu %s live activation.\n", x1,
lfa_components[fw_seq_id].activator ? "supports" :
"does not support");
@@ -340,10 +336,7 @@ uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
lfa_components[fw_seq_id].activation_pending ? "true" : "false");
}
- INFO("x1 = 0x%016lx, x2 = 0x%016lx\n", retx1, retx2);
-
SMC_RET4(handle, LFA_SUCCESS, retx1, retx2, get_fw_activation_flags(fw_seq_id));
-
break;
case LFA_PRIME:
@@ -372,7 +365,6 @@ uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
ret = lfa_activate(fw_seq_id, x2, x3, x4);
/* TODO: implement activate again */
SMC_RET2(handle, ret, 0ULL);
-
break;
case LFA_CANCEL:
@@ -383,11 +375,8 @@ uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2,
default:
WARN("Unimplemented LFA Service Call: 0x%x\n", smc_fid);
SMC_RET1(handle, SMC_UNK);
- break; /* unreachable */
-
+ break;
}
- SMC_RET1(handle, SMC_UNK);
-
return 0;
}