Merge "feat: specify the secure partition package for an SP"
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/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index c640fc7..90d4706 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -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)
@@ -1661,6 +1665,24 @@
 #define POR_EL1			S3_0_C10_C2_4
 #define S2POR_EL1		S3_0_C10_C2_5
 
+/* Perm value encoding for S2POR_EL1 */
+#define PERM_LABEL_NO_ACCESS		U(0)
+#define PERM_LABEL_RESERVED_1		U(1)
+#define PERM_LABEL_MRO			U(2)
+#define PERM_LABEL_MRO_TL1		U(3)
+#define PERM_LABEL_WO			U(4)
+#define PERM_LABEL_RESERVED_5		U(5)
+#define PERM_LABEL_MRO_TL0		U(6)
+#define PERM_LABEL_MRO_TL01		U(7)
+#define PERM_LABEL_RO			U(8)
+#define PERM_LABEL_RO_uX		U(9)
+#define PERM_LABEL_RO_pX		U(10)
+#define PERM_LABEL_RO_upX		U(11)
+#define PERM_LABEL_RW			U(12)
+#define PERM_LABEL_RW_uX		U(13)
+#define PERM_LABEL_RW_pX		U(14)
+#define PERM_LABEL_RW_upX		U(15)
+
 /*******************************************************************************
  * FEAT_GCS - Guarded Control Stack Registers
  ******************************************************************************/
@@ -1683,4 +1705,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/timer.h b/include/lib/timer.h
index 0bfff01..ff57cbd 100644
--- a/include/lib/timer.h
+++ b/include/lib/timer.h
@@ -32,6 +32,8 @@
  */
 int tftf_initialise_timer(void);
 
+void tftf_initialise_timer_secondary_core(void);
+
 /*
  * Requests the timer framework to send an interrupt after milli_secs.
  * The interrupt is sent to the calling core of this api. The actual
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/ffa_helpers.h b/include/runtime_services/ffa_helpers.h
index 4dc3f53..0a63e96 100644
--- a/include/runtime_services/ffa_helpers.h
+++ b/include/runtime_services/ffa_helpers.h
@@ -357,8 +357,8 @@
  */
 struct ffa_partition_rxtx_header {
 	uint32_t flags;
-	/* MBZ */
-	uint32_t reserved;
+	/* Reserved (SBZ). */
+	uint32_t reserved_1;
 	/* Offset from the beginning of the buffer to the message payload. */
 	uint32_t offset;
 	/* Sender(Bits[31:16]) and Receiver(Bits[15:0]) endpoint IDs. */
@@ -366,6 +366,10 @@
 	ffa_id_t sender;
 	/* Size of message in buffer. */
 	uint32_t size;
+	/* Reserved (SBZ). Added in v1.2 */
+	uint32_t reserved_2;
+	/* UUID identifying the communication protocol. Added in v1.2. */
+	struct ffa_uuid uuid;
 };
 
 #define FFA_RXTX_HEADER_SIZE sizeof(struct ffa_partition_rxtx_header)
@@ -375,11 +379,13 @@
 	struct ffa_partition_rxtx_header *header)
 {
 	header->flags = 0;
-	header->reserved = 0;
+	header->reserved_1 = 0;
 	header->offset = FFA_RXTX_HEADER_SIZE;
 	header->sender = sender;
 	header->receiver = receiver;
 	header->size = size;
+	header->reserved_2 = 0;
+	header->uuid = (struct ffa_uuid){0};
 }
 
 /* The maximum length possible for a single message. */
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 168bb0a..6ea9b72 100644
--- a/include/runtime_services/host_realm_managment/host_realm_helper.h
+++ b/include/runtime_services/host_realm_managment/host_realm_helper.h
@@ -18,7 +18,8 @@
 		u_register_t feature_flag,
 		long sl,
 		const u_register_t *rec_flag,
-		unsigned int rec_count);
+		unsigned int rec_count,
+		unsigned int num_aux_planes);
 
 /*
  * Creates realm, initializes heap, creates RTTs and also
@@ -29,7 +30,8 @@
 		u_register_t feature_flag,
 		long sl,
 		const u_register_t *rec_flag,
-		unsigned int rec_count);
+		unsigned int rec_count,
+		unsigned int num_aux_planes);
 
 /*
  * Creates realm, initializes heap, creates RTTs,
@@ -40,14 +42,21 @@
 		u_register_t feature_flag,
 		long sl,
 		const u_register_t *rec_flag,
-		unsigned int rec_count);
+		unsigned int rec_count,
+		unsigned int num_aux_planes);
 bool host_destroy_realm(struct realm *realm_ptr);
 void host_rec_send_sgi(struct realm *realm_ptr,
 		unsigned int sgi, unsigned int rec_num);
 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_mem_layout.h b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
index 7458146..1bef986 100644
--- a/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
+++ b/include/runtime_services/host_realm_managment/host_realm_mem_layout.h
@@ -41,8 +41,8 @@
 #ifdef ENABLE_REALM_PAYLOAD_TESTS
  /* 1MB for shared buffer between Realm and Host */
  #define NS_REALM_SHARED_MEM_SIZE	U(0x100000)
- /* 8MB of memory used as a pool for realm's objects creation */
- #define PAGE_POOL_MAX_SIZE		U(0x800000)
+ /* 10MB of memory used as a pool for realm's objects creation */
+ #define PAGE_POOL_MAX_SIZE		U(0xA00000)
 #else
  #define NS_REALM_SHARED_MEM_SIZE       U(0x0)
  #define PAGE_POOL_MAX_SIZE             U(0x0)
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..66bd385 100644
--- a/include/runtime_services/host_realm_managment/host_realm_pmu.h
+++ b/include/runtime_services/host_realm_managment/host_realm_pmu.h
@@ -23,7 +23,25 @@
 #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;
+	unsigned long pmxevcntr_el0;
+	unsigned long pmxevtyper_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 8f487d0..4de9671 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -146,6 +146,30 @@
 
 /*
  * arg0 == RD address
+ * arg1 == RTT address
+ * arg2 == map address
+ * arg3 == level
+ * arg4 == RTT tree index
+ *
+ * ret0 == status/index
+ */
+#define RMI_RTT_AUX_CREATE		SMC64_RMI_FID(U(0x2D))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
+ * arg2 == level
+ * arg3 == RTT tree index
+ *
+ * ret1 == Address (PA) of the RTT, if ret0 == RMI_SUCCESS
+ *         Otherwise, undefined.
+ * ret2 == Top of the non-live address region. Only valid
+ *         if ret0 == RMI_SUCCESS or ret0 == (RMI_ERROR_RTT_WALK, x)
+ */
+#define RMI_RTT_AUX_DESTROY		SMC64_RMI_FID(U(0x2E))
+
+/*
+ * arg0 == RD address
  * arg1 == map address
  * arg2 == level
  *
@@ -167,6 +191,31 @@
 /*
  * arg0 == RD address
  * arg1 == map address
+ * arg2 == RTT tree index
+ *
+ * ret0 == status/index
+ * ret1 == fail_index
+ * ret2 == primary level
+ * ret3 == state
+ * ret4 == ripas
+ */
+#define RMI_RTT_AUX_MAP_PROTECTED	SMC64_RMI_FID(U(0x30))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
+ * arg2 == RTT tree index
+ *
+ * ret0 == status/index
+ * ret1 == fail_index
+ * ret2 == primary level
+ * ret3 == state
+ */
+#define RMI_RTT_AUX_MAP_UNPROTECTED	SMC64_RMI_FID(U(0x31))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
  * arg2 == level
  *
  * ret1 == level
@@ -185,6 +234,40 @@
 #define RMI_RTT_UNMAP_UNPROTECTED	SMC64_RMI_FID(U(0x12))
 
 /*
+ * arg0 == RD address
+ * arg1 == map address
+ * arg2 == RTT tree index
+ *
+ * ret0 == status/index
+ * ret1 == top
+ * ret2 == level
+ */
+#define RMI_RTT_AUX_UNMAP_PROTECTED	SMC64_RMI_FID(U(0x33))
+
+/*
+ * arg0 == RD address
+ * arg1 == map address
+ * arg2 == RTT tree index
+ *
+ * ret0 == status/index
+ * ret1 == top
+ * ret2 == level
+ */
+#define RMI_RTT_AUX_UNMAP_UNPROTECTED	SMC64_RMI_FID(U(0x34))
+
+/*
+ * arg0 == RD address
+ * arg1 == target rec
+ * arg2 == base adr
+ * arg3 == top adr
+ *
+ * ret0 == return code
+ * ret1 == Top IPA of range whose S2AP was modified
+ * ret2 == Index of RTT tree in which base alignment check failed
+ */
+#define RMI_RTT_SET_S2AP		SMC64_RMI_FID(U(0x3B))
+
+/*
  * arg0 == calling rec address
  * arg1 == target rec address
  */
@@ -206,6 +289,16 @@
 
 /*
  * arg0 == RD address
+ * arg1 == map address
+ * arg2 == level
+ * arg3 == RTT tree index
+ *
+ * ret1 == Address(PA) of the RTT folded, if ret0 == RMI_SUCCESS
+ */
+#define RMI_RTT_AUX_FOLD		SMC64_RMI_FID(U(0x2F))
+
+/*
+ * arg0 == RD address
  */
 #define RMI_REC_AUX_COUNT		SMC64_RMI_FID(U(0x17))
 
@@ -398,10 +491,14 @@
 #define RMI_FEATURE_FALSE		0U
 #define RMI_FEATURE_TRUE		1U
 
-/* RmiRealmFlags format */
-#define RMI_REALM_FLAGS_LPA2		BIT(0)
-#define RMI_REALM_FLAGS_SVE		BIT(1)
-#define RMI_REALM_FLAGS_PMU		BIT(2)
+/* RmiRealmFlags0 format */
+#define RMI_REALM_FLAGS0_LPA2		BIT(0)
+#define RMI_REALM_FLAGS0_SVE		BIT(1)
+#define RMI_REALM_FLAGS0_PMU		BIT(2)
+#define RMI_REALM_FLAGS0_DA		BIT(3)
+
+/* RmiRealmFlags1 format */
+#define RMI_REALM_FLAGS1_RTT_TREE_PP	BIT(0)
 
 /* RmiInterfaceVersion type */
 #define RMI_MAJOR_VERSION		0U
@@ -426,7 +523,11 @@
 #define RMI_EXIT_RIPAS_CHANGE		4U
 #define RMI_EXIT_HOST_CALL		5U
 #define RMI_EXIT_SERROR			6U
