summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexeiFedorov <Alexei.Fedorov@arm.com>2023-03-13 19:37:46 +0000
committerSoby Mathew <soby.mathew@arm.com>2023-03-31 11:41:56 +0200
commit2f30f1030f186760b20cd06b59832e332b2bdd0a (patch)
treee06899ba1be405650b4a15603429900dac67ccc2
parent2eb601b98a245df8a31e670a7dc322c2e8f153cf (diff)
feat(rme): add PMU Realm tests
This patch adds Realm PMU payload tests with PMU interrupt handling. Signed-off-by: AlexeiFedorov <Alexei.Fedorov@arm.com> Change-Id: I86ef96252e04c57db385e129227cc0d7dcd1fec2
-rw-r--r--include/common/test_helpers.h4
-rw-r--r--include/drivers/arm/gic_v3.h21
-rw-r--r--include/lib/aarch32/arch.h5
-rw-r--r--include/lib/aarch64/arch.h38
-rw-r--r--include/lib/aarch64/arch_helpers.h21
-rw-r--r--include/runtime_services/host_realm_managment/host_realm_helper.h11
-rw-r--r--include/runtime_services/host_realm_managment/host_realm_mem_layout.h8
-rw-r--r--include/runtime_services/host_realm_managment/host_realm_pmu.h29
-rw-r--r--include/runtime_services/host_realm_managment/host_realm_rmi.h60
-rw-r--r--include/runtime_services/host_realm_managment/host_shared_data.h24
-rw-r--r--include/runtime_services/host_realm_managment/realm_def.h2
-rw-r--r--realm/aarch64/realm_exceptions.S8
-rw-r--r--realm/include/platform.h (renamed from realm/platform.h)8
-rw-r--r--realm/include/realm_rsi.h (renamed from realm/realm_rsi.h)8
-rw-r--r--realm/include/realm_tests.h17
-rw-r--r--realm/realm.mk8
-rw-r--r--realm/realm_interrupt.c20
-rw-r--r--realm/realm_payload_main.c32
-rw-r--r--realm/realm_pmuv3.c316
-rw-r--r--tftf/tests/common/test_helpers.c10
-rw-r--r--tftf/tests/misc_tests/test_invalid_access.c27
-rw-r--r--tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c240
-rw-r--r--tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c147
-rw-r--r--tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c638
-rw-r--r--tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c103
-rw-r--r--tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c16
-rw-r--r--tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c198
-rw-r--r--tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c10
-rw-r--r--tftf/tests/tests-realm-payload.mk5
-rw-r--r--tftf/tests/tests-realm-payload.xml22
-rw-r--r--tftf/tests/tests-standard.mk7
31 files changed, 1504 insertions, 559 deletions
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index aa13a3f..66a5f27 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -443,4 +443,8 @@ void wait_for_non_lead_cpus(void);
* OFF.
*/
void wait_for_core_to_turn_off(unsigned int mpidr);
+
+/* Generate 64-bit random number */
+unsigned long long rand64(void);
+
#endif /* __TEST_HELPERS_H__ */
diff --git a/include/drivers/arm/gic_v3.h b/include/drivers/arm/gic_v3.h
index 0346a23..e164103 100644
--- a/include/drivers/arm/gic_v3.h
+++ b/include/drivers/arm/gic_v3.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -83,6 +83,25 @@
#define IGRPEN1_EL1_ENABLE_SHIFT 0
#define IGRPEN1_EL1_ENABLE_BIT (1 << IGRPEN1_EL1_ENABLE_SHIFT)
+/* ICH_ICH_LR<n>_EL2 definitions */
+#define ICH_LRn_EL2_STATE_Invalid (0UL << 62)
+#define ICH_LRn_EL2_STATE_Pending (1UL << 62)
+#define ICH_LRn_EL2_STATE_Active (2UL << 62)
+#define ICH_LRn_EL2_STATE_Pending_Active (3UL << 62)
+#define ICH_LRn_EL2_Group_0 (0UL << 60)
+#define ICH_LRn_EL2_Group_1 (1UL << 60)
+#define ICH_LRn_EL2_Priority_SHIFT 48
+#define ICH_LRn_EL2_Priority_MASK 0xFF
+#define ICH_LRn_EL2_vINTID_SHIFT 0
+#define ICH_LRn_EL2_vINTID_MASK 0xFFFF
+
+/* ICV_CTLR_EL1 definitions */
+#define ICV_CTLR_EL1_PRIbits_SHIFT 8
+#define ICV_CTLR_EL1_PRIbits_MASK 7
+
+/* ICV_IGRPEN1_EL1 definition */
+#define ICV_IGRPEN1_EL1_Enable 1UL
+
/* The highest affinity 0 that can be a SGI target*/
#define SGI_TARGET_MAX_AFF0 16
diff --git a/include/lib/aarch32/arch.h b/include/lib/aarch32/arch.h
index 230d69a..53ef4ba 100644
--- a/include/lib/aarch32/arch.h
+++ b/include/lib/aarch32/arch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2022, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -440,10 +440,11 @@
/* PMCCFILTR definitions */
#define PMCCFILTR_EL0_P_BIT (U(1) << 31)
+#define PMCCFILTR_EL0_U_BIT (U(1) << 30)
#define PMCCFILTR_EL0_NSK_BIT (U(1) << 29)
+#define PMCCFILTR_EL0_NSU_BIT (U(1) << 28)
#define PMCCFILTR_EL0_NSH_BIT (U(1) << 27)
#define PMCCFILTR_EL0_M_BIT (U(1) << 26)
-#define PMCCFILTR_EL0_MT_BIT (U(1) << 25)
#define PMCCFILTR_EL0_SH_BIT (U(1) << 24)
/* PMU event counter ID definitions */
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index e48e51c..f43bc8a 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -85,15 +85,21 @@
#define ICC_CTLR_EL3 S3_6_C12_C12_4
#define ICC_PMR_EL1 S3_0_C4_C6_0
#define ICC_RPR_EL1 S3_0_C12_C11_3
-#define ICC_IGRPEN1_EL3 S3_6_c12_c12_7
-#define ICC_IGRPEN0_EL1 S3_0_c12_c12_6
-#define ICC_HPPIR0_EL1 S3_0_c12_c8_2
-#define ICC_HPPIR1_EL1 S3_0_c12_c12_2
-#define ICC_IAR0_EL1 S3_0_c12_c8_0
-#define ICC_IAR1_EL1 S3_0_c12_c12_0
-#define ICC_EOIR0_EL1 S3_0_c12_c8_1
-#define ICC_EOIR1_EL1 S3_0_c12_c12_1
-#define ICC_SGI0R_EL1 S3_0_c12_c11_7
+#define ICC_IGRPEN1_EL3 S3_6_C12_C12_7
+#define ICC_IGRPEN0_EL1 S3_0_C12_C12_6
+#define ICC_HPPIR0_EL1 S3_0_C12_C8_2
+#define ICC_HPPIR1_EL1 S3_0_C12_C12_2
+#define ICC_IAR0_EL1 S3_0_C12_C8_0
+#define ICC_IAR1_EL1 S3_0_C12_C12_0
+#define ICC_EOIR0_EL1 S3_0_C12_C8_1
+#define ICC_EOIR1_EL1 S3_0_C12_C12_1
+#define ICC_SGI0R_EL1 S3_0_C12_C11_7
+
+#define ICV_CTRL_EL1 S3_0_C12_C12_4
+#define ICV_IAR1_EL1 S3_0_C12_C12_0
+#define ICV_IGRPEN1_EL1 S3_0_C12_C12_7
+#define ICV_EOIR1_EL1 S3_0_C12_C12_1
+#define ICV_PMR_EL1 S3_0_C4_C6_0
/*******************************************************************************
* Generic timer memory mapped registers & offsets
@@ -808,20 +814,30 @@
/* PMEVTYPER<n>_EL0 definitions */
#define PMEVTYPER_EL0_P_BIT (U(1) << 31)
+#define PMEVTYPER_EL0_U_BIT (U(1) << 30)
#define PMEVTYPER_EL0_NSK_BIT (U(1) << 29)
+#define PMEVTYPER_EL0_NSU_BIT (U(1) << 28)
#define PMEVTYPER_EL0_NSH_BIT (U(1) << 27)
#define PMEVTYPER_EL0_M_BIT (U(1) << 26)
#define PMEVTYPER_EL0_MT_BIT (U(1) << 25)
#define PMEVTYPER_EL0_SH_BIT (U(1) << 24)
+#define PMEVTYPER_EL0_T_BIT (U(1) << 23)
+#define PMEVTYPER_EL0_RLK_BIT (U(1) << 22)
+#define PMEVTYPER_EL0_RLU_BIT (U(1) << 21)
+#define PMEVTYPER_EL0_RLH_BIT (U(1) << 20)
#define PMEVTYPER_EL0_EVTCOUNT_BITS U(0x0000FFFF)
/* PMCCFILTR_EL0 definitions */
#define PMCCFILTR_EL0_P_BIT (U(1) << 31)
+#define PMCCFILTR_EL0_U_BIT (U(1) << 30)
#define PMCCFILTR_EL0_NSK_BIT (U(1) << 29)
#define PMCCFILTR_EL0_NSH_BIT (U(1) << 27)
#define PMCCFILTR_EL0_M_BIT (U(1) << 26)
-#define PMCCFILTR_EL0_MT_BIT (U(1) << 25)
#define PMCCFILTR_EL0_SH_BIT (U(1) << 24)
+#define PMCCFILTR_EL0_T_BIT (U(1) << 23)
+#define PMCCFILTR_EL0_RLK_BIT (U(1) << 22)
+#define PMCCFILTR_EL0_RLU_BIT (U(1) << 21)
+#define PMCCFILTR_EL0_RLH_BIT (U(1) << 20)
/* PMSELR_EL0 definitions */
#define PMSELR_EL0_SEL_SHIFT U(0)
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index f79174e..7c3ffc5 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -409,16 +409,22 @@ DEFINE_SYSREG_READ_FUNC(isr_el1)
DEFINE_SYSREG_RW_FUNCS(mdcr_el2)
DEFINE_SYSREG_RW_FUNCS(mdcr_el3)
DEFINE_SYSREG_RW_FUNCS(hstr_el2)
+
DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcntenclr_el0)
DEFINE_SYSREG_RW_FUNCS(pmcntenset_el0)
-DEFINE_SYSREG_READ_FUNC(pmccntr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmccntr_el0)
DEFINE_SYSREG_RW_FUNCS(pmccfiltr_el0)
-
DEFINE_SYSREG_RW_FUNCS(pmevtyper0_el0)
-DEFINE_SYSREG_READ_FUNC(pmevcntr0_el0)
+DEFINE_SYSREG_RW_FUNCS(pmevcntr0_el0)
+DEFINE_SYSREG_RW_FUNCS(pmovsclr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmovsset_el0)
DEFINE_SYSREG_RW_FUNCS(pmselr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmuserenr_el0);
DEFINE_SYSREG_RW_FUNCS(pmxevtyper_el0)
DEFINE_SYSREG_RW_FUNCS(pmxevcntr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmintenclr_el1)
+DEFINE_SYSREG_RW_FUNCS(pmintenset_el1)
/* parameterised event counter accessors */
static inline u_register_t read_pmevcntrn_el0(int ctr_num)
@@ -450,7 +456,6 @@ DEFINE_SYSREG_READ_FUNC(rndr)
DEFINE_SYSREG_READ_FUNC(rndrrs)
/* GICv3 System Registers */
-
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el1, ICC_SRE_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el2, ICC_SRE_EL2)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sre_el3, ICC_SRE_EL3)
@@ -468,6 +473,12 @@ DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_eoir1_el1, ICC_EOIR1_EL1)
DEFINE_RENAME_SYSREG_WRITE_FUNC(icc_sgi0r_el1, ICC_SGI0R_EL1)
DEFINE_RENAME_SYSREG_RW_FUNCS(icc_sgi1r, ICC_SGI1R)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icv_ctrl_el1, ICV_CTRL_EL1)
+DEFINE_RENAME_SYSREG_READ_FUNC(icv_iar1_el1, ICV_IAR1_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icv_igrpen1_el1, ICV_IGRPEN1_EL1)
+DEFINE_RENAME_SYSREG_WRITE_FUNC(icv_eoir1_el1, ICV_EOIR1_EL1)
+DEFINE_RENAME_SYSREG_RW_FUNCS(icv_pmr_el1, ICV_PMR_EL1)
+
DEFINE_RENAME_SYSREG_RW_FUNCS(amcr_el0, AMCR_EL0)
DEFINE_RENAME_SYSREG_RW_FUNCS(amcgcr_el0, AMCGCR_EL0)
DEFINE_RENAME_SYSREG_READ_FUNC(amcfgr_el0, AMCFGR_EL0)
diff --git a/include/runtime_services/host_realm_managment/host_realm_helper.h b/include/runtime_services/host_realm_managment/host_realm_helper.h
index 255f257..6269efd 100644
--- a/include/runtime_services/host_realm_managment/host_realm_helper.h
+++ b/include/runtime_services/host_realm_managment/host_realm_helper.h
@@ -1,24 +1,25 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef HOST_REALM_HELPER_H
#define HOST_REALM_HELPER_H
+#include <stdlib.h>
#include <host_realm_rmi.h>
+#include <tftf_lib.h>
bool host_create_realm_payload(u_register_t realm_payload_adr,
u_register_t plat_mem_pool_adr,
u_register_t plat_mem_pool_size,
- u_register_t realm_pages_size);
+ u_register_t realm_pages_size,
+ u_register_t feature_flag);
bool host_create_shared_mem(
u_register_t ns_shared_mem_adr,
u_register_t ns_shared_mem_size);
bool host_destroy_realm(void);
-bool host_enter_realm_execute(uint8_t cmd);
-
+bool host_enter_realm_execute(uint8_t cmd, struct realm **realm_ptr);
test_result_t host_cmp_result(void);
#endif /* HOST_REALM_HELPER_H */
-
diff --git a/include/runtime_services/host_realm_managment/host_realm_mem_layout.h b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
index 2c5a605..6e94b30 100644
--- a/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
+++ b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -35,13 +35,13 @@
/*
* Default values defined in platform.mk, and can be provided as build arguments
- * TFTF_MAX_IMAGE_SIZE: 1mb
+ * TFTF_MAX_IMAGE_SIZE: 1MB
*/
#ifdef TFTF_MAX_IMAGE_SIZE
-/* 1MB for shared buffer between Realm and Host*/
+/* 1MB for shared buffer between Realm and Host */
#define NS_REALM_SHARED_MEM_SIZE U(0x100000)
-/* 3MB of memory used as a pool for realm's objects creation*/
+/* 3MB of memory used as a pool for realm's objects creation */
#define PAGE_POOL_MAX_SIZE U(0x300000)
/* Base address of each section */
#define REALM_IMAGE_BASE (TFTF_BASE + TFTF_MAX_IMAGE_SIZE)
diff --git a/include/runtime_services/host_realm_managment/host_realm_pmu.h b/include/runtime_services/host_realm_managment/host_realm_pmu.h
new file mode 100644
index 0000000..48089f3
--- /dev/null
+++ b/include/runtime_services/host_realm_managment/host_realm_pmu.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef HOST_REALM_PMU_H
+#define HOST_REALM_PMU_H
+
+#include <arch_helpers.h>
+
+/* PMU physical interrupt */
+#define PMU_PPI 23UL
+
+/* PMU virtual interrupt */
+#define PMU_VIRQ PMU_PPI
+
+/* Clear bits P0-P30, C and F0 */
+#define PMU_CLEAR_ALL 0x1FFFFFFFF
+
+/* Number of event counters implemented */
+#define GET_CNT_NUM \
+ ((read_pmcr_el0() >> PMCR_EL0_N_SHIFT) & PMCR_EL0_N_MASK)
+
+void host_set_pmu_state(void);
+bool host_check_pmu_state(void);
+
+#endif /* HOST_REALM_PMU_H */
diff --git a/include/runtime_services/host_realm_managment/host_realm_rmi.h b/include/runtime_services/host_realm_managment/host_realm_rmi.h
index dcf0982..923c003 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -9,8 +9,8 @@
#define HOST_REALM_RMI_H
#include <stdint.h>
+#include <stdbool.h>
-#include <realm_rsi.h>
#include <smccc.h>
#include <utils_def.h>
@@ -426,7 +426,13 @@ struct rmi_rec_exit {
unsigned char ripas_value; /* 0x510 */
}, 0x500, 0x600);
/* Host call immediate value */
- SET_MEMBER(unsigned int imm, 0x600, 0x800); /* 0x600 */
+ SET_MEMBER(unsigned int imm, 0x600, 0x700); /* 0x600 */
+ /* PMU overflow */
+ SET_MEMBER(unsigned long pmu_ovf, 0x700, 0x708); /* 0x700 */
+ /* PMU interrupt enable */
+ SET_MEMBER(unsigned long pmu_intr_en, 0x708, 0x710); /* 0x708 */
+ /* PMU counter enable */
+ SET_MEMBER(unsigned long pmu_cntr_en, 0x710, 0x800); /* 0x710 */
};
/*
@@ -469,34 +475,28 @@ struct realm {
};
/* RMI/SMC */
-u_register_t rmi_version(void);
-u_register_t rmi_granule_delegate(u_register_t addr);
-u_register_t rmi_granule_undelegate(u_register_t addr);
-u_register_t rmi_realm_create(u_register_t rd, u_register_t params_ptr);
-u_register_t rmi_realm_destroy(u_register_t rd);
-u_register_t rmi_features(u_register_t index, u_register_t *features);
+u_register_t host_rmi_version(void);
+u_register_t host_rmi_granule_delegate(u_register_t addr);
+u_register_t host_rmi_granule_undelegate(u_register_t addr);
+u_register_t host_rmi_realm_create(u_register_t rd, u_register_t params_ptr);
+u_register_t host_rmi_realm_destroy(u_register_t rd);
+u_register_t host_rmi_features(u_register_t index, u_register_t *features);
/* Realm management */
-u_register_t realm_map_protected_data_unknown(struct realm *realm,
- u_register_t target_pa,
- u_register_t map_size);
-u_register_t realm_create(struct realm *realm);
-u_register_t realm_map_payload_image(struct realm *realm,
- u_register_t realm_payload_adr);
-u_register_t realm_map_ns_shared(struct realm *realm,
- u_register_t ns_shared_mem_adr,
- u_register_t ns_shared_mem_size);
-u_register_t realm_rec_create(struct realm *realm);
-u_register_t realm_activate(struct realm *realm);
-u_register_t realm_destroy(struct realm *realm);
-u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
- unsigned int *test_result);
-u_register_t realm_init_ipa_state(struct realm *realm,
- u_register_t level,
- u_register_t start,
- uint64_t end);
-test_result_t realm_cmp_result(void);
-void rmi_init_cmp_result(void);
-bool rmi_get_cmp_result(void);
+u_register_t host_realm_create(struct realm *realm);
+u_register_t host_realm_map_payload_image(struct realm *realm,
+ u_register_t realm_payload_adr);
+u_register_t host_realm_map_ns_shared(struct realm *realm,
+ u_register_t ns_shared_mem_adr,
+ u_register_t ns_shared_mem_size);
+u_register_t host_realm_rec_create(struct realm *realm);
+u_register_t host_realm_activate(struct realm *realm);
+u_register_t host_realm_destroy(struct realm *realm);
+u_register_t host_realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
+ unsigned int *host_call_result);
+u_register_t host_realm_init_ipa_state(struct realm *realm, u_register_t level,
+ u_register_t start, uint64_t end);
+void host_rmi_init_cmp_result(void);
+bool host_rmi_get_cmp_result(void);
#endif /* HOST_REALM_RMI_H */
diff --git a/include/runtime_services/host_realm_managment/host_shared_data.h b/include/runtime_services/host_realm_managment/host_shared_data.h
index 9c9cc8c..ca379e2 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -18,16 +18,16 @@
* payload
*/
typedef struct host_shared_data {
- /* Buffer used from Realm for logging*/
+ /* Buffer used from Realm for logging */
uint8_t log_buffer[MAX_BUF_SIZE];
- /* Command set from Host and used by Realm*/
+ /* Command set from Host and used by Realm */
uint8_t realm_cmd;
- /* array of params passed from Host to Realm*/
+ /* array of params passed from Host to Realm */
u_register_t host_param_val[MAX_DATA_SIZE];
- /* array of output results passed from Realm to Host*/
+ /* array of output results passed from Realm to Host */
u_register_t realm_out_val[MAX_DATA_SIZE];
/* Lock to avoid concurrent accesses to log_buffer */
@@ -39,7 +39,11 @@ typedef struct host_shared_data {
*/
enum realm_cmd {
REALM_SLEEP_CMD = 1U,
- REALM_GET_RSI_VERSION
+ REALM_GET_RSI_VERSION,
+ REALM_PMU_CYCLE,
+ REALM_PMU_EVENT,
+ REALM_PMU_PRESERVE,
+ REALM_PMU_INTERRUPT
};
/*
@@ -49,10 +53,18 @@ enum host_param_index {
HOST_CMD_INDEX = 0U,
HOST_SLEEP_INDEX
};
+
+enum host_call_cmd {
+ HOST_CALL_GET_SHARED_BUFF_CMD = 1U,
+ HOST_CALL_EXIT_SUCCESS_CMD,
+ HOST_CALL_EXIT_FAILED_CMD
+};
+
/*
* Return shared buffer pointer mapped as host_shared_data_t structure
*/
host_shared_data_t *host_get_shared_structure(void);
+
/*
* Set data to be shared from Host to realm
*/
diff --git a/include/runtime_services/host_realm_managment/realm_def.h b/include/runtime_services/host_realm_managment/realm_def.h
index 22cd380..618007e 100644
--- a/include/runtime_services/host_realm_managment/realm_def.h
+++ b/include/runtime_services/host_realm_managment/realm_def.h
@@ -10,7 +10,7 @@
#include <xlat_tables_defs.h>
-/* 1mb for Realm payload as a default value*/
+/* 1MB for Realm payload as a default value */
#define REALM_MAX_LOAD_IMG_SIZE U(0x100000)
#define REALM_STACK_SIZE 0x1000U
#define DATA_PATTERN_1 0x12345678U
diff --git a/realm/aarch64/realm_exceptions.S b/realm/aarch64/realm_exceptions.S
index 6ce8810..99b601d 100644
--- a/realm/aarch64/realm_exceptions.S
+++ b/realm/aarch64/realm_exceptions.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,7 +14,7 @@
*/
.macro unhandled_exception name
vector_entry \name
- b crash_dump
+ b crash_dump
end_vector_entry \name
.endm
@@ -106,11 +106,11 @@ func sync_exception_vector_entry
mov x19, sp
bl tftf_sync_exception_handler
cbnz x0, 0f
- mov x0, x19
+ mov x0, x19
/* Save original stack pointer value on the stack */
add x1, x0, #0x100
str x1, [x0, #0xf8]
- b print_exception
+ b print_exception
0: restore_gp_regs
add sp, sp, #0x100
eret
diff --git a/realm/platform.h b/realm/include/platform.h
index 2c6ad27..de91c16 100644
--- a/realm/platform.h
+++ b/realm/include/platform.h
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
-#ifndef REALM_PLATFORM_H
-#define REALM_PLATFORM_H
+#ifndef PLATFORM_H
+#define PLATFORM_H
/*
* Helper that returns a linear core ID from a MPID
@@ -17,4 +17,4 @@ unsigned int platform_get_core_pos(u_register_t mpid)
return 0U;
}
-#endif /* REALM_PLATFORM_H */
+#endif /* PLATFORM_H */
diff --git a/realm/realm_rsi.h b/realm/include/realm_rsi.h
index 34721cd..c7ea5a5 100644
--- a/realm/realm_rsi.h
+++ b/realm/include/realm_rsi.h
@@ -9,6 +9,7 @@
#define REALM_RSI_H
#include <stdint.h>
+#include <host_shared_data.h>
#include <tftf_lib.h>
#define SMC_RSI_CALL_BASE 0xC4000190
@@ -63,12 +64,6 @@ typedef enum {
RSI_ERROR_COUNT
} rsi_status_t;
-enum host_call_cmd {
- HOST_CALL_GET_SHARED_BUFF_CMD = 1U,
- HOST_CALL_EXIT_SUCCESS_CMD,
- HOST_CALL_EXIT_FAILED_CMD
-};
-
struct rsi_realm_config {
/* IPA width in bits */
SET_MEMBER(unsigned long ipa_width, 0, 0x1000); /* Offset 0 */
@@ -100,6 +95,7 @@ struct rsi_host_call {
#define RSI_ABI_VERSION SMC_RSI_FID(0U)
+
/*
* arg0 == struct rsi_realm_config address
*/
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
new file mode 100644
index 0000000..0e653ba
--- /dev/null
+++ b/realm/include/realm_tests.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef REALM_TESTS_H
+#define REALM_TESTS_H
+
+bool test_pmuv3_cycle_works_realm(void);
+bool test_pmuv3_event_works_realm(void);
+bool test_pmuv3_rmm_preserves(void);
+bool test_pmuv3_overflow_interrupt(void);
+
+#endif /* REALM_TESTS_H */
+
diff --git a/realm/realm.mk b/realm/realm.mk
index 638f02e..b033627 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2022, Arm Limited. All rights reserved.
+# Copyright (c) 2022-2023, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -18,15 +18,17 @@ REALM_INCLUDES := \
-Iinclude/runtime_services \
-Iinclude/runtime_services/host_realm_managment \
-Irealm \
- -Irealm/aarch64
+ -Irealm/aarch64 \
+ -Irealm/include
REALM_SOURCES:= \
$(addprefix realm/, \
aarch64/realm_entrypoint.S \
aarch64/realm_exceptions.S \
realm_debug.c \
- realm_payload_main.c \
realm_interrupt.c \
+ realm_payload_main.c \
+ realm_pmuv3.c \
realm_rsi.c \
realm_shared_data.c \
)
diff --git a/realm/realm_interrupt.c b/realm/realm_interrupt.c
index 02ab55c..7f8dc15 100644
--- a/realm/realm_interrupt.c
+++ b/realm/realm_interrupt.c
@@ -1,13 +1,27 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <arch_helpers.h>
#include <debug.h>
+#include <host_realm_pmu.h>
-/* dummy interrupt handler as for now*/
+/* Realm interrupt handler */
void realm_interrupt_handler(void)
{
- INFO("%s\n", __func__);
+ /* Read INTID and acknowledge interrupt */
+ unsigned long iar1_el1 = read_icv_iar1_el1();
+
+ /* Deactivate interrupt */
+ write_icv_eoir1_el1(iar1_el1);
+
+ /* Clear PMU interrupt */
+ if (iar1_el1 == PMU_VIRQ) {
+ write_pmintenclr_el1(read_pmintenset_el1());
+ isb();
+ } else {
+ panic();
+ }
}
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index bd4dec7..414c329 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -12,17 +12,18 @@
#include <host_shared_data.h>
#include "realm_def.h"
#include <realm_rsi.h>
+#include <realm_tests.h>
#include <tftf_lib.h>
/*
- * This function reads sleep time in ms from shared buffer and spins PE in a loop
- * for that time period.
+ * This function reads sleep time in ms from shared buffer and spins PE
+ * in a loop for that time period.
*/
static void realm_sleep_cmd(void)
{
uint64_t sleep = realm_shared_data_get_host_val(HOST_SLEEP_INDEX);
- INFO("REALM_PAYLOAD: Realm payload going to sleep for %llums\n", sleep);
+ realm_printf("Realm: going to sleep for %llums\n", sleep);
waitms(sleep);
}
@@ -35,11 +36,11 @@ static void realm_get_rsi_version(void)
version = rsi_get_version();
if (version == (u_register_t)SMC_UNKNOWN) {
- ERROR("SMC_RSI_ABI_VERSION failed (%ld)", (long)version);
+ realm_printf("SMC_RSI_ABI_VERSION failed (%ld)", (long)version);
return;
}
- INFO("RSI ABI version %u.%u (expected: %u.%u)",
+ realm_printf("RSI ABI version %u.%u (expected: %u.%u)",
RSI_ABI_VERSION_GET_MAJOR(version),
RSI_ABI_VERSION_GET_MINOR(version),
RSI_ABI_VERSION_GET_MAJOR(RSI_ABI_VERSION),
@@ -56,12 +57,13 @@ static void realm_get_rsi_version(void)
*/
void realm_payload_main(void)
{
- uint8_t cmd = 0U;
bool test_succeed = false;
realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
+
if (realm_get_shared_structure() != NULL) {
- cmd = realm_shared_data_get_realm_cmd();
+ uint8_t cmd = realm_shared_data_get_realm_cmd();
+
switch (cmd) {
case REALM_SLEEP_CMD:
realm_sleep_cmd();
@@ -71,8 +73,20 @@ void realm_payload_main(void)
realm_get_rsi_version();
test_succeed = true;
break;
+ case REALM_PMU_CYCLE:
+ test_succeed = test_pmuv3_cycle_works_realm();
+ break;
+ case REALM_PMU_EVENT:
+ test_succeed = test_pmuv3_event_works_realm();
+ break;
+ case REALM_PMU_PRESERVE:
+ test_succeed = test_pmuv3_rmm_preserves();
+ break;
+ case REALM_PMU_INTERRUPT:
+ test_succeed = test_pmuv3_overflow_interrupt();
+ break;
default:
- INFO("REALM_PAYLOAD: %s invalid cmd=%hhu", __func__, cmd);
+ realm_printf("%s() invalid cmd %u\n", __func__, cmd);
break;
}
}
diff --git a/realm/realm_pmuv3.c b/realm/realm_pmuv3.c
new file mode 100644
index 0000000..862e93e
--- /dev/null
+++ b/realm/realm_pmuv3.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <arm_arch_svc.h>
+#include <debug.h>
+#include <drivers/arm/gic_v3.h>
+
+#include <host_realm_pmu.h>
+#include <realm_rsi.h>
+
+/* PMUv3 events */
+#define PMU_EVT_SW_INCR 0x0
+#define PMU_EVT_INST_RETIRED 0x8
+#define PMU_EVT_CPU_CYCLES 0x11
+#define PMU_EVT_MEM_ACCESS 0x13
+
+#define NOP_REPETITIONS 50
+#define MAX_COUNTERS 32
+
+#define PRE_OVERFLOW ~(0xF)
+
+#define DELAY_MS 3000ULL
+
+static inline void read_all_counters(u_register_t *array, int impl_ev_ctrs)
+{
+ array[0] = read_pmccntr_el0();
+ for (unsigned int i = 0U; i < impl_ev_ctrs; i++) {
+ array[i + 1] = read_pmevcntrn_el0(i);
+ }
+}
+
+static inline void read_all_counter_configs(u_register_t *array, int impl_ev_ctrs)
+{
+ array[0] = read_pmccfiltr_el0();
+ for (unsigned int i = 0U; i < impl_ev_ctrs; i++) {
+ array[i + 1] = read_pmevtypern_el0(i);
+ }
+}
+
+static inline void read_all_pmu_configs(u_register_t *array)
+{
+ array[0] = read_pmcntenset_el0();
+ array[1] = read_pmcr_el0();
+ array[2] = read_pmselr_el0();
+}
+
+static inline void enable_counting(void)
+{
+ write_pmcr_el0(read_pmcr_el0() | PMCR_EL0_E_BIT);
+ /* This function means we are about to use the PMU, synchronize */
+ isb();
+}
+
+static inline void disable_counting(void)
+{
+ write_pmcr_el0(read_pmcr_el0() & ~PMCR_EL0_E_BIT);
+ /* We also rely that disabling really did work */
+ isb();
+}
+
+static inline void clear_counters(void)
+{
+ write_pmcr_el0(read_pmcr_el0() | PMCR_EL0_C_BIT | PMCR_EL0_P_BIT);
+ isb();
+}
+
+static void pmu_reset(void)
+{
+ /* Reset all counters */
+ write_pmcr_el0(read_pmcr_el0() |
+ PMCR_EL0_DP_BIT | PMCR_EL0_C_BIT | PMCR_EL0_P_BIT);
+
+ /* Disable all counters */
+ write_pmcntenclr_el0(PMU_CLEAR_ALL);
+
+ /* Clear overflow status */
+ write_pmovsclr_el0(PMU_CLEAR_ALL);
+
+ /* Disable overflow interrupts on all counters */
+ write_pmintenclr_el1(PMU_CLEAR_ALL);
+ isb();
+}
+
+/*
+ * This test runs in Realm EL1, don't bother enabling counting at lower ELs
+ * and secure world. TF-A has other controls for them and counting there
+ * doesn't impact us.
+ */
+static inline void enable_cycle_counter(void)
+{
+ /*
+ * Set PMCCFILTR_EL0.U != PMCCFILTR_EL0.RLU
+ * to disable counting in Realm EL0.
+ * Set PMCCFILTR_EL0.P = PMCCFILTR_EL0.RLK
+ * to enable counting in Realm EL1.
+ * Set PMCCFILTR_EL0.NSH = PMCCFILTR_EL0_EL0.RLH
+ * to disable event counting in Realm EL2.
+ */
+ write_pmccfiltr_el0(PMCCFILTR_EL0_U_BIT |
+ PMCCFILTR_EL0_P_BIT | PMCCFILTR_EL0_RLK_BIT |
+ PMCCFILTR_EL0_NSH_BIT | PMCCFILTR_EL0_RLH_BIT);
+ write_pmcntenset_el0(read_pmcntenset_el0() | PMCNTENSET_EL0_C_BIT);
+ isb();
+}
+
+static inline void enable_event_counter(int ctr_num)
+{
+ /*
+ * Set PMEVTYPER_EL0.U != PMEVTYPER_EL0.RLU
+ * to disable event counting in Realm EL0.
+ * Set PMEVTYPER_EL0.P = PMEVTYPER_EL0.RLK
+ * to enable counting in Realm EL1.
+ * Set PMEVTYPER_EL0.NSH = PMEVTYPER_EL0.RLH
+ * to disable event counting in Realm EL2.
+ */
+ write_pmevtypern_el0(ctr_num,
+ PMEVTYPER_EL0_U_BIT |
+ PMEVTYPER_EL0_P_BIT | PMEVTYPER_EL0_RLK_BIT |
+ PMEVTYPER_EL0_NSH_BIT | PMEVTYPER_EL0_RLH_BIT |
+ (PMU_EVT_INST_RETIRED & PMEVTYPER_EL0_EVTCOUNT_BITS));
+ write_pmcntenset_el0(read_pmcntenset_el0() |
+ PMCNTENSET_EL0_P_BIT(ctr_num));
+ isb();
+}
+
+/* Doesn't really matter what happens, as long as it happens a lot */
+static inline void execute_nops(void)
+{
+ for (unsigned int i = 0U; i < NOP_REPETITIONS; i++) {
+ __asm__ ("orr x0, x0, x0\n");
+ }
+}
+
+/*
+ * Try the cycle counter with some NOPs to see if it works
+ */
+bool test_pmuv3_cycle_works_realm(void)
+{
+ u_register_t ccounter_start;
+ u_register_t ccounter_end;
+
+ pmu_reset();
+
+ enable_cycle_counter();
+ enable_counting();
+
+ ccounter_start = read_pmccntr_el0();
+ execute_nops();
+ ccounter_end = read_pmccntr_el0();
+ disable_counting();
+ clear_counters();
+
+ realm_printf("Realm: counted from %lu to %lu\n",
+ ccounter_start, ccounter_end);
+ if (ccounter_start != ccounter_end) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Try an event counter with some NOPs to see if it works.
+ */
+bool test_pmuv3_event_works_realm(void)
+{
+ u_register_t evcounter_start;
+ u_register_t evcounter_end;
+
+ if (GET_CNT_NUM == 0) {
+ realm_printf("Realm: no event counters implemented\n");
+ return false;
+ }
+
+ pmu_reset();
+
+ enable_event_counter(0);
+ enable_counting();
+
+ /*
+ * If any is enabled it will be in the first range.
+ */
+ evcounter_start = read_pmevcntrn_el0(0);
+ execute_nops();
+ disable_counting();
+ evcounter_end = read_pmevcntrn_el0(0);
+ clear_counters();
+
+ realm_printf("Realm: counted from %lu to %lu\n",
+ evcounter_start, evcounter_end);
+ if (evcounter_start != evcounter_end) {
+ return true;
+ }
+ return false;
+}
+
+/*
+ * Check if entering/exiting RMM (with a NOP) preserves all PMU registers.
+ */
+bool test_pmuv3_rmm_preserves(void)
+{
+ u_register_t ctr_start[MAX_COUNTERS] = {0};
+ u_register_t ctr_cfg_start[MAX_COUNTERS] = {0};
+ u_register_t pmu_cfg_start[3];
+ u_register_t ctr_end[MAX_COUNTERS] = {0};
+ u_register_t ctr_cfg_end[MAX_COUNTERS] = {0};
+ u_register_t pmu_cfg_end[3];
+ unsigned int impl_ev_ctrs = GET_CNT_NUM;
+
+ realm_printf("Realm: testing %u event counters\n", impl_ev_ctrs);
+
+ pmu_reset();
+
+ /* Pretend counters have just been used */
+ enable_cycle_counter();
+ enable_event_counter(0);
+ enable_counting();
+ execute_nops();
+ disable_counting();
+
+ /* Get before reading */
+ read_all_counters(ctr_start, impl_ev_ctrs);
+ read_all_counter_configs(ctr_cfg_start, impl_ev_ctrs);
+ read_all_pmu_configs(pmu_cfg_start);
+
+ /* Give RMM a chance to scramble everything */
+ (void)rsi_get_version();
+
+ /* Get after reading */
+ read_all_counters(ctr_end, impl_ev_ctrs);
+ read_all_counter_configs(ctr_cfg_end, impl_ev_ctrs);
+ read_all_pmu_configs(pmu_cfg_end);
+
+ if (memcmp(ctr_start, ctr_end, sizeof(ctr_start)) != 0) {
+ realm_printf("Realm: SMC call did not preserve %s\n",
+ "counters");
+ return false;
+ }
+
+ if (memcmp(ctr_cfg_start, ctr_cfg_end, sizeof(ctr_cfg_start)) != 0) {
+ realm_printf("Realm: SMC call did not preserve %s\n",
+ "counter config");
+ return false;
+ }
+
+ if (memcmp(pmu_cfg_start, pmu_cfg_end, sizeof(pmu_cfg_start)) != 0) {
+ realm_printf("Realm: SMC call did not preserve %s\n",
+ "PMU registers");
+ return false;
+ }
+
+ return true;
+}
+
+bool test_pmuv3_overflow_interrupt(void)
+{
+ unsigned long priority_bits, priority;
+ uint64_t delay_time = DELAY_MS;
+
+ pmu_reset();
+
+ /* Get the number of priority bits implemented */
+ priority_bits = ((read_icv_ctrl_el1() >> ICV_CTLR_EL1_PRIbits_SHIFT) &
+ ICV_CTLR_EL1_PRIbits_MASK) + 1UL;
+
+ /* Unimplemented bits are RES0 and start from LSB */
+ priority = (0xFFUL << (8UL - priority_bits)) & 0xFFUL;
+
+ /* Set the priority mask register to allow all interrupts */
+ write_icv_pmr_el1(priority);
+
+ /* Enable Virtual Group 1 interrupts */
+ write_icv_igrpen1_el1(ICV_IGRPEN1_EL1_Enable);
+
+ /* Enable IRQ */
+ enable_irq();
+
+ write_pmevcntrn_el0(0, PRE_OVERFLOW);
+ enable_event_counter(0);
+
+ /* Enable interrupt on event counter #0 */
+ write_pmintenset_el1((1UL << 0));
+
+ realm_printf("Realm: waiting for PMU vIRQ...\n");
+
+ enable_counting();
+ execute_nops();
+
+ /*
+ * Interrupt handler will clear
+ * Performance Monitors Interrupt Enable Set register
+ * as part of handling the overflow interrupt.
+ */
+ while ((read_pmintenset_el1() != 0UL) && (delay_time != 0ULL)) {
+ --delay_time;
+ }
+
+ /* Disable IRQ */
+ disable_irq();
+
+ pmu_reset();
+
+ if (delay_time == 0ULL) {
+ realm_printf("Realm: PMU vIRQ %sreceived in %llums\n", "not ",
+ DELAY_MS);
+ return false;
+ }
+
+ realm_printf("Realm: PMU vIRQ %sreceived in %llums\n", "",
+ DELAY_MS - delay_time);
+
+ return true;
+}
diff --git a/tftf/tests/common/test_helpers.c b/tftf/tests/common/test_helpers.c
index cba4dad..90773ae 100644
--- a/tftf/tests/common/test_helpers.c
+++ b/tftf/tests/common/test_helpers.c
@@ -1,9 +1,11 @@
/*
- * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
+#include <stdlib.h>
+
#include <arch_helpers.h>
#include <cactus_test_cmds.h>
#include <plat_topology.h>
@@ -270,3 +272,9 @@ void wait_for_core_to_turn_off(unsigned int mpidr)
continue;
}
}
+
+/* Generate 64-bit random number */
+unsigned long long rand64(void)
+{
+ return ((unsigned long long)rand() << 32) | rand();
+}
diff --git a/tftf/tests/misc_tests/test_invalid_access.c b/tftf/tests/misc_tests/test_invalid_access.c
index 1d0b6f4..9cbd8f2 100644
--- a/tftf/tests/misc_tests/test_invalid_access.c
+++ b/tftf/tests/misc_tests/test_invalid_access.c
@@ -140,12 +140,12 @@ test_result_t rl_memory_cannot_be_accessed_in_ns(void)
goto out_unregister;
}
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
/* Delegate the shared page to Realm. */
- retmm = rmi_granule_delegate((u_register_t)&share_page);
+ retmm = host_rmi_granule_delegate((u_register_t)&share_page);
if (retmm != 0UL) {
- ERROR("Granule delegate failed!\n");
+ ERROR("%s() failed\n", "host_rmi_granule_delegate");
goto out_unregister;
}
@@ -161,9 +161,9 @@ test_result_t rl_memory_cannot_be_accessed_in_ns(void)
out_undelegate:
/* Undelegate the shared page. */
- retmm = rmi_granule_undelegate((u_register_t)&share_page);
+ retmm = host_rmi_granule_undelegate((u_register_t)&share_page);
if (retmm != 0UL) {
- ERROR("Granule undelegate failed!\n");
+ ERROR("Granule undelegate failed, ret=0x%lx\n", retmm);
}
out_unregister:
@@ -234,9 +234,9 @@ static test_result_t memory_cannot_be_accessed_in_rl(u_register_t params)
return TEST_RESULT_SKIPPED;
}
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
- retrmm = rmi_version();
+ retrmm = host_rmi_version();
VERBOSE("RMM version is: %lu.%lu\n",
RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -250,17 +250,18 @@ static test_result_t memory_cannot_be_accessed_in_rl(u_register_t params)
return TEST_RESULT_SKIPPED;
}
- retrmm = rmi_granule_delegate((u_register_t)&rd[0]);
+ retrmm = host_rmi_granule_delegate((u_register_t)&rd[0]);
if (retrmm != 0UL) {
- ERROR("Delegate operation returns fail, %lx\n", retrmm);
+ ERROR("%s() failed, ret=0x%lx\n", "host_rmi_granule_delegate",
+ retrmm);
return TEST_RESULT_FAIL;
}
/* Create a realm using a parameter in a secure physical address space should fail. */
- retrmm = rmi_realm_create((u_register_t)&rd[0], params);
+ retrmm = host_rmi_realm_create((u_register_t)&rd[0], params);
if (retrmm == 0UL) {
ERROR("Realm create operation should fail, %lx\n", retrmm);
- retrmm = rmi_realm_destroy((u_register_t)&rd[0]);
+ retrmm = host_rmi_realm_destroy((u_register_t)&rd[0]);
if (retrmm != 0UL) {
ERROR("Realm destroy operation returns fail, %lx\n", retrmm);
}
@@ -271,9 +272,9 @@ static test_result_t memory_cannot_be_accessed_in_rl(u_register_t params)
result = TEST_RESULT_SUCCESS;
}
- retrmm = rmi_granule_undelegate((u_register_t)&rd[0]);
+ retrmm = host_rmi_granule_undelegate((u_register_t)&rd[0]);
if (retrmm != 0UL) {
- INFO("Undelegate operation returns fail, %lx\n", retrmm);
+ INFO("Undelegate operation returns 0x%lx\n", retrmm);
return TEST_RESULT_FAIL;
}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c b/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c
new file mode 100644
index 0000000..042132e
--- /dev/null
+++ b/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <test_helpers.h>
+
+#include <host_realm_helper.h>
+#include <host_realm_pmu.h>
+#include <platform.h>
+
+#define MAX_COUNTERS 31
+
+/* PMCCFILTR_EL0 mask */
+#define PMCCFILTR_EL0_MASK ( \
+ PMCCFILTR_EL0_P_BIT | \
+ PMCCFILTR_EL0_U_BIT | \
+ PMCCFILTR_EL0_NSK_BIT | \
+ PMCCFILTR_EL0_NSH_BIT | \
+ PMCCFILTR_EL0_M_BIT | \
+ PMCCFILTR_EL0_RLK_BIT | \
+ PMCCFILTR_EL0_RLU_BIT | \
+ PMCCFILTR_EL0_RLH_BIT)
+
+/* PMEVTYPER<n>_EL0 mask */
+#define PMEVTYPER_EL0_MASK ( \
+ PMEVTYPER_EL0_P_BIT | \
+ PMEVTYPER_EL0_U_BIT | \
+ PMEVTYPER_EL0_NSK_BIT | \
+ PMEVTYPER_EL0_NSU_BIT | \
+ PMEVTYPER_EL0_NSH_BIT | \
+ PMEVTYPER_EL0_M_BIT | \
+ PMEVTYPER_EL0_RLK_BIT | \
+ PMEVTYPER_EL0_RLU_BIT | \
+ PMEVTYPER_EL0_RLH_BIT | \
+ PMEVTYPER_EL0_EVTCOUNT_BITS)
+
+/* PMSELR_EL0 mask */
+#define PMSELR_EL0_MASK 0x1F
+
+#define WRITE_PMEV_REGS(n) { \
+ case n: \
+ pmu_ptr->pmevcntr_el0[n] = rand64(); \
+ write_pmevcntrn_el0(n, pmu_ptr->pmevcntr_el0[n]); \
+ pmu_ptr->pmevtyper_el0[n] = rand() & PMEVTYPER_EL0_MASK;\
+ write_pmevtypern_el0(n, pmu_ptr->pmevtyper_el0[n]); \
+}
+
+#define CHECK_PMEV_REG(n, reg) { \
+ read_val = read_##reg##n_el0(n); \
+ if (read_val != pmu_ptr->reg##_el0[n]) { \
+ ERROR("Corrupted "#reg"%d_el0=0x%lx (0x%lx)\n", \
+ n, read_val, pmu_ptr->reg##_el0[n]); \
+ return false; \
+ } \
+}
+
+#define CHECK_PMEV_REGS(n) { \
+ case n: \
+ CHECK_PMEV_REG(n, pmevcntr); \
+ CHECK_PMEV_REG(n, pmevtyper); \
+}
+
+#define WRITE_PMREG(reg, mask) { \
+ pmu_ptr->reg = rand64() & mask; \
+ write_##reg(pmu_ptr->reg); \
+}
+
+#define CHECK_PMREG(reg) { \
+ read_val = read_##reg(); \
+ val = pmu_ptr->reg; \
+ if (read_val != val) { \
+ ERROR("Corrupted "#reg"=0x%lx (0x%lx)\n", \
+ read_val, val); \
+ return false; \
+ } \
+}
+
+struct pmu_registers {
+ unsigned long pmcr_el0;
+ unsigned long pmcntenset_el0;
+ unsigned long pmovsset_el0;
+ unsigned long pmintenset_el1;
+ unsigned long pmccntr_el0;
+ unsigned long pmccfiltr_el0;
+ unsigned long pmuserenr_el0;
+
+ unsigned long pmevcntr_el0[MAX_COUNTERS];
+ unsigned long pmevtyper_el0[MAX_COUNTERS];
+
+ unsigned long pmselr_el0;
+ unsigned long pmxevcntr_el0;
+ unsigned long pmxevtyper_el0;
+
+} __aligned(CACHE_WRITEBACK_GRANULE);
+
+static struct pmu_registers pmu_state[PLATFORM_CORE_COUNT];
+
+void host_set_pmu_state(void)
+{
+ unsigned int core_pos = platform_get_core_pos(read_mpidr_el1());
+ struct pmu_registers *pmu_ptr = &pmu_state[core_pos];
+ unsigned int num_cnts = GET_CNT_NUM;
+ unsigned long val;
+
+ val = read_pmcr_el0() | PMCR_EL0_DP_BIT;
+ pmu_ptr->pmcr_el0 = val;
+
+ /* Disable cycle counting and reset all counters */
+ write_pmcr_el0(val | PMCR_EL0_C_BIT | PMCR_EL0_P_BIT);
+
+ /* Disable all counters */
+ pmu_ptr->pmcntenset_el0 = 0UL;
+ write_pmcntenclr_el0(PMU_CLEAR_ALL);
+
+ /* Clear overflow status */
+ pmu_ptr->pmovsset_el0 = 0UL;
+ write_pmovsclr_el0(PMU_CLEAR_ALL);
+
+ /* Disable overflow interrupts on all counters */
+ pmu_ptr->pmintenset_el1 = 0UL;
+ write_pmintenclr_el1(PMU_CLEAR_ALL);
+
+ WRITE_PMREG(pmccntr_el0, UINT64_MAX);
+ WRITE_PMREG(pmccfiltr_el0, PMCCFILTR_EL0_MASK);
+
+ pmu_ptr->pmuserenr_el0 = read_pmuserenr_el0();
+
+ if (num_cnts != 0U) {
+ switch (--num_cnts) {
+ WRITE_PMEV_REGS(30);
+ WRITE_PMEV_REGS(29);
+ WRITE_PMEV_REGS(28);
+ WRITE_PMEV_REGS(27);
+ WRITE_PMEV_REGS(26);
+ WRITE_PMEV_REGS(25);
+ WRITE_PMEV_REGS(24);
+ WRITE_PMEV_REGS(23);
+ WRITE_PMEV_REGS(22);
+ WRITE_PMEV_REGS(21);
+ WRITE_PMEV_REGS(20);
+ WRITE_PMEV_REGS(19);
+ WRITE_PMEV_REGS(18);
+ WRITE_PMEV_REGS(17);
+ WRITE_PMEV_REGS(16);
+ WRITE_PMEV_REGS(15);
+ WRITE_PMEV_REGS(14);
+ WRITE_PMEV_REGS(13);
+ WRITE_PMEV_REGS(12);
+ WRITE_PMEV_REGS(11);
+ WRITE_PMEV_REGS(10);
+ WRITE_PMEV_REGS(9);
+ WRITE_PMEV_REGS(8);
+ WRITE_PMEV_REGS(7);
+ WRITE_PMEV_REGS(6);
+ WRITE_PMEV_REGS(5);
+ WRITE_PMEV_REGS(4);
+ WRITE_PMEV_REGS(3);
+ WRITE_PMEV_REGS(2);
+ WRITE_PMEV_REGS(1);
+ default:
+ WRITE_PMEV_REGS(0);
+ }
+
+ /* Generate a random number between 0 and num_cnts */
+ val = rand() % ++num_cnts;
+ } else {
+ val = 0UL;
+ }
+
+ pmu_ptr->pmselr_el0 = val;
+ write_pmselr_el0(val);
+
+ pmu_ptr->pmxevcntr_el0 = read_pmxevcntr_el0();
+ pmu_ptr->pmxevtyper_el0 = read_pmxevtyper_el0();
+}
+
+bool host_check_pmu_state(void)
+{
+ unsigned int core_pos = platform_get_core_pos(read_mpidr_el1());
+ struct pmu_registers *pmu_ptr = &pmu_state[core_pos];
+ unsigned int num_cnts = GET_CNT_NUM;
+ unsigned long val, read_val;
+
+ CHECK_PMREG(pmcr_el0);
+ CHECK_PMREG(pmcntenset_el0);
+ CHECK_PMREG(pmovsset_el0);
+ CHECK_PMREG(pmintenset_el1);
+ CHECK_PMREG(pmccntr_el0);
+ CHECK_PMREG(pmccfiltr_el0);
+ CHECK_PMREG(pmuserenr_el0);
+ CHECK_PMREG(pmselr_el0);
+ CHECK_PMREG(pmxevcntr_el0);
+ CHECK_PMREG(pmxevtyper_el0);
+
+ if (num_cnts != 0UL) {
+ switch (--num_cnts) {
+ CHECK_PMEV_REGS(30);
+ CHECK_PMEV_REGS(29);
+ CHECK_PMEV_REGS(28);
+ CHECK_PMEV_REGS(27);
+ CHECK_PMEV_REGS(26);
+ CHECK_PMEV_REGS(25);
+ CHECK_PMEV_REGS(24);
+ CHECK_PMEV_REGS(23);
+ CHECK_PMEV_REGS(22);
+ CHECK_PMEV_REGS(21);
+ CHECK_PMEV_REGS(20);
+ CHECK_PMEV_REGS(19);
+ CHECK_PMEV_REGS(18);
+ CHECK_PMEV_REGS(17);
+ CHECK_PMEV_REGS(16);
+ CHECK_PMEV_REGS(15);
+ CHECK_PMEV_REGS(14);
+ CHECK_PMEV_REGS(13);
+ CHECK_PMEV_REGS(12);
+ CHECK_PMEV_REGS(11);
+ CHECK_PMEV_REGS(10);
+ CHECK_PMEV_REGS(9);
+ CHECK_PMEV_REGS(8);
+ CHECK_PMEV_REGS(7);
+ CHECK_PMEV_REGS(6);
+ CHECK_PMEV_REGS(5);
+ CHECK_PMEV_REGS(4);
+ CHECK_PMEV_REGS(3);
+ CHECK_PMEV_REGS(2);
+ CHECK_PMEV_REGS(1);
+ default:
+ CHECK_PMEV_REGS(0);
+ }
+ }
+
+ return true;
+}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
index 3fbe6a6..4787da4 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_helper.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -26,7 +26,7 @@ static bool realm_payload_created;
static bool shared_mem_created;
static bool realm_payload_mmaped;
static u_register_t exit_reason = RMI_EXIT_INVALID;
-static unsigned int test_result = TEST_RESULT_FAIL;
+static unsigned int host_call_result = TEST_RESULT_FAIL;
static volatile bool timer_enabled;
/* From the TFTF_BASE offset, memory used by TFTF + Shared + Realm + POOL should
@@ -37,6 +37,20 @@ CASSERT((((uint64_t)NS_REALM_SHARED_MEM_BASE + (uint64_t)NS_REALM_SHARED_MEM_SIZ
< ((uint64_t)DRAM_BASE + (uint64_t)DRAM_SIZE)),\
error_ns_memory_and_realm_payload_exceed_DRAM_SIZE);
+#define RMI_EXIT(id) \
+ [RMI_EXIT_##id] = #id
+
+const char *rmi_exit[] = {
+ RMI_EXIT(SYNC),
+ RMI_EXIT(IRQ),
+ RMI_EXIT(FIQ),
+ RMI_EXIT(FIQ),
+ RMI_EXIT(PSCI),
+ RMI_EXIT(RIPAS_CHANGE),
+ RMI_EXIT(HOST_CALL),
+ RMI_EXIT(SERROR)
+};
+
/*
* The function handler to print the Realm logged buffer,
* executed by the secondary core
@@ -53,7 +67,7 @@ static inline test_result_t timer_handler(void)
/*
* Read Realm message from shared printf location and print
- * them using uart
+ * them using UART
*/
if (str_len != 0UL) {
/* Avoid memory overflow */
@@ -72,15 +86,16 @@ static inline test_result_t timer_handler(void)
/*
* Initialisation function which will clear the shared region,
* and try to find another CPU other than the lead one to
- * handle the Realm message logging
+ * handle the Realm message logging.
*/
void host_init_realm_print_buffer(void)
{
u_register_t other_mpidr, my_mpidr;
- int ret;
host_shared_data_t *host_shared_data = host_get_shared_structure();
+ int ret;
(void)memset((char *)host_shared_data, 0, sizeof(host_shared_data_t));
+
/* Program timer */
timer_enabled = false;
@@ -95,8 +110,7 @@ void host_init_realm_print_buffer(void)
/* Power on the other CPU */
ret = tftf_cpu_on(other_mpidr, (uintptr_t)timer_handler, 0);
if (ret != PSCI_E_SUCCESS) {
- ERROR("powering on %llx failed",
- (unsigned long long)other_mpidr);
+ ERROR("Powering on %lx failed\n", other_mpidr);
return;
}
timer_enabled = true;
@@ -119,9 +133,8 @@ static test_result_t host_mmap_realm_payload(u_register_t realm_payload_adr,
plat_mem_pool_adr,
plat_mem_pool_size,
MT_RW_DATA | MT_NS);
-
if (rc != 0) {
- ERROR("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
+ ERROR("%u: mmap_add_dynamic_region() %d\n", __LINE__, rc);
return TEST_RESULT_FAIL;
}
@@ -130,36 +143,36 @@ static test_result_t host_mmap_realm_payload(u_register_t realm_payload_adr,
realm_payload_adr,
REALM_MAX_LOAD_IMG_SIZE,
MT_RW_DATA | MT_NS);
-
if (rc != 0) {
- ERROR("%d: mmap_add_dynamic_region() = %d\n", __LINE__, rc);
+ ERROR("%u: mmap_add_dynamic_region() %d\n", __LINE__, rc);
return TEST_RESULT_FAIL;
}
realm_payload_mmaped = true;
return REALM_SUCCESS;
}
-static bool host_enter_realm(u_register_t *exit_reason, unsigned int *test_result)
+static bool host_enter_realm(u_register_t *exit_reason,
+ unsigned int *host_call_result)
{
u_register_t ret;
if (!realm_payload_created) {
- ERROR("%s failed, Realm not created\n", __func__);
+ ERROR("%s() failed\n", "realm_payload_created");
return false;
}
if (!shared_mem_created) {
- ERROR("%s failed, shared memory not created\n", __func__);
+ ERROR("%s() failed\n", "shared_mem_created");
return false;
}
- /* Enter Realm */
- ret = realm_rec_enter(&realm, exit_reason, test_result);
+ /* Enter Realm */
+ ret = host_realm_rec_enter(&realm, exit_reason, host_call_result);
if (ret != REALM_SUCCESS) {
- ERROR("Rec enter failed something went wrong, ret=%lx\n", ret);
+ ERROR("%s() failed, ret=%lx\n", "host_realm_rec_enter", ret);
/* Free test resources */
- if (realm_destroy(&realm) != REALM_SUCCESS) {
- ERROR("%s\n", "realm_destroy failed");
+ if (host_realm_destroy(&realm) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_realm_destroy");
}
realm_payload_created = false;
return false;
@@ -169,12 +182,13 @@ static bool host_enter_realm(u_register_t *exit_reason, unsigned int *test_resul
}
bool host_create_realm_payload(u_register_t realm_payload_adr,
- u_register_t plat_mem_pool_adr,
- u_register_t plat_mem_pool_size,
- u_register_t realm_pages_size)
+ u_register_t plat_mem_pool_adr,
+ u_register_t plat_mem_pool_size,
+ u_register_t realm_pages_size,
+ u_register_t feature_flag)
{
if (realm_payload_adr == TFTF_BASE) {
- ERROR("realm_payload_adr should grater then TFTF_BASE\n");
+ ERROR("realm_payload_adr should be grater then TFTF_BASE\n");
return false;
}
@@ -182,57 +196,65 @@ bool host_create_realm_payload(u_register_t realm_payload_adr,
plat_mem_pool_size == 0UL ||
realm_pages_size == 0UL) {
ERROR("plat_mem_pool_size or "
- "plat_mem_pool_size or realm_pages_size isNull\n");
+ "plat_mem_pool_size or realm_pages_size is NULL\n");
return false;
}
/* Initialize Host NS heap memory to be used in Realm creation*/
if (page_pool_init(plat_mem_pool_adr, realm_pages_size)
!= HEAP_INIT_SUCCESS) {
- ERROR("page_pool_init() failed\n");
+ ERROR("%s() failed\n", "page_pool_init");
return false;
}
- /* Mmap Realm payload region*/
+ /* Mmap Realm payload region */
if (host_mmap_realm_payload(realm_payload_adr,
plat_mem_pool_adr,
plat_mem_pool_size) != REALM_SUCCESS) {
- ERROR("host_mmap_realm_payload() failed\n");
+ ERROR("%s() failed\n", "host_mmap_realm_payload");
return false;
}
- /* Read Realm feature Regs*/
- if (rmi_features(0UL, &realm.rmm_feat_reg0) != REALM_SUCCESS) {
- ERROR("rmi_features() Read Realm feature failed\n");
+ /* Read Realm Feature Reg 0 */
+ if (host_rmi_features(0UL, &realm.rmm_feat_reg0) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_rmi_features");
goto destroy_realm;
}
+ /* Disable PMU if not required */
+ if ((feature_flag & RMI_FEATURE_REGISTER_0_PMU_EN) == 0UL) {
+ realm.rmm_feat_reg0 &=
+ ~(RMI_FEATURE_REGISTER_0_PMU_EN |
+ RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS);
+ }
+
/* Create Realm */
- if (realm_create(&realm) != REALM_SUCCESS) {
- ERROR("realm_create() failed\n");
+ if (host_realm_create(&realm) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_realm_create");
goto destroy_realm;
}
- if (realm_init_ipa_state(&realm, 0U, 0U, 1ULL << 32)
+ if (host_realm_init_ipa_state(&realm, 0U, 0U, 1ULL << 32)
!= RMI_SUCCESS) {
- ERROR("realm_init_ipa_state\n");
+ ERROR("%s() failed\n", "host_realm_init_ipa_state");
goto destroy_realm;
}
+
/* RTT map Realm image */
- if (realm_map_payload_image(&realm, realm_payload_adr) !=
+ if (host_realm_map_payload_image(&realm, realm_payload_adr) !=
REALM_SUCCESS) {
- ERROR("realm_map_payload_image() failed\n");
+ ERROR("%s() failed\n", "host_realm_map_payload_image");
goto destroy_realm;
}
/* Create REC */
- if (realm_rec_create(&realm) != REALM_SUCCESS) {
- ERROR("REC create failed\n");
+ if (host_realm_rec_create(&realm) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_realm_rec_create");
goto destroy_realm;
}
/* Activate Realm */
- if (realm_activate(&realm) != REALM_SUCCESS) {
- ERROR("Realm activate failed\n");
+ if (host_realm_activate(&realm) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_realm_activate");
goto destroy_realm;
}
@@ -242,8 +264,8 @@ bool host_create_realm_payload(u_register_t realm_payload_adr,
/* Free test resources */
destroy_realm:
- if (realm_destroy(&realm) != REALM_SUCCESS) {
- ERROR("%s\n", "realm_destroy failed");
+ if (host_realm_destroy(&realm) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_realm_destroy");
}
realm_payload_created = false;
@@ -254,9 +276,9 @@ bool host_create_shared_mem(u_register_t ns_shared_mem_adr,
u_register_t ns_shared_mem_size)
{
/* RTT map NS shared region */
- if (realm_map_ns_shared(&realm, ns_shared_mem_adr, ns_shared_mem_size) !=
- REALM_SUCCESS) {
- ERROR("realm_map_ns_shared() failed\n");
+ if (host_realm_map_ns_shared(&realm, ns_shared_mem_adr,
+ ns_shared_mem_size) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_realm_map_ns_shared");
shared_mem_created = false;
return false;
}
@@ -275,42 +297,53 @@ bool host_destroy_realm(void)
page_pool_reset();
if (!realm_payload_created) {
- ERROR("realm_destroy failed, Realm not created\n");
+ ERROR("%s() failed\n", "realm_payload_created");
return false;
}
realm_payload_created = false;
- if (realm_destroy(&realm) != REALM_SUCCESS) {
- ERROR("%s\n", "realm_destroy failed");
+ if (host_realm_destroy(&realm) != REALM_SUCCESS) {
+ ERROR("%s() failed\n", "host_realm_destroy");
return false;
}
return true;
}
-bool host_enter_realm_execute(uint8_t cmd)
+bool host_enter_realm_execute(uint8_t cmd, struct realm **realm_ptr)
{
exit_reason = RMI_EXIT_INVALID;
- test_result = TEST_RESULT_FAIL;
+ host_call_result = TEST_RESULT_FAIL;
realm_shared_data_set_realm_cmd(cmd);
- if (!host_enter_realm(&exit_reason, &test_result)) {
+ if (!host_enter_realm(&exit_reason, &host_call_result)) {
return false;
}
- if (exit_reason == RMI_EXIT_HOST_CALL &&
- test_result == TEST_RESULT_SUCCESS) {
+ if (realm_ptr != NULL) {
+ *realm_ptr = &realm;
+ }
+
+ if (((exit_reason == RMI_EXIT_IRQ) &&
+ (cmd == REALM_PMU_INTERRUPT)) ||
+ ((exit_reason == RMI_EXIT_HOST_CALL) &&
+ (host_call_result == TEST_RESULT_SUCCESS))) {
return true;
}
- ERROR("host_enter_realm_execute exit_reason:[0x%lx],test_result:[0x%x]\n",
- exit_reason,
- test_result);
+
+ if (exit_reason <= RMI_EXIT_SERROR) {
+ ERROR("%s(%u) RMI_EXIT_%s host_call_result=%u\n",
+ __func__, cmd, rmi_exit[exit_reason], host_call_result);
+ } else {
+ ERROR("%s(%u) 0x%lx host_call_result=%u\n",
+ __func__, cmd, exit_reason, host_call_result);
+ }
return false;
}
test_result_t host_cmp_result(void)
{
- if (rmi_get_cmp_result()) {
+ if (host_rmi_get_cmp_result()) {
return TEST_RESULT_SUCCESS;
}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
index f0aba64..eebb873 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_realm_rmi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -10,16 +10,18 @@
#include <debug.h>
#include <heap/page_alloc.h>
+#include <test_helpers.h>
#include <host_realm_helper.h>
#include <host_realm_mem_layout.h>
#include <host_realm_rmi.h>
+#include <host_shared_data.h>
#include <plat/common/platform.h>
#include <realm_def.h>
#include <tftf_lib.h>
#define SET_ARG(_n) { \
case _n: \
- regs[_n] = rand(); \
+ regs[_n] = rand64(); \
CONC(args->arg, _n) = regs[_n]; \
__attribute__((fallthrough)); \
}
@@ -31,8 +33,9 @@
}
static bool rmi_cmp_result;
+static unsigned short vmid;
-static smc_ret_values rmi_handler(smc_args *args, unsigned int in_reg)
+static smc_ret_values host_rmi_handler(smc_args *args, unsigned int in_reg)
{
u_register_t regs[8];
smc_ret_values ret_val;
@@ -90,134 +93,145 @@ static smc_ret_values rmi_handler(smc_args *args, unsigned int in_reg)
return ret_val;
}
-void rmi_init_cmp_result(void)
+void host_rmi_init_cmp_result(void)
{
rmi_cmp_result = true;
}
-bool rmi_get_cmp_result(void)
+bool host_rmi_get_cmp_result(void)
{
return rmi_cmp_result;
}
-static inline u_register_t rmi_data_create(bool unknown, u_register_t data,
- u_register_t rd, u_register_t map_addr, u_register_t src)
+static inline u_register_t host_rmi_data_create(bool unknown, u_register_t data,
+ u_register_t rd, u_register_t map_addr, u_register_t src)
{
if (unknown) {
- return rmi_handler(&(smc_args){RMI_DATA_CREATE_UNKNOWN,
+ return host_rmi_handler(&(smc_args){RMI_DATA_CREATE_UNKNOWN,
data, rd, map_addr}, 4U).ret0;
} else {
- return rmi_handler(&(smc_args){RMI_DATA_CREATE,
- /* X5 = flags */
- data, rd, map_addr, src, 0UL}, 6U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_DATA_CREATE,
+ /* X5 = flags */
+ data, rd, map_addr, src, 0UL}, 6U).ret0;
}
}
-static inline u_register_t rmi_realm_activate(u_register_t rd)
+static inline u_register_t host_rmi_realm_activate(u_register_t rd)
{
- return rmi_handler(&(smc_args){RMI_REALM_ACTIVATE, rd}, 2U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_REALM_ACTIVATE, rd}, 2U).ret0;
}
-u_register_t rmi_realm_create(u_register_t rd, u_register_t params_ptr)
+u_register_t host_rmi_realm_create(u_register_t rd, u_register_t params_ptr)
{
- return rmi_handler(&(smc_args){RMI_REALM_CREATE,
+ return host_rmi_handler(&(smc_args){RMI_REALM_CREATE,
rd, params_ptr}, 3U).ret0;
}
-u_register_t rmi_realm_destroy(u_register_t rd)
+u_register_t host_rmi_realm_destroy(u_register_t rd)
{
- return rmi_handler(&(smc_args){RMI_REALM_DESTROY, rd}, 2U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_REALM_DESTROY, rd}, 2U).ret0;
}
-static inline u_register_t rmi_data_destroy(u_register_t rd,
- u_register_t map_addr)
+static inline u_register_t host_rmi_data_destroy(u_register_t rd,
+ u_register_t map_addr)
{
- return rmi_handler(&(smc_args){RMI_DATA_DESTROY, rd, map_addr},
- 3U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_DATA_DESTROY, rd, map_addr},
+ 3U).ret0;
}
-static inline u_register_t rmi_rec_create(u_register_t rec, u_register_t rd,
- u_register_t params_ptr)
+static inline u_register_t host_rmi_rec_create(u_register_t rec,
+ u_register_t rd,
+ u_register_t params_ptr)
{
- return rmi_handler(&(smc_args){RMI_REC_CREATE, rec, rd, params_ptr},
- 4U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_REC_CREATE, rec, rd, params_ptr},
+ 4U).ret0;
}
-static inline u_register_t rmi_rec_destroy(u_register_t rec)
+static inline u_register_t host_rmi_rec_destroy(u_register_t rec)
{
- return rmi_handler(&(smc_args){RMI_REC_DESTROY, rec}, 2U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_REC_DESTROY, rec}, 2U).ret0;
}
-static inline u_register_t rmi_rtt_create(u_register_t rtt, u_register_t rd,
- u_register_t map_addr, u_register_t level)
+static inline u_register_t host_rmi_rtt_create(u_register_t rtt,
+ u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level)
{
- return rmi_handler(&(smc_args){RMI_RTT_CREATE,
- rtt, rd, map_addr, level}, 5U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_RTT_CREATE,
+ rtt, rd, map_addr, level}, 5U).ret0;
}
-static inline u_register_t rmi_rtt_destroy(u_register_t rtt, u_register_t rd,
- u_register_t map_addr, u_register_t level)
+static inline u_register_t host_rmi_rtt_destroy(u_register_t rtt,
+ u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level)
{
- return rmi_handler(&(smc_args){RMI_RTT_DESTROY,
- rtt, rd, map_addr, level}, 5U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_RTT_DESTROY,
+ rtt, rd, map_addr, level}, 5U).ret0;
}
-u_register_t rmi_features(u_register_t index, u_register_t *features)
+u_register_t host_rmi_features(u_register_t index, u_register_t *features)
{
smc_ret_values rets;
- rets = rmi_handler(&(smc_args){RMI_FEATURES, index}, 2U);
+ rets = host_rmi_handler(&(smc_args){RMI_FEATURES, index}, 2U);
*features = rets.ret1;
return rets.ret0;
}
-static inline u_register_t rmi_rtt_init_ripas(u_register_t rd,
- u_register_t map_addr,
- u_register_t level)
+static inline u_register_t host_rmi_rtt_init_ripas(u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level)
{
- return rmi_handler(&(smc_args){RMI_RTT_INIT_RIPAS,
+ return host_rmi_handler(&(smc_args){RMI_RTT_INIT_RIPAS,
rd, map_addr, level}, 4U).ret0;
}
-static inline u_register_t rmi_rtt_fold(u_register_t rtt, u_register_t rd,
- u_register_t map_addr, u_register_t level)
+static inline u_register_t host_rmi_rtt_fold(u_register_t rtt, u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level)
{
- return rmi_handler(&(smc_args){RMI_RTT_FOLD,
+ return host_rmi_handler(&(smc_args){RMI_RTT_FOLD,
rtt, rd, map_addr, level}, 5U).ret0;
}
-static inline u_register_t rmi_rec_aux_count(u_register_t rd,
- u_register_t *aux_count)
+static inline u_register_t host_rmi_rec_aux_count(u_register_t rd,
+ u_register_t *aux_count)
{
smc_ret_values rets;
- rets = rmi_handler(&(smc_args){RMI_REC_AUX_COUNT, rd}, 2U);
+ rets = host_rmi_handler(&(smc_args){RMI_REC_AUX_COUNT, rd}, 2U);
*aux_count = rets.ret1;
return rets.ret0;
}
-static inline u_register_t rmi_rtt_set_ripas(u_register_t rd, u_register_t rec,
- u_register_t map_addr, u_register_t level,
- u_register_t ripas)
+static inline u_register_t host_rmi_rtt_set_ripas(u_register_t rd,
+ u_register_t rec,
+ u_register_t map_addr,
+ u_register_t level,
+ u_register_t ripas)
{
- return rmi_handler(&(smc_args){RMI_RTT_SET_RIPAS,
+ return host_rmi_handler(&(smc_args){RMI_RTT_SET_RIPAS,
rd, rec, map_addr, level, ripas}, 6U).ret0;
}
-static inline u_register_t rmi_rtt_mapunprotected(u_register_t rd,
- u_register_t map_addr,
- u_register_t level, u_register_t ns_pa)
+static inline u_register_t host_rmi_rtt_mapunprotected(u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level,
+ u_register_t ns_pa)
{
- return rmi_handler(&(smc_args){RMI_RTT_MAP_UNPROTECTED,
- rd, map_addr, level, ns_pa}, 5U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_RTT_MAP_UNPROTECTED,
+ rd, map_addr, level, ns_pa}, 5U).ret0;
}
-static u_register_t rmi_rtt_readentry(u_register_t rd, u_register_t map_addr,
- u_register_t level, struct rtt_entry *rtt)
+static u_register_t host_rmi_rtt_readentry(u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level,
+ struct rtt_entry *rtt)
{
smc_ret_values rets;
- rets = rmi_handler(&(smc_args){RMI_RTT_READ_ENTRY,
+ rets = host_rmi_handler(&(smc_args){RMI_RTT_READ_ENTRY,
rd, map_addr, level}, 4U);
rtt->walk_level = rets.ret1;
rtt->state = rets.ret2 & 0xFF;
@@ -225,15 +239,16 @@ static u_register_t rmi_rtt_readentry(u_register_t rd, u_register_t map_addr,
return rets.ret0;
}
-static inline u_register_t rmi_rtt_unmap_unprotected(u_register_t rd,
- u_register_t map_addr,
- u_register_t level, u_register_t ns_pa)
+static inline u_register_t host_rmi_rtt_unmap_unprotected(u_register_t rd,
+ u_register_t map_addr,
+ u_register_t level,
+ u_register_t ns_pa)
{
- return rmi_handler(&(smc_args){RMI_RTT_UNMAP_UNPROTECTED,
+ return host_rmi_handler(&(smc_args){RMI_RTT_UNMAP_UNPROTECTED,
rd, map_addr, level, ns_pa}, 5U).ret0;
}
-static inline u_register_t rtt_level_mapsize(u_register_t level)
+static inline u_register_t host_rtt_level_mapsize(u_register_t level)
{
if (level > RTT_MAX_LEVEL) {
return PAGE_SIZE;
@@ -242,19 +257,19 @@ static inline u_register_t rtt_level_mapsize(u_register_t level)
return (1UL << RTT_LEVEL_SHIFT(level));
}
-static inline u_register_t realm_rtt_create(struct realm *realm,
- u_register_t addr,
- u_register_t level,
- u_register_t phys)
+static inline u_register_t host_realm_rtt_create(struct realm *realm,
+ u_register_t addr,
+ u_register_t level,
+ u_register_t phys)
{
- addr = ALIGN_DOWN(addr, rtt_level_mapsize(level - 1U));
- return rmi_rtt_create(phys, realm->rd, addr, level);
+ addr = ALIGN_DOWN(addr, host_rtt_level_mapsize(level - 1U));
+ return host_rmi_rtt_create(phys, realm->rd, addr, level);
}
-static u_register_t rmi_create_rtt_levels(struct realm *realm,
- u_register_t map_addr,
- u_register_t level,
- u_register_t max_level)
+static u_register_t host_rmi_create_rtt_levels(struct realm *realm,
+ u_register_t map_addr,
+ u_register_t level,
+ u_register_t max_level)
{
u_register_t rtt, ret;
@@ -264,18 +279,18 @@ static u_register_t rmi_create_rtt_levels(struct realm *realm,
ERROR("Failed to allocate memory for rtt\n");
return REALM_ERROR;
} else {
- ret = rmi_granule_delegate(rtt);
+ ret = host_rmi_granule_delegate(rtt);
if (ret != RMI_SUCCESS) {
- ERROR("Rtt delegation failed,"
- "rtt=0x%lx ret=0x%lx\n", rtt, ret);
+ ERROR("%s() failed, rtt=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_delegate", rtt, ret);
return REALM_ERROR;
}
}
- ret = realm_rtt_create(realm, map_addr, level, rtt);
+ ret = host_realm_rtt_create(realm, map_addr, level, rtt);
if (ret != RMI_SUCCESS) {
- ERROR("Rtt create failed,"
- "rtt=0x%lx ret=0x%lx\n", rtt, ret);
- rmi_granule_undelegate(rtt);
+ ERROR("%s() failed, rtt=0x%lx ret=0x%lx\n",
+ "host_realm_rtt_create", rtt, ret);
+ host_rmi_granule_undelegate(rtt);
page_free(rtt);
return REALM_ERROR;
}
@@ -284,30 +299,29 @@ static u_register_t rmi_create_rtt_levels(struct realm *realm,
return REALM_SUCCESS;
}
-static u_register_t realm_fold_rtt(u_register_t rd, u_register_t addr,
- u_register_t level)
+static u_register_t host_realm_fold_rtt(u_register_t rd, u_register_t addr,
+ u_register_t level)
{
struct rtt_entry rtt;
u_register_t ret;
- ret = rmi_rtt_readentry(rd, addr, level, &rtt);
+ ret = host_rmi_rtt_readentry(rd, addr, level, &rtt);
if (ret != RMI_SUCCESS) {
- ERROR("Rtt readentry failed,"
- "level=0x%lx addr=0x%lx ret=0x%lx\n",
- level, addr, ret);
+ ERROR("%s() failed, level=0x%lx addr=0x%lx ret=0x%lx\n",
+ "host_rmi_rtt_readentry", level, addr, ret);
return REALM_ERROR;
}
if (rtt.state != RMI_TABLE) {
- ERROR("Rtt readentry failed, rtt.state=0x%x\n", rtt.state);
+ ERROR("%s() failed, rtt.state=0x%x\n", "rmi_rtt_readentry",
+ rtt.state);
return REALM_ERROR;
}
- ret = rmi_rtt_fold(rtt.out_addr, rd, addr, level + 1U);
+ ret = host_rmi_rtt_fold(rtt.out_addr, rd, addr, level + 1U);
if (ret != RMI_SUCCESS) {
- ERROR("Rtt destroy failed,"
- "rtt.out_addr=0x%llx addr=0x%lx ret=0x%lx\n",
- rtt.out_addr, addr, ret);
+ ERROR("%s() failed, rtt.out_addr=0x%llx addr=0x%lx ret=0x%lx\n",
+ "host_rmi_rtt_fold", rtt.out_addr, addr, ret);
return REALM_ERROR;
}
@@ -317,10 +331,11 @@ static u_register_t realm_fold_rtt(u_register_t rd, u_register_t addr,
}
-static u_register_t realm_map_protected_data(bool unknown, struct realm *realm,
- u_register_t target_pa,
- u_register_t map_size,
- u_register_t src_pa)
+static u_register_t host_realm_map_protected_data(bool unknown,
+ struct realm *realm,
+ u_register_t target_pa,
+ u_register_t map_size,
+ u_register_t src_pa)
{
u_register_t rd = realm->rd;
u_register_t map_level, level;
@@ -345,51 +360,52 @@ static u_register_t realm_map_protected_data(bool unknown, struct realm *realm,
return REALM_ERROR;
}
- ret = rmi_rtt_init_ripas(rd, map_addr, map_level);
+ ret = host_rmi_rtt_init_ripas(rd, map_addr, map_level);
if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
- ret = rmi_create_rtt_levels(realm, map_addr,
- RMI_RETURN_INDEX(ret), map_level);
+ ret = host_rmi_create_rtt_levels(realm, map_addr,
+ RMI_RETURN_INDEX(ret),
+ map_level);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_create_rtt_levels failed,"
- "ret=0x%lx line:%d\n",
- ret, __LINE__);
+ ERROR("%s() failed, ret=0x%lx line=%u\n",
+ "host_rmi_create_rtt_levels", ret, __LINE__);
goto err;
}
- ret = rmi_rtt_init_ripas(rd, map_addr, map_level);
+ ret = host_rmi_rtt_init_ripas(rd, map_addr, map_level);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_create_rtt_levels failed,"
- "ret=0x%lx line:%d\n",
- ret, __LINE__);
+ ERROR("%s() failed, ret=0x%lx line=%u\n",
+ "host_rmi_rtt_init_ripas", ret, __LINE__);
goto err;
}
}
for (size = 0UL; size < map_size; size += PAGE_SIZE) {
- ret = rmi_granule_delegate(phys);
+ ret = host_rmi_granule_delegate(phys);
if (ret != RMI_SUCCESS) {
- ERROR("Granule delegation failed, PA=0x%lx ret=0x%lx\n",
- phys, ret);
+ ERROR("%s() failed, PA=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_delegate", phys, ret);
return REALM_ERROR;
}
- ret = rmi_data_create(unknown, phys, rd, map_addr, src_pa);
+ ret = host_rmi_data_create(unknown, phys, rd, map_addr, src_pa);
if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
/* Create missing RTTs and retry */
level = RMI_RETURN_INDEX(ret);
- ret = rmi_create_rtt_levels(realm, map_addr, level,
- map_level);
+ ret = host_rmi_create_rtt_levels(realm, map_addr, level,
+ map_level);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_create_rtt_levels failed,"
- "ret=0x%lx line:%d\n",
+ ERROR("%s() failed, ret=0x%lx line=%u\n",
+ "host_rmi_create_rtt_levels",
ret, __LINE__);
goto err;
}
- ret = rmi_data_create(unknown, phys, rd, map_addr, src_pa);
+ ret = host_rmi_data_create(unknown, phys, rd, map_addr,
+ src_pa);
}
if (ret != RMI_SUCCESS) {
- ERROR("rmi_data_create failed, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n",
+ "host_rmi_data_create", ret);
goto err;
}
@@ -399,15 +415,16 @@ static u_register_t realm_map_protected_data(bool unknown, struct realm *realm,
}
if (map_size == RTT_L2_BLOCK_SIZE) {
- ret = realm_fold_rtt(rd, target_pa, map_level);
+ ret = host_realm_fold_rtt(rd, target_pa, map_level);
if (ret != RMI_SUCCESS) {
- ERROR("fold_rtt failed, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n",
+ "host_realm_fold_rtt", ret);
goto err;
}
}
if (ret != RMI_SUCCESS) {
- ERROR("rmi_rtt_mapprotected failed, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n", __func__, ret);
goto err;
}
@@ -415,15 +432,17 @@ static u_register_t realm_map_protected_data(bool unknown, struct realm *realm,
err:
while (size >= PAGE_SIZE) {
- ret = rmi_data_destroy(rd, map_addr);
+ ret = host_rmi_data_destroy(rd, map_addr);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_rtt_mapprotected failed, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n",
+ "host_rmi_data_destroy", ret);
}
- ret = rmi_granule_undelegate(phys);
+ ret = host_rmi_granule_undelegate(phys);
if (ret != RMI_SUCCESS) {
/* Page can't be returned to NS world so is lost */
- ERROR("rmi_granule_undelegate failed\n");
+ ERROR("%s() failed, ret=0x%lx\n",
+ "host_rmi_granule_undelegate", ret);
}
phys -= PAGE_SIZE;
size -= PAGE_SIZE;
@@ -433,9 +452,9 @@ err:
return REALM_ERROR;
}
-u_register_t realm_map_unprotected(struct realm *realm,
- u_register_t ns_pa,
- u_register_t map_size)
+u_register_t host_realm_map_unprotected(struct realm *realm,
+ u_register_t ns_pa,
+ u_register_t map_size)
{
u_register_t rd = realm->rd;
u_register_t map_level, level;
@@ -445,7 +464,6 @@ u_register_t realm_map_unprotected(struct realm *realm,
(1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
realm->rmm_feat_reg0) - 1UL)) ;
-
if (!IS_ALIGNED(map_addr, map_size)) {
return REALM_ERROR;
}
@@ -464,53 +482,58 @@ u_register_t realm_map_unprotected(struct realm *realm,
u_register_t desc = phys | S2TTE_ATTR_FWB_WB_RW;
- ret = rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
+ ret = host_rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
/* Create missing RTTs and retry */
level = RMI_RETURN_INDEX(ret);
- ret = rmi_create_rtt_levels(realm, map_addr, level, map_level);
+ ret = host_rmi_create_rtt_levels(realm, map_addr, level,
+ map_level);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_create_rtt_levels failed, ret=0x%lx line:%d\n",
- ret, __LINE__);
+ ERROR("%s() failed, ret=0x%lx line=%u\n",
+ "host_rmi_create_rtt_levels", ret, __LINE__);
return REALM_ERROR;
}
- ret = rmi_rtt_mapunprotected(rd, map_addr, map_level, desc);
+ ret = host_rmi_rtt_mapunprotected(rd, map_addr, map_level,
+ desc);
}
if (ret != RMI_SUCCESS) {
- ERROR("al_rmi_rtt_mapunprotected failed, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n", "host_rmi_rtt_mapunprotected",
+ ret);
return REALM_ERROR;
}
return REALM_SUCCESS;
}
-static u_register_t realm_rtt_destroy(struct realm *realm, u_register_t addr,
- u_register_t level,
- u_register_t rtt_granule)
+static u_register_t host_realm_rtt_destroy(struct realm *realm,
+ u_register_t addr,
+ u_register_t level,
+ u_register_t rtt_granule)
{
- addr = ALIGN_DOWN(addr, rtt_level_mapsize(level - 1U));
- return rmi_rtt_destroy(rtt_granule, realm->rd, addr, level);
+ addr = ALIGN_DOWN(addr, host_rtt_level_mapsize(level - 1U));
+ return host_rmi_rtt_destroy(rtt_granule, realm->rd, addr, level);
}
-static u_register_t realm_destroy_free_rtt(struct realm *realm,
- u_register_t addr,
- u_register_t level, u_register_t rtt_granule)
+static u_register_t host_realm_destroy_free_rtt(struct realm *realm,
+ u_register_t addr,
+ u_register_t level,
+ u_register_t rtt_granule)
{
u_register_t ret;
- ret = realm_rtt_destroy(realm, addr, level, rtt_granule);
+ ret = host_realm_rtt_destroy(realm, addr, level, rtt_granule);
if (ret != RMI_SUCCESS) {
- ERROR("realm_rtt_destroy failed, rtt=0x%lx, ret=0x%lx\n",
- rtt_granule, ret);
+ ERROR("%s() failed, rtt=0x%lx ret=0x%lx\n",
+ "host_realm_rtt_destroy", rtt_granule, ret);
return REALM_ERROR;
}
- ret = rmi_granule_undelegate(rtt_granule);
+ ret = host_rmi_granule_undelegate(rtt_granule);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_granule_undelegate failed, rtt=0x%lx, ret=0x%lx\n",
- rtt_granule, ret);
+ ERROR("%s() failed, rtt=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", rtt_granule, ret);
return REALM_ERROR;
}
@@ -518,26 +541,25 @@ static u_register_t realm_destroy_free_rtt(struct realm *realm,
return REALM_SUCCESS;
}
-static void realm_destroy_undelegate_range(struct realm *realm,
- u_register_t ipa,
- u_register_t addr,
- u_register_t size)
+static void host_realm_destroy_undelegate_range(struct realm *realm,
+ u_register_t ipa,
+ u_register_t addr,
+ u_register_t size)
{
u_register_t rd = realm->rd;
u_register_t ret;
while (size >= PAGE_SIZE) {
- ret = rmi_data_destroy(rd, ipa);
+ ret = host_rmi_data_destroy(rd, ipa);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_data_destroy failed, addr=0x%lx, ret=0x%lx\n",
- ipa, ret);
+ ERROR("%s() failed, addr=0x%lx ret=0x%lx\n",
+ "host_rmi_data_destroy", ipa, ret);
}
- ret = rmi_granule_undelegate(addr);
+ ret = host_rmi_granule_undelegate(addr);
if (ret != RMI_SUCCESS) {
- ERROR("al_rmi_granule_undelegate failed, addr=0x%lx,"
- "ret=0x%lx\n",
- ipa, ret);
+ ERROR("%s() failed, addr=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", ipa, ret);
}
page_free(addr);
@@ -548,13 +570,13 @@ static void realm_destroy_undelegate_range(struct realm *realm,
}
}
-static u_register_t realm_tear_down_rtt_range(struct realm *realm,
- u_register_t level,
- u_register_t start,
- u_register_t end)
+static u_register_t host_realm_tear_down_rtt_range(struct realm *realm,
+ u_register_t level,
+ u_register_t start,
+ u_register_t end)
{
u_register_t rd = realm->rd, ret;
- u_register_t map_size = rtt_level_mapsize(level);
+ u_register_t map_size = host_rtt_level_mapsize(level);
u_register_t map_addr, next_addr, rtt_out_addr, end_addr;
struct rtt_entry rtt;
@@ -562,8 +584,8 @@ static u_register_t realm_tear_down_rtt_range(struct realm *realm,
next_addr = ALIGN(map_addr + 1U, map_size);
end_addr = MIN(next_addr, end);
- ret = rmi_rtt_readentry(rd, ALIGN_DOWN(map_addr, map_size),
- level, &rtt);
+ ret = host_rmi_rtt_readentry(rd, ALIGN_DOWN(map_addr, map_size),
+ level, &rtt);
if (ret != RMI_SUCCESS) {
continue;
}
@@ -572,38 +594,41 @@ static u_register_t realm_tear_down_rtt_range(struct realm *realm,
switch (rtt.state) {
case RMI_ASSIGNED:
- realm_destroy_undelegate_range(realm, map_addr,
- rtt_out_addr, map_size);
+ host_realm_destroy_undelegate_range(realm, map_addr,
+ rtt_out_addr,
+ map_size);
break;
case RMI_UNASSIGNED:
case RMI_DESTROYED:
break;
case RMI_TABLE:
- ret = realm_tear_down_rtt_range(realm, level + 1U,
- map_addr, end_addr);
+ ret = host_realm_tear_down_rtt_range(realm, level + 1U,
+ map_addr,
+ end_addr);
if (ret != RMI_SUCCESS) {
- ERROR("realm_tear_down_rtt_range failed, \
- map_addr=0x%lx ret=0x%lx\n",
+ ERROR("%s() failed, map_addr=0x%lx ret=0x%lx\n",
+ "host_realm_tear_down_rtt_range",
map_addr, ret);
return REALM_ERROR;
}
- ret = realm_destroy_free_rtt(realm, map_addr, level + 1U,
- rtt_out_addr);
+ ret = host_realm_destroy_free_rtt(realm, map_addr,
+ level + 1U,
+ rtt_out_addr);
if (ret != RMI_SUCCESS) {
- ERROR("rrt destroy can't be performed failed, \
- map_addr=0x%lx ret=0x%lx\n",
+ ERROR("%s() failed, map_addr=0x%lx ret=0x%lx\n",
+ "host_realm_destroy_free_rtt",
map_addr, ret);
return REALM_ERROR;
}
break;
case RMI_VALID_NS:
- ret = rmi_rtt_unmap_unprotected(rd, map_addr, level,
- rtt_out_addr);
+ ret = host_rmi_rtt_unmap_unprotected(rd, map_addr, level,
+ rtt_out_addr);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_rtt_unmap_unprotected failed,"
- "addr=0x%lx, ret=0x%lx\n",
- map_addr, ret);
+ ERROR("%s() failed, addr=0x%lx ret=0x%lx\n",
+ "host_rmi_rtt_unmap_unprotected",
+ map_addr, ret);
return REALM_ERROR;
}
break;
@@ -615,22 +640,22 @@ static u_register_t realm_tear_down_rtt_range(struct realm *realm,
return REALM_SUCCESS;
}
-u_register_t rmi_granule_delegate(u_register_t addr)
+u_register_t host_rmi_granule_delegate(u_register_t addr)
{
- return rmi_handler(&(smc_args){RMI_GRANULE_DELEGATE, addr}, 2U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_GRANULE_DELEGATE, addr}, 2U).ret0;
}
-u_register_t rmi_granule_undelegate(u_register_t addr)
+u_register_t host_rmi_granule_undelegate(u_register_t addr)
{
- return rmi_handler(&(smc_args){RMI_GRANULE_UNDELEGATE, addr}, 2U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_GRANULE_UNDELEGATE, addr}, 2U).ret0;
}
-u_register_t rmi_version(void)
+u_register_t host_rmi_version(void)
{
- return rmi_handler(&(smc_args){RMI_VERSION}, 1U).ret0;
+ return host_rmi_handler(&(smc_args){RMI_VERSION}, 1U).ret0;
}
-u_register_t realm_create(struct realm *realm)
+u_register_t host_realm_create(struct realm *realm)
{
struct rmi_realm_params *params;
u_register_t ret;
@@ -655,10 +680,10 @@ u_register_t realm_create(struct realm *realm)
ERROR("Failed to allocate memory for rd\n");
goto err_free_par;
} else {
- ret = rmi_granule_delegate(realm->rd);
+ ret = host_rmi_granule_delegate(realm->rd);
if (ret != RMI_SUCCESS) {
- ERROR("rd delegation failed, rd=0x%lx, ret=0x%lx\n",
- realm->rd, ret);
+ ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_delegate", realm->rd, ret);
goto err_free_rd;
}
}
@@ -669,10 +694,10 @@ u_register_t realm_create(struct realm *realm)
ERROR("Failed to allocate memory for rtt_addr\n");
goto err_undelegate_rd;
} else {
- ret = rmi_granule_delegate(realm->rtt_addr);
+ ret = host_rmi_granule_delegate(realm->rtt_addr);
if (ret != RMI_SUCCESS) {
- ERROR("rtt delegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
- realm->rtt_addr, ret);
+ ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_delegate", realm->rtt_addr, ret);
goto err_free_rtt;
}
}
@@ -689,22 +714,22 @@ u_register_t realm_create(struct realm *realm)
params->rtt_level_start = 0L;
params->rtt_num_start = 1U;
params->rtt_base = realm->rtt_addr;
- params->vmid = 1U;
+ params->vmid = vmid++;
params->hash_algo = RMI_HASH_SHA_256;
/* Create Realm */
- ret = rmi_realm_create(realm->rd, (u_register_t)params);
+ ret = host_rmi_realm_create(realm->rd, (u_register_t)params);
if (ret != RMI_SUCCESS) {
- ERROR("Realm create failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
- ret);
+ ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
+ "host_rmi_realm_create", realm->rd, ret);
goto err_free_params;
}
- ret = rmi_rec_aux_count(realm->rd, &realm->num_aux);
+ ret = host_rmi_rec_aux_count(realm->rd, &realm->num_aux);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_rec_aux_count failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
- ret);
- rmi_realm_destroy(realm->rd);
+ ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
+ "host_rmi_rec_aux_count", realm->rd, ret);
+ host_rmi_realm_destroy(realm->rd);
goto err_free_params;
}
@@ -718,20 +743,20 @@ err_free_params:
page_free((u_register_t)params);
err_undelegate_rtt:
- ret = rmi_granule_undelegate(realm->rtt_addr);
+ ret = host_rmi_granule_undelegate(realm->rtt_addr);
if (ret != RMI_SUCCESS) {
- WARN("rtt undelegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
- realm->rtt_addr, ret);
+ WARN("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", realm->rtt_addr, ret);
}
err_free_rtt:
page_free(realm->rtt_addr);
err_undelegate_rd:
- ret = rmi_granule_undelegate(realm->rd);
+ ret = host_rmi_granule_undelegate(realm->rd);
if (ret != RMI_SUCCESS) {
- WARN("rd undelegation failed, rd=0x%lx, ret=0x%lx\n", realm->rd,
- ret);
+ WARN("%s() failed, rd=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", realm->rd, ret);
}
err_free_rd:
page_free(realm->rd);
@@ -742,8 +767,8 @@ err_free_par:
return REALM_ERROR;
}
-u_register_t realm_map_payload_image(struct realm *realm,
- u_register_t realm_payload_adr)
+u_register_t host_realm_map_payload_image(struct realm *realm,
+ u_register_t realm_payload_adr)
{
u_register_t src_pa = realm_payload_adr;
u_register_t i = 0UL;
@@ -751,13 +776,13 @@ u_register_t realm_map_payload_image(struct realm *realm,
/* MAP image regions */
while (i < (realm->par_size / PAGE_SIZE)) {
- ret = realm_map_protected_data(false, realm,
- realm->par_base + i * PAGE_SIZE,
- PAGE_SIZE,
- src_pa + i * PAGE_SIZE);
+ ret = host_realm_map_protected_data(false, realm,
+ realm->par_base + i * PAGE_SIZE,
+ PAGE_SIZE,
+ src_pa + i * PAGE_SIZE);
if (ret != RMI_SUCCESS) {
- ERROR("realm_map_protected_data failed,"
- "par_base=0x%lx ret=0x%lx\n",
+ ERROR("%s() failed, par_base=0x%lx ret=0x%lx\n",
+ "host_realm_map_protected_data",
realm->par_base, ret);
return REALM_ERROR;
}
@@ -767,28 +792,26 @@ u_register_t realm_map_payload_image(struct realm *realm,
return REALM_SUCCESS;
}
-u_register_t realm_init_ipa_state(struct realm *realm,
- u_register_t level,
- u_register_t start,
- uint64_t end)
+u_register_t host_realm_init_ipa_state(struct realm *realm, u_register_t level,
+ u_register_t start, uint64_t end)
{
u_register_t rd = realm->rd, ret;
- u_register_t map_size = rtt_level_mapsize(level);
+ u_register_t map_size = host_rtt_level_mapsize(level);
while (start < end) {
- ret = rmi_rtt_init_ripas(rd, start, level);
+ ret = host_rmi_rtt_init_ripas(rd, start, level);
if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
int cur_level = RMI_RETURN_INDEX(ret);
if (cur_level < level) {
- ret = rmi_create_rtt_levels(realm,
- start,
- cur_level,
- level);
+ ret = host_rmi_create_rtt_levels(realm,
+ start,
+ cur_level,
+ level);
if (ret != RMI_SUCCESS) {
- ERROR("rmi_create_rtt_levels failed,"
- "ret=0x%lx line:%d\n",
+ ERROR("%s() failed, ret=0x%lx line=%u\n",
+ "host_rmi_create_rtt_levels",
ret, __LINE__);
return ret;
}
@@ -801,8 +824,8 @@ u_register_t realm_init_ipa_state(struct realm *realm,
}
/* There's an entry at a lower level, recurse */
- realm_init_ipa_state(realm, start, start + map_size,
- level + 1);
+ host_realm_init_ipa_state(realm, start,
+ start + map_size, level + 1);
} else if (ret != RMI_SUCCESS) {
return REALM_ERROR;
}
@@ -813,9 +836,9 @@ u_register_t realm_init_ipa_state(struct realm *realm,
return RMI_SUCCESS;
}
-u_register_t realm_map_ns_shared(struct realm *realm,
- u_register_t ns_shared_mem_adr,
- u_register_t ns_shared_mem_size)
+u_register_t host_realm_map_ns_shared(struct realm *realm,
+ u_register_t ns_shared_mem_adr,
+ u_register_t ns_shared_mem_size)
{
u_register_t i = 0UL;
u_register_t ret;
@@ -826,12 +849,12 @@ u_register_t realm_map_ns_shared(struct realm *realm,
realm->ns_buffer_size = ns_shared_mem_size;
/* MAP SHARED_NS region */
while (i < ns_shared_mem_size / PAGE_SIZE) {
- ret = realm_map_unprotected(realm,
- ns_shared_mem_adr + i * PAGE_SIZE, PAGE_SIZE);
+ ret = host_realm_map_unprotected(realm, ns_shared_mem_adr +
+ (i * PAGE_SIZE), PAGE_SIZE);
if (ret != RMI_SUCCESS) {
- ERROR("\trealm_map_unprotected failepar"
- "base=0x%lx ret=0x%lx\n",
- (ns_shared_mem_adr + i * PAGE_SIZE), ret);
+ ERROR("%s() failed, par_base=0x%lx ret=0x%lx\n",
+ "host_realm_map_unprotected",
+ (ns_shared_mem_adr + i * PAGE_SIZE), ret);
return REALM_ERROR;
}
i++;
@@ -839,37 +862,37 @@ u_register_t realm_map_ns_shared(struct realm *realm,
return REALM_SUCCESS;
}
-static void realm_free_rec_aux(u_register_t *aux_pages, unsigned int num_aux)
+static void host_realm_free_rec_aux(u_register_t *aux_pages,
+ unsigned int num_aux)
{
u_register_t ret;
for (unsigned int i = 0U; i < num_aux; i++) {
- ret = rmi_granule_undelegate(aux_pages[i]);
+ ret = host_rmi_granule_undelegate(aux_pages[i]);
if (ret != RMI_SUCCESS) {
- WARN("realm_free_rec_aux undelegation failed,"
- "index=%u, ret=0x%lx\n",
- i, ret);
+ WARN("%s() failed, index=%u ret=0x%lx\n",
+ "host_rmi_granule_undelegate", i, ret);
}
page_free(aux_pages[i]);
}
}
-static u_register_t realm_alloc_rec_aux(struct realm *realm,
- struct rmi_rec_params *params)
+static u_register_t host_realm_alloc_rec_aux(struct realm *realm,
+ struct rmi_rec_params *params)
{
u_register_t ret;
unsigned int i;
- for (i = 0; i < realm->num_aux; i++) {
+ for (i = 0U; i < realm->num_aux; i++) {
params->aux[i] = (u_register_t)page_alloc(PAGE_SIZE);
if (params->aux[i] == HEAP_NULL_PTR) {
ERROR("Failed to allocate memory for aux rec\n");
goto err_free_mem;
}
- ret = rmi_granule_delegate(params->aux[i]);
+ ret = host_rmi_granule_delegate(params->aux[i]);
if (ret != RMI_SUCCESS) {
- ERROR("aux rec delegation failed at index=%d, ret=0x%lx\n",
- i, ret);
+ ERROR("%s() failed, index=%u ret=0x%lx\n",
+ "host_rmi_granule_delegate", i, ret);
goto err_free_mem;
}
@@ -878,11 +901,11 @@ static u_register_t realm_alloc_rec_aux(struct realm *realm,
}
return RMI_SUCCESS;
err_free_mem:
- realm_free_rec_aux(params->aux, i);
+ host_realm_free_rec_aux(params->aux, i);
return ret;
}
-u_register_t realm_rec_create(struct realm *realm)
+u_register_t host_realm_rec_create(struct realm *realm)
{
struct rmi_rec_params *rec_params = HEAP_NULL_PTR;
u_register_t ret;
@@ -901,10 +924,10 @@ u_register_t realm_rec_create(struct realm *realm)
ERROR("Failed to allocate memory for REC\n");
goto err_free_mem;
} else {
- ret = rmi_granule_delegate(realm->rec);
+ ret = host_rmi_granule_delegate(realm->rec);
if (ret != RMI_SUCCESS) {
- ERROR("rec delegation failed, rec=0x%lx, ret=0x%lx\n",
- realm->rd, ret);
+ ERROR("%s() failed, rec=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_delegate", realm->rd, ret);
goto err_free_mem;
}
}
@@ -918,16 +941,17 @@ u_register_t realm_rec_create(struct realm *realm)
(void)memset(rec_params, 0x0, PAGE_SIZE);
/* Populate rec_params */
- for (unsigned int i = 0UL; i < (sizeof(rec_params->gprs) /
+ for (unsigned int i = 0U; i < (sizeof(rec_params->gprs) /
sizeof(rec_params->gprs[0]));
i++) {
rec_params->gprs[i] = 0x0UL;
}
/* Delegate the required number of auxiliary Granules */
- ret = realm_alloc_rec_aux(realm, rec_params);
+ ret = host_realm_alloc_rec_aux(realm, rec_params);
if (ret != RMI_SUCCESS) {
- ERROR("REC realm_alloc_rec_aux, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n", "host_realm_alloc_rec_aux",
+ ret);
goto err_free_mem;
}
@@ -937,10 +961,9 @@ u_register_t realm_rec_create(struct realm *realm)
rec_params->num_aux = realm->num_aux;
/* Create REC */
- ret = rmi_rec_create(realm->rec, realm->rd,
- (u_register_t)rec_params);
+ ret = host_rmi_rec_create(realm->rec, realm->rd, (u_register_t)rec_params);
if (ret != RMI_SUCCESS) {
- ERROR("REC create failed, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n", "host_rmi_rec_create", ret);
goto err_free_rec_aux;
}
@@ -949,13 +972,13 @@ u_register_t realm_rec_create(struct realm *realm)
return REALM_SUCCESS;
err_free_rec_aux:
- realm_free_rec_aux(rec_params->aux, realm->num_aux);
+ host_realm_free_rec_aux(rec_params->aux, realm->num_aux);
err_undelegate_rec:
- ret = rmi_granule_undelegate(realm->rec);
+ ret = host_rmi_granule_undelegate(realm->rec);
if (ret != RMI_SUCCESS) {
- WARN("rec undelegation failed, rec=0x%lx, ret=0x%lx\n",
- realm->rec, ret);
+ WARN("%s() failed, rec=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", realm->rec, ret);
}
err_free_mem:
@@ -966,14 +989,15 @@ err_free_mem:
return REALM_ERROR;
}
-u_register_t realm_activate(struct realm *realm)
+u_register_t host_realm_activate(struct realm *realm)
{
u_register_t ret;
/* Activate Realm */
- ret = rmi_realm_activate(realm->rd);
+ ret = host_rmi_realm_activate(realm->rd);
if (ret != RMI_SUCCESS) {
- ERROR("Realm activate failed, ret=0x%lx\n", ret);
+ ERROR("%s() failed, ret=0x%lx\n", "host_rmi_realm_activate",
+ ret);
return REALM_ERROR;
}
@@ -982,7 +1006,7 @@ u_register_t realm_activate(struct realm *realm)
return REALM_SUCCESS;
}
-u_register_t realm_destroy(struct realm *realm)
+u_register_t host_realm_destroy(struct realm *realm)
{
u_register_t ret;
@@ -995,26 +1019,26 @@ u_register_t realm_destroy(struct realm *realm)
}
if (realm->state != REALM_STATE_ACTIVE) {
- ERROR("Invalid realm state found =0x%x\n", realm->state);
+ ERROR("Invalid realm state found 0x%x\n", realm->state);
return REALM_ERROR;
}
/* For each REC - Destroy, undelegate and free */
- ret = rmi_rec_destroy(realm->rec);
+ ret = host_rmi_rec_destroy(realm->rec);
if (ret != RMI_SUCCESS) {
- ERROR("REC destroy failed, rec=0x%lx, ret=0x%lx\n",
- realm->rec, ret);
+ ERROR("%s() failed, rec=0x%lx ret=0x%lx\n",
+ "host_rmi_rec_destroy", realm->rec, ret);
return REALM_ERROR;
}
- ret = rmi_granule_undelegate(realm->rec);
+ ret = host_rmi_granule_undelegate(realm->rec);
if (ret != RMI_SUCCESS) {
- ERROR("rec undelegation failed, rec=0x%lx, ret=0x%lx\n",
- realm->rec, ret);
+ ERROR("%s() failed, rec=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", realm->rec, ret);
return REALM_ERROR;
}
- realm_free_rec_aux(realm->aux_pages, realm->num_aux);
+ host_realm_free_rec_aux(realm->aux_pages, realm->num_aux);
page_free(realm->rec);
/* Free run object */
@@ -1026,16 +1050,16 @@ u_register_t realm_destroy(struct realm *realm)
* using RMI_DATA_DESTROY, RMI_RTT_DESTROY and RMI_GRANULE_UNDELEGATE
* commands.
*/
- if (realm_tear_down_rtt_range(realm, 0UL, 0UL,
- (1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
- realm->rmm_feat_reg0) - 1))) != RMI_SUCCESS) {
- ERROR("realm_tear_down_rtt_range\n");
+ if (host_realm_tear_down_rtt_range(realm, 0UL, 0UL,
+ (1UL << (EXTRACT(RMM_FEATURE_REGISTER_0_S2SZ,
+ realm->rmm_feat_reg0) - 1))) != RMI_SUCCESS) {
+ ERROR("host_realm_tear_down_rtt_range() line=%u\n", __LINE__);
return REALM_ERROR;
}
- if (realm_tear_down_rtt_range(realm, 0UL, realm->ipa_ns_buffer,
+ if (host_realm_tear_down_rtt_range(realm, 0UL, realm->ipa_ns_buffer,
(realm->ipa_ns_buffer + realm->ns_buffer_size)) !=
RMI_SUCCESS) {
- ERROR("realm_tear_down_rtt_range\n");
+ ERROR("host_realm_tear_down_rtt_range() line=%u\n", __LINE__);
return REALM_ERROR;
}
undo_from_new_state:
@@ -1045,24 +1069,24 @@ undo_from_new_state:
* RTT(L0) undelegate and free
* PAR free
*/
- ret = rmi_realm_destroy(realm->rd);
+ ret = host_rmi_realm_destroy(realm->rd);
if (ret != RMI_SUCCESS) {
- ERROR("Realm destroy failed, rd=0x%lx, ret=0x%lx\n",
- realm->rd, ret);
+ ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
+ "host_rmi_realm_destroy", realm->rd, ret);
return REALM_ERROR;
}
- ret = rmi_granule_undelegate(realm->rd);
+ ret = host_rmi_granule_undelegate(realm->rd);
if (ret != RMI_SUCCESS) {
- ERROR("rd undelegation failed, rd=0x%lx, ret=0x%lx\n",
- realm->rd, ret);
+ ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", realm->rd, ret);
return REALM_ERROR;
}
- ret = rmi_granule_undelegate(realm->rtt_addr);
+ ret = host_rmi_granule_undelegate(realm->rtt_addr);
if (ret != RMI_SUCCESS) {
- ERROR("rtt undelegation failed, rtt_addr=0x%lx, ret=0x%lx\n",
- realm->rtt_addr, ret);
+ ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+ "host_rmi_granule_undelegate", realm->rtt_addr, ret);
return REALM_ERROR;
}
@@ -1073,9 +1097,9 @@ undo_from_new_state:
return REALM_SUCCESS;
}
-
-u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
- unsigned int *test_result)
+u_register_t host_realm_rec_enter(struct realm *realm,
+ u_register_t *exit_reason,
+ unsigned int *host_call_result)
{
struct rmi_rec_run *run = (struct rmi_rec_run *)realm->run;
u_register_t ret;
@@ -1083,20 +1107,15 @@ u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
do {
re_enter_rec = false;
- ret = rmi_handler(&(smc_args){RMI_REC_ENTER,
+ ret = host_rmi_handler(&(smc_args){RMI_REC_ENTER,
realm->rec, realm->run}, 3U).ret0;
- VERBOSE("rmi_rec_enter, \
- run->exit.exit_reason=0x%lx, \
- run->exit.esr=0x%lx, \
- EC_BITS=%d, \
- ISS_DFSC_MASK=0x%lx\n",
- run->exit.exit_reason,
- run->exit.esr,
- ((EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL)),
- (ISS_BITS(run->exit.esr) & ISS_DFSC_MASK));
-
- /* If a data abort because of a GPF. */
+ VERBOSE("%s() run->exit.exit_reason=%lu "
+ "run->exit.esr=0x%lx EC_BITS=%u ISS_DFSC_MASK=0x%lx\n",
+ __func__, run->exit.exit_reason, run->exit.esr,
+ ((EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL)),
+ (ISS_BITS(run->exit.esr) & ISS_DFSC_MASK));
+ /* If a data abort because of a GPF */
if (EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL) {
ERROR("EC_BITS(run->exit.esr) == EC_DABORT_CUR_EL\n");
if ((ISS_BITS(run->exit.esr) & ISS_DFSC_MASK) ==
@@ -1105,7 +1124,6 @@ u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
}
}
-
if (ret != RMI_SUCCESS) {
return ret;
}
@@ -1117,20 +1135,16 @@ u_register_t realm_rec_enter(struct realm *realm, u_register_t *exit_reason,
re_enter_rec = true;
break;
case HOST_CALL_EXIT_SUCCESS_CMD:
- *test_result = TEST_RESULT_SUCCESS;
+ *host_call_result = TEST_RESULT_SUCCESS;
break;
case HOST_CALL_EXIT_FAILED_CMD:
- *test_result = TEST_RESULT_FAIL;
- break;
+ *host_call_result = TEST_RESULT_FAIL;
default:
break;
}
-
}
-
} while (re_enter_rec);
*exit_reason = run->exit.exit_reason;
-
return ret;
}
diff --git a/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
index f35bf65..77d2db0 100644
--- a/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_delegate_tests.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -16,10 +16,8 @@
#include "rmi_spm_tests.h"
#include <test_helpers.h>
-
-
-static test_result_t realm_multi_cpu_payload_test(void);
-static test_result_t realm_multi_cpu_payload_del_undel(void);
+static test_result_t host_realm_multi_cpu_payload_test(void);
+static test_result_t host_realm_multi_cpu_payload_del_undel(void);
/* Buffer to delegate and undelegate */
static char bufferdelegate[NUM_GRANULES * GRANULE_SIZE * PLATFORM_CORE_COUNT]
@@ -43,19 +41,19 @@ static char bufferstate[NUM_GRANULES * PLATFORM_CORE_COUNT];
* twice and then testing a misaligned address
*/
-test_result_t init_buffer_del(void)
+test_result_t host_init_buffer_del(void)
{
u_register_t retrmm;
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if ((rand() % 2) == 0) {
- retrmm = rmi_granule_delegate(
- (u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+ retrmm = host_rmi_granule_delegate(
+ (u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
bufferstate[i] = B_DELEGATED;
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation returns fail, %lx\n",
+ tftf_testcase_printf("Delegate operation returns 0x%lx\n",
retrmm);
return TEST_RESULT_FAIL;
}
@@ -70,7 +68,7 @@ test_result_t init_buffer_del(void)
/*
* Single CPU version check function
*/
-test_result_t realm_version_single_cpu(void)
+test_result_t host_realm_version_single_cpu(void)
{
u_register_t retrmm;
@@ -78,9 +76,9 @@ test_result_t realm_version_single_cpu(void)
return TEST_RESULT_SKIPPED;
}
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
- retrmm = rmi_version();
+ retrmm = host_rmi_version();
tftf_testcase_printf("RMM version is: %lu.%lu\n",
RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -92,7 +90,7 @@ test_result_t realm_version_single_cpu(void)
/*
* Multi CPU version check function in parallel.
*/
-test_result_t realm_version_multi_cpu(void)
+test_result_t host_realm_version_multi_cpu(void)
{
u_register_t lead_mpid, target_mpid;
int cpu_node;
@@ -102,7 +100,7 @@ test_result_t realm_version_multi_cpu(void)
return TEST_RESULT_SKIPPED;
}
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
lead_mpid = read_mpidr_el1() & MPID_MASK;
@@ -114,7 +112,7 @@ test_result_t realm_version_multi_cpu(void)
}
ret = tftf_cpu_on(target_mpid,
- (uintptr_t)realm_multi_cpu_payload_test, 0);
+ (uintptr_t)host_realm_multi_cpu_payload_test, 0);
if (ret != PSCI_E_SUCCESS) {
ERROR("CPU ON failed for 0x%llx\n",
@@ -124,7 +122,7 @@ test_result_t realm_version_multi_cpu(void)
}
- ret = realm_multi_cpu_payload_test();
+ ret = host_realm_multi_cpu_payload_test();
for_each_cpu(cpu_node) {
target_mpid = tftf_get_mpidr_from_node(cpu_node) & MPID_MASK;
@@ -145,7 +143,7 @@ test_result_t realm_version_multi_cpu(void)
/*
* Delegate and Undelegate Non Secure Granule
*/
-test_result_t realm_delegate_undelegate(void)
+test_result_t host_realm_delegate_undelegate(void)
{
u_register_t retrmm;
@@ -153,16 +151,18 @@ test_result_t realm_delegate_undelegate(void)
return TEST_RESULT_SKIPPED;
}
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
- retrmm = rmi_granule_delegate((u_register_t)bufferdelegate);
+ retrmm = host_rmi_granule_delegate((u_register_t)bufferdelegate);
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Delegate operation returns 0x%lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
- retrmm = rmi_granule_undelegate((u_register_t)bufferdelegate);
+ retrmm = host_rmi_granule_undelegate((u_register_t)bufferdelegate);
if (retrmm != 0UL) {
- tftf_testcase_printf("Undelegate operation returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Undelegate operation returns 0x%lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
tftf_testcase_printf("Delegate and undelegate of buffer 0x%lx succeeded\n",
@@ -171,13 +171,13 @@ test_result_t realm_delegate_undelegate(void)
return host_cmp_result();
}
-static test_result_t realm_multi_cpu_payload_test(void)
+static test_result_t host_realm_multi_cpu_payload_test(void)
{
u_register_t retrmm;
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
- retrmm = rmi_version();
+ retrmm = host_rmi_version();
tftf_testcase_printf("Multi CPU RMM version on CPU %llx is: %lu.%lu\n",
(long long)read_mpidr_el1() & MPID_MASK, RMI_ABI_VERSION_GET_MAJOR(retrmm),
@@ -190,7 +190,7 @@ static test_result_t realm_multi_cpu_payload_test(void)
* Select all CPU's to randomly delegate/undelegate
* granule pages to stress the delegate mechanism
*/
-test_result_t realm_delundel_multi_cpu(void)
+test_result_t host_realm_delundel_multi_cpu(void)
{
u_register_t lead_mpid, target_mpid;
int cpu_node;
@@ -203,9 +203,9 @@ test_result_t realm_delundel_multi_cpu(void)
lead_mpid = read_mpidr_el1() & MPID_MASK;
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
- if (init_buffer_del() == TEST_RESULT_FAIL) {
+ if (host_init_buffer_del() == TEST_RESULT_FAIL) {
return TEST_RESULT_FAIL;
}
@@ -217,7 +217,7 @@ test_result_t realm_delundel_multi_cpu(void)
}
ret = tftf_cpu_on(target_mpid,
- (uintptr_t)realm_multi_cpu_payload_del_undel, 0);
+ (uintptr_t)host_realm_multi_cpu_payload_del_undel, 0);
if (ret != PSCI_E_SUCCESS) {
ERROR("CPU ON failed for 0x%llx\n",
@@ -245,8 +245,8 @@ test_result_t realm_delundel_multi_cpu(void)
*/
for (uint32_t i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if (bufferstate[i] == B_DELEGATED) {
- retrmm = rmi_granule_undelegate(
- (u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
+ retrmm = host_rmi_granule_undelegate(
+ (u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
bufferstate[i] = B_UNDELEGATED;
if (retrmm != 0UL) {
tftf_testcase_printf("Delegate operation returns fail, %lx\n",
@@ -266,27 +266,28 @@ test_result_t realm_delundel_multi_cpu(void)
* assigns NUM_GRANULES to each CPU for delegation or undelgation
* depending upon the initial state
*/
-static test_result_t realm_multi_cpu_payload_del_undel(void)
+static test_result_t host_realm_multi_cpu_payload_del_undel(void)
{
u_register_t retrmm;
unsigned int cpu_node;
cpu_node = platform_get_core_pos(read_mpidr_el1() & MPID_MASK);
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
for (uint32_t i = 0; i < NUM_GRANULES; i++) {
if (bufferstate[((cpu_node * NUM_GRANULES) + i)] == B_UNDELEGATED) {
- retrmm = rmi_granule_delegate((u_register_t)
- &bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
+ retrmm = host_rmi_granule_delegate((u_register_t)
+ &bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_DELEGATED;
} else {
- retrmm = rmi_granule_undelegate((u_register_t)
- &bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
+ retrmm = host_rmi_granule_undelegate((u_register_t)
+ &bufferdelegate[((cpu_node * NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_UNDELEGATED;
}
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Delegate operation returns 0x%lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
}
@@ -299,7 +300,7 @@ static test_result_t realm_multi_cpu_payload_del_undel(void)
* for processing the same granule twice and the second is submission of
* a misaligned address
*/
-test_result_t realm_fail_del(void)
+test_result_t host_realm_fail_del(void)
{
if (get_armv9_2_feat_rme_support() == 0U) {
return TEST_RESULT_SKIPPED;
@@ -307,33 +308,33 @@ test_result_t realm_fail_del(void)
u_register_t retrmm;
- rmi_init_cmp_result();
-
- retrmm = rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
+ host_rmi_init_cmp_result();
+ retrmm = host_rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
if (retrmm != 0UL) {
tftf_testcase_printf
- ("Delegate operation does not pass as expected for double delegation, %lx\n", retrmm);
+ ("Delegate operation does not pass as expected for double delegation, %lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
- retrmm = rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
-
+ retrmm = host_rmi_granule_delegate((u_register_t)&bufferdelegate[0]);
if (retrmm == 0UL) {
tftf_testcase_printf
- ("Delegate operation does not fail as expected for double delegation, %lx\n", retrmm);
+ ("Delegate operation does not fail as expected for double delegation, %lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
- retrmm = rmi_granule_undelegate((u_register_t)&bufferdelegate[1]);
-
+ retrmm = host_rmi_granule_undelegate((u_register_t)&bufferdelegate[1]);
if (retrmm == 0UL) {
tftf_testcase_printf
- ("Delegate operation does not return fail for misaligned address, %lx\n", retrmm);
+ ("Delegate operation does not return fail for misaligned address, %lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
- retrmm = rmi_granule_undelegate((u_register_t)&bufferdelegate[0]);
+ retrmm = host_rmi_granule_undelegate((u_register_t)&bufferdelegate[0]);
if (retrmm != 0UL) {
tftf_testcase_printf
diff --git a/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
index c313a23..7d2fe7f 100644
--- a/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_spm_tests.c
@@ -89,12 +89,12 @@ static test_result_t init_buffer_del_spm_rmi(void)
for (int i = 0; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if ((rand() % 2) == 0) {
- retrmm = rmi_granule_delegate(
+ retrmm = host_rmi_granule_delegate(
(u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
bufferstate[i] = B_DELEGATED;
if (retrmm != 0UL) {
- tftf_testcase_printf("Delegate operation\
- returns fail, %lx\n", retrmm);
+ tftf_testcase_printf("Delegate operation returns 0x%lx\n",
+ retrmm);
return TEST_RESULT_FAIL;
}
} else {
@@ -110,7 +110,7 @@ static test_result_t reset_buffer_del_spm_rmi(void)
for (uint32_t i = 0U; i < (NUM_GRANULES * PLATFORM_CORE_COUNT) ; i++) {
if (bufferstate[i] == B_DELEGATED) {
- retrmm = rmi_granule_undelegate(
+ retrmm = host_rmi_granule_undelegate(
(u_register_t)&bufferdelegate[i * GRANULE_SIZE]);
if (retrmm != 0UL) {
ERROR("Undelegate operation returns fail, %lx\n",
@@ -315,12 +315,12 @@ static test_result_t realm_multi_cpu_payload_del_undel(void)
for (int i = 0; i < NUM_GRANULES; i++) {
if (bufferstate[((cpu_node * NUM_GRANULES) + i)] == B_UNDELEGATED) {
- retrmm = rmi_granule_delegate((u_register_t)
+ retrmm = host_rmi_granule_delegate((u_register_t)
&bufferdelegate[((cpu_node *
NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_DELEGATED;
} else {
- retrmm = rmi_granule_undelegate((u_register_t)
+ retrmm = host_rmi_granule_undelegate((u_register_t)
&bufferdelegate[((cpu_node *
NUM_GRANULES) + i) * GRANULE_SIZE]);
bufferstate[((cpu_node * NUM_GRANULES) + i)] = B_UNDELEGATED;
@@ -360,7 +360,7 @@ test_result_t test_spm_rmm_serial_smc(void)
**********************************************************************/
CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
/*
* Randomize the initial state of the RMI granules to realm or non-secure
@@ -420,7 +420,7 @@ test_result_t test_spm_rmm_parallel_smc(void)
**********************************************************************/
CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
/*
* Randomize the initial state of the RMI granules to realm or non-secure
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
index 14b08b2..42fab1d 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_tests.c
@@ -1,22 +1,31 @@
/*
- * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdlib.h>
+#include <assert.h>
#include <arch_features.h>
#include <debug.h>
+#include <irq.h>
+#include <drivers/arm/arm_gic.h>
+#include <drivers/arm/gic_v3.h>
+
#include <host_realm_helper.h>
#include <host_realm_mem_layout.h>
+#include <host_realm_pmu.h>
#include <host_shared_data.h>
#define SLEEP_TIME_MS 200U
+
+extern const char *rmi_exit[];
+
/*
* @Test_Aim@ Test realm payload creation and execution
*/
-test_result_t test_realm_create_enter(void)
+test_result_t host_test_realm_create_enter(void)
{
bool ret1, ret2;
u_register_t retrmm;
@@ -26,9 +35,9 @@ test_result_t test_realm_create_enter(void)
return TEST_RESULT_SKIPPED;
}
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
- retrmm = rmi_version();
+ retrmm = host_rmi_version();
VERBOSE("RMM version is: %lu.%lu\n",
RMI_ABI_VERSION_GET_MAJOR(retrmm),
RMI_ABI_VERSION_GET_MINOR(retrmm));
@@ -44,7 +53,8 @@ test_result_t test_realm_create_enter(void)
(u_register_t)PAGE_POOL_BASE,
(u_register_t)(PAGE_POOL_MAX_SIZE +
NS_REALM_SHARED_MEM_SIZE),
- (u_register_t)PAGE_POOL_MAX_SIZE)) {
+ (u_register_t)PAGE_POOL_MAX_SIZE,
+ 0UL)) {
return TEST_RESULT_FAIL;
}
if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
@@ -53,14 +63,186 @@ test_result_t test_realm_create_enter(void)
}
realm_shared_data_set_host_val(HOST_SLEEP_INDEX, SLEEP_TIME_MS);
- ret1 = host_enter_realm_execute(REALM_SLEEP_CMD);
+ ret1 = host_enter_realm_execute(REALM_SLEEP_CMD, NULL);
ret2 = host_destroy_realm();
if (!ret1 || !ret2) {
- ERROR("test_realm_create_enter create:%d destroy:%d\n",
- ret1, ret2);
+ ERROR("%s(): enter=%d destroy=%d\n",
+ __func__, ret1, ret2);
+ return TEST_RESULT_FAIL;
+ }
+
+ return host_cmp_result();
+}
+/*
+ * This function is called on REC exit due to IRQ.
+ * By checking Realm PMU state in RecExit object this finction
+ * detects if the exit was caused by PMU interrupt. In that
+ * case it disables physical PMU interrupt and sets virtual
+ * PMU interrupt pending by writing to gicv3_lrs attribute
+ * of RecEntry object and re-enters the Realm.
+ *
+ * @return true in case of PMU interrupt, false otherwise.
+ */
+static bool host_realm_handle_irq_exit(struct realm *realm_ptr)
+{
+ struct rmi_rec_run *run = (struct rmi_rec_run *)realm_ptr->run;
+
+ /* Check PMU state */
+ if ((run->exit.pmu_ovf & run->exit.pmu_intr_en &
+ run->exit.pmu_cntr_en) != 0UL) {
+ unsigned int host_call_result;
+ u_register_t exit_reason, retrmm;
+ int ret;
+
+ tftf_irq_disable(PMU_PPI);
+ ret = tftf_irq_unregister_handler(PMU_PPI);
+ if (ret != 0) {
+ ERROR("Failed to %sregister IRQ handler\n", "un");
+ return false;
+ }
+
+ /* Inject PMU virtual interrupt */
+ run->entry.gicv3_lrs[0] =
+ ICH_LRn_EL2_STATE_Pending | ICH_LRn_EL2_Group_1 |
+ (PMU_VIRQ << ICH_LRn_EL2_vINTID_SHIFT);
+
+ /* Re-enter Realm */
+ INFO("Re-entering Realm with vIRQ %lu pending\n", PMU_VIRQ);
+
+ retrmm = host_realm_rec_enter(realm_ptr, &exit_reason,
+ &host_call_result);
+ if ((retrmm == REALM_SUCCESS) &&
+ (exit_reason == RMI_EXIT_HOST_CALL) &&
+ (host_call_result == TEST_RESULT_SUCCESS)) {
+ return true;
+ }
+
+ ERROR("%s() failed, ret=%lx host_call_result %u\n",
+ "host_realm_rec_enter", retrmm, host_call_result);
+ }
+ return false;
+}
+
+/*
+ * @Test_Aim@ Test realm PMU
+ *
+ * This function tests PMU functionality in Realm
+ *
+ * @cmd: PMU test number
+ * @return test result
+ */
+static test_result_t host_test_realm_pmuv3(uint8_t cmd)
+{
+ struct realm *realm_ptr;
+ u_register_t retrmm;
+ bool ret1, ret2;
+
+ if (get_armv9_2_feat_rme_support() == 0U) {
+ INFO("platform doesn't support RME\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ host_rmi_init_cmp_result();
+
+ retrmm = host_rmi_version();
+ VERBOSE("RMM version is: %lu.%lu\n",
+ RMI_ABI_VERSION_GET_MAJOR(retrmm),
+ RMI_ABI_VERSION_GET_MINOR(retrmm));
+ /*
+ * Skip the test if RMM is TRP, TRP version is always null.
+ */
+ if (retrmm == 0UL) {
+ INFO("Test case not supported for TRP as RMM\n");
+ return TEST_RESULT_SKIPPED;
+ }
+
+ host_set_pmu_state();
+
+ if (!host_create_realm_payload((u_register_t)REALM_IMAGE_BASE,
+ (u_register_t)PAGE_POOL_BASE,
+ (u_register_t)(PAGE_POOL_MAX_SIZE +
+ NS_REALM_SHARED_MEM_SIZE),
+ (u_register_t)PAGE_POOL_MAX_SIZE,
+ RMI_FEATURE_REGISTER_0_PMU_EN)) {
+ return TEST_RESULT_FAIL;
+ }
+ if (!host_create_shared_mem(NS_REALM_SHARED_MEM_BASE,
+ NS_REALM_SHARED_MEM_SIZE)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ ret1 = host_enter_realm_execute(cmd, &realm_ptr);
+ if (!ret1 || (cmd != REALM_PMU_INTERRUPT)) {
+ goto test_exit;
+ }
+
+ ret1 = host_realm_handle_irq_exit(realm_ptr);
+
+test_exit:
+ ret2 = host_destroy_realm();
+ if (!ret1 || !ret2) {
+ ERROR("%s() enter=%u destroy=%u\n", __func__, ret1, ret2);
+ return TEST_RESULT_FAIL;
+ }
+
+ if (!host_check_pmu_state()) {
return TEST_RESULT_FAIL;
}
return host_cmp_result();
}
+
+/*
+ * Test if the cycle counter works in Realm with NOPs execution
+ */
+test_result_t host_realm_pmuv3_cycle_works(void)
+{
+ return host_test_realm_pmuv3(REALM_PMU_CYCLE);
+}
+
+/*
+ * Test if the event counter works in Realm with NOPs execution
+ */
+test_result_t host_realm_pmuv3_event_works(void)
+{
+ return host_test_realm_pmuv3(REALM_PMU_EVENT);
+}
+
+/*
+ * Test if Realm entering/exiting RMM preserves PMU state
+ */
+test_result_t host_realm_pmuv3_rmm_preserves(void)
+{
+ return host_test_realm_pmuv3(REALM_PMU_PRESERVE);
+}
+
+/*
+ * IRQ handler for PMU_PPI #23.
+ * This handler should not be called, as RMM handles IRQs.
+ */
+static int host_overflow_interrupt(void *data)
+{
+ (void)data;
+
+ assert(false);
+ return -1;
+}
+
+/*
+ * Test PMU interrupt functionality in Realm
+ */
+test_result_t host_realm_pmuv3_overflow_interrupt(void)
+{
+ /* Register PMU IRQ handler */
+ int ret = tftf_irq_register_handler(PMU_PPI, host_overflow_interrupt);
+
+ if (ret != 0) {
+ tftf_testcase_printf("Failed to %sregister IRQ handler\n",
+ "");
+ return TEST_RESULT_FAIL;
+ }
+
+ tftf_irq_enable(PMU_PPI, GIC_HIGHEST_NS_PRIORITY);
+ return host_test_realm_pmuv3(REALM_PMU_INTERRUPT);
+}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
index 75cd942..870a00a 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_exceptions.c
@@ -70,12 +70,12 @@ test_result_t rl_memory_cannot_be_accessed_in_s(void)
VERBOSE("TFTF - Handle: %llx Address: %p\n",
handle, constituents[0].address);
- rmi_init_cmp_result();
+ host_rmi_init_cmp_result();
/* Delegate the shared page to Realm. */
- retmm = rmi_granule_delegate((u_register_t)&share_page);
+ retmm = host_rmi_granule_delegate((u_register_t)&share_page);
if (retmm != 0UL) {
- ERROR("Granule delegate failed!\n");
+ ERROR("Granule delegate failed, ret=0x%lx\n", retmm);
return TEST_RESULT_FAIL;
}
@@ -84,9 +84,9 @@ test_result_t rl_memory_cannot_be_accessed_in_s(void)
handle, 0, true, 1);
/* Undelegate the shared page. */
- retmm = rmi_granule_undelegate((u_register_t)&share_page);
+ retmm = host_rmi_granule_undelegate((u_register_t)&share_page);
if (retmm != 0UL) {
- ERROR("Granule undelegate failed!\n");
+ ERROR("Granule undelegate failed, ret=0x%lx\n", retmm);
return TEST_RESULT_FAIL;
}
diff --git a/tftf/tests/tests-realm-payload.mk b/tftf/tests/tests-realm-payload.mk
index 6d23e38..764a51e 100644
--- a/tftf/tests/tests-realm-payload.mk
+++ b/tftf/tests/tests-realm-payload.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -14,6 +14,7 @@ TESTS_SOURCES += \
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/host_realm_managment/, \
+ host_pmuv3.c \
host_realm_rmi.c \
host_realm_helper.c \
host_shared_data.c \
@@ -23,4 +24,4 @@ TESTS_SOURCES += \
TESTS_SOURCES += \
$(addprefix lib/heap/, \
page_alloc.c \
- ) \ No newline at end of file
+ )
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 8438ea1..e84929a 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2021, Arm Limited. All rights reserved.
+ Copyright (c) 2021-2023, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -9,16 +9,24 @@
<testsuites>
<testsuite name="Realm payload at EL1" description="Test Realm EL1 framework capabilities" >
<testcase name="Realm EL1 creation and execution test"
- function="test_realm_create_enter" />
+ function="host_test_realm_create_enter" />
<testcase name="Realm payload boot"
- function="realm_version_single_cpu" />
+ function="host_realm_version_single_cpu" />
<testcase name="Realm payload multi CPU request"
- function="realm_version_multi_cpu" />
+ function="host_realm_version_multi_cpu" />
<testcase name="Realm payload Delegate and Undelegate"
- function="realm_delegate_undelegate" />
+ function="host_realm_delegate_undelegate" />
<testcase name="Multi CPU Realm payload Delegate and Undelegate"
- function="realm_delundel_multi_cpu" />
+ function="host_realm_delundel_multi_cpu" />
<testcase name="Testing delegation fails"
- function="realm_fail_del" />
+ function="host_realm_fail_del" />
+ <testcase name="PMUv3 cycle counter functional in Realm"
+ function="host_realm_pmuv3_cycle_works" />
+ <testcase name="PMUv3 event counter functional in Realm"
+ function="host_realm_pmuv3_event_works" />
+ <testcase name="PMUv3 RSI SMC counter preservation"
+ function="host_realm_pmuv3_rmm_preserves" />
+ <testcase name="PMUv3 overflow interrupt"
+ function="host_realm_pmuv3_overflow_interrupt" />
</testsuite>
</testsuites>
diff --git a/tftf/tests/tests-standard.mk b/tftf/tests/tests-standard.mk
index d57c381..988a0b8 100644
--- a/tftf/tests/tests-standard.mk
+++ b/tftf/tests/tests-standard.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2023, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -24,7 +24,12 @@ TESTS_MAKEFILE := $(addprefix tftf/tests/, \
tests-uncontainable.mk \
tests-debugfs.mk \
tests-rmi-spm.mk \
+)
+
+ifeq (${ARCH},aarch64)
+TESTS_MAKEFILE += $(addprefix tftf/tests/, \
tests-realm-payload.mk \
)
+endif
include ${TESTS_MAKEFILE}