Merge "test(psci): add test to validate "psci_is_last_cpu_to_idle_at_pwrlvl""
diff --git a/.gitignore b/.gitignore
index 708900d..7548ec2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,8 @@
 # Ignore build directory and binary files
 build/
 *.bin
+
+# Ignore the generated fuzzing files
+arg_struct_def.h
+field_specification.h
+fuzz_names.h
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index 124cc4e..8ca4cdf 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -431,6 +431,13 @@
 		}								\
 	} while (false)
 
+#define SKIP_TEST_IF_FEAT_MPAM_NOT_SUPPORTED()					\
+	do {									\
+		if (is_feat_mpam_supported() == false) {			\
+			return TEST_RESULT_SKIPPED;				\
+		}								\
+	} while (false)								\
+
 /* Helper macro to verify if system suspend API is supported */
 #define is_psci_sys_susp_supported()	\
 		(tftf_get_psci_feature_info(SMC_PSCI_SYSTEM_SUSPEND)		\
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index f0d1398..1d5e75a 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -1037,13 +1037,22 @@
 #define EC_AARCH32_FP			U(0x28)
 #define EC_AARCH64_FP			U(0x2c)
 #define EC_SERROR			U(0x2f)
+
+/* Common DFSC/IFSC code */
+#define ISS_FSC_MASK			U(0x3f)
+#define FSC_L0_ADR_SIZE_FAULT		U(0)
+#define FSC_L0_TRANS_FAULT		U(4)
+#define FSC_L1_TRANS_FAULT		U(5)
+#define FSC_L2_TRANS_FAULT		U(6)
+#define FSC_L3_TRANS_FAULT		U(7)
+#define FSC_L_MINUS1_TRANS_FAULT	U(0x2B)
+#define FSC_L0_PERM_FAULT		U(0xC)
+#define FSC_L1_PERM_FAULT		U(0xD)
+#define FSC_L2_PERM_FAULT		U(0xE)
+#define FSC_L3_PERM_FAULT		U(0xF)
+
 /* Data Fault Status code, not all error codes listed */
 #define ISS_DFSC_MASK			U(0x3f)
-#define DFSC_L0_ADR_SIZE_FAULT		U(0)
-#define DFSC_L0_TRANS_FAULT		U(4)
-#define DFSC_L1_TRANS_FAULT		U(5)
-#define DFSC_L2_TRANS_FAULT		U(6)
-#define DFSC_L3_TRANS_FAULT		U(7)
 #define DFSC_NO_WALK_SEA		U(0x10)
 #define DFSC_L0_SEA			U(0x14)
 #define DFSC_L1_SEA			U(0x15)
@@ -1054,11 +1063,6 @@
 
 /* Instr Fault Status code, not all error codes listed */
 #define ISS_IFSC_MASK			U(0x3f)
-#define IFSC_L0_ADR_SIZE_FAULT		U(0)
-#define IFSC_L0_TRANS_FAULT		U(4)
-#define IFSC_L1_TRANS_FAULT		U(5)
-#define IFSC_L2_TRANS_FAULT		U(6)
-#define IFSC_L3_TRANS_FAULT		U(7)
 #define IFSC_NO_WALK_SEA		U(0x10)
 #define IFSC_L0_SEA			U(0x24)
 #define IFSC_L1_SEA			U(0x25)
@@ -1167,6 +1171,10 @@
 #define PMSELR_EL0_SEL_SHIFT		U(0)
 #define PMSELR_EL0_SEL_MASK		U(0x1f)
 
+/* PMINTENSET_EL1 definitions */
+#define PMINTENSET_EL1_C_BIT		(U(1) << 31)
+#define PMINTENSET_EL1_P_BIT(x)		(U(1) << x)
+
 /* PMU event counter ID definitions */
 #define PMU_EV_PC_WRITE_RETIRED		U(0x000C)
 
@@ -1701,4 +1709,72 @@
  ******************************************************************************/
 #define FPMR			S3_3_C4_C4_2
 
+/******************************************************************************
+ * Definitions of system register identifiers
+ *****************************************************************************/
+
+#define ESR_EL2_SYSREG_TRAP_OP0_SHIFT	20
+#define ESR_EL2_SYSREG_TRAP_OP0_WIDTH	U(2)
+
+#define ESR_EL2_SYSREG_TRAP_OP2_SHIFT	17
+#define ESR_EL2_SYSREG_TRAP_OP2_WIDTH	U(3)
+
+#define ESR_EL2_SYSREG_TRAP_OP1_SHIFT	14
+#define ESR_EL2_SYSREG_TRAP_OP1_WIDTH	U(3)
+
+#define ESR_EL2_SYSREG_TRAP_CRN_SHIFT	10
+#define ESR_EL2_SYSREG_TRAP_CRN_WIDTH	U(4)
+
+#define ESR_EL2_SYSREG_TRAP_CRM_SHIFT	1
+#define ESR_EL2_SYSREG_TRAP_CRM_WIDTH	U(4)
+
+#define SYSREG_ESR(op0, op1, crn, crm, op2) \
+		((UL(op0) << ESR_EL2_SYSREG_TRAP_OP0_SHIFT) | \
+		 (UL(op1) << ESR_EL2_SYSREG_TRAP_OP1_SHIFT) | \
+		 (UL(crn) << ESR_EL2_SYSREG_TRAP_CRN_SHIFT) | \
+		 (UL(crm) << ESR_EL2_SYSREG_TRAP_CRM_SHIFT) | \
+		 (UL(op2) << ESR_EL2_SYSREG_TRAP_OP2_SHIFT))
+
+#define SYSREG_ID_sp_el0			SYSREG_ESR(3, 0, 4, 1, 0)
+#define SYSREG_ID_sp_el1			SYSREG_ESR(3, 4, 4, 1, 0)
+#define SYSREG_ID_elr_el1			SYSREG_ESR(3, 0, 4, 0, 1)
+#define SYSREG_ID_spsr_el1			SYSREG_ESR(3, 0, 4, 0, 0)
+#define SYSREG_ID_pmcr_el0			SYSREG_ESR(3, 3, 9, 12, 0)
+#define SYSREG_ID_tpidrro_el0			SYSREG_ESR(3, 3, 13, 0, 3)
+#define SYSREG_ID_tpidr_el0			SYSREG_ESR(3, 3, 13, 0, 2)
+#define SYSREG_ID_csselr_el1			SYSREG_ESR(3, 2, 0, 0, 0)
+#define SYSREG_ID_sctlr_el1			SYSREG_ESR(3, 0, 1, 0, 0)
+#define SYSREG_ID_actlr_el1			SYSREG_ESR(3, 0, 1, 0, 1)
+#define SYSREG_ID_cpacr_el1			SYSREG_ESR(3, 0, 1, 0, 2)
+#define SYSREG_ID_zcr_el1			SYSREG_ESR(3, 0, 1, 2, 0)
+#define SYSREG_ID_ttbr0_el1			SYSREG_ESR(3, 0, 2, 0, 0)
+#define SYSREG_ID_ttbr1_el1			SYSREG_ESR(3, 0, 2, 0, 1)
+#define SYSREG_ID_tcr_el1			SYSREG_ESR(3, 0, 2, 0, 2)
+#define SYSREG_ID_esr_el1			SYSREG_ESR(3, 0, 5, 2, 0)
+#define SYSREG_ID_afsr0_el1			SYSREG_ESR(3, 0, 5, 1, 0)
+#define SYSREG_ID_afsr1_el1			SYSREG_ESR(3, 0, 5, 1, 1)
+#define SYSREG_ID_far_el1			SYSREG_ESR(3, 0, 6, 0, 0)
+#define SYSREG_ID_mair_el1			SYSREG_ESR(3, 0, 10, 2, 0)
+#define SYSREG_ID_vbar_el1			SYSREG_ESR(3, 0, 12, 0, 0)
+#define SYSREG_ID_contextidr_el1		SYSREG_ESR(3, 0, 13, 0, 1)
+#define SYSREG_ID_tpidr_el1			SYSREG_ESR(3, 0, 13, 0, 4)
+#define SYSREG_ID_amair_el1			SYSREG_ESR(3, 0, 10, 3, 0)
+#define SYSREG_ID_cntkctl_el1			SYSREG_ESR(3, 0, 14, 1, 0)
+#define SYSREG_ID_par_el1			SYSREG_ESR(3, 0, 7, 4, 0)
+#define SYSREG_ID_mdscr_el1			SYSREG_ESR(2, 0, 0, 2, 2)
+#define SYSREG_ID_mdccint_el1			SYSREG_ESR(2, 0, 0, 2, 0)
+#define SYSREG_ID_disr_el1			SYSREG_ESR(3, 0, 12, 1, 1)
+#define SYSREG_ID_mpam0_el1			SYSREG_ESR(3, 0, 10, 5, 1)
+#define SYSREG_ID_apiakeylo_el1			SYSREG_ESR(3, 0, 2,  1, 0)
+#define SYSREG_ID_apiakeyhi_el1			SYSREG_ESR(3, 0, 2,  1, 1)
+#define SYSREG_ID_apibkeylo_el1			SYSREG_ESR(3, 0, 2,  1, 2)
+#define SYSREG_ID_apibkeyhi_el1			SYSREG_ESR(3, 0, 2,  1, 3)
+#define SYSREG_ID_apdakeylo_el1			SYSREG_ESR(3, 0, 2,  2, 0)
+#define SYSREG_ID_apdakeyhi_el1			SYSREG_ESR(3, 0, 2,  2, 1)
+#define SYSREG_ID_apdbkeylo_el1			SYSREG_ESR(3, 0, 2,  2, 2)
+#define SYSREG_ID_apdbkeyhi_el1			SYSREG_ESR(3, 0, 2,  2, 3)
+#define SYSREG_ID_apgakeylo_el1			SYSREG_ESR(3, 0, 2,  3, 0)
+#define SYSREG_ID_apgakeyhi_el1			SYSREG_ESR(3, 0, 2,  3, 1)
+#define SYSREG_ID_mpamidr_el1			SYSREG_ESR(3, 0, 10, 4, 4)
+
 #endif /* ARCH_H */
diff --git a/include/lib/aarch64/arch_helpers.h b/include/lib/aarch64/arch_helpers.h
index 35d2454..da1794d 100644
--- a/include/lib/aarch64/arch_helpers.h
+++ b/include/lib/aarch64/arch_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2013-2025, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -522,6 +522,9 @@
 DEFINE_RENAME_SYSREG_RW_FUNCS(mpam3_el3, MPAM3_EL3)
 DEFINE_RENAME_SYSREG_RW_FUNCS(mpam2_el2, MPAM2_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(mpamhcr_el2, MPAMHCR_EL2)
+DEFINE_RENAME_SYSREG_WRITE_FUNC(mpamidr_el1, MPAMIDR_EL1)
+DEFINE_RENAME_SYSREG_WRITE_FUNC(mpam0_el1, MPAM0_EL1)
+DEFINE_RENAME_SYSREG_WRITE_FUNC(mpam1_el1, MPAM1_EL1)
 
 DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el2, SCXTNUM_EL2)
 DEFINE_RENAME_SYSREG_RW_FUNCS(scxtnum_el1, SCXTNUM_EL1)
diff --git a/include/runtime_services/arm_arch_svc.h b/include/runtime_services/arm_arch_svc.h
index 0b4e2ad..4c2358a 100644
--- a/include/runtime_services/arm_arch_svc.h
+++ b/include/runtime_services/arm_arch_svc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,5 +14,6 @@
 #define SMCCC_ARCH_WORKAROUND_2	0x80007FFF
 #define SMCCC_ARCH_WORKAROUND_3	0x80003FFF
 #define SMCCC_ARCH_FEATURE_AVAILABILITY		U(0x80000003)
+#define SMCCC_ARCH_WORKAROUND_4	0x80000004
 
 #endif /* __ARM_ARCH_SVC_H__ */
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 6909a4e..6ea9b72 100644
--- a/include/runtime_services/host_realm_managment/host_realm_helper.h
+++ b/include/runtime_services/host_realm_managment/host_realm_helper.h
@@ -50,7 +50,13 @@
 bool host_enter_realm_execute(struct realm *realm_ptr, uint8_t cmd,
 		int test_exit_reason, unsigned int rec_num);
 test_result_t host_cmp_result(void);
-void realm_print_handler(struct realm *realm_ptr, unsigned int rec_num);
+void realm_print_handler(struct realm *realm_ptr, unsigned int plane_num, unsigned int rec_num);
 bool host_ipa_is_ns(u_register_t addr, u_register_t rmm_feat_reg0);
 
+/*
+ * This functions sets the shared data args needed for entering aux plane,
+ * using REALM_ENTER_PLANE_N_CMD
+ */
+void host_realm_set_aux_plane_args(struct realm *realm_ptr, unsigned int plane_num);
+
 #endif /* HOST_REALM_HELPER_H */
diff --git a/include/runtime_services/host_realm_managment/host_realm_pmu.h b/include/runtime_services/host_realm_managment/host_realm_pmu.h
index 844bb29..c7f5fab 100644
--- a/include/runtime_services/host_realm_managment/host_realm_pmu.h
+++ b/include/runtime_services/host_realm_managment/host_realm_pmu.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -23,7 +23,23 @@
 #define GET_PMU_CNT	\
 	((read_pmcr_el0() >> PMCR_EL0_N_SHIFT) & PMCR_EL0_N_MASK)
 
-void host_set_pmu_state(void);
-bool host_check_pmu_state(void);
+#define MAX_COUNTERS	31U
+
+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;
+} __aligned(64);
+
+void host_set_pmu_state(struct pmu_registers *pmu_ptr);
+
+bool host_check_pmu_state(struct pmu_registers *pmu_ptr);
 
 #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 00435b0..6394fb6 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-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -582,15 +582,6 @@
 #define RMI_FEATURE_REGISTER_0_MAX_NUM_AUX_PLANES_SHIFT	45UL
 #define RMI_FEATURE_REGISTER_0_MAX_NUM_AUX_PLANES_WIDTH	4UL
 
-#define FEATURE_SVE_VL_SHIFT				56UL
-#define FEATURE_SVE_VL_WIDTH				4UL
-#define FEATURE_NUM_BPS_SHIFT				14UL
-#define FEATURE_NUM_BPS_WIDTH				6UL
-#define FEATURE_NUM_WPS_SHIFT				20UL
-#define FEATURE_NUM_WPS_WIDTH				6UL
-#define FEATURE_PMU_NUM_CTRS_SHIFT			35UL
-#define FEATURE_PMU_NUM_CTRS_WIDTH			4UL
-
 /* Possible values for RmiPlaneRttFeature */
 #define RMI_PLANE_RTT_AUX				0UL
 #define RMI_PLANE_RTT_AUX_SINGLE			1UL
@@ -787,7 +778,11 @@
 		u_register_t far;				/* 0x108 */
 		/* Hypervisor IPA Fault Address register */
 		u_register_t hpfar;				/* 0x110 */
-	}, 0x100, 0x200);
+	}, 0x100, 0x118);
+	/* Index of RTT tree active at time of the exit */
+	SET_MEMBER(u_register_t rtt_tree, 0x118, 0x120);/* Offset 0x118 */
+	/* Level of requested RTT */
+	SET_MEMBER(u_register_t rtt_level, 0x120, 0x200);/* Offset 0x120 */
 	/* General-purpose registers */
 	SET_MEMBER(u_register_t gprs[REC_EXIT_NR_GPRS], 0x200, 0x300); /* 0x200 */
 	SET_MEMBER(struct {
@@ -817,7 +812,15 @@
 		u_register_t ripas_size;			/* 0x508 */
 		/* RIPAS value of pending RIPAS change */
 		unsigned char ripas_value;			/* 0x510 */
-	}, 0x500, 0x600);
+	}, 0x500, 0x518);
+	/* Base PA of MMIO region, if RIPAS change
+	 * is pending due to exeception of RSI_RDEV_VALIDATE_IO
+	 */
+	SET_MEMBER(u_register_t ripas_io_pa, 0x518, 0x520);	/* Offset 0x518 */
+	/* Base address of target region for pending S2AP change */
+	SET_MEMBER(u_register_t s2ap_base, 0x520, 0x528);     /* Offset 0x520 */
+	/* Top address of target region for pending S2AP change */
+	SET_MEMBER(u_register_t s2ap_top, 0x528, 0x600);     /* Offset 0x528 */
 	/* Host call immediate value */
 	SET_MEMBER(unsigned int imm, 0x600, 0x700);		/* 0x600 */
 	/* PMU overflow status */
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 7005c0d..763306f 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-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -36,14 +36,17 @@
 
 	/* Buffer to save Realm command results */
 	uint8_t realm_cmd_output_buffer[REALM_CMD_BUFFER_SIZE];
-} host_shared_data_t;
+}host_shared_data_t;
 
+typedef host_shared_data_t (*host_shared_data_arr_t)[MAX_PLANE_COUNT][MAX_REC_COUNT];
 /*
  * Different commands that the Host can requests the Realm to perform
  */
 enum realm_cmd {
 	REALM_SLEEP_CMD = 1U,
 	REALM_LOOP_CMD,
+	REALM_MPAM_ACCESS,
+	REALM_MPAM_PRESENT,
 	REALM_MULTIPLE_REC_PSCI_DENIED_CMD,
 	REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD,
 	REALM_GET_RSI_VERSION,
@@ -53,7 +56,8 @@
 	REALM_PMU_COUNTER,
 	REALM_PMU_EVENT,
 	REALM_PMU_PRESERVE,
-	REALM_PMU_INTERRUPT,
+	REALM_PMU_CYCLE_INTERRUPT,
+	REALM_PMU_EVENT_INTERRUPT,
 	REALM_REQ_FPU_FILL_CMD,
 	REALM_REQ_FPU_CMP_CMD,
 	REALM_SET_RIPAS_CMD,
@@ -73,7 +77,9 @@
 	REALM_SME_UNDEF_ABORT,
 	REALM_FEAT_DOUBLEFAULT2_TEST,
 	REALM_ATTESTATION,
-	REALM_ATTESTATION_FAULT
+	REALM_ATTESTATION_FAULT,
+	REALM_ENTER_PLANE_N_CMD,
+	REALM_PLANE_N_REG_RW_CMD
 };
 
 /*
@@ -82,14 +88,16 @@
 enum host_param_index {
 	HOST_CMD_INDEX = 0U,
 	HOST_ARG1_INDEX,
-	HOST_ARG2_INDEX
+	HOST_ARG2_INDEX,
+	HOST_ARG3_INDEX
 };
 
 enum host_call_cmd {
         HOST_CALL_GET_SHARED_BUFF_CMD = 1U,
         HOST_CALL_EXIT_SUCCESS_CMD,
 	HOST_CALL_EXIT_FAILED_CMD,
-	HOST_CALL_EXIT_PRINT_CMD
+	HOST_CALL_EXIT_PRINT_CMD,
+	HOST_CALL_GET_PLANE_ID_CMD
 };
 
 /***************************************
@@ -99,25 +107,34 @@
 /*
  * Return shared buffer pointer mapped as host_shared_data_t structure
  */
-host_shared_data_t *host_get_shared_structure(struct realm *realm_ptr, unsigned int rec_num);
+host_shared_data_t *host_get_shared_structure(struct realm *realm_ptr,
+					      unsigned int plane_num,
+					      unsigned int rec_num);
 
 /*
  * Set data to be shared from Host to realm
  */
 void host_shared_data_set_host_val(struct realm *realm_ptr,
-		unsigned int rec_num, uint8_t index, u_register_t val);
+				   unsigned int plane_num,
+				   unsigned int rec_num,
+				   uint8_t index,
+				   u_register_t val);
 
 /*
  * Get data shared from realm to Host
  */
 u_register_t host_shared_data_get_realm_val(struct realm *realm_ptr,
-		unsigned int rec_num, uint8_t index);
+					    unsigned int plane_num,
+					    unsigned int rec_num,
+					    uint8_t index);
 
 /*
  * Set command to be send from Host to realm
  */
-void host_shared_data_set_realm_cmd(struct realm *realm_ptr, uint8_t cmd,
-		unsigned int rec_num);
+void host_shared_data_set_realm_cmd(struct realm *realm_ptr,
+				    uint8_t cmd,
+				    unsigned int plane_num,
+				    unsigned int rec_num);
 
 
 /****************************************
@@ -127,7 +144,7 @@
 /*
  * Set guest mapped shared buffer pointer
  */
-void realm_set_shared_structure(host_shared_data_t *ptr);
+void realm_set_shared_structure(u_register_t ptr);
 
 /*
  * Get guest mapped shared buffer pointer
@@ -149,4 +166,28 @@
  */
 void realm_shared_data_set_my_realm_val(uint8_t index, u_register_t val);
 
+/*
+ * Set data to be shared from Host/Plane0 to Plane N
+ */
+void realm_shared_data_set_plane_n_val(unsigned int plane_num,
+		unsigned int rec_num, uint8_t index, u_register_t val);
+
+/*
+ * Get data shared from Host/Plane0 to Plane N
+ */
+u_register_t realm_shared_data_get_plane_n_val(unsigned int plane_num,
+		unsigned int rec_num, uint8_t index);
+/*
+ * Get cmd shared from Host/Plane0 to Plane N
+ */
+u_register_t realm_shared_data_get_plane_n_cmd(unsigned int plane_num,
+		unsigned int rec_num, uint8_t index);
+
+/*
+ * Set command to be send from Host/Plane0 to Plane N
+ */
+void realm_shared_data_set_plane_n_cmd(uint8_t cmd,
+		 unsigned int plane_num,
+		unsigned int rec_num);
+
 #endif /* HOST_SHARED_DATA_H */
diff --git a/include/runtime_services/sdei.h b/include/runtime_services/sdei.h
index 0e0a249..43cb9df 100644
--- a/include/runtime_services/sdei.h
+++ b/include/runtime_services/sdei.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -92,6 +92,8 @@
 int64_t sdei_event_context(uint32_t param);
 int64_t sdei_event_complete(uint32_t flags);
 int64_t sdei_event_complete_and_resume(uint64_t addr);
+int64_t sdei_features(uint32_t feature);
+int64_t sdei_event_get_info(int32_t event, uint32_t info);
 #endif /* __ASSEMBLY__ */
 
 #endif /* __SDEI_H__ */
diff --git a/lib/sdei/sdei.c b/lib/sdei/sdei.c
index 157ab6c..eb0e961 100644
--- a/lib/sdei/sdei.c
+++ b/lib/sdei/sdei.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -76,6 +76,7 @@
 	args.arg4 = flags;
 	args.arg5 = mpidr;
 	ret = tftf_smc(&args);
+
 	return ret.ret0;
 }
 
@@ -219,3 +220,26 @@
 	ret = tftf_smc(&args);
 	return ret.ret0;
 }
+
+int64_t sdei_features(uint32_t feature)
+{
+	smc_args args = { 0 };
+	smc_ret_values ret;
+
+	args.fid = SDEI_FEATURES;
+	args.arg1 = feature;
+	ret = tftf_smc(&args);
+	return ret.ret0;
+}
+
+int64_t sdei_event_get_info(int32_t event, uint32_t info)
+{
+	smc_args args = { 0 };
+	smc_ret_values ret;
+
+	args.fid = SDEI_EVENT_GET_INFO;
+	args.arg1 = event;
+	args.arg2 = info;
+	ret = tftf_smc(&args);
+	return ret.ret0;
+}
diff --git a/realm/aarch64/realm_entrypoint.S b/realm/aarch64/realm_entrypoint.S
index 7e535bb..1c20dca 100644
--- a/realm/aarch64/realm_entrypoint.S
+++ b/realm/aarch64/realm_entrypoint.S
@@ -81,6 +81,8 @@
 	 */
 	adr	x0, cold_boot_flag
 	str	xzr, [x0]
+
+	bl	realm_plane_init
 loop:
 	/* And jump to the C entrypoint */
 	bl	realm_payload_main
@@ -92,6 +94,7 @@
 #if ENABLE_PAUTH
 	bl	pauth_init_enable
 #endif
+	bl	realm_plane_init
 	mov	x0, x20
 	b	realm_secondary_entrypoint
 endfunc realm_entrypoint
diff --git a/realm/include/realm_helpers.h b/realm/include/realm_helpers.h
index a9b2f7c..c5af1be 100644
--- a/realm/include/realm_helpers.h
+++ b/realm/include/realm_helpers.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -8,8 +8,24 @@
 #ifndef REALM_HELPERS_H
 #define REALM_HELPERS_H
 
+#include <realm_rsi.h>
+
 /* Generate 64-bit random number */
 unsigned long long realm_rand64(void);
+
+/* Reset the undefined aborts counter */
+void realm_reset_undef_abort_count(void);
+
+/* Return the undefined aborts counter value */
+unsigned int realm_get_undef_abort_count(void);
+
+/*
+ * Sync exception handler.
+ * If the exception is an undefined abort, it increases the value
+ * of the abort counter and returns 'true'. Otherwise, it returns 'false'
+ */
+bool realm_sync_exception_handler(void);
+
 /*
  * Function to enter Aux Plane from Primary Plane
  * arg1 == plane index
@@ -21,8 +37,19 @@
 bool realm_plane_enter(u_register_t plane_index, u_register_t perm_index,
 		u_register_t base, u_register_t flags, rsi_plane_run *run);
 
+/* This function will call the Host to request IPA of the NS shared buffer */
+u_register_t realm_get_ns_buffer(void);
+
+/* This function will return plane index of current plane */
+unsigned int realm_get_my_plane_num(void);
+
+/** This function will return true for primary plane false for aux plane */
+bool realm_is_plane0(void);
+
 /* Function for initializing planes, called at Boot */
 void realm_plane_init(void);
+bool plane_common_init(u_register_t plane_index, u_register_t perm_index,
+		u_register_t base, rsi_plane_run *run);
 
 #endif /* REALM_HELPERS_H */
 
diff --git a/realm/include/realm_psi.h b/realm/include/realm_psi.h
new file mode 100644
index 0000000..bab2896
--- /dev/null
+++ b/realm/include/realm_psi.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#ifndef REALM_PSI_H
+#define REALM_PSI_H
+
+#include <stdint.h>
+#include <realm_rsi.h>
+
+/*
+ * Plane Service Interface
+ * ABIs are designed to be used by auxillary planes to interact with primary plane.
+ * PSI calls uses HVC conduit which causes Plane exit to P0
+ * PSI commands and Planes shared buffer can be used for communication.
+ */
+#define PSI_RETURN_TO_P0	1U
+#define PSI_RETURN_TO_PN	2U
+
+/* PSI Commands to return back to P0 */
+#define PSI_P0_CALL			RSI_HOST_CALL
+#define PSI_REALM_CONFIG		RSI_REALM_CONFIG
+#define PSI_CALL_EXIT_PRINT_CMD		HOST_CALL_EXIT_PRINT_CMD
+#define PSI_CALL_EXIT_SUCCESS_CMD	HOST_CALL_EXIT_SUCCESS_CMD
+#define PSI_CALL_EXIT_FAILED_CMD	HOST_CALL_EXIT_FAILED_CMD
+#define PSI_CALL_GET_PLANE_ID_CMD	HOST_CALL_GET_PLANE_ID_CMD
+#define PSI_CALL_GET_SHARED_BUFF_CMD	HOST_CALL_GET_SHARED_BUFF_CMD
+
+/* Exit back to Plane 0 */
+void psi_exit_to_plane0(u_register_t psi_cmd,
+			u_register_t arg1,
+			u_register_t arg2,
+			u_register_t arg3,
+			u_register_t arg4,
+			u_register_t arg5,
+			u_register_t arg6,
+			u_register_t arg7);
+
+/* Request plane_id from P0 */
+u_register_t psi_get_plane_id(void);
+
+#endif /* REALM_PSI_H */
diff --git a/realm/include/realm_rsi.h b/realm/include/realm_rsi.h
index 33e8fcf..06f857f 100644
--- a/realm/include/realm_rsi.h
+++ b/realm/include/realm_rsi.h
@@ -270,6 +270,12 @@
  */
 #define RSI_PLANE_REG_READ	SMC_RSI_FID(0x1EU)
 
+u_register_t rsi_plane_reg_read(u_register_t plane_index, u_register_t register_encoding,
+		u_register_t *value);
+
+u_register_t rsi_plane_reg_write(u_register_t plane_index, u_register_t register_encoding,
+		u_register_t value);
+
 /*
  * arg1 == plane index
  * arg2 == register encoding
@@ -321,9 +327,6 @@
 /* This function return RSI_ABI_VERSION */
 u_register_t rsi_get_version(u_register_t req_ver);
 
-/* This function will call the Host to request IPA of the NS shared buffer */
-u_register_t rsi_get_ns_buffer(void);
-
 /* This function will initialize the attestation context */
 u_register_t rsi_attest_token_init(u_register_t challenge_0,
 				   u_register_t challenge_1,
@@ -342,7 +345,7 @@
 					u_register_t *bytes_copied);
 
 /* This function call Host and request to exit Realm with proper exit code */
-void rsi_exit_to_host(enum host_call_cmd exit_code);
+u_register_t rsi_exit_to_host(enum host_call_cmd exit_code);
 
 /* Function to get Realm configuration. See RSI_REALM_CONFIG */
 u_register_t rsi_realm_config(struct rsi_realm_config *s);
diff --git a/realm/include/realm_tests.h b/realm/include/realm_tests.h
index 2c1d3a1..6c1e6c3 100644
--- a/realm/include/realm_tests.h
+++ b/realm/include/realm_tests.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -12,7 +12,7 @@
 bool test_pmuv3_counter(void);
 bool test_pmuv3_event_works_realm(void);
 bool test_pmuv3_rmm_preserves(void);
-bool test_pmuv3_overflow_interrupt(void);
+bool test_pmuv3_overflow_interrupt(bool cycle_cnt);
 bool test_realm_pauth_set_cmd(void);
 bool test_realm_pauth_check_cmd(void);
 bool test_realm_pauth_fault(void);
@@ -30,6 +30,7 @@
 bool test_realm_sctlr2_ease(void);
 bool test_realm_attestation(void);
 bool test_realm_attestation_fault(void);
+bool test_realm_mpam_undef_abort(void);
 
 #endif /* REALM_TESTS_H */
 
diff --git a/realm/realm.mk b/realm/realm.mk
index f59387c..6281779 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -37,14 +37,17 @@
 	realm_plane.c							\
 	realm_pmuv3.c							\
 	realm_psci.c							\
+	realm_psi.c							\
 	realm_rsi.c							\
 	realm_shared_data.c						\
 	realm_simd.c							\
+	realm_mpam.c							\
 	)
 
 REALM_SOURCES += lib/${ARCH}/cache_helpers.S				\
 	lib/${ARCH}/misc_helpers.S					\
 	lib/smc/${ARCH}/asm_smc.S					\
+	lib/smc/${ARCH}/hvc.c						\
 	lib/smc/${ARCH}/smc.c						\
 	lib/exceptions/${ARCH}/serror.c					\
 	lib/exceptions/${ARCH}/sync.c					\
diff --git a/realm/realm_debug.c b/realm/realm_debug.c
index 1c4ee03..6bf8adf 100644
--- a/realm/realm_debug.c
+++ b/realm/realm_debug.c
@@ -11,6 +11,8 @@
 
 #include <arch_helpers.h>
 #include <host_shared_data.h>
+#include <realm_helpers.h>
+#include <realm_psi.h>
 #include <realm_rsi.h>
 
 /*
@@ -23,6 +25,7 @@
 	host_shared_data_t *guest_shared_data = realm_get_my_shared_structure();
 	char *log_buffer = (char *)guest_shared_data->log_buffer;
 	va_list args;
+	u_register_t ret;
 
 	va_start(args, fmt);
 	if (strnlen((const char *)log_buffer, MAX_BUF_SIZE) == MAX_BUF_SIZE) {
@@ -32,7 +35,15 @@
 			strnlen((const char *)log_buffer, MAX_BUF_SIZE),
 			MAX_BUF_SIZE, fmt, args);
 	va_end(args);
-	rsi_exit_to_host(HOST_CALL_EXIT_PRINT_CMD);
+	ret = rsi_exit_to_host(HOST_CALL_EXIT_PRINT_CMD);
+
+	/*
+	 * Retry with PSI call for secondary planes
+	 * Note - RSI_HOST_CALL will fail if test in P0 sets trap_hc flag in plane_enter
+	 */
+	if ((ret != RSI_SUCCESS && !realm_is_plane0())) {
+		psi_exit_to_plane0(PSI_CALL_EXIT_PRINT_CMD, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
+	}
 }
 
 void __attribute__((__noreturn__)) do_panic(const char *file, int line)
diff --git a/realm/realm_helpers.c b/realm/realm_helpers.c
index 6a3c57d..f11e2f3 100644
--- a/realm/realm_helpers.c
+++ b/realm/realm_helpers.c
@@ -1,14 +1,69 @@
 /*
- * Copyright (c) 2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <debug.h>
 #include <stdlib.h>
 
+#include <realm_helpers.h>
+#include <realm_psi.h>
+#include <realm_rsi.h>
+#include <smccc.h>
+
+static unsigned int volatile realm_got_undef_abort;
+
 /* Generate 64-bit random number */
 unsigned long long realm_rand64(void)
 {
 	return ((unsigned long long)rand() << 32) | rand();
 }
 