-#define RMI_EXIT_INVALID		(RMI_EXIT_SERROR + 1U)
+#define RMI_EXIT_IO			7U
+#define RMI_EXIT_RTT_REQUEST		8U
+#define RMI_EXIT_S2AP_CHANGE		9U
+#define RMI_EXIT_VDEV_REQUEST		10U
+#define RMI_EXIT_INVALID		(RMI_EXIT_VDEV_REQUEST + 1U)
 
 /* RmiRecRunnable types */
 #define RMI_NOT_RUNNABLE		0U
@@ -473,14 +574,27 @@
  * Value -1 (0 in case of NUM_BPS and NUM_WPS) indicates not set field,
  * and parameter will be set from the corresponding field of feature register 0.
  */
-#define FEATURE_SVE_VL_SHIFT				32UL
-#define FEATURE_SVE_VL_WIDTH				8UL
-#define FEATURE_NUM_BPS_SHIFT				40UL
-#define FEATURE_NUM_BPS_WIDTH				8UL
-#define FEATURE_NUM_WPS_SHIFT				48UL
-#define FEATURE_NUM_WPS_WIDTH				8UL
-#define FEATURE_PMU_NUM_CTRS_SHIFT			56UL
-#define FEATURE_PMU_NUM_CTRS_WIDTH			8UL
+#define RMI_FEATURE_REGISTER_0_DA			BIT(42)
+
+#define RMI_FEATURE_REGISTER_0_PLANE_RTT_SHIFT		43UL
+#define RMI_FEATURE_REGISTER_0_PLANE_RTT_WIDTH		2UL
+
+#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
+#define RMI_PLANE_RTT_SINGLE				2UL
 
 /* RmiStatusCode types */
 /*
@@ -520,6 +634,18 @@
 	 * index: RTT level at which the walk terminated
 	 */
 	RMI_ERROR_RTT = 4,
+	/*
+	 * An attribute of a device does not match the expected value
+	 */
+	RMI_ERROR_DEVICE = 5,
+	/*
+	 * The command is not supported
+	 */
+	RMI_ERROR_NOT_SUPPORTED = 6,
+	/*
+	 * RTTE in an auxiliary RTT contained an unexpected value
+	 */
+	RMI_ERROR_RTT_AUX = 7,
 	RMI_ERROR_COUNT
 } status_t;
 
@@ -560,31 +686,41 @@
  */
 struct rmi_realm_params {
 	/* Flags */
-	SET_MEMBER(unsigned long flags, 0, 0x8);		/* Offset 0 */
+	SET_MEMBER(unsigned long flags0, 0, 0x8);			/* Offset 0 */
 	/* Requested IPA width */
-	SET_MEMBER(unsigned int s2sz, 0x8, 0x10);		/* 0x8 */
+	SET_MEMBER(unsigned int s2sz, 0x8, 0x10);			/* 0x8 */
 	/* Requested SVE vector length */
-	SET_MEMBER(unsigned int sve_vl, 0x10, 0x18);		/* 0x10 */
+	SET_MEMBER(unsigned int sve_vl, 0x10, 0x18);			/* 0x10 */
 	/* Requested number of breakpoints */
-	SET_MEMBER(unsigned int num_bps, 0x18, 0x20);		/* 0x18 */
+	SET_MEMBER(unsigned int num_bps, 0x18, 0x20);			/* 0x18 */
 	/* Requested number of watchpoints */
-	SET_MEMBER(unsigned int num_wps, 0x20, 0x28);		/* 0x20 */
+	SET_MEMBER(unsigned int num_wps, 0x20, 0x28);			/* 0x20 */
 	/* Requested number of PMU counters */
-	SET_MEMBER(unsigned int pmu_num_ctrs, 0x28, 0x30);	/* 0x28 */
+	SET_MEMBER(unsigned int pmu_num_ctrs, 0x28, 0x30);		/* 0x28 */
 	/* Measurement algorithm */
-	SET_MEMBER(unsigned char hash_algo, 0x30, 0x400);	/* 0x30 */
+	SET_MEMBER(unsigned char algorithm, 0x30, 0x38);		/* 0x30 */
+	/* Number of auxiliary Planes */
+	SET_MEMBER(unsigned int num_aux_planes, 0x38, 0x400);		/* 0x38 */
 	/* Realm Personalization Value */
-	SET_MEMBER(unsigned char rpv[RPV_SIZE], 0x400, 0x800);	/* 0x400 */
+	SET_MEMBER(unsigned char rpv[RPV_SIZE], 0x400, 0x800);		/* 0x400 */
 	SET_MEMBER(struct {
-		/* Virtual Machine Identifier */
-		unsigned short vmid;				/* 0x800 */
-		/* Realm Translation Table base */
-		u_register_t rtt_base;				/* 0x808 */
-		/* RTT starting level */
-		long rtt_level_start;				/* 0x810 */
-		/* Number of starting level RTTs */
-		unsigned int rtt_num_start;			/* 0x818 */
-	}, 0x800, 0x1000);
+			/* Virtual Machine Identifier */
+			unsigned short vmid;				/* 0x800 */
+			/* Realm Translation Table base */
+			unsigned long rtt_base;				/* 0x808 */
+			/* RTT starting level */
+			long rtt_level_start;				/* 0x810 */
+			/* Number of starting level RTTs */
+			unsigned int rtt_num_start;			/* 0x818 */
+		   }, 0x800, 0x820);
+	/* Flags */
+	SET_MEMBER(unsigned long flags1, 0x820, 0x828);			/* 0x820 */
+	/* MECID */
+	SET_MEMBER(long mecid, 0x828, 0xF00);				/* 0x828 */
+	/* Auxiliary Virtual Machine Identifiers */
+	SET_MEMBER(unsigned short aux_vmid[3], 0xF00, 0xF80);		/* 0xF00 */
+	/* Base address of auxiliary RTTs */
+	SET_MEMBER(unsigned long aux_rtt_base[3], 0xF80, 0x1000);	/* 0xF80 */
 };
 
 /*
@@ -651,7 +787,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 {
@@ -681,7 +821,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 */
@@ -959,6 +1107,7 @@
 struct realm {
 	u_register_t     host_shared_data;
 	unsigned int     rec_count;
+	unsigned int     num_aux_planes;
 	u_register_t     par_base;
 	u_register_t     par_size;
 	u_register_t     rd;
@@ -979,9 +1128,12 @@
 	uint8_t          pmu_num_ctrs;
 	bool             payload_created;
 	bool             shared_mem_created;
+	bool             rtt_tree_single;
 	unsigned short   vmid;
 	enum realm_state state;
 	long start_level;
+	u_register_t     aux_rtt_addr[MAX_AUX_PLANE_COUNT];
+	unsigned short   aux_vmid[MAX_AUX_PLANE_COUNT];
 };
 
 /* RMI/SMC */
@@ -1020,6 +1172,12 @@
 				    u_register_t start,
 				    u_register_t end,
 				    u_register_t *top);
+u_register_t host_rmi_rtt_set_s2ap(u_register_t rd,
+				   u_register_t rec,
+				   u_register_t start,
+				   u_register_t end,
+				   u_register_t *top,
+				   u_register_t *rtt_tree);
 u_register_t host_rmi_psci_complete(u_register_t calling_rec, u_register_t target_rec,
 				    unsigned long status);
 void host_rmi_init_cmp_result(void);
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..fecb27b 100644
--- a/include/runtime_services/host_realm_managment/host_shared_data.h
+++ b/include/runtime_services/host_realm_managment/host_shared_data.h
@@ -36,8 +36,9 @@
 
 	/* 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
  */
@@ -73,7 +74,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 +85,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 +104,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 +141,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 +163,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/host_realm_managment/realm_def.h b/include/runtime_services/host_realm_managment/realm_def.h
index 226034f..5d3a196 100644
--- a/include/runtime_services/host_realm_managment/realm_def.h
+++ b/include/runtime_services/host_realm_managment/realm_def.h
@@ -10,7 +10,7 @@
 
 #include <xlat_tables_defs.h>
 
-/* 1MB for Realm payload as a default value */
+/* 1 MB for Realm payload as a default value */
 #define REALM_MAX_LOAD_IMG_SIZE		U(0x100000)
 #define REALM_STACK_SIZE		0x1000U
 #define DATA_PATTERN_1			0x12345678U
@@ -19,6 +19,10 @@
 #define REALM_ERROR			1U
 #define MAX_REC_COUNT			17U
 #define MAX_REALM_COUNT			U(2)
+#define MAX_AUX_PLANE_COUNT		U(3)
+#define MAX_PLANE_COUNT			MAX_AUX_PLANE_COUNT + U(1)
+#define PRIMARY_RTT_INDEX		0U
+#define PRIMARY_PLANE_ID		0U
 
 /* Only support 4KB at the moment */
 
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/include/runtime_services/spm_test_helpers.h b/include/runtime_services/spm_test_helpers.h
index 93027d6..14b2fb5 100644
--- a/include/runtime_services/spm_test_helpers.h
+++ b/include/runtime_services/spm_test_helpers.h
@@ -104,12 +104,6 @@
                                       event_t *cpu_booted);
 
 /**
- * Call FFA_RUN in the designated SP to make it reach the message loop.
- * Used within CPU_ON handlers, to bring up the SP in the current core.
- */
-bool spm_core_sp_init(ffa_id_t sp_id);
-
-/**
  * Initializes the Mailbox for other SPM related tests that need to use
  * RXTX buffers.
  */
diff --git a/lib/power_management/hotplug/hotplug.c b/lib/power_management/hotplug/hotplug.c
index 76fa287..3981aa9 100644
--- a/lib/power_management/hotplug/hotplug.c
+++ b/lib/power_management/hotplug/hotplug.c
@@ -254,7 +254,7 @@
 	tftf_prepare_cpu_off();
 	tftf_set_cpu_offline();
 
-	INFO("Powering off\n");
+	INFO("Powering off CPU:%lx\n", read_mpidr_el1());
 
 	/* Flush console before the last CPU is powered off. */
 	if (tftf_get_ref_cnt() == 0)
@@ -303,10 +303,11 @@
 
 	/* Enable the SGI used by the timer management framework */
 	tftf_irq_enable(IRQ_WAKE_SGI, GIC_HIGHEST_NS_PRIORITY);
+	tftf_initialise_timer_secondary_core();
 
 	enable_irq();
 
-	INFO("Booting\n");
+	INFO("Booting CPU:%lx\n", read_mpidr_el1());
 
 	tftf_set_cpu_online();
 
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 11c4423..7ed8f9b 100644
--- a/realm/include/realm_helpers.h
+++ b/realm/include/realm_helpers.h
@@ -8,8 +8,34 @@
 #ifndef REALM_HELPERS_H
 #define REALM_HELPERS_H
 
