feat(rmm): add psci api to realms
add wrappers for PSCI APIs
CPU_ON
CPU_OFF
PSCI_AFFINITY_INFO
PSCI_FEATURES
Signed-off-by: Shruti Gupta <shruti.gupta@arm.com>
Change-Id: Ice7bc03d052a0726163c7a31a32f59688e7f516b
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index 73406f9..ab00989 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -16,6 +16,8 @@
stacks_end:
func realm_entrypoint
+ /* Save x0 - context_id */
+ mov x20, x0
mrs x0, mpidr_el1
mov_imm x1, MPID_MASK
and x0, x0, x1
@@ -26,6 +28,7 @@
/* mpidr 0 is assumed to be primary CPU, jump to warmboot otherwise */
cbnz x0, realm_warmboot_endpoint
+ /* Primary CPU Only */
/* Clear BSS */
ldr x0, =__REALM_BSS_START__
adr x1, realm_entrypoint
@@ -53,7 +56,6 @@
add x1, x1, x0
bl fixup_gdt_reloc
-realm_warmboot_endpoint:
/* Initialize architectural state. */
bl arch_init
#if ENABLE_PAUTH
@@ -64,6 +66,15 @@
/* And jump to the C entrypoint. */
bl realm_payload_main
b loop
+
+realm_warmboot_endpoint:
+ /* Initialize architectural state. */
+ bl arch_init
+#if ENABLE_PAUTH
+ bl pauth_init_enable
+#endif
+ mov x0, x20
+ b realm_secondary_entrypoint
endfunc realm_entrypoint
/*
diff --git a/realm/include/realm_psci.h b/realm/include/realm_psci.h
new file mode 100644
index 0000000..ce41ffb
--- /dev/null
+++ b/realm/include/realm_psci.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+
+void realm_cpu_off(void);
+u_register_t realm_cpu_on(u_register_t mpidr, uintptr_t entrypoint,
+ u_register_t context_id);
+u_register_t realm_psci_affinity_info(u_register_t target_affinity,
+ uint32_t lowest_affinity_level);
+u_register_t realm_psci_features(uint32_t psci_func_id);
diff --git a/realm/realm.mk b/realm/realm.mk
index 77499d0..23ebc0c 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -31,6 +31,7 @@
realm_pauth.c \
realm_payload_main.c \
realm_pmuv3.c \
+ realm_psci.c \
realm_rsi.c \
realm_shared_data.c \
realm_sve.c \
diff --git a/realm/realm_psci.c b/realm/realm_psci.c
new file mode 100644
index 0000000..2a5b951
--- /dev/null
+++ b/realm/realm_psci.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <debug.h>
+#include <psci.h>
+#include <realm_def.h>
+#include <tftf_lib.h>
+
+typedef void (*secondary_ep_t)(u_register_t);
+static secondary_ep_t entrypoint[MAX_REC_COUNT];
+static u_register_t context_id[MAX_REC_COUNT];
+void realm_entrypoint(void);
+void realm_payload_main(void);
+
+void realm_cpu_off(void)
+{
+ smc_args args = { SMC_PSCI_CPU_OFF };
+
+ tftf_smc(&args);
+}
+
+u_register_t realm_cpu_on(u_register_t mpidr, uintptr_t ep, u_register_t cxt_id)
+{
+ smc_args args;
+ smc_ret_values ret_vals;
+
+
+ if (mpidr > MAX_REC_COUNT) {
+ return PSCI_E_INVALID_PARAMS;
+ }
+
+ if (entrypoint[mpidr] != NULL) {
+ return PSCI_E_ALREADY_ON;
+ }
+
+ args.fid = SMC_PSCI_CPU_ON;
+ args.arg1 = mpidr;
+ args.arg2 = (u_register_t)realm_entrypoint;
+ args.arg3 = cxt_id;
+ entrypoint[mpidr] = (secondary_ep_t)ep;
+ context_id[mpidr] = cxt_id;
+ ret_vals = tftf_smc(&args);
+ return ret_vals.ret0;
+}
+
+u_register_t realm_psci_affinity_info(u_register_t target_affinity,
+ uint32_t lowest_affinity_level)
+{
+ smc_args args;
+ smc_ret_values ret_vals;
+
+ args.fid = SMC_PSCI_AFFINITY_INFO;
+ args.arg1 = target_affinity;
+ args.arg2 = lowest_affinity_level;
+ ret_vals = tftf_smc(&args);
+ return ret_vals.ret0;
+}
+
+u_register_t realm_psci_features(uint32_t psci_func_id)
+{
+
+ smc_args args;
+ smc_ret_values ret_vals;
+
+ args.fid = SMC_PSCI_FEATURES;
+ args.arg1 = psci_func_id;
+ ret_vals = tftf_smc(&args);
+ return ret_vals.ret0;
+}
+
+void realm_secondary_entrypoint(u_register_t cxt_id)
+{
+ u_register_t my_mpidr;
+ secondary_ep_t ep;
+
+ my_mpidr = read_mpidr_el1() & MPID_MASK;
+ ep = entrypoint[my_mpidr];
+ if (ep != NULL) {
+ entrypoint[my_mpidr] = NULL;
+ context_id[my_mpidr] = 0;
+ (ep)(context_id[my_mpidr]);
+ } else {
+ /*
+ * Host can execute Rec directly without CPU_ON
+ * from Realm, if Rec is created RUNNABLE
+ * Jump to main in this case.
+ */
+ while (true) {
+ realm_payload_main();
+ }
+ }
+ realm_cpu_off();
+}