1 /* 2 * Copyright (c) 2025, Arm Limited. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <lib/el3_runtime/context_mgmt.h> 8 #include <plat/common/platform.h> 9 #include <services/lfa_holding_pen.h> 10 #include <services/lfa_svc.h> 11 #include <services/rmmd_rmm_lfa.h> 12 #include <services/rmmd_svc.h> 13 14 static int lfa_rmm_prime(struct lfa_component_status *activation) 15 { 16 /* RMM-specific PRIME actions. Currently, no action is required. */ 17 18 return LFA_SUCCESS; 19 } 20 21 static int lfa_rmm_activate(struct lfa_component_status *activation, 22 uint64_t ep_address, uint64_t context_id) 23 { 24 int ret = LFA_SUCCESS; 25 26 if (lfa_holding_start()) { 27 /* Leader CPU */ 28 INFO("LFA_ACTIVATE: Last CPU proceed with activation\n"); 29 30 cm_el2_sysregs_context_save(NON_SECURE); 31 ret = rmmd_primary_activate(); 32 cm_el2_sysregs_context_restore(NON_SECURE); 33 34 cm_set_next_eret_context(NON_SECURE); 35 36 if (ret == LFA_SUCCESS) { 37 VERBOSE("Successful activation of component %d\n", 38 activation->component_id); 39 } else { 40 ERROR("Failed to activate component %d\n", activation->component_id); 41 ret = LFA_BUSY; 42 } 43 44 lfa_holding_release(ret); 45 46 /** 47 * TODO: avoid race condition trying to prime next firmware 48 * before secondary activations are finished 49 */ 50 lfa_reset_activation(); 51 } else { 52 ret = lfa_holding_wait(); 53 54 if (ret == LFA_SUCCESS) { 55 cm_el2_sysregs_context_save(NON_SECURE); 56 ret = rmmd_secondary_activate(); 57 cm_el2_sysregs_context_restore(NON_SECURE); 58 59 cm_set_next_eret_context(NON_SECURE); 60 } 61 } 62 63 return ret; 64 } 65 66 static struct lfa_component_ops rmm_activator = { 67 .prime = lfa_rmm_prime, 68 .activate = lfa_rmm_activate, 69 .may_reset_cpu = false, 70 .cpu_rendezvous_required = true, 71 }; 72 73 struct lfa_component_ops *get_rmm_activator(void) 74 { 75 return &rmm_activator; 76 } 77