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