+#include <realm_rsi.h>
+
 /* Generate 64-bit random number */
 unsigned long long realm_rand64(void);
+/*
+ * Function to enter Aux Plane from Primary Plane
+ * arg1 == plane index
+ * arg2 == permission index to be used by plane
+ * arg3 == base entrypoint
+ * arg4 == entry flags
+ * aarg5 == run object, needs to be PAGE aligned
+ */
+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 72ee80e..06f857f 100644
--- a/realm/include/realm_rsi.h
+++ b/realm/include/realm_rsi.h
@@ -8,6 +8,7 @@
 #ifndef REALM_RSI_H
 #define REALM_RSI_H
 
+#include <arch.h>
 #include <stdint.h>
 #include <host_shared_data.h>
 #include <tftf_lib.h>
@@ -71,7 +72,9 @@
 	/* IPA width in bits */
 	SET_MEMBER(unsigned long ipa_width, 0, 8);	/* Offset 0 */
 	/* Hash algorithm */
-	SET_MEMBER(unsigned long algorithm, 8, 0x200);	/* Offset 8 */
+	SET_MEMBER(unsigned long algorithm, 8, 0x10);	/* Offset 8 */
+	/* Number of auxiliary Planes */
+	SET_MEMBER(unsigned long num_aux_planes, 0x10, 0x200); /* Offset 0x10 */
 	/* Realm Personalization Value */
 	SET_MEMBER(unsigned char rpv[RSI_RPV_SIZE], 0x200, 0x1000); /* Offset 0x200 */
 };
@@ -157,7 +160,157 @@
 #define RSI_NO_CHANGE_DESTROYED	0UL
 #define RSI_CHANGE_DESTROYED	1UL
 
-/* Request RIPAS of a target IPA range to be changed to a specified value */
+/*
+ * arg1 == plane index
+ * arg2 == perm index
+ *
+ * ret0 == status
+ * ret1 == perm value
+ */
+#define RSI_MEM_GET_PERM_VALUE	SMC_RSI_FID(0x10U)
+
+/*
+ * arg1 == base adr
+ * arg2 == top adr
+ * arg3 == perm index
+ * arg4 == cookie
+ *
+ * ret0 == status
+ * ret1 == new_base
+ * ret2 == response
+ * ret3 == new_cookie
+ */
+#define RSI_MEM_SET_PERM_INDEX	SMC_RSI_FID(0x11U)
+
+/*
+ * arg1 == plane index
+ * arg2 == perm index
+ *
+ * ret0 == status
+ */
+#define RSI_MEM_SET_PERM_VALUE	SMC_RSI_FID(0x12U)
+
+#define RSI_PLANE_NR_GPRS	31U
+#define RSI_PLANE_GIC_NUM_LRS	16U
+
+/*
+ * Flags provided by the Primary Plane to the secondary ones upon
+ * plane entry.
+ */
+#define RSI_PLANE_ENTRY_FLAG_TRAP_WFI	U(1UL << 0)
+#define RSI_PLANE_ENTRY_FLAG_TRAP_WFE	U(1UL << 1)
+#define RSI_PLANE_ENTRY_FLAG_TRAP_HC	U(1UL << 2)
+
+/* Data structure used to pass values from P0 to the RMM on Plane entry */
+struct rsi_plane_entry {
+	/* Flags */
+	SET_MEMBER(u_register_t flags, 0, 0x8);	/* Offset 0 */
+	/* PC */
+	SET_MEMBER(u_register_t pc, 0x8, 0x100);	/* Offset 0x8 */
+	/* General-purpose registers */
+	SET_MEMBER(u_register_t gprs[RSI_PLANE_NR_GPRS], 0x100, 0x200);	/* 0x100 */
+	/* EL1 system registers */
+	SET_MEMBER(struct {
+		/* GICv3 Hypervisor Control Register */
+		u_register_t gicv3_hcr;                         /* 0x200 */
+		/* GICv3 List Registers */
+		u_register_t gicv3_lrs[RSI_PLANE_GIC_NUM_LRS];        /* 0x208 */
+	}, 0x200, 0x800);
+};
+
+/* Data structure used to pass values from the RMM to P0 on Plane exit */
+struct rsi_plane_exit {
+	/* Exit reason */
+	SET_MEMBER(u_register_t exit_reason, 0, 0x100);/* Offset 0 */
+	SET_MEMBER(struct {
+		/* Exception Link Register */
+		u_register_t elr;				/* 0x100 */
+		/* Exception Syndrome Register */
+		u_register_t esr;				/* 0x108 */
+		/* Fault Address Register */
+		u_register_t far;				/* 0x108 */
+		/* Hypervisor IPA Fault Address register */
+		u_register_t hpfar;				/* 0x110 */
+	}, 0x100, 0x200);
+	/* General-purpose registers */
+	SET_MEMBER(u_register_t gprs[RSI_PLANE_NR_GPRS], 0x200, 0x300); /* 0x200 */
+	SET_MEMBER(struct {
+		/* GICv3 Hypervisor Control Register */
+		u_register_t gicv3_hcr;				/* 0x300 */
+		/* GICv3 List Registers */
+		u_register_t gicv3_lrs[RSI_PLANE_GIC_NUM_LRS];	/* 0x308 */
+		/* GICv3 Maintenance Interrupt State Register */
+		u_register_t gicv3_misr;			/* 0x388 */
+		/* GICv3 Virtual Machine Control Register */
+		u_register_t gicv3_vmcr;			/* 0x390 */
+	}, 0x300, 0x600);
+};
+
+typedef struct {
+	/* Entry information */
+	SET_MEMBER(struct rsi_plane_entry enter, 0, 0x800); /* Offset 0 */
+	/* Exit information */
+	SET_MEMBER(struct rsi_plane_exit exit, 0x800, 0x1000);/* 0x800 */
+} rsi_plane_run;
+
+/*
+ * arg1 == plane index
+ * arg2 == run pointer
+ *
+ * ret0 == status
+ */
+#define RSI_PLANE_ENTER		SMC_RSI_FID(0x13U)
+
+/*
+ * arg1 == plane index
+ * arg2 == register encoding
+ *
+ * ret0 == status
+ * ret1 = register value
+ */
+#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
+ * arg3 == register value
+ *
+ * ret0 == status
+ */
+#define RSI_PLANE_REG_WRITE	SMC_RSI_FID(0x1FU)
+
+/*
+ * Function to set overlay permission value for a specified
+ * (plane index, overlay permission index) tuple
+ */
+u_register_t rsi_mem_set_perm_value(u_register_t plane_index,
+	u_register_t perm_index,
+	u_register_t perm);
+
+/*
+ * Function to Get overlay permission value for a specified
+ * (plane index, overlay permission index) tuple
+ */
+u_register_t rsi_mem_get_perm_value(u_register_t plane_index,
+	u_register_t perm_index,
+	u_register_t *perm);
+
+/* Function to Set overlay permission index for a specified IPA range See RSI_MEM_SET_PERM_INDEX */
+u_register_t rsi_mem_set_perm_index(u_register_t base,
+	u_register_t top,
+	u_register_t perm_index,
+	u_register_t cookie,
+	u_register_t *new_base,
+	u_register_t *response,
+	u_register_t *new_cookie);
+
+/* Request RIPAS of a target IPA range to be changed to a specified value. */
 u_register_t rsi_ipa_state_set(u_register_t base,
 				u_register_t top,
 				rsi_ripas_type ripas,
@@ -174,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,
@@ -195,6 +345,12 @@
 					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);
+
+/* Function to enter aux plane. See RSI_PLANE_ENTER */
+u_register_t rsi_plane_enter(u_register_t plane_index, u_register_t run);
 
 #endif /* REALM_RSI_H */
diff --git a/realm/realm.mk b/realm/realm.mk
index 3e66adc..7d21ed5 100644
--- a/realm/realm.mk
+++ b/realm/realm.mk
@@ -34,8 +34,10 @@
 	realm_multiple_rec.c						\
 	realm_pauth.c							\
 	realm_payload_main.c						\
+	realm_plane.c							\
 	realm_pmuv3.c							\
 	realm_psci.c							\
+	realm_psi.c							\
 	realm_rsi.c							\
 	realm_shared_data.c						\
 	realm_simd.c							\
@@ -44,6 +46,7 @@
 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..bf47efc 100644
--- a/realm/realm_helpers.c
+++ b/realm/realm_helpers.c
@@ -5,6 +5,10 @@
  */
 
 #include <stdlib.h>
+#include <realm_helpers.h>
+#include <realm_psi.h>
+#include <realm_rsi.h>
+#include <smccc.h>
 
 /* Generate 64-bit random number */
 unsigned long long realm_rand64(void)
@@ -12,3 +16,26 @@
 	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];
+}
diff --git a/realm/realm_payload_main.c b/realm/realm_payload_main.c
index 3339b9a..aeadb9e 100644
--- a/realm/realm_payload_main.c
+++ b/realm/realm_payload_main.c
@@ -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,12 @@
 			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_MULTIPLE_REC_PSCI_DENIED_CMD:
 			test_succeed = test_realm_multiple_rec_psci_denied_cmd();
 			break;
@@ -381,8 +491,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
new file mode 100644
index 0000000..c7225ed
--- /dev/null
+++ b/realm/realm_plane.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+#include <stdio.h>
+#include <arch.h>
+#include <arch_features.h>
+#include <assert.h>
+#include <debug.h>
+
+#include <host_realm_helper.h>
+#include <realm_psi.h>
+#include <realm_rsi.h>
+#include <sync.h>
+
+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)
+{
+	u_register_t ret;
+
+	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;
+	}
+}
+
+static void restore_plane_context(rsi_plane_run *run)
+{
+	for (unsigned int i = 0U; i < RSI_PLANE_NR_GPRS; i++) {
+		run->enter.gprs[i] = run->exit.gprs[i];
+	}
+
+	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 */
+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 PSI_RETURN_TO_PN;
+	}
+
+	/* 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;
+}
+
+bool plane_common_init(u_register_t plane_index,
+		u_register_t perm_index,
+		u_register_t base,
+		rsi_plane_run *run)
+{
+	u_register_t ret;
+
+	memset(run, 0, sizeof(rsi_plane_run));
+	run->enter.pc = base;
+
+	/* Perm init */
+	ret = rsi_mem_set_perm_value(plane_index, perm_index, PERM_LABEL_RW_upX);
+	if (ret != RSI_SUCCESS) {
+		ERROR("rsi_mem_set_perm_value failed %u\n", plane_index);
+		return false;
+	}
+	return true;
+}
+
+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)
+{
+	u_register_t ret;
+
+	run->enter.flags = flags;
+
+	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);
+			return false;
+		}
+
+		VERBOSE("plane exit_reason=0x%lx esr=0x%lx hpfar=0x%lx far=0x%lx\n",
+				run->exit.exit_reason,
+				run->exit.esr,
+				run->exit.hpfar,
+				run->exit.far);
+
+		ret = handle_plane_exit(plane_index, perm_index, run);
+
+		if (ret != PSI_RETURN_TO_PN) {
+			return true;
+		}
+	}
+}
+
diff --git a/realm/realm_pmuv3.c b/realm/realm_pmuv3.c
index 0d4782a..214f6df 100644
--- a/realm/realm_pmuv3.c
+++ b/realm/realm_pmuv3.c
@@ -19,7 +19,6 @@
 #define PMU_EVT_MEM_ACCESS	0x13
 
 #define NOP_REPETITIONS		50