+/* This function will call the Host to request IPA of the NS shared buffer */
+u_register_t realm_get_ns_buffer(void)
+{
+	smc_ret_values res = {};
+	struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
+
+	host_cal.imm = HOST_CALL_GET_SHARED_BUFF_CMD;
+	res = tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
+		0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+
+	if (res.ret0 != RSI_SUCCESS) {
+		/* retry with PSI */
+		hvc_ret_values ret = tftf_hvc(&(hvc_args) {PSI_CALL_GET_SHARED_BUFF_CMD, 0UL, 0UL,
+			0UL, 0UL, 0UL, 0UL, 0UL});
+
+		if (ret.ret0 != RSI_SUCCESS) {
+			return 0U;
+		}
+		return ret.ret1;
+	}
+
+	return host_cal.gprs[0];
+}
+
+bool realm_sync_exception_handler(void)
+{
+	uint64_t esr_el1 = read_esr_el1();
+
+	if (EC_BITS(esr_el1) == EC_UNKNOWN) {
+		realm_printf("received undefined abort. "
+			     "ESR_EL1: 0x%llx ELR_EL1: 0x%llx\n",
+			     esr_el1, read_elr_el1());
+		realm_got_undef_abort++;
+	}
+
+	return true;
+}
+
+void realm_reset_undef_abort_count(void)
+{
+	realm_got_undef_abort = 0U;
+}
+
+unsigned int realm_get_undef_abort_count(void)
+{
+	return realm_got_undef_abort;
+}
diff --git a/realm/realm_mpam.c b/realm/realm_mpam.c
new file mode 100644
index 0000000..913e451
--- /dev/null
+++ b/realm/realm_mpam.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <arch_helpers.h>
+#include <sync.h>
+#include <realm_helpers.h>
+
+/* Check if Realm gets undefined abort when it access MPAM registers */
+bool test_realm_mpam_undef_abort(void)
+{
+	realm_reset_undef_abort_count();
+
+	/* Install exception handler to catch undefined abort */
+	register_custom_sync_exception_handler(realm_sync_exception_handler);
+	write_mpam0_el1(0UL);
+	unregister_custom_sync_exception_handler();
+
+	return (realm_get_undef_abort_count() != 0UL);
+}
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index 3339b9a..d364aa0 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -14,6 +14,8 @@
 #include <host_shared_data.h>
 #include <pauth.h>
 #include "realm_def.h"
+#include <realm_helpers.h>
+#include <realm_psi.h>
 #include <realm_rsi.h>
 #include <realm_tests.h>
 #include <serror.h>
@@ -22,6 +24,7 @@
 
 static fpu_state_t rl_fpu_state_write;
 static fpu_state_t rl_fpu_state_read;
+static rsi_plane_run run __aligned(PAGE_SIZE);
 
 /*
  * This function reads sleep time in ms from shared buffer and spins PE
@@ -42,6 +45,105 @@
 	}
 }
 
+static bool test_realm_enter_plane_n(void)
+{
+	u_register_t base, plane_index, perm_index, flags = 0U;
+	bool ret1;
+
+	plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+	base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
+	perm_index = plane_index + 1U;
+
+	ret1 = plane_common_init(plane_index, perm_index, base, &run);
+	if (!ret1) {
+		return ret1;
+	}
+
+	realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
+	return realm_plane_enter(plane_index, perm_index, base, flags, &run);
+}
+
+static bool test_realm_enter_plane_n_reg_rw(void)
+{
+	u_register_t base, plane_index, perm_index, flags = 0U;
+	u_register_t reg1, reg2, reg3, reg4, ret;
+	bool ret1;
+
+	if (realm_is_plane0()) {
+		plane_index = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
+		base = realm_shared_data_get_my_host_val(HOST_ARG2_INDEX);
+		perm_index = plane_index + 1U;
+
+		ret1 = plane_common_init(plane_index, perm_index, base, &run);
+		if (!ret1) {
+			return ret1;
+		}
+
+		realm_printf("Entering plane %ld, ep=0x%lx run=0x%lx\n", plane_index, base, &run);
+		ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
+		if (ret) {
+			/* get return value from plane1 */
+			reg1 = realm_shared_data_get_plane_n_val(plane_index,
+					REC_IDX(read_mpidr_el1()), HOST_ARG1_INDEX);
+
+			reg2 = realm_shared_data_get_plane_n_val(plane_index,
+					REC_IDX(read_mpidr_el1()), HOST_ARG2_INDEX);
+
+			realm_printf("P0 read 0x%lx 0x%lx\n", reg1, reg2);
+
+			/* read pauth register for plane1 */
+			ret = rsi_plane_reg_read(plane_index, SYSREG_ID_apiakeylo_el1, &reg3);
+			if ((ret != RSI_SUCCESS) || (reg1 != reg3)) {
+				realm_printf("pauth register mismatch 0x%lx 0x%lx\n", reg1, reg3);
+				return false;
+			}
+
+			/* read sctlr register for plane1 */
+			ret = rsi_plane_reg_read(plane_index, SYSREG_ID_sctlr_el1, &reg4);
+			if ((ret != RSI_SUCCESS) || (reg2 != reg4)) {
+				realm_printf("sctlr register mismatch 0x%lx 0x%lx\n", reg2, reg4);
+				return false;
+			}
+
+			/* write pauth register and verify it is same after exiting plane n */
+			ret = rsi_plane_reg_write(plane_index, SYSREG_ID_apibkeylo_el1, 0xABCD);
+			if (ret != RSI_SUCCESS) {
+				realm_printf("pauth register write failed\n");
+				return false;
+			}
+
+			/* enter plane n */
+			ret = realm_plane_enter(plane_index, perm_index, base, flags, &run);
+			if (ret) {
+				/* read pauth register for plane1 */
+				ret = rsi_plane_reg_read(plane_index, SYSREG_ID_apibkeylo_el1,
+						&reg3);
+
+				if ((ret != RSI_SUCCESS) || (reg3 != 0xABCD)) {
+					realm_printf("reg mismatch after write 0x%lx\n", reg3);
+					return false;
+				}
+			}
+
+			/* read sysreg not supported by rmm, expect error */
+			ret = rsi_plane_reg_read(plane_index, SYSREG_ID_mpamidr_el1, &reg3);
+			if (ret == RSI_SUCCESS) {
+				realm_printf("reg read should have failed\n");
+				return false;
+			}
+			return true;
+		}
+		return false;
+	} else {
+		realm_printf("PN set 0x%lx 0x%lx\n", read_apiakeylo_el1(), read_sctlr_el1());
+
+		/* return pauth and sctlr back to p0 */
+		realm_shared_data_set_my_realm_val(HOST_ARG1_INDEX, read_apiakeylo_el1());
+		realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, read_sctlr_el1());
+		return true;
+	}
+}
+
 /*
  * This function requests RSI/ABI version from RMM.
  */
@@ -184,18 +286,20 @@
 
 static bool realm_exception_handler(void)
 {
-	u_register_t base, far, esr;
+	u_register_t base, far, esr, elr;
 
 	base = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
 	far = read_far_el1();
 	esr = read_esr_el1();
+	elr = read_elr_el1();
 
 	if (far == base) {
 		/* Return ESR to Host */
 		realm_shared_data_set_my_realm_val(HOST_ARG2_INDEX, esr);
 		rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
 	}
-	realm_printf("Realm Abort fail incorrect FAR=0x%lx ESR=0x%lx\n", far, esr);
+	realm_printf("Realm Abort fail incorrect FAR=0x%lx ESR=0x%lx ELR=0x%lx\n",
+			far, esr, elr);
 	rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
 
 	/* Should not return */
@@ -266,7 +370,7 @@
 	/* No serror handler registered by default */
 	unregister_custom_serror_handler();
 
-	realm_set_shared_structure((host_shared_data_t *)rsi_get_ns_buffer());
+	realm_set_shared_structure(realm_get_ns_buffer());
 
 	if (realm_get_my_shared_structure() != NULL) {
 		uint8_t cmd = realm_shared_data_get_my_realm_cmd();
@@ -280,6 +384,19 @@
 			realm_loop_cmd();
 			test_succeed = true;
 			break;
+		case REALM_ENTER_PLANE_N_CMD:
+			test_succeed = test_realm_enter_plane_n();
+			break;
+		case REALM_PLANE_N_REG_RW_CMD:
+			test_succeed = test_realm_enter_plane_n_reg_rw();
+			break;
+		case REALM_MPAM_ACCESS:
+			test_succeed = test_realm_mpam_undef_abort();
+			break;
+		case REALM_MPAM_PRESENT:
+			/* FEAT_MPAM must be hidden to the Realm */
+			test_succeed = !is_feat_mpam_supported();
+			break;
 		case REALM_MULTIPLE_REC_PSCI_DENIED_CMD:
 			test_succeed = test_realm_multiple_rec_psci_denied_cmd();
 			break;
@@ -323,8 +440,11 @@
 		case REALM_PMU_PRESERVE:
 			test_succeed = test_pmuv3_rmm_preserves();
 			break;
-		case REALM_PMU_INTERRUPT:
-			test_succeed = test_pmuv3_overflow_interrupt();
+		case REALM_PMU_CYCLE_INTERRUPT:
+			test_succeed = test_pmuv3_overflow_interrupt(true);
+			break;
+		case REALM_PMU_EVENT_INTERRUPT:
+			test_succeed = test_pmuv3_overflow_interrupt(false);
 			break;
 		case REALM_REQ_FPU_FILL_CMD:
 			fpu_state_write_rand(&rl_fpu_state_write);
@@ -381,8 +501,18 @@
 	}
 
 	if (test_succeed) {
-		rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
+		if (realm_is_plane0()) {
+			rsi_exit_to_host(HOST_CALL_EXIT_SUCCESS_CMD);
+		} else {
+			psi_exit_to_plane0(PSI_CALL_EXIT_SUCCESS_CMD,
+					0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
+		}
 	} else {
-		rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+		if (realm_is_plane0()) {
+			rsi_exit_to_host(HOST_CALL_EXIT_FAILED_CMD);
+		} else {
+			psi_exit_to_plane0(PSI_CALL_EXIT_FAILED_CMD,
+					0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL);
+		}
 	}
 }
diff --git a/realm/realm_plane.c b/realm/realm_plane.c
index ef1e0ab..c7225ed 100644
--- a/realm/realm_plane.c
+++ b/realm/realm_plane.c
@@ -11,10 +11,22 @@
 #include <debug.h>
 
 #include <host_realm_helper.h>
+#include <realm_psi.h>
 #include <realm_rsi.h>
 #include <sync.h>
 
-bool is_plane0;
+static bool is_plane0;
+static unsigned int plane_num;
+
+bool realm_is_plane0(void)
+{
+	return is_plane0;
+}
+
+unsigned int realm_get_my_plane_num(void)
+{
+	return plane_num;
+}
 
 void realm_plane_init(void)
 {
@@ -23,8 +35,10 @@
 	ret = rsi_get_version(RSI_ABI_VERSION_VAL);
 	if (ret == RSI_ERROR_STATE) {
 		is_plane0 = false;
+		plane_num = (unsigned int)psi_get_plane_id();
 	} else {
 		is_plane0 = true;
+		plane_num = PRIMARY_PLANE_ID;
 	}
 }
 
@@ -37,23 +51,91 @@
 	run->enter.pc = run->exit.elr;
 }
 
+static u_register_t realm_exit_to_host_as_plane_n(enum host_call_cmd exit_code,
+		u_register_t plane_num)
+{
+	struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
+	smc_ret_values res = {};
+
+	assert(realm_is_p0());
+	host_cal.imm = exit_code;
+	host_cal.gprs[0] = plane_num;
+	host_cal.gprs[1] = read_mpidr_el1();
+	res = tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
+		0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+	return res.ret0;
+}
+
 /* return true to re-enter PlaneN, false to exit to P0 */
-static bool handle_plane_exit(u_register_t plane_index,
+u_register_t handle_plane_exit(u_register_t plane_index,
 		u_register_t perm_index,
 		rsi_plane_run *run)
 {
 	u_register_t ec = EC_BITS(run->exit.esr);
+	u_register_t ret;
+
+	if (((run->exit.esr & ISS_FSC_MASK) >= FSC_L0_PERM_FAULT) &&
+		((run->exit.esr & ISS_FSC_MASK) <= FSC_L3_PERM_FAULT)) {
+
+		/* If Plane N exit is due to permission fault, change s2ap */
+		u_register_t base, new_base, response, ret;
+		u_register_t new_cookie = 0UL;
+
+		new_base = base = (run->exit.far & ~PAGE_SIZE_MASK);
+
+		VERBOSE("P0 set s2ap 0x%lx\n", base);
+		while (new_base != (base + PAGE_SIZE)) {
+
+			ret = rsi_mem_set_perm_index(new_base, base + PAGE_SIZE,
+				perm_index, new_cookie, &new_base,
+				&response, &new_cookie);
+
+			if (ret != RSI_SUCCESS || response == RSI_REJECT) {
+				ERROR("rsi_mem_set_perm_index failed 0x%lx\n", new_base);
+				return PSI_RETURN_TO_P0;
+			}
+		}
+
+		restore_plane_context(run);
+		return PSI_RETURN_TO_PN;
+	}
 
 	/* Disallow SMC from Plane N */
 	if (ec == EC_AARCH64_SMC) {
+		/* TODO Support PSCI in future */
 		restore_plane_context(run);
 		run->enter.gprs[0] = RSI_ERROR_STATE;
-		return true;
+		return PSI_RETURN_TO_PN;
 	}
-	return false;
+
+	/* Handle PSI HVC call from Plane N */
+	if (ec == EC_AARCH64_HVC) {
+		u_register_t hvc_id = run->exit.gprs[0];
+
+		restore_plane_context(run);
+		switch (hvc_id) {
+		case PSI_CALL_GET_SHARED_BUFF_CMD:
+			run->enter.gprs[0] = RSI_SUCCESS;
+			run->enter.gprs[1] = (u_register_t)realm_get_my_shared_structure();
+			return PSI_RETURN_TO_PN;
+		case PSI_CALL_GET_PLANE_ID_CMD:
+			run->enter.gprs[0] = RSI_SUCCESS;
+			run->enter.gprs[1] = plane_index;
+			return PSI_RETURN_TO_PN;
+		case PSI_CALL_EXIT_PRINT_CMD:
+			/* exit to host to flush buffer, then return to PN */
+			ret = realm_exit_to_host_as_plane_n(HOST_CALL_EXIT_PRINT_CMD, plane_index);
+			run->enter.gprs[0] = ret;
+			return PSI_RETURN_TO_PN;
+		case PSI_P0_CALL:
+		default:
+			return PSI_RETURN_TO_P0;
+		}
+	}
+	return PSI_RETURN_TO_P0;
 }
 
-static bool plane_common_init(u_register_t plane_index,
+bool plane_common_init(u_register_t plane_index,
 		u_register_t perm_index,
 		u_register_t base,
 		rsi_plane_run *run)
@@ -79,16 +161,10 @@
 		rsi_plane_run *run)
 {
 	u_register_t ret;
-	bool ret1;
-
-	ret1 = plane_common_init(plane_index, perm_index, base, run);
-	if (!ret1) {
-		return ret1;
-	}
 
 	run->enter.flags = flags;
 
-	while (ret1) {
+	while (true) {
 		ret = rsi_plane_enter(plane_index, (u_register_t)run);
 		if (ret != RSI_SUCCESS) {
 			ERROR("Plane %u enter failed ret= 0x%lx\n", plane_index, ret);
@@ -101,8 +177,11 @@
 				run->exit.hpfar,
 				run->exit.far);
 
-		ret1 = handle_plane_exit(plane_index, perm_index, run);
+		ret = handle_plane_exit(plane_index, perm_index, run);
+
+		if (ret != PSI_RETURN_TO_PN) {
+			return true;
+		}
 	}
-	return true;
 }
 
diff --git a/realm/realm_pmuv3.c b/realm/realm_pmuv3.c
index 0d4782a..620daf3 100644
--- a/realm/realm_pmuv3.c
+++ b/realm/realm_pmuv3.c
@@ -1,9 +1,11 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <stdlib.h>
+
 #include <arch_helpers.h>
 #include <arm_arch_svc.h>
 #include <debug.h>
@@ -19,24 +21,23 @@
 #define PMU_EVT_MEM_ACCESS	0x13
 
 #define NOP_REPETITIONS		50
-#define MAX_COUNTERS		32
 
 #define PRE_OVERFLOW		~(0xF)
 
-#define	DELAY_MS		3000ULL
+#define	DELAY_MS		3000UL
 
-static inline void read_all_counters(u_register_t *array, int impl_ev_ctrs)
+static inline void read_all_counters(u_register_t *array, unsigned int num_cnts)
 {
 	array[0] = read_pmccntr_el0();
-	for (unsigned int i = 0U; i < impl_ev_ctrs; i++) {
+	for (unsigned int i = 0U; i < num_cnts; i++) {
 		array[i + 1] = read_pmevcntrn_el0(i);
 	}
 }
 
-static inline void read_all_counter_configs(u_register_t *array, int impl_ev_ctrs)
+static inline void read_all_counter_configs(u_register_t *array, unsigned int num_cnts)
 {
 	array[0] = read_pmccfiltr_el0();
-	for (unsigned int i = 0U; i < impl_ev_ctrs; i++) {
+	for (unsigned int i = 0U; i < num_cnts; i++) {
 		array[i + 1] = read_pmevtypern_el0(i);
 	}
 }
@@ -107,7 +108,7 @@
 	isb();
 }
 
-static inline void enable_event_counter(int ctr_num)
+static inline void enable_event_counter(unsigned int ctr_num)
 {
 	/*
 	 * Set PMEVTYPER_EL0.U != PMEVTYPER_EL0.RLU
@@ -154,27 +155,21 @@
 	disable_counting();
 	clear_counters();
 
-	realm_printf("counted from %lu to %lu\n",
-		ccounter_start, ccounter_end);
-	if (ccounter_start != ccounter_end) {
-		return true;
-	}
-	return false;
+	realm_printf("cycle counter counted from %lu to %lu\n",
+			ccounter_start, ccounter_end);
+	return (ccounter_start != ccounter_end);
 }
 
 /* Test if max counter available is same as that programmed by host */
 bool test_pmuv3_counter(void)
 {
-	uint64_t num_cnts, num_cnts_host;
+	unsigned int num_cnts, num_cnts_host;
 
 	num_cnts_host = realm_shared_data_get_my_host_val(HOST_ARG1_INDEX);
 	num_cnts = GET_PMU_CNT;
-	realm_printf("CPU=%u num_cnts=%lu num_cnts_host=%lu\n", read_mpidr_el1() & MPID_MASK,
+	realm_printf("CPU=%u num_cnts=%u num_cnts_host=%u\n", read_mpidr_el1() & MPID_MASK,
 			num_cnts, num_cnts_host);
-	if (num_cnts == num_cnts_host) {
-		return true;
-	}
-	return false;
+	return (num_cnts == num_cnts_host);
 }
 
 /*
@@ -184,28 +179,31 @@
 {
 	u_register_t evcounter_start;
 	u_register_t evcounter_end;
+	unsigned int num_cnts = GET_PMU_CNT;
+	unsigned int ctr_num;
 
-	if (GET_PMU_CNT == 0) {
-		realm_printf("no event counters implemented\n");
-		return false;
-	}
+	/* Seed the random number generator */
+	srand((unsigned int)read_cntpct_el0());
+
+	/* Select a random number of event counter */
+	ctr_num = (unsigned int)rand() % num_cnts;
 
 	pmu_reset();
 
-	enable_event_counter(0);
+	enable_event_counter(ctr_num);
 	enable_counting();
 
 	/*
 	 * If any is enabled it will be in the first range.
 	 */
-	evcounter_start = read_pmevcntrn_el0(0);
+	evcounter_start = read_pmevcntrn_el0(ctr_num);
 	execute_nops();
 	disable_counting();
-	evcounter_end = read_pmevcntrn_el0(0);
+	evcounter_end = read_pmevcntrn_el0(ctr_num);
 	clear_counters();
 
-	realm_printf("counted from %lu to %lu\n",
-		evcounter_start, evcounter_end);
+	realm_printf("event counter #%u counted from %lu to %lu\n",
+			ctr_num, evcounter_start, evcounter_end);
 	if (evcounter_start != evcounter_end) {
 		return true;
 	}
@@ -223,30 +221,38 @@
 	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_PMU_CNT;
+	unsigned int num_cnts = GET_PMU_CNT;
 
-	realm_printf("testing %u event counters\n", impl_ev_ctrs);
+	if (num_cnts  == 0U) {
+		realm_printf("testing cycle counter\n");
+	} else {
+		realm_printf("testing %u event counters\n", num_cnts);
+	}
 
 	pmu_reset();
 
-	/* Pretend counters have just been used */
+	/* Pretend all counters have just been used */
 	enable_cycle_counter();
-	enable_event_counter(0);
+
+	for (unsigned int i = 0U; i < num_cnts; i++) {
+		enable_event_counter(i);
+	}
+
 	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_counters(ctr_start, num_cnts);
+	read_all_counter_configs(ctr_cfg_start, num_cnts);
 	read_all_pmu_configs(pmu_cfg_start);
 
 	/* Give RMM a chance to scramble everything */
 	(void)rsi_get_version(RSI_ABI_VERSION_VAL);
 
 	/* Get after reading */
-	read_all_counters(ctr_end, impl_ev_ctrs);
-	read_all_counter_configs(ctr_cfg_end, impl_ev_ctrs);
+	read_all_counters(ctr_end, num_cnts);
+	read_all_counter_configs(ctr_cfg_end, num_cnts);
 	read_all_pmu_configs(pmu_cfg_end);
 
 	if (memcmp(ctr_start, ctr_end, sizeof(ctr_start)) != 0) {
@@ -270,10 +276,11 @@
 	return true;
 }
 
-bool test_pmuv3_overflow_interrupt(void)
+bool test_pmuv3_overflow_interrupt(bool cycle_cnt)
 {
 	unsigned long priority_bits, priority;
-	uint64_t delay_time = DELAY_MS;
+	unsigned long delay_time = DELAY_MS;
+	unsigned int num_cnts, ctr_num;
 
 	pmu_reset();
 
@@ -293,13 +300,30 @@
 	/* Enable IRQ */
 	enable_irq();
 
-	write_pmevcntrn_el0(0, PRE_OVERFLOW);
-	enable_event_counter(0);
+	if (cycle_cnt) {
+		write_pmccntr_el0(PRE_OVERFLOW);
+		enable_cycle_counter();
 
-	/* Enable interrupt on event counter #0 */
-	write_pmintenset_el1((1UL << 0));
+		/* Enable interrupt on cycle counter */
+		write_pmintenset_el1(PMINTENSET_EL1_C_BIT);
+		realm_printf("waiting for PMU cycle counter vIRQ...\n");
+	} else {
+		num_cnts = GET_PMU_CNT;
 
-	realm_printf("waiting for PMU vIRQ...\n");
+		/* Seed the random number generator */
+		srand((unsigned int)read_cntpct_el0());
+
+		/* Select a random number of event counter */
+		ctr_num = (unsigned int)rand() % num_cnts;
+
+		write_pmevcntrn_el0(ctr_num, PRE_OVERFLOW);
+		enable_event_counter(ctr_num);
+
+		/* Enable interrupt on event counter */
+		write_pmintenset_el1(PMINTENSET_EL1_P_BIT(ctr_num));
+		realm_printf("waiting for PMU event counter #%u vIRQ...\n",
+				ctr_num);
+	}
 
 	enable_counting();
 	execute_nops();
@@ -309,7 +333,7 @@
 	 * Performance Monitors Interrupt Enable Set register
 	 * as part of handling the overflow interrupt.
 	 */
-	while ((read_pmintenset_el1() != 0UL) && (delay_time != 0ULL)) {
+	while ((read_pmintenset_el1() != 0UL) && (delay_time != 0UL)) {
 		--delay_time;
 	}
 
@@ -318,14 +342,13 @@
 
 	pmu_reset();
 
-	if (delay_time == 0ULL) {
-		realm_printf("PMU vIRQ %sreceived in %llums\n",	"not ",
+	if (delay_time == 0UL) {
+		realm_printf("PMU vIRQ %sreceived in %lums\n",	"not ",
 				DELAY_MS);
 		return false;
 	}
 
-	realm_printf("PMU vIRQ %sreceived in %llums\n", "",
+	realm_printf("PMU vIRQ %sreceived in %lums\n", "",
 			DELAY_MS - delay_time);
-
 	return true;
 }
diff --git a/realm/realm_psi.c b/realm/realm_psi.c
new file mode 100644
index 0000000..9939d7e
--- /dev/null
+++ b/realm/realm_psi.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <host_realm_rmi.h>
+#include <realm_helpers.h>
+#include <realm_psi.h>
+#include <realm_rsi.h>
+#include <smccc.h>
+
+void psi_exit_to_plane0(u_register_t psi_cmd,
+			u_register_t arg1,
+			u_register_t arg2,
+			u_register_t arg3,
+			u_register_t arg4,
+			u_register_t arg5,
+			u_register_t arg6,
+			u_register_t arg7)
+{
+	if (realm_is_plane0()) {
+		return;
+	}
+	tftf_hvc(&(hvc_args) {psi_cmd, arg1, arg2, arg3, arg4,
+			arg5, arg6, arg7});
+}
+
+u_register_t psi_get_plane_id(void)
+{
+	hvc_ret_values res = tftf_hvc(&(hvc_args) {PSI_CALL_GET_PLANE_ID_CMD, 0UL, 0UL,
+			0UL, 0UL, 0UL, 0UL, 0UL});
+
+	if (res.ret0 != RSI_SUCCESS) {
+		return (u_register_t)-1;
+	}
+	return res.ret1;
+}
+
diff --git a/realm/realm_rsi.c b/realm/realm_rsi.c
index 1c6fc8e..4e223ca 100644
--- a/realm/realm_rsi.c
+++ b/realm/realm_rsi.c
@@ -8,6 +8,7 @@
 
 #include <host_realm_rmi.h>
 #include <lib/aarch64/arch_features.h>
+#include <realm_helpers.h>
 #include <realm_rsi.h>
 #include <smccc.h>
 
@@ -31,30 +32,18 @@
 	return res.ret1;
 }
 
-/* This function will call the Host to request IPA of the NS shared buffer */
-u_register_t rsi_get_ns_buffer(void)
-{
-	smc_ret_values res = {};
-	struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
-
-	host_cal.imm = HOST_CALL_GET_SHARED_BUFF_CMD;
-	res = tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
-		0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
-	if (res.ret0 != RSI_SUCCESS) {
-		return 0U;
-	}
-	return host_cal.gprs[0];
-}
-
 /* This function call Host and request to exit Realm with proper exit code */
-void rsi_exit_to_host(enum host_call_cmd exit_code)
+u_register_t rsi_exit_to_host(enum host_call_cmd exit_code)
 {
 	struct rsi_host_call host_cal __aligned(sizeof(struct rsi_host_call));
+	smc_ret_values res = {};
 
 	host_cal.imm = exit_code;
-	host_cal.gprs[0] = read_mpidr_el1();
-	tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
+	host_cal.gprs[0] = realm_get_my_plane_num();
+	host_cal.gprs[1] = read_mpidr_el1();
+	res = tftf_smc(&(smc_args) {RSI_HOST_CALL, (u_register_t)&host_cal,
 		0UL, 0UL, 0UL, 0UL, 0UL, 0UL});
+	return res.ret0;
 }
 
 /* This function will exit to the Host to request RIPAS CHANGE of IPA range */
@@ -210,3 +199,28 @@
 			{RSI_PLANE_ENTER, plane_index, plane_run});
 	return res.ret0;
 }
+
+u_register_t rsi_plane_reg_read(u_register_t plane_index,
+				u_register_t register_encoding,
+				u_register_t *value)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+			{RSI_PLANE_REG_READ, plane_index, register_encoding});
+	if (res.ret0 == RSI_SUCCESS) {
+		*value = res.ret1;
+	}
+	return res.ret0;
+}
+
+u_register_t rsi_plane_reg_write(u_register_t plane_index,
+				 u_register_t register_encoding,
+				 u_register_t value)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+			{RSI_PLANE_REG_WRITE, plane_index, register_encoding, value});
+	return res.ret0;
+}
diff --git a/realm/realm_shared_data.c b/realm/realm_shared_data.c
index 2825796..c52072e 100644
--- a/realm/realm_shared_data.c
+++ b/realm/realm_shared_data.c
@@ -9,6 +9,7 @@
 #include <assert.h>
 #include <host_shared_data.h>
 #include <realm_def.h>
+#include <realm_helpers.h>
 
 /**
  *   @brief    - Returns the base address of the shared region
@@ -16,14 +17,14 @@
  *   @return   - Base address of the shared region
  **/
 
-static host_shared_data_t *guest_shared_data;
+static host_shared_data_arr_t guest_shared_data;
 
 /*
  * Set guest mapped shared buffer pointer
  */
-void realm_set_shared_structure(host_shared_data_t *ptr)
+void realm_set_shared_structure(u_register_t ptr)
 {
-	guest_shared_data = ptr;
+	guest_shared_data = (host_shared_data_arr_t)ptr;
 }
 
 /*
@@ -31,7 +32,7 @@
  */
 host_shared_data_t *realm_get_my_shared_structure(void)
 {
-	return &guest_shared_data[REC_IDX(read_mpidr_el1())];
+	return &(*guest_shared_data)[realm_get_my_plane_num()][REC_IDX(read_mpidr_el1())];
 }
 
 /*
@@ -40,7 +41,7 @@
 u_register_t realm_shared_data_get_my_host_val(uint8_t index)
 {
 	assert(index < MAX_DATA_SIZE);
-	return guest_shared_data[REC_IDX(read_mpidr_el1())].host_param_val[index];
+	return (*guest_shared_data)[realm_get_my_plane_num()][REC_IDX(read_mpidr_el1())].host_param_val[index];
 }
 
 /*
@@ -48,7 +49,7 @@
  */
 uint8_t realm_shared_data_get_my_realm_cmd(void)
 {
-	return guest_shared_data[REC_IDX(read_mpidr_el1())].realm_cmd;
+	return (*guest_shared_data)[realm_get_my_plane_num()][REC_IDX(read_mpidr_el1())].realm_cmd;
 }
 
 /*
@@ -57,6 +58,45 @@
 void realm_shared_data_set_my_realm_val(uint8_t index, u_register_t val)
 {
 	assert(index < MAX_DATA_SIZE);
-	guest_shared_data[REC_IDX(read_mpidr_el1())].realm_out_val[index] = val;
+	(*guest_shared_data)[realm_get_my_plane_num()][REC_IDX(read_mpidr_el1())].realm_out_val[index] = val;
 }
 
+void realm_shared_data_set_plane_n_val(unsigned int plane_num, unsigned int rec_num,
+		uint8_t index, u_register_t val)
+{
+	assert(index < MAX_DATA_SIZE);
+	assert(plane_num < MAX_PLANE_COUNT);
+	assert(rec_num < MAX_REC_COUNT);
+	assert(is_plane0);
+
+	(*guest_shared_data)[plane_num][rec_num].realm_out_val[index] = val;
+}
+
+u_register_t realm_shared_data_get_plane_n_val(unsigned int plane_num,
+		unsigned int rec_num, uint8_t index)
+{
+	assert(plane_num < MAX_PLANE_COUNT);
+	assert(rec_num < MAX_REC_COUNT);
+	assert(is_plane0);
+
+	return (*guest_shared_data)[plane_num][rec_num].realm_out_val[index];
+}
+
+u_register_t realm_shared_data_get_plane_n_cmd(unsigned int plane_num,
+		unsigned int rec_num, uint8_t index)
+{
+	assert(plane_num < MAX_PLANE_COUNT);
+	assert(rec_num < MAX_REC_COUNT);
+	assert(is_plane0);
+
+	return (*guest_shared_data)[plane_num][rec_num].realm_cmd;
+}
+
+void realm_shared_data_set_plane_n_cmd(uint8_t cmd, unsigned int plane_num, unsigned int rec_num)
+{
+	assert(plane_num < MAX_PLANE_COUNT);
+	assert(rec_num < MAX_REC_COUNT);
+	assert(is_plane0);
+
+	(*guest_shared_data)[plane_num][rec_num].realm_cmd = cmd;
+}
diff --git a/realm/realm_simd.c b/realm/realm_simd.c
index 2eb3eab..0ff1710 100644
--- a/realm/realm_simd.c
+++ b/realm/realm_simd.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
@@ -9,9 +9,11 @@
 #include <assert.h>
 #include <debug.h>
 #include <stdlib.h>
+
 #include <sync.h>
 #include <lib/extensions/fpu.h>
 #include <lib/extensions/sve.h>
+#include <realm_helpers.h>
 
 #include <host_realm_simd.h>
 #include <host_shared_data.h>
@@ -34,8 +36,6 @@
 static fpu_cs_regs_t rl_fpu_cs_regs_write;
 static fpu_cs_regs_t rl_fpu_cs_regs_read;
 
-static int volatile realm_got_undef_abort;
-
 /* Returns the maximum supported VL. This test is called only by sve Realm */
 bool test_realm_sve_rdvl(void)
 {
@@ -188,35 +188,17 @@
 	return rc;
 }
 
-static bool realm_sync_exception_handler(void)
-{
-	uint64_t esr_el1 = read_esr_el1();
-
-	if (EC_BITS(esr_el1) == EC_UNKNOWN) {
-		realm_printf("received undefined abort. "
-			     "esr_el1: 0x%llx elr_el1: 0x%llx\n",
-			     esr_el1, read_elr_el1());
-		realm_got_undef_abort++;
-	}
-
-	return true;
-}
-
 /* Check if Realm gets undefined abort when it accesses SVE functionality */
 bool test_realm_sve_undef_abort(void)
 {
-	realm_got_undef_abort = 0UL;
+	realm_reset_undef_abort_count();
 
-	/* install exception handler to catch undef abort */
+	/* Install exception handler to catch undefined abort */
 	register_custom_sync_exception_handler(&realm_sync_exception_handler);
 	(void)sve_rdvl_1();
 	unregister_custom_sync_exception_handler();
 
-	if (realm_got_undef_abort == 0UL) {
-		return false;
-	}
-
-	return true;
+	return (realm_get_undef_abort_count() != 0U);
 }
 
 /* Reads and returns the ID_AA64PFR1_EL1 and ID_AA64SMFR0_EL1 registers */
@@ -240,16 +222,12 @@
 /* Check if Realm gets undefined abort when it access SME functionality */
 bool test_realm_sme_undef_abort(void)
 {
-	realm_got_undef_abort = 0UL;
+	realm_reset_undef_abort_count();
 
-	/* install exception handler to catch undef abort */
+	/* Install exception handler to catch undefined abort */
 	register_custom_sync_exception_handler(&realm_sync_exception_handler);
 	(void)read_svcr();
 	unregister_custom_sync_exception_handler();
 
-	if (realm_got_undef_abort == 0UL) {
-		return false;
-	}
-
-	return true;
+	return (realm_get_undef_abort_count() != 0U);
 }
diff --git a/smc_fuzz/dts/auto.dts b/smc_fuzz/dts/auto.dts
new file mode 100644
index 0000000..3c2626c
--- /dev/null
+++ b/smc_fuzz/dts/auto.dts
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+/ {
+	candidates {
+		bias = <1>;
+		sdei_pe_unmask_funcid {
+			bias = <30>;
+			functionname = "sdei_pe_unmask_funcid";
+		};
+		sdei_version_funcid {
+			bias = <30>;
+			functionname = "sdei_version_funcid";
+		};
+		sdei_interrupt_bind_funcid {
+			bias = <30>;
+			functionname = "sdei_interrupt_bind_funcid";
+		};
+		sdei_event_enable_funcid {
+			bias = <30>;
+			functionname = "sdei_event_enable_funcid";
+		};
+		sdei_interrupt_release_funcid {
+			bias = <30>;
+			functionname = "sdei_interrupt_release_funcid";
+		};
+		sdei_features_funcid {
+			bias = <30>;
+			functionname = "sdei_features_funcid";
+		};
+		sdei_private_reset_funcid {
+			bias = <30>;
+			functionname = "sdei_private_reset_funcid";
+		};
+		sdei_event_disable_funcid {
+			bias = <30>;
+			functionname = "sdei_event_disable_funcid";
+		};
+		sdei_event_status_funcid {
+			bias = <30>;
+			functionname = "sdei_event_status_funcid";
+		};
+		sdei_shared_reset_funcid {
+			bias = <30>;
+			functionname = "sdei_shared_reset_funcid";
+		};
+		sdei_event_routing_set_funcid {
+			bias = <30>;
+			functionname = "sdei_event_routing_set_funcid";
+		};
+		sdei_event_unregister_funcid {
+			bias = <30>;
+			functionname = "sdei_event_unregister_funcid";
+		};
+		sdei_pe_mask_funcid {
+			bias = <30>;
+			functionname = "sdei_pe_mask_funcid";
+		};
+	};
+};
diff --git a/smc_fuzz/dts/sdei.dts b/smc_fuzz/dts/sdei.dts
index a8199e1..bf9acf1 100644
--- a/smc_fuzz/dts/sdei.dts
+++ b/smc_fuzz/dts/sdei.dts
@@ -1,12 +1,9 @@
 /*
- * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-
-
-
 /dts-v1/;
 
 / {
@@ -41,6 +38,53 @@
 			bias = <30>;
 			functionname = "sdei_shared_reset_funcid";
 		};
+		sdei_interrupt_bind {
+			bias = <30>;
+			functionname = "sdei_interrupt_bind_funcid";
+		};
+		sdei_event_register {
+			bias = <30>;
+			functionname = "sdei_event_register_funcid";
+		};
+		sdei_event_enable {
+			bias = <30>;
+			functionname = "sdei_event_enable_funcid";
+		};
+		sdei_features {
+			bias = <30>;
+			functionname = "sdei_features_funcid";
+		};
+		sdei_event_disable {
+			bias = <30>;
+			functionname = "sdei_event_disable_funcid";
+		};
+		sdei_event_context {
+			bias = <30>;
+			functionname = "sdei_event_context_funcid";
+		};
+		sdei_event_complete {
+			bias = <30>;
+			functionname = "sdei_event_complete_funcid";
+		};
+		sdei_event_complete_and_resume {
+			bias = <30>;
+			functionname = "sdei_event_complete_and_resume_funcid";
+		};
+		sdei_event_unregister {
+			bias = <30>;
+			functionname = "sdei_event_unregister_funcid";
+		};
+		sdei_event_get_info {
+			bias = <30>;
+			functionname = "sdei_event_get_info_funcid";
+		};
+		sdei_event_routing_set {
+			bias = <30>;
+			functionname = "sdei_event_routing_set_funcid";
+		};
+		sdei_interrupt_release {
+			bias = <30>;
+			functionname = "sdei_interrupt_release_funcid";
+		};
 	};
-
 };
diff --git a/smc_fuzz/dts/sdei_and_vendor.dts b/smc_fuzz/dts/sdei_and_vendor.dts
new file mode 100644
index 0000000..d057cff
--- /dev/null
+++ b/smc_fuzz/dts/sdei_and_vendor.dts
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+
+	vendor_el3 {
+		bias = <1>;
+		uid {
+			bias = <30>;
+			functionname = "ven_el3_svc_uuid_funcid";
+		};
+		count {
+			bias = <30>;
+			functionname = "ven_el3_svc_count_funcid";
+		};
+		version {
+			bias = <30>;
+			functionname = "ven_el3_svc_version_funcid";
+		};
+	};
+
+	sdei {
+		bias = <0>;
+		sdei_version {
+			bias = <30>;
+			functionname = "sdei_version_funcid";
+		};
+		sdei_pe_unmask {
+			bias = <30>;
+			functionname = "sdei_pe_unmask_funcid";
+		};
+		sdei_pe_mask {
+			bias = <30>;
+			functionname = "sdei_pe_mask_funcid";
+		};
+		sdei_event_status {
+			bias = <30>;
+			functionname = "sdei_event_status_funcid";
+		};
+		sdei_event_signal {
+			bias = <0>;
+			functionname = "sdei_event_signal_funcid";
+		};
+		sdei_private_reset {
+			bias = <30>;
+			functionname = "sdei_private_reset_funcid";
+		};
+		sdei_shared_reset {
+			bias = <30>;
+			functionname = "sdei_shared_reset_funcid";
+		};
+		sdei_interrupt_bind {
+			bias = <150>;
+			functionname = "sdei_interrupt_bind_funcid";
+		};
+		sdei_event_register {
+			bias = <30>;
+			functionname = "sdei_event_register_funcid";
+		};
+		sdei_event_enable {
+			bias = <30>;
+			functionname = "sdei_event_enable_funcid";
+		};
+		sdei_features {
+			bias = <30>;
+			functionname = "sdei_features_funcid";
+		};
+		sdei_event_disable {
+			bias = <30>;
+			functionname = "sdei_event_disable_funcid";
+		};
+		sdei_event_context {
+			bias = <30>;
+			functionname = "sdei_event_context_funcid";
+		};
+		sdei_event_complete {
+			bias = <30>;
+			functionname = "sdei_event_complete_funcid";
+		};
+		sdei_event_complete_and_resume {
+			bias = <30>;
+			functionname = "sdei_event_complete_and_resume_funcid";
+		};
+		sdei_event_unregister {
+			bias = <30>;
+			functionname = "sdei_event_unregister_funcid";
+		};
+		sdei_event_get_info {
+			bias = <30>;
+			functionname = "sdei_event_get_info_funcid";
+		};
+		sdei_event_routing_set {
+			bias = <30>;
+			functionname = "sdei_event_routing_set_funcid";
+		};
+		sdei_interrupt_release {
+			bias = <30>;
+			functionname = "sdei_interrupt_release_funcid";
+		};
+	};
+};
diff --git a/smc_fuzz/dts/sdei_coverage.dts b/smc_fuzz/dts/sdei_coverage.dts
new file mode 100644
index 0000000..2afbc50
--- /dev/null
+++ b/smc_fuzz/dts/sdei_coverage.dts
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+
+	sdei {
+		bias = <30>;
+		sdei_version {
+			bias = <30>;
+			functionname = "sdei_version_funcid";
+		};
+		sdei_pe_unmask {
+			bias = <30>;
+			functionname = "sdei_pe_unmask_funcid";
+		};
+		sdei_pe_mask {
+			bias = <30>;
+			functionname = "sdei_pe_mask_funcid";
+		};
+		sdei_event_status {
+			bias = <30>;
+			functionname = "sdei_event_status_funcid";
+		};
+		sdei_event_signal {
+			bias = <30>;
+			functionname = "sdei_event_signal_funcid";
+		};
+		sdei_private_reset {
+			bias = <30>;
+			functionname = "sdei_private_reset_funcid";
+		};
+		sdei_shared_reset {
+			bias = <30>;
+			functionname = "sdei_shared_reset_funcid";
+		};
+		sdei_interrupt_bind {
+			bias = <100>;
+			functionname = "sdei_interrupt_bind_funcid";
+		};
+		// added
+		sdei_event_register {
+			bias = <30>;
+			functionname = "sdei_event_register_funcid";
+		};
+		sdei_event_enable {
+			bias = <30>;
+			functionname = "sdei_event_enable_funcid";
+		};
+		sdei_features {
+			bias = <30>;
+			functionname = "sdei_features_funcid";
+		};
+		sdei_event_disable {
+			bias = <30>;
+			functionname = "sdei_event_disable_funcid";
+		};
+		sdei_event_context {
+			bias = <30>;
+			functionname = "sdei_event_context_funcid";
+		};
+		sdei_event_complete {
+			bias = <30>;
+			functionname = "sdei_event_complete_funcid";
+		};
+		sdei_event_complete_and_resume {
+			bias = <30>;
+			functionname = "sdei_event_complete_and_resume_funcid";
+		};
+		sdei_event_unregister {
+			bias = <30>;
+			functionname = "sdei_event_unregister_funcid";
+		};
+		sdei_event_get_info {
+			bias = <30>;
+			functionname = "sdei_event_get_info_funcid";
+		};
+		sdei_event_routing_set {
+			bias = <30>;
+			functionname = "sdei_event_routing_set_funcid";
+		};
+		sdei_interrupt_release {
+			bias = <30>;
+			functionname = "sdei_interrupt_release_funcid";
+		};
+		sdei_routing_set_coverage {
+			bias = <30>;
+			functionname = "sdei_routing_set_coverage_funcid";
+		};
+		sdei_event_get_info_coverage {
+			bias = <30>;
+			functionname = "sdei_event_get_info_coverage_funcid";
+		};
+	};
+
+};
diff --git a/smc_fuzz/dts/test.dts b/smc_fuzz/dts/test.dts
new file mode 100644
index 0000000..2d2b3ec
--- /dev/null
+++ b/smc_fuzz/dts/test.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	experiment {
+		bias = <1>;
+		interrupt {
+			bias = <30>;
+			functionname = "test_funcid";
+		};
+		interrupt_release {
+			bias = <0>;
+			functionname = "sdei_event_signal_funcid";
+		};
+		event {
+			bias = <0>;
+			functionname = "sdei_event_register_funcid";
+		};
+	};
+};
diff --git a/smc_fuzz/dts/vendor.dts b/smc_fuzz/dts/vendor.dts
new file mode 100644
index 0000000..5abf1bd
--- /dev/null
+++ b/smc_fuzz/dts/vendor.dts
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/dts-v1/;
+
+/ {
+	vendor_el3 {
+		bias = <1>;
+		uid {
+			bias = <30>;
+			functionname = "ven_el3_svc_uuid_funcid";
+		};
+		count {
+			bias = <30>;
+			functionname = "ven_el3_svc_count_funcid";
+		};
+		version {
+			 bias = <30>;
+			functionname = "ven_el3_svc_version_funcid";
+		};
+	};
+};
diff --git a/smc_fuzz/include/constraint.h b/smc_fuzz/include/constraint.h
new file mode 100644
index 0000000..3a4af1d
--- /dev/null
+++ b/smc_fuzz/include/constraint.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef CONSTRAINT_H
+#define CONSTRAINT_H
+
+#include <stdint.h>
+#include "smcmalloc.h"
+
+#define SANITY_LEVEL_0 0
+#define SANITY_LEVEL_1 1
+#define SANITY_LEVEL_2 2
+#define SANITY_LEVEL_3 3
+
+#define FUZZER_CONSTRAINT_SVALUE 0
+#define FUZZER_CONSTRAINT_RANGE 1
+#define FUZZER_CONSTRAINT_VECTOR 2
+
+#define FUZZER_CONSTRAINT_ACCMODE 0
+#define FUZZER_CONSTRAINT_EXCMODE 1
+
+#define FUZZ_MAX_SHIFT_AMNT 16
+#define FUZZ_MAX_REG_SIZE 64
+#define FUZZ_MAX_NAME_SIZE 80
+
+struct inputparameters {
+	uint64_t x1;
+	uint64_t x2;
+	uint64_t x3;
+	uint64_t x4;
+	uint64_t x5;
+	uint64_t x6;
+	uint64_t x7;
+	uint64_t x8;
+	uint64_t x9;
+	uint64_t x10;
+	uint64_t x11;
+	uint64_t x12;
+	uint64_t x13;
+	uint64_t x14;
+	uint64_t x15;
+	uint64_t x16;
+	uint64_t x17;
+};
+
+void setconstraint(int contype, uint64_t *vecinput, int veclen, int fieldnameptr, struct memmod *mmod, int mode);
+struct inputparameters generate_args(int smccall, int sanity);
+uint64_t get_generated_value(int fieldnameptr, struct inputparameters inp);
+void print_smccall(int smccall, struct inputparameters inp);
+#endif /* CONSTRAINT_H */
diff --git a/smc_fuzz/include/sdei.h b/smc_fuzz/include/sdei.h
new file mode 100644
index 0000000..63c9698
--- /dev/null
+++ b/smc_fuzz/include/sdei.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __SDEI_H__
+#define __SDEI_H__
+
+#define SDEI_VERSION				0xC4000020
+#define SDEI_EVENT_REGISTER			0xC4000021
+#define SDEI_EVENT_ENABLE			0xC4000022
+#define SDEI_EVENT_DISABLE			0xC4000023
+#define SDEI_EVENT_CONTEXT			0xC4000024
+#define SDEI_EVENT_COMPLETE			0xC4000025
+#define SDEI_EVENT_COMPLETE_AND_RESUME		0xC4000026
+
+#define SDEI_EVENT_UNREGISTER			0xC4000027
+#define SDEI_EVENT_STATUS			0xC4000028
+#define SDEI_EVENT_GET_INFO			0xC4000029
+#define SDEI_EVENT_ROUTING_SET			0xC400002A
+#define SDEI_PE_MASK				0xC400002B
+#define SDEI_PE_UNMASK				0xC400002C
+
+#define SDEI_INTERRUPT_BIND			0xC400002D
+#define SDEI_INTERRUPT_RELEASE			0xC400002E
+#define SDEI_EVENT_SIGNAL			0xC400002F
+#define SDEI_FEATURES				0xC4000030
+#define SDEI_PRIVATE_RESET			0xC4000031
+#define SDEI_SHARED_RESET			0xC4000032
+
+/* For debug */
+#define SDEI_SHOW_DEBUG				0xC400003F
+
+/* SDEI_EVENT_REGISTER flags */
+#define SDEI_REGF_RM_ANY	0
+#define SDEI_REGF_RM_PE		1
+
+/* SDEI_EVENT_COMPLETE status flags */
+#define SDEI_EV_HANDLED		0
+#define SDEI_EV_FAILED		1
+
+/* sde event status values in bit position */
+#define SDEI_STATF_REGISTERED		0
+#define SDEI_STATF_ENABLED		1
+#define SDEI_STATF_RUNNING		2
+
+#define SDEI_INFOF_TYPE			0
+#define SDEI_INFOF_SIGNALABLE		1
+#define SDEI_INFOF_ROUTING_MODE		2
+#define SDEI_INFOF_ROUTING_AFF		3
+
+#define	SMC_EINVAL	2
+#define	SMC_EDENY	3
+#define	SMC_EPEND	5
+#define	SMC_ENOMEM	10
+
+#define MAKE_SDEI_VERSION(_major, _minor, _vendor) \
+	(((uint64_t)(_major)) << 48 | \
+	((uint64_t)(_minor)) << 32 | \
+	(_vendor))
+
+#ifndef __ASSEMBLY__
+#include <stdint.h>
+
+struct sdei_intr_ctx {
+	unsigned int priority;
+	unsigned int num;
+	unsigned int enabled;
+};
+
+typedef int sdei_handler_t(int ev, uint64_t arg);
+
+void sdei_trigger_event(void);
+void sdei_handler_done(void);
+
+int64_t sdei_version(void);
+int64_t sdei_interrupt_bind(int intr, struct sdei_intr_ctx *intr_ctx);
+int64_t sdei_interrupt_release(int intr, const struct sdei_intr_ctx *intr_ctx);
+int64_t sdei_event_register(int ev, sdei_handler_t *ep,
+	uint64_t ep_arg, int flags, uint64_t mpidr);
+int64_t sdei_event_unregister(int ev);
+int64_t sdei_event_enable(int ev);
+int64_t sdei_event_disable(int ev);
+int64_t sdei_pe_mask(void);
+int64_t sdei_pe_unmask(void);
+int64_t sdei_private_reset(void);
+int64_t sdei_shared_reset(void);
+int64_t sdei_event_signal(uint64_t mpidr);
+int64_t sdei_event_status(int32_t ev);
+int64_t sdei_event_routing_set(int32_t ev, uint64_t flags);
+int64_t sdei_event_context(uint32_t param);
+int64_t sdei_event_complete(uint32_t flags);
+int64_t sdei_event_complete_and_resume(uint64_t addr);
+// added
+int64_t sdei_features(uint32_t feature);
+#endif /* __ASSEMBLY__ */
+
+#endif /* __SDEI_H__ */
diff --git a/smc_fuzz/include/sdei_fuzz_helper.h b/smc_fuzz/include/sdei_fuzz_helper.h
index cf4ddd1..b05cb91 100644
--- a/smc_fuzz/include/sdei_fuzz_helper.h
+++ b/smc_fuzz/include/sdei_fuzz_helper.h
@@ -4,7 +4,12 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <stdlib.h>
+#include <time.h>
+
 #include <fuzz_helper.h>
+#include "smcmalloc.h"
+
 #include <power_management.h>
 #include <sdei.h>
 #include <test_helpers.h>
@@ -34,6 +39,64 @@
 #endif
 
 
-void tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr);
+#ifndef sdei_event_register_funcid
+#define sdei_event_register_funcid 0
+#endif
+#ifndef sdei_event_enable_funcid
+#define sdei_event_enable_funcid 0
+#endif
+#ifndef sdei_event_disable_funcid
+#define sdei_event_disable_funcid 0
+#endif
+#ifndef sdei_event_context_funcid
+#define sdei_event_context_funcid 0
+#endif
+#ifndef sdei_event_complete_funcid
+#define sdei_event_complete_funcid 0
+#endif
+#ifndef sdei_event_complete_and_resume_funcid
+#define sdei_event_complete_and_resume_funcid 0
+#endif
+#ifndef sdei_event_unregister_funcid
+#define sdei_event_unregister_funcid 0
+#endif
+#ifndef sdei_event_get_info_funcid
+#define sdei_event_get_info_funcid 0
+#endif
+#ifndef sdei_event_routing_set_funcid
+#define sdei_event_routing_set_funcid 0
+#endif
+#ifndef sdei_interrupt_bind_funcid
+#define sdei_interrupt_bind_funcid 0
+#endif
+#ifndef sdei_interrupt_release_funcid
+#define sdei_interrupt_release_funcid 0
+#endif
+#ifndef sdei_features_funcid
+#define sdei_features_funcid 0
+#endif
+#ifndef sdei_signal_hang_funcid
+#define sdei_signal_hang_funcid 0
+#endif
+#ifndef experiment_funcid
+#define experiment_funcid 0
+#endif
+#ifndef repeat_interrupt_bind_funcid
+#define repeat_interrupt_bind_funcid 0
+#endif
+#ifndef sdei_event_get_info_coverage_funcid
+#define sdei_event_get_info_coverage_funcid 0
+#endif
+#ifndef sdei_routing_set_coverage_funcid
+#define sdei_routing_set_coverage_funcid 0
+#endif
+#ifndef test_funcid
+#define test_funcid 0
+#endif
+
+
+int64_t tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr);
 void tftf_test_sdei_singlearg(int64_t (*sdei_func)(uint64_t), char *funcstr);
