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
lfa_rmm_prime(struct lfa_component_status * activation)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
lfa_rmm_activate(struct lfa_component_status * activation,uint64_t ep_address,uint64_t context_id)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 #if RMM_V1_COMPAT
32 cm_el2_sysregs_context_save_gic(NON_SECURE);
33 #endif
34
35 ret = rmmd_primary_activate();
36 cm_el2_sysregs_context_restore(NON_SECURE);
37 #if RMM_V1_COMPAT
38 cm_el2_sysregs_context_restore_gic(NON_SECURE);
39 #endif
40
41 cm_set_next_eret_context(NON_SECURE);
42
43 if (ret == LFA_SUCCESS) {
44 VERBOSE("Successful activation of component %d\n",
45 activation->component_id);
46 } else {
47 ERROR("Failed to activate component %d\n", activation->component_id);
48 ret = LFA_BUSY;
49 }
50
51 lfa_holding_release(ret);
52
53 /**
54 * TODO: avoid race condition trying to prime next firmware
55 * before secondary activations are finished
56 */
57 lfa_reset_activation();
58 } else {
59 ret = lfa_holding_wait();
60
61 if (ret == LFA_SUCCESS) {
62 cm_el2_sysregs_context_save(NON_SECURE);
63 #if RMM_V1_COMPAT
64 cm_el2_sysregs_context_save_gic(NON_SECURE);
65 #endif
66 ret = rmmd_secondary_activate();
67 cm_el2_sysregs_context_restore(NON_SECURE);
68 #if RMM_V1_COMPAT
69 cm_el2_sysregs_context_restore_gic(NON_SECURE);
70 #endif
71 cm_set_next_eret_context(NON_SECURE);
72 }
73 }
74
75 return ret;
76 }
77
78 static struct lfa_component_ops rmm_activator = {
79 .prime = lfa_rmm_prime,
80 .activate = lfa_rmm_activate,
81 .may_reset_cpu = false,
82 .cpu_rendezvous_required = true,
83 };
84
get_rmm_activator(void)85 struct lfa_component_ops *get_rmm_activator(void)
86 {
87 return &rmm_activator;
88 }
89