-#define MAX_COUNTERS		32
 
 #define PRE_OVERFLOW		~(0xF)
 
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 db2394c..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>
 
@@ -22,34 +23,27 @@
 	if (res.ret0 == SMC_UNKNOWN) {
 		return SMC_UNKNOWN;
 	}
+
+	if (res.ret0 == RSI_ERROR_STATE) {
+		return RSI_ERROR_STATE;
+	}
+
 	/* Return lower version */
 	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 */
@@ -141,3 +135,92 @@
 	}
 	return res.ret0;
 }
+
+u_register_t rsi_realm_config(struct rsi_realm_config *s)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+			{RSI_REALM_CONFIG, (u_register_t)s});
+	return res.ret0;
+}
+
+u_register_t rsi_mem_get_perm_value(u_register_t plane_index,
+				    u_register_t perm_index,
+				    u_register_t *perm)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+			{RSI_MEM_GET_PERM_VALUE, plane_index, perm_index});
+	if (res.ret0 == RSI_SUCCESS) {
+		*perm = res.ret1;
+	}
+	return res.ret0;
+}
+
+u_register_t rsi_mem_set_perm_value(u_register_t plane_index,
+				    u_register_t perm_index,
+				    u_register_t perm)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+			{RSI_MEM_SET_PERM_VALUE, plane_index, perm_index, perm});
+	return res.ret0;
+}
+
+u_register_t rsi_mem_set_perm_index(u_register_t base,
+				    u_register_t top,
+				    u_register_t perm_index,
+				    u_register_t cookie,
+				    u_register_t *new_base,
+				    u_register_t *response,
+				    u_register_t *new_cookie)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+			{RSI_MEM_SET_PERM_INDEX, base, top, perm_index, cookie});
+	if (res.ret0 == RSI_SUCCESS) {
+		*new_base = res.ret1;
+		*response = res.ret2;
+		*new_cookie = res.ret3;
+	}
+	return res.ret0;
+}
+
+u_register_t rsi_plane_enter(u_register_t plane_index,
+			     u_register_t plane_run)
+{
+	smc_ret_values res = {};
+
+	res = tftf_smc(&(smc_args)
+			{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/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/cactus_main.c b/spm/cactus/cactus_main.c
index b608d7b..c15ee4e 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -61,8 +61,9 @@
 	ffa_ret = ffa_msg_wait();
 
 	for (;;) {
-		VERBOSE("Woke up with func id: %s\n",
-			ffa_func_name(ffa_func_id(ffa_ret)));
+		VERBOSE("Woke up with func:%s  id: %x\n",
+			ffa_func_name(ffa_func_id(ffa_ret)),
+			ffa_func_id(ffa_ret));
 
 		if (ffa_func_id(ffa_ret) == FFA_ERROR) {
 			ERROR("Error: %s\n",
@@ -74,7 +75,7 @@
 		    ffa_func_id(ffa_ret) != FFA_MSG_SEND_DIRECT_REQ_SMC64 &&
 		    ffa_func_id(ffa_ret) != FFA_INTERRUPT &&
 		    ffa_func_id(ffa_ret) != FFA_RUN) {
-			ERROR("%s(%u) unknown func id %s\n", __func__, vm_id,
+			ERROR("%s(%x) unknown func id %s\n", __func__, vm_id,
 			      ffa_func_name(ffa_func_id(ffa_ret)));
 			break;
 		}
@@ -87,10 +88,15 @@
 			 * informational as we're running with virtual
 			 * interrupts unmasked and the interrupt is processed
 			 * by the interrupt handler.
-			 *
-			 * Received FFA_RUN in waiting state, the endpoint
-			 * simply returns by FFA_MSG_WAIT.
 			 */
+			if (ffa_func_id(ffa_ret) == FFA_RUN) {
+				/*
+				 * Received FFA_RUN in waiting state, the
+				 * endpoint simply returns by FFA_MSG_WAIT.
+				 */
+				VERBOSE("Nothing to do. Exit to NWd\n");
+			}
+
 			ffa_ret = ffa_msg_wait();
 			continue;
 		}
diff --git a/tftf/framework/timer/timer_framework.c b/tftf/framework/timer/timer_framework.c
index 49fd07f..46fe987 100644
--- a/tftf/framework/timer/timer_framework.c
+++ b/tftf/framework/timer/timer_framework.c
@@ -96,6 +96,14 @@
 	return 0;
 }
 
+void tftf_initialise_timer_secondary_core(void)
+{
+	if (!IS_SPI(TIMER_IRQ)) {
+		arm_gic_set_intr_priority(TIMER_IRQ, GIC_HIGHEST_NS_PRIORITY);
+		arm_gic_intr_enable(TIMER_IRQ);
+	}
+}
+
 /*
  * It returns the core number of next timer request to be serviced or
  * -1 if there is no request from any core. The next service request
@@ -179,7 +187,9 @@
 	if ((!get_current_prog_time()) || (interrupt_req_time[core_pos] <
 				(get_current_prog_time() - TIMER_STEP_VALUE))) {
 
-		arm_gic_set_intr_target(TIMER_IRQ, core_pos);
+		if (IS_SPI(TIMER_IRQ)) {
+			arm_gic_set_intr_target(TIMER_IRQ, core_pos);
+		}
 
 		rc = PROGRAM_TIMER(time_out_ms);
 		/* We don't expect timer programming to fail */
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..16e87e9 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_pmuv3.c
@@ -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	| \
@@ -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;
@@ -181,12 +157,13 @@
 	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);
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 9c7ceba..c1edd79 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
@@ -34,21 +34,25 @@
 	RMI_EXIT(PSCI),
 	RMI_EXIT(RIPAS_CHANGE),
 	RMI_EXIT(HOST_CALL),
-	RMI_EXIT(SERROR)
+	RMI_EXIT(SERROR),
+	RMI_EXIT(IO),
+	RMI_EXIT(RTT_REQUEST),
+	RMI_EXIT(S2AP_CHANGE),
+	RMI_EXIT(VDEV_REQUEST)
 };
 
 /*
  * 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);
 
@@ -59,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,
@@ -125,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;
 }
@@ -135,7 +124,8 @@
 			       u_register_t feature_flag,
 			       long sl,
 			       const u_register_t *rec_flag,
-			       unsigned int rec_count)
+			       unsigned int rec_count,
+			       unsigned int num_aux_planes)
 {
 	int8_t value;
 
@@ -169,6 +159,21 @@
 				EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ, feature_flag));
 	}
 
+	realm_ptr->rtt_tree_single = false;
+	if (num_aux_planes > 0U) {
+		if (EXTRACT(RMI_FEATURE_REGISTER_0_PLANE_RTT, feature_flag) >=
+							RMI_PLANE_RTT_SINGLE) {
+			ERROR("S2POE not suported on TFTF\n");
+			return false;
+		}
+
+		/*
+		 * @TODO: once S2POE is supported, this should be a parameter
+		 * so it can be tested with and without support for auxiliary
+		 * tables.
+		 */
+	}
+
 	/* Disable PMU if not required */
 	if ((feature_flag & RMI_FEATURE_REGISTER_0_PMU_EN) == 0UL) {
 		realm_ptr->rmm_feat_reg0 &= ~RMI_FEATURE_REGISTER_0_PMU_EN;
@@ -246,6 +251,12 @@
 
 	realm_ptr->start_level = sl;
 
+	if (num_aux_planes > MAX_AUX_PLANE_COUNT) {
+		ERROR("Invalid aux plane count\n");
+		return false;
+	}
+	realm_ptr->num_aux_planes = num_aux_planes;
+
 	/* Create Realm */
 	if (host_realm_create(realm_ptr) != REALM_SUCCESS) {
 		ERROR("%s() failed\n", "host_realm_create");
@@ -283,7 +294,8 @@
 			       u_register_t feature_flag,
 			       long sl,
 			       const u_register_t *rec_flag,
-			       unsigned int rec_count)
+			       unsigned int rec_count,
+			       unsigned int num_aux_planes)
 {
 	bool ret;
 
@@ -292,7 +304,8 @@
 			feature_flag,
 			sl,
 			rec_flag,
-			rec_count);
+			rec_count,
+			num_aux_planes);
 	if (!ret) {
 		goto destroy_realm;
 	} else {
@@ -323,7 +336,8 @@
 			u_register_t feature_flag,
 			long sl,
 			const u_register_t *rec_flag,
-			unsigned int rec_count)
+			unsigned int rec_count,
+			unsigned int num_aux_planes)
 
 {
 	bool ret;
@@ -333,7 +347,8 @@
 			feature_flag,
 			sl,
 			rec_flag,
-			rec_count);
+			rec_count,
+			num_aux_planes);
 	if (!ret) {
 		goto destroy_realm;
 	} else {
@@ -403,7 +418,7 @@
 		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;
 	}
@@ -470,3 +485,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 ebf4580..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
@@ -76,7 +76,7 @@
 	 * must be preserved unless they contain result,
 	 * as specified in the function definition.
 	 */
-	if (regs[0] != RMI_RTT_READ_ENTRY) {
+	if ((regs[0] != RMI_RTT_READ_ENTRY) && (regs[0] != RMI_RTT_AUX_MAP_PROTECTED)) {
 		CHECK_RET(4);
 	}
 
@@ -184,6 +184,16 @@
 				rd, rtt, map_addr, (u_register_t)level}, 5U).ret0;
 }
 
+static inline u_register_t host_rmi_rtt_aux_create(u_register_t rd,
+						u_register_t rtt,
+						u_register_t map_addr,
+						long  level,
+						u_register_t tree_index)
+{
+	return host_rmi_handler(&(smc_args) {RMI_RTT_AUX_CREATE,
+				rd, rtt, map_addr, (u_register_t)level, tree_index}, 6U).ret0;
+}
+
 u_register_t host_rmi_rtt_destroy(u_register_t rd,
 				  u_register_t map_addr,
 				  long level,
@@ -200,6 +210,24 @@
 	return rets.ret0;
 }
 