-void run_sdei_fuzz(int funcid);
+void run_sdei_fuzz(int funcid, struct memmod *mmod, bool inrange, int cntid);
+char *return_str(int64_t ret);
+void print_ret(char *funcstr, int64_t ret);
diff --git a/smc_fuzz/include/smcmalloc.h b/smc_fuzz/include/smcmalloc.h
index fe134bf..97b33e9 100644
--- a/smc_fuzz/include/smcmalloc.h
+++ b/smc_fuzz/include/smcmalloc.h
@@ -52,12 +52,12 @@
 };
 
 void initmem(void);
-struct peret priorityencoder(unsigned int);
-void *smcmalloc(unsigned int, struct memmod*);
-int smcfree(void*, struct memmod *);
+struct peret priorityencoder(unsigned int ennum);
+void *smcmalloc(unsigned int req, struct memmod *mmod);
+int smcfree(void *vin, struct memmod *mmod);
 #ifdef DEBUG_SMC_MALLOC
-void displayblocks(struct memmod *);
-void displaymalloctable(struct memmod *);
+void displayblocks(struct memmod *mmod);
+void displaymalloctable(struct memmod *mmod);
 #endif
 
 #endif /* SMCMALLOC_H */
diff --git a/smc_fuzz/include/vendor_fuzz_helper.h b/smc_fuzz/include/vendor_fuzz_helper.h
new file mode 100644
index 0000000..106df12
--- /dev/null
+++ b/smc_fuzz/include/vendor_fuzz_helper.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <time.h>
+
+#include <fuzz_helper.h>
+#include "smcmalloc.h"
+
+#include <power_management.h>
+#include <sdei.h>
+#include <test_helpers.h>
+#include <tftf_lib.h>
+#include <timer.h>
+
+#ifndef ven_el3_svc_uuid_funcid
+#define ven_el3_svc_uuid_funcid 0
+#endif
+#ifndef ven_el3_svc_count_funcid
+#define ven_el3_svc_count_funcid 0
+#endif
+#ifndef ven_el3_svc_version_funcid
+#define ven_el3_svc_version_funcid 0
+#endif
+
+void run_ven_el3_fuzz(int funcid, struct memmod *mmod);
diff --git a/smc_fuzz/script/gen_arg_struct_def.py b/smc_fuzz/script/gen_arg_struct_def.py
new file mode 100755
index 0000000..ce24679
--- /dev/null
+++ b/smc_fuzz/script/gen_arg_struct_def.py
@@ -0,0 +1,69 @@
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+def gen_arg_struct_def(asdname,argfieldname,arglst,argnumfield):
+	asdfile = open(asdname, "w")
+	hline = "/*\n"
+	hline += " * Copyright (c) 2024, Arm Limited. All rights reserved.\n"
+	hline += " *\n"
+	hline += " * SPDX-License-Identifier: BSD-3-Clause\n"
+	hline += " */\n"
+	hline += "\n"
+	hline += "#ifndef ARG_STRUCT_DEF_H\n"
+	hline += "#define ARG_STRUCT_DEF_H\n"
+	hline += "\n"
+	asdfile.write(hline)
+	smccount = 0
+	argcount = 0
+	for sn in argfieldname:
+		hline = "#define "
+		hline += sn
+		hline += " "
+		hline += str(smccount)
+		hline += "\n"
+		asdfile.write(hline)
+		smccount = smccount + 1
+	smccount = smccount - 1
+	hline = "#define MAX_SMC_CALLS "
+	hline += str(smccount)
+	hline += "\n"
+	asdfile.write(hline)
+	asdfile.write("\n")
+	for sn in arglst:
+		for an in arglst[sn]:
+			hline = "#define "
+			hline += sn
+			hline += "_ARG" + str(an) + " " + str(argcount)
+			hline += "\n"
+			asdfile.write(hline)
+			argcount = argcount + 1
+	argcount = argcount - 1
+	hline = "#define MAX_ARG_LENGTH "
+	hline += str(argcount)
+	hline += "\n\n"
+	asdfile.write(hline)
+	for sn in argnumfield:
+		for ag in argnumfield[sn]:
+			fieldcount = 0
+			for fn in argnumfield[sn][ag]:
+				hline = "#define " + sn + "_ARG" + str(argnumfield[sn][ag][fn]) + "_" + fn.upper() + "_CNT " + str(fieldcount)
+				hline += "\n"
+				asdfile.write(hline)
+				fieldcount = fieldcount + 1
+	fieldcount = 0
+	hline = "\n\n"
+	asdfile.write(hline)
+	for sn in argnumfield:
+		for ag in argnumfield[sn]:
+			for fn in argnumfield[sn][ag]:
+				hline = "#define " + sn + "_ARG" + str(argnumfield[sn][ag][fn]) + "_" + fn.upper() + " " +  str(fieldcount)
+				hline += "\n"
+				asdfile.write(hline)
+				fieldcount = fieldcount + 1
+	hline = "\n#endif /* ARG_STRUCT_DEF_H */\n"
+	asdfile.write(hline)
+
+	asdfile.close()
diff --git a/smc_fuzz/script/gen_field_specification.py b/smc_fuzz/script/gen_field_specification.py
new file mode 100755
index 0000000..86eff31
--- /dev/null
+++ b/smc_fuzz/script/gen_field_specification.py
@@ -0,0 +1,152 @@
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+def gen_field_specification(fsname,argfieldname,argendbit,argstartbit,argdefval,argnumfield):
+	faafile  = open(fsname, "w")
+	hline = "struct fuzzer_arg_def {\n"
+	hline += "        int regnum;\n"
+	hline += "        char smcname[FUZZ_MAX_NAME_SIZE];\n"
+	hline += "        char smcargname[FUZZ_MAX_NAME_SIZE];\n"
+	hline += "        int bitw;\n"
+	hline += "        int bitst;\n"
+	hline += "        char bnames[FUZZ_MAX_NAME_SIZE];\n"
+	hline += "        uint64_t defval;\n"
+	hline += "        uint64_t **contval;\n"
+	hline += "        int *contvallen;\n"
+	hline += "        int contlen;\n"
+	hline += "        int *conttype;\n"
+	hline += "        int genvalues;\n"
+	hline += "};\n\n"
+	hline += "struct fuzzer_arg_arange {\n"
+	hline += "        int arg_span[2];\n"
+	hline += "};\n"
+	faafile.write(hline)
+	hline = "struct fuzzer_arg_def fuzzer_arg_array[] = {\n"
+	faafile.write(hline)
+	ifield = 1
+	for sn in argfieldname:
+		for an in argfieldname[sn]:
+			for fn in argfieldname[sn][an]:
+				if not ifield:
+					hline = ",\n"
+					hline += "{ .bitw = "
+				else:
+					hline = "{ .bitw = "
+				hline += str((int(argendbit[sn][an][fn]) - int(argstartbit[sn][an][fn])) + 1)
+				hline += ", .bitst = " + argstartbit[sn][an][fn] + ", .bnames = \""
+				hline += fn + "\", .defval = " + argdefval[sn][an][fn] + ", .regnum = "
+				hline += argnumfield[sn][an][fn] + ", .smcname = \"" + sn + "\", .smcargname = \""
+				hline += an + "\" }"
+				ifield = 0
+				faafile.write(hline)
+	hline = " };\n\n"
+	faafile.write(hline)
+	lc = 0
+	hline = "struct fuzzer_arg_arange fuzzer_arg_array_lst[] = {" + "\n"
+	faafile.write(hline)
+	ifield = 1
+	for sn in argfieldname:
+		for ag in argfieldname[sn]:
+			if not ifield:
+				hline = ",\n"
+				hline += "{ .arg_span = {" + str(lc) + "," + str(len(argfieldname[sn][ag]) - 1 + lc) + "} }"
+			else :
+				hline = "{ .arg_span = {" + str(lc) + "," + str(len(argfieldname[sn][ag]) - 1 + lc) + "} }"
+			ifield = 0
+			faafile.write(hline)
+			lc = lc + len(argfieldname[sn][ag])
+	hline = " };\n\n"
+	faafile.write(hline)
+	hline = "int fuzzer_arg_array_range[] = {" + "\n"
+	faafile.write(hline)
+	lc = 0
+	ifield = 1
+	hline = ""
+	for sn in argfieldname:
+		if not ifield:
+			hline += ","
+			hline += str(len(argfieldname[sn]))
+		else:
+			hline += str(len(argfieldname[sn]))
+		lc = lc + 1
+		ifield = 0
+		if lc == 20:
+			hline += "\n"
+			lc = 0
+	hline += "};\n\n"
+	faafile.write(hline)
+	hline = "int fuzzer_arg_array_start[] = {" + "\n"
+	faafile.write(hline)
+	lc = 0
+	ifield = 1
+	cargs = 0
+	hline = ""
+	for sn in argfieldname:
+		if not ifield:
+			hline += ","
+			hline += str(cargs)
+		else:
+			hline += str(cargs)
+		cargs = cargs + len(argfieldname[sn])
+		lc = lc + 1
+		ifield = 0
+		if lc == 20:
+			hline += "\n"
+			lc = 0
+	hline += "};\n\n"
+	faafile.write(hline)
+	hline = "int fuzzer_fieldarg[] = {" + "\n"
+	faafile.write(hline)
+	blist = 1
+	hline = "\t"
+	for sn in argnumfield:
+		for ag in argnumfield[sn]:
+			for fn in argnumfield[sn][ag]:
+				if not blist:
+					hline += ",\n\t"
+				blist = 0
+				hline += sn + "_ARG" + str(argnumfield[sn][ag][fn])
+				faafile.write(hline)
+				hline = ""
+	hline = "\n};"
+	faafile.write(hline)
+	hline = "\n\n"
+	faafile.write(hline)
+	hline = "int fuzzer_fieldcall[] = {" + "\n"
+	faafile.write(hline)
+	blist = 1
+	hline = "\t"
+	for sn in argnumfield:
+		for ag in argnumfield[sn]:
+			for fn in argnumfield[sn][ag]:
+				if not blist:
+					hline += ",\n\t"
+				blist = 0
+				hline += sn
+				faafile.write(hline)
+				hline = ""
+	hline = "\n};"
+	faafile.write(hline)
+	hline = "\n\n"
+	faafile.write(hline)
+	hline = "int fuzzer_fieldfld[] = {" + "\n"
+	faafile.write(hline)
+	blist = 1
+	hline = "\t"
+	for sn in argnumfield:
+		for ag in argnumfield[sn]:
+			for fn in argnumfield[sn][ag]:
+				if not blist:
+					hline += ",\n\t"
+				blist = 0
+				hline += sn + "_ARG" + str(argnumfield[sn][ag][fn]) + "_" + fn.upper() + "_CNT"
+				faafile.write(hline)
+				hline = ""
+	hline = "\n};"
+
+	faafile.write(hline)
+
+	faafile.close()
diff --git a/smc_fuzz/script/generate_smc.py b/smc_fuzz/script/generate_smc.py
new file mode 100755
index 0000000..dac5924
--- /dev/null
+++ b/smc_fuzz/script/generate_smc.py
@@ -0,0 +1,45 @@
+# !/usr/bin/env python
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+
+#python3 generate_smc.py -s smclist
+#This script generated C files after the read of the SMC description/list file
+import argparse
+import readsmclist
+import gen_arg_struct_def
+import gen_field_specification
+
+parser = argparse.ArgumentParser(
+		prog='generate_smc.py',
+		description='Generates SMC code to add to fuzzer library',
+		epilog='one argument input')
+
+parser.add_argument('-s', '--smclist',help="SMC list file .")
+
+args = parser.parse_args()
+
+print("starting generate SMC")
+
+seq = 0
+
+readsmclist.readsmclist(args.smclist,seq)
+
+arglst = readsmclist.arglst
+argnumfield = readsmclist.argnumfield
+argfieldname = readsmclist.argfieldname
+argstartbit = readsmclist.argstartbit
+argendbit = readsmclist.argendbit
+argdefval = readsmclist.argdefval
+smcname = readsmclist.smcname
+argnum = readsmclist.argnum
+argname = readsmclist.argname
+
+gen_arg_struct_def.gen_arg_struct_def("./include/arg_struct_def.h",argfieldname,arglst,argnumfield)
+
+gen_field_specification.gen_field_specification("./include/field_specification.h",
+argfieldname,argendbit,argstartbit,argdefval,argnumfield)
+
diff --git a/smc_fuzz/script/readsmclist.py b/smc_fuzz/script/readsmclist.py
new file mode 100755
index 0000000..3bfcb6a
--- /dev/null
+++ b/smc_fuzz/script/readsmclist.py
@@ -0,0 +1,193 @@
+#
+# Copyright (c) 2025 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+import re
+import copy
+import sys
+
+arglst = {}
+argnumfield = {}
+argfieldname = {}
+argstartbit = {}
+argendbit = {}
+argdefval = {}
+smcname = ""
+argnum = ""
+argname = ""
+
+def readsmclist(smclist,seq):
+	smclistfile =  open(smclist, "r")
+	smclist_lines = smclistfile.readlines()
+	smclistfile.close()
+	for sline in smclist_lines:
+		lcon = 0
+		sl = sline.strip()
+		sinstr = re.search(r'^smc:\s*([a-zA-Z0-9_]+)$',sl)
+		if sinstr:
+			smcname = sinstr.group(1)
+			arglst[sinstr.group(1)] = []
+			argnumfield[sinstr.group(1)] = {}
+			argfieldname[sinstr.group(1)] = {}
+			argstartbit[sinstr.group(1)] = {}
+			argendbit[sinstr.group(1)] = {}
+			argdefval[sinstr.group(1)] = {}
+			lcon = 1
+			argoccupy = {}
+			if not seq:
+				seq = seq + 1
+			else:
+				if seq != 2:
+					print("Error: out of sequence for smc call",end=" ")
+					print(smcname)
+					sys.exit()
+				else:
+					seq = 1
+		sinstr = re.search(r'^arg(\d+)\s*:\s*([a-zA-Z0-9_]+)$',sl)
+		if sinstr:
+			if sinstr.group(1) in argoccupy:
+				print("Error: register already specified for SMC call",end=" ")
+				print(smcname,end=" ")
+				print("argument",end=" ")
+				print(sinstr.group(1))
+				sys.exit()
+			argnum = sinstr.group(1)
+			argname = sinstr.group(2)
+			arglst[smcname].append(argnum)
+			argnumfield[smcname][sinstr.group(2)] = {}
+			argfieldname[smcname][sinstr.group(2)] = []
+			argstartbit[smcname][sinstr.group(2)] = {}
+			argendbit[smcname][sinstr.group(2)] = {}
+			argdefval[smcname][sinstr.group(2)] = {}
+			lcon = 1
+			argoccupy[argnum] = 1
+			fieldoccupy = []
+			if seq != 1:
+				if seq != 2:
+					print("Error: out of sequence for arg(value)",end=" ")
+					print("arg",end=" ")
+					print(argnum,end=" ")
+					print("for argname",end=" ")
+					print(argname)
+					sys.exit()
+				else:
+					seq = 2
+			else:
+				seq = seq + 1
+
+		sinstr = re.search(r'^arg(\d+)\s*=\s*(0x[a-fA-F0-9]+|\d+)$',sl)
+		if sinstr:
+			if sinstr.group(1) in argoccupy:
+				print("Error: register already specified for SMC call",end=" ")
+				print(smcname,end=" ")
+				print("argument",end=" ")
+				print(sinstr.group(1))
+				sys.exit()
+			srange = sinstr.group(1)
+			argrangename = smcname + "_args_"+ sinstr.group(1)
+			argnum = srange
+			argname = smcname + "_arg_" + argnum
+			fieldnameargdef = smcname + "_arg_" + argnum + "_field"
+			arglst[smcname].append(argnum)
+			argnumfield[smcname][argname] = {}
+			argfieldname[smcname][argname] = []
+			argstartbit[smcname][argname] = {}
+			argendbit[smcname][argname] = {}
+			argdefval[smcname][argname] = {}
+			argnumfield[smcname][argname][fieldnameargdef] = argnum
+			argfieldname[smcname][argname].append(fieldnameargdef)
+			argstartbit[smcname][argname][fieldnameargdef] = str(0)
+			argendbit[smcname][argname][fieldnameargdef] = str(63)
+			argdefval[smcname][argname][fieldnameargdef] = sinstr.group(2)
+			lcon = 1
+			argoccupy[argnum] = 1
+			if seq != 1:
+				if seq != 2:
+					print("Error: out of sequence for arg(value)",end=" ")
+					print("arg",end=" ")
+					print(argnum,end=" ")
+					print("for argname",end=" ")
+					print(argname)
+					sys.exit()
+			else:
+				seq = seq + 1
+		sinstr = re.search(r'^arg(\d+)-arg(\d+)\s*=\s*(0x[a-fA-F0-9]+|\d+)$',sl)
+		if sinstr:
+			srange = int(sinstr.group(1))
+			erange = int(sinstr.group(2))
+			argrangename = smcname + "_args_"+ sinstr.group(1) + "_" + sinstr.group(2)
+			for i in range((erange - srange) + 1):
+				if str(srange + i) in argoccupy:
+					print("Error: register already specified for SMC call",end=" ")
+					print(smcname,end=" ")
+					print("argument",end=" ")
+					print(str(srange + i))
+					sys.exit()
+				argnum = srange + i
+				argname = smcname + "_arg_" + str(argnum)
+				fieldnameargdef = smcname + "_arg_" + str(argnum) + "_field"
+				arglst[smcname].append(argnum)
+				argnumfield[smcname][argname] = {}
+				argfieldname[smcname][argname] = []
+				argstartbit[smcname][argname] = {}
+				argendbit[smcname][argname] = {}
+				argdefval[smcname][argname] = {}
+				argnumfield[smcname][argname][fieldnameargdef] = str(argnum)
+				argfieldname[smcname][argname].append(fieldnameargdef)
+				argstartbit[smcname][argname][fieldnameargdef] = str(0)
+				argendbit[smcname][argname][fieldnameargdef] = str(63)
+				argdefval[smcname][argname][fieldnameargdef] = sinstr.group(3)
+				argoccupy[str(argnum)] = 1
+			lcon = 1
+			if seq != 1:
+				if seq != 2:
+					print("Error: out of sequence for arg(value)",end=" ")
+					print("arg",end=" ")
+					print(argnum,end=" ")
+					print("for argname",end=" ")
+					print(argname)
+					sys.exit()
+				else:
+					seq = 2
+			else:
+				seq = seq + 1
+		sinstr = re.search(r'^field:([a-zA-Z0-9_]+):\[(\d+),(\d+)\]\s*=\s*(0x[a-fA-F0-9]+|\d+)$',sl)
+		if sinstr:
+			for fs in fieldoccupy:
+				if(((fs[0] <= int(sinstr.group(3))) and (fs[0] >= int(sinstr.group(2)))) or
+				((fs[1] <= int(sinstr.group(3))) and (fs[1] >= int(sinstr.group(2))))):
+					print("Error: field overlap",end=" ")
+					print(smcname,end=" ")
+					print(argname,end=" ")
+					print(sinstr.group(1),end=" ")
+					print(fs[0],end=" ")
+					print(fs[1],end=" ")
+					print(" with",end=" ")
+					print(sinstr.group(2),end=" ")
+					print(sinstr.group(3))
+					sys.exit()
+			argnumfield[smcname][argname][sinstr.group(1)] = argnum
+			argfieldname[smcname][argname].append(sinstr.group(1))
+			argstartbit[smcname][argname][sinstr.group(1)] = sinstr.group(2)
+			argendbit[smcname][argname][sinstr.group(1)] = sinstr.group(3)
+			argdefval[smcname][argname][sinstr.group(1)] = sinstr.group(4)
+			flist = []
+			flist.append(int(sinstr.group(2)))
+			flist.append(int(sinstr.group(3)))
+			fieldoccupy.append(flist)
+			lcon = 1
+			if seq != 2:
+				print("Error: out of sequence for field")
+				sys.exit()
+		if not lcon:
+			cline = re.search(r'^#',sl)
+			if not cline:
+				if sl:
+					print("Error: malformed line at",end=" ")
+					print(sl)
+					sys.exit()
+	if(seq != 2):
+		print("incorrect ending for smc specification")
+		sys.exit()
diff --git a/smc_fuzz/sdei_and_vendor_smc_calls.txt b/smc_fuzz/sdei_and_vendor_smc_calls.txt
new file mode 100644
index 0000000..63ca64b
--- /dev/null
+++ b/smc_fuzz/sdei_and_vendor_smc_calls.txt
@@ -0,0 +1,83 @@
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+smc: SDEI_EVENT_STATUS_CALL
+        arg1:bev
+                field:bev:[0,31] = 0
+smc: SDEI_INTERRUPT_BIND_CALL
+        arg1:interruptnum
+                field:inum:[0,31] = 1
+smc: SDEI_VERSION_CALL
+        arg1-arg17 = 0
+smc: SDEI_EVENT_REGISTER_CALL
+        arg1:eventnum
+                field:enum:[0,31] = 0
+        arg2:entryaddr
+                field:addr:[0,63] = 0
+        arg3:eparg
+                field:arg:[0,63] = 0
+        arg4:flags
+                field:routing:[0,0] = 0
+                field:relative:[1,1] = 0
+                field:reserved:[2,63] = 0
+        arg5:affinity
+                field:aff:[0,63] = 0
+smc: SDEI_EVENT_ENABLE_CALL
+        arg1:eventnum
+                field:enum:[0,31] = 0
+smc: SDEI_FEATURES_CALL
+        arg1:feature
+                field:feat:[0,31] = 0
+smc: SDEI_EVENT_DISABLE_CALL
+        arg1:eventnum
+                field:enum:[0,31] = 0
+smc: SDEI_EVENT_CONTEXT_CALL
+        arg1:paramid
+                field:param:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_CALL
+        arg1:status
+                field:stat:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_AND_RESUME_CALL
+        arg1:resumeaddr
+                field:addr:[0,63] = 0
+smc: SDEI_EVENT_UNREGISTER_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+smc: SDEI_EVENT_GET_INFO_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+        arg2:info
+                field:info:[0,31] = 0
+smc: SDEI_EVENT_ROUTING_SET_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+        arg2:routingmode
+                field:routing:[0,0] = 0
+                field:constant:[1,63] = 0
+        arg3:affinity
+                field:aff:[0,63] = 0
+smc: SDEI_PE_MASK_CALL
+        arg1 = 0
+smc: SDEI_PE_UNMASK_CALL
+        arg1 = 0
+smc:  SDEI_INTERRUPT_RELEASE_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+smc: SDEI_EVENT_SIGNAL_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+        arg2:targetpe
+                field:pe:[0,31] = 0
+smc: SDEI_PRIVATE_RESET_CALL
+        arg1 = 0
+smc: SDEI_SHARED_RESET_CALL
+        arg1 = 0
+smc: VEN_EL3_SVC_UUID_CALL
+        arg1=0
+smc: VEN_EL3_SVC_COUNT_CALL
+        arg1=0
+smc: VEN_EL3_SVC_VERSION_CALL
+        arg1=0
diff --git a/smc_fuzz/sdei_smc_calls.txt b/smc_fuzz/sdei_smc_calls.txt
new file mode 100644
index 0000000..3017630
--- /dev/null
+++ b/smc_fuzz/sdei_smc_calls.txt
@@ -0,0 +1,77 @@
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+smc: SDEI_EVENT_STATUS_CALL
+        arg1:bev
+                field:bev:[0,31] = 0
+smc: SDEI_INTERRUPT_BIND_CALL
+        arg1:interruptnum
+                field:inum:[0,31] = 1
+smc: SDEI_VERSION_CALL
+        arg1-arg17 = 0
+smc: SDEI_EVENT_REGISTER_CALL
+        arg1:eventnum
+                field:enum:[0,31] = 0
+        arg2:entryaddr
+                field:addr:[0,63] = 0
+        arg3:eparg
+                field:arg:[0,63] = 0
+        arg4:flags
+                field:routing:[0,0] = 0
+                field:relative:[1,1] = 0
+                field:reserved:[2,63] = 0
+        arg5:affinity
+                field:aff:[0,63] = 0
+smc: SDEI_EVENT_ENABLE_CALL
+        arg1:eventnum
+                field:enum:[0,31] = 0
+smc: SDEI_FEATURES_CALL
+        arg1:feature
+                field:feat:[0,31] = 0
+smc: SDEI_EVENT_DISABLE_CALL
+        arg1:eventnum
+                field:enum:[0,31] = 0
+smc: SDEI_EVENT_CONTEXT_CALL
+        arg1:paramid
+                field:param:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_CALL
+        arg1:status
+                field:stat:[0,31] = 0
+smc: SDEI_EVENT_COMPLETE_AND_RESUME_CALL
+        arg1:resumeaddr
+                field:addr:[0,63] = 0
+smc: SDEI_EVENT_UNREGISTER_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+smc: SDEI_EVENT_GET_INFO_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+        arg2:info
+                field:info:[0,31] = 0
+smc: SDEI_EVENT_ROUTING_SET_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+        arg2:routingmode
+                field:routing:[0,0] = 0
+                field:constant:[1,63] = 0
+        arg3:affinity
+                field:aff:[0,63] = 0
+smc: SDEI_PE_MASK_CALL
+        arg1 = 0
+smc: SDEI_PE_UNMASK_CALL
+        arg1 = 0
+smc:  SDEI_INTERRUPT_RELEASE_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+smc: SDEI_EVENT_SIGNAL_CALL
+        arg1:event
+                field:enum:[0,31] = 0
+        arg2:targetpe
+                field:pe:[0,31] = 0
+smc: SDEI_PRIVATE_RESET_CALL
+        arg1 = 0
+smc: SDEI_SHARED_RESET_CALL
+        arg1 = 0
diff --git a/smc_fuzz/src/constraint.c b/smc_fuzz/src/constraint.c
new file mode 100644
index 0000000..7e4c4b5
--- /dev/null
+++ b/smc_fuzz/src/constraint.c
@@ -0,0 +1,1040 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arg_struct_def.h>
+#include <constraint.h>
+#include <field_specification.h>
+
+#include <debug.h>
+
+#ifdef SMC_FUZZ_TMALLOC
+#define GENMALLOC(x)    malloc((x))
+#define GENFREE(x)      free((x))
+#else
+#define GENMALLOC(x)    smcmalloc((x), mmod)
+#define GENFREE(x)      smcfree((x), mmod)
+#endif
+
+/*******************************************************
+* Random 64 bit generator for registers
+*******************************************************/
+
+uint64_t rand64bit(void)
+{
+	uint64_t xreg = (rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) << FUZZ_MAX_SHIFT_AMNT;
+
+	xreg = ((rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) | xreg) << FUZZ_MAX_SHIFT_AMNT;
+	xreg = ((rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) | xreg) << FUZZ_MAX_SHIFT_AMNT;
+	xreg = ((rand() % (1 << FUZZ_MAX_SHIFT_AMNT)) | xreg);
+	return xreg;
+}
+
+/*******************************************************
+* Shift left function for registers
+*******************************************************/
+
+uint64_t shiftlft(uint64_t val, int shamnt)
+{
+	uint64_t ressh = val;
+
+	if (shamnt > FUZZ_MAX_REG_SIZE) {
+		printf("Error: cannot shift beyond %d bits\n", FUZZ_MAX_REG_SIZE);
+		panic();
+	}
+	if (shamnt > FUZZ_MAX_SHIFT_AMNT) {
+		for (int i = 0; i < ((shamnt / FUZZ_MAX_SHIFT_AMNT) + 1); i++) {
+			if (i == (shamnt / FUZZ_MAX_SHIFT_AMNT)) {
+				ressh = ressh << (shamnt % FUZZ_MAX_SHIFT_AMNT);
+			} else {
+				ressh = ressh << FUZZ_MAX_SHIFT_AMNT;
+			}
+		}
+	} else {
+		ressh = ressh << shamnt;
+	}
+	return ressh;
+}
+
+/*******************************************************
+* Shift right function for registers
+*******************************************************/
+
+uint64_t shiftrht(uint64_t val, int shamnt)
+{
+	uint64_t ressh = val;
+
+	if (shamnt > FUZZ_MAX_REG_SIZE) {
+		printf("Error: cannot shift beyond %d bits\n", FUZZ_MAX_REG_SIZE);
+		panic();
+	}
+	if (shamnt > FUZZ_MAX_SHIFT_AMNT) {
+		for (int i = 0; i < ((shamnt / FUZZ_MAX_SHIFT_AMNT) + 1); i++) {
+			if (i == (shamnt / FUZZ_MAX_SHIFT_AMNT)) {
+				ressh = ressh >> (shamnt % FUZZ_MAX_SHIFT_AMNT);
+			} else {
+				ressh = ressh >> FUZZ_MAX_SHIFT_AMNT;
+			}
+		}
+	} else {
+		ressh = ressh >> shamnt;
+	}
+	return ressh;
+}
+
+/*******************************************************
+* Set constraints for the fields in the SMC call
+*******************************************************/
+
+
+void setconstraint(int contype, uint64_t *vecinput, int veclen, int fieldnameptr, struct memmod *mmod, int mode)
+{
+	int argdef = fuzzer_fieldarg[fieldnameptr];
+	int fieldname = fuzzer_fieldfld[fieldnameptr];
+
+	if ((argdef > MAX_ARG_LENGTH) || (argdef < 0)) {
+		printf("SMC argument is out of bounds\n");
+		panic();
+	}
+	if ((fieldname > (fuzzer_arg_array_lst[argdef].arg_span[1] -
+		fuzzer_arg_array_lst[argdef].arg_span[0])) || (fieldname < 0)) {
+		printf("SMC fieldname is out of bounds\n");
+		panic();
+	}
+	int fieldptr = fuzzer_arg_array_lst[argdef].arg_span[0] + fieldname;
+
+	if ((contype > FUZZER_CONSTRAINT_VECTOR) || (contype < 0)) {
+		printf("SMC constraint type is out of bounds\n");
+		panic();
+	}
+	if (mode > 2) {
+		printf("SMC constriant mode input is invalid\n");
+		panic();
+	}
+	if (mmod == NULL) {
+		printf("SMC constraint memory pointer is invalid\n");
+		panic();
+	}
+	if (contype == FUZZER_CONSTRAINT_SVALUE) {
+		if (veclen < 1) {
+			printf("vector length to constraint for single value is not large enough");
+			printf(" %d", veclen);
+			panic();
+		}
+		if (vecinput == NULL) {
+			printf("vector input to constraint single value is not defined\n");
+			panic();
+		}
+		if (fuzzer_arg_array[fieldptr].contval == NULL) {
+			fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+			fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(1 * sizeof(uint64_t *));
+			fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+			fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+			fuzzer_arg_array[fieldptr].contvallen[0] = 1;
+			fuzzer_arg_array[fieldptr].contlen = 1;
+			fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+			fuzzer_arg_array[fieldptr].conttype[0] = contype;
+		} else {
+			if (mode == FUZZER_CONSTRAINT_ACCMODE) {
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					if (fuzzer_arg_array[fieldptr].conttype[i] ==
+					FUZZER_CONSTRAINT_SVALUE) {
+						if (fuzzer_arg_array[fieldptr].contval[i][0] == vecinput[0]) {
+							return;
+						}
+					}
+				}
+				uint64_t **tarray;
+
+				tarray = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+				* sizeof(uint64_t **));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarray[i] = GENMALLOC(fuzzer_arg_array[fieldptr].contvallen[i]
+					* sizeof(uint64_t *));
+					for (int k = 0; k < fuzzer_arg_array[fieldptr].contvallen[i]; k++) {
+						tarray[i][k] = fuzzer_arg_array[fieldptr].contval[i][k];
+					}
+				}
+				tarray[fuzzer_arg_array[fieldptr].contlen] = GENMALLOC(1 * sizeof(int *));
+				tarray[fuzzer_arg_array[fieldptr].contlen][0] = vecinput[0];
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+				}
+				GENFREE(fuzzer_arg_array[fieldptr].contval);
+				fuzzer_arg_array[fieldptr].contval = tarray;
+				int *tarraysingle;
+
+				tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen) * sizeof(int *));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarraysingle[i] = fuzzer_arg_array[fieldptr].contvallen[i];
+				}
+				tarraysingle[fuzzer_arg_array[fieldptr].contlen] = 1;
+				GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+				fuzzer_arg_array[fieldptr].contvallen = tarraysingle;
+				tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+				* sizeof(int *));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarraysingle[i] = fuzzer_arg_array[fieldptr].conttype[i];
+				}
+				tarraysingle[fuzzer_arg_array[fieldptr].contlen] = contype;
+				GENFREE(fuzzer_arg_array[fieldptr].conttype);
+				fuzzer_arg_array[fieldptr].conttype = tarraysingle;
+				fuzzer_arg_array[fieldptr].contlen++;
+			}
+			if (mode == FUZZER_CONSTRAINT_EXCMODE) {
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+				}
+				GENFREE(fuzzer_arg_array[fieldptr].contval);
+				GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+				GENFREE(fuzzer_arg_array[fieldptr].conttype);
+				fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+				fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(1 * sizeof(uint64_t *));
+				fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+				fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+				fuzzer_arg_array[fieldptr].contvallen[0] = 1;
+				fuzzer_arg_array[fieldptr].contlen = 1;
+				fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+				fuzzer_arg_array[fieldptr].conttype[0] = contype;
+			}
+		}
+	}
+	if (contype == FUZZER_CONSTRAINT_RANGE) {
+		if (veclen < 2) {
+			printf("vector length to constraint for range is not large enough");
+			printf(" %d", veclen);
+			panic();
+		}
+		if (vecinput == NULL) {
+			printf("vector inputs to constraint for range is not defined\n");
+			panic();
+		}
+		if (fuzzer_arg_array[fieldptr].contval == NULL) {
+			fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+			fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(2 * sizeof(uint64_t *));
+			fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+			fuzzer_arg_array[fieldptr].contval[0][1] = vecinput[1];
+			fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+			fuzzer_arg_array[fieldptr].contvallen[0] = 2;
+			fuzzer_arg_array[fieldptr].contlen = 1;
+			fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+			fuzzer_arg_array[fieldptr].conttype[0] = contype;
+		} else {
+			if (mode == FUZZER_CONSTRAINT_ACCMODE) {
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					if (fuzzer_arg_array[fieldptr].conttype[i] ==
+					FUZZER_CONSTRAINT_RANGE) {
+						if ((fuzzer_arg_array[fieldptr].contval[i][0] ==
+						vecinput[0]) && (fuzzer_arg_array[fieldptr].contval[i][1]
+						== vecinput[1])) {
+							return;
+						}
+					}
+				}
+				uint64_t **tarray;
+
+				tarray = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+				* sizeof(uint64_t **));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarray[i] =
+					GENMALLOC(fuzzer_arg_array[fieldptr].contvallen[i]
+					* sizeof(uint64_t *));
+					for (int k = 0; k < fuzzer_arg_array[fieldptr].contvallen[i]; k++) {
+						tarray[i][k] = fuzzer_arg_array[fieldptr].contval[i][k];
+					}
+				}
+				tarray[fuzzer_arg_array[fieldptr].contlen] = GENMALLOC(2
+				* sizeof(uint64_t *));
+				tarray[fuzzer_arg_array[fieldptr].contlen][0] = vecinput[0];
+				tarray[fuzzer_arg_array[fieldptr].contlen][1] = vecinput[1];
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+				}
+				GENFREE(fuzzer_arg_array[fieldptr].contval);
+				fuzzer_arg_array[fieldptr].contval = tarray;
+				int *tarraysingle;
+				tarraysingle =
+				GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen) * sizeof(int *));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarraysingle[i] = fuzzer_arg_array[fieldptr].contvallen[i];
+				}
+				tarraysingle[fuzzer_arg_array[fieldptr].contlen] = 2;
+				GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+				fuzzer_arg_array[fieldptr].contvallen = tarraysingle;
+				tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+				* sizeof(int *));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarraysingle[i] = fuzzer_arg_array[fieldptr].conttype[i];
+				}
+				tarraysingle[fuzzer_arg_array[fieldptr].contlen] = contype;
+				GENFREE(fuzzer_arg_array[fieldptr].conttype);
+				fuzzer_arg_array[fieldptr].conttype = tarraysingle;
+				fuzzer_arg_array[fieldptr].contlen++;
+			}
+			if (mode == FUZZER_CONSTRAINT_EXCMODE) {
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+				}
+				GENFREE(fuzzer_arg_array[fieldptr].contval);
+				GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+				GENFREE(fuzzer_arg_array[fieldptr].conttype);
+				fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+				fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(2 * sizeof(uint64_t *));
+				fuzzer_arg_array[fieldptr].contval[0][0] = vecinput[0];
+				fuzzer_arg_array[fieldptr].contval[0][1] = vecinput[1];
+				fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+				fuzzer_arg_array[fieldptr].contvallen[0] = 2;
+				fuzzer_arg_array[fieldptr].contlen = 1;
+				fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+				fuzzer_arg_array[fieldptr].conttype[0] = contype;
+			}
+		}
+	}
+	if (contype == FUZZER_CONSTRAINT_VECTOR) {
+		if (veclen < 2) {
+			printf("vector length to constraint for vector is not large enough");
+			printf(" %d", veclen);
+			panic();
+		}
+		if (vecinput == NULL) {
+			printf("vector input to constraint vector is not defined\n");
+			panic();
+		}
+		if (fuzzer_arg_array[fieldptr].contval == NULL) {
+			fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+			fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(veclen * sizeof(uint64_t *));
+			for (int i = 0; i < veclen; i++) {
+				fuzzer_arg_array[fieldptr].contval[0][i] = vecinput[i];
+			}
+			fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+			fuzzer_arg_array[fieldptr].contvallen[0] = veclen;
+			fuzzer_arg_array[fieldptr].contlen = 1;
+			fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+			fuzzer_arg_array[fieldptr].conttype[0] = contype;
+
+		} else {
+			if (mode == FUZZER_CONSTRAINT_ACCMODE) {
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					if (fuzzer_arg_array[fieldptr].conttype[i] ==
+					FUZZER_CONSTRAINT_VECTOR) {
+						if (fuzzer_arg_array[fieldptr].contvallen[i] == veclen) {
+							int fne = 0;
+							for (int j = 0; j <
+							fuzzer_arg_array[fieldptr].contvallen[i]; j++) {
+							if (fuzzer_arg_array[fieldptr].contval
+								[i][j] != vecinput[j]) {
+									fne = 1;
+								}
+							}
+							if (fne == 0) {
+								return;
+							}
+						}
+					}
+				}
+				uint64_t **tarray;
+
+				tarray = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+				* sizeof(uint64_t **));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarray[i] = GENMALLOC(fuzzer_arg_array[fieldptr].contvallen
+					[i] * sizeof(uint64_t *));
+					for (int k = 0; k < fuzzer_arg_array[fieldptr].contvallen[i]; k++) {
+						tarray[i][k] = fuzzer_arg_array[fieldptr].contval[i][k];
+					}
+				}
+				tarray[fuzzer_arg_array[fieldptr].contlen] =
+				GENMALLOC(veclen * sizeof(uint64_t *));
+				for (int i = 0; i < veclen; i++) {
+					tarray[fuzzer_arg_array[fieldptr].contlen][i] = vecinput[i];
+				}
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+				}
+				GENFREE(fuzzer_arg_array[fieldptr].contval);
+				fuzzer_arg_array[fieldptr].contval = tarray;
+				int *tarraysingle;
+				tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+				* sizeof(int *));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarraysingle[i] = fuzzer_arg_array[fieldptr].contvallen[i];
+				}
+				tarraysingle[fuzzer_arg_array[fieldptr].contlen] = veclen;
+				GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+				fuzzer_arg_array[fieldptr].contvallen = tarraysingle;
+				tarraysingle = GENMALLOC((1 + fuzzer_arg_array[fieldptr].contlen)
+				* sizeof(int *));
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					tarraysingle[i] = fuzzer_arg_array[fieldptr].conttype[i];
+				}
+				tarraysingle[fuzzer_arg_array[fieldptr].contlen] = contype;
+				GENFREE(fuzzer_arg_array[fieldptr].conttype);
+				fuzzer_arg_array[fieldptr].conttype = tarraysingle;
+				fuzzer_arg_array[fieldptr].contlen++;
+			}
+			if (mode == FUZZER_CONSTRAINT_EXCMODE) {
+				for (int i = 0; i < fuzzer_arg_array[fieldptr].contlen; i++) {
+					GENFREE(fuzzer_arg_array[fieldptr].contval[i]);
+				}
+				GENFREE(fuzzer_arg_array[fieldptr].contval);
+				GENFREE(fuzzer_arg_array[fieldptr].contvallen);
+				GENFREE(fuzzer_arg_array[fieldptr].conttype);
+				fuzzer_arg_array[fieldptr].contval = GENMALLOC(1 * sizeof(uint64_t **));
+				fuzzer_arg_array[fieldptr].contval[0] = GENMALLOC(veclen
+				* sizeof(uint64_t *));
+				for (int i = 0; i < veclen; i++) {
+					fuzzer_arg_array[fieldptr].contval[0][i] = vecinput[i];
+				}
+				fuzzer_arg_array[fieldptr].contvallen = GENMALLOC(1 * sizeof(int *));
+				fuzzer_arg_array[fieldptr].contvallen[0] = veclen;
+				fuzzer_arg_array[fieldptr].contlen = 1;
+				fuzzer_arg_array[fieldptr].conttype = GENMALLOC(1 * sizeof(int *));
+				fuzzer_arg_array[fieldptr].conttype[0] = contype;
+			}
+		}
+	}
+}
+
+/*******************************************************
+* Generate the uncondition(no constraint)
+* fields in the SMC call
+*******************************************************/
+
+uint64_t generate_field_uncon(int smccall, int rsel)
+{
+	uint64_t shiftreg = 0;
+	uint64_t resreg = 0;
+	int fieldptr = 0;
+	int argptr = fuzzer_arg_array_start[smccall] + rsel;
+
+	for (int i = 0; i <= (fuzzer_arg_array_lst[argptr].arg_span[1] -
+	fuzzer_arg_array_lst[argptr].arg_span[0]); i++) {
+		fieldptr = fuzzer_arg_array_lst[argptr].arg_span[0] + i;
+		shiftreg = shiftlft((rand() % shiftlft(1, fuzzer_arg_array[fieldptr].bitw)),
+		fuzzer_arg_array[fieldptr].bitst);
+		resreg = resreg | shiftreg;
+	}
+	return resreg;
+}
+
+uint64_t generate_field_con(int smccall, int rsel)
+{
+	uint64_t shiftreg = 0;
+	uint64_t resreg = 0;
+	int fieldptr = 0;
+	int nullstat = 0;
+	int argptr = fuzzer_arg_array_start[smccall] + rsel;
+
+	for (int i = 0; i <= (fuzzer_arg_array_lst[argptr].arg_span[1] -
+	fuzzer_arg_array_lst[argptr].arg_span[0]); i++) {
+		fieldptr = fuzzer_arg_array_lst[argptr].arg_span[0] + i;
+		nullstat = 0;
+		if (fuzzer_arg_array[fieldptr].contval == NULL) {
+			if (fuzzer_arg_array[fieldptr].defval >
+				(shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1)) {
+				printf("Default constraint will not fit inside bitfield %llx %llx\n",
+				fuzzer_arg_array[fieldptr].defval,
+				(shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1));
+				panic();
+			} else {
+				shiftreg = shiftlft(fuzzer_arg_array[fieldptr].defval,
+				fuzzer_arg_array[fieldptr].bitst);
+				resreg = resreg | shiftreg;
+			}
+			nullstat = 1;
+		} else if (fuzzer_arg_array[fieldptr].contval[0] == NULL) {
+			if (fuzzer_arg_array[fieldptr].defval >
+				(shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1)) {
+				printf("Default constraint will not fit inside bitfield %llx %llx\n",
+				fuzzer_arg_array[fieldptr].defval,
+				(shiftlft(1, fuzzer_arg_array[fieldptr].bitw) - 1));
+				panic();
+			} else {
+				shiftreg = shiftlft(fuzzer_arg_array[fieldptr].defval,
+				fuzzer_arg_array[fieldptr].bitst);
+				resreg = resreg | shiftreg;
+			}
+			nullstat = 1;
+		}
+		if (nullstat == 0) {
+			int selcon = rand() % (fuzzer_arg_array[fieldptr].contlen);
+
+			if (fuzzer_arg_array[fieldptr].conttype[selcon] == FUZZER_CONSTRAINT_SVALUE) {
+				if (fuzzer_arg_array[fieldptr].contval[selcon][0] >
+					((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1)) {
+					printf("Constraint will not fit inside bitfield %llx %llx\n",
+					fuzzer_arg_array[fieldptr].contval[selcon][0],
+					((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1));
+					panic();
+				} else {
+					shiftreg = shiftlft(fuzzer_arg_array[fieldptr].contval[selcon][0],
+					fuzzer_arg_array[fieldptr].bitst);
+					resreg = resreg | shiftreg;
+				}
+			}
+
+			if (fuzzer_arg_array[fieldptr].conttype[selcon] == FUZZER_CONSTRAINT_RANGE) {
+				uint64_t maxn = shiftlft(1, fuzzer_arg_array[fieldptr].bitw);
+
+				if ((fuzzer_arg_array[fieldptr].contval[selcon][0] >
+					((maxn) - 1)) || ((fuzzer_arg_array[fieldptr].contval[selcon][1] >
+					((maxn) - 1))))  {
+					if (fuzzer_arg_array[fieldptr].contval[selcon][0] >
+					((maxn) - 1)) {
+						printf("Constraint will not fit inside bitfield %llx %llx\n",
+						fuzzer_arg_array[fieldptr].contval[selcon][0], ((maxn) - 1));
+					}
+					if (fuzzer_arg_array[fieldptr].contval[selcon][1] >
+					((maxn) - 1)) {
+						printf("Constraint will not fit inside bitfield %llx %llx\n",
+						fuzzer_arg_array[fieldptr].contval[selcon][1], ((maxn) - 1));
+					}
+					panic();
+				} else {
+					shiftreg = shiftlft(((rand() %
+					(fuzzer_arg_array[fieldptr].contval[selcon][1] -
+					fuzzer_arg_array[fieldptr].contval[selcon][0] + 1)) +
+					fuzzer_arg_array[fieldptr].contval[selcon][0]),
+					fuzzer_arg_array[fieldptr].bitst);
+					resreg = resreg | shiftreg;
+				}
+			}
+
+			if (fuzzer_arg_array[fieldptr].conttype[selcon] == FUZZER_CONSTRAINT_VECTOR) {
+				for (int j = 0; j < fuzzer_arg_array[fieldptr].contvallen[selcon]; j++) {
+					if (fuzzer_arg_array[fieldptr].contval[selcon][j] >
+						((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1)) {
+						printf("Constraint will not fit inside bitfield");
+						printf(" %llx %llx\n",
+						fuzzer_arg_array[fieldptr].contval[selcon][j],
+						((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) - 1));
+						panic();
+					}
+				}
+				shiftreg = shiftlft((fuzzer_arg_array[fieldptr].contval[selcon]
+				[(rand() % (fuzzer_arg_array[fieldptr].contvallen[selcon]))]),
+				fuzzer_arg_array[fieldptr].bitst);
+				resreg = resreg | shiftreg;
+			}
+		}
+	}
+	return resreg;
+}
+
+/*******************************************************
+* Generate the field arguments for constrained fields
+* for all sanity levels
+*******************************************************/
+
+struct inputparameters generate_args(int smccall, int sanity)
+{
+	if ((smccall > MAX_SMC_CALLS) || (smccall < 0)) {
+		printf("generate args SMC call is out of bounds\n");
+		panic();
+	}
+	if ((sanity > SANITY_LEVEL_3) || (sanity < 0)) {
+		printf("generate args sanity level is out of bounds\n");
+		panic();
+	}
+	struct inputparameters nparam;
+
+	nparam.x1 = 1;
+	if (sanity == SANITY_LEVEL_0) {
+		for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+			switch (i) {
+				case 0: {
+					nparam.x1 = rand64bit();
+					break;
+				}
+				case 1: {
+					nparam.x2 = rand64bit();
+					break;
+				}
+				case 2: {
+					nparam.x3 = rand64bit();
+					break;
+				}
+				case 3: {
+					nparam.x4 = rand64bit();
+					break;
+				}
+				case 4: {
+					nparam.x5 = rand64bit();
+					break;
+				}
+				case 5: {
+					nparam.x6 = rand64bit();
+					break;
+				}
+				case 6: {
+					nparam.x7 = rand64bit();
+					break;
+				}
+				case 7: {
+					nparam.x8 = rand64bit();
+					break;
+				}
+				case 8: {
+					nparam.x9 = rand64bit();
+					break;
+				}
+				case 9: {
+					nparam.x10 = rand64bit();
+					break;
+				}
+				case 10: {
+					nparam.x11 = rand64bit();
+					break;
+				}
+				case 11: {
+					nparam.x12 = rand64bit();
+					break;
+				}
+				case 12: {
+					nparam.x13 = rand64bit();
+					break;
+				}
+				case 13: {
+					nparam.x14 = rand64bit();
+					break;
+				}
+				case 14: {
+					nparam.x15 = rand64bit();
+					break;
+				}
+				case 15: {
+					nparam.x16 = rand64bit();
+					break;
+				}
+				case 16: {
+					nparam.x17 = rand64bit();
+					break;
+				}
+			}
+		}
+	}
+	if (sanity == SANITY_LEVEL_1) {
+		int selreg = rand() % (fuzzer_arg_array_range[smccall] + 1);
+		for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+			switch (i) {
+				case 0: {
+					if (selreg == 0) {
+						nparam.x1 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x1 = rand64bit();
+					}
+					break;
+				}
+				case 1: {
+					if (selreg == 1) {
+						nparam.x2 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x2 = rand64bit();
+					}
+					break;
+				}
+				case 2: {
+					if (selreg == 2) {
+						nparam.x3 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x3 = rand64bit();
+					}
+					break;
+				}
+				case 3: {
+					if (selreg == 3) {
+						nparam.x4 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x4 = rand64bit();
+					}
+					break;
+				}
+				case 4: {
+					if (selreg == 4) {
+						nparam.x5 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x5 = rand64bit();
+					}
+					break;
+				}
+				case 5: {
+					if (selreg == 5) {
+						nparam.x6 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x6 = rand64bit();
+					}
+					break;
+				}
+				case 6: {
+					if (selreg == 6) {
+						nparam.x7 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x7 = rand64bit();
+					}
+					break;
+				}
+				case 7: {
+					if (selreg == 7) {
+						nparam.x8 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x8 = rand64bit();
+					}
+					break;
+				}
+				case 8: {
+					if (selreg == 8) {
+						nparam.x9 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x9 = rand64bit();
+					}
+					break;
+				}
+				case 9: {
+					if (selreg == 9) {
+						nparam.x10 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x10 = rand64bit();
+					}
+					break;
+				}
+				case 10: {
+					if (selreg == 10) {
+						nparam.x11 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x11 = rand64bit();
+					}
+					break;
+				}
+				case 11: {
+					if (selreg == 11) {
+						nparam.x12 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x12 = rand64bit();
+					}
+					break;
+				}
+				case 12: {
+					if (selreg == 12) {
+						nparam.x13 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x13 = rand64bit();
+					}
+					break;
+				}
+				case 13: {
+					if (selreg == 13) {
+						nparam.x14 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x14 = rand64bit();
+					}
+					break;
+				}
+				case 14: {
+					if (selreg == 14) {
+						nparam.x15 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x15 = rand64bit();
+					}
+					break;
+				}
+				case 15: {
+					if (selreg == 15) {
+						nparam.x16 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x16 = rand64bit();
+					}
+					break;
+				}
+				case 16: {
+					if (selreg == 16) {
+						nparam.x17 = generate_field_uncon(smccall, i);
+					} else {
+						nparam.x17 = rand64bit();
+					}
+					break;
+				}
+			}
+		}
+	}
+	if (sanity == SANITY_LEVEL_2) {
+		for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+			switch (i) {
+				case 0: {
+					nparam.x1 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 1: {
+					nparam.x2 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 2: {
+					nparam.x3 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 3: {
+					nparam.x4 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 4: {
+					nparam.x5 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 5: {
+					nparam.x6 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 6: {
+					nparam.x7 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 7: {
+					nparam.x8 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 8: {
+					nparam.x9 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 9: {
+					nparam.x10 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 10: {
+					nparam.x11 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 11: {
+					nparam.x12 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 12: {
+					nparam.x13 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 13: {
+					nparam.x14 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 14: {
+					nparam.x15 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 15: {
+					nparam.x16 = generate_field_uncon(smccall, i);
+					break;
+				}
+				case 16: {
+					nparam.x17 = generate_field_uncon(smccall, i);
+					break;
+				}
+			}
+		}
+	}
+	if (sanity == SANITY_LEVEL_3) {
+		for (int i = 0; i < fuzzer_arg_array_range[smccall]; i++) {
+			switch (i) {
+				case 0: {
+					nparam.x1 = generate_field_con(smccall, i);
+					break;
+				}
+				case 1: {
+					nparam.x2 = generate_field_con(smccall, i);
+					break;
+				}
+				case 2: {
+					nparam.x3 = generate_field_con(smccall, i);
+					break;
+				}
+				case 3: {
+					nparam.x4 = generate_field_con(smccall, i);
+					break;
+				}
+				case 4: {
+					nparam.x5 = generate_field_con(smccall, i);
+					break;
+				}
+				case 5: {
+					nparam.x6 = generate_field_con(smccall, i);
+					break;
+				}
+				case 6: {
+					nparam.x7 = generate_field_con(smccall, i);
+					break;
+				}
+				case 7: {
+					nparam.x8 = generate_field_con(smccall, i);
+					break;
+				}
+				case 8: {
+					nparam.x9 = generate_field_con(smccall, i);
+					break;
+				}
+				case 9: {
+					nparam.x10 = generate_field_con(smccall, i);
+					break;
+				}
+				case 10: {
+					nparam.x11 = generate_field_con(smccall, i);
+					break;
+				}
+				case 11: {
+					nparam.x12 = generate_field_con(smccall, i);
+					break;
+				}
+				case 12: {
+					nparam.x13 = generate_field_con(smccall, i);
+					break;
+				}
+				case 13: {
+					nparam.x14 = generate_field_con(smccall, i);
+					break;
+				}
+				case 14: {
+					nparam.x15 = generate_field_con(smccall, i);
+					break;
+				}
+				case 15: {
+					nparam.x16 = generate_field_con(smccall, i);
+					break;
+				}
+				case 16: {
+					nparam.x17 = generate_field_con(smccall, i);
+					break;
+				}
+			}
+		}
+	}
+	#ifdef SMC_FUZZER_DEBUG
+		print_smccall(smccall, nparam);
+	#endif
+	return nparam;
+}
+
+/*******************************************************
+* Get generated value from fuzzer for a given field
+*******************************************************/
+
+uint64_t get_generated_value(int fieldnameptr, struct inputparameters inp)
+{
+	uint64_t xval = 0;
+	int argdef = fuzzer_fieldarg[fieldnameptr];
+	int fieldname = fuzzer_fieldfld[fieldnameptr];
+	int fieldptr = fuzzer_arg_array_lst[argdef].arg_span[0] + fieldname;
+
+	switch(fuzzer_arg_array[fieldptr].regnum) {
+		case 1: {
+			xval = shiftrht(inp.x1, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 2: {
+			xval = shiftrht(inp.x2, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 3: {
+			xval = shiftrht(inp.x3, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 4: {
+			xval = shiftrht(inp.x4, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 5: {
+			xval = shiftrht(inp.x5, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 6: {
+			xval = shiftrht(inp.x6, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 7: {
+			xval = shiftrht(inp.x7, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 8: {
+			xval = shiftrht(inp.x8, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 9: {
+			xval = shiftrht(inp.x9, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 10: {
+			xval = shiftrht(inp.x10, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 11: {
+			xval = shiftrht(inp.x11, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 12: {
+			xval = shiftrht(inp.x12, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 13: {
+			xval = shiftrht(inp.x13, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 14: {
+			xval = shiftrht(inp.x14, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 15: {
+			xval = shiftrht(inp.x15, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 16: {
+			xval = shiftrht(inp.x16, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+		case 17: {
+			xval = shiftrht(inp.x17, fuzzer_arg_array[fieldptr].bitst) &
+			((shiftlft(1, fuzzer_arg_array[fieldptr].bitw)) -  1);
+			return xval;
+		}
+	}
+	return xval;
+}
+
+/*******************************************************
+* Print the values from a generated SMC call from fuzzer
+*******************************************************/
+
+void print_smccall(int smccall, struct inputparameters inp)
+{
+	if ((smccall > MAX_SMC_CALLS) || (smccall < 0)) {
+		printf("generate args SMC call is out of bounds\n");
+		panic();
+	}
+	int argptr = fuzzer_arg_array_start[smccall];
+	int fieldptr = fuzzer_arg_array_lst[fuzzer_arg_array_start[smccall]].arg_span[0];
+
+	printf("%s\n", fuzzer_arg_array[fieldptr].smcname);
+	for (int i = 0; i < (fuzzer_arg_array_range[smccall]); i++) {
+		fieldptr = fuzzer_arg_array_lst[argptr + i].arg_span[0];
+		printf("argument: %s\n", fuzzer_arg_array[fieldptr].smcargname);
+		for (int j = fieldptr; j <= ((fuzzer_arg_array_lst[argptr + i].arg_span[1] -
+		fuzzer_arg_array_lst[argptr + i].arg_span[0]) + fieldptr); j++) {
+			printf("%s = %llx\n", fuzzer_arg_array[j].bnames,
+				get_generated_value(j, inp));
+		}
+	}
+	printf("\n\n");
+}
diff --git a/smc_fuzz/src/randsmcmod.c b/smc_fuzz/src/randsmcmod.c
index a86feb6..e1725f0 100644
--- a/smc_fuzz/src/randsmcmod.c
+++ b/smc_fuzz/src/randsmcmod.c
@@ -4,20 +4,22 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include "fifo3d.h"
+#include "nfifo.h"
+
 #include <arch_helpers.h>
 #include <debug.h>
 #include <drivers/arm/private_timer.h>
 #include <events.h>
-#include "fifo3d.h"
-#include "nfifo.h"
 #include <libfdt.h>
-
 #include <plat_topology.h>
 #include <power_management.h>
 #include <tftf_lib.h>
 
+
 extern char _binary___dtb_start[];
-extern void runtestfunction(int funcid);
+extern void runtestfunction(int funcid, struct memmod *mmod);
+extern void init_input_arg_struct(void);
 
 struct memmod tmod __aligned(65536) __section("smcfuzz");
 static int cntndarray;
@@ -233,9 +235,9 @@
 				     (fdt32_to_cpu(fhd.off_dt_strings) +
 				      fdt32_to_cpu(pv.nameoff)), cset);
 			if (strcmp(cset, "bias") == 0) {
-				rval = *((unsigned int *)dtb);
+				unsigned int bval = *((unsigned int *)dtb);
 				dtb += sizeof(unsigned int);
-				push_3dfifo_bias(&f3d, fdt32_to_cpu(rval));
+				push_3dfifo_bias(&f3d, fdt32_to_cpu(bval));
 				bias_count++;
 				if (bintnode == 1U) {
 					fnode = 0U;
@@ -460,6 +462,7 @@
 test_result_t smc_fuzzing_instance(uint32_t seed)
 {
 	struct rand_smc_node *tlnode;
+
 	/*
 	 * Initialize pseudo random number generator with supplied seed.
 	 */
@@ -494,7 +497,10 @@
 			int selent = tlnode->biasarray[nch];
 
 			if (tlnode->norcall[selent] == 0) {
-				runtestfunction(tlnode->snameid[selent]);
+			#ifdef SMC_FUZZER_DEBUG
+				printf("the name of the SMC call is %s\n", tlnode->snames[selent]);
+			#endif
+				runtestfunction(tlnode->snameid[selent], mmod);
 				nd = 1;
 			} else {
 				tlnode = &tlnode->treenodes[selent];
diff --git a/smc_fuzz/src/runtestfunction_helpers.c b/smc_fuzz/src/runtestfunction_helpers.c
index c3b2cca..411949c 100644
--- a/smc_fuzz/src/runtestfunction_helpers.c
+++ b/smc_fuzz/src/runtestfunction_helpers.c
@@ -5,14 +5,24 @@
  */
 
 #include <sdei_fuzz_helper.h>
+#include "smcmalloc.h"
 #include <tsp_fuzz_helper.h>
 
+int cntid = 0;
+
+#include <vendor_fuzz_helper.h>
 
 /*
  * Invoke the SMC call based on the function name specified.
  */
-void runtestfunction(int funcid)
+void runtestfunction(int funcid, struct memmod *mmod)
 {
-	run_sdei_fuzz(funcid);
+	bool inrange = (cntid >= SMC_FUZZ_CALL_START) && (cntid < SMC_FUZZ_CALL_END);
+	inrange = inrange && (funcid != EXCLUDE_FUNCID);
+
+	run_sdei_fuzz(funcid, mmod, inrange, cntid);
 	run_tsp_fuzz(funcid);
+	run_ven_el3_fuzz(funcid, mmod);
+
+	cntid++;
 }
diff --git a/smc_fuzz/src/sdei_fuzz_helper.c b/smc_fuzz/src/sdei_fuzz_helper.c
index 1d22335..5a1d866 100644
--- a/smc_fuzz/src/sdei_fuzz_helper.c
+++ b/smc_fuzz/src/sdei_fuzz_helper.c
@@ -4,19 +4,94 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <arg_struct_def.h>
+#include "constraint.h"
 #include <fuzz_names.h>
 #include <sdei_fuzz_helper.h>
 
+int stbev = 0;
+
+#define MIN_PPI_ID		U(16)
+#define MAX_PPI_ID		U(31)
+#define MIN_SPI_ID		U(32)
+#define MAX_SPI_ID		U(255)
+#define EV_COOKIE 0xDEADBEEF
+#define PPI_RANGE ((uint64_t[2]) {MIN_PPI_ID, MAX_PPI_ID})
+#define SPI_RANGE ((uint64_t[2]) {MIN_SPI_ID, MAX_SPI_ID})
+#define BIND_SLOTS_MASK			0xffffU
+#define FEATURES_SHARED_SLOTS_SHIFT	16U
+#define FEATURES_PRIVATE_SLOTS_SHIFT	0U
+
+extern sdei_handler_t sdei_entrypoint;
+extern sdei_handler_t sdei_entrypoint_resume;
+
+#define HANDLER_SVALUE ((uint64_t[1]) { (uint64_t)(uintptr_t)sdei_entrypoint_resume })
+#define PE_SVALUE ((uint64_t[1]) { read_mpidr_el1() })
+#define ZERO_EVENT_SVALUE ((uint64_t[1]) { 0 })
+#define EV_COOKIE_SVALUE ((uint64_t[1]) { 0xDEADBEEF })
+#define VENDOR_EVENTS_RANGE ((uint64_t[2]) { 0x40000000, 0x40FFFFFF })
+#define STD_EVENTS_RANGE ((uint64_t[2]) { 0x00000001, 0x00FFFFFF })
+#define ANY_ROUTING ((uint64_t[1]) { SDEI_REGF_RM_ANY })
+#define PE_ROUTING ((uint64_t[1]) { SDEI_REGF_RM_PE })
+#define ROUTING_MODES ((uint64_t[2]) { SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE })
+#define OUT_OF_RESOURCE_ERR -10
+#define MAX_BIND_SLOTS (1 << 16)
+
+#define register_handler() setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, \
+SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE)
+
+char *return_str(int64_t return_val)
+{
+	switch (return_val) {
+	case -1:
+		return "NOT_SUPPORTED";
+	case -2:
+		return "INVALID_PARAMETERS";
+	case -3:
+		return "DENIED";
+	case -5:
+		return "PENDING";
+	case -10:
+		return "OUT_OF_RESOURCE";
+	default:
+		return "UNKNOWN ERROR CODE";
+	}
+}
+
+void print_return(char *funcstr, int64_t ret)
+{
+	if (ret < 0) {
+		printf("%s failed: 0x%llx. %s\n", funcstr, ret, return_str(ret));
+	} else {
+		printf("%s successful return: %llx\n", funcstr, ret);
+	}
+}
+
+void set_event_constraints(int sdei_arg_name, struct memmod *mmod)
+{
+	setconstraint(FUZZER_CONSTRAINT_SVALUE, ZERO_EVENT_SVALUE, 1, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
+	setconstraint(FUZZER_CONSTRAINT_SVALUE, STD_EVENTS_RANGE, 2, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
+	setconstraint(FUZZER_CONSTRAINT_SVALUE, VENDOR_EVENTS_RANGE, 2, sdei_arg_name, mmod, FUZZER_CONSTRAINT_ACCMODE);
+}
+
 /*
  * SDEI function that has no arguments
  */
-void tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr)
+int64_t tftf_test_sdei_noarg(int64_t (*sdei_func)(void), char *funcstr)
 {
 		int64_t ret = (*sdei_func)();
 
 		if (ret < 0) {
 			tftf_testcase_printf("%s failed: 0x%llx\n", funcstr, ret);
 		}
+
+		printf("%s return: %llx\n", funcstr, ret);
+
+		return ret;
 }
 
 /*
@@ -24,37 +99,689 @@
  */
 void tftf_test_sdei_singlearg(int64_t (*sdei_func)(uint64_t), char *funcstr)
 {
-		int64_t ret = (*sdei_func)(0);
+		struct sdei_intr_ctx intr_ctx;
+		int bev;
+
+		bev = sdei_interrupt_bind(tftf_get_timer_irq(), &intr_ctx);
+		int64_t ret = (*sdei_func)(bev);
 
 		if (ret < 0) {
 			tftf_testcase_printf("%s failed: 0x%llx\n", funcstr, ret);
 		}
 }
 
+uint64_t *bound_shared_inums;
+uint64_t *bound_private_inums;
+uint64_t *bound_shared_evnums;
+uint64_t *bound_private_evnums;
+int64_t private_slots_count;
+int64_t shared_slots_count;
+static int64_t private_slots_len;
+static int64_t shared_slots_len;
+
+
+void bound_event_constraints(int fieldname, struct memmod *mmod)
+{
+	setconstraint(FUZZER_CONSTRAINT_VECTOR, bound_shared_evnums, shared_slots_len, fieldname, mmod, FUZZER_CONSTRAINT_ACCMODE);
+	setconstraint(FUZZER_CONSTRAINT_VECTOR, bound_private_evnums, private_slots_len, fieldname, mmod, FUZZER_CONSTRAINT_ACCMODE);
+}
+
+void release_shared_slots(struct memmod *mmod, int slots, bool release)
+{
+
+	if ((slots < 0) || (slots > shared_slots_len)) {
+		return;
+	}
+
+	struct inputparameters inp;
+	int64_t ret;
+	struct sdei_intr_ctx intr_ctx;
+
+	if (release) {
+		for (int k = 0; k < slots; k++) {
+			uint64_t release_enum[1] = {bound_shared_evnums[shared_slots_len - 1 - k]};
+
+
+			setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+			inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+			ret = sdei_event_unregister(inp.x1);
+			print_return("unregister", ret);
+
+
+			setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+			inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SANITY_LEVEL_3);
+			ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+			print_return("release", ret);
+		}
+	}
+
+	for (int i = shared_slots_len; i > 0; i--) {
+		bound_shared_inums[i] = bound_shared_inums[i-slots];
+	}
+	for (int i = 0; i < slots; i++) {
+		bound_shared_inums[i] = 0;
+	}
+
+	for (int i = shared_slots_len; i > 0; i--) {
+		bound_shared_evnums[i] = bound_shared_evnums[i-slots];
+	}
+	for (int i = 0; i < slots; i++) {
+		bound_shared_evnums[i] = 0;
+	}
+	shared_slots_count = (shared_slots_count + slots < shared_slots_len ? shared_slots_count + slots : shared_slots_len);
+}
+
+void release_private_slots(struct memmod *mmod, int slots, bool release)
+{
+	if ((slots < 0) || (slots > private_slots_len)) {
+		return;
+	}
+
+	struct inputparameters inp;
+	int64_t ret;
+	struct sdei_intr_ctx intr_ctx;
+
+	if (release) {
+		for (int k = 0; k < slots; k++) {
+			uint64_t release_enum[1] = {bound_private_evnums[private_slots_len-1-k]};
+
+			setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+			inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+			ret = sdei_event_unregister(inp.x1);
+			print_return("unregister", ret);
+
+			setconstraint(FUZZER_CONSTRAINT_SVALUE, release_enum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+			inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SANITY_LEVEL_3);
+			ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+			print_return("release", ret);
+		}
+	}
+
+	for (int i = private_slots_len; i > 0; i--) {
+		bound_private_inums[i] = bound_private_inums[i-slots];
+	}
+	for (int i = 0; i < slots; i++) {
+		bound_private_inums[i] = 0;
+	}
+
+	for (int i = private_slots_len; i > 0; i--) {
+		bound_private_evnums[i] = bound_private_evnums[i-slots];
+	}
+	for (int i = 0; i < slots; i++) {
+		bound_private_evnums[i] = 0;
+	}
+
+	private_slots_count = (private_slots_count + slots < private_slots_len ? private_slots_count + slots : private_slots_len);
+}
+
+void initalize_interrupt_slots(struct memmod *mmod)
+{
+	uint64_t bind_slots[1] = {0};
+
+	setconstraint(FUZZER_CONSTRAINT_SVALUE, bind_slots, 1, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+	struct inputparameters inp = generate_args(SDEI_FEATURES_CALL, SMC_FUZZ_SANITY_LEVEL);
+	int64_t slots = sdei_features(inp.x1);
+
+	shared_slots_count = slots & 0xffffU;
+	private_slots_count = (slots >> 16U) & 0xfffU;
+	shared_slots_len = shared_slots_count;
+	private_slots_len = private_slots_count;
+	static uint64_t tmp[MAX_BIND_SLOTS];
+	static uint64_t tmp1[MAX_BIND_SLOTS];
+	static uint64_t tmp2[MAX_BIND_SLOTS];
+	static uint64_t tmp3[MAX_BIND_SLOTS];
+
+	bound_shared_inums = tmp;
+	bound_shared_evnums = tmp1;
+
+	bound_private_inums = tmp2;
+	bound_private_evnums = tmp3;
+	for (int i = 0; i < shared_slots_count; i++) {
+		bound_shared_inums[i] = 0;
+		bound_shared_evnums[i] = 0;
+	}
+	for (int i = 0; i < private_slots_count; i++) {
+		bound_private_inums[i] = 0;
+		bound_private_evnums[i] = 0;
+	}
+}
+
+void release_full_slots(struct inputparameters inp, struct memmod *mmod)
+{
+	if ((!shared_slots_count)) {
+			if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+				release_shared_slots(mmod, 1, true);
+			}
+		}
+
+	if ((!private_slots_count)) {
+		if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+			release_private_slots(mmod, 1, true);
+		}
+	}
+}
+
 /*
  * SDEI function called from fuzzer
  */
-void run_sdei_fuzz(int funcid)
+void run_sdei_fuzz(int funcid, struct memmod *mmod, bool inrange, int cntid)
 {
-	if (funcid == sdei_version_funcid) {
-		long long ret = sdei_version();
+	#ifdef SMC_FUZZER_DEBUG
+	if (inrange) {
+		printf("%d\n", cntid);
+	}
+	#endif
 
-		if (ret != MAKE_SDEI_VERSION(1, 0, 0)) {
-			tftf_testcase_printf("Unexpected SDEI version: 0x%llx\n",
-					     ret);
+	if (cntid == 0 && CONSTRAIN_EVENTS) {
+		initalize_interrupt_slots(mmod);
+	}
+
+	#ifdef SMC_FUZZER_DEBUG
+	if (CONSTRAIN_EVENTS) {
+		printf("Bound priv inums: %llu, %llu, %llu\n", bound_private_inums[0], bound_private_inums[1], bound_private_inums[2]);
+		printf("Bound priv evnums: %llu, %llu, %llu\n", bound_private_evnums[0], bound_private_evnums[1], bound_private_evnums[2]);
+		printf("Bound shared inums: %llu, %llu, %llu\n", bound_shared_inums[0], bound_shared_inums[1], bound_shared_inums[2]);
+		printf("Bound shared evnums: %llu, %llu, %llu\n", bound_shared_evnums[0], bound_shared_evnums[1], bound_shared_evnums[2]);
+		printf("Shared slots left: %lld\n", shared_slots_count);
+		printf("Private slots left: %lld\n\n", private_slots_count);
+	}
+	#endif
+	if (funcid == sdei_version_funcid) {
+		long long ret;
+
+		if (inrange) {
+			ret = sdei_version();
+
+			if (ret != MAKE_SDEI_VERSION(1, 0, 0)) {
+				tftf_testcase_printf("Unexpected SDEI version: 0x%llx\n", ret);
+			}
 		}
 	} else if (funcid == sdei_pe_unmask_funcid) {
-		tftf_test_sdei_noarg(sdei_pe_unmask, "sdei_pe_unmuask");
+		if (inrange) {
+			tftf_test_sdei_noarg(sdei_pe_unmask, "sdei_pe_unmask");
+		}
 	} else if (funcid == sdei_pe_mask_funcid) {
-		tftf_test_sdei_noarg(sdei_pe_mask, "sdei_pe_mask");
+		if (inrange) {
+			tftf_test_sdei_noarg(sdei_pe_mask, "sdei_pe_mask");
+		}
+	} else if (funcid == sdei_interrupt_bind_funcid) {
+		struct sdei_intr_ctx intr_ctx;
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, SPI_RANGE, 2,
+		SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+		if (INTR_ASSERT) {
+			setconstraint(FUZZER_CONSTRAINT_RANGE, PPI_RANGE, 2,
+			SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		}
+
+		struct inputparameters inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
+
+		release_full_slots(inp, mmod);
+
+		if (inrange) {
+			stbev = sdei_interrupt_bind(inp.x1, &intr_ctx);
+			if (stbev < 0) {
+				tftf_testcase_printf("sdei_interrupt_bind failed: 0x%llx %d\n", inp.x1, stbev);
+			} else if (CONSTRAIN_EVENTS) {
+				bool duplicate = false;
+
+				if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+
+					for (int i = 0; i < shared_slots_len; i++) {
+						if (bound_shared_inums[i] == inp.x1) {
+							duplicate = true;
+						}
+					}
+					if (!duplicate) {
+						shared_slots_count--;
+						bound_shared_inums[shared_slots_count] = inp.x1;
+						bound_shared_evnums[shared_slots_count] = stbev;
+					}
+
+				} else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+					for (int i = 0; i < private_slots_len; i++) {
+						if (bound_private_inums[i] == inp.x1) {
+							duplicate = true;
+						}
+					}
+					if (!duplicate) {
+						private_slots_count--;
+						bound_private_inums[private_slots_count] = inp.x1;
+						bound_private_evnums[private_slots_count] = stbev;
+					}
+				}
+			}
+
+			#ifdef SMC_FUZZER_DEBUG
+			printf("stbev is %d and interrupt number is %lld\n", stbev, inp.x1);
+			#endif
+		}
 	} else if (funcid == sdei_event_status_funcid) {
-		tftf_test_sdei_singlearg((int64_t (*)(uint64_t))sdei_event_status,
-		"sdei_event_status");
+		struct inputparameters inp;
+
+		if (CONSTRAIN_EVENTS) {
+			bound_event_constraints(SDEI_EVENT_STATUS_CALL_ARG1_BEV, mmod);
+			set_event_constraints(SDEI_EVENT_STATUS_CALL_ARG1_BEV, mmod);
+		}
+		inp = generate_args(SDEI_EVENT_STATUS_CALL, SMC_FUZZ_SANITY_LEVEL);
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_status(inp.x1);
+			if (ret < 0) {
+
+				tftf_testcase_printf("sdei_event_status failed: 0x%llx %d\n", ret, stbev);
+			} else {
+
+			}
+		}
+
 	} else if (funcid == sdei_event_signal_funcid) {
-		tftf_test_sdei_singlearg(sdei_event_signal, "sdei_event_signal");
+
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1,
+		SDEI_EVENT_SIGNAL_CALL_ARG2_PE, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		struct inputparameters inp = generate_args(SDEI_EVENT_SIGNAL_CALL, SMC_FUZZ_SANITY_LEVEL);
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_signal(inp.x2);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_signal failed: %lld\n", ret);
+			}
+		}
 	} else if (funcid == sdei_private_reset_funcid) {
-		tftf_test_sdei_noarg(sdei_private_reset, "sdei_private_reset");
+		if (inrange) {
+			tftf_test_sdei_noarg(sdei_private_reset, "sdei_private_reset");
+		}
 	} else if (funcid == sdei_shared_reset_funcid) {
-		tftf_test_sdei_noarg(sdei_shared_reset, "sdei_shared_reset");
+		int64_t ret = -1;
+
+		if (inrange) {
+			ret = tftf_test_sdei_noarg(sdei_shared_reset, "sdei_shared_reset");
+		}
+		if (ret == 0) {
+			release_shared_slots(mmod, private_slots_len, false);
+			release_private_slots(mmod, shared_slots_len, false);
+		}
+
+	} else if (funcid == sdei_event_register_funcid) {
+
+		if (CONSTRAIN_EVENTS) {
+			set_event_constraints(SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod);
+			bound_event_constraints(SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod);
+		}
+
+		register_handler();
+
+		uint64_t routing_modes[2] = {SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE};
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, routing_modes, 2, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, EV_COOKIE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG3_ARG, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+		struct inputparameters inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_register(inp.x1, (int (*)(int,  uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_register failed: 0x%llx\n", ret);
+			}
+		}
+
+
+	} else if (funcid == sdei_event_enable_funcid) {
+		struct inputparameters inp;
+
+
+		if (CONSTRAIN_EVENTS) {
+			set_event_constraints(SDEI_EVENT_ENABLE_CALL_ARG1_ENUM, mmod);
+			bound_event_constraints(SDEI_EVENT_ENABLE_CALL_ARG1_ENUM, mmod);
+		}
+
+		inp = generate_args(SDEI_EVENT_ENABLE_CALL, SMC_FUZZ_SANITY_LEVEL);
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_enable(inp.x1);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_enable failed: 0x%llx\n", ret);
+			}
+		}
+
+	} else if (funcid == sdei_event_disable_funcid) {
+		struct inputparameters inp;
+
+		if (CONSTRAIN_EVENTS) {
+			set_event_constraints(SDEI_EVENT_DISABLE_CALL_ARG1_ENUM, mmod);
+			bound_event_constraints(SDEI_EVENT_DISABLE_CALL_ARG1_ENUM, mmod);
+		}
+
+		inp = generate_args(SDEI_EVENT_DISABLE_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_disable(inp.x1);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_disable failed: 0x%llx\n", ret);
+			}
+		}
+
+	} else if (funcid == sdei_features_funcid) {
+		uint64_t feature_values[2] = {0, 1};
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, feature_values, 2, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		struct inputparameters inp = generate_args(SDEI_FEATURES_CALL, SANITY_LEVEL_3);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_features(inp.x1);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_features failed: 0x%llx\n", ret);
+			} else if ((ret >> 32) == 0) {
+				#ifdef SMC_FUZZER_DEBUG
+				printf("SUCCESS: sdei_features expected [63:32]\n");
+				printf("private event slots: %llx\n", (ret & 0xffffU));
+				printf("shared event slots: %llx\n", ((ret >> 16U) & 0xfffU));
+				#endif
+			}
+		}
+	} else if (funcid == sdei_event_unregister_funcid) {
+		struct inputparameters inp;
+
+		if (CONSTRAIN_EVENTS) {
+			set_event_constraints(SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod);
+			bound_event_constraints(SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod);
+		}
+
+		inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_unregister(inp.x1);
+
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_unregister failed: 0x%llx\n", ret);
+			}
+		}
+
+	} else if (funcid == sdei_event_context_funcid) {
+
+		uint64_t register_range[2] = {0, 17};
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, register_range, 2, SDEI_EVENT_CONTEXT_CALL_ARG1_PARAM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		struct inputparameters inp = generate_args(SDEI_EVENT_CONTEXT_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_context(inp.x1);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_context failed: 0x%llx\n", ret);
+			}
+		}
+
+	} else if (funcid == sdei_event_complete_funcid) {
+
+		uint64_t status_codes[2] = {0, 1};
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, status_codes, 2, SDEI_EVENT_COMPLETE_CALL_ARG1_STAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+		struct inputparameters inp = generate_args(SDEI_EVENT_COMPLETE_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_complete(inp.x1);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_complete failed: 0x%llx\n", ret);
+			}
+		}
+
+	} else if (funcid == sdei_event_complete_and_resume_funcid) {
+		struct inputparameters inp = generate_args(SDEI_EVENT_COMPLETE_AND_RESUME_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_complete_and_resume(inp.x1);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_complete_and_resume failed: 0x%llx\n", ret);
+			}
+		}
+
+	} else if (funcid == sdei_event_get_info_funcid) {
+		struct inputparameters inp;
+		uint64_t info_values[2] = {0, 4};
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, info_values, 2, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+
+		if (CONSTRAIN_EVENTS) {
+			set_event_constraints(SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod);
+			bound_event_constraints(SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod);
+		}
+
+		inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_get_info(inp.x1, inp.x2);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_get_info failed: 0x%llx\n", ret);
+			}
+		}
+	} else if (funcid == sdei_event_routing_set_funcid) {
+		uint64_t routing_modes[2] = {SDEI_REGF_RM_ANY, SDEI_REGF_RM_PE};
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, routing_modes, 2, SDEI_EVENT_ROUTING_SET_CALL_ARG2_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG3_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		struct inputparameters inp;
+
+		if (CONSTRAIN_EVENTS) {
+			set_event_constraints(SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod);
+			bound_event_constraints(SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod);
+		}
+
+		inp = generate_args(SDEI_EVENT_ROUTING_SET_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_event_routing_set(inp.x1, inp.x2);
+			if (ret < 0) {
+				tftf_testcase_printf("sdei_event_routing_set failed: 0x%llx\n", ret);
+			}
+		}
+
+	} else if (funcid == sdei_interrupt_release_funcid) {
+		struct sdei_intr_ctx intr_ctx;
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, PPI_RANGE, 2,
+		SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_RANGE, SPI_RANGE, 2,
+		SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+
+		struct inputparameters inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		int64_t ret;
+
+		if (inrange) {
+			ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+			if (ret < 0) {
+
+				tftf_testcase_printf("sdei_interrupt_release failed: 0x%llx\n", ret);
+			} else {
+				if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+					release_shared_slots(mmod, 1, false);
+				} else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+					release_private_slots(mmod, 1, false);
+				}
+			}
+		}
+
+	} else if (funcid == sdei_routing_set_coverage_funcid) {
+		int64_t ret;
+		struct inputparameters inp;
+
+		uint64_t bind_slots[1] = {0};
+
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, bind_slots, 1, SDEI_FEATURES_CALL_ARG1_FEAT, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		inp = generate_args(SDEI_FEATURES_CALL, SMC_FUZZ_SANITY_LEVEL);
+		int64_t slots = sdei_features(inp.x1);
+
+		print_return("features", slots);
+
+		// bind shared interrupt to create shared event
+		struct sdei_intr_ctx intr_ctx;
+		uint64_t inum_range[2] = { MIN_SPI_ID, U(255) };
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, inum_range, 2, SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
+
+		release_full_slots(inp, mmod);
+
+
+		ret = sdei_interrupt_bind(inp.x1, &intr_ctx);
+		if (ret < 0) {
+			return;
+		}
+
+		// register shared event
+		uint64_t evnum[1] = {ret};
+
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, ANY_ROUTING, 1, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_register(inp.x1, (int (*)(int,  uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
+		print_return("register", ret);
+
+		uint64_t signal_info[1] = {0};
+
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, signal_info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_get_info(inp.x1, inp.x2);
+		print_return("get_info", ret);
+
+
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, ANY_ROUTING, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG2_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_ROUTING_SET_CALL_ARG3_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		inp = generate_args(SDEI_EVENT_ROUTING_SET_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_routing_set(inp.x1, inp.x2);
+		print_return("routing_set", ret);
+
+		// unregister
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_unregister(inp.x1);
+		print_return("unregister", ret);
+
+		// release
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
+		sdei_interrupt_release(inp.x1, &intr_ctx);
+		print_return("release", ret);
+
+		if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+			release_shared_slots(mmod, 1, false);
+		} else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+			release_private_slots(mmod, 1, false);
+		}
+
+	} else if (funcid == sdei_event_get_info_coverage_funcid) {
+		int64_t ret;
+		struct inputparameters inp;
+		uint64_t info[1];
+
+		// bind shared interrupt to create shared event
+		struct sdei_intr_ctx intr_ctx;
+		uint64_t inum_range[2] = { MIN_SPI_ID, U(255)};
+
+		setconstraint(FUZZER_CONSTRAINT_RANGE, inum_range, 2, SDEI_INTERRUPT_BIND_CALL_ARG1_INUM, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		inp = generate_args(SDEI_INTERRUPT_BIND_CALL, SANITY_LEVEL_3);
+
+		release_full_slots(inp, mmod);
+
+		ret = sdei_interrupt_bind(inp.x1, &intr_ctx);
+
+		if (ret < 0) {
+			return;
+		}
+
+		uint64_t evnum[1] = {ret};
+
+		// event type
+		info[0] = 0;
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_GET_INFO_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_get_info(inp.x1, inp.x2);
+		print_return("get info", ret);
+
+		// event signalable
+		info[0] = 1;
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_get_info(inp.x1, inp.x2);
+		print_return("get info", ret);
+
+		// event priority
+		printf("priority\n");
+		info[0] = 2;
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_get_info(inp.x1, inp.x2);
+		print_return("get info", ret);
+
+		// register event
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_REGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, HANDLER_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG2_ADDR, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_SVALUE, 1, SDEI_EVENT_REGISTER_CALL_ARG5_AFF, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, PE_ROUTING, 1, SDEI_EVENT_REGISTER_CALL_ARG4_ROUTING, mmod, FUZZER_CONSTRAINT_ACCMODE);
+		inp = generate_args(SDEI_EVENT_REGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_register(inp.x1, (int (*)(int,  uint64_t))(uintptr_t)inp.x2, inp.x3, inp.x4, inp.x5);
+		print_return("register", ret);
+
+		// event routing mode
+		info[0] = 3;
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_get_info(inp.x1, inp.x2);
+		print_return("get info", ret);
+
+		// event affinity
+		info[0] = 4;
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, info, 1, SDEI_EVENT_GET_INFO_CALL_ARG2_INFO, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_EVENT_GET_INFO_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_get_info(inp.x1, inp.x2);
+		print_return("get info", ret);
+
+		// unregister
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_EVENT_UNREGISTER_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_EVENT_UNREGISTER_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_event_unregister(inp.x1);
+		print_return("unregister", ret);
+
+		// release
+		setconstraint(FUZZER_CONSTRAINT_SVALUE, evnum, 1, SDEI_INTERRUPT_RELEASE_CALL_ARG1_ENUM, mmod, FUZZER_CONSTRAINT_EXCMODE);
+		inp = generate_args(SDEI_INTERRUPT_RELEASE_CALL, SMC_FUZZ_SANITY_LEVEL);
+		ret = sdei_interrupt_release(inp.x1, &intr_ctx);
+		print_return("release", ret);
+
+		if (inp.x1 >= MIN_SPI_ID && inp.x1 <= MAX_SPI_ID) {
+			release_shared_slots(mmod, 1, false);
+		} else if (inp.x1 >= MIN_PPI_ID && inp.x1 <= MAX_PPI_ID) {
+			release_private_slots(mmod, 1, false);
+		}
 	}
 }
diff --git a/smc_fuzz/src/vendor_fuzz_helper.c b/smc_fuzz/src/vendor_fuzz_helper.c
new file mode 100644
index 0000000..2de10b4
--- /dev/null
+++ b/smc_fuzz/src/vendor_fuzz_helper.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arg_struct_def.h>
+#include "constraint.h"
+#include <fuzz_names.h>
+#include <vendor_fuzz_helper.h>
+
+#include <lib/tftf_lib.h>
+#include <runtime_services/ven_el3_svc.h>
+#include <smccc.h>
+#include <uuid_utils.h>
+
+/*
+ * Vendor-Specific EL3 UUID as returned by the implementation in the Trusted
+ * Firmware.
+ */
+static const uuid_t armtf_ven_el3_svc_uuid = {
+	{0xb6, 0x01, 0x1d, 0xca},
+	{0x57, 0xc4},
+	{0x40, 0x7e},
+	0x83, 0xf0,
+	{0xa7, 0xed, 0xda, 0xf0, 0xdf, 0x6c}
+};
+
+void inputparameters_to_ven_el3_args(struct inputparameters inp, smc_args *args)
+{
+	args->arg1 = inp.x1;
+	args->arg2 = inp.x2;
+	args->arg3 = inp.x3;
+	args->arg4 = inp.x4;
+	args->arg5 = inp.x5;
+	args->arg6 = inp.x6;
+	args->arg7 = inp.x7;
+}
+
+void run_ven_el3_fuzz(int funcid, struct memmod *mmod)
+{
+	if (funcid == ven_el3_svc_uuid_funcid) {
+
+		smc_args ven_el3_svc_args;
+		smc_ret_values ret;
+		uuid_t ven_el3_svc_uuid;
+		char uuid_str[UUID_STR_SIZE];
+
+		/* Standard Service Call UID */
+		ven_el3_svc_args.fid = VEN_EL3_SVC_UID;
+		struct inputparameters inp = generate_args(VEN_EL3_SVC_UUID_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		inputparameters_to_ven_el3_args(inp, &ven_el3_svc_args);
+
+		ret = tftf_smc(&ven_el3_svc_args);
+
+		make_uuid_from_4words(&ven_el3_svc_uuid,
+		ret.ret0, ret.ret1, ret.ret2, ret.ret3);
+
+		if (!uuid_equal(&ven_el3_svc_uuid, &armtf_ven_el3_svc_uuid)) {
+			tftf_testcase_printf("Wrong UUID: expected %s,\n",
+			uuid_to_str(&armtf_ven_el3_svc_uuid, uuid_str));
+			tftf_testcase_printf("		 got %s\n",
+			uuid_to_str(&ven_el3_svc_uuid, uuid_str));
+		} else {
+		#ifdef SMC_FUZZER_DEBUG
+			printf("Correct UUID: got %s,\n",
+			uuid_to_str(&ven_el3_svc_uuid, uuid_str));
+		#endif
+		}
+	} else if (funcid == ven_el3_svc_count_funcid) {
+		smc_args ven_el3_svc_args;
+		smc_ret_values ret;
+
+		ven_el3_svc_args.fid = VEN_EL3_SVC_UID + 1;
+		struct inputparameters inp = generate_args(VEN_EL3_SVC_COUNT_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		inputparameters_to_ven_el3_args(inp, &ven_el3_svc_args);
+
+		ret = tftf_smc(&ven_el3_svc_args);
+
+		if (ret.ret0 != SMC_UNKNOWN) {
+			tftf_testcase_printf("Querying Vendor-Specific el3 service call count"
+			" which is reserved failed\n");
+		} else {
+		#ifdef SMC_FUZZER_DEBUG
+			printf("Querying Vendor-Specific el3 service call count"
+			" got %ld\n", ret.ret0);
+		#endif
+	}
+	} else if (funcid == ven_el3_svc_version_funcid) {
+		smc_args ven_el3_svc_args;
+		smc_ret_values ret;
+
+		ven_el3_svc_args.fid = VEN_EL3_SVC_VERSION;
+		struct inputparameters inp = generate_args(VEN_EL3_SVC_UUID_CALL, SMC_FUZZ_SANITY_LEVEL);
+
+		inputparameters_to_ven_el3_args(inp, &ven_el3_svc_args);
+
+		ret = tftf_smc(&ven_el3_svc_args);
+
+		if ((ret.ret0 != VEN_EL3_SVC_VERSION_MAJOR) ||
+		(ret.ret1 != VEN_EL3_SVC_VERSION_MINOR)) {
+			tftf_testcase_printf(
+			"Vendor Specific El3 service reported wrong version: expected {%u.%u}, got {%llu.%llu}\n",
+			VEN_EL3_SVC_VERSION_MAJOR, VEN_EL3_SVC_VERSION_MINOR,
+			(unsigned long long)ret.ret0,
+			(unsigned long long)ret.ret1);
+		}
+	}
+}
diff --git a/smc_fuzz/vendor_smc_calls.txt b/smc_fuzz/vendor_smc_calls.txt
new file mode 100644
index 0000000..a5251ac
--- /dev/null
+++ b/smc_fuzz/vendor_smc_calls.txt
@@ -0,0 +1,12 @@
+#
+# Copyright (c) 2024 Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+smc: VEN_EL3_SVC_UUID_CALL
+        arg1=0
+smc: VEN_EL3_SVC_COUNT_CALL
+        arg1=0
+smc: VEN_EL3_SVC_VERSION_CALL
+        arg1=0
diff --git a/spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts b/spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts
index 1c01a9f..0f6c23d 100644
--- a/spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus-secondary.dts
@@ -24,7 +24,7 @@
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7100000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <1>;
 	messaging-method = <3>; /* Direct messaging only */
diff --git a/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts b/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts
index 946301d..d1ffa2f 100644
--- a/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts
+++ b/spm/cactus/plat/arm/fvp/fdts/cactus-tertiary.dts
@@ -24,7 +24,7 @@
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7200000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <2>;
 	notification-support;
diff --git a/spm/cactus/plat/arm/tc/fdts/cactus-secondary.dts b/spm/cactus/plat/arm/tc/fdts/cactus-secondary.dts
index 839fb82..aa48e29 100644
--- a/spm/cactus/plat/arm/tc/fdts/cactus-secondary.dts
+++ b/spm/cactus/plat/arm/tc/fdts/cactus-secondary.dts
@@ -22,7 +22,7 @@
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0xfe100000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <1>;
 	messaging-method = <3>; /* Direct messaging only */
diff --git a/spm/cactus/plat/arm/tc/fdts/cactus-tertiary.dts b/spm/cactus/plat/arm/tc/fdts/cactus-tertiary.dts
index 1db2c1e..145be36 100644
--- a/spm/cactus/plat/arm/tc/fdts/cactus-tertiary.dts
+++ b/spm/cactus/plat/arm/tc/fdts/cactus-tertiary.dts
@@ -22,7 +22,7 @@
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0xfe200000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	xlat-granule = <0>; /* 4KiB */
 	boot-order = <2>;
 	messaging-method = <3>; /* Direct messaging only */
diff --git a/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel0.dts b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel0.dts
index 7bf7d91..f885c5f 100644
--- a/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel0.dts
+++ b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel0.dts
@@ -21,7 +21,7 @@
 	exception-level = <1>; /* S-EL0 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7600000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	boot-order = <3>;
 	messaging-method = <3>; /* Direct messaging only */
 
diff --git a/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel1.dts b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel1.dts
index a4d26ef..1dfca01 100644
--- a/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel1.dts
+++ b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel1.dts
@@ -22,7 +22,7 @@
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7600000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	boot-order = <3>;
 	messaging-method = <3>; /* Direct messaging only */
 	/* Non-secure interrupts are signaled by default. */
diff --git a/spm/ivy/app/plat/arm/tc/fdts/ivy-sel0.dts b/spm/ivy/app/plat/arm/tc/fdts/ivy-sel0.dts
index 7d333a6..1dd3b61 100644
--- a/spm/ivy/app/plat/arm/tc/fdts/ivy-sel0.dts
+++ b/spm/ivy/app/plat/arm/tc/fdts/ivy-sel0.dts
@@ -20,7 +20,7 @@
 	exception-level = <1>; /* S-EL0 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0xfe280000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	boot-order = <3>;
 	messaging-method = <3>; /* Direct messaging only */
 
diff --git a/spm/ivy/app/plat/arm/tc/fdts/ivy-sel1.dts b/spm/ivy/app/plat/arm/tc/fdts/ivy-sel1.dts
index 6503e15..bcb3162 100644
--- a/spm/ivy/app/plat/arm/tc/fdts/ivy-sel1.dts
+++ b/spm/ivy/app/plat/arm/tc/fdts/ivy-sel1.dts
@@ -21,7 +21,7 @@
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0xfe280000>;
-	entrypoint-offset = <0x00004000>;
+	entrypoint-offset = <0x00002000>;
 	boot-order = <3>;
 	messaging-method = <3>; /* Direct messaging only */
 
diff --git a/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_4.c b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_4.c
new file mode 100644
index 0000000..98872a1
--- /dev/null
+++ b/tftf/tests/runtime_services/arm_arch_svc/smccc_arch_workaround_4.c
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <arm_arch_svc.h>
+#include <debug.h>
+#include <plat_topology.h>
+#include <power_management.h>
+#include <psci.h>
+#include <smccc.h>
+#include <string.h>
+#include <tftf_lib.h>
+
+#ifdef __aarch64__
+#define CORTEX_X2_MIDR		0x410FD480
+#define CORTEX_X3_MIDR		0x410FD4E0
+#define CORTEX_X4_MIDR		0x410FD821
+#define CORTEX_X925_MIDR	0x410FD850
+#define NEOVERSE_V2_MIDR	0x410FD4F0
+#define NEOVERSE_V3_MIDR	0x410FD840
+
+static int cortex_x2_test(void);
+static int cortex_x3_test(void);
+static int cortex_x4_test(void);
+static int cortex_x925_test(void);
+static int neoverse_v2_test(void);
+static int neoverse_v3_test(void);
+
+struct ent {
+	unsigned int midr;
+	int (*smc_ret)(void);
+};
+
+struct ent negative_entries[] = {
+	{ .midr = CORTEX_X2_MIDR, .smc_ret = cortex_x2_test }
+};
+
+struct ent positive_entries[] = {
+	{ .midr = CORTEX_X3_MIDR, .smc_ret = cortex_x3_test },
+	{ .midr = CORTEX_X4_MIDR, .smc_ret = cortex_x4_test },
+	{ .midr = CORTEX_X925_MIDR, .smc_ret = cortex_x925_test },
+	{ .midr = NEOVERSE_V2_MIDR, .smc_ret = neoverse_v2_test},
+	{ .midr = NEOVERSE_V3_MIDR, .smc_ret = neoverse_v3_test},
+};
+
+static int cortex_x2_test(void)
+{
+	return -1;
+}
+static int cortex_x3_test(void)
+{
+	return 0;
+}
+
+static int cortex_x4_test(void)
+{
+	return 0;
+}
+
+static int cortex_x925_test(void)
+{
+	return 0;
+}
+
+static int neoverse_v2_test(void)
+{
+	return 0;
+}
+
+static int neoverse_v3_test(void)
+{
+	return 0;
+}
+
+static test_result_t test_smccc_entrypoint(void)
+{
+	smc_args args;
+	smc_ret_values ret;
+	int32_t expected_ver;
+	unsigned int my_midr, midr_mask;
+	size_t i;
+
+	/* Check if SMCCC version is at least v1.1 */
+	expected_ver = MAKE_SMCCC_VERSION(1, 1);
+	memset(&args, 0, sizeof(args));
+	args.fid = SMCCC_VERSION;
+	ret = tftf_smc(&args);
+	if ((int32_t)ret.ret0 < expected_ver) {
+		tftf_testcase_printf("Unexpected SMCCC version: 0x%x\n",
+		       (int)ret.ret0);
+		return TEST_RESULT_SKIPPED;
+	}
+
+	/* Check if SMCCC_ARCH_WORKAROUND_4 is required or not */
+	memset(&args, 0, sizeof(args));
+	args.fid = SMCCC_ARCH_FEATURES;
+	args.arg1 = SMCCC_ARCH_WORKAROUND_4;
+	ret = tftf_smc(&args);
+
+	/*
+	 * Negetive test. Checks if select non-affected cores
+	 * return -1 (Not supported)
+	 */
+	my_midr = (unsigned int)read_midr_el1();
+	midr_mask = (MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | (MIDR_PN_MASK << MIDR_PN_SHIFT);
+	for (i = 0; i < ARRAY_SIZE(negative_entries); i++) {
+		struct ent *entp = &negative_entries[i];
+		if ((my_midr & midr_mask) == (entp->midr & midr_mask)) {
+			if (entp->smc_ret() != -1) {
+				return TEST_RESULT_FAIL;
+			}
+			break;
+		}
+	}
+
+	if ((int)ret.ret0 == -1) {
+		tftf_testcase_printf("SMCCC_ARCH_WORKAROUND_4 is not implemented\n");
+		return TEST_RESULT_SKIPPED;
+	}
+
+	/* Check if the SMC return value matches our expectations */
+	for (i = 0; i < ARRAY_SIZE(positive_entries); i++) {
+		struct ent *entp = &positive_entries[i];
+		if ((my_midr & midr_mask) == (entp->midr & midr_mask)) {
+			if (entp->smc_ret() != 0) {
+				return TEST_RESULT_FAIL;
+			}
+			break;
+		}
+	}
+
+	if ((i == ARRAY_SIZE(positive_entries)) && ((int)ret.ret0) == 0) {
+		tftf_testcase_printf("TFTF workaround table out of sync with TF-A\n");
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Invoke the workaround to make sure nothing nasty happens */
+	memset(&args, 0, sizeof(args));
+	args.fid = SMCCC_ARCH_WORKAROUND_4;
+	tftf_smc(&args);
+	return TEST_RESULT_SUCCESS;
+}
+
+test_result_t test_smccc_arch_workaround_4(void)
+{
+	u_register_t lead_mpid, target_mpid;
+	int cpu_node, ret;
+
+	lead_mpid = read_mpidr_el1() & MPID_MASK;
+
+	/* Power on all the non-lead cores. */
+	for_each_cpu(cpu_node) {
+		target_mpid = tftf_get_mpidr_from_node(cpu_node);
+		if (lead_mpid == target_mpid) {
+			continue;
+		}
+		ret = tftf_cpu_on(target_mpid,
+		    (uintptr_t)test_smccc_entrypoint, 0);
+		if (ret != PSCI_E_SUCCESS) {
+			ERROR("CPU ON failed for 0x%llx\n",
+			    (unsigned long long)target_mpid);
+			return TEST_RESULT_FAIL;
+		}
+		/*
+		 * Wait for test_smccc_entrypoint to return
+		 * and the CPU to power down
+		 */
+		while (tftf_psci_affinity_info(target_mpid, MPIDR_AFFLVL0) !=
+			PSCI_STATE_OFF) {
+			continue;
+		}
+	}
+
+	return test_smccc_entrypoint();
+}
+#else
+test_result_t test_smccc_arch_workaround_4(void)
+{
+	INFO("%s skipped on AArch32\n", __func__);
+	return TEST_RESULT_SKIPPED;
+}
+#endif
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c b/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c
index ceca36d..31965be 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,8 +15,6 @@
 #include <host_realm_pmu.h>
 #include <platform.h>
 
-#define MAX_COUNTERS		31
-
 /* PMCCFILTR_EL0 mask */
 #define PMCCFILTR_EL0_MASK (	  \
 	PMCCFILTR_EL0_P_BIT	| \
@@ -67,9 +65,9 @@
 	CHECK_PMEV_REG(n, pmevtyper);	\
 }
 
-#define WRITE_PMREG(reg, mask) {		\
+#define WRITE_PMREG(reg, mask) {	\
 	pmu_ptr->reg = rand64() & mask;	\
-	write_##reg(pmu_ptr->reg);		\
+	write_##reg(pmu_ptr->reg);	\
 }
 
 #define CHECK_PMREG(reg) {					\
@@ -82,32 +80,10 @@
 	}							\
 }
 
-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)
+void host_set_pmu_state(struct pmu_registers *pmu_ptr)
 {
-	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_PMU_CNT;
 	unsigned long val;
+	unsigned int num_cnts = GET_PMU_CNT;
 
 	val = read_pmcr_el0() | PMCR_EL0_DP_BIT;
 	pmu_ptr->pmcr_el0 = val;
@@ -127,11 +103,15 @@
 	pmu_ptr->pmintenset_el1 = 0UL;
 	write_pmintenclr_el1(PMU_CLEAR_ALL);
 
+	/* Seed the random number generator */
+	srand((unsigned int)read_cntpct_el0());
+
 	WRITE_PMREG(pmccntr_el0, UINT64_MAX);
 	WRITE_PMREG(pmccfiltr_el0, PMCCFILTR_EL0_MASK);
 
 	pmu_ptr->pmuserenr_el0 = read_pmuserenr_el0();
 
+	/* Check number of event counters implemented */
 	if (num_cnts != 0U) {
 		switch (--num_cnts) {
 		WRITE_PMEV_REGS(30);
@@ -168,25 +148,30 @@
 		WRITE_PMEV_REGS(0);
 		}
 
-		/* Generate a random number between 0 and num_cnts */
+		/* Seed the random number generator */
+		srand((unsigned int)read_cntpct_el0());
+
+		/*
+		 * Select a random number of event counter
+		 * between 0 and num_cnts - 1
+		 */
 		val = rand() % ++num_cnts;
 	} else {
-		val = 0UL;
+		/* Select the cycle counter, PMCCNTR_EL0 */
+		val = 31UL;
 	}
 
 	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)
+bool host_check_pmu_state(struct pmu_registers *pmu_ptr)
 {
-	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_PMU_CNT;
 	unsigned long val, read_val;
+	unsigned int num_cnts = GET_PMU_CNT;
+
+	INFO("Check PMU core_pos=%u num_cnts=%u\n",
+			platform_get_core_pos(read_mpidr_el1()), num_cnts);
 
 	CHECK_PMREG(pmcr_el0);
 	CHECK_PMREG(pmcntenset_el0);
@@ -196,9 +181,8 @@
 	CHECK_PMREG(pmccfiltr_el0);
 	CHECK_PMREG(pmuserenr_el0);
 	CHECK_PMREG(pmselr_el0);
-	CHECK_PMREG(pmxevcntr_el0);
-	CHECK_PMREG(pmxevtyper_el0);
 
+	/* Check number of event counters implemented */
 	if (num_cnts != 0UL) {
 		switch (--num_cnts) {
 		CHECK_PMEV_REGS(30);
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 3a4121b..e73fe0d 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-2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -45,14 +45,14 @@
  * The function handler to print the Realm logged buffer,
  * executed by the secondary core
  */
-void realm_print_handler(struct realm *realm_ptr, unsigned int rec_num)
+void realm_print_handler(struct realm *realm_ptr, unsigned int plane_num, unsigned int rec_num)
 {
 	size_t str_len = 0UL;
 	host_shared_data_t *host_shared_data;
 	char *log_buffer;
 
 	assert(realm_ptr != NULL);
-	host_shared_data = host_get_shared_structure(realm_ptr, rec_num);
+	host_shared_data = host_get_shared_structure(realm_ptr, plane_num, rec_num);
 	log_buffer = (char *)host_shared_data->log_buffer;
 	str_len = strlen((const char *)log_buffer);
 
@@ -63,26 +63,12 @@
 	if (str_len != 0UL) {
 		/* Avoid memory overflow */
 		log_buffer[MAX_BUF_SIZE - 1] = 0U;
-		mp_printf("[VMID %u][Rec %u]: %s", realm_ptr->vmid, rec_num, log_buffer);
+		mp_printf("[VMID %u][Rec %u]: %s", plane_num == 0U ? realm_ptr->vmid :
+				realm_ptr->aux_vmid[plane_num - 1U], rec_num, log_buffer);
 		(void)memset((char *)log_buffer, 0, MAX_BUF_SIZE);
 	}
 }
 
-/*
- * 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.
- */
-static void host_init_realm_print_buffer(struct realm *realm_ptr)
-{
-	host_shared_data_t *host_shared_data;
-
-	for (unsigned int i = 0U; i < realm_ptr->rec_count; i++) {
-		host_shared_data = host_get_shared_structure(realm_ptr, i);
-		(void)memset((char *)host_shared_data, 0, sizeof(host_shared_data_t));
-	}
-}
-
 static bool host_enter_realm(struct realm *realm_ptr,
 			     u_register_t *exit_reason,
 			     unsigned int *host_call_result,
@@ -129,7 +115,6 @@
 	memset((void *)ns_shared_mem_adr, 0, (size_t)NS_REALM_SHARED_MEM_SIZE);
 	realm_ptr->host_shared_data = ns_shared_mem_adr;
 	realm_ptr->shared_mem_created = true;
-	host_init_realm_print_buffer(realm_ptr);
 
 	return true;
 }
@@ -194,14 +179,9 @@
 		realm_ptr->rmm_feat_reg0 &= ~RMI_FEATURE_REGISTER_0_PMU_EN;
 		realm_ptr->pmu_num_ctrs = 0U;
 	} else {
-		value = EXTRACT(FEATURE_PMU_NUM_CTRS, feature_flag);
-		if (value != -1) {
-			realm_ptr->pmu_num_ctrs = (unsigned int)value;
-		} else {
-			realm_ptr->pmu_num_ctrs =
-				EXTRACT(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS,
-					realm_ptr->rmm_feat_reg0);
-		}
+		/* Requested number of event counters */
+		realm_ptr->pmu_num_ctrs = EXTRACT(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS,
+							feature_flag);
 	}
 
 	/* Disable SVE if not required */
@@ -209,11 +189,12 @@
 		realm_ptr->rmm_feat_reg0 &= ~RMI_FEATURE_REGISTER_0_SVE_EN;
 		realm_ptr->sve_vl = 0U;
 	} else {
-		realm_ptr->sve_vl = EXTRACT(FEATURE_SVE_VL, feature_flag);
+		realm_ptr->sve_vl = EXTRACT(RMI_FEATURE_REGISTER_0_SVE_VL,
+						feature_flag);
 	}
 
 	/* Requested number of breakpoints */
-	value = EXTRACT(FEATURE_NUM_BPS, feature_flag);
+	value = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_BPS, feature_flag);
 	if (value != 0) {
 		realm_ptr->num_bps = (unsigned int)value;
 	} else {
@@ -222,7 +203,7 @@
 	}
 
 	/* Requested number of watchpoints */
-	value = EXTRACT(FEATURE_NUM_WPS, feature_flag);
+	value = EXTRACT(RMI_FEATURE_REGISTER_0_NUM_WPS, feature_flag);
 	if (value != 0) {
 		realm_ptr->num_wps = (unsigned int)value;
 	} else {
@@ -433,12 +414,11 @@
 		ERROR("Invalid Rec Count\n");
 		return false;
 	}
-	host_shared_data_set_realm_cmd(realm_ptr, cmd, rec_num);
+	host_shared_data_set_realm_cmd(realm_ptr, cmd, PRIMARY_PLANE_ID, rec_num);
 	if (!host_enter_realm(realm_ptr, &realm_exit_reason, &host_call_result, rec_num)) {
 		return false;
 	}
 
-
 	if (test_exit_reason == realm_exit_reason) {
 		if (realm_exit_reason != RMI_EXIT_HOST_CALL) {
 			return true;
@@ -500,3 +480,19 @@
 		tftf_send_sgi(sgi, core_pos);
 	}
 }
+
+/*
+ * Set Args for Aux Plane Enter
+ * Realm helpers copy the same realm image for each plane
+ * Entrypoint for aux plane = realm.par_base + (plane_num * realm..par_size)
+ */
+void host_realm_set_aux_plane_args(struct realm *realm_ptr,
+		unsigned int plane_num)
+{
+	/* Plane Index */
+	host_shared_data_set_host_val(realm_ptr, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, plane_num);
+
+	/* Plane entrypoint */
+	host_shared_data_set_host_val(realm_ptr, PRIMARY_PLANE_ID, 0U, HOST_ARG2_INDEX,
+			realm_ptr->par_base + (plane_num * realm_ptr->par_size));
+}
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 5c851a7..27b03e8 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
@@ -482,12 +482,12 @@
 				return REALM_ERROR;
 			}
 		}
-		ipa_align = ALIGN_DOWN(map_addr, RTT_MAP_SIZE(level - 1));
-		ret = host_rmi_rtt_aux_create(realm->rd, rtt, ipa_align, (u_register_t)level,
+		ipa_align = ALIGN_DOWN(map_addr, RTT_MAP_SIZE(level <= 0 ? level : level - 1));
+		ret = host_rmi_rtt_aux_create(realm->rd, rtt, ipa_align, level,
 				tree_index);
 		if (ret != RMI_SUCCESS) {
-			ERROR("%s() failed, rtt=0x%lx ret=0x%lx\n",
-				"host_realm_rtt_aux_create", rtt, ret);
+			ERROR("%s() failed, map_addr =0x%lx ipa_align=0x%lx level=%lx ret=0x%lx\n",
+				"host_realm_rtt_aux_create", map_addr, ipa_align, level, ret);
 			host_rmi_granule_undelegate(rtt);
 			page_free(rtt);
 			return REALM_ERROR;
@@ -551,7 +551,7 @@
 			level = (long)ulevel;
 
 			ret = host_realm_create_rtt_aux_levels(realm, map_addr,
-							 (u_register_t)level,
+							 level,
 							 3U, tree_index);
 			if (ret != RMI_SUCCESS) {
 				ERROR("%s() failed, ret=0x%lx line=%u\n",
@@ -1082,6 +1082,9 @@
 	 * Allocate memory for PAR - Realm image for each Plane.
 	 * Granule delegation
 	 * of PAR will be performed during rtt creation.
+	 * realm->par_size is size if single Plane image.
+	 * Same image is copied for each plane.
+	 * Offset for Plane N will be realm->par_base + (N*realm->par_size)
 	 */
 	realm->par_base = (u_register_t)page_alloc((realm->par_size) *
 			(realm->num_aux_planes + 1U));
@@ -1340,25 +1343,74 @@
 					u_register_t ns_shared_mem_adr,
 					u_register_t ns_shared_mem_size)
 {
-	u_register_t i = 0UL;
 	u_register_t ret;
 
 	realm->ipa_ns_buffer = ns_shared_mem_adr |
 			(1UL << (EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ,
 			realm->rmm_feat_reg0) - 1));
 	realm->ns_buffer_size = ns_shared_mem_size;
+
 	/* MAP SHARED_NS region */
-	while (i < ns_shared_mem_size / PAGE_SIZE) {
-		ret = host_realm_map_unprotected(realm, ns_shared_mem_adr +
-						 (i * PAGE_SIZE), PAGE_SIZE);
+	for (unsigned int i = 0U; i < ns_shared_mem_size / PAGE_SIZE; i++) {
+		ret = host_realm_map_unprotected(realm,
+				ns_shared_mem_adr + (i * PAGE_SIZE),
+				PAGE_SIZE);
+
 		if (ret != RMI_SUCCESS) {
 			ERROR("%s() failed, par_base=0x%lx ret=0x%lx\n",
 				"host_realm_map_unprotected",
-				(ns_shared_mem_adr + i * PAGE_SIZE), ret);
+				(ns_shared_mem_adr + (i * PAGE_SIZE)), ret);
 			return REALM_ERROR;
 		}
-		i++;
 	}
+
+	/* AUX MAP NS buffer for all RTTs */
+	if (!realm->rtt_tree_single) {
+		for (unsigned int i = 0U; i < ns_shared_mem_size / PAGE_SIZE; i++) {
+			for (unsigned int j = 0U; j < realm->num_aux_planes; j++) {
+				u_register_t fail_index, level_pri, state;
+
+				ret = host_rmi_rtt_aux_map_unprotected(realm->rd,
+						realm->ipa_ns_buffer + (i * PAGE_SIZE),
+						j + 1, &fail_index, &level_pri, &state);
+
+				if (ret == RMI_SUCCESS) {
+					continue;
+				} else if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT_AUX) {
+
+					/* Create Level and retry */
+					int8_t ulevel = RMI_RETURN_INDEX(ret);
+					long level = (long)ulevel;
+
+					ret = host_realm_create_rtt_aux_levels(realm,
+							realm->ipa_ns_buffer +
+							(i * PAGE_SIZE),
+							level, 3, j + 1);
+
+					if (ret != RMI_SUCCESS) {
+						return REALM_ERROR;
+					}
+
+					ret = host_rmi_rtt_aux_map_unprotected(realm->rd,
+							realm->ipa_ns_buffer +
+							(i * PAGE_SIZE),
+							j + 1, &fail_index,
+							&level_pri, &state);
+
+					if (ret == RMI_SUCCESS) {
+						continue;
+					}
+				}
+
+				ERROR("%s() failed, par_base=0x%lx ret=0x%lx\n",
+						"host_realm_aux_map_unprotected",
+						(ns_shared_mem_adr), ret);
+				return REALM_ERROR;
+
+			}
+		}
+	}
+
 	return REALM_SUCCESS;
 }
 
@@ -1651,6 +1703,126 @@
 	return MAX_REC_COUNT;
 }
 
+/* Check if adr is in range of any of the Plane Images */
+static bool is_adr_in_par(struct realm *realm, u_register_t addr)
+{
+	if ((addr >= realm->par_base) && (addr <
+			(realm->par_base + (realm->par_size * (realm->num_aux_planes + 1U))))) {
+		return true;
+	}
+	return false;
+}
+
+/* Handle Plane permission falut, return true to return to realm, false to host */
+static bool host_realm_handle_perm_fault(struct realm *realm, struct rmi_rec_run *run)
+{
+	/*
+	 * If exception is not in primary rtt
+	 * Map Adr in failing Aux RTT and re-enter rec
+	 * Validate faulting adr is in Realm payload area
+	 * Note - PlaneN uses Primary RTT tree index 0
+	 */
+
+	u_register_t fail_index;
+	u_register_t level_pri;
+	u_register_t state;
+	u_register_t ripas;
+	u_register_t ret;
+
+	VERBOSE("host aux_map 0x%lx rtt 0x%lx\n",
+			run->exit.hpfar, run->exit.rtt_tree);
+
+	ret = host_realm_aux_map_protected_data(realm,
+			run->exit.hpfar << 8U,
+			PAGE_SIZE,
+			run->exit.rtt_tree,
+			&fail_index, &level_pri, &state, &ripas);
+
+	if (ret != REALM_SUCCESS) {
+		ERROR("host_realm_aux_map_protected_data failed\n");
+		return false;
+	}
+
+	/* re-enter realm */
+	return true;
+}
+
+/* Handle RSI_MEM_SET_PERM_INDEX by P0, return true to return to realm, false to return to host */
+static bool host_realm_handle_s2ap_change(struct realm *realm, struct rmi_rec_run *run)
+{
+
+
+	u_register_t new_base = run->exit.s2ap_base;
+	u_register_t top = run->exit.s2ap_top;
+	u_register_t rtt_tree, ret;
+	bool ret1 = true;
+
+	while (new_base != top) {
+		ret = host_rmi_rtt_set_s2ap(realm->rd,
+				    realm->rec[0U],
+				    new_base,
+				    top, &new_base,
+				    &rtt_tree);
+
+		if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT_AUX) {
+
+			int8_t ulevel = RMI_RETURN_INDEX(ret);
+			long level = (long)ulevel;
+
+			assert(rtt_tree != PRIMARY_RTT_INDEX);
+
+			/* create missing aux rtt level */
+			VERBOSE("set s2ap fail missing aux rtt=%lx 0x%lx 0x%lx\n",
+					rtt_tree, new_base, top);
+
+			ret = host_realm_create_rtt_aux_levels(realm, new_base,
+						level,
+						level + 1, rtt_tree);
+			if (ret != RMI_SUCCESS) {
+				INFO("host_rmi_create_rtt_aux_levels \
+						failed 0x%lx\n", new_base);
+				ret1 = false;
+				break;
+			}
+
+			/* Retry RMI_RTT_SET_S2AP */
+			continue;
+		} else if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT) {
+
+			int8_t ulevel = RMI_RETURN_INDEX(ret);
+			long level = (long)ulevel;
+
+			assert(rtt_tree == PRIMARY_RTT_INDEX);
+			INFO("set s2ap failed missing rtt=0x%lx 0x%lx 0x%lx\n\n",
+						rtt_tree, new_base, top);
+
+			/* create missing rtt level */
+			ret = host_rmi_create_rtt_levels(realm, new_base,
+							level,
+							level + 1);
+
+			if (ret != RMI_SUCCESS) {
+				INFO("host_rmi_create_rtt_levels \
+							failed 0x%lx\n", new_base);
+				ret1 = false;
+				break;
+			}
+
+			/* Retry RMI_RTT_SET_S2AP */
+			continue;
+		} else if (RMI_RETURN_STATUS(ret) != RMI_SUCCESS) {
+			INFO("host set s2ap failed ret=0x%lx\n",
+					RMI_RETURN_STATUS(ret));
+			ret1 = false;
+			break;
+		}
+	}
+
+	/* re-enter realm */
+	return ret1;
+}
+
+
 u_register_t host_realm_rec_enter(struct realm *realm,
 				  u_register_t *exit_reason,
 				  unsigned int *host_call_result,
@@ -1685,6 +1857,28 @@
 			}
 		}
 
+		if ((run->exit.exit_reason == RMI_EXIT_SYNC) &&
+		     is_adr_in_par(realm, (run->exit.hpfar << 8U)) &&
+		     (((((run->exit.esr & ISS_FSC_MASK) >= FSC_L0_TRANS_FAULT) &&
+		     ((run->exit.esr & ISS_FSC_MASK) <= FSC_L3_TRANS_FAULT)) ||
+		     ((run->exit.esr & ISS_FSC_MASK) == FSC_L_MINUS1_TRANS_FAULT))) &&
+		     !realm->rtt_tree_single &&
+		     (realm->num_aux_planes > 0U)) {
+
+			re_enter_rec = host_realm_handle_perm_fault(realm, run);
+		}
+
+		/*
+		 * P0 issued RSI_MEM_SET_PERM_INDEX call
+		 * Validate base is in range of realm payload area
+		 */
+		if ((run->exit.exit_reason == RMI_EXIT_S2AP_CHANGE) &&
+		    is_adr_in_par(realm, run->exit.s2ap_base) &&
+		    (realm->num_aux_planes > 0U)) {
+
+			re_enter_rec = host_realm_handle_s2ap_change(realm, run);
+		}
+
 		if (ret != RMI_SUCCESS) {
 			return ret;
 		}
@@ -1696,7 +1890,8 @@
 				re_enter_rec = true;
 				break;
 			case HOST_CALL_EXIT_PRINT_CMD:
-				realm_print_handler(realm, REC_IDX(run->exit.gprs[0]));
+				realm_print_handler(realm, run->exit.gprs[0],
+						REC_IDX(run->exit.gprs[1]));
 				re_enter_rec = true;
 				break;
 			case HOST_CALL_EXIT_SUCCESS_CMD:
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c b/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c
index b3bfdae..eb75028 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_shared_data.c
@@ -11,69 +11,65 @@
 #include <host_realm_rmi.h>
 #include <host_shared_data.h>
 
-/*
- * Currently we support only creation of a single Realm in TFTF.
- * Hence we can assume that Shared area should be sufficient for all
- * the RECs of this Realm.
- */
-CASSERT(NS_REALM_SHARED_MEM_SIZE > (MAX_REC_COUNT *
+CASSERT(NS_REALM_SHARED_MEM_SIZE > (MAX_REC_COUNT * MAX_PLANE_COUNT *
 				sizeof(host_shared_data_t)),
 		too_small_realm_shared_mem_size);
 
 /*
  * Return shared buffer pointer mapped as host_shared_data_t structure
  */
-host_shared_data_t *host_get_shared_structure(struct realm *realm_ptr, unsigned int rec_num)
+host_shared_data_t *host_get_shared_structure(struct realm *realm_ptr,
+		unsigned int plane_num, unsigned int rec_num)
 {
-	host_shared_data_t *host_shared_data;
+	host_shared_data_arr_t host_shared_data;
 
 	assert(realm_ptr != NULL);
 	assert(rec_num < MAX_REC_COUNT);
-	host_shared_data = (host_shared_data_t *)realm_ptr->host_shared_data;
-	return &host_shared_data[rec_num];
+	host_shared_data = (host_shared_data_arr_t)realm_ptr->host_shared_data;
+	return (host_shared_data_t *)&(*host_shared_data)[plane_num][rec_num];
 }
 
 /*
  * Set data to be shared from Host to realm
  */
 void host_shared_data_set_host_val(struct realm *realm_ptr,
-		unsigned int rec_num, uint8_t index, u_register_t val)
+		unsigned int plane_num, unsigned int rec_num, uint8_t index, u_register_t val)
 {
-	host_shared_data_t *host_shared_data;
+	host_shared_data_arr_t host_shared_data;
 
 	assert(realm_ptr != NULL);
 	assert(rec_num < MAX_REC_COUNT);
 	assert(index < MAX_DATA_SIZE);
-	host_shared_data = (host_shared_data_t *)realm_ptr->host_shared_data;
-	host_shared_data[rec_num].host_param_val[index] = val;
+	host_shared_data = (host_shared_data_arr_t)realm_ptr->host_shared_data;
+	(*host_shared_data)[plane_num][rec_num].host_param_val[index] = val;
 }
 
 /*
  * Return data shared by realm in realm_out_val.
  */
 u_register_t host_shared_data_get_realm_val(struct realm *realm_ptr,
-		unsigned int rec_num, uint8_t index)
+		unsigned int plane_num, unsigned int rec_num, uint8_t index)
 {
-	host_shared_data_t *host_shared_data;
+	host_shared_data_arr_t host_shared_data;
 
 	assert(realm_ptr != NULL);
 	assert(rec_num < MAX_REC_COUNT);
 	assert(index < MAX_DATA_SIZE);
-	host_shared_data = (host_shared_data_t *)realm_ptr->host_shared_data;
-	return host_shared_data[rec_num].realm_out_val[index];
+	host_shared_data = (host_shared_data_arr_t)realm_ptr->host_shared_data;
+	return (*host_shared_data)[plane_num][rec_num].realm_out_val[index];
 }
 
 /*
  * Set command to be send from Host to realm
  */
 void host_shared_data_set_realm_cmd(struct realm *realm_ptr,
-		uint8_t cmd, unsigned int rec_num)
+		uint8_t cmd, unsigned int plane_num, unsigned int rec_num)
 {
-	host_shared_data_t *host_shared_data;
+	host_shared_data_arr_t host_shared_data;
 
 	assert(realm_ptr != NULL);
 	assert(rec_num < MAX_REC_COUNT);
-	host_shared_data = (host_shared_data_t *)realm_ptr->host_shared_data;
-	host_shared_data[rec_num].realm_cmd = cmd;
+	host_shared_data = (host_shared_data_arr_t)realm_ptr->host_shared_data;
+	(*host_shared_data)[plane_num][rec_num].realm_cmd = cmd;
 }
 
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_mpam_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_mpam_tests.c
new file mode 100644
index 0000000..7967828
--- /dev/null
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_mpam_tests.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <debug.h>
+#include <host_realm_helper.h>
+#include <host_realm_mem_layout.h>
+#include <host_shared_data.h>
+#include <test_helpers.h>
+
+static test_result_t realm_test_feat_mpam(enum realm_cmd cmd)
+{
+	bool ret1, ret2;
+	u_register_t rec_flag[] = {RMI_RUNNABLE};
+	struct realm realm;
+	u_register_t feature_flag = 0UL;
+	long sl = RTT_MIN_LEVEL;
+
+	assert((cmd >= REALM_MPAM_ACCESS) && (cmd <= REALM_MPAM_PRESENT));
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+	SKIP_TEST_IF_FEAT_MPAM_NOT_SUPPORTED();
+
+	if (is_feat_52b_on_4k_2_supported()) {
+		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
+		sl = RTT_MIN_LEVEL_LPA2;
+	}
+
+	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
+			feature_flag, sl, rec_flag, 1U, 0U)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	ret1 = host_enter_realm_execute(&realm, cmd, RMI_EXIT_HOST_CALL, 0U);
+	ret2 = host_destroy_realm(&realm);
+
+	if (!ret1 || !ret2) {
+		ERROR("%s(): enter=%u destroy=%u\n",
+		__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return true;
+}
+
+/*
+ * @Test_Aim@ Test that FEAT_MPAM is hidden to the realm
+ */
+test_result_t host_realm_hide_feat_mpam(void)
+{
+	return realm_test_feat_mpam(REALM_MPAM_PRESENT);
+}
+
+/*
+ * @Test_Aim@ Test that access to MPAM registers triggers an undefined abort
+ * taken into the realm.
+ */
+test_result_t host_realm_mpam_undef_abort(void)
+{
+	return realm_test_feat_mpam(REALM_MPAM_ACCESS);
+}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
index 151e871..5c3299a 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_multiple_rec_tests.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -22,6 +22,7 @@
 static uint64_t is_secondary_cpu_on;
 static struct realm realm;
 static struct realm realm1;
+static struct pmu_registers pmu_state[PLATFORM_CORE_COUNT];
 
 /*
  * Test tries to create max Rec
@@ -37,7 +38,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -55,7 +56,9 @@
 	rec_num = (unsigned int)rand() % MAX_REC_COUNT;
 
 	for (unsigned int i = 0; i < MAX_REC_COUNT; i++) {
-		host_shared_data_set_host_val(&realm, rec_num, HOST_ARG1_INDEX, 10U);
+		host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID,
+				rec_num, HOST_ARG1_INDEX, 10U);
+
 		ret1 = host_enter_realm_execute(&realm, REALM_SLEEP_CMD,
 				RMI_EXIT_HOST_CALL, rec_num);
 		if (!ret1) {
@@ -106,7 +109,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -247,7 +250,7 @@
 	rec_count = tftf_get_total_cpus_count();
 	assert(rec_count <= MAX_REC_COUNT);
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -351,7 +354,7 @@
 	rec_count = tftf_get_total_cpus_count();
 	assert(rec_count <= MAX_REC_COUNT);
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -368,7 +371,7 @@
 	is_secondary_cpu_on = 0U;
 	init_spinlock(&secondary_cpu_lock);
 	my_mpidr = read_mpidr_el1() & MPID_MASK;
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, rec_count);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, rec_count);
 	ret1 = host_enter_realm_execute(&realm, REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD,
 			RMI_EXIT_PSCI, 0U);
 	if (!ret1) {
@@ -489,7 +492,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -510,7 +513,7 @@
 	}
 
 	/* Realm to request CPU_ON for rec 2 */
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, 2U);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, 2U);
 	ret1 = host_enter_realm_execute(&realm, REALM_MULTIPLE_REC_MULTIPLE_CPU_CMD,
 			RMI_EXIT_PSCI, 0U);
 	if (!ret1) {
@@ -585,6 +588,9 @@
 	spin_lock(&secondary_cpu_lock);
 	i = is_secondary_cpu_on++;
 	spin_unlock(&secondary_cpu_lock);
+
+	host_set_pmu_state(&pmu_state[i]);
+
 	ret1 = host_enter_realm_execute(&realm, REALM_PMU_COUNTER, RMI_EXIT_HOST_CALL, i);
 	if (!ret1) {
 		return TEST_RESULT_FAIL;
@@ -597,10 +603,16 @@
 	if (!ret1) {
 		return TEST_RESULT_FAIL;
 	}
+
 	ret1 = host_enter_realm_execute(&realm1, REALM_PMU_PRESERVE, RMI_EXIT_HOST_CALL, i);
-	if (ret1) {
+	if (!ret1) {
+		return TEST_RESULT_FAIL;
+	}
+
+	if (host_check_pmu_state(&pmu_state[i])) {
 		return TEST_RESULT_SUCCESS;
 	}
+
 	return TEST_RESULT_FAIL;
 }
 
@@ -621,17 +633,19 @@
 	u_register_t rmm_feat_reg0;
 	u_register_t rec_flag[MAX_REC_COUNT];
 	bool ret1 = false, ret2;
-	unsigned int num_cnts, rec_count, i;
+	unsigned int rec_count, i, num_cnts;
 	u_register_t other_mpidr, my_mpidr, ret;
 	int cpu_node;
 	long sl = RTT_MIN_LEVEL;
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
+	host_rmi_init_cmp_result();
+
 	rec_count = tftf_get_total_cpus_count();
 	assert(rec_count <= MAX_REC_COUNT);
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -640,135 +654,157 @@
 		rec_flag[i] = RMI_RUNNABLE;
 	}
 
-	/* Get Max PMU counter implemented through RMI_FEATURES */
+	/* Get number of PMU event counters implemented through RMI_FEATURES */
 	if (host_rmi_features(0UL, &rmm_feat_reg0) != REALM_SUCCESS) {
 		ERROR("%s() failed\n", "host_rmi_features");
 		return TEST_RESULT_FAIL;
 	}
 
 	num_cnts = EXTRACT(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, rmm_feat_reg0);
-	host_set_pmu_state();
+	host_set_pmu_state(&pmu_state[0U]);
+
 	is_secondary_cpu_on = 0;
 	my_mpidr = read_mpidr_el1() & MPID_MASK;
 
-	if (num_cnts == 0U) {
-		ERROR("No PMU counters implemented\n");
-		return TEST_RESULT_SKIPPED;
+	if (num_cnts == 0) {
+		INFO("No event counters implemented\n");
+	} else {
+		INFO("Testing %u event counters\n", num_cnts);
 	}
 
-	feature_flag |= RMI_FEATURE_REGISTER_0_PMU_EN |
-			INPLACE(FEATURE_PMU_NUM_CTRS, num_cnts + 1U);
+	/*
+	 * Check that number of event counters is less
+	 * than maximum supported by architecture.
+	 */
+	if (num_cnts < ((1U << RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS_WIDTH) - 1U)) {
+		feature_flag |= RMI_FEATURE_REGISTER_0_PMU_EN |
+				INPLACE(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, num_cnts + 1U);
 
-	/* Request more PMU counter than total, expect failure */
-	if (host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U, 0U)) {
-		ERROR("Realm create should have failed\n");
-		host_destroy_realm(&realm);
-		return TEST_RESULT_FAIL;
+		if (is_feat_52b_on_4k_2_supported()) {
+			feature_flag |= RMI_FEATURE_REGISTER_0_LPA2;
+		}
+
+		/* Request more event counters than total, expect failure */
+		if (host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
+							feature_flag, sl, rec_flag, 1U, 0U)) {
+			ERROR("Realm create should have failed\n");
+			host_destroy_realm(&realm);
+			return TEST_RESULT_FAIL;
+		}
 	}
 
-	/* Request 0 PMU counter */
+	/* Request Cycle Counter with no event counters */
 	feature_flag = RMI_FEATURE_REGISTER_0_PMU_EN |
-			INPLACE(FEATURE_PMU_NUM_CTRS, 0U);
+			INPLACE(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, 0U);
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag |= RMI_FEATURE_REGISTER_0_LPA2;
 	}
 
 	ret1 = host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, rec_flag, 1U, 0U);
+						feature_flag, sl, rec_flag, 1U, 0U);
+	host_destroy_realm(&realm);
 
 	if (!get_feat_hpmn0_supported()) {
 		if (ret1) {
-			ERROR("Realm create with 0 PMU Counter should have failed\n");
-			host_destroy_realm(&realm);
+			ERROR("Realm create with 0 event counters should have failed\n");
 			return TEST_RESULT_FAIL;
 		}
 	} else {
 		if (!ret1) {
-			ERROR("Realm create with 0 PMU Counter should not have failed\n");
+			ERROR("Realm create with 0 event counters should not have failed\n");
 			return TEST_RESULT_FAIL;
 		}
-		host_destroy_realm(&realm);
 	}
 
-	/* Test 2 create first realm with max PMU counters */
+	/* Create first realm with number of PMU event counters */
 	feature_flag = RMI_FEATURE_REGISTER_0_PMU_EN |
-			INPLACE(FEATURE_PMU_NUM_CTRS, num_cnts);
+			INPLACE(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, num_cnts);
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag |= RMI_FEATURE_REGISTER_0_LPA2;
 	}
 
-	/* Prepare realm0, create recs for realm0 later */
+	/* Prepare realm, create recs later */
 	if (!host_prepare_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
 			feature_flag, sl, rec_flag, rec_count, 0U)) {
-		goto test_exit;
 		return TEST_RESULT_FAIL;
 	}
 
-	/* Second realm with less num of PMU counters */
+	/*
+	 * Second realm1 with less or equal number of event counters.
+	 * When no event counters are implemented, only Cycle Counter
+	 * will be tested.
+	 */
 	feature_flag = RMI_FEATURE_REGISTER_0_PMU_EN |
-			INPLACE(FEATURE_PMU_NUM_CTRS, num_cnts - 1U);
+			INPLACE(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS,
+			(num_cnts == 0U) ? num_cnts : num_cnts - 1U);
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag |= RMI_FEATURE_REGISTER_0_LPA2;
 	}
 
-	if (!host_create_activate_realm_payload(&realm1, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, rec_count, 0U)) {
-		goto test_exit2;
+	ret1 = host_create_activate_realm_payload(&realm1, (u_register_t)REALM_IMAGE_BASE,
+					feature_flag, sl, rec_flag, rec_count, 0U);
+	if (!ret1) {
+		goto test_exit;
 	}
 
-	/* create realm0 recs, activate realm0 */
+	/* Create realm recs, activate realm0 */
 	if (host_realm_rec_create(&realm) != REALM_SUCCESS) {
 		ERROR("%s() failed\n", "host_realm_rec_create");
-		goto test_exit2;
+		goto test_exit;
 	}
 
 	if (host_realm_init_ipa_state(&realm, sl, 0U, 1ULL << 32)
 		!= RMI_SUCCESS) {
 		ERROR("%s() failed\n", "host_realm_init_ipa_state");
-		goto test_exit2;
+		goto test_exit;
 	}
 
 	if (host_realm_activate(&realm) != REALM_SUCCESS) {
 		ERROR("%s() failed\n", "host_realm_activate");
-		goto test_exit2;
+		goto test_exit;
 	}
-	INFO("MAX PMU Counter=%u\n", num_cnts);
 
-	/* Pass num of PMU counters programmed to realm */
+	/* Pass number of event counters programmed to realms */
 	for (unsigned int j = 0U; j < rec_count; j++) {
-		host_shared_data_set_host_val(&realm, j, HOST_ARG1_INDEX, num_cnts);
-		host_shared_data_set_host_val(&realm1, j, HOST_ARG1_INDEX, num_cnts - 1U);
+		host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, j,
+						HOST_ARG1_INDEX, num_cnts);
+		host_shared_data_set_host_val(&realm1, PRIMARY_PLANE_ID, j,
+						HOST_ARG1_INDEX,
+						(num_cnts == 0U) ? 0U : num_cnts - 1U);
 	}
 
 	/*
-	 * Enter realm0 rec0 test PMU counters available is same as that programmed by host
-	 * Validation is done by the Realm and will return error if the count does not match
+	 * Enter realm rec0 test PMU counters available is same as that programmed by host.
+	 * Validation is done by the Realm and will return error if the count does not match.
 	 */
 	ret1 = host_enter_realm_execute(&realm, REALM_PMU_COUNTER, RMI_EXIT_HOST_CALL, 0U);
 	if (!ret1) {
-		goto test_exit2;
+		goto test_exit;
 	}
 
 	/* Enter realm1 rec0 test PMU counters available is same as that programmed by host */
 	ret1 = host_enter_realm_execute(&realm1, REALM_PMU_COUNTER, RMI_EXIT_HOST_CALL, 0U);
 	if (!ret1) {
-		goto test_exit2;
+		goto test_exit;
 	}
 
-	/* Test if Realm0 rec0 entering/exiting preserves PMU state */
+	/* Test if realm rec0 entering/exiting preserves PMU state */
 	ret1 = host_enter_realm_execute(&realm, REALM_PMU_PRESERVE, RMI_EXIT_HOST_CALL, 0U);
 	if (!ret1) {
-		goto test_exit2;
+		goto test_exit;
 	}
 
-	/* Test if Realm1 rec0 entering/exiting preserves PMU state */
+	/* Test if realm1 rec0 entering/exiting preserves PMU state */
 	ret1 = host_enter_realm_execute(&realm1, REALM_PMU_PRESERVE, RMI_EXIT_HOST_CALL, 0U);
 	if (!ret1) {
-		goto test_exit2;
+		goto test_exit;
+	}
+
+	if (!host_check_pmu_state(&pmu_state[0U])) {
+		goto test_exit;
 	}
 
 	i = 0U;
@@ -787,7 +823,7 @@
 		ret = tftf_try_cpu_on(other_mpidr, (uintptr_t)cpu_on_handler_pmu, 0);
 		if (ret != PSCI_E_SUCCESS) {
 			ERROR("TFTF CPU ON failed\n");
-			goto test_exit2;
+			goto test_exit;
 		}
 		i++;
 	}
@@ -808,21 +844,17 @@
 		}
 	}
 
-test_exit2:
+test_exit:
 	ret2 = host_destroy_realm(&realm1);
 	if (!ret1 || !ret2) {
 		ERROR("%s() enter=%u destroy=%u\n", __func__, ret1, ret2);
 	}
-test_exit:
+
 	ret2 = host_destroy_realm(&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 TEST_RESULT_SUCCESS;
+	return host_cmp_result();
 }
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c
index 5304180..023ec1c 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_payload_simd_tests.c
@@ -113,7 +113,7 @@
 	}
 
 	/* Check if rdvl matches the SVE VL created */
-	sd = host_get_shared_structure(&realm, 0U);
+	sd = host_get_shared_structure(&realm, PRIMARY_PLANE_ID, 0U);
 	rl_output = (struct sve_cmd_rdvl *)sd->realm_cmd_output_buffer;
 	rl_max_sve_vq = SVE_VL_TO_VQ(rl_output->rdvl);
 	if (sve_vq == rl_max_sve_vq) {
@@ -188,7 +188,7 @@
 		goto rm_realm;
 	}
 
-	sd = host_get_shared_structure(&realm, 0U);
+	sd = host_get_shared_structure(&realm, PRIMARY_PLANE_ID, 0U);
 	r_regs = (struct sve_cmd_id_regs *)sd->realm_cmd_output_buffer;
 
 	/* Check ID register SVE flags */
@@ -275,7 +275,7 @@
 		goto rm_realm;
 	}
 
-	sd = host_get_shared_structure(&realm, 0U);
+	sd = host_get_shared_structure(&realm, PRIMARY_PLANE_ID, 0U);
 	rl_output = (struct sve_cmd_probe_vl *)sd->realm_cmd_output_buffer;
 
 	INFO("Supported SVE vector length in bits (expected):\n");
@@ -649,7 +649,7 @@
 		goto rm_realm;
 	}
 
-	sd = host_get_shared_structure(&realm, 0U);
+	sd = host_get_shared_structure(&realm, PRIMARY_PLANE_ID, 0U);
 	r_regs = (struct sme_cmd_id_regs *)sd->realm_cmd_output_buffer;
 
 	/* Check ID register SME flags */
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 c25c58d..9b03393 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,5 +1,5 @@
 /*
- * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,17 +21,160 @@
 #include <host_realm_pmu.h>
 #include <host_shared_data.h>
 
-#define SLEEP_TIME_MS	20U
+#define SLEEP_TIME_MS		2U
 
 extern const char *rmi_exit[];
 
 static struct realm realm[MAX_REALM_COUNT];
+static struct pmu_registers pmu_state;
 
 #if ENABLE_PAUTH
 static uint128_t pauth_keys_before[NUM_KEYS];
 static uint128_t pauth_keys_after[NUM_KEYS];
 #endif
 
+bool are_planes_supported(void)
+{
+	u_register_t feature_flag;
+
+	/* Read Realm Feature Reg 0 */
+	if (host_rmi_features(0UL, &feature_flag) != REALM_SUCCESS) {
+		ERROR("%s() failed\n", "host_rmi_features");
+		return false;
+	}
+
+	if (EXTRACT(RMI_FEATURE_REGISTER_0_MAX_NUM_AUX_PLANES, feature_flag) > 0UL) {
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * @Test_Aim@ Test RSI_PLANE_REG_READ/WRITE
+ */
+test_result_t host_test_realm_create_planes_register_rw(void)
+{
+	bool ret1, ret2;
+	u_register_t rec_flag[MAX_REC_COUNT];
+	struct realm realm;
+	u_register_t feature_flag = 0UL;
+	long sl = RTT_MIN_LEVEL;
+	struct rmi_rec_run *run;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	if (!are_planes_supported()) {
+		return TEST_RESULT_SKIPPED;
+	}
+
+	if (is_feat_52b_on_4k_2_supported() == true) {
+		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
+		sl = RTT_MIN_LEVEL_LPA2;
+	}
+
+	for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+		rec_flag[i] = RMI_RUNNABLE;
+	}
+
+	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
+			feature_flag, sl, rec_flag, 1U, 1U)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	/* CMD for Plane N */
+	host_shared_data_set_realm_cmd(&realm, REALM_PLANE_N_REG_RW_CMD, 1U, 0U);
+
+	run = (struct rmi_rec_run *)realm.run[0U];
+
+	host_realm_set_aux_plane_args(&realm, 1U);
+	ret1 = host_enter_realm_execute(&realm, REALM_PLANE_N_REG_RW_CMD,
+			RMI_EXIT_HOST_CALL, 0U);
+
+	if (run->exit.exit_reason != RMI_EXIT_HOST_CALL) {
+		ERROR("Rec0 error exit=0x%lx ret1=%d HPFAR=0x%lx \
+				esr=0x%lx far=0x%lx\n",
+				run->exit.exit_reason, ret1,
+				run->exit.hpfar,
+				run->exit.esr, run->exit.far);
+	}
+	ret2 = host_destroy_realm(&realm);
+
+	if (!ret1 || !ret2) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+		__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+	return host_cmp_result();
+}
+/*
+ * @Test_Aim@ Test realm payload creation with 3 Aux Planes, enter all Planes
+ * Host cannot enter Aux Planes directly,
+ * Host will enter P0, P0 will enter aux plane
+ */
+test_result_t host_test_realm_create_planes_enter(void)
+{
+	bool ret1, ret2;
+	u_register_t rec_flag[MAX_REC_COUNT];
+	struct realm realm;
+	u_register_t feature_flag = 0UL;
+	long sl = RTT_MIN_LEVEL;
+	struct rmi_rec_run *run;
+
+	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
+
+	if (!are_planes_supported()) {
+		return TEST_RESULT_SKIPPED;
+	}
+
+	if (is_feat_52b_on_4k_2_supported() == true) {
+		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
+		sl = RTT_MIN_LEVEL_LPA2;
+	}
+
+	for (unsigned int i = 0U; i < MAX_REC_COUNT; i++) {
+		rec_flag[i] = RMI_RUNNABLE;
+	}
+
+	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
+			feature_flag, sl, rec_flag, 1U, MAX_AUX_PLANE_COUNT)) {
+		return TEST_RESULT_FAIL;
+	}
+
+	/* CMD for Plane N */
+	for (unsigned int j = 1U; j <= MAX_AUX_PLANE_COUNT; j++) {
+		host_shared_data_set_realm_cmd(&realm, REALM_SLEEP_CMD, j, 0U);
+		host_shared_data_set_host_val(&realm, j, 0U,
+				HOST_ARG1_INDEX, SLEEP_TIME_MS);
+	}
+
+	for (unsigned int j = 1U; j <= MAX_AUX_PLANE_COUNT; j++) {
+		run = (struct rmi_rec_run *)realm.run[0U];
+
+		host_realm_set_aux_plane_args(&realm, j);
+		ret1 = host_enter_realm_execute(&realm, REALM_ENTER_PLANE_N_CMD,
+				RMI_EXIT_HOST_CALL, 0U);
+
+
+		if (run->exit.exit_reason != RMI_EXIT_HOST_CALL) {
+			ERROR("Rec0 error exit=0x%lx ret1=%d HPFAR=0x%lx \
+					esr=0x%lx far=0x%lx\n",
+					run->exit.exit_reason, ret1,
+					run->exit.hpfar,
+					run->exit.esr, run->exit.far);
+		}
+	}
+	ret2 = host_destroy_realm(&realm);
+
+	if (!ret1 || !ret2) {
+		ERROR("%s(): enter=%d destroy=%d\n",
+		__func__, ret1, ret2);
+		return TEST_RESULT_FAIL;
+	}
+
+	return host_cmp_result();
+}
+
 /*
  * @Test_Aim@ Test realm payload creation, execution and destruction iteratively
  */
@@ -45,7 +188,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -63,7 +206,9 @@
 			return TEST_RESULT_FAIL;
 		}
 
-		host_shared_data_set_host_val(&realm, run_num, HOST_ARG1_INDEX, SLEEP_TIME_MS);
+		host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, run_num,
+				HOST_ARG1_INDEX, SLEEP_TIME_MS);
+
 		ret1 = host_enter_realm_execute(&realm, REALM_SLEEP_CMD, RMI_EXIT_HOST_CALL,
 						run_num);
 		ret2 = host_destroy_realm(&realm);
@@ -91,7 +236,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -130,7 +275,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -195,7 +340,7 @@
 	u_register_t feature_flag = 0U;
 	long sl = RTT_MIN_LEVEL;
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -296,12 +441,12 @@
 	}
 
 	num_cnts = EXTRACT(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, rmm_feat_reg0);
-	host_set_pmu_state();
+	host_set_pmu_state(&pmu_state);
 
 	feature_flag = RMI_FEATURE_REGISTER_0_PMU_EN |
-			INPLACE(FEATURE_PMU_NUM_CTRS, num_cnts);
+			INPLACE(RMI_FEATURE_REGISTER_0_PMU_NUM_CTRS, num_cnts);
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag |= RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -312,9 +457,11 @@
 	}
 
 	ret1 = host_enter_realm_execute(&realm, cmd,
-					(cmd == REALM_PMU_INTERRUPT) ?
+					((cmd == REALM_PMU_CYCLE_INTERRUPT) ||
+					 (cmd == REALM_PMU_EVENT_INTERRUPT)) ?
 					RMI_EXIT_IRQ : RMI_EXIT_HOST_CALL, 0U);
-	if (!ret1 || (cmd != REALM_PMU_INTERRUPT)) {
+	if (!ret1 || ((cmd != REALM_PMU_CYCLE_INTERRUPT) &&
+		      (cmd != REALM_PMU_EVENT_INTERRUPT))) {
 		goto test_exit;
 	}
 
@@ -327,7 +474,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	if (!host_check_pmu_state()) {
+	if (!host_check_pmu_state(&pmu_state)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -347,6 +494,11 @@
  */
 test_result_t host_realm_pmuv3_event_works(void)
 {
+	if (GET_PMU_CNT == 0) {
+		tftf_testcase_printf("No event counters implemented\n");
+		return TEST_RESULT_SKIPPED;
+	}
+
 	return host_test_realm_pmuv3(REALM_PMU_EVENT);
 }
 
@@ -370,22 +522,50 @@
 	return -1;
 }
 
-/*
- * Test PMU interrupt functionality in Realm
- */
-test_result_t host_realm_pmuv3_overflow_interrupt(void)
+static test_result_t host_realm_pmuv3_overflow_interrupt(uint8_t cmd)
 {
-	/* Register PMU IRQ handler */
-	int ret = tftf_irq_register_handler(PMU_PPI, host_overflow_interrupt);
+	test_result_t ret;
 
-	if (ret != 0) {
-		tftf_testcase_printf("Failed to %sregister IRQ handler\n",
-					"");
+	/* Register PMU IRQ handler */
+	if (tftf_irq_register_handler(PMU_PPI, host_overflow_interrupt) != 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);
+
+	ret = host_test_realm_pmuv3(cmd);
+	if (ret != TEST_RESULT_SUCCESS) {
+		tftf_irq_disable(PMU_PPI);
+		if (tftf_irq_unregister_handler(PMU_PPI) != 0) {
+			ERROR("Failed to %sregister IRQ handler\n", "un");
+			return TEST_RESULT_FAIL;
+		}
+		return ret;
+	}
+
+	return TEST_RESULT_SUCCESS;
+}
+
+/*
+ * Test PMU cycle counter interrupt functionality in Realm
+ */
+test_result_t host_realm_pmuv3_cycle_overflow_interrupt(void)
+{
+	return host_realm_pmuv3_overflow_interrupt(REALM_PMU_CYCLE_INTERRUPT);
+}
+
+/*
+ * Test PMU event counter interrupt functionality in Realm
+ */
+test_result_t host_realm_pmuv3_event_overflow_interrupt(void)
+{
+	if (GET_PMU_CNT == 0) {
+		tftf_testcase_printf("No event counters implemented\n");
+		return TEST_RESULT_SKIPPED;
+	}
+
+	return host_realm_pmuv3_overflow_interrupt(REALM_PMU_EVENT_INTERRUPT);
 }
 
 /*
@@ -405,7 +585,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -429,8 +609,9 @@
 
 	for (unsigned int j = 0U; j < MAX_REC_COUNT; j++) {
 		for (unsigned int i = 0U; i < MAX_REALM_COUNT; i++) {
-			host_shared_data_set_host_val(&realm[i], run_rec[i], HOST_ARG1_INDEX,
-							SLEEP_TIME_MS);
+			host_shared_data_set_host_val(&realm[i], PRIMARY_PLANE_ID, run_rec[i],
+					HOST_ARG1_INDEX, SLEEP_TIME_MS);
+
 			ret = host_enter_realm_execute(&realm[i], REALM_SLEEP_CMD,
 							RMI_EXIT_HOST_CALL, run_rec[i]);
 			if (!ret) {
@@ -479,7 +660,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -489,11 +670,11 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, 10U);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, 10U);
 	ret1 = host_enter_realm_execute(&realm, REALM_SLEEP_CMD, RMI_EXIT_HOST_CALL, 0U);
 	base = (u_register_t)page_alloc(PAGE_SIZE * test_page_num);
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG2_INDEX,
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG2_INDEX,
 			base + (PAGE_SIZE * test_page_num));
 
 	for (unsigned int i = 0U; i < test_page_num; i++) {
@@ -578,7 +759,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -595,7 +776,7 @@
 		ERROR("host_realm_delegate_map_protected_data failede\n");
 		goto destroy_realm;
 	}
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base);
 	ret1 = host_enter_realm_execute(&realm, REALM_REJECT_SET_RIPAS_CMD,
 			RMI_EXIT_RIPAS_CHANGE, 0U);
 
@@ -650,7 +831,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -681,8 +862,8 @@
 	}
 	INFO("Initial state base = 0x%lx rtt.state=0x%lx rtt.ripas=0x%lx\n",
 			base, rtt.state, rtt.ripas);
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
-	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG1_INDEX, base);
 
 	ret = host_rmi_data_destroy(realm.rd, base, &data, &top);
 	if (ret != RMI_SUCCESS || data != base) {
@@ -711,8 +892,8 @@
 	/* ESR.EC == 0b100000 Instruction Abort from a lower Exception level */
 	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
 			|| (EC_BITS(run->exit.esr) != EC_IABORT_LOWER_EL)
-			|| ((run->exit.esr & ISS_IFSC_MASK) < IFSC_L0_TRANS_FAULT)
-			|| ((run->exit.esr & ISS_IFSC_MASK) > IFSC_L3_TRANS_FAULT)
+			|| ((run->exit.esr & ISS_IFSC_MASK) < FSC_L0_TRANS_FAULT)
+			|| ((run->exit.esr & ISS_IFSC_MASK) > FSC_L3_TRANS_FAULT)
 			|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
 		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
 		goto undelegate_destroy;
@@ -729,8 +910,8 @@
 	/* ESR.EC == 0b100100 Data Abort exception from a lower Exception level */
 	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
 		|| (EC_BITS(run->exit.esr) != EC_DABORT_LOWER_EL)
-		|| ((run->exit.esr & ISS_DFSC_MASK) < DFSC_L0_TRANS_FAULT)
-		|| ((run->exit.esr & ISS_DFSC_MASK) > DFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) < FSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) > FSC_L3_TRANS_FAULT)
 		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
 		ERROR("Rec did not fault\n");
 		goto undelegate_destroy;
@@ -776,7 +957,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -811,8 +992,8 @@
 	}
 	INFO("Initial state base = 0x%lx rtt.state=0x%lx rtt.ripas=0x%lx\n",
 			base, rtt.state, rtt.ripas);
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
-	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG1_INDEX, base);
 
 	/* Rec0 expect rec exit due to Instr Abort unassigned ram page */
 	ret1 = host_enter_realm_execute(&realm, REALM_INSTR_FETCH_CMD,
@@ -821,8 +1002,8 @@
 	/* ESR.EC == 0b100000 Instruction Abort from a lower Exception level */
 	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
 			|| (EC_BITS(run->exit.esr) != EC_IABORT_LOWER_EL)
-			|| ((run->exit.esr & ISS_IFSC_MASK) < IFSC_L0_TRANS_FAULT)
-			|| ((run->exit.esr & ISS_IFSC_MASK) > IFSC_L3_TRANS_FAULT)
+			|| ((run->exit.esr & ISS_IFSC_MASK) < FSC_L0_TRANS_FAULT)
+			|| ((run->exit.esr & ISS_IFSC_MASK) > FSC_L3_TRANS_FAULT)
 			|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
 		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
 		goto destroy_realm;
@@ -838,8 +1019,8 @@
 	/* ESR.EC == 0b100100 Data Abort exception from a lower Exception level */
 	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
 		|| (EC_BITS(run->exit.esr) != EC_DABORT_LOWER_EL)
-		|| ((run->exit.esr & ISS_DFSC_MASK) < DFSC_L0_TRANS_FAULT)
-		|| ((run->exit.esr & ISS_DFSC_MASK) > DFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) < FSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) > FSC_L3_TRANS_FAULT)
 		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
 		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
 		goto destroy_realm;
@@ -885,7 +1066,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -913,8 +1094,8 @@
 	}
 	INFO("Initial state base = 0x%lx rtt.state=0x%lx rtt.ripas=0x%lx\n",
 			base, rtt.state, rtt.ripas);
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
-	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG1_INDEX, base);
 
 	if (host_realm_activate(&realm) != REALM_SUCCESS) {
 		ERROR("%s() failed\n", "host_realm_activate");
@@ -954,8 +1135,8 @@
 	/* ESR.EC == 0b100000 Instruction Abort from a lower Exception level */
 	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
 		|| (EC_BITS(run->exit.esr) != EC_IABORT_LOWER_EL)
-		|| ((run->exit.esr & ISS_IFSC_MASK) < IFSC_L0_TRANS_FAULT)
-		|| ((run->exit.esr & ISS_IFSC_MASK) > IFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_IFSC_MASK) < FSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_IFSC_MASK) > FSC_L3_TRANS_FAULT)
 		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
 		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
 		goto destroy_data;
@@ -971,8 +1152,8 @@
 	/* ESR.EC == 0b100100 Data Abort exception from a lower Exception level */
 	if (!ret1 || ((run->exit.hpfar >> 4U) != (base >> PAGE_SIZE_SHIFT)
 		|| (EC_BITS(run->exit.esr) != EC_DABORT_LOWER_EL)
-		|| ((run->exit.esr & ISS_DFSC_MASK) < DFSC_L0_TRANS_FAULT)
-		|| ((run->exit.esr & ISS_DFSC_MASK) > DFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) < FSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) > FSC_L3_TRANS_FAULT)
 		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U))) {
 		ERROR("Rec did not fault ESR=0x%lx\n", run->exit.esr);
 		goto destroy_data;
@@ -1020,7 +1201,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -1038,10 +1219,10 @@
 		ERROR("wrong initial state\n");
 		goto destroy_realm;
 	}
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
-	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base);
-	host_shared_data_set_host_val(&realm, 2U, HOST_ARG1_INDEX, base);
-	host_shared_data_set_host_val(&realm, 3U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 2U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 3U, HOST_ARG1_INDEX, base);
 
 	/* Rec0 expect IA due to SEA unassigned empty page */
 	ret1 = host_enter_realm_execute(&realm, REALM_INSTR_FETCH_CMD,
@@ -1052,7 +1233,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 0U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, 0U, 0U, HOST_ARG2_INDEX);
 	if (((esr & ISS_IFSC_MASK) != IFSC_NO_WALK_SEA) || (EC_BITS(esr) != EC_IABORT_CUR_EL)) {
 		ERROR("Rec0 incorrect ESR=0x%lx\n", esr);
 		goto destroy_realm;
@@ -1068,7 +1249,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 1U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, 0U, 1U, HOST_ARG2_INDEX);
 	if (((esr & ISS_DFSC_MASK) != DFSC_NO_WALK_SEA) || (EC_BITS(esr) != EC_DABORT_CUR_EL)) {
 		ERROR("Rec1 incorrect ESR=0x%lx\n", esr);
 		goto destroy_realm;
@@ -1100,7 +1281,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 2U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, 0U, 2U, HOST_ARG2_INDEX);
 	if (((esr & ISS_IFSC_MASK) != IFSC_NO_WALK_SEA) || (EC_BITS(esr) != EC_IABORT_CUR_EL)) {
 		ERROR("Rec2 incorrect ESR=0x%lx\n", esr);
 		goto destroy_realm;
@@ -1116,7 +1297,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 3U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, 0U, 3U, HOST_ARG2_INDEX);
 	if (((esr & ISS_DFSC_MASK) != DFSC_NO_WALK_SEA) || (EC_BITS(esr) != EC_DABORT_CUR_EL)) {
 		ERROR("Rec3 incorrect ESR=0x%lx\n", esr);
 	}
@@ -1162,7 +1343,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -1185,8 +1366,8 @@
 	}
 
 	run = (struct rmi_rec_run *)realm.run[0];
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base_ipa);
-	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base_ipa);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base_ipa);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG1_INDEX, base_ipa);
 
 	/* Rec0 expect SEA in realm due to IA unprotected IPA page */
 	ret1 = host_enter_realm_execute(&realm, REALM_INSTR_FETCH_CMD,
@@ -1197,7 +1378,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 0U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG2_INDEX);
 	if (((esr & ISS_IFSC_MASK) != IFSC_NO_WALK_SEA) || (EC_BITS(esr) != EC_IABORT_CUR_EL)) {
 		ERROR("Rec0 incorrect ESR=0x%lx\n", esr);
 		goto destroy_realm;
@@ -1212,8 +1393,8 @@
 
 	if (!ret1 || (run->exit.hpfar >> 4U) != (base_ipa >> PAGE_SIZE_SHIFT)
 		|| (EC_BITS(run->exit.esr) != EC_DABORT_LOWER_EL)
-		|| ((run->exit.esr & ISS_DFSC_MASK) < DFSC_L0_TRANS_FAULT)
-		|| ((run->exit.esr & ISS_DFSC_MASK) > DFSC_L3_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) < FSC_L0_TRANS_FAULT)
+		|| ((run->exit.esr & ISS_DFSC_MASK) > FSC_L3_TRANS_FAULT)
 		|| ((run->exit.esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U)) {
 		ERROR("Rec1 did not fault exit=0x%lx ret1=%d HPFAR=0x%lx esr=0x%lx\n",
 				run->exit.exit_reason, ret1, run->exit.hpfar, run->exit.esr);
@@ -1233,7 +1414,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 1U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG2_INDEX);
 	if (((esr & ISS_DFSC_MASK) != DFSC_NO_WALK_SEA) || (EC_BITS(esr) != EC_DABORT_CUR_EL)) {
 		ERROR("Rec1 incorrect ESR=0x%lx\n", esr);
 		goto destroy_realm;
@@ -1266,7 +1447,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -1283,7 +1464,7 @@
 	/* Enable FEAT_DIT on Host */
 	write_dit(DIT_BIT);
 	for (unsigned int i = 0; i < MAX_REC_COUNT; i++) {
-		host_shared_data_set_host_val(&realm, i, HOST_ARG1_INDEX, 10U);
+		host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, i, HOST_ARG1_INDEX, 10U);
 		ret1 = host_enter_realm_execute(&realm, REALM_DIT_CHECK_CMD,
 				RMI_EXIT_HOST_CALL, i);
 		if (!ret1) {
@@ -1500,7 +1681,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -1686,7 +1867,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -1747,8 +1928,8 @@
 	/* IPA outside Realm space */
 	base_ipa = base | (1UL << (EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ,
 					realm.rmm_feat_reg0) + 1U));
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base_ipa);
-	host_shared_data_set_host_val(&realm, 1U, HOST_ARG1_INDEX, base_ipa);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG1_INDEX, base_ipa);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG1_INDEX, base_ipa);
 
 	INFO("base_ipa=0x%lx\n", base_ipa);
 
