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
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 @@
  * 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_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(pmcntenset_el0)
-DEFINE_SYSREG_READ_FUNC(pmccntr_el0)
-DEFINE_SYSREG_RW_FUNCS(pmccfiltr_el0)
 
+DEFINE_SYSREG_RW_FUNCS(pmcr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcntenclr_el0)
+DEFINE_SYSREG_RW_FUNCS(pmcntenset_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(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_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 @@
 		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 @@
 };
 
 /* 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 @@
  */
 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 @@
 	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 @@
 	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
similarity index 65%
rename from realm/platform.h
rename to 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 @@
 	return 0U;
 }
 
-#endif /* REALM_PLATFORM_H */
+#endif /* PLATFORM_H */
diff --git a/realm/realm_rsi.h b/realm/include/realm_rsi.h
similarity index 95%
rename from realm/realm_rsi.h
rename to 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 @@
 	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 @@
 
 
 #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 @@
 	-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 @@
 
 	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 @@
  */
 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 @@
 			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 @@
 		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 @@
 		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 @@
 
 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 @@
 		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 @@
 		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 @@
 		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 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 @@
 	< ((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 @@
 
 		/*
 		 * 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 @@
 /*
  * 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 @@
 	/* 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 @@
 					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 @@
 					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 @@
 }
 
 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 @@
 			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 @@
 
 	/* 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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 			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 @@
 	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_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 @@
 		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 @@
 	}
 
 	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 @@
 
 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 @@
 	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 @@
 			(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 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 @@
 	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 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 @@
 		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 @@
 
 		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 @@
 	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 @@
 		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 @@
 		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 @@
 	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 @@
 	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 @@
 	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 @@
 
 	/* 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 @@
 	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 @@
 			}
 
 			/* 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 @@
 	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 @@
 	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 @@
 	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 @@
 	}
 	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 @@
 		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 @@
 	(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 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 	}
 
 	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 @@
 	 * 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 @@
 	 * 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 @@
 	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 @@
 
 	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));
+		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 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 @@
 			}
 		}
 
-
 		if (ret != RMI_SUCCESS) {
 			return ret;
 		}
@@ -1117,20 +1135,16 @@
 				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 @@
  * 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 @@
 /*
  * 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 @@
 		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 @@
 /*
  * 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 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
-	rmi_init_cmp_result();
+	host_rmi_init_cmp_result();
 
 	lead_mpid = read_mpidr_el1() & MPID_MASK;
 
@@ -114,7 +112,7 @@
 		}
 
 		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 @@
 
 	}
 
-	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 @@
 /*
  * 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 @@
 		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 @@
 	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 @@
  * 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 @@
 
 	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 @@
 		}
 
 		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 @@
 	 */
 	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 @@
  * 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 @@
  * 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 @@
 
 	u_register_t retrmm;
 
-	rmi_init_cmp_result();
+	host_rmi_init_cmp_result();
 
-	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 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 @@
 
 	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 @@
 
 	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 @@
 
 	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 @@
 	 **********************************************************************/
 	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 @@
 	 **********************************************************************/
 	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 @@
 		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 @@
 			(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 @@
 	}
 
 	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 @@
 	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 @@
 				  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	+=							\
 	$(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	+=							\
 	$(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-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}