+u_register_t host_rmi_rtt_aux_destroy(u_register_t rd,
+				  u_register_t map_addr,
+				  long level,
+				  u_register_t tree_index,
+				  u_register_t *rtt,
+				  u_register_t *top)
+{
+	smc_ret_values rets;
+
+	rets = host_rmi_handler(&(smc_args) {RMI_RTT_AUX_DESTROY,
+				rd, map_addr, (u_register_t)level,
+				tree_index,
+				(u_register_t)&rets}, 6U);
+	*rtt = rets.ret1;
+	*top = rets.ret2;
+	return rets.ret0;
+}
+
 u_register_t host_rmi_features(u_register_t index, u_register_t *features)
 {
 	smc_ret_values rets;
@@ -243,6 +271,22 @@
 	return rets.ret0;
 }
 
+static inline u_register_t host_rmi_rtt_aux_fold(u_register_t rd,
+						 u_register_t map_addr,
+						 long level,
+						 u_register_t tree_index,
+						 u_register_t *pa)
+{
+	smc_ret_values rets;
+
+	rets = host_rmi_handler(&(smc_args) {RMI_RTT_AUX_FOLD,
+				rd, map_addr, (u_register_t)level,
+				tree_index,
+				(u_register_t)&rets}, 6U);
+	*pa = rets.ret1;
+	return rets.ret0;
+}
+
 static inline u_register_t host_rmi_rec_aux_count(u_register_t rd,
 						  u_register_t *aux_count)
 {
@@ -276,6 +320,42 @@
 				rd, map_addr, (u_register_t)level, ns_pa}, 5U).ret0;
 }
 
+u_register_t host_rmi_rtt_aux_map_unprotected(u_register_t rd,
+					      u_register_t map_addr,
+					      u_register_t tree_index,
+					      u_register_t *fail_index,
+					      u_register_t *level_pri,
+					      u_register_t *state)
+{
+	smc_ret_values rets;
+
+	rets = host_rmi_handler(&(smc_args) {RMI_RTT_AUX_MAP_UNPROTECTED,
+				rd, map_addr, tree_index}, 4U);
+	*fail_index = rets.ret1;
+	*level_pri = rets.ret2;
+	*state = rets.ret3;
+	return rets.ret0;
+}
+
+u_register_t host_rmi_rtt_aux_map_protected(u_register_t rd,
+					 u_register_t map_addr,
+					 u_register_t tree_index,
+					 u_register_t *fail_index,
+					 u_register_t *level_pri,
+					 u_register_t *state,
+					 u_register_t *ripas)
+{
+	smc_ret_values rets;
+
+	rets = host_rmi_handler(&(smc_args) {RMI_RTT_AUX_MAP_PROTECTED,
+				rd, map_addr, tree_index}, 4U);
+	*fail_index = rets.ret1;
+	*level_pri = rets.ret2;
+	*state = rets.ret3;
+	*ripas = rets.ret4;
+	return rets.ret0;
+}
+
 u_register_t host_rmi_rtt_readentry(u_register_t rd,
 				   u_register_t map_addr,
 				   long level,
@@ -305,6 +385,36 @@
 	return rets.ret0;
 }
 
+u_register_t host_rmi_rtt_aux_unmap_unprotected(u_register_t rd,
+					  u_register_t map_addr,
+					  u_register_t tree_index,
+					  u_register_t *top,
+					  u_register_t *level)
+{
+	smc_ret_values rets;
+
+	rets = host_rmi_handler(&(smc_args) {RMI_RTT_AUX_UNMAP_UNPROTECTED,
+					rd, map_addr, tree_index}, 4U);
+	*top = rets.ret1;
+	*level = rets.ret2;
+	return rets.ret0;
+}
+
+u_register_t host_rmi_rtt_aux_unmap_protected(u_register_t rd,
+					  u_register_t map_addr,
+					  u_register_t tree_index,
+					  u_register_t *top,
+					  u_register_t *level)
+{
+	smc_ret_values rets;
+
+	rets = host_rmi_handler(&(smc_args) {RMI_RTT_AUX_UNMAP_PROTECTED,
+					rd, map_addr, tree_index}, 4U);
+	*top = rets.ret1;
+	*level = rets.ret2;
+	return rets.ret0;
+}
+
 bool host_ipa_is_ns(u_register_t addr, u_register_t rmm_feat_reg0)
 {
 	return (addr >> (EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ, rmm_feat_reg0) - 1UL) == 1UL);
@@ -351,6 +461,42 @@
 	return REALM_SUCCESS;
 }
 
+static u_register_t host_realm_create_rtt_aux_levels(struct realm *realm,
+					    u_register_t map_addr,
+					    long level, long max_level,
+					    u_register_t tree_index)
+{
+	u_register_t rtt, ret, ipa_align;
+
+	assert(tree_index != PRIMARY_RTT_INDEX);
+	while (level++ < max_level) {
+		rtt = (u_register_t)page_alloc(PAGE_SIZE);
+		if (rtt == HEAP_NULL_PTR) {
+			ERROR("Failed to allocate memory for rtt\n");
+			return REALM_ERROR;
+		} else {
+			ret = host_rmi_granule_delegate(rtt);
+			if (ret != RMI_SUCCESS) {
+				ERROR("%s() failed, rtt=0x%lx ret=0x%lx\n",
+					"host_rmi_granule_delegate", rtt, ret);
+				return REALM_ERROR;
+			}
+		}
+		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, 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;
+		}
+	}
+
+	return REALM_SUCCESS;
+}
+
 u_register_t host_realm_fold_rtt(u_register_t rd, u_register_t addr,
 				 long level)
 {
@@ -379,6 +525,93 @@
 
 }
 
