diff options
author | AlexeiFedorov <Alexei.Fedorov@arm.com> | 2023-03-13 19:37:46 +0000 |
---|---|---|
committer | Soby Mathew <soby.mathew@arm.com> | 2023-03-31 11:41:56 +0200 |
commit | 2f30f1030f186760b20cd06b59832e332b2bdd0a (patch) | |
tree | e06899ba1be405650b4a15603429900dac67ccc2 | |
parent | 2eb601b98a245df8a31e670a7dc322c2e8f153cf (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
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} |