@@ -1764,7 +1945,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 0U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG2_INDEX);
 	if (((esr & ISS_DFSC_MASK) != DFSC_NO_WALK_SEA)
 			|| (EC_BITS(esr) != EC_DABORT_CUR_EL)
 			|| ((esr & (1UL << ESR_ISS_EABORT_EA_BIT)) == 0U)) {
@@ -1784,7 +1965,7 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 1U, HOST_ARG2_INDEX);
+	esr = host_shared_data_get_realm_val(&realm, PRIMARY_PLANE_ID, 1U, HOST_ARG2_INDEX);
 	if (((esr & ISS_DFSC_MASK) != IFSC_NO_WALK_SEA)
 			|| (EC_BITS(esr) != EC_IABORT_CUR_EL)
 			|| ((esr & (1UL << ESR_ISS_EABORT_EA_BIT)) == 0U)) {
@@ -1799,8 +1980,8 @@
 
 	INFO("base_ipa=0x%lx\n", base_ipa);
 
-	host_shared_data_set_host_val(&realm, 2U, HOST_ARG1_INDEX, base_ipa);
-	host_shared_data_set_host_val(&realm, 3U, HOST_ARG1_INDEX, base_ipa);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 2U, HOST_ARG1_INDEX, base_ipa);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 3U, HOST_ARG1_INDEX, base_ipa);
 
 	run = (struct rmi_rec_run *)realm.run[2];
 