+u_register_t host_realm_aux_map_protected_data(struct realm *realm,
+						u_register_t target_pa,
+						u_register_t map_size,
+						u_register_t tree_index,
+						u_register_t *fail_index,
+						u_register_t *level_pri,
+						u_register_t *state,
+						u_register_t *ripas)
+{
+	u_register_t ret, top;
+	long level;
+	int8_t ulevel;
+	u_register_t size = 0UL;
+	u_register_t map_addr = target_pa;
+
+	assert(tree_index != PRIMARY_RTT_INDEX);
+	for (size = 0UL; size < map_size; size += PAGE_SIZE) {
+		ret =  host_rmi_rtt_aux_map_protected(realm->rd, map_addr, tree_index,
+			fail_index, level_pri, state, ripas);
+
+		if (RMI_RETURN_STATUS(ret) == RMI_ERROR_RTT_AUX) {
+			/* Create missing RTTs till L3 and retry */
+			ulevel = RMI_RETURN_INDEX(ret);
+			level = (long)ulevel;
+
+			ret = host_realm_create_rtt_aux_levels(realm, map_addr,
+							 level,
+							 3U, tree_index);
+			if (ret != RMI_SUCCESS) {
+				ERROR("%s() failed, ret=0x%lx line=%u\n",
+					"host_realm_create_rtt_aux_levels",
+					ret, __LINE__);
+				goto err;
+			}
+			ret =  host_rmi_rtt_aux_map_protected(realm->rd, target_pa, tree_index,
+				fail_index, level_pri, state, ripas);
+			if (ret != RMI_SUCCESS) {
+				ERROR("%s() failed, ret=0x%lx\n",
+				"host_rmi_data_create", ret);
+				goto err;
+			}
+		} else if (ret != RMI_SUCCESS) {
+			ERROR("host_rmi_rtt_aux_map_protected failed ret = 0x%lx", ret);
+			goto err;
+		}
+		map_addr += PAGE_SIZE;
+	}
+	return REALM_SUCCESS;
+
+err:
+	while (size >= PAGE_SIZE) {
+		ret = host_rmi_rtt_aux_unmap_protected(realm->rd, target_pa, tree_index,
+				&top, (u_register_t *)&level);
+		if (ret != RMI_SUCCESS) {
+			ERROR("%s() failed, addr=0x%lx ret=0x%lx\n",
+				"host_rmi_rtt_aux_unmap_protected", map_addr, ret);
+		}
+		size -= PAGE_SIZE;
+		map_addr -= PAGE_SIZE;
+	}
+	return REALM_ERROR;
+}
+
+u_register_t host_realm_aux_unmap_protected_data(struct realm *realm,
+						u_register_t target_ipa,
+						u_register_t map_size,
+						u_register_t tree_index,
+						u_register_t *top,
+						u_register_t *level)
+{
+	u_register_t ret, size = 0UL, map_addr = target_ipa;
+
+	assert(tree_index != PRIMARY_RTT_INDEX);
+	for (size = 0UL; size < map_size; size += PAGE_SIZE) {
+		ret = host_rmi_rtt_aux_unmap_protected(realm->rd, map_addr, tree_index,
+				top, level);
+		if (ret != RMI_SUCCESS) {
+			WARN("%s() failed, ret=0x%lx line=%u\n",
+					"host_rmi_rtt_aux_unmap_protected",
+					ret, __LINE__);
+			return REALM_ERROR;
+		}
+		map_addr += PAGE_SIZE;
+	}
+	return REALM_SUCCESS;
+}
+
 u_register_t host_realm_delegate_map_protected_data(bool unknown,
 						    struct realm *realm,
 						    u_register_t target_pa,
@@ -392,7 +625,7 @@
 	u_register_t phys = target_pa;
 	u_register_t map_addr = target_pa;
 
-	if (!IS_ALIGNED(map_addr, map_size)) {
+	if (!IS_ALIGNED(map_addr, PAGE_SIZE)) {
 		return REALM_ERROR;
 	}
 
@@ -562,6 +795,50 @@
 	return REALM_SUCCESS;
 }
 
+static u_register_t host_realm_destroy_free_aux_rtt(struct realm *realm,
+						    u_register_t addr,
+						    long level)
+{
+	u_register_t rtt2, top, ret;
+
+	/* Destroy and undelegate RTT entry for all trees */
+	for (unsigned int tree_index = 1U;
+			tree_index <= realm->num_aux_planes;
+			tree_index++) {
+
+		ret = host_rmi_rtt_aux_destroy(realm->rd, ALIGN_DOWN(addr,
+					RTT_MAP_SIZE(level)),
+					level + 1L,
+					tree_index, &rtt2, &top);
+
+		if (ret != RMI_SUCCESS) {
+			/*
+			 * IPA might not be mapped on all AUX RTTs
+			 * ignore error
+			 */
+			VERBOSE("%s() failed, map_addr=0x%lx ret=0x%lx \
+					rtt2=0x%lx \
+					top=0x%lx level=0x%lx\n",
+					"host_rmi_rtt_aux_destroy",
+					addr, ret, rtt2,
+					top, level + 1L);
+		}
+
+		if (rtt2 != 0UL) {
+			ret = host_rmi_granule_undelegate(rtt2);
+			if (ret != RMI_SUCCESS) {
+				ERROR("%s() failed, rtt=0x%lx ret=0x%lx\n",
+					"host_rmi_granule_undelegate",
+					rtt2, ret);
+				return REALM_ERROR;
+			}
+
+			page_free(rtt2);
+		}
+	}
+	return REALM_SUCCESS;
+}
+
 static u_register_t host_realm_destroy_undelegate_range(struct realm *realm,
 							u_register_t ipa,
 							u_register_t addr,
@@ -573,6 +850,29 @@
 
 	while (size >= PAGE_SIZE) {
 		ret = host_rmi_data_destroy(rd, ipa, &data, &top);
+
+		if (ret == RMI_ERROR_RTT_AUX) {
+			/* Unmap from all Aux RTTs */
+			for (unsigned int tree_index = 1U; tree_index <= realm->num_aux_planes;
+					tree_index++) {
+				u_register_t top1, level1;
+
+				/* IPA might not be mapped in all Aux RTTs ignore error */
+				ret = host_rmi_rtt_aux_unmap_protected(
+								rd,
+								ipa,
+								tree_index,
+								&top1, &level1);
+				if (ret != RMI_SUCCESS) {
+					VERBOSE("%s() failed, addr=0x%lx ret=0x%lx tree=0x%x\n",
+					"host_rmi_rtt_aux_unmap_protected",
+					ipa, ret, tree_index);
+				}
+			}
+			/* Retry DATA_DESTROY */
+			continue;
+		}
+
 		if (ret != RMI_SUCCESS) {
 			ERROR("%s() failed, addr=0x%lx ret=0x%lx\n",
 				"host_rmi_data_destroy", ipa, ret);
@@ -622,6 +922,28 @@
 		case RMI_ASSIGNED:
 			if (host_ipa_is_ns(map_addr, realm->rmm_feat_reg0)) {
 
+				u_register_t level1;
+
+				/* Unmap from all Aux RTT */
+				if (!realm->rtt_tree_single) {
+					for (unsigned int tree_index = 1U;
+						tree_index <= realm->num_aux_planes;
+						tree_index++) {
+
+						ret = host_rmi_rtt_aux_unmap_unprotected(
+								rd,
+								map_addr,
+								tree_index,
+								&top, &level1);
+
+						if (ret != RMI_SUCCESS) {
+							ERROR("%s() failed, addr=0x%lx ret=0x%lx\n",
+							"host_rmi_rtt_unmap_unprotected",
+							map_addr, ret);
+						}
+					}
+				}
+
 				ret = host_rmi_rtt_unmap_unprotected(
 								rd,
 								map_addr,
@@ -669,6 +991,19 @@
 					map_addr, ret);
 				return REALM_ERROR;
 			}
+
+			/* RTT_AUX_DESTROY */
+			if (!realm->rtt_tree_single) {
+				ret = host_realm_destroy_free_aux_rtt(realm, map_addr,
+						level);
+
+				if (ret != RMI_SUCCESS) {
+					ERROR("%s() failed, map_addr=0x%lx ret=0x%lx\n",
+						"host_realm_destroy_free_aux_rtt",
+						map_addr, ret);
+					return REALM_ERROR;
+				}
+			}
 			break;
 		default:
 			return REALM_ERROR;
@@ -700,11 +1035,28 @@
 	return ret.ret1;
 }
 
+u_register_t host_rmi_rtt_set_s2ap(u_register_t rd,
+				u_register_t rec,
+				u_register_t base,
+				u_register_t top,
+				u_register_t *out_top,
+				u_register_t *rtt_tree)
+{
+	smc_ret_values rets;
+
+	rets = host_rmi_handler(&(smc_args) {RMI_RTT_SET_S2AP,
+				rd, rec, base, top,
+				(u_register_t)&rets}, 6U);
+	*out_top = rets.ret1;
+	*rtt_tree = rets.ret2;
+	return rets.ret0;
+}
+
 u_register_t host_realm_create(struct realm *realm)
 {
 	struct rmi_realm_params *params;
 	u_register_t ret;
-	unsigned int count;
+	unsigned int count, rtt_page_count = 0U;
 
 	realm->par_size = REALM_MAX_LOAD_IMG_SIZE;
 
@@ -724,11 +1076,19 @@
 		}
 	}
 
+	assert(realm->num_aux_planes <= MAX_AUX_PLANE_COUNT);
+
 	/*
-	 * Allocate memory for PAR - Realm image. Granule delegation
+	 * 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->par_base = (u_register_t)page_alloc((realm->par_size) *
+			(realm->num_aux_planes + 1U));
+
 	if (realm->par_base == HEAP_NULL_PTR) {
 		ERROR("page_alloc failed, base=0x%lx, size=0x%lx\n",
 			  realm->par_base, realm->par_size);
@@ -737,6 +1097,15 @@
 
 	INFO("Realm start adr=0x%lx\n", realm->par_base);
 
+	/* Allocate memory for params */
+	params = (struct rmi_realm_params *)page_alloc(PAGE_SIZE);
+	if (params == NULL) {
+		ERROR("Failed to allocate memory for params\n");
+		goto pool_reset;
+	}
+
+	memset(params, 0, PAGE_SIZE);
+
 	/* Allocate and delegate RD */
 	realm->rd = (u_register_t)page_alloc(PAGE_SIZE);
 	if (realm->rd == HEAP_NULL_PTR) {
@@ -752,28 +1121,41 @@
 	}
 
 	/* Allocate and delegate RTT */
-	realm->rtt_addr = (u_register_t)page_alloc(PAGE_SIZE);
+	if (realm->rtt_tree_single) {
+		rtt_page_count = 1U;
+	} else {
+		/* Primary + AUX RTT Tree */
+		rtt_page_count = (realm->num_aux_planes + 1U);
+	}
+
+	realm->rtt_addr = (u_register_t)page_alloc(rtt_page_count * PAGE_SIZE);
+
 	if (realm->rtt_addr == HEAP_NULL_PTR) {
 		ERROR("Failed to allocate memory for rtt_addr\n");
 		goto err_undelegate_rd;
 	} else {
-		ret = host_rmi_granule_delegate(realm->rtt_addr);
-		if (ret != RMI_SUCCESS) {
-			ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+		for (unsigned int i = 0U; i < rtt_page_count; i++) {
+			ret = host_rmi_granule_delegate(realm->rtt_addr + (i * PAGE_SIZE));
+
+			if (ret != RMI_SUCCESS) {
+				ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
 				"host_rmi_granule_delegate", realm->rtt_addr, ret);
-			goto err_free_rtt;
+
+				for (unsigned int j = 0U; j < i; j++) {
+					host_rmi_granule_undelegate(realm->rtt_addr
+							+ (i * PAGE_SIZE));
+				}
+
+				goto err_free_rtt;
+			}
+
+			if (i > 0U && !realm->rtt_tree_single) {
+				realm->aux_rtt_addr[i - 1] = realm->rtt_addr + (i * PAGE_SIZE);
+				params->aux_rtt_base[i - 1] = realm->rtt_addr + (i * PAGE_SIZE);
+			}
 		}
 	}
 
-	/* Allocate memory for params */
-	params = (struct rmi_realm_params *)page_alloc(PAGE_SIZE);
-	if (params == NULL) {
-		ERROR("Failed to allocate memory for params\n");
-		goto err_undelegate_rtt;
-	}
-
-	memset((char *)params, 0U, PAGE_SIZE);
-
 	/* Populate params */
 	params->s2sz = EXTRACT(RMI_FEATURE_REGISTER_0_S2SZ,
 				realm->rmm_feat_reg0);
@@ -782,16 +1164,16 @@
 
 	/* SVE enable and vector length */
 	if ((realm->rmm_feat_reg0 & RMI_FEATURE_REGISTER_0_SVE_EN) != 0UL) {
-		params->flags = RMI_REALM_FLAGS_SVE;
+		params->flags0 = RMI_REALM_FLAGS0_SVE;
 		params->sve_vl = realm->sve_vl;
 	} else {
-		params->flags = 0UL;
+		params->flags0 = 0UL;
 		params->sve_vl = 0U;
 	}
 
 	/* PMU enable and number of event counters */
 	if ((realm->rmm_feat_reg0 & RMI_FEATURE_REGISTER_0_PMU_EN) != 0UL) {
-		params->flags |= RMI_REALM_FLAGS_PMU;
+		params->flags0 |= RMI_REALM_FLAGS0_PMU;
 		params->pmu_num_ctrs = realm->pmu_num_ctrs;
 	} else {
 		params->pmu_num_ctrs = 0U;
@@ -799,21 +1181,32 @@
 
 	/* LPA2 enable */
 	if ((realm->rmm_feat_reg0 & RMI_FEATURE_REGISTER_0_LPA2) != 0UL) {
-		params->flags |= RMI_REALM_FLAGS_LPA2;
+		params->flags0 |= RMI_REALM_FLAGS0_LPA2;
 	}
 
 	params->rtt_level_start = realm->start_level;
-	params->hash_algo = RMI_HASH_SHA_256;
+	params->algorithm = RMI_HASH_SHA_256;
 	params->vmid = vmid++;
 	params->rtt_base = realm->rtt_addr;
 	params->rtt_num_start = 1U;
 
+	if (!realm->rtt_tree_single) {
+		params->flags1 = RMI_REALM_FLAGS1_RTT_TREE_PP;
+	}
+	params->num_aux_planes = realm->num_aux_planes;
+
+	/* Allocate VMID for all planes */
+	for (unsigned int i = 0U; i < realm->num_aux_planes; i++) {
+		params->aux_vmid[i] = (unsigned short)(vmid++);
+		realm->aux_vmid[i] = params->aux_vmid[i];
+	}
+
 	/* Create Realm */
 	ret = host_rmi_realm_create(realm->rd, (u_register_t)params);
 	if (ret != RMI_SUCCESS) {
 		ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
 			"host_rmi_realm_create", realm->rd, ret);
-		goto err_free_params;
+		goto err_free_vmid;
 	}
 
 	realm->vmid = params->vmid;
@@ -822,7 +1215,7 @@
 		ERROR("%s() failed, rd=0x%lx ret=0x%lx\n",
 			"host_rmi_rec_aux_count", realm->rd, ret);
 		host_rmi_realm_destroy(realm->rd);
-		goto err_free_params;
+		goto err_free_vmid;
 	}
 
 	realm->state = REALM_STATE_NEW;
@@ -831,14 +1224,10 @@
 	page_free((u_register_t)params);
 	return REALM_SUCCESS;
 
-err_free_params:
-	page_free((u_register_t)params);
-
-err_undelegate_rtt:
-	ret = host_rmi_granule_undelegate(realm->rtt_addr);
-	if (ret != RMI_SUCCESS) {
-		WARN("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
-			"host_rmi_granule_undelegate", realm->rtt_addr, ret);
+err_free_vmid:
+	/* Free VMID */
+	for (unsigned int i = 0U; i <= realm->num_aux_planes; i++) {
+		vmid--;
 	}
 
 err_free_rtt:
@@ -850,9 +1239,20 @@
 		WARN("%s() failed, rd=0x%lx ret=0x%lx\n",
 			"host_rmi_granule_undelegate", realm->rd, ret);
 	}
+
 err_free_rd:
 	page_free(realm->rd);
 
+	page_free((u_register_t)params);
+
+	for (unsigned int i = 0U; i < rtt_page_count; i++) {
+		ret = host_rmi_granule_undelegate(realm->rtt_addr + (i * PAGE_SIZE));
+		if (ret != RMI_SUCCESS) {
+			WARN("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+			"host_rmi_granule_undelegate", realm->rtt_addr + (i * PAGE_SIZE), ret);
+		}
+	}
+
 err_free_par:
 	page_free(realm->par_base);
 
@@ -875,22 +1275,23 @@
 					  u_register_t realm_payload_adr)
 {
 	u_register_t src_pa = realm_payload_adr;
-	u_register_t i = 0UL;
 	u_register_t ret;
 
 	/* MAP image regions */
-	while (i < (realm->par_size / PAGE_SIZE)) {
+	/* Copy Plane 0-N Images */
+
+	for (unsigned int j = 0U; j <= realm->num_aux_planes; j++) {
 		ret = host_realm_delegate_map_protected_data(false, realm,
-						realm->par_base + i * PAGE_SIZE,
-						PAGE_SIZE,
-						src_pa + i * PAGE_SIZE);
+					realm->par_base + (j * realm->par_size),
+					realm->par_size,
+					src_pa);
+
 		if (ret != RMI_SUCCESS) {
-			ERROR("%s() failed, par_base=0x%lx ret=0x%lx\n",
-				"host_realm_delegate_map_protected_data",
-				realm->par_base, ret);
+			ERROR("%s() failed par_base=0x%lx size=0x%lx j=%u ret=0x%lx\n",
+			"host_realm_delegate_map_protected_data",
+			realm->par_base, realm->par_size, j, ret);
 			return REALM_ERROR;
 		}
-		i++;
 	}
 
 	return REALM_SUCCESS;
@@ -942,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;
 }
 
@@ -1131,6 +1581,7 @@
 u_register_t host_realm_destroy(struct realm *realm)
 {
 	u_register_t ret;
+	unsigned int rtt_page_count;
 	long rtt_start_level = realm->start_level;
 
 	if (realm->state == REALM_STATE_NULL) {
@@ -1209,11 +1660,24 @@
 		return REALM_ERROR;
 	}
 
-	ret = host_rmi_granule_undelegate(realm->rtt_addr);
-	if (ret != RMI_SUCCESS) {
-		ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
-			"host_rmi_granule_undelegate", realm->rtt_addr, ret);
-		return REALM_ERROR;
+	if (realm->rtt_tree_single) {
+		rtt_page_count = 1U;
+	} else {
+		rtt_page_count = realm->num_aux_planes + 1U;
+	}
+
+	for (unsigned int i = 0U; i < rtt_page_count; i++) {
+		ret = host_rmi_granule_undelegate(realm->rtt_addr + (i * PAGE_SIZE));
+		if (ret != RMI_SUCCESS) {
+			ERROR("%s() failed, rtt_addr=0x%lx ret=0x%lx\n",
+			"host_rmi_granule_undelegate", realm->rtt_addr + (i * PAGE_SIZE), ret);
+			return REALM_ERROR;
+		}
+	}
+
+	/* Free VMID */
+	for (unsigned int i = 0U; i <= realm->num_aux_planes; i++) {
+		vmid--;
 	}
 
 	page_free(realm->rd);
@@ -1239,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,
@@ -1273,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;
 		}
@@ -1284,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_lpa2_tests.c b/tftf/tests/runtime_services/realm_payload/host_realm_lpa2_tests.c
index 9a6341d..43d9f01 100644
--- a/tftf/tests/runtime_services/realm_payload/host_realm_lpa2_tests.c
+++ b/tftf/tests/runtime_services/realm_payload/host_realm_lpa2_tests.c
@@ -22,7 +22,7 @@
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			0UL, RTT_MIN_LEVEL_LPA2, rec_flag, 1U)) {
+			0UL, RTT_MIN_LEVEL_LPA2, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_SUCCESS;
 	}
 
@@ -41,7 +41,7 @@
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
 			INPLACE(RMI_FEATURE_REGISTER_0_S2SZ, 50UL),
-			RTT_MIN_LEVEL, rec_flag, 1U)) {
+			RTT_MIN_LEVEL, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_SUCCESS;
 	}
 
@@ -67,7 +67,7 @@
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
 			INPLACE(RMI_FEATURE_REGISTER_0_S2SZ, 48UL),
-			RTT_MIN_LEVEL, rec_flag, 1U)) {
+			RTT_MIN_LEVEL, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -99,7 +99,7 @@
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
 			INPLACE(RMI_FEATURE_REGISTER_0_S2SZ, 48UL),
-			RTT_MIN_LEVEL, rec_flag, 1U)) {
+			RTT_MIN_LEVEL, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -155,7 +155,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, RTT_MIN_LEVEL, rec_flag, 1U)) {
+			feature_flag, RTT_MIN_LEVEL, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_SUCCESS;
 	}
 
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 e3ee23b..00d2d57 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
@@ -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
@@ -47,7 +48,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+			feature_flag, sl, rec_flag, MAX_REC_COUNT, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -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) {
@@ -112,7 +115,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 3U)) {
+			feature_flag, sl, rec_flag, 3U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -257,7 +260,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, rec_count)) {
+			feature_flag, sl, rec_flag, rec_count, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -361,14 +364,14 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, rec_count)) {
+			feature_flag, sl, rec_flag, rec_count, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
 	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) {
@@ -499,18 +502,18 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+			feature_flag, sl, rec_flag, MAX_REC_COUNT, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
 	if (!host_create_activate_realm_payload(&realm2, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		ret2 = host_destroy_realm(&realm);
 		return TEST_RESULT_FAIL;
 	}
 
 	/* 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,7 +633,7 @@
 	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;
@@ -647,7 +659,8 @@
 	}
 
 	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;
 
@@ -661,7 +674,7 @@
 
 	/* 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)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		ERROR("Realm create should have failed\n");
 		host_destroy_realm(&realm);
 		return TEST_RESULT_FAIL;
@@ -676,7 +689,7 @@
 	}
 
 	ret1 = host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, rec_flag, 1U);
+				feature_flag, sl, rec_flag, 1U, 0U);
 
 	if (!get_feat_hpmn0_supported()) {
 		if (ret1) {
@@ -702,7 +715,7 @@
 
 	/* Prepare realm0, create recs for realm0 later */
 	if (!host_prepare_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, rec_count)) {
+			feature_flag, sl, rec_flag, rec_count, 0U)) {
 		goto test_exit;
 		return TEST_RESULT_FAIL;
 	}
@@ -716,7 +729,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm1, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, rec_count)) {
+			feature_flag, sl, rec_flag, rec_count, 0U)) {
 		goto test_exit2;
 	}
 
@@ -740,8 +753,11 @@
 
 	/* Pass num of PMU counters programmed to realm */
 	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 - 1U);
 	}
 
 	/*
@@ -771,6 +787,10 @@
 		goto test_exit2;
 	}
 
+	if (!host_check_pmu_state(&pmu_state[0U])) {
+		goto test_exit;
+	}
+
 	i = 0U;
 
 	/* Turn on all CPUs */
@@ -820,9 +840,5 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	if (!host_check_pmu_state()) {
-		return TEST_RESULT_FAIL;
-	}
-
 	return TEST_RESULT_SUCCESS;
 }
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 ce5409c..760a286 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
@@ -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
  */
@@ -59,11 +202,13 @@
 		unsigned int run_num = (unsigned int)rand() % MAX_REC_COUNT;
 
 		if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+				feature_flag, sl, rec_flag, MAX_REC_COUNT, 0U)) {
 			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);
@@ -97,7 +242,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -141,7 +286,7 @@
 
 	pauth_test_lib_fill_regs_and_template(pauth_keys_before);
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+				feature_flag, sl, rec_flag, MAX_REC_COUNT, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -203,7 +348,7 @@
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, rec_flag, 1U)) {
+				feature_flag, sl, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -281,17 +426,25 @@
 static test_result_t host_test_realm_pmuv3(uint8_t cmd)
 {
 	struct realm realm;
-	u_register_t feature_flag;
+	u_register_t feature_flag, rmm_feat_reg0;
+	unsigned int num_cnts;
 	long sl = RTT_MIN_LEVEL;
 	u_register_t rec_flag[1] = {RMI_RUNNABLE};
 	bool ret1, ret2;
 
 	SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();
 
-	host_set_pmu_state();
+	/* Get Max PMU counter 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(&pmu_state);
 
 	feature_flag = RMI_FEATURE_REGISTER_0_PMU_EN |
-			INPLACE(FEATURE_PMU_NUM_CTRS, (unsigned long long)(-1));
+			INPLACE(FEATURE_PMU_NUM_CTRS, num_cnts);
 
 	if (is_feat_52b_on_4k_2_supported() == true) {
 		feature_flag |= RMI_FEATURE_REGISTER_0_LPA2;
@@ -299,7 +452,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -319,7 +472,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	if (!host_check_pmu_state()) {
+	if (!host_check_pmu_state(&pmu_state)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -412,7 +565,8 @@
 
 		ret = host_create_activate_realm_payload(&realm[num],
 							(u_register_t)REALM_IMAGE_BASE,
-							feature_flag, sl, rec_flag, MAX_REC_COUNT);
+							feature_flag, sl, rec_flag,
+							MAX_REC_COUNT, 0U);
 		if (!ret) {
 			goto destroy_realms;
 		}
@@ -420,8 +574,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) {
@@ -476,15 +631,15 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		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++) {
@@ -575,7 +730,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -586,7 +741,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);
 
@@ -647,7 +802,7 @@
 	}
 
 	if (!host_create_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 2U)) {
+			feature_flag, sl, rec_flag, 2U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -672,8 +827,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) {
@@ -702,8 +857,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;
@@ -720,8 +875,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;
@@ -773,7 +928,7 @@
 	}
 
 	if (!host_create_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 2U)) {
+			feature_flag, sl, rec_flag, 2U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -802,8 +957,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,
@@ -812,8 +967,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;
@@ -829,8 +984,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;
@@ -882,7 +1037,7 @@
 	}
 
 	if (!host_create_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 2U)) {
+			feature_flag, sl, rec_flag, 2U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -904,8 +1059,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");
@@ -945,8 +1100,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;
@@ -962,8 +1117,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;
@@ -1017,7 +1172,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 4U)) {
+			feature_flag, sl, rec_flag, 4U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -1029,10 +1184,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,
@@ -1043,7 +1198,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;
@@ -1059,7 +1214,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;
@@ -1091,7 +1246,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;
@@ -1107,7 +1262,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);
 	}
@@ -1159,7 +1314,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 2U)) {
+			feature_flag, sl, rec_flag, 2U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -1176,8 +1331,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,
@@ -1188,7 +1343,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;
@@ -1203,8 +1358,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);
@@ -1224,7 +1379,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;
@@ -1267,14 +1422,14 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, MAX_REC_COUNT)) {
+			feature_flag, sl, rec_flag, MAX_REC_COUNT, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
 	/* 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) {
@@ -1497,7 +1652,7 @@
 	}
 
 	if (!host_create_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 2U)) {
+			feature_flag, sl, rec_flag, 2U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -1683,7 +1838,7 @@
 	}
 
 	if (!host_create_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		goto destroy_realm;
 	}
 
@@ -1729,7 +1884,7 @@
 	feature_flag = INPLACE(RMI_FEATURE_REGISTER_0_S2SZ, 0x2CU);
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, RTT_MIN_LEVEL, rec_flag, 4U)) {
+			feature_flag, RTT_MIN_LEVEL, rec_flag, 4U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -1738,8 +1893,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);
 
@@ -1755,7 +1910,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)) {
@@ -1775,7 +1930,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)) {
@@ -1790,8 +1945,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];
 
@@ -1805,8 +1960,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);
@@ -1825,8 +1980,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",
@@ -1876,7 +2031,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		ERROR("Realm creation failed\n");
 		goto destroy_realm;
 	}
@@ -2033,7 +2188,7 @@
 	}
 
 	if (!host_create_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		ERROR("Realm creation failed\n");
 		goto destroy_realm;
 	}
@@ -2208,7 +2363,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		ERROR("Realm creation failed\n");
 		goto destroy_realm;
 	}
@@ -2323,7 +2478,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		ERROR("Realm creation failed\n");
 		goto destroy_realm;
 	}
@@ -2436,7 +2591,7 @@
 	}
 
 	if (!host_create_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-			feature_flag, sl, rec_flag, 1U)) {
+			feature_flag, sl, rec_flag, 1U, 0U)) {
 		ERROR("Realm creation failed\n");
 		goto destroy_realm;
 	}
@@ -2552,7 +2707,7 @@
 
 	if (!host_create_activate_realm_payload(&realm,
 					(u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, &rec_flag, 1U)) {
+				feature_flag, sl, &rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -2572,10 +2727,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 */
@@ -2612,7 +2767,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, rec_flag, 1U)) {
+				feature_flag, sl, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
@@ -2653,7 +2808,7 @@
 	}
 
 	if (!host_create_activate_realm_payload(&realm, (u_register_t)REALM_IMAGE_BASE,
-				feature_flag, sl, rec_flag, 1U)) {
+				feature_flag, sl, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
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 02c5d0f..235e093 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
@@ -39,7 +39,7 @@
 	/* Initialise Realm payload */
 	if (!host_create_activate_realm_payload(realm,
 				       (u_register_t)REALM_IMAGE_BASE,
-				       feature_flag, sl, rec_flag, 1U)) {
+				       feature_flag, sl, rec_flag, 1U, 0U)) {
 		return TEST_RESULT_FAIL;
 	}
 
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/secure_service/spm_test_helpers.c b/tftf/tests/runtime_services/secure_service/spm_test_helpers.c
index 054e774..09482f2 100644
--- a/tftf/tests/runtime_services/secure_service/spm_test_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/spm_test_helpers.c
@@ -106,23 +106,3 @@
 
 	return TEST_RESULT_SUCCESS;
 }
-
-bool spm_core_sp_init(ffa_id_t sp_id)
-{
-	/*
-	 * Secure Partitions secondary ECs need one round of ffa_run to reach
-	 * the message loop.
-	 */
-	if (sp_id != SP_ID(1)) {
-		uint32_t core_pos = get_current_core_id();
-		struct ffa_value ret = ffa_run(sp_id, core_pos);
-
-		if (ffa_func_id(ret) != FFA_MSG_WAIT) {
-			ERROR("Failed to run SP%x on core %u\n",
-			      sp_id, core_pos);
-			return false;
-		}
-	}
-
-	return true;
-}
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
index 1f8e81c..4686e4c 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_direct_messaging.c
@@ -185,19 +185,6 @@
 	}
 
 	/*
-	 * Secure Partitions beyond the first SP only have their first
-	 * EC (or vCPU0) woken up at boot time by the SPMC.
-	 * Other ECs need one round of ffa_run to reach the message loop.
-	 */
-	ffa_ret = ffa_run(SP_ID(2), core_pos);
-	if (ffa_func_id(ffa_ret) != FFA_MSG_WAIT) {
-		ERROR("Failed to run SP%x on core %u\n", SP_ID(2),
-				core_pos);
-		ret = TEST_RESULT_FAIL;
-		goto out;
-	}
-
-	/*
 	 * Send a direct message request to SP2 (MP SP) from current physical
 	 * CPU. The SPMC uses the MP pinned context corresponding to the
 	 * physical CPU emitting the request.
diff --git a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
index 4b61565..fe04751 100644
--- a/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
+++ b/tftf/tests/runtime_services/secure_service/test_ffa_notifications.c
@@ -981,14 +981,6 @@
 		 per_vcpu_receiver, core_pos);
 
 	/*
-	 * Secure Partitions secondary ECs need one round of ffa_run to reach
-	 * the message loop.
-	 */
-	if (!spm_core_sp_init(per_vcpu_receiver)) {
-		goto out;
-	}
-
-	/*
 	 * Request to get notifications sent to the respective vCPU.
 	 * Check also if NPI was handled by the receiver. It should have been
 	 * pended at notifications set, in the respective vCPU.
@@ -1002,6 +994,8 @@
 	result = TEST_RESULT_SUCCESS;
 
 out:
+	INFO("Request get per-vCPU notification to %x, core: %u.\n",
+		 per_vcpu_receiver, core_pos);
 	/* Tell the lead CPU that the calling CPU has completed the test. */
 	tftf_send_event(&per_vcpu_finished[core_pos]);
 
@@ -1016,17 +1010,8 @@
 	VERBOSE("Request SP %x to enable NPI in core %u\n",
 		 per_vcpu_receiver, core_pos);
 
-	/*
-	 * Secure Partitions secondary ECs need one round of ffa_run to reach
-	 * the message loop.
-	 */
-	if (!spm_core_sp_init(per_vcpu_receiver)) {
-		goto out;
-	}
-
 	result = TEST_RESULT_SUCCESS;
 
-out:
 	/* Tell the lead CPU that the calling CPU has completed the test. */
 	tftf_send_event(&per_vcpu_finished[core_pos]);
 
@@ -1083,6 +1068,7 @@
 	per_vcpu_receiver = receiver;
 	per_vcpu_sender = sender;
 
+	INFO("Execute npi_enable_per_vcpu_on_handler\n");
 	/* Boot all cores and enable the NPI in all of them. */
 	if (spm_run_multi_core_test(
 		(uintptr_t)npi_enable_per_vcpu_on_handler,
@@ -1134,6 +1120,7 @@
 		result = TEST_RESULT_FAIL;
 	}
 
+	INFO("Execute request_notification_get_per_vcpu_on_handler\n");
 	/*
 	 * Bring up all the cores, and request the receiver to get notifications
 	 * in each one of them.
@@ -1145,6 +1132,7 @@
 	}
 
 out:
+	INFO("UNbind message on CPU:%lx\n", read_mpidr_el1());
 	/* As a clean-up, unbind notifications. */
 	if (!request_notification_unbind(receiver, receiver,
 					 sender,
@@ -1153,6 +1141,7 @@
 		result = TEST_RESULT_FAIL;
 	}
 
+	INFO("Execute npi_disable_per_vcpu_on_handler\n");
 	/* Boot all cores and DISABLE the NPI in all of them. */
 	if (spm_run_multi_core_test(
 		(uintptr_t)npi_disable_per_vcpu_on_handler,
@@ -1187,10 +1176,6 @@
 	VERBOSE("Getting per-vCPU notifications from %x, core: %u.\n",
 		 per_vcpu_receiver, core_pos);
 
-	if (!spm_core_sp_init(per_vcpu_sender)) {
-		goto out;
-	}
-
 	if (!notification_get_and_validate(per_vcpu_receiver,
 					   FFA_NOTIFICATION(core_pos), 0,
 					   core_pos,
@@ -1199,7 +1184,6 @@
 		result = TEST_RESULT_FAIL;
 	}
 
-out:
 	/* Tell the lead CPU that the calling CPU has completed the test. */
 	tftf_send_event(&per_vcpu_finished[core_pos]);
 
@@ -1498,10 +1482,6 @@
 	unsigned int core_pos = get_current_core_id();
 	test_result_t result = TEST_RESULT_FAIL;
 
-	if (!spm_core_sp_init(per_vcpu_sender)) {
-		goto out;
-	}
-
 	if (!notification_set(per_vcpu_receiver, per_vcpu_sender,
 			      FFA_NOTIFICATIONS_FLAG_DELAY_SRI |
 			      FFA_NOTIFICATIONS_FLAG_PER_VCPU  |
diff --git a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
index eae5ccd..3f0c9cb 100644
--- a/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
+++ b/tftf/tests/runtime_services/trusted_os/tsp/test_irq_spurious_gicv2.c
@@ -23,7 +23,7 @@
 #define TEST_SPURIOUS_ITERATIONS_COUNT	1000000
 
 #define TEST_SPI_ID		(MIN_SPI_ID + 2)
-#define CPU_TARGET_FIELD	((1 << PLATFORM_CORE_COUNT) - 1)
+#define CPU_TARGET_FIELD	0xFF
 
 static event_t cpu_ready[PLATFORM_CORE_COUNT];
 static volatile int requested_irq_received[PLATFORM_CORE_COUNT];
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.xml b/tftf/tests/tests-realm-payload.xml
index da88701..7cc7866 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"
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 \
 	)