diff options
Diffstat (limited to 'services/std_svc/lfa/lfa_main.c')
| -rw-r--r-- | services/std_svc/lfa/lfa_main.c | 99 |
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(¤t_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(¤t_activation, ep_address, - context_id); } - /* - * Update the activation pending flag only if the activation was - * successful. - */ + ret = activator->activate(¤t_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; } |
