1cf48f49fSManish V Badarkhe /* 2cf48f49fSManish V Badarkhe * Copyright (c) 2025, Arm Limited. All rights reserved. 310f81c86SVarun Wadekar * Copyright (c) 2025, NVIDIA Corporation. All rights reserved. 4cf48f49fSManish V Badarkhe * 5cf48f49fSManish V Badarkhe * SPDX-License-Identifier: BSD-3-Clause 6cf48f49fSManish V Badarkhe */ 7cf48f49fSManish V Badarkhe 807de22d2SManish V Badarkhe #include <errno.h> 9c0d32ee6Sazimmerman #include <string.h> 1007de22d2SManish V Badarkhe 11c8e08212SVarun Wadekar #include <lib/spinlock.h> 12b9dee50cSManish V Badarkhe #include <plat/common/platform.h> 13b9dee50cSManish V Badarkhe #include <services/bl31_lfa.h> 14cf48f49fSManish V Badarkhe #include <services/lfa_svc.h> 15b9dee50cSManish V Badarkhe #include <services/rmmd_rmm_lfa.h> 16cf48f49fSManish V Badarkhe #include <smccc_helpers.h> 17cf48f49fSManish V Badarkhe 18b9dee50cSManish V Badarkhe static uint32_t lfa_component_count; 19b9dee50cSManish V Badarkhe static plat_lfa_component_info_t *lfa_components; 20b9dee50cSManish V Badarkhe static struct lfa_component_status current_activation; 21b9dee50cSManish V Badarkhe static bool is_lfa_initialized; 22b9dee50cSManish V Badarkhe 23c8e08212SVarun Wadekar /* 24c8e08212SVarun Wadekar * Spinlock to serialize LFA operations (PRIME, ACTIVATE). 25c8e08212SVarun Wadekar * This ensures that these calls from different CPUs are properly 26c8e08212SVarun Wadekar * serialized and do not execute concurrently, while still allowing 27c8e08212SVarun Wadekar * the same operation to be invoked from any CPU. 28c8e08212SVarun Wadekar */ 29c8e08212SVarun Wadekar static spinlock_t lfa_lock; 30c8e08212SVarun Wadekar 31b9dee50cSManish V Badarkhe void lfa_reset_activation(void) 32b9dee50cSManish V Badarkhe { 33b9dee50cSManish V Badarkhe current_activation.component_id = LFA_INVALID_COMPONENT; 34b9dee50cSManish V Badarkhe current_activation.prime_status = PRIME_NONE; 3507de22d2SManish V Badarkhe current_activation.cpu_rendezvous_required = false; 36b9dee50cSManish V Badarkhe } 37b9dee50cSManish V Badarkhe 3867fa182fSManish V Badarkhe static int convert_to_lfa_error(int ret) 3967fa182fSManish V Badarkhe { 4067fa182fSManish V Badarkhe switch (ret) { 4167fa182fSManish V Badarkhe case 0: 4267fa182fSManish V Badarkhe return LFA_SUCCESS; 4367fa182fSManish V Badarkhe case -EAUTH: 4467fa182fSManish V Badarkhe return LFA_AUTH_ERROR; 4567fa182fSManish V Badarkhe case -ENOMEM: 4667fa182fSManish V Badarkhe return LFA_NO_MEMORY; 4767fa182fSManish V Badarkhe default: 4867fa182fSManish V Badarkhe return LFA_DEVICE_ERROR; 4967fa182fSManish V Badarkhe } 5067fa182fSManish V Badarkhe } 5167fa182fSManish V Badarkhe 52b9dee50cSManish V Badarkhe static bool lfa_initialize_components(void) 53b9dee50cSManish V Badarkhe { 54b9dee50cSManish V Badarkhe lfa_component_count = plat_lfa_get_components(&lfa_components); 55b9dee50cSManish V Badarkhe 56b9dee50cSManish V Badarkhe if (lfa_component_count == 0U || lfa_components == NULL) { 57b9dee50cSManish V Badarkhe /* unlikely to reach here */ 58b9dee50cSManish V Badarkhe ERROR("Invalid LFA component setup: count = 0 or components are NULL"); 59b9dee50cSManish V Badarkhe return false; 60b9dee50cSManish V Badarkhe } 61b9dee50cSManish V Badarkhe 62b9dee50cSManish V Badarkhe return true; 63b9dee50cSManish V Badarkhe } 64b9dee50cSManish V Badarkhe 6506a6f296SManish V Badarkhe static uint64_t get_fw_activation_flags(uint32_t fw_seq_id) 6606a6f296SManish V Badarkhe { 6706a6f296SManish V Badarkhe const plat_lfa_component_info_t *comp = 6806a6f296SManish V Badarkhe &lfa_components[fw_seq_id]; 6906a6f296SManish V Badarkhe uint64_t flags = 0ULL; 7006a6f296SManish V Badarkhe 7106a6f296SManish V Badarkhe flags |= ((comp->activator == NULL ? 0ULL : 1ULL) 7206a6f296SManish V Badarkhe << LFA_ACTIVATION_CAPABLE_SHIFT); 7306a6f296SManish V Badarkhe flags |= (uint64_t)(comp->activation_pending) 7406a6f296SManish V Badarkhe << LFA_ACTIVATION_PENDING_SHIFT; 7506a6f296SManish V Badarkhe 7606a6f296SManish V Badarkhe if (comp->activator != NULL) { 7706a6f296SManish V Badarkhe flags |= ((comp->activator->may_reset_cpu ? 1ULL : 0ULL) 7806a6f296SManish V Badarkhe << LFA_MAY_RESET_CPU_SHIFT); 7906a6f296SManish V Badarkhe flags |= ((comp->activator->cpu_rendezvous_required ? 0ULL : 1ULL) 8006a6f296SManish V Badarkhe << LFA_CPU_RENDEZVOUS_OPTIONAL_SHIFT); 8106a6f296SManish V Badarkhe } 8206a6f296SManish V Badarkhe 8306a6f296SManish V Badarkhe return flags; 8406a6f296SManish V Badarkhe } 8506a6f296SManish V Badarkhe 863f7b2862SManish V Badarkhe static int lfa_cancel(uint32_t component_id) 873f7b2862SManish V Badarkhe { 883f7b2862SManish V Badarkhe int ret = LFA_SUCCESS; 893f7b2862SManish V Badarkhe 903f7b2862SManish V Badarkhe if (lfa_component_count == 0U) { 913f7b2862SManish V Badarkhe return LFA_WRONG_STATE; 923f7b2862SManish V Badarkhe } 933f7b2862SManish V Badarkhe 943f7b2862SManish V Badarkhe /* Check if component ID is in range. */ 953f7b2862SManish V Badarkhe if ((component_id >= lfa_component_count) || 963f7b2862SManish V Badarkhe (component_id != current_activation.component_id)) { 973f7b2862SManish V Badarkhe return LFA_INVALID_PARAMETERS; 983f7b2862SManish V Badarkhe } 993f7b2862SManish V Badarkhe 1003f7b2862SManish V Badarkhe ret = plat_lfa_cancel(component_id); 1013f7b2862SManish V Badarkhe if (ret != LFA_SUCCESS) { 1023f7b2862SManish V Badarkhe return LFA_BUSY; 1033f7b2862SManish V Badarkhe } 1043f7b2862SManish V Badarkhe 1053f7b2862SManish V Badarkhe /* TODO: add proper termination prime and activate phases */ 1063f7b2862SManish V Badarkhe lfa_reset_activation(); 1073f7b2862SManish V Badarkhe 1083f7b2862SManish V Badarkhe return ret; 1093f7b2862SManish V Badarkhe } 1103f7b2862SManish V Badarkhe 11107de22d2SManish V Badarkhe static int lfa_activate(uint32_t component_id, uint64_t flags, 11207de22d2SManish V Badarkhe uint64_t ep_address, uint64_t context_id) 11307de22d2SManish V Badarkhe { 11407de22d2SManish V Badarkhe int ret = LFA_ACTIVATION_FAILED; 11507de22d2SManish V Badarkhe struct lfa_component_ops *activator; 11607de22d2SManish V Badarkhe 11707de22d2SManish V Badarkhe if ((lfa_component_count == 0U) || 11807de22d2SManish V Badarkhe (!lfa_components[component_id].activation_pending) || 11907de22d2SManish V Badarkhe (current_activation.prime_status != PRIME_COMPLETE)) { 12007de22d2SManish V Badarkhe return LFA_COMPONENT_WRONG_STATE; 12107de22d2SManish V Badarkhe } 12207de22d2SManish V Badarkhe 12307de22d2SManish V Badarkhe /* Check if fw_seq_id is in range. */ 12407de22d2SManish V Badarkhe if ((component_id >= lfa_component_count) || 12507de22d2SManish V Badarkhe (current_activation.component_id != component_id)) { 12607de22d2SManish V Badarkhe return LFA_INVALID_PARAMETERS; 12707de22d2SManish V Badarkhe } 12807de22d2SManish V Badarkhe 12907de22d2SManish V Badarkhe if (lfa_components[component_id].activator == NULL) { 13007de22d2SManish V Badarkhe return LFA_NOT_SUPPORTED; 13107de22d2SManish V Badarkhe } 13207de22d2SManish V Badarkhe 1335084b7f1SManish V Badarkhe ret = plat_lfa_notify_activate(component_id); 1345084b7f1SManish V Badarkhe if (ret != 0) { 1355084b7f1SManish V Badarkhe return LFA_ACTIVATION_FAILED; 1365084b7f1SManish V Badarkhe } 1375084b7f1SManish V Badarkhe 13807de22d2SManish V Badarkhe activator = lfa_components[component_id].activator; 13907de22d2SManish V Badarkhe if (activator->activate != NULL) { 14007de22d2SManish V Badarkhe /* 14107de22d2SManish V Badarkhe * Pass skip_cpu_rendezvous (flag[0]) only if flag[0]==1 14207de22d2SManish V Badarkhe * & CPU_RENDEZVOUS is not required. 14307de22d2SManish V Badarkhe */ 14407de22d2SManish V Badarkhe if (flags & LFA_SKIP_CPU_RENDEZVOUS_BIT) { 14507de22d2SManish V Badarkhe if (!activator->cpu_rendezvous_required) { 14607de22d2SManish V Badarkhe INFO("Skipping rendezvous requested by caller.\n"); 14707de22d2SManish V Badarkhe current_activation.cpu_rendezvous_required = false; 14807de22d2SManish V Badarkhe } 14907de22d2SManish V Badarkhe /* 15007de22d2SManish V Badarkhe * Return error if caller tries to skip rendezvous when 15107de22d2SManish V Badarkhe * it is required. 15207de22d2SManish V Badarkhe */ 15307de22d2SManish V Badarkhe else { 15407de22d2SManish V Badarkhe ERROR("CPU Rendezvous is required, can't skip.\n"); 15507de22d2SManish V Badarkhe return LFA_INVALID_PARAMETERS; 15607de22d2SManish V Badarkhe } 15707de22d2SManish V Badarkhe } 15807de22d2SManish V Badarkhe 15907de22d2SManish V Badarkhe ret = activator->activate(¤t_activation, ep_address, 16007de22d2SManish V Badarkhe context_id); 16107de22d2SManish V Badarkhe } 16207de22d2SManish V Badarkhe 16307de22d2SManish V Badarkhe lfa_components[component_id].activation_pending = false; 16407de22d2SManish V Badarkhe 16507de22d2SManish V Badarkhe return ret; 16607de22d2SManish V Badarkhe } 16707de22d2SManish V Badarkhe 16867fa182fSManish V Badarkhe static int lfa_prime(uint32_t component_id, uint64_t *flags) 16967fa182fSManish V Badarkhe { 17067fa182fSManish V Badarkhe int ret = LFA_SUCCESS; 17167fa182fSManish V Badarkhe struct lfa_component_ops *activator; 17267fa182fSManish V Badarkhe 17367fa182fSManish V Badarkhe if (lfa_component_count == 0U || 17467fa182fSManish V Badarkhe !lfa_components[component_id].activation_pending) { 17567fa182fSManish V Badarkhe return LFA_WRONG_STATE; 17667fa182fSManish V Badarkhe } 17767fa182fSManish V Badarkhe 17867fa182fSManish V Badarkhe /* Check if fw_seq_id is in range. */ 17967fa182fSManish V Badarkhe if (component_id >= lfa_component_count) { 18067fa182fSManish V Badarkhe return LFA_INVALID_PARAMETERS; 18167fa182fSManish V Badarkhe } 18267fa182fSManish V Badarkhe 18367fa182fSManish V Badarkhe if (lfa_components[component_id].activator == NULL) { 18467fa182fSManish V Badarkhe return LFA_NOT_SUPPORTED; 18567fa182fSManish V Badarkhe } 18667fa182fSManish V Badarkhe 18767fa182fSManish V Badarkhe switch (current_activation.prime_status) { 18867fa182fSManish V Badarkhe case PRIME_NONE: 18967fa182fSManish V Badarkhe current_activation.component_id = component_id; 19067fa182fSManish V Badarkhe current_activation.prime_status = PRIME_STARTED; 19167fa182fSManish V Badarkhe break; 19267fa182fSManish V Badarkhe 19367fa182fSManish V Badarkhe case PRIME_STARTED: 19467fa182fSManish V Badarkhe if (current_activation.component_id != component_id) { 19567fa182fSManish V Badarkhe /* Mismatched component trying to continue PRIME - error */ 19667fa182fSManish V Badarkhe return LFA_WRONG_STATE; 19767fa182fSManish V Badarkhe } 19867fa182fSManish V Badarkhe break; 19967fa182fSManish V Badarkhe 20067fa182fSManish V Badarkhe case PRIME_COMPLETE: 20167fa182fSManish V Badarkhe default: 20267fa182fSManish V Badarkhe break; 20367fa182fSManish V Badarkhe } 20467fa182fSManish V Badarkhe 205*59b826ceSVarun Wadekar /* Initialise the flags to start with. Only valid if ret=LFA_SUCCESS. */ 206*59b826ceSVarun Wadekar *flags = 0ULL; 20767fa182fSManish V Badarkhe 208*59b826ceSVarun Wadekar ret = plat_lfa_load_auth_image(component_id); 209*59b826ceSVarun Wadekar if (ret == 0) { 21067fa182fSManish V Badarkhe activator = lfa_components[component_id].activator; 21167fa182fSManish V Badarkhe if (activator->prime != NULL) { 21267fa182fSManish V Badarkhe ret = activator->prime(¤t_activation); 21367fa182fSManish V Badarkhe if (ret != LFA_SUCCESS) { 21467fa182fSManish V Badarkhe /* 21567fa182fSManish V Badarkhe * TODO: it should be LFA_PRIME_FAILED but specification 21667fa182fSManish V Badarkhe * has not define this error yet 21767fa182fSManish V Badarkhe */ 21867fa182fSManish V Badarkhe return ret; 21967fa182fSManish V Badarkhe } 22067fa182fSManish V Badarkhe } 22167fa182fSManish V Badarkhe 22267fa182fSManish V Badarkhe current_activation.prime_status = PRIME_COMPLETE; 223*59b826ceSVarun Wadekar } 22467fa182fSManish V Badarkhe 225*59b826ceSVarun Wadekar /* 226*59b826ceSVarun Wadekar * Set lfa_flags to indicate that LFA_PRIME must be called again and 227*59b826ceSVarun Wadekar * reset ret to 0, as LFA_PRIME must return LFA_SUCCESS if it is 228*59b826ceSVarun Wadekar * incomplete. 229*59b826ceSVarun Wadekar */ 230*59b826ceSVarun Wadekar if (ret == -EAGAIN) { 231*59b826ceSVarun Wadekar ret = 0; 232*59b826ceSVarun Wadekar *flags = LFA_CALL_AGAIN; 233*59b826ceSVarun Wadekar } 23467fa182fSManish V Badarkhe 235*59b826ceSVarun Wadekar return convert_to_lfa_error(ret); 23667fa182fSManish V Badarkhe } 23767fa182fSManish V Badarkhe 238b17fc0a6SManish V Badarkhe bool lfa_is_prime_complete(uint32_t lfa_component_id) 239ce78f3cdSManish V Badarkhe { 240b17fc0a6SManish V Badarkhe if (lfa_component_id >= lfa_component_count) { 241ce78f3cdSManish V Badarkhe return false; 242ce78f3cdSManish V Badarkhe } 243ce78f3cdSManish V Badarkhe 244b17fc0a6SManish V Badarkhe return (current_activation.component_id == lfa_component_id && 245ce78f3cdSManish V Badarkhe current_activation.prime_status == PRIME_COMPLETE && 246b17fc0a6SManish V Badarkhe lfa_components[lfa_component_id].activation_pending == true); 247ce78f3cdSManish V Badarkhe } 248ce78f3cdSManish V Badarkhe 249cf48f49fSManish V Badarkhe int lfa_setup(void) 250cf48f49fSManish V Badarkhe { 251b9dee50cSManish V Badarkhe is_lfa_initialized = lfa_initialize_components(); 252b9dee50cSManish V Badarkhe if (!is_lfa_initialized) { 253b9dee50cSManish V Badarkhe return -1; 254b9dee50cSManish V Badarkhe } 255b9dee50cSManish V Badarkhe 256b9dee50cSManish V Badarkhe lfa_reset_activation(); 257b9dee50cSManish V Badarkhe 258b9dee50cSManish V Badarkhe return 0; 259cf48f49fSManish V Badarkhe } 260cf48f49fSManish V Badarkhe 261cf48f49fSManish V Badarkhe uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, 262cf48f49fSManish V Badarkhe u_register_t x3, u_register_t x4, void *cookie, 263cf48f49fSManish V Badarkhe void *handle, u_register_t flags) 264cf48f49fSManish V Badarkhe { 26506a6f296SManish V Badarkhe uint64_t retx1, retx2; 26667fa182fSManish V Badarkhe uint64_t lfa_flags; 26706a6f296SManish V Badarkhe uint8_t *uuid_p; 26806a6f296SManish V Badarkhe uint32_t fw_seq_id = (uint32_t)x1; 2693f7b2862SManish V Badarkhe int ret; 27006a6f296SManish V Badarkhe 271cf48f49fSManish V Badarkhe /** 272cf48f49fSManish V Badarkhe * TODO: Acquire serialization lock. 273cf48f49fSManish V Badarkhe */ 274b9dee50cSManish V Badarkhe 275b9dee50cSManish V Badarkhe if (!is_lfa_initialized) { 276b9dee50cSManish V Badarkhe return LFA_NOT_SUPPORTED; 277b9dee50cSManish V Badarkhe } 278b9dee50cSManish V Badarkhe 279cf48f49fSManish V Badarkhe switch (smc_fid) { 280cf48f49fSManish V Badarkhe case LFA_VERSION: 281cf48f49fSManish V Badarkhe SMC_RET1(handle, LFA_VERSION_VAL); 282cf48f49fSManish V Badarkhe break; 283cf48f49fSManish V Badarkhe 284cf48f49fSManish V Badarkhe case LFA_FEATURES: 285cf48f49fSManish V Badarkhe SMC_RET1(handle, is_lfa_fid(x1) ? LFA_SUCCESS : LFA_NOT_SUPPORTED); 286cf48f49fSManish V Badarkhe break; 287cf48f49fSManish V Badarkhe 288cf48f49fSManish V Badarkhe case LFA_GET_INFO: 289b9dee50cSManish V Badarkhe /** 290b9dee50cSManish V Badarkhe * The current specification limits this input parameter to be zero for 291b9dee50cSManish V Badarkhe * version 1.0 of LFA 292b9dee50cSManish V Badarkhe */ 293b9dee50cSManish V Badarkhe if (x1 == 0ULL) { 294b9dee50cSManish V Badarkhe SMC_RET3(handle, LFA_SUCCESS, lfa_component_count, 0); 295b9dee50cSManish V Badarkhe } else { 296b9dee50cSManish V Badarkhe SMC_RET1(handle, LFA_INVALID_PARAMETERS); 297b9dee50cSManish V Badarkhe } 298cf48f49fSManish V Badarkhe break; 299cf48f49fSManish V Badarkhe 300cf48f49fSManish V Badarkhe case LFA_GET_INVENTORY: 30106a6f296SManish V Badarkhe if (lfa_component_count == 0U) { 30206a6f296SManish V Badarkhe SMC_RET1(handle, LFA_WRONG_STATE); 30306a6f296SManish V Badarkhe } 30406a6f296SManish V Badarkhe 30506a6f296SManish V Badarkhe /* 30606a6f296SManish V Badarkhe * Check if fw_seq_id is in range. LFA_GET_INFO must be called first to scan 30706a6f296SManish V Badarkhe * platform firmware and create a valid number of firmware components. 30806a6f296SManish V Badarkhe */ 30906a6f296SManish V Badarkhe if (fw_seq_id >= lfa_component_count) { 31006a6f296SManish V Badarkhe SMC_RET1(handle, LFA_INVALID_PARAMETERS); 31106a6f296SManish V Badarkhe } 31206a6f296SManish V Badarkhe 31306a6f296SManish V Badarkhe /* 31406a6f296SManish V Badarkhe * grab the UUID of asked fw_seq_id and set the return UUID 31506a6f296SManish V Badarkhe * variables 31606a6f296SManish V Badarkhe */ 31706a6f296SManish V Badarkhe uuid_p = (uint8_t *)&lfa_components[fw_seq_id].uuid; 31806a6f296SManish V Badarkhe memcpy(&retx1, uuid_p, sizeof(uint64_t)); 31906a6f296SManish V Badarkhe memcpy(&retx2, uuid_p + sizeof(uint64_t), sizeof(uint64_t)); 32006a6f296SManish V Badarkhe 32106a6f296SManish V Badarkhe /* 32206a6f296SManish V Badarkhe * check the given fw_seq_id's update available 32306a6f296SManish V Badarkhe * and accordingly set the active_pending flag 32406a6f296SManish V Badarkhe */ 32506a6f296SManish V Badarkhe lfa_components[fw_seq_id].activation_pending = 32606a6f296SManish V Badarkhe is_plat_lfa_activation_pending(fw_seq_id); 32706a6f296SManish V Badarkhe 32806a6f296SManish V Badarkhe INFO("Component %lu %s live activation:\n", x1, 32906a6f296SManish V Badarkhe lfa_components[fw_seq_id].activator ? "supports" : 33006a6f296SManish V Badarkhe "does not support"); 33106a6f296SManish V Badarkhe 33206a6f296SManish V Badarkhe if (lfa_components[fw_seq_id].activator != NULL) { 33306a6f296SManish V Badarkhe INFO("Activation pending: %s\n", 33406a6f296SManish V Badarkhe lfa_components[fw_seq_id].activation_pending ? "true" : "false"); 33506a6f296SManish V Badarkhe } 33606a6f296SManish V Badarkhe 33706a6f296SManish V Badarkhe INFO("x1 = 0x%016lx, x2 = 0x%016lx\n", retx1, retx2); 33806a6f296SManish V Badarkhe 33906a6f296SManish V Badarkhe SMC_RET4(handle, LFA_SUCCESS, retx1, retx2, get_fw_activation_flags(fw_seq_id)); 34006a6f296SManish V Badarkhe 341cf48f49fSManish V Badarkhe break; 342cf48f49fSManish V Badarkhe 343cf48f49fSManish V Badarkhe case LFA_PRIME: 344c8e08212SVarun Wadekar /* 345c8e08212SVarun Wadekar * Acquire lock to serialize PRIME operations across CPUs. 346c8e08212SVarun Wadekar * This ensures that multiple PRIME calls to the same component 347c8e08212SVarun Wadekar * do not execute concurrently, even if issued from different 348c8e08212SVarun Wadekar * CPUs. 349c8e08212SVarun Wadekar */ 350c8e08212SVarun Wadekar if (!spin_trylock(&lfa_lock)) { 351c8e08212SVarun Wadekar SMC_RET1(handle, LFA_BUSY); 352c8e08212SVarun Wadekar } 353c8e08212SVarun Wadekar 35467fa182fSManish V Badarkhe ret = lfa_prime(x1, &lfa_flags); 355c8e08212SVarun Wadekar 356c8e08212SVarun Wadekar spin_unlock(&lfa_lock); 357c8e08212SVarun Wadekar 35867fa182fSManish V Badarkhe if (ret != LFA_SUCCESS) { 35967fa182fSManish V Badarkhe SMC_RET1(handle, ret); 36067fa182fSManish V Badarkhe } else { 36167fa182fSManish V Badarkhe SMC_RET2(handle, ret, lfa_flags); 36267fa182fSManish V Badarkhe } 363cf48f49fSManish V Badarkhe break; 364cf48f49fSManish V Badarkhe 365cf48f49fSManish V Badarkhe case LFA_ACTIVATE: 36607de22d2SManish V Badarkhe ret = lfa_activate(fw_seq_id, x2, x3, x4); 36707de22d2SManish V Badarkhe /* TODO: implement activate again */ 36807de22d2SManish V Badarkhe SMC_RET2(handle, ret, 0ULL); 36907de22d2SManish V Badarkhe 370cf48f49fSManish V Badarkhe break; 371cf48f49fSManish V Badarkhe 372cf48f49fSManish V Badarkhe case LFA_CANCEL: 3733f7b2862SManish V Badarkhe ret = lfa_cancel(x1); 3743f7b2862SManish V Badarkhe SMC_RET1(handle, ret); 375cf48f49fSManish V Badarkhe break; 376cf48f49fSManish V Badarkhe 377cf48f49fSManish V Badarkhe default: 378cf48f49fSManish V Badarkhe WARN("Unimplemented LFA Service Call: 0x%x\n", smc_fid); 379cf48f49fSManish V Badarkhe SMC_RET1(handle, SMC_UNK); 380cf48f49fSManish V Badarkhe break; /* unreachable */ 381cf48f49fSManish V Badarkhe 382cf48f49fSManish V Badarkhe } 383cf48f49fSManish V Badarkhe 384cf48f49fSManish V Badarkhe SMC_RET1(handle, SMC_UNK); 385cf48f49fSManish V Badarkhe 386cf48f49fSManish V Badarkhe return 0; 387cf48f49fSManish V Badarkhe } 388