@@ -1814,8 +1995,8 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 2U, HOST_ARG2_INDEX);
-	if (((esr & ISS_DFSC_MASK) != DFSC_L0_ADR_SIZE_FAULT)
+	esr = host_shared_data_get_realm_val(&realm, PRIMARY_PLANE_ID, 2U, HOST_ARG2_INDEX);
+	if (((esr & ISS_DFSC_MASK) != FSC_L0_ADR_SIZE_FAULT)
 			|| (EC_BITS(esr) != EC_DABORT_CUR_EL)
 			|| ((esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U)) {
 		ERROR("Rec2 incorrect ESR=0x%lx\n", esr);
@@ -1834,8 +2015,8 @@
 	}
 
 	/* get ESR set by Realm exception handler */
-	esr = host_shared_data_get_realm_val(&realm, 3U, HOST_ARG2_INDEX);
-	if (((esr & ISS_IFSC_MASK) != IFSC_L0_ADR_SIZE_FAULT)
+	esr = host_shared_data_get_realm_val(&realm, PRIMARY_PLANE_ID, 3U, HOST_ARG2_INDEX);
+	if (((esr & ISS_IFSC_MASK) != FSC_L0_ADR_SIZE_FAULT)
 			|| (EC_BITS(esr) != EC_IABORT_CUR_EL)
 			|| ((esr & (1UL << ESR_ISS_EABORT_EA_BIT)) != 0U)) {
 		ERROR("Rec3 did not fault exit=0x%lx ret1=%d HPFAR=0x%lx esr=0x%lx\n",
@@ -1879,7 +2060,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -2036,7 +2217,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -2211,7 +2392,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -2326,7 +2507,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -2439,7 +2620,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -2552,7 +2733,7 @@
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 	SKIP_TEST_IF_DOUBLE_FAULT2_NOT_SUPPORTED();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -2581,10 +2762,10 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, base);
+	host_shared_data_set_host_val(&realm, 0U, 0U, HOST_ARG1_INDEX, base);
 
 	for (unsigned int i = 0U; i < 2U; i++) {
-		host_shared_data_set_host_val(&realm, 0U, HOST_ARG2_INDEX,
+		host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U, HOST_ARG2_INDEX,
 					      (unsigned long)i);
 
 		/* Rec0 expect IA due to SEA unassigned empty page */
@@ -2615,7 +2796,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
@@ -2656,7 +2837,7 @@
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	if (is_feat_52b_on_4k_2_supported() == true) {
+	if (is_feat_52b_on_4k_2_supported()) {
 		feature_flag = RMI_FEATURE_REGISTER_0_LPA2;
 		sl = RTT_MIN_LEVEL_LPA2;
 	}
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c
index 235e093..40e8590 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_simd_common.c
@@ -33,7 +33,7 @@
 
 	if (sve_en) {
 		feature_flag |= RMI_FEATURE_REGISTER_0_SVE_EN |
-				INPLACE(FEATURE_SVE_VL, sve_vq);
+				INPLACE(RMI_FEATURE_REGISTER_0_SVE_VL, sve_vq);
 	}
 
 	/* Initialise Realm payload */
diff --git a/tftf/tests/runtime_services/realm_payload/host_realm_spm.c b/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
index 8649014..e81d82d 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_spm.c
@@ -203,7 +203,9 @@
 	 * Spin Realm payload for REALM_TIME_SLEEP ms, This ensures secure wdog
 	 * timer triggers during this time.
 	 */
-	host_shared_data_set_host_val(&realm, 0U, HOST_ARG1_INDEX, REALM_TIME_SLEEP);
+	host_shared_data_set_host_val(&realm, PRIMARY_PLANE_ID, 0U,
+			HOST_ARG1_INDEX, REALM_TIME_SLEEP);
+
 	host_enter_realm_execute(&realm, REALM_SLEEP_CMD, RMI_EXIT_FIQ, 0U);
 
 	/*
diff --git a/tftf/tests/runtime_services/standard_service/errata_abi/api_tests/test_errata_abi_functionality.c b/tftf/tests/runtime_services/standard_service/errata_abi/api_tests/test_errata_abi_functionality.c
index 0baf471..91e5307 100644
--- a/tftf/tests/runtime_services/standard_service/errata_abi/api_tests/test_errata_abi_functionality.c
+++ b/tftf/tests/runtime_services/standard_service/errata_abi/api_tests/test_errata_abi_functionality.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -387,7 +387,23 @@
 em_cpu_t cortex_X4_errata_list = {
 	.cpu_pn = 0xD82,
 	.cpu_errata = {
-		{2701112, 0x00, 0x00},
+		{2726228, 0x00, 0x01},
+		{2740089, 0x00, 0x01},
+		{2763018, 0x00, 0x01},
+		{2816013, 0x00, 0x01},
+		{2897503, 0x00, 0x01},
+		{2923985, 0x00, 0x01},
+		{2957258, 0x00, 0x01},
+		{3076789, 0x00, 0x01},
+		{-1}
+	},
+};
+
+em_cpu_t cortex_X925_errata_list = {
+	.cpu_pn = 0xD85,
+	.cpu_errata = {
+		{2963999, 0x00, 0x00},
+		{3701747, 0x00, 0x01},
 		{-1}
 	},
 };
@@ -631,6 +647,12 @@
 		cpu_ptr =  &cortex_X4_errata_list;
 		break;
 	}
+	case 0xD85:
+	{
+		VERBOSE("MIDR matches Cortex-X925 -> %x\n", midr_val);
+		cpu_ptr =  &cortex_X925_errata_list;
+		break;
+	}
 	case 0xD4E:
 	{
 		VERBOSE("MIDR matches Cortex-X3 -> %x\n", midr_val);
diff --git a/tftf/tests/tests-cpu-extensions.mk b/tftf/tests/tests-cpu-extensions.mk
index 7375633..9358c49 100644
--- a/tftf/tests/tests-cpu-extensions.mk
+++ b/tftf/tests/tests-cpu-extensions.mk
@@ -34,4 +34,5 @@
 	runtime_services/arm_arch_svc/smccc_arch_workaround_2.c		\
 	runtime_services/arm_arch_svc/smccc_arch_workaround_3.c		\
 	runtime_services/arm_arch_svc/smccc_feature_availability.c	\
+	runtime_services/arm_arch_svc/smccc_arch_workaround_4.c		\
 )
diff --git a/tftf/tests/tests-cpu-extensions.xml b/tftf/tests/tests-cpu-extensions.xml
index 51aa27c..632e231 100644
--- a/tftf/tests/tests-cpu-extensions.xml
+++ b/tftf/tests/tests-cpu-extensions.xml
@@ -49,6 +49,7 @@
      <testcase name="SMCCC_ARCH_WORKAROUND_1 test" function="test_smccc_arch_workaround_1" />
      <testcase name="SMCCC_ARCH_WORKAROUND_2 test" function="test_smccc_arch_workaround_2" />
      <testcase name="SMCCC_ARCH_WORKAROUND_3 test" function="test_smccc_arch_workaround_3" />
+     <testcase name="SMCCC_ARCH_WORKAROUND_4 test" function="test_smccc_arch_workaround_4" />
      <testcase name="SMCCC_ARCH_SOC_ID test" function="test_smccc_arch_soc_id" />
      <testcase name="SMCCC_ARCH_FEATURE_AVAILABILITY test" function="test_smccc_arch_feature_availability" />
   </testsuite>
diff --git a/tftf/tests/tests-realm-payload.mk b/tftf/tests/tests-realm-payload.mk
index b6833e1..1fe01ed 100644
--- a/tftf/tests/tests-realm-payload.mk
+++ b/tftf/tests/tests-realm-payload.mk
@@ -16,6 +16,7 @@
 		host_realm_spm.c					\
 		host_realm_payload_simd_tests.c				\
 		host_realm_lpa2_tests.c					\
+		host_realm_mpam_tests.c					\
 	)
 
 TESTS_SOURCES	+=							\
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index da88701..c8747f6 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -8,6 +8,10 @@
 
 <testsuites>
   <testsuite name="Realm payload at EL1" description="Test Realm EL1 framework capabilities" >
+	  <testcase name="Realm Planes execution test"
+	  function="host_test_realm_create_planes_enter" />
+	  <testcase name="Realm Planes register read/write test"
+	  function="host_test_realm_create_planes_register_rw" />
 	  <testcase name="Realm EL1 creation and execution test"
 	  function="host_test_realm_create_enter" />
 	  <testcase name="Realm RTT fold unfold test Unassigned Empty"
@@ -66,8 +70,10 @@
 	  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" />
+	  <testcase name="PMUv3 cycle counter overflow interrupt"
+	  function="host_realm_pmuv3_cycle_overflow_interrupt" />
+	  <testcase name="PMUv3 event counter overflow interrupt"
+	  function="host_realm_pmuv3_event_overflow_interrupt" />
 	  <testcase name="PMUv3 multiple rec validations"
 	  function="host_realm_pmuv3_mul_rec" />
 	  <testcase name="Test Secure interrupt can preempt Realm EL1"
@@ -140,5 +146,10 @@
 	  <!-- Invoke RMI calls related to PDEV management -->
 	  <testcase name="Invoke RMI PDEV calls "
 	  function="host_test_rmi_pdev_calls" />
+	  <!-- Test cases related to FEAT_MPAM -->
+	  <testcase name="Test that FEAT_MPAM is hidden to the Realm"
+	  function="host_realm_hide_feat_mpam" />
+	  <testcase name="Test that access to FEAT_MPAM from Realm causes an undef abort taken to the Realm"
+	  function="host_realm_mpam_undef_abort" />
   </testsuite>
 </testsuites>
diff --git a/tftf/tests/tests-smcfuzzing.mk b/tftf/tests/tests-smcfuzzing.mk
index 2834e4e..9218da1 100644
--- a/tftf/tests/tests-smcfuzzing.mk
+++ b/tftf/tests/tests-smcfuzzing.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2023, Arm Limited. All rights reserved.
+# Copyright (c) 2024, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -11,6 +11,13 @@
 SMC_FUZZ_INSTANCE_COUNT ?= 1
 SMC_FUZZ_SEEDS ?= $(shell python -c "from random import randint; seeds = [randint(0, 4294967295) for i in range($(SMC_FUZZ_INSTANCE_COUNT))];print(\",\".join(str(x) for x in seeds));")
 SMC_FUZZ_CALLS_PER_INSTANCE ?= 100
+# ADDED: which fuzz call to start with per instance
+SMC_FUZZ_CALL_START ?= 0
+SMC_FUZZ_CALL_END ?= $(SMC_FUZZ_CALLS_PER_INSTANCE)
+# ADDED: define whether events should specifically be constrained
+EXCLUDE_FUNCID ?= 0
+CONSTRAIN_EVENTS ?= 0
+INTR_ASSERT ?= 0
 
 # Validate SMC fuzzer parameters
 
@@ -30,13 +37,47 @@
 $(error Number of seeds does not match SMC_FUZZ_INSTANCE_COUNT!)
 endif
 
+# Start must be nonnegative and less than calls per instance
+ifeq ($(shell test $(SMC_FUZZ_CALL_START) -lt 0; echo $$?),0)
+$(error SMC_FUZZ_CALL_START must be nonnegative!)
+endif
+
+ifeq ($(shell test $(SMC_FUZZ_CALL_START) -gt $(shell expr $(SMC_FUZZ_CALLS_PER_INSTANCE) - 1); echo $$?),0)
+$(error SMC_FUZZ_CALL_START must be less than SMC_FUZZ_CALLS_PER_INSTANCE!)
+endif
+
+# End must be greater than start and less than or equal to calls per instance
+ifneq ($(shell test $(SMC_FUZZ_CALL_START) -lt $(SMC_FUZZ_CALL_END); echo $$?),0)
+$(error SMC_FUZZ_CALL_END must be greater than SMC_FUZZ_CALL_START!)
+endif
+
+ifeq ($(shell test $(SMC_FUZZ_CALL_END) -gt $(SMC_FUZZ_CALLS_PER_INSTANCE); echo $$?),0)
+$(error SMC_FUZZ_CALL_END must not be greater than SMC_FUZZ_CALLS_PER_INSTANCE!)
+endif
+
+
 # Add definitions to TFTF_DEFINES so they can be used in the code
 $(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_SEEDS))
 $(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_INSTANCE_COUNT))
 $(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_CALLS_PER_INSTANCE))
+ifeq ($(SMC_FUZZER_DEBUG),1)
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZER_DEBUG))
+endif
 ifeq ($(MULTI_CPU_SMC_FUZZER),1)
 $(eval $(call add_define,TFTF_DEFINES,MULTI_CPU_SMC_FUZZER))
 endif
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_SANITY_LEVEL))
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_CALL_START))
+$(eval $(call add_define,TFTF_DEFINES,SMC_FUZZ_CALL_END))
+$(eval $(call add_define,TFTF_DEFINES,CONSTRAIN_EVENTS))
+$(eval $(call add_define,TFTF_DEFINES,EXCLUDE_FUNCID))
+$(eval $(call add_define,TFTF_DEFINES,INTR_ASSERT))
+
+TESTS_SOURCES	+=								\
+	$(addprefix tftf/tests/runtime_services/standard_service/sdei/system_tests/, \
+		sdei_entrypoint.S \
+		test_sdei.c \
+	)
 
 TESTS_SOURCES	+=							\
 	$(addprefix smc_fuzz/src/,					\
@@ -47,4 +88,6 @@
 		sdei_fuzz_helper.c					\
 		tsp_fuzz_helper.c					\
 		nfifo.c							\
+		constraint.c						\
+		vendor_fuzz_helper.c \
 	)
diff --git a/tools/generate_json/generate_json.sh b/tools/generate_json/generate_json.sh
index 5867700..9d51ba5 100755
--- a/tools/generate_json/generate_json.sh
+++ b/tools/generate_json/generate_json.sh
@@ -59,14 +59,16 @@
 	"image": "cactus.bin",
 	"pm": "cactus-secondary.dts",
 	"physical-load-address": "0x7100000",
-	"owner": "Plat"
+	"owner": "Plat",
+	"package": "tl_pkg"
 },
 
 "cactus-tertiary" : {
 	"image": "cactus.bin",
 	"pm": "cactus-tertiary.dts",
 	"physical-load-address": "0x7200000",
-	"owner": "Plat"
+	"owner": "Plat",
+	"package": "tl_pkg"
 EOF
 	PARTITION_ALREADY_PRESENT=true
 fi
@@ -81,7 +83,8 @@
 	"image": "ivy.bin",
 	"pm": "ivy-sel0.dts",
 	"physical-load-address": "0x7600000",
-	"owner": "Plat"
+	"owner": "Plat",
+	"package": "tl_pkg"
 }
 EOF
 
@@ -95,7 +98,8 @@
 	"image": "ivy.bin",
 	"pm": "ivy-sel1.dts",
 	"physical-load-address": "0x7600000",
-	"owner": "Plat"
+	"owner": "Plat",
+	"package":"tl_pkg"
 }
 EOF