1cf48f49fSManish V Badarkhe /* 2cf48f49fSManish V Badarkhe * Copyright (c) 2025, Arm Limited. All rights reserved. 3cf48f49fSManish V Badarkhe * 4cf48f49fSManish V Badarkhe * SPDX-License-Identifier: BSD-3-Clause 5cf48f49fSManish V Badarkhe */ 6cf48f49fSManish V Badarkhe 7*b9dee50cSManish V Badarkhe #include <plat/common/platform.h> 8*b9dee50cSManish V Badarkhe #include <services/bl31_lfa.h> 9cf48f49fSManish V Badarkhe #include <services/lfa_svc.h> 10*b9dee50cSManish V Badarkhe #include <services/rmmd_rmm_lfa.h> 11cf48f49fSManish V Badarkhe #include <smccc_helpers.h> 12cf48f49fSManish V Badarkhe 13*b9dee50cSManish V Badarkhe static uint32_t lfa_component_count; 14*b9dee50cSManish V Badarkhe static plat_lfa_component_info_t *lfa_components; 15*b9dee50cSManish V Badarkhe static struct lfa_component_status current_activation; 16*b9dee50cSManish V Badarkhe static bool is_lfa_initialized; 17*b9dee50cSManish V Badarkhe 18*b9dee50cSManish V Badarkhe void lfa_reset_activation(void) 19*b9dee50cSManish V Badarkhe { 20*b9dee50cSManish V Badarkhe current_activation.component_id = LFA_INVALID_COMPONENT; 21*b9dee50cSManish V Badarkhe current_activation.prime_status = PRIME_NONE; 22*b9dee50cSManish V Badarkhe } 23*b9dee50cSManish V Badarkhe 24*b9dee50cSManish V Badarkhe static bool lfa_initialize_components(void) 25*b9dee50cSManish V Badarkhe { 26*b9dee50cSManish V Badarkhe lfa_component_count = plat_lfa_get_components(&lfa_components); 27*b9dee50cSManish V Badarkhe 28*b9dee50cSManish V Badarkhe if (lfa_component_count == 0U || lfa_components == NULL) { 29*b9dee50cSManish V Badarkhe /* unlikely to reach here */ 30*b9dee50cSManish V Badarkhe ERROR("Invalid LFA component setup: count = 0 or components are NULL"); 31*b9dee50cSManish V Badarkhe return false; 32*b9dee50cSManish V Badarkhe } 33*b9dee50cSManish V Badarkhe 34*b9dee50cSManish V Badarkhe return true; 35*b9dee50cSManish V Badarkhe } 36*b9dee50cSManish V Badarkhe 37cf48f49fSManish V Badarkhe int lfa_setup(void) 38cf48f49fSManish V Badarkhe { 39*b9dee50cSManish V Badarkhe is_lfa_initialized = lfa_initialize_components(); 40*b9dee50cSManish V Badarkhe if (!is_lfa_initialized) { 41*b9dee50cSManish V Badarkhe return -1; 42*b9dee50cSManish V Badarkhe } 43*b9dee50cSManish V Badarkhe 44*b9dee50cSManish V Badarkhe lfa_reset_activation(); 45*b9dee50cSManish V Badarkhe 46*b9dee50cSManish V Badarkhe return 0; 47cf48f49fSManish V Badarkhe } 48cf48f49fSManish V Badarkhe 49cf48f49fSManish V Badarkhe uint64_t lfa_smc_handler(uint32_t smc_fid, u_register_t x1, u_register_t x2, 50cf48f49fSManish V Badarkhe u_register_t x3, u_register_t x4, void *cookie, 51cf48f49fSManish V Badarkhe void *handle, u_register_t flags) 52cf48f49fSManish V Badarkhe { 53cf48f49fSManish V Badarkhe /** 54cf48f49fSManish V Badarkhe * TODO: Acquire serialization lock. 55cf48f49fSManish V Badarkhe */ 56*b9dee50cSManish V Badarkhe 57*b9dee50cSManish V Badarkhe if (!is_lfa_initialized) { 58*b9dee50cSManish V Badarkhe return LFA_NOT_SUPPORTED; 59*b9dee50cSManish V Badarkhe } 60*b9dee50cSManish V Badarkhe 61cf48f49fSManish V Badarkhe switch (smc_fid) { 62cf48f49fSManish V Badarkhe case LFA_VERSION: 63cf48f49fSManish V Badarkhe SMC_RET1(handle, LFA_VERSION_VAL); 64cf48f49fSManish V Badarkhe break; 65cf48f49fSManish V Badarkhe 66cf48f49fSManish V Badarkhe case LFA_FEATURES: 67cf48f49fSManish V Badarkhe SMC_RET1(handle, is_lfa_fid(x1) ? LFA_SUCCESS : LFA_NOT_SUPPORTED); 68cf48f49fSManish V Badarkhe break; 69cf48f49fSManish V Badarkhe 70cf48f49fSManish V Badarkhe case LFA_GET_INFO: 71*b9dee50cSManish V Badarkhe /** 72*b9dee50cSManish V Badarkhe * The current specification limits this input parameter to be zero for 73*b9dee50cSManish V Badarkhe * version 1.0 of LFA 74*b9dee50cSManish V Badarkhe */ 75*b9dee50cSManish V Badarkhe if (x1 == 0ULL) { 76*b9dee50cSManish V Badarkhe SMC_RET3(handle, LFA_SUCCESS, lfa_component_count, 0); 77*b9dee50cSManish V Badarkhe } else { 78*b9dee50cSManish V Badarkhe SMC_RET1(handle, LFA_INVALID_PARAMETERS); 79*b9dee50cSManish V Badarkhe } 80cf48f49fSManish V Badarkhe break; 81cf48f49fSManish V Badarkhe 82cf48f49fSManish V Badarkhe case LFA_GET_INVENTORY: 83cf48f49fSManish V Badarkhe break; 84cf48f49fSManish V Badarkhe 85cf48f49fSManish V Badarkhe case LFA_PRIME: 86cf48f49fSManish V Badarkhe break; 87cf48f49fSManish V Badarkhe 88cf48f49fSManish V Badarkhe case LFA_ACTIVATE: 89cf48f49fSManish V Badarkhe break; 90cf48f49fSManish V Badarkhe 91cf48f49fSManish V Badarkhe case LFA_CANCEL: 92cf48f49fSManish V Badarkhe break; 93cf48f49fSManish V Badarkhe 94cf48f49fSManish V Badarkhe default: 95cf48f49fSManish V Badarkhe WARN("Unimplemented LFA Service Call: 0x%x\n", smc_fid); 96cf48f49fSManish V Badarkhe SMC_RET1(handle, SMC_UNK); 97cf48f49fSManish V Badarkhe break; /* unreachable */ 98cf48f49fSManish V Badarkhe 99cf48f49fSManish V Badarkhe } 100cf48f49fSManish V Badarkhe 101cf48f49fSManish V Badarkhe SMC_RET1(handle, SMC_UNK); 102cf48f49fSManish V Badarkhe 103cf48f49fSManish V Badarkhe return 0; 104cf48f49fSManish V Badarkhe } 105