Merge changes from topics "multi_pdev", "pcie_enum"

* changes:
  feat(realm_host_mgmt): support multiple devices in DA test
  refactor(lib/pcie): rename macro CHECK_DA_SUPPORT_IN_RMI
  feat(lib/pcie): init pcie device capabilities
  feat(lib/pcie): add dvsec helpers
  fix(lib/pcie): import pcie enumeration helpers from rmm-acs
diff --git a/include/lib/pcie/pcie.h b/include/lib/pcie/pcie.h
index d7188a0..a08cd4a 100644
--- a/include/lib/pcie/pcie.h
+++ b/include/lib/pcie/pcie.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,6 +7,7 @@
 #ifndef PCIE_H
 #define PCIE_H
 
+#include <stdbool.h>
 #include <cdefs.h>
 #include <stdint.h>
 #include <utils_def.h>
@@ -14,6 +15,8 @@
 /* platforms need to ensure that number of entries is less that this value */
 #define MAX_PCIE_INFO_ENTRIES 5
 
+#define PCIE_DEVICES_MAX	128
+
 typedef struct {
 	unsigned long ecam_base;	/* ECAM base address */
 	unsigned int segment_num;	/* Segment number of this ECAM */
@@ -26,14 +29,39 @@
 	pcie_info_block_t block[MAX_PCIE_INFO_ENTRIES];
 };
 
-typedef struct {
-	uint32_t bdf;
-	uint32_t rp_bdf;
-} pcie_device_attr_t;
+/* Flags for PCIe device capability */
+#define PCIE_DEV_CFLAG_DOE		(U(1) << 0)
+#define PCIE_DEV_CFLAG_IDE		(U(1) << 1)
+#define PCIE_DEV_CFLAG_DVSEC_RMEDA	(U(1) << 3)
 
-typedef struct __packed {
+#define pcie_dev_has_doe(_d)	(((_d)->cflags & PCIE_DEV_CFLAG_DOE) != 0U)
+#define pcie_dev_has_ide(_d)	(((_d)->cflags & PCIE_DEV_CFLAG_IDE) != 0U)
+#define pcie_dev_has_dvsec_rmeda(_d)	\
+	(((_d)->cflags & PCIE_DEV_CFLAG_DVSEC_RMEDA) != 0U)
+
+struct pcie_dev {
+	uint32_t bdf;
+
+	/* Pointer to rootport device if this is a endpoint */
+	struct pcie_dev *rp_dev;
+
+	/* PCIe capabilities flags */
+	uint32_t cflags;
+
+	uint32_t doe_cap_base;
+	uint32_t ide_cap_base;
+	uint32_t dvsec_rmeda_cap_base;
+
+	/* Device port type */
+	uint32_t dp_type;
+
+	unsigned long ecam_base;
+};
+typedef struct pcie_dev pcie_dev_t;
+
+typedef struct {
 	uint32_t num_entries;
-	pcie_device_attr_t device[]; /* in the format of Segment/Bus/Dev/Func */
+	pcie_dev_t device[PCIE_DEVICES_MAX];
 } pcie_device_bdf_table_t;
 
 /* Address initialisation structure */
@@ -71,9 +99,6 @@
 #define PCIE_CAP_NOT_FOUND	0x10000010  /* The specified capability was not found */
 #define PCIE_UNKNOWN_RESPONSE	0xFFFFFFFF  /* Function not found or UR response from completer */
 
-/* Allows storage of 2048 valid BDFs */
-#define PCIE_DEVICE_BDF_TABLE_SZ	8192
-
 typedef enum {
 	HEADER = 0,
 	PCIE_CAP = 1,
@@ -100,7 +125,7 @@
 #define CC_BASE_SHIFT	24
 
 void pcie_init(void);
-void pcie_create_info_table(void);
+
 pcie_device_bdf_table_t *pcie_get_bdf_table(void);
 uint32_t pcie_find_capability(uint32_t bdf, uint32_t cid_type, uint32_t cid,
 				uint32_t *cid_offset);
diff --git a/include/lib/pcie/pcie_doe.h b/include/lib/pcie/pcie_doe.h
index 777309a..2d9016d 100644
--- a/include/lib/pcie/pcie_doe.h
+++ b/include/lib/pcie/pcie_doe.h
@@ -91,23 +91,6 @@
 	uint8_t next_index;
 } pcie_doe_disc_resp_t;
 
-/* Skip test if DA is not supported in RMI features */
-#define CHECK_DA_SUPPORT_IN_RMI(_reg0)						\
-	do {									\
-		SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();			\
-		/* Get feature register0 */					\
-		if (host_rmi_features(0UL, &_reg0) != REALM_SUCCESS) {		\
-			ERROR("Failed to get RMI feat_reg0\n");			\
-			return TEST_RESULT_FAIL;				\
-		}								\
-										\
-		/* DA not supported in RMI features? */				\
-		if ((_reg0 & RMI_FEATURE_REGISTER_0_DA_EN) == 0UL) {		\
-			WARN("DA not in RMI features, skipping\n");		\
-			return TEST_RESULT_SKIPPED;				\
-		}								\
-	} while (false)
-
 #define SKIP_TEST_IF_DOE_NOT_SUPPORTED(_bdf, _doe_cap_base)			\
 	do {									\
 		/* Test PCIe DOE only for RME */				\
diff --git a/include/lib/pcie/pcie_dvsec_rmeda.h b/include/lib/pcie/pcie_dvsec_rmeda.h
new file mode 100644
index 0000000..b693f2a
--- /dev/null
+++ b/include/lib/pcie/pcie_dvsec_rmeda.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PCIE_DVSEC_RME_DA_H
+#define PCIE_DVSEC_RME_DA_H
+
+/* PCI RootPort Extended Capability RMEDA registers offset */
+
+/*
+ * Extended Capability Header
+ * DVSEC Headers
+ * RME-DA Control registers
+ */
+#define PCIE_ECAP_ECH_OFFSET			U(0)
+#define PCIE_ECAP_DVSEC_HDR1_OFFSET		U(4)
+#define PCIE_ECAP_DVSEC_HDR2_OFFSET		U(8)
+#define PCIE_ECAP_DVSEC_RME_DA_CTL_REG1_OFFSET	U(12)
+#define PCIE_ECAP_DVSEC_RME_DA_CTL_REG2_OFFSET	U(16)
+
+/* RME-DA DVSEC Header1 */
+#define DVSEC_HDR1_VENDOR_ID_SHIFT		U(0)
+#define DVSEC_HDR1_VENDOR_ID_WIDTH		U(16)
+#define DVSEC_HDR1_REVISION_SHIFT		U(16)
+#define DVSEC_HDR1_REVISION_WIDTH		U(4)
+#define DVSEC_HDR1_LENGTH_SHIFT			U(20)
+#define DVSEC_HDR1_LENGTH_WIDTH			U(12)
+
+/* RME-DA DVSEC Header1 - Values */
+#define DVSEC_VENDOR_ID_ARM			U(0x13b5)
+#define DVSEC_REVISION_0			U(0x0)
+
+/* RME-DA DVSEC Header2 */
+#define DVSEC_HDR2_DVSEC_ID_SHIFT		U(0)
+#define DVSEC_HDR2_DVSEC_ID_WIDTH		U(16)
+
+/* RME-DA DVSEC Header2 - Values */
+#define DVSEC_ID_RME_DA				U(0xFF01)
+
+/* RME-DA Control register 1 */
+#define DVSEC_RMEDA_CTL_REG1_TDISP_EN_SHIFT	U(0)
+#define DVSEC_RMEDA_CTL_REG1_TDISP_EN_WIDTH	U(1)
+
+/* RME-DA Control register 1 - Values */
+#define RME_DA_TDISP_DISABLE			U(0)
+#define RME_DA_TDISP_ENABLE			U(1)
+
+/* RME-DA Control register 2. 32 IDE Selective Stream Lock bits */
+#define DVSEC_RME_DA_CTL_REG2_SEL_STR_LOCK_SHIFT	U(0)
+#define DVSEC_RME_DA_CTL_REG2_SEL_STR_LOCK_WIDTH	U(32)
+
+uint32_t pcie_find_rmeda_capability(uint32_t bdf, uint32_t *cid_offset);
+
+#endif /* PCIE_DVSEC_RME_DA_H */
diff --git a/include/lib/pcie/pcie_spec.h b/include/lib/pcie/pcie_spec.h
index 31fd98b..cd851ee 100644
--- a/include/lib/pcie/pcie_spec.h
+++ b/include/lib/pcie/pcie_spec.h
@@ -87,6 +87,14 @@
 #define PCIE_ECAP_CIDR_MASK	0xffff
 #define PCIE_ECAP_NCPR_MASK	0xfff
 
+/* PCIe Extended Capability Header */
+#define PCIE_ECH_ID_SHIFT			U(0)
+#define PCIE_ECH_ID_WIDTH			U(16)
+#define PCIE_ECH_CAP_VER_SHIFT			U(16)
+#define PCIE_ECH_CAP_VER_WIDTH			U(4)
+#define PCIE_ECH_NEXT_CAP_OFFSET_SHIFT		U(20)
+#define PCIE_ECH_NEXT_CAP_OFFSET_WIDTH		U(12)
+
 #define PCIE_CAP_START		0x40
 #define PCIE_CAP_END		0xFC
 #define PCIE_ECAP_START		0x100
@@ -107,6 +115,8 @@
 #define ECID_PASID		0x001B
 #define ECID_DPC		0x001D
 #define ECID_DVSEC		0x0023
+#define ECID_DOE		0x002E
+#define ECID_IDE		0x0030
 
 /* PCI Express capability struct offsets */
 #define CIDR_OFFSET		0x0
diff --git a/include/plat/common/plat_pcie_enum.h b/include/plat/common/plat_pcie_enum.h
new file mode 100644
index 0000000..667fe05
--- /dev/null
+++ b/include/plat/common/plat_pcie_enum.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2025, Arm Limited or its affiliates. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __PLAT_PCIE_ENUM_H__
+#define __PLAT_PCIE_ENUM_H__
+
+#include <stdio.h>
+#include <stdint.h>
+
+/* Header Offset and Type */
+#define HEADER_OFFSET		0xC
+#define TYPE0_HEADER		0
+#define TYPE1_HEADER		1
+
+#define TYPE01_RIDR		0x8
+
+#define DEVICE_ID_OFFSET	16
+
+/* Initial BUS definitions */
+#define PRI_BUS			0
+#define SEC_BUS			1
+#define BUS_NUM_REG_OFFSET	0x18
+
+/* BAR offset */
+#define BAR0_OFFSET		0x10
+#define TYPE1_BAR_MAX_OFF	0x14
+#define TYPE0_BAR_MAX_OFF	0x24
+
+#define BAR_NON_PRE_MEM		0
+#define BAR_PRE_MEM		0x1
+
+#define MEM_BASE32_LIM_MASK	0xFFF00000
+#define MEM_BASE64_LIM_MASK	0xFFFFFFFFFFF00000
+#define NON_PRE_FET_OFFSET	0x20
+#define PRE_FET_OFFSET		0x24
+#define BAR_INCREMENT		0x100000
+
+#define PRI_BUS_CLEAR_MASK	0xFFFFFF00
+
+#define TYPE0_MAX_BARS		6
+#define TYPE1_MAX_BARS		2
+
+/* BAR register masks */
+#define BAR_MIT_MASK		0x1
+#define BAR_MDT_MASK		0x3
+#define BAR_MT_MASK		0x1
+#define BAR_BASE_MASK		0xfffffff
+
+/* BAR register shifts */
+#define BAR_MIT_SHIFT		0
+#define BAR_MDT_SHIFT		1
+#define BAR_MT_SHIFT		3
+#define BAR_BASE_SHIFT		4
+
+/* TYPE 0/1 Cmn Cfg reg offsets and mask*/
+#define TYPE01_CPR		0x34
+#define TYPE01_CPR_MASK		0xff
+#define COMMAND_REG_OFFSET	0x04
+#define REG_ACC_DATA		0x7
+
+#define BAR_MASK		0xFFFFFFF0
+
+#define PCIE_HEADER_TYPE(header_value)		((header_value >> 16) & 0x3)
+#define BUS_NUM_REG_CFG(sub_bus, sec_bus, pri_bus)	(sub_bus << 16 | sec_bus << 8 | bus)
+
+#define BAR_REG(bar_reg_value)		((bar_reg_value >> 2) & 0x1)
+#define BAR_MEM(bar_reg_value)		((bar_reg_value & 0xF) >> 3)
+#define REG_MASK_SHIFT(bar_value)	((bar_value & MEM_BASE32_LIM_MASK) >> 16)
+
+#endif /* __PLAT_PCIE_ENUM_H__ */
diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h
index e5032fa..077ccb3 100644
--- a/include/plat/common/platform.h
+++ b/include/plat/common/platform.h
@@ -208,6 +208,11 @@
  */
 const struct pcie_info_table *plat_pcie_get_info_table(void);
 
+/* Retrieve platform PCIe bar config values */
+int plat_pcie_get_bar_config(uint64_t *bar64_val, uint64_t *rp_bar64_val,
+			     uint32_t *bar32np_val, uint32_t *bar32p_val,
+			     uint32_t *rp_bar32_val);
+
 /*
  * This function provides an address that is recognized as invalid for use
  * as an entry point in the CPU_ON and CPU_SUSPEND calls on this platform.
diff --git a/include/runtime_services/host_realm_managment/host_da_helper.h b/include/runtime_services/host_realm_managment/host_da_helper.h
index 0f6bf6a..f650bef 100644
--- a/include/runtime_services/host_realm_managment/host_da_helper.h
+++ b/include/runtime_services/host_realm_managment/host_da_helper.h
@@ -8,10 +8,37 @@
 #define HOST_DA_HELPER_H
 
 #include <host_realm_rmi.h>
+#include <pcie.h>
+
+/*
+ * Skip DA test if any of the below check is true
+ *   RMM is TRP
+ *   FEAT_RME not supported
+ *   DA is not supported in RMI features
+ */
+#define SKIP_DA_TEST_IF_PREREQS_NOT_MET(_reg0)					\
+	do {									\
+		SKIP_TEST_IF_RME_NOT_SUPPORTED_OR_RMM_IS_TRP();			\
+										\
+		/* Get feature register0 */					\
+		if (host_rmi_features(0UL, &_reg0) != REALM_SUCCESS) {		\
+			ERROR("Failed to get RMI feat_reg0\n");			\
+			return TEST_RESULT_FAIL;				\
+		}								\
+										\
+		/* DA not supported in RMI features? */				\
+		if ((_reg0 & RMI_FEATURE_REGISTER_0_DA_EN) == 0UL) {		\
+			WARN("DA not in RMI features, skipping\n");		\
+			return TEST_RESULT_SKIPPED;				\
+		}								\
+	} while (false)
 
 /* SPDM_MAX_CERTIFICATE_CHAIN_SIZE is 64KB */
 #define HOST_PDEV_CERT_LEN_MAX		(64 * 1024)
 
+/* todo: This macro can come from platform layer */
+#define HOST_PDEV_MAX		32
+
 /*
  * Measurement max supported is 4KB.
  * todo: This will be increased if device supports returning more measurements
@@ -45,9 +72,11 @@
 	size_t public_key_metadata_len;
 	unsigned char public_key_sig_algo;
 
-	/* PCIe details: bdf, DOE, Stream id, IO range */
-	uint32_t bdf;
-	uint32_t doe_cap_base;
+	/* Is this device connected to TSM */
+	bool is_connected_to_tsm;
+
+	/* The PCIe device for this host_pdev */
+	pcie_dev_t *dev;
 };
 
 struct host_vdev {
@@ -82,16 +111,18 @@
 	size_t ifc_report_len;
 };
 
+void host_pdevs_init(void);
+bool is_host_pdev_independently_attested(struct host_pdev *h_pdev);
 int host_create_realm_with_feat_da(struct realm *realm);
 int host_pdev_create(struct host_pdev *h_pdev);
 int host_pdev_reclaim(struct host_pdev *h_pdev);
 int host_pdev_setup(struct host_pdev *h_pdev);
 int host_pdev_transition(struct host_pdev *h_pdev, unsigned char to_state);
 
-int host_assign_vdev_to_realm(struct realm *realm, struct host_pdev *h_pdev,
-			      struct host_vdev *h_vdev);
-int host_unassign_vdev_from_realm(struct realm *realm, struct host_pdev *h_pdev,
-				  struct host_vdev *h_vdev);
+int host_assign_vdev_to_realm(struct realm *realm, struct host_vdev *h_vdev,
+			      unsigned long tdi_id, void *pdev_ptr);
+int host_unassign_vdev_from_realm(struct realm *realm, struct host_vdev *h_vdev);
+
 u_register_t host_dev_mem_map(struct realm *realm, u_register_t dev_pa,
 				long map_level, u_register_t *dev_ipa);
 
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 18e47a1..05570fd 100644
--- a/include/runtime_services/host_realm_managment/host_realm_rmi.h
+++ b/include/runtime_services/host_realm_managment/host_realm_rmi.h
@@ -1234,7 +1234,7 @@
 	/* Bits16: Segment ID */
 	SET_MEMBER_RMI(unsigned short segment_id, 0x10, 0x18);
 	/* Address: ECAM base address of the PCIe configuration space */
-	SET_MEMBER_RMI(unsigned short ecam_addr, 0x18, 0x20);
+	SET_MEMBER_RMI(unsigned long ecam_addr, 0x18, 0x20);
 	/* Bits16: Root Port identifier */
 	SET_MEMBER_RMI(unsigned short root_id, 0x20, 0x28);
 	/* UInt64: Certificate identifier */
diff --git a/lib/pcie/pcie.c b/lib/pcie/pcie.c
index 8de2825..96e1fb9 100644
--- a/lib/pcie/pcie.c
+++ b/lib/pcie/pcie.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,17 +13,36 @@
 #include <pcie.h>
 #include <pcie_doe.h>
 #include <pcie_spec.h>
+#include <pcie_dvsec_rmeda.h>
 #include <platform.h>
+#include <plat_pcie_enum.h>
 #include <tftf_lib.h>
 
 #define PCIE_DEBUG	VERBOSE
 
 const struct pcie_info_table *g_pcie_info_table;
-pcie_device_bdf_table_t *g_pcie_bdf_table;
+static pcie_device_bdf_table_t *g_pcie_bdf_table;
+static pcie_device_bdf_table_t pcie_bdf_table;
 
-pcie_device_bdf_table_t pcie_bdf_table[PCIE_DEVICE_BDF_TABLE_SZ];
+static uint32_t g_pcie_index;
+static uint32_t g_enumerate;
 
-uintptr_t pcie_cfg_addr(uint32_t bdf)
+/* 64-bit address initialisation */
+static uint64_t g_bar64_p_start;
+static uint64_t g_rp_bar64_value;
+static uint64_t g_bar64_p_max;
+static uint32_t g_64_bus, g_bar64_size;
+
+/* 32-bit address initialisation */
+static uint32_t g_bar32_np_start;
+static uint32_t g_bar32_p_start;
+static uint32_t g_rp_bar32_value;
+static uint32_t g_bar32_np_max;
+static uint32_t g_bar32_p_max;
+static uint32_t g_np_bar_size, g_p_bar_size;
+static uint32_t g_np_bus, g_p_bus;
+
+static uintptr_t pcie_cfg_addr(uint32_t bdf)
 {
 	uint32_t bus = PCIE_EXTRACT_BDF_BUS(bdf);
 	uint32_t dev = PCIE_EXTRACT_BDF_DEV(bdf);
@@ -102,7 +121,7 @@
  * @param   bdf - Function's Segment/Bus/Dev/Func in PCIE_CREATE_BDF format
  * @return  false If not a Host Bridge, true If it's a Host Bridge.
  */
-bool pcie_is_host_bridge(uint32_t bdf)
+static bool pcie_is_host_bridge(uint32_t bdf)
 {
 	uint32_t reg_value = pcie_read_cfg(bdf, TYPE01_RIDR);
 
@@ -168,7 +187,7 @@
  * @param  bdf
  * @return true if bdf is valid else false
  */
-bool pcie_check_device_valid(uint32_t bdf)
+static bool pcie_check_device_valid(uint32_t bdf)
 {
 	(void) bdf;
 	/*
@@ -185,7 +204,7 @@
  * @return Returns TRUE if the Function is on-chip peripheral, FALSE if it is
  *	   not an on-chip peripheral
  */
-bool pcie_is_onchip_peripheral(uint32_t bdf)
+static bool pcie_is_onchip_peripheral(uint32_t bdf)
 {
 	(void)bdf;
 	return false;
@@ -200,7 +219,7 @@
  *		   (1 << 0b1100) for iEP_EP, (1 << 0b1011) for iEP_RP,
  *		   (1 << PCIECR[7:4]) for any other device type.
  */
-uint32_t pcie_device_port_type(uint32_t bdf)
+static uint32_t pcie_device_port_type(uint32_t bdf)
 {
 	uint32_t pciecs_base, reg_value, dp_type;
 
@@ -233,13 +252,13 @@
  * @brief  Returns BDF of the upstream Root Port of a pcie device function.
  *
  * @param  bdf	     - Function's Segment/Bus/Dev/Func in PCIE_CREATE_BDF format
- * @param  usrp_bdf  - Upstream Rootport bdf in PCIE_CREATE_BDF format
- * @return 0 for success, 1 for failure.
+ * @return pcie_dev for success, NULL for failure.
  */
-uint32_t pcie_get_rootport(uint32_t bdf, uint32_t *rp_bdf)
+static pcie_dev_t *pcie_get_rootport(uint32_t bdf)
 {
 	uint32_t seg_num, sec_bus, sub_bus;
 	uint32_t reg_value, dp_type, index = 0;
+	uint32_t rp_bdf;
 
 	dp_type = pcie_device_port_type(bdf);
 
@@ -247,43 +266,43 @@
 
 	/* If the device is RP or iEP_RP, set its rootport value to same */
 	if ((dp_type == RP) || (dp_type == iEP_RP)) {
-		*rp_bdf = bdf;
-		return 0;
+		return NULL;
 	}
 
 	/* If the device is RCiEP and RCEC, set RP as 0xff */
 	if ((dp_type == RCiEP) || (dp_type == RCEC)) {
-		*rp_bdf = 0xffffffff;
-		return 1;
+		return NULL;
 	}
 
 	assert(g_pcie_bdf_table != NULL);
 
 	while (index < g_pcie_bdf_table->num_entries) {
-		*rp_bdf = g_pcie_bdf_table->device[index++].bdf;
+		rp_bdf = g_pcie_bdf_table->device[index].bdf;
 
 		/*
 		 * Extract Secondary and Subordinate Bus numbers of the
 		 * upstream Root port and check if the input function's
 		 * bus number falls within that range.
 		 */
-		reg_value = pcie_read_cfg(*rp_bdf, TYPE1_PBN);
-		seg_num = PCIE_EXTRACT_BDF_SEG(*rp_bdf);
+		reg_value = pcie_read_cfg(rp_bdf, TYPE1_PBN);
+		seg_num = PCIE_EXTRACT_BDF_SEG(rp_bdf);
 		sec_bus = ((reg_value >> SECBN_SHIFT) & SECBN_MASK);
 		sub_bus = ((reg_value >> SUBBN_SHIFT) & SUBBN_MASK);
-		dp_type = pcie_device_port_type(*rp_bdf);
+		dp_type = pcie_device_port_type(rp_bdf);
 
 		if (((dp_type == RP) || (dp_type == iEP_RP)) &&
-			(sec_bus <= PCIE_EXTRACT_BDF_BUS(bdf)) &&
-			(sub_bus >= PCIE_EXTRACT_BDF_BUS(bdf)) &&
-			(seg_num == PCIE_EXTRACT_BDF_SEG(bdf)))
-			return 0;
+		    (sec_bus <= PCIE_EXTRACT_BDF_BUS(bdf)) &&
+		    (sub_bus >= PCIE_EXTRACT_BDF_BUS(bdf)) &&
+		    (seg_num == PCIE_EXTRACT_BDF_SEG(bdf))) {
+			return &g_pcie_bdf_table->device[index];
 		}
 
-		/* Return failure */
-		ERROR("PCIe Hierarchy fail: RP of bdf 0x%x not found\n", bdf);
-		*rp_bdf = 0;
-		return 1;
+		index++;
+	}
+
+	/* Return failure */
+	ERROR("PCIe Hierarchy fail: RP of bdf 0x%x not found\n", bdf);
+	return NULL;
 }
 
 /*
@@ -294,8 +313,9 @@
  */
 static uint32_t pcie_populate_device_rootport(void)
 {
-	uint32_t bdf, rp_bdf;
+	uint32_t bdf;
 	pcie_device_bdf_table_t *bdf_tbl_ptr = g_pcie_bdf_table;
+	pcie_dev_t *rp_dev;
 
 	assert(bdf_tbl_ptr != NULL);
 
@@ -304,16 +324,125 @@
 		bdf = bdf_tbl_ptr->device[tbl_index].bdf;
 
 		/* Checks if the BDF has RootPort */
-		pcie_get_rootport(bdf, &rp_bdf);
+		rp_dev = pcie_get_rootport(bdf);
 
-		bdf_tbl_ptr->device[tbl_index].rp_bdf = rp_bdf;
-		PCIE_DEBUG("Dev bdf: 0x%x RP bdf: 0x%x\n", bdf, rp_bdf);
+		bdf_tbl_ptr->device[tbl_index].rp_dev = rp_dev;
+
+		if (rp_dev != NULL) {
+			INFO("Dev bdf: 0x%x RP bdf: 0x%x\n", bdf,
+			     rp_dev->bdf);
+		} else {
+			INFO("Dev bdf: 0x%x RP bdf: none\n", bdf);
+		}
 	}
 
 	return 0;
 }
 
 /*
+ * @brief  Returns the header type of the input pcie device function
+ *
+ * @param  bdf   - Segment/Bus/Dev/Func in the format of PCIE_CREATE_BDF
+ * @return TYPE0_HEADER for functions with Type 0 config space header,
+ *         TYPE1_HEADER for functions with Type 1 config space header,
+ */
+static uint32_t pcie_function_header_type(uint32_t bdf)
+{
+	/* Read four bytes of config space starting from cache line size register */
+	uint32_t reg_value = pcie_read_cfg(bdf, TYPE01_CLSR);
+
+	/* Extract header type register value */
+	reg_value = ((reg_value >> TYPE01_HTR_SHIFT) & TYPE01_HTR_MASK);
+
+	/* Header layout bits within header type register indicate the header type */
+	return ((reg_value >> HTR_HL_SHIFT) & HTR_HL_MASK);
+}
+
+/*
+ * @brief  Returns the ECAM address of the input PCIe function
+ *
+ * @param  bdf   - Segment/Bus/Dev/Func in PCIE_CREATE_BDF format
+ * @return ECAM address if success, else NULL address
+ */
+static uintptr_t pcie_get_ecam_base(uint32_t bdf)
+{
+	uint8_t ecam_index = 0, sec_bus = 0, sub_bus;
+	uint16_t seg_num = (uint16_t)PCIE_EXTRACT_BDF_SEG(bdf);
+	uint32_t reg_value;
+	uintptr_t ecam_base = 0;
+
+	assert(g_pcie_info_table != NULL);
+
+	while (ecam_index < g_pcie_info_table->num_entries) {
+		/* Derive ECAM specific information */
+		const pcie_info_block_t *block = &g_pcie_info_table->block[ecam_index];
+
+		if (seg_num == block->segment_num) {
+			if (pcie_function_header_type(bdf) == TYPE0_HEADER) {
+				/* Return ecam_base if Type0 Header */
+				ecam_base = block->ecam_base;
+				break;
+			}
+
+			/* Check for Secondary/Subordinate bus if Type1 Header */
+			reg_value = pcie_read_cfg(bdf, TYPE1_PBN);
+			sec_bus = ((reg_value >> SECBN_SHIFT) & SECBN_MASK);
+			sub_bus = ((reg_value >> SUBBN_SHIFT) & SUBBN_MASK);
+
+			if ((sec_bus >= block->start_bus_num) &&
+			    (sub_bus <= block->end_bus_num)) {
+				ecam_base = block->ecam_base;
+				break;
+			}
+		}
+		ecam_index++;
+	}
+
+	return ecam_base;
+}
+
+static void pcie_devices_init_fields(void)
+{
+	pcie_device_bdf_table_t *bdf_tbl_ptr = g_pcie_bdf_table;
+	pcie_dev_t *pcie_dev;
+	uint32_t status;
+	uint32_t base;
+	uint32_t bdf;
+
+	assert(bdf_tbl_ptr != NULL);
+
+	for (uint32_t i = 0; i < bdf_tbl_ptr->num_entries; i++) {
+		pcie_dev = &bdf_tbl_ptr->device[i];
+		bdf = pcie_dev->bdf;
+
+		pcie_dev->dp_type = pcie_device_port_type(bdf);
+		pcie_dev->ecam_base = pcie_get_ecam_base(bdf);
+
+		/* Has DOE? */
+		status = pcie_find_capability(bdf, PCIE_ECAP, ECID_DOE, &base);
+		if (status == PCIE_SUCCESS) {
+			pcie_dev->cflags |= PCIE_DEV_CFLAG_DOE;
+			pcie_dev->doe_cap_base = base;
+		}
+
+		/* Has IDE? */
+		status = pcie_find_capability(bdf, PCIE_ECAP, ECID_IDE, &base);
+		if (status == PCIE_SUCCESS) {
+			pcie_dev->cflags |= PCIE_DEV_CFLAG_IDE;
+			pcie_dev->ide_cap_base = base;
+		}
+
+		if (pcie_dev->dp_type == RP) {
+			status = pcie_find_rmeda_capability(bdf, &base);
+			if (status == PCIE_SUCCESS) {
+				pcie_dev->cflags |= PCIE_DEV_CFLAG_DVSEC_RMEDA;
+				pcie_dev->dvsec_rmeda_cap_base = base;
+			}
+		}
+	}
+}
+
+/*
  * @brief  Returns the BDF Table pointer
  *
  * @param  None
@@ -334,7 +463,7 @@
  *
  * @return  None
  */
-void pcie_create_device_bdf_table(void)
+static void pcie_create_device_bdf_table(void)
 {
 	uint32_t seg_num, start_bus, end_bus;
 	uint32_t bus_index, dev_index, func_index, ecam_index;
@@ -386,6 +515,8 @@
 
 						g_pcie_bdf_table->device[
 							g_pcie_bdf_table->num_entries++].bdf = bdf;
+
+						assert(g_pcie_bdf_table->num_entries < PCIE_DEVICES_MAX);
 					}
 				}
 			}
@@ -394,79 +525,24 @@
 
 	/* Sanity Check : Confirm all EP (normal, integrated) have a rootport */
 	pcie_populate_device_rootport();
+
+	/*
+	 * Once devices are enumerated and rootports are assigned, initialize
+	 * the rest of pcie_dev fields
+	 */
+	pcie_devices_init_fields();
+
 	INFO("Number of BDFs found     : %u\n", g_pcie_bdf_table->num_entries);
 }
 
 /*
- * @brief  Returns the header type of the input pcie device function
- *
- * @param  bdf   - Segment/Bus/Dev/Func in the format of PCIE_CREATE_BDF
- * @return TYPE0_HEADER for functions with Type 0 config space header,
- *         TYPE1_HEADER for functions with Type 1 config space header,
- */
-uint32_t pcie_function_header_type(uint32_t bdf)
-{
-	/* Read four bytes of config space starting from cache line size register */
-	uint32_t reg_value = pcie_read_cfg(bdf, TYPE01_CLSR);
-
-	/* Extract header type register value */
-	reg_value = ((reg_value >> TYPE01_HTR_SHIFT) & TYPE01_HTR_MASK);
-
-	/* Header layout bits within header type register indicate the header type */
-	return ((reg_value >> HTR_HL_SHIFT) & HTR_HL_MASK);
-}
-
-/*
- * @brief  Returns the ECAM address of the input PCIe function
- *
- * @param  bdf   - Segment/Bus/Dev/Func in PCIE_CREATE_BDF format
- * @return ECAM address if success, else NULL address
- */
-uintptr_t pcie_get_ecam_base(uint32_t bdf)
-{
-	uint8_t ecam_index = 0, sec_bus = 0, sub_bus;
-	uint16_t seg_num = (uint16_t)PCIE_EXTRACT_BDF_SEG(bdf);
-	uint32_t reg_value;
-	uintptr_t ecam_base = 0;
-
-	assert(g_pcie_info_table != NULL);
-
-	while (ecam_index < g_pcie_info_table->num_entries) {
-		/* Derive ECAM specific information */
-		const pcie_info_block_t *block = &g_pcie_info_table->block[ecam_index];
-
-		if (seg_num == block->segment_num) {
-			if (pcie_function_header_type(bdf) == TYPE0_HEADER) {
-				/* Return ecam_base if Type0 Header */
-				ecam_base = block->ecam_base;
-				break;
-			}
-
-			/* Check for Secondary/Subordinate bus if Type1 Header */
-			reg_value = pcie_read_cfg(bdf, TYPE1_PBN);
-			sec_bus = ((reg_value >> SECBN_SHIFT) & SECBN_MASK);
-			sub_bus = ((reg_value >> SUBBN_SHIFT) & SUBBN_MASK);
-
-			if ((sec_bus >= block->start_bus_num) &&
-			    (sub_bus <= block->end_bus_num)) {
-				ecam_base = block->ecam_base;
-				break;
-			}
-		}
-		ecam_index++;
-	}
-
-	return ecam_base;
-}
-
-/*
  * @brief   This API prints all the PCIe Devices info
  * 1. Caller	   -  Validation layer.
  * 2. Prerequisite -  val_pcie_create_info_table()
  * @param   None
  * @return  None
  */
-void pcie_print_device_info(void)
+static void pcie_print_device_info(void)
 {
 	uint32_t bdf, dp_type;
 	uint32_t tbl_index = 0;
@@ -596,19 +672,12 @@
  * @param	void
  * @return	void
  */
-void pcie_create_info_table(void)
+static void pcie_create_info_table(void)
 {
 	unsigned int num_ecam;
 
 	INFO("Creating PCIe info table\n");
-
-	g_pcie_info_table = plat_pcie_get_info_table();
-	if (g_pcie_info_table == NULL) {
-		ERROR("PCIe info not returned by platform\n");
-		panic();
-	}
-
-	g_pcie_bdf_table = pcie_bdf_table;
+	g_pcie_bdf_table = &pcie_bdf_table;
 
 	num_ecam = g_pcie_info_table->num_entries;
 	INFO("Number of ECAM regions   : %u\n", num_ecam);
@@ -620,12 +689,611 @@
 	pcie_print_device_info();
 }
 
+static void pal_pci_cfg_write(uint32_t bus, uint32_t dev, uint32_t func,
+			      uint32_t offset, uint32_t data)
+{
+	pcie_write_cfg(PCIE_CREATE_BDF(0, bus, dev, func), offset, data);
+}
+
+static void pal_pci_cfg_read(uint32_t bus, uint32_t dev, uint32_t func,
+			     uint32_t offset, uint32_t *value)
+{
+	*value = pcie_read_cfg(PCIE_CREATE_BDF(0, bus, dev, func), offset);
+}
+
+/*
+ * This API programs the Memory Base and Memeory limit register of the Bus,
+ * Device and Function of Type1 Header
+ */
+static void get_resource_base_32(uint32_t bus, uint32_t dev, uint32_t func,
+				 uint32_t bar32_p_base, uint32_t bar32_np_base,
+				 uint32_t bar32_p_limit, uint32_t bar32_np_limit)
+{
+	uint32_t mem_bar_np;
+	uint32_t mem_bar_p;
+
+	/* Update the 32 bit NP-BAR start address for the next iteration */
+	if (bar32_np_base != g_bar32_np_start) {
+		if ((g_bar32_np_start << 12) != 0) {
+			g_bar32_np_start = (g_bar32_np_start &
+					    MEM_BASE32_LIM_MASK) + BAR_INCREMENT;
+		}
+
+		if (bar32_np_limit == g_bar32_np_start) {
+			bar32_np_limit = bar32_np_limit - BAR_INCREMENT;
+		}
+
+		pal_pci_cfg_read(bus, dev, func, NON_PRE_FET_OFFSET,
+				 &mem_bar_np);
+		mem_bar_np = ((bar32_np_limit & MEM_BASE32_LIM_MASK) |
+			      mem_bar_np);
+		pal_pci_cfg_write(bus, dev, func, NON_PRE_FET_OFFSET,
+				  mem_bar_np);
+	}
+
+	/* Update the 32 bit P-BAR start address for the next iteration */
+	if (bar32_p_base != g_bar32_p_start) {
+		if ((g_bar32_p_start  << 12) != 0) {
+			g_bar32_p_start  = (g_bar32_p_start &
+					    MEM_BASE32_LIM_MASK) + BAR_INCREMENT;
+		}
+
+		if (bar32_p_limit == g_bar32_p_start) {
+			bar32_p_limit = bar32_p_limit - BAR_INCREMENT;
+		}
+
+		pal_pci_cfg_read(bus, dev, func, PRE_FET_OFFSET, &mem_bar_p);
+		mem_bar_p = ((bar32_p_limit & MEM_BASE32_LIM_MASK) | mem_bar_p);
+		pal_pci_cfg_write(bus, dev, func, PRE_FET_OFFSET, mem_bar_p);
+	}
+}
+
+/*
+ * This API programs the Memory Base and Memeory limit register of the Bus,
+ * Device and Function of Type1 Header
+ */
+static void get_resource_base_64(uint32_t bus, uint32_t dev, uint32_t func,
+				 uint64_t bar64_p_base, uint64_t g_bar64_p_max)
+{
+	uint32_t bar64_p_lower32_base = (uint32_t)bar64_p_base;
+	uint32_t bar64_p_upper32_base = (uint32_t)(bar64_p_base >> 32);
+	uint32_t bar64_p_lower32_limit = (uint32_t)g_bar64_p_max;
+	uint32_t bar64_p_upper32_limit = (uint32_t)(g_bar64_p_max >> 32);
+
+	/* Obtain the memory base and memory limit */
+	bar64_p_lower32_base = REG_MASK_SHIFT(bar64_p_lower32_base);
+	bar64_p_lower32_limit = REG_MASK_SHIFT(bar64_p_lower32_limit);
+	uint32_t mem_bar_p = ((bar64_p_lower32_limit << 16) |
+			      bar64_p_lower32_base);
+
+	/* Configure Memory base and Memory limit register */
+	if ((bar64_p_base != g_bar64_p_max) && (g_bar64_p_start <=
+						g_bar64_p_max)) {
+		if ((g_bar64_p_start  << 12) != 0) {
+			g_bar64_p_start = (g_bar64_p_start &
+					   MEM_BASE64_LIM_MASK) + BAR_INCREMENT;
+		}
+
+		if (bar64_p_lower32_limit == g_bar64_p_start) {
+			bar64_p_lower32_limit = bar64_p_lower32_limit -
+				BAR_INCREMENT;
+		}
+
+		g_bar64_p_start = (g_bar64_p_start & MEM_BASE64_LIM_MASK) +
+			BAR_INCREMENT;
+
+		pal_pci_cfg_write(bus, dev, func, PRE_FET_OFFSET, mem_bar_p);
+		pal_pci_cfg_write(bus, dev, func, PRE_FET_OFFSET + 4,
+				  bar64_p_upper32_base);
+		pal_pci_cfg_write(bus, dev, func, PRE_FET_OFFSET + 8,
+				  bar64_p_upper32_limit);
+	}
+}
+
+static void pcie_rp_program_bar(uint32_t bus, uint32_t dev, uint32_t func)
+{
+	uint64_t bar_size, bar_upper_bits;
+	uint32_t offset = BAR0_OFFSET;
+	uint32_t bar_reg_value, bar_lower_bits;
+
+	while (offset <= TYPE1_BAR_MAX_OFF) {
+		pal_pci_cfg_read(bus, dev, func, offset, &bar_reg_value);
+
+		if (BAR_REG(bar_reg_value) == BAR_64_BIT) {
+			/*
+			 * BAR supports 64-bit address therefore, write all 1's
+			 * to BARn and BARn+1 and identify the size requested
+			 */
+			pal_pci_cfg_write(bus, dev, func, offset, 0xFFFFFFF0);
+			pal_pci_cfg_write(bus, dev, func, offset + 4,
+					  0xFFFFFFFF);
+			pal_pci_cfg_read(bus, dev, func, offset,
+					 &bar_lower_bits);
+			bar_size = bar_lower_bits & BAR_MASK;
+
+			pal_pci_cfg_read(bus, dev, func, offset + 4,
+					 &bar_reg_value);
+			bar_upper_bits = bar_reg_value;
+			bar_size = bar_size | (bar_upper_bits << 32);
+
+			bar_size = ~bar_size + 1;
+
+			/*
+			 * If BAR size is 0, then BAR not implemented, move to
+			 * next BAR
+			 */
+			if (bar_size == 0) {
+				offset = offset + 8;
+				continue;
+			}
+
+			pal_pci_cfg_write(bus, dev, func, offset,
+					  (uint32_t)g_rp_bar64_value);
+			pal_pci_cfg_write(bus, dev, func, offset + 4,
+					  (uint32_t)(g_rp_bar64_value >> 32));
+			offset = offset + 8;
+		} else {
+			/*
+			 * BAR supports 32-bit address. Write all 1's to BARn
+			 * and identify the size requested
+			 */
+			pal_pci_cfg_write(bus, dev, func, offset, 0xFFFFFFF0);
+			pal_pci_cfg_read(bus, dev, func, offset,
+					 &bar_lower_bits);
+			bar_reg_value = bar_lower_bits & BAR_MASK;
+			bar_size = ~bar_reg_value + 1;
+
+			/*
+			 * If BAR size is 0, then BAR not implemented, move to
+			 * next BAR
+			 */
+			if (bar_size == 0) {
+				offset = offset + 4;
+				continue;
+			}
+
+			pal_pci_cfg_write(bus, dev, func, offset,
+					  g_rp_bar32_value);
+			g_rp_bar32_value = g_rp_bar32_value + (uint32_t)bar_size;
+			offset = offset + 4;
+		}
+	}
+}
+
+/*
+ * This API programs all the BAR register in PCIe config space pointed by Bus,
+ *  Device and Function for an End Point PCIe device
+ */
+static void pcie_program_bar_reg(uint32_t bus, uint32_t dev, uint32_t func)
+{
+	uint64_t bar_size, bar_upper_bits;
+	uint32_t bar_reg_value, bar_lower_bits;
+	uint32_t offset = BAR0_OFFSET;
+	uint32_t np_bar_size = 0;
+	uint32_t p_bar_size = 0, p_bar64_size = 0;
+
+	while (offset <= TYPE0_BAR_MAX_OFF) {
+		pal_pci_cfg_read(bus, dev, func, offset, &bar_reg_value);
+
+		if (BAR_MEM(bar_reg_value) == BAR_PRE_MEM) {
+			if (BAR_REG(bar_reg_value) == BAR_64_BIT) {
+				/*
+				 * BAR supports 64-bit address therefore,
+				 * write all 1's to BARn and BARn+1 and identify
+				 * the size requested
+				 */
+
+				pal_pci_cfg_write(bus, dev, func, offset,
+						  0xFFFFFFF0);
+				pal_pci_cfg_write(bus, dev, func, offset + 4,
+						  0xFFFFFFFF);
+				pal_pci_cfg_read(bus, dev, func, offset,
+						 &bar_lower_bits);
+				bar_size = bar_lower_bits & BAR_MASK;
+
+				pal_pci_cfg_read(bus, dev, func, offset + 4,
+						 &bar_reg_value);
+				bar_upper_bits = bar_reg_value;
+				bar_size = bar_size | (bar_upper_bits << 32);
+
+				bar_size = ~bar_size + 1;
+
+				/*
+				 * If BAR size is 0, then BAR not implemented,
+				 * move to next BAR
+				 */
+				if (bar_size == 0) {
+					offset = offset + 8;
+					continue;
+				}
+
+				/*
+				 * If p_bar64_size = 0 and bus number is same as
+				 * bus of previous bus number, then check if the
+				 * current PCIe Device BAR size is greater than
+				 * the previous BAR size, if yes then add current
+				 * BAR size to the updated start address else
+				 * add the previous BAR size to the updated
+				 * start address
+				 */
+				if ((p_bar64_size == 0) && ((g_64_bus == bus))) {
+					if (g_bar64_size < bar_size) {
+						g_bar64_p_start =
+							g_bar64_p_start +
+							bar_size;
+					} else {
+						g_bar64_p_start =
+							g_bar64_p_start +
+							g_bar64_size;
+					}
+				} else if ((g_bar64_size < bar_size) &&
+					   (p_bar64_size != 0)) {
+					g_bar64_p_start = g_bar64_p_start +
+						bar_size;
+				} else {
+					g_bar64_p_start = g_bar64_p_start +
+						p_bar64_size;
+				}
+
+				pal_pci_cfg_write(bus, dev, func, offset,
+						  (uint32_t)g_bar64_p_start);
+				pal_pci_cfg_write(bus, dev, func, offset + 4,
+						  (uint32_t)(g_bar64_p_start >>
+							     32));
+
+				p_bar64_size = (uint32_t)bar_size;
+				g_bar64_size = (uint32_t)bar_size;
+				g_64_bus = bus;
+				offset = offset + 8;
+			} else {
+				/*
+				 * BAR supports 32-bit address. Write all 1's
+				 * to BARn and identify the size requested
+				 */
+				pal_pci_cfg_write(bus, dev, func, offset,
+						  0xFFFFFFF0);
+				pal_pci_cfg_read(bus, dev, func, offset,
+						 &bar_lower_bits);
+				bar_reg_value = bar_lower_bits & BAR_MASK;
+				bar_size = ~bar_reg_value + 1;
+
+				/*
+				 * If BAR size is 0, then BAR not implemented,
+				 * move to next BAR
+				 */
+				if (bar_size == 0) {
+					offset = offset + 4;
+					continue;
+				}
+
+				/*
+				 * If p_bar_size = 0 and bus number is same as
+				 * bus of previous bus number, then check if the
+				 * current PCIe Device BAR size is greater than
+				 * the previous BAR size, if yes then add
+				 * current BAR size to the updated start
+				 * address else add the previous BAR size to the
+				 * updated start address
+				 */
+				if ((p_bar_size == 0) && ((g_p_bus == bus))) {
+					if (g_p_bar_size < bar_size) {
+						g_bar32_p_start =
+							g_bar32_p_start +
+							(uint32_t)bar_size;
+					} else {
+						g_bar32_p_start =
+							g_bar32_p_start +
+							g_p_bar_size;
+					}
+				} else if ((g_p_bar_size < bar_size) &&
+					   (p_bar_size != 0)) {
+					g_bar32_p_start = g_bar32_p_start +
+						(uint32_t)bar_size;
+				} else {
+					g_bar32_p_start = g_bar32_p_start +
+						p_bar_size;
+				}
+
+				pal_pci_cfg_write(bus, dev, func, offset,
+						  g_bar32_p_start);
+				p_bar_size = (uint32_t)bar_size;
+				g_p_bar_size = (uint32_t)bar_size;
+				g_p_bus = bus;
+
+				offset = offset + 4;
+			}
+		} else {
+			/*
+			 * BAR supports 32-bit address. Write all 1's to BARn
+			 * and identify the size requested
+			 */
+			pal_pci_cfg_write(bus, dev, func, offset, 0xFFFFFFF0);
+			pal_pci_cfg_read(bus, dev, func, offset,
+					 &bar_lower_bits);
+			bar_reg_value = bar_lower_bits & BAR_MASK;
+			bar_size = ~bar_reg_value + 1;
+
+			/*
+			 * If BAR size is 0, then BAR not implemented, move to
+			 * next BAR
+			 */
+			if (bar_size == 0) {
+				if (BAR_REG(bar_lower_bits) == BAR_64_BIT) {
+					offset = offset + 8;
+				}
+
+				if (BAR_REG(bar_lower_bits) == BAR_32_BIT) {
+					offset = offset + 4;
+				}
+
+				continue;
+			}
+
+			/*
+			 * If np_bar_size = 0 and bus number is same as bus of
+			 * previous bus number, then check if the current PCIe
+			 * Device BAR size is greater than the previous BAR
+			 * size, if yes then add current BAR size to the
+			 * updated start address else add the previous BAR size
+			 * to the updated start address
+			 */
+			if ((np_bar_size == 0) && ((g_np_bus == bus))) {
+				if (g_np_bar_size < bar_size) {
+					g_bar32_np_start = g_bar32_np_start +
+						(uint32_t)bar_size;
+				} else {
+					g_bar32_np_start = g_bar32_np_start +
+						g_np_bar_size;
+				}
+			} else if ((g_np_bar_size < bar_size) &&
+				   (np_bar_size != 0)) {
+				g_bar32_np_start = g_bar32_np_start +
+					(uint32_t)bar_size;
+			} else {
+				g_bar32_np_start = g_bar32_np_start +
+					np_bar_size;
+			}
+
+			pal_pci_cfg_write(bus, dev, func, offset,
+					  g_bar32_np_start);
+			np_bar_size = (uint32_t)bar_size;
+			g_np_bar_size = (uint32_t)bar_size;
+			g_np_bus = bus;
+
+			pal_pci_cfg_read(bus, dev, func, offset, &bar_reg_value);
+			if (BAR_REG(bar_reg_value) == BAR_64_BIT) {
+				pal_pci_cfg_write(bus, dev, func,
+						  offset + 4, 0);
+				offset = offset + 8;
+			}
+
+			if (BAR_REG(bar_reg_value) == BAR_32_BIT) {
+				offset = offset + 4;
+			}
+		}
+
+		g_bar32_p_max = g_bar32_p_start;
+		g_bar32_np_max = g_bar32_np_start;
+		g_bar64_p_max =  g_bar64_p_start;
+	}
+}
+
+/*
+ * This API performs the PCIe bus enumeration
+ *
+ * bus,sec_bus - Bus(8-bits), secondary bus (8-bits)
+ * sub_bus - Subordinate bus
+ */
+static uint32_t pcie_enumerate_device(uint32_t bus, uint32_t sec_bus)
+{
+	uint32_t vendor_id = 0;
+	uint32_t header_value;
+	uint32_t sub_bus = bus;
+	uint32_t dev;
+	uint32_t func;
+	uint32_t class_code;
+	uint32_t com_reg_value;
+	uint32_t bar32_p_limit;
+	uint32_t bar32_np_limit;
+	uint32_t bar32_p_base = g_bar32_p_start;
+	uint32_t bar32_np_base = g_bar32_np_start;
+	uint64_t bar64_p_base = g_bar64_p_start;
+
+	if (bus == ((g_pcie_info_table->block[g_pcie_index].end_bus_num) + 1)) {
+		return sub_bus;
+	}
+
+	for (dev = 0; dev < PCIE_MAX_DEV; dev++) {
+		for (func = 0; func < PCIE_MAX_FUNC; func++) {
+			pal_pci_cfg_read(bus, dev, func, 0, &vendor_id);
+
+			if ((vendor_id == 0x0) || (vendor_id == 0xFFFFFFFF)) {
+				continue;
+			}
+
+			/* Skip Hostbridge configuration */
+			pal_pci_cfg_read(bus, dev, func, TYPE01_RIDR,
+					 &class_code);
+
+			if ((((class_code >> CC_BASE_SHIFT) & CC_BASE_MASK) ==
+			     HB_BASE_CLASS) &&
+			    (((class_code >> CC_SUB_SHIFT) & CC_SUB_MASK)) ==
+			    HB_SUB_CLASS) {
+				continue;
+			}
+
+			pal_pci_cfg_read(bus, dev, func, HEADER_OFFSET,
+					 &header_value);
+			if (PCIE_HEADER_TYPE(header_value) == TYPE1_HEADER) {
+				/*
+				 * Enable memory access, Bus master enable and
+				 * I/O access
+				 */
+				pal_pci_cfg_read(bus, dev, func,
+						 COMMAND_REG_OFFSET,
+						 &com_reg_value);
+
+				pal_pci_cfg_write(bus, dev, func,
+						  COMMAND_REG_OFFSET,
+						  (com_reg_value |
+						   REG_ACC_DATA));
+
+				pal_pci_cfg_write(bus, dev, func,
+						  BUS_NUM_REG_OFFSET,
+						  BUS_NUM_REG_CFG(0xFF, sec_bus,
+								  bus));
+
+				pal_pci_cfg_write(bus, dev, func,
+						  NON_PRE_FET_OFFSET,
+						  ((g_bar32_np_start >> 16) &
+						   0xFFF0));
+
+				pal_pci_cfg_write(bus, dev, func,
+						  PRE_FET_OFFSET,
+						  ((g_bar32_p_start >> 16) &
+						   0xFFF0));
+
+				sub_bus = pcie_enumerate_device(sec_bus,
+								(sec_bus + 1));
+				pal_pci_cfg_write(bus, dev, func,
+						  BUS_NUM_REG_OFFSET,
+						  BUS_NUM_REG_CFG(sub_bus,
+								  sec_bus, bus));
+				sec_bus = sub_bus + 1;
+
+				/*
+				 * Obtain the start memory base address & the
+				 * final memory base address of 32 bit BAR
+				 */
+				bar32_p_limit = g_bar32_p_max;
+				bar32_np_limit = g_bar32_np_max;
+
+				get_resource_base_32(bus, dev, func,
+						     bar32_p_base,
+						     bar32_np_base,
+						     bar32_p_limit,
+						     bar32_np_limit);
+
+				/*
+				 * Obtain the start memory base address & the
+				 * final memory base address of 64 bit BAR
+				 */
+				get_resource_base_64(bus, dev, func,
+						     bar64_p_base,
+						     g_bar64_p_max);
+
+				/* Update the BAR values of Type 1 Devices */
+				pcie_rp_program_bar(bus, dev, func);
+
+				/* Update the base and limit values */
+				bar32_p_base = g_bar32_p_start;
+				bar32_np_base = g_bar32_np_start;
+				bar64_p_base = g_bar64_p_start;
+			}
+
+			if (PCIE_HEADER_TYPE(header_value) == TYPE0_HEADER) {
+				pcie_program_bar_reg(bus, dev, func);
+				sub_bus = sec_bus - 1;
+			}
+		}
+	}
+
+	return sub_bus;
+}
+
+/*
+ * This API clears the primary bus number configured in the Type1 Header.
+ * Note: This is done to make sure the hardware is compatible
+ * with Linux enumeration.
+ */
+static void pcie_clear_pri_bus(void)
+{
+	uint32_t bus;
+	uint32_t dev;
+	uint32_t func;
+	uint32_t bus_value;
+	uint32_t header_value;
+	uint32_t vendor_id;
+
+	for (bus = 0; bus <= g_pcie_info_table->block[g_pcie_index].end_bus_num;
+	     bus++) {
+		for (dev = 0; dev < PCIE_MAX_DEV; dev++) {
+			for (func = 0; func < PCIE_MAX_FUNC; func++) {
+				pal_pci_cfg_read(bus, dev, func, 0, &vendor_id);
+
+				if ((vendor_id == 0x0) ||
+				    (vendor_id == 0xFFFFFFFF)) {
+					continue;
+				}
+
+				pal_pci_cfg_read(bus, dev, func, HEADER_OFFSET,
+						 &header_value);
+				if (PCIE_HEADER_TYPE(header_value) ==
+				    TYPE1_HEADER) {
+					pal_pci_cfg_read(bus, dev, func,
+							 BUS_NUM_REG_OFFSET,
+							 &bus_value);
+
+					bus_value = bus_value &
+						PRI_BUS_CLEAR_MASK;
+
+					pal_pci_cfg_write(bus, dev, func,
+							  BUS_NUM_REG_OFFSET,
+							  bus_value);
+				}
+			}
+		}
+	}
+}
+
+static void pcie_enumerate_devices(void)
+{
+	uint32_t pri_bus, sec_bus;
+	int rc;
+
+	g_pcie_info_table = plat_pcie_get_info_table();
+	if (g_pcie_info_table == NULL) {
+		ERROR("PCIe info not returned by platform\n");
+		panic();
+	}
+
+	if (g_pcie_info_table->num_entries == 0) {
+		INFO("Skipping Enumeration\n");
+		return;
+	}
+
+	/* Get platform specific bar config parameters */
+	rc = plat_pcie_get_bar_config(&g_bar64_p_start, &g_rp_bar64_value,
+				      &g_bar32_np_start, &g_bar32_p_start,
+				      &g_rp_bar32_value);
+	if (rc != 0) {
+		ERROR("PCIe bar config parameters not returned by platform\n");
+		panic();
+	}
+
+	INFO("Starting Enumeration\n");
+	while (g_pcie_index < g_pcie_info_table->num_entries) {
+		pri_bus = g_pcie_info_table->block[g_pcie_index].start_bus_num;
+
+		sec_bus = pri_bus + 1;
+
+		pcie_enumerate_device(pri_bus, sec_bus);
+		pcie_clear_pri_bus();
+
+		g_pcie_index++;
+	}
+	g_enumerate = 0;
+	g_pcie_index = 0;
+}
+
 void pcie_init(void)
 {
 	static bool is_init;
 
 	/* Create PCIe table and enumeration */
 	if (!is_init) {
+		pcie_enumerate_devices();
+
 		pcie_create_info_table();
 		is_init = true;
 	}
diff --git a/lib/pcie/pcie_doe.c b/lib/pcie/pcie_doe.c
index bd8e53a..e1d6449 100644
--- a/lib/pcie/pcie_doe.c
+++ b/lib/pcie/pcie_doe.c
@@ -13,6 +13,7 @@
 
 #include <debug.h>
 #include <pcie.h>
+#include <pcie_spec.h>
 #include <pcie_doe.h>
 #include <tftf_lib.h>
 
@@ -241,10 +242,12 @@
 	return rc;
 }
 
+/* TODO: add an iterator interface to get next eligible device */
 int pcie_find_doe_device(uint32_t *bdf_ptr, uint32_t *cap_base_ptr)
 {
 	pcie_device_bdf_table_t *bdf_table_ptr = pcie_get_bdf_table();
 	uint32_t num_bdf = bdf_table_ptr->num_entries;
+	pcie_dev_t *dev;
 
 	INFO("PCI BDF table entries: %u\n", num_bdf);
 
@@ -257,15 +260,13 @@
 	INFO("PCI BDF table 0x%lx\n", (uintptr_t)bdf_table_ptr);
 
 	while (num_bdf-- != 0) {
-		uint32_t bdf = bdf_table_ptr->device[num_bdf].bdf;
-		uint32_t status, doe_cap_base;
+		dev = &bdf_table_ptr->device[num_bdf];
 
-		/* Check for DOE capability */
-		status = pcie_find_capability(bdf, PCIE_ECAP, DOE_CAP_ID, &doe_cap_base);
-		if (status == PCIE_SUCCESS) {
-			INFO("PCIe DOE capability: bdf 0x%x cap_base 0x%x\n", bdf, doe_cap_base);
-			*bdf_ptr = bdf;
-			*cap_base_ptr = doe_cap_base;
+		if ((dev->dp_type == EP) && (pcie_dev_has_doe(dev))) {
+			INFO("PCIe DOE capability: bdf 0x%x cap_base 0x%x\n",
+			     dev->bdf, dev->doe_cap_base);
+			*bdf_ptr = dev->bdf;
+			*cap_base_ptr = dev->doe_cap_base;
 			return 0;
 		}
 	}
diff --git a/lib/pcie/pcie_dvsec_rmeda.c b/lib/pcie/pcie_dvsec_rmeda.c
new file mode 100644
index 0000000..c1da99a
--- /dev/null
+++ b/lib/pcie/pcie_dvsec_rmeda.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2025, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <common_def.h>
+#include <errno.h>
+#include <stddef.h>
+#include <debug.h>
+#include <mmio.h>
+#include <pcie.h>
+#include <pcie_spec.h>
+#include <pcie_dvsec_rmeda.h>
+#include <platform.h>
+#include <tftf_lib.h>
+
+/*
+ * Check if the DVSEC header matches RME Sys Arch spec
+ *
+ * DVSEC_REVISION must be 0
+ * DVSEC_VENDOR_ID must be Arm
+ * DVSEC_ID must be RME_DA
+ */
+static bool is_dvsec_arm_rmeda(uint32_t rp_bdf, uint32_t dvsec_base)
+{
+	uint32_t hdr1 = 0U;
+	uint32_t hdr2 = 0U;
+
+	hdr1 = pcie_read_cfg(rp_bdf, dvsec_base + PCIE_ECAP_DVSEC_HDR1_OFFSET);
+	hdr2 = pcie_read_cfg(rp_bdf, dvsec_base + PCIE_ECAP_DVSEC_HDR2_OFFSET);
+
+	if ((EXTRACT(DVSEC_HDR1_VENDOR_ID, hdr1) == DVSEC_VENDOR_ID_ARM) &&
+	    (EXTRACT(DVSEC_HDR1_REVISION, hdr1) == DVSEC_REVISION_0) &&
+	    (EXTRACT(DVSEC_HDR2_DVSEC_ID, hdr2) == DVSEC_ID_RME_DA)) {
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * Traverse all DVSEC extended capability and return the first RMEDA DVSEC if the
+ * header, revision are expected as mentioned in RME System Architecture.
+ */
+uint32_t pcie_find_rmeda_capability(uint32_t rp_bdf, uint32_t *cid_offset)
+{
+	uint32_t ech;
+	unsigned int dvsec_offset;
+	uint16_t next_cap_offset;
+
+	dvsec_offset = PCIE_ECAP_START;
+	do {
+		assert((dvsec_offset + sizeof(ech)) < SZ_4K);
+
+		ech = pcie_read_cfg(rp_bdf, dvsec_offset);
+
+		/* Check for PCIE_ECH_CAP_VER_1 as well? */
+		if ((EXTRACT(PCIE_ECH_ID, ech) == ECID_DVSEC) &&
+		    is_dvsec_arm_rmeda(rp_bdf, dvsec_offset)) {
+			*cid_offset = dvsec_offset;
+			return PCIE_SUCCESS;
+		}
+
+		next_cap_offset = EXTRACT(PCIE_ECH_NEXT_CAP_OFFSET, ech);
+		dvsec_offset += next_cap_offset;
+	} while ((next_cap_offset != 0U) && (dvsec_offset < PCIE_ECAP_END));
+
+	return PCIE_CAP_NOT_FOUND;
+}
diff --git a/plat/arm/fvp/fvp_pcie.c b/plat/arm/fvp/fvp_pcie.c
index 38bdf39..4bba516 100644
--- a/plat/arm/fvp/fvp_pcie.c
+++ b/plat/arm/fvp/fvp_pcie.c
@@ -27,6 +27,28 @@
 	return &fvp_pcie_cfg;
 }
 
+/* Retrieve platform PCIe bar config values */
+int plat_pcie_get_bar_config(uint64_t *bar64_val, uint64_t *rp_bar64_val,
+			     uint32_t *bar32np_val, uint32_t *bar32p_val,
+			     uint32_t *rp_bar32_val)
+{
+#ifdef __aarch64__
+	assert((bar64_val != NULL) && (rp_bar64_val != NULL) &&
+	       (bar32np_val != NULL) && (bar32p_val != NULL) &&
+	       (rp_bar32_val != NULL));
+
+	*bar64_val = PLATFORM_OVERRIDE_PCIE_BAR64_VALUE;
+	*rp_bar64_val = PLATFORM_OVERRIDE_RP_BAR64_VALUE;
+
+	*bar32np_val = PLATFORM_OVERRIDE_PCIE_BAR32NP_VALUE;
+	*bar32p_val = PLATFORM_OVERRIDE_PCIE_BAR32P_VALUE;
+	*rp_bar32_val = PLATOFRM_OVERRIDE_RP_BAR32_VALUE;
+
+	return 0;
+#endif
+	return -1;
+}
+
 /*
  * Retrieve platform PCIe memory region (Base Platform RevC only)
  */
diff --git a/plat/arm/fvp/include/platform_pcie.h b/plat/arm/fvp/include/platform_pcie.h
index 4b3a0e9..4a2817e 100644
--- a/plat/arm/fvp/include/platform_pcie.h
+++ b/plat/arm/fvp/include/platform_pcie.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024, Arm Limited. All rights reserved.
+ * Copyright (c) 2024-2025, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,4 +19,11 @@
 #define PLATFORM_PCIE_START_BUS_NUM_0	0x0
 #define PLATFORM_PCIE_END_BUS_NUM_0	0xFF
 
+/* PCIe BAR config parameters*/
+#define PLATFORM_OVERRIDE_PCIE_BAR64_VALUE	0x4000100000
+#define PLATFORM_OVERRIDE_RP_BAR64_VALUE	0x4000000000
+#define PLATFORM_OVERRIDE_PCIE_BAR32NP_VALUE	0x50000000
+#define PLATFORM_OVERRIDE_PCIE_BAR32P_VALUE	0x50600000
+#define PLATOFRM_OVERRIDE_RP_BAR32_VALUE	0x50850000
+
 #endif	/* PLATFORM_PCIE_H */
diff --git a/plat/common/plat_common.c b/plat/common/plat_common.c
index c06ad13..f8524cf 100644
--- a/plat/common/plat_common.c
+++ b/plat/common/plat_common.c
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
  *
@@ -25,6 +26,7 @@
 #pragma weak tftf_plat_reset
 #pragma weak plat_get_prot_regions
 #pragma weak plat_pcie_get_info_table
+#pragma weak plat_pcie_get_bar_config
 #pragma weak plat_get_invalid_addr
 #pragma weak plat_get_dev_region
 
@@ -157,6 +159,13 @@
 	return NULL;
 }
 
+int plat_pcie_get_bar_config(uint64_t *bar64_val, uint64_t *rp_bar64_val,
+			     uint32_t *bar32np_val, uint32_t *bar32p_val,
+			     uint32_t *rp_bar32_val)
+{
+	return -1;
+}
+
 uintptr_t plat_get_invalid_addr(void)
 {
 	return (uintptr_t)0x0;
diff --git a/realm/realm_da.c b/realm/realm_da.c
index c442b21..a0e812c 100644
--- a/realm/realm_da.c
+++ b/realm/realm_da.c
@@ -62,6 +62,11 @@
 		return false;
 	}
 
+	realm_printf("======================================\n");
+	realm_printf("Realm: Lock -> Accept -> Unlock device: (bdf: 0x%x)\n",
+		     rdev->id);
+	realm_printf("======================================\n");
+
 	rsi_rc = realm_rsi_rdev_get_state(rdev);
 	if (rsi_rc != RSI_SUCCESS) {
 		return false;
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_da_helper.c b/tftf/tests/runtime_services/host_realm_managment/host_da_helper.c
index 8bcf370..c9a82c2 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_da_helper.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_da_helper.c
@@ -6,16 +6,17 @@
  */
 
 #include <stdint.h>
-
 #include <arch_features.h>
 #include <debug.h>
 #include <heap/page_alloc.h>
 #include <host_da_helper.h>
 #include <host_realm_helper.h>
 #include <host_realm_mem_layout.h>
+#include <pcie_spec.h>
 #include <pcie_doe.h>
 
-extern struct host_pdev gbl_host_pdev;
+extern int gbl_host_pdev_count;
+extern struct host_pdev gbl_host_pdevs[32];
 extern struct host_vdev gbl_host_vdev;
 
 static const char * const pdev_state_str[] = {
@@ -28,7 +29,7 @@
 	"RMI_PDEV_STATE_ERROR"
 };
 
-struct host_vdev *find_host_vdev_from_id(unsigned long vdev_id)
+static struct host_vdev *find_host_vdev_from_id(unsigned long vdev_id)
 {
 	struct host_vdev *h_vdev = &gbl_host_vdev;
 
@@ -39,18 +40,23 @@
 	return NULL;
 }
 
-struct host_pdev *find_host_pdev_from_pdev_ptr(unsigned long pdev_ptr)
+static struct host_pdev *find_host_pdev_from_pdev_ptr(unsigned long pdev_ptr)
 {
-	struct host_pdev *h_pdev = &gbl_host_pdev;
+	uint32_t i;
+	struct host_pdev *h_pdev;
 
-	if (h_pdev->pdev == (void *)pdev_ptr) {
-		return h_pdev;
+	for (i = 0; i < gbl_host_pdev_count; i++) {
+		h_pdev = &gbl_host_pdevs[i];
+
+		if (h_pdev->pdev == (void *)pdev_ptr) {
+			return h_pdev;
+		}
 	}
 
 	return NULL;
 }
 
-struct host_vdev *find_host_vdev_from_vdev_ptr(unsigned long vdev_ptr)
+static struct host_vdev *find_host_vdev_from_vdev_ptr(unsigned long vdev_ptr)
 {
 	struct host_vdev *h_vdev = &gbl_host_vdev;
 
@@ -122,9 +128,11 @@
 
 	pdev_params->flags = h_pdev->pdev_flags;
 	pdev_params->cert_id = h_pdev->cert_slot_id;
-	pdev_params->pdev_id = h_pdev->bdf;
+	pdev_params->pdev_id = h_pdev->dev->bdf;
 	pdev_params->num_aux = h_pdev->pdev_aux_num;
 	pdev_params->hash_algo = h_pdev->pdev_hash_algo;
+	pdev_params->root_id = h_pdev->dev->rp_dev->bdf;
+	pdev_params->ecam_addr = h_pdev->dev->ecam_base;
 	for (i = 0; i < h_pdev->pdev_aux_num; i++) {
 		pdev_params->aux[i] = (uintptr_t)h_pdev->pdev_aux[i];
 	}
@@ -340,7 +348,8 @@
 	}
 
 	resp_len = 0UL;
-	rc = pcie_doe_communicate(doe_header, h_pdev->bdf, h_pdev->doe_cap_base,
+	rc = pcie_doe_communicate(doe_header, h_pdev->dev->bdf,
+				  h_pdev->dev->doe_cap_base,
 				  (void *)dcomm_enter->req_addr,
 				  dcomm_exit->req_len,
 				  (void *)dcomm_enter->resp_addr, &resp_len);
@@ -493,7 +502,10 @@
 	u_register_t ret, count;
 	int i;
 
-	memset(h_pdev, 0, sizeof(struct host_pdev));
+	/* RCiEP devices not supported by RMM */
+	if (h_pdev->dev->dp_type == RCiEP) {
+		return -1;
+	}
 
 	/* Allocate granule for PDEV and delegate */
 	h_pdev->pdev = page_alloc(PAGE_SIZE);
@@ -512,10 +524,20 @@
 	 * Off chip PCIe device - set flags as non coherent device protected by
 	 * end to end IDE, with SPDM.
 	 */
-	h_pdev->pdev_flags = (INPLACE(RMI_PDEV_FLAGS_SPDM, RMI_PDEV_SPDM_TRUE) |
-			   INPLACE(RMI_PDEV_FLAGS_IDE, RMI_PDEV_IDE_TRUE) |
-			   INPLACE(RMI_PDEV_FLAGS_COHERENT,
-				   RMI_PDEV_COHERENT_FALSE));
+	h_pdev->pdev_flags = 0;
+
+	/* Set IDE based on device capability */
+	if (pcie_dev_has_ide(h_pdev->dev)) {
+		h_pdev->pdev_flags |= INPLACE(RMI_PDEV_FLAGS_IDE,
+					      RMI_PDEV_IDE_TRUE);
+	}
+
+	/* Supports SPDM */
+	h_pdev->pdev_flags |= INPLACE(RMI_PDEV_FLAGS_SPDM, RMI_PDEV_SPDM_TRUE);
+
+	/* Not a coherent device */
+	h_pdev->pdev_flags |= INPLACE(RMI_PDEV_FLAGS_COHERENT,
+				      RMI_PDEV_COHERENT_FALSE);
 
 	/* Get num of aux granules required for this PDEV */
 	ret = host_rmi_pdev_aux_count(h_pdev->pdev_flags, &count);
@@ -606,7 +628,6 @@
 	return -1;
 }
 
-
 /*
  * Stop PDEV and ternimate secure session and call PDEV destroy
  */
@@ -642,10 +663,13 @@
 			ERROR("Aux granule undelegate failed 0x%lx\n", ret);
 			result = -1;
 		}
+
+		h_pdev->pdev_aux[i] = NULL;
 	}
 
 	/* Undelegate PDEV granule */
 	ret = host_rmi_granule_undelegate((u_register_t)h_pdev->pdev);
+	h_pdev->pdev = NULL;
 	if (ret != RMI_SUCCESS) {
 		ERROR("PDEV undelegate failed 0x%lx\n", ret);
 		result = -1;
@@ -683,7 +707,8 @@
  * response buffer, VDEV AUX granules and memory required to device
  * measurements, interface report.
  */
-static int host_vdev_setup(struct host_pdev *h_pdev, struct host_vdev *h_vdev)
+static int host_vdev_setup(struct host_vdev *h_vdev, unsigned long tdi_id,
+			   void *pdev_ptr)
 {
 	u_register_t ret;
 
@@ -694,9 +719,9 @@
 	 * the VMM view of vdev_id and Realm view of device_id must match.
 	 */
 	h_vdev->vdev_id = 0UL;
-	h_vdev->tdi_id = h_pdev->bdf;
+	h_vdev->tdi_id = tdi_id;
 	h_vdev->flags = 0UL;
-	h_vdev->pdev_ptr = h_pdev->pdev;
+	h_vdev->pdev_ptr = pdev_ptr;
 
 	/* Allocate granule for VDEV and delegate */
 	h_vdev->vdev_ptr = (void *)page_alloc(PAGE_SIZE);
@@ -751,15 +776,14 @@
 	return -1;
 }
 
-int host_assign_vdev_to_realm(struct realm *realm,
-				struct host_pdev *h_pdev,
-				struct host_vdev *h_vdev)
+int host_assign_vdev_to_realm(struct realm *realm, struct host_vdev *h_vdev,
+			      unsigned long tdi_id, void *pdev_ptr)
 {
 	struct rmi_vdev_params *vdev_params;
 	u_register_t ret;
 	int rc;
 
-	rc = host_vdev_setup(h_pdev, h_vdev);
+	rc = host_vdev_setup(h_vdev, tdi_id, pdev_ptr);
 	if (rc != 0) {
 		return rc;
 	}
@@ -778,12 +802,12 @@
 	 * This is TDI id, this must be same as PDEV ID for assigning the whole
 	 * device.
 	 */
-	vdev_params->tdi_id = h_pdev->bdf;
+	vdev_params->tdi_id = tdi_id;
 
 	vdev_params->flags = h_vdev->flags;
 	vdev_params->num_aux = 0UL;
 
-	ret = host_rmi_vdev_create(realm->rd, (u_register_t)h_pdev->pdev,
+	ret = host_rmi_vdev_create(realm->rd, (u_register_t)pdev_ptr,
 				  (u_register_t)h_vdev->vdev_ptr,
 				  (u_register_t)vdev_params);
 	if (ret != RMI_SUCCESS) {
@@ -794,10 +818,9 @@
 	return 0;
 }
 
-int host_unassign_vdev_from_realm(struct realm *realm,
-				  struct host_pdev *h_pdev,
-				  struct host_vdev *h_vdev)
+int host_unassign_vdev_from_realm(struct realm *realm, struct host_vdev *h_vdev)
 {
+	struct host_pdev *h_pdev;
 	u_register_t ret, state;
 	int rc;
 
@@ -818,6 +841,9 @@
 		return -1;
 	}
 
+	h_pdev = find_host_pdev_from_pdev_ptr((unsigned long)h_vdev->pdev_ptr);
+	assert(h_pdev);
+
 	/* Do VDEV communicate to move VDEV from STOPPING to STOPPED state */
 	rc = host_dev_communicate(h_pdev, h_vdev, RMI_VDEV_STATE_STOPPED);
 	if (rc != 0) {
@@ -825,14 +851,15 @@
 		return rc;
 	}
 
-	ret = host_rmi_vdev_destroy(realm->rd, (u_register_t)h_pdev->pdev,
-				   (u_register_t)h_vdev->vdev_ptr);
+	ret = host_rmi_vdev_destroy(realm->rd,
+				    (u_register_t)h_vdev->pdev_ptr,
+				    (u_register_t)h_vdev->vdev_ptr);
 	if (ret != RMI_SUCCESS) {
 		ERROR("VDEV destroy failed\n");
 		return -1;
 	}
 
-	ret = host_rmi_granule_undelegate((u_register_t)(u_register_t)h_vdev->vdev_ptr);
+	ret = host_rmi_granule_undelegate((u_register_t)h_vdev->vdev_ptr);
 	if (ret != RMI_SUCCESS) {
 		ERROR("VDEV undelegate failed\n");
 		return -1;
@@ -921,3 +948,83 @@
 	*dev_ipa = map_addr;
 	return REALM_SUCCESS;
 }
+
+bool is_host_pdev_independently_attested(struct host_pdev *h_pdev)
+{
+	assert(h_pdev);
+	assert(h_pdev->dev);
+
+	if ((pcie_dev_has_doe(h_pdev->dev)) &&
+	    (pcie_dev_has_ide(h_pdev->dev)) &&
+	    (h_pdev->dev->rp_dev != NULL) &&
+	    (pcie_dev_has_ide(h_pdev->dev->rp_dev)) &&
+	    (pcie_dev_has_dvsec_rmeda(h_pdev->dev->rp_dev))) {
+		return true;
+	}
+
+	return false;
+}
+
+/*
+ * Find all PCIe off-chip devices that confimrs to TEE-IO standards
+ * Devices that supports DOE, IDE, TDISP with RootPort that supports
+ * RME DA are initlized in host_pdevs[]
+ */
+void host_pdevs_init(void)
+{
+	static bool gbl_host_pdevs_init_done;
+	pcie_device_bdf_table_t *bdf_table;
+	pcie_dev_t *dev;
+	uint32_t i;
+	uint32_t cnt = 0;
+
+	if (gbl_host_pdevs_init_done) {
+		return;
+	}
+
+	/* When called for the first time this does PCIe enumeration */
+	pcie_init();
+
+	INFO("Initializing host_pdevs\n");
+	bdf_table = pcie_get_bdf_table();
+	if ((bdf_table == NULL) || (bdf_table->num_entries == 0)) {
+		goto out_init;
+	}
+
+	for (i = 0; i < bdf_table->num_entries; i++) {
+		dev = &bdf_table->device[i];
+
+		if ((dev->dp_type != EP) && (dev->dp_type != RCiEP)) {
+			continue;
+		}
+
+		if ((dev->dp_type == EP) && (dev->rp_dev == NULL)) {
+			INFO("No RP found for Device %x:%x.%x\n",
+			     PCIE_EXTRACT_BDF_BUS(dev->bdf),
+			     PCIE_EXTRACT_BDF_DEV(dev->bdf),
+			     PCIE_EXTRACT_BDF_FUNC(dev->bdf));
+			continue;
+		}
+
+		/*
+		 * Skip VF in multi function device as it can't be treated as
+		 * PDEV
+		 */
+		if (PCIE_EXTRACT_BDF_FUNC(dev->bdf) != 0) {
+			continue;
+		}
+
+		/* Initialize host_pdev */
+		gbl_host_pdevs[cnt].dev = dev;
+		cnt++;
+
+		if (cnt == HOST_PDEV_MAX) {
+			WARN("Max host_pdev count reached.\n");
+			break;
+		}
+	}
+
+out_init:
+	gbl_host_pdevs_init_done = true;
+	gbl_host_pdev_count = cnt;
+}
diff --git a/tftf/tests/runtime_services/host_realm_managment/host_rmi_da_flow.c b/tftf/tests/runtime_services/host_realm_managment/host_rmi_da_flow.c
index f110e10..5b41e55 100644
--- a/tftf/tests/runtime_services/host_realm_managment/host_rmi_da_flow.c
+++ b/tftf/tests/runtime_services/host_realm_managment/host_rmi_da_flow.c
@@ -20,9 +20,34 @@
 #include <spdm.h>
 #include <test_helpers.h>
 
-struct host_pdev gbl_host_pdev;
+int gbl_host_pdev_count;
+struct host_pdev gbl_host_pdevs[HOST_PDEV_MAX];
 struct host_vdev gbl_host_vdev;
 
+static test_result_t tsm_disconnect_device(struct host_pdev *h_pdev)
+{
+	int rc;
+
+	assert(h_pdev->is_connected_to_tsm);
+
+	INFO("===========================================\n");
+	INFO("Host: TSM disconnect device: (0x%x) %x:%x.%x\n",
+	     h_pdev->dev->bdf,
+	     PCIE_EXTRACT_BDF_BUS(h_pdev->dev->bdf),
+	     PCIE_EXTRACT_BDF_DEV(h_pdev->dev->bdf),
+	     PCIE_EXTRACT_BDF_FUNC(h_pdev->dev->bdf));
+	INFO("===========================================\n");
+
+	rc = host_pdev_reclaim(h_pdev);
+	if (rc != 0) {
+		return TEST_RESULT_FAIL;
+	}
+
+	h_pdev->is_connected_to_tsm = false;
+
+	return TEST_RESULT_SUCCESS;
+}
+
 /*
  * This invokes various RMI calls related to PDEV, VDEV management that does
  * PDEV create/communicate/set_key/abort/stop/destroy and assigns the device
@@ -31,58 +56,27 @@
  * 1. Create a Realm with DA feature enabled
  * 2. Find a known PCIe endpoint and connect with TSM to get_cert and establish
  *    secure session
- * 3. Assign the PCIe endpoint (a PF) to the Realm
- * 4. Call Realm to do DA related RSI calls
- * 5. Unassign the PCIe endpoint from the Realm
- * 6. Delete the Realm
- * 7. Reclaim the PCIe TDI from TSM
  */
-test_result_t host_invoke_rmi_da_flow(void)
+static test_result_t tsm_connect_device(struct host_pdev *h_pdev)
 {
-	u_register_t rmi_feat_reg0;
-	uint32_t pdev_bdf, doe_cap_base;
-	struct host_pdev *h_pdev;
-	struct host_vdev *h_vdev;
-	uint8_t public_key_algo;
 	int rc;
-	bool realm_rc;
-	struct realm realm;
-	test_result_t result = TEST_RESULT_FAIL;
+	uint8_t public_key_algo;
 
-	CHECK_DA_SUPPORT_IN_RMI(rmi_feat_reg0);
-	SKIP_TEST_IF_DOE_NOT_SUPPORTED(pdev_bdf, doe_cap_base);
-
-	INFO("DA on bdf: 0x%x, doe_cap_base: 0x%x\n", pdev_bdf, doe_cap_base);
-
-	/*
-	 * Create a Realm with DA feature enabled
-	 *
-	 * todo: creating this after host_pdev_setup causes Realm create to
-	 * fail.
-	 */
-	rc = host_create_realm_with_feat_da(&realm);
-	if (rc != 0) {
-		INFO("Realm create with feat_da failed\n");
-		return TEST_RESULT_FAIL;
-	}
-
-	INFO("Realm created with feat_da enabled\n");
-
-	h_pdev = &gbl_host_pdev;
-	h_vdev = &gbl_host_vdev;
+	INFO("======================================\n");
+	INFO("Host: TSM connect device: (0x%x) %x:%x.%x\n",
+	     h_pdev->dev->bdf,
+	     PCIE_EXTRACT_BDF_BUS(h_pdev->dev->bdf),
+	     PCIE_EXTRACT_BDF_DEV(h_pdev->dev->bdf),
+	     PCIE_EXTRACT_BDF_FUNC(h_pdev->dev->bdf));
+	INFO("======================================\n");
 
 	/* Allocate granules. Skip DA ABIs if host_pdev_setup fails */
 	rc = host_pdev_setup(h_pdev);
 	if (rc == -1) {
-		INFO("host_pdev_setup failed.\n");
-		(void)host_destroy_realm(&realm);
+		ERROR("host_pdev_setup failed.\n");
 		return TEST_RESULT_FAIL;
 	}
 
-	/* todo: move to tdi_pdev_setup */
-	h_pdev->bdf = pdev_bdf;
-	h_pdev->doe_cap_base = doe_cap_base;
-
 	/* Call rmi_pdev_create to transition PDEV to STATE_NEW */
 	rc = host_pdev_transition(h_pdev, RMI_PDEV_STATE_NEW);
 	if (rc != 0) {
@@ -123,71 +117,223 @@
 	/* Call rmi_pdev_set_key transition PDEV to HAS_KEY */
 	rc = host_pdev_transition(h_pdev, RMI_PDEV_STATE_HAS_KEY);
 	if (rc != 0) {
-		INFO("PDEV transition: PDEV_NEEDS_KEY -> PDEV_HAS_KEY failed\n");
+		ERROR("PDEV transition: PDEV_NEEDS_KEY -> PDEV_HAS_KEY failed\n");
 		goto err_pdev_reclaim;
 	}
 
 	/* Call rmi_pdev_comminucate to transition PDEV to READY state */
 	rc = host_pdev_transition(h_pdev, RMI_PDEV_STATE_READY);
 	if (rc != 0) {
-		INFO("PDEV transition: PDEV_HAS_KEY -> PDEV_READY failed\n");
+		ERROR("PDEV transition: PDEV_HAS_KEY -> PDEV_READY failed\n");
 		goto err_pdev_reclaim;
 	}
 
-
-	/*
-	 * 3 Assign VDEV (the PCIe endpoint) from the Realm
-	 */
-	rc = host_assign_vdev_to_realm(&realm, h_pdev, h_vdev);
-	if (rc != 0) {
-		INFO("VDEV assign to realm failed\n");
-		/* TF-RMM has support till here. Change error code temporarily */
-		result = TEST_RESULT_SUCCESS;
-		goto err_pdev_reclaim;
-	}
-
-	/*
-	 * 4 Call Realm to do DA related RSI calls
-	 */
-	realm_rc = host_enter_realm_execute(&realm, REALM_DA_RSI_CALLS,
-					    RMI_EXIT_HOST_CALL, 0U);
-	if (!realm_rc) {
-		INFO("Realm DA_RSI_CALLS failed\n");
-		goto err_pdev_reclaim;
-	}
-
-	/*
-	 * 5 Unassign VDEV (the PCIe endpoint) from the Realm
-	 */
-	rc = host_unassign_vdev_from_realm(&realm, h_pdev, h_vdev);
-	if (rc != 0) {
-		INFO("VDEV unassign to realm failed\n");
-		goto err_pdev_reclaim;
-	}
-
-	/*
-	 * 6 Destroy the Realm
-	 */
-	if (!host_destroy_realm(&realm)) {
-		INFO("Realm destroy failed\n");
-		(void)host_pdev_reclaim(h_pdev);
-		return TEST_RESULT_FAIL;
-	}
-
-	/*
-	 * 7 Reclaim PDEV (the PCIe TDI) from TSM
-	 */
-	rc = host_pdev_reclaim(h_pdev);
-	if (rc != 0) {
-		INFO("Reclaim PDEV from TSM failed\n");
-		return TEST_RESULT_FAIL;
-	}
+	h_pdev->is_connected_to_tsm = true;
 
 	return TEST_RESULT_SUCCESS;
 
 err_pdev_reclaim:
-	(void)host_destroy_realm(&realm);
 	(void)host_pdev_reclaim(h_pdev);
+
+	return TEST_RESULT_FAIL;
+}
+
+/* Iterate thorough all host_pdevs and try to connect to TSM */
+static test_result_t tsm_connect_devices(void)
+{
+	uint32_t i;
+	int count = 0;
+	struct host_pdev *h_pdev;
+	test_result_t result = TEST_RESULT_SKIPPED;
+
+	for (i = 0; i < gbl_host_pdev_count; i++) {
+		h_pdev = &gbl_host_pdevs[i];
+
+		if (!is_host_pdev_independently_attested(h_pdev)) {
+			continue;
+		}
+
+		result = tsm_connect_device(h_pdev);
+		if (result != TEST_RESULT_SUCCESS) {
+			ERROR("tsm_connect_device: 0x%x failed\n",
+			     h_pdev->dev->bdf);
+			break;
+		}
+
+		count++;
+	}
+
+	if (count != 0U) {
+		INFO("%d devices connected to TSM\n", count);
+	} else {
+		INFO("No device connected to TSM\n");
+	}
+
+	return result;
+}
+
+/* Iterate thorough all connected host_pdevs and disconnect from TSM */
+static test_result_t tsm_disconnect_devices(void)
+{
+	uint32_t i;
+	struct host_pdev *h_pdev;
+	test_result_t rc;
+	bool return_error = false;
+
+	for (i = 0; i < gbl_host_pdev_count; i++) {
+		h_pdev = &gbl_host_pdevs[i];
+
+		if (h_pdev->is_connected_to_tsm) {
+			rc = tsm_disconnect_device(h_pdev);
+			if (rc != TEST_RESULT_SUCCESS) {
+				/* Set error, continue with other devices */
+				return_error = true;
+			}
+		}
+	}
+
+	if (return_error) {
+		return TEST_RESULT_FAIL;
+	}
+
+	return TEST_RESULT_SUCCESS;
+}
+
+static test_result_t realm_assign_unassign_device(struct realm *realm_ptr,
+						struct host_vdev *h_vdev,
+						unsigned long tdi_id,
+						void *pdev_ptr)
+{
+	int rc;
+	bool realm_rc;
+
+	/* Assign VDEV */
+	INFO("======================================\n");
+	INFO("Host: Assign device: (0x%x) %x:%x.%x to Realm \n",
+	     (uint32_t)tdi_id,
+	     PCIE_EXTRACT_BDF_BUS((uint32_t)tdi_id),
+	     PCIE_EXTRACT_BDF_DEV((uint32_t)tdi_id),
+	     PCIE_EXTRACT_BDF_FUNC((uint32_t)tdi_id));
+	INFO("======================================\n");
+
+	rc = host_assign_vdev_to_realm(realm_ptr, h_vdev, tdi_id, pdev_ptr);
+	if (rc != 0) {
+		ERROR("VDEV assign to realm failed\n");
+		/* TF-RMM has support till here. Change error code temporarily */
+		return TEST_RESULT_SUCCESS;
+		/* return TEST_RESULT_FAIL */
+	}
+
+	/* Enter Realm. Lock -> Accept -> Unlock the assigned device */
+	realm_rc = host_enter_realm_execute(realm_ptr, REALM_DA_RSI_CALLS,
+					    RMI_EXIT_HOST_CALL, 0U);
+
+	/* Unassign VDEV */
+	INFO("======================================\n");
+	INFO("Host: Unassign device: (0x%x) %x:%x.%x from Realm \n",
+	     (uint32_t)tdi_id,
+	     PCIE_EXTRACT_BDF_BUS((uint32_t)tdi_id),
+	     PCIE_EXTRACT_BDF_DEV((uint32_t)tdi_id),
+	     PCIE_EXTRACT_BDF_FUNC((uint32_t)tdi_id));
+	INFO("======================================\n");
+
+	rc = host_unassign_vdev_from_realm(realm_ptr, h_vdev);
+	if (rc != 0) {
+		ERROR("VDEV unassign to realm failed\n");
+		return TEST_RESULT_FAIL;
+	}
+
+	if (!realm_rc) {
+		ERROR("Realm DA_RSI_CALLS failed\n");
+		return TEST_RESULT_FAIL;
+	}
+
+	return TEST_RESULT_SUCCESS;
+}
+
+static test_result_t
+realm_assign_unassign_devices(struct realm *realm_ptr)
+{
+	uint32_t i;
+	test_result_t rc;
+	struct host_pdev *h_pdev;
+	struct host_vdev *h_vdev;
+
+	for (i = 0; i < gbl_host_pdev_count; i++) {
+		h_pdev = &gbl_host_pdevs[i];
+
+		if (h_pdev->is_connected_to_tsm) {
+			h_vdev = &gbl_host_vdev;
+
+			rc = realm_assign_unassign_device(realm_ptr, h_vdev,
+							  h_pdev->dev->bdf,
+							  h_pdev->pdev);
+			if (rc != TEST_RESULT_SUCCESS) {
+				break;
+			}
+		}
+	}
+
+	return rc;
+}
+
+/*
+ * Iterate thorugh all host_pdevs and do
+ * TSM connect
+ * TSM disconnect
+ */
+test_result_t host_da_workflow_on_all_offchip_devices(void)
+{
+	int rc;
+	struct realm realm;
+	test_result_t result;
+	bool return_error = false;
+	u_register_t rmi_feat_reg0;
+
+	SKIP_DA_TEST_IF_PREREQS_NOT_MET(rmi_feat_reg0);
+	host_pdevs_init();
+
+	/*
+	 * Create a Realm with DA feature enabled
+	 *
+	 * todo: creating this after host_pdev_setup causes Realm create to
+	 * fail.
+	 */
+	rc = host_create_realm_with_feat_da(&realm);
+	if (rc != 0) {
+		ERROR("Realm create with feat_da failed\n");
+		return TEST_RESULT_FAIL;
+	}
+
+	/* Connect all devices with TSM */
+	result = tsm_connect_devices();
+	if (result == TEST_RESULT_SKIPPED) {
+		goto out_rm_realm;
+	} else if (result != TEST_RESULT_SUCCESS) {
+		return_error = true;
+	}
+
+	/* Assign all TSM connected devices to a Realm */
+	result = realm_assign_unassign_devices(&realm);
+	if (result != TEST_RESULT_SUCCESS) {
+		return_error = true;
+	}
+
+	result = tsm_disconnect_devices();
+	if (result != TEST_RESULT_SUCCESS) {
+		return_error = true;
+	}
+
+out_rm_realm:
+	/* Destroy the Realm */
+	if (!host_destroy_realm(&realm)) {
+		return_error = true;
+	}
+
+	if (return_error) {
+		result = TEST_RESULT_FAIL;
+	}
+
 	return result;
 }
 
@@ -205,6 +351,8 @@
 		return TEST_RESULT_SKIPPED;
 	}
 
+	host_pdevs_init();
+
 	/* Initialize Host NS heap memory */
 	ret = page_pool_init((u_register_t)PAGE_POOL_BASE,
 				(u_register_t)PAGE_POOL_MAX_SIZE);
@@ -213,7 +361,7 @@
 		return TEST_RESULT_FAIL;
 	}
 
-	h_pdev = &gbl_host_pdev;
+	h_pdev = &gbl_host_pdevs[0];
 
 	/*
 	 * Call rmi_pdev_create with invalid pdev, expect an error
diff --git a/tftf/tests/runtime_services/host_realm_managment/rmi_dev_delegate_tests.c b/tftf/tests/runtime_services/host_realm_managment/rmi_dev_delegate_tests.c
index 554029c..ae81946 100644
--- a/tftf/tests/runtime_services/host_realm_managment/rmi_dev_delegate_tests.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_dev_delegate_tests.c
@@ -8,10 +8,10 @@
 
 #include <arch_features.h>
 #include <common_def.h>
+#include <host_da_helper.h>
 #include <host_realm_helper.h>
 #include <host_realm_mem_layout.h>
 #include <host_shared_data.h>
-#include <pcie_doe.h>
 #include <plat_topology.h>
 #include <platform.h>
 #include <power_management.h>
@@ -90,7 +90,7 @@
 	u_register_t rmi_feat_reg0;
 	unsigned int num_reg = 0U;
 
-	CHECK_DA_SUPPORT_IN_RMI(rmi_feat_reg0);
+	SKIP_DA_TEST_IF_PREREQS_NOT_MET(rmi_feat_reg0);
 
 	host_rmi_init_cmp_result();
 
@@ -147,7 +147,7 @@
 	u_register_t rmi_feat_reg0, lead_mpid;
 	unsigned int num_reg = 0U;
 
-	CHECK_DA_SUPPORT_IN_RMI(rmi_feat_reg0);
+	SKIP_DA_TEST_IF_PREREQS_NOT_MET(rmi_feat_reg0);
 
 	lead_mpid = read_mpidr_el1() & MPID_MASK;
 
@@ -275,7 +275,7 @@
 	u_register_t rmi_feat_reg0;
 	unsigned int num_reg = 0U;
 
-	CHECK_DA_SUPPORT_IN_RMI(rmi_feat_reg0);
+	SKIP_DA_TEST_IF_PREREQS_NOT_MET(rmi_feat_reg0);
 
 	host_rmi_init_cmp_result();
 
diff --git a/tftf/tests/runtime_services/host_realm_managment/rmi_dev_mem_map_tests.c b/tftf/tests/runtime_services/host_realm_managment/rmi_dev_mem_map_tests.c
index f55a1c9..1a28d4f 100644
--- a/tftf/tests/runtime_services/host_realm_managment/rmi_dev_mem_map_tests.c
+++ b/tftf/tests/runtime_services/host_realm_managment/rmi_dev_mem_map_tests.c
@@ -12,7 +12,6 @@
 #include <host_realm_helper.h>
 #include <host_realm_mem_layout.h>
 #include <host_shared_data.h>
-#include <pcie_doe.h>
 #include <plat_topology.h>
 #include <platform.h>
 #include <test_helpers.h>
@@ -77,7 +76,7 @@
 	unsigned int num[NUM_INFO_TESTS];
 	unsigned int num_reg, offset, i, j;
 
-	CHECK_DA_SUPPORT_IN_RMI(rmi_features);
+	SKIP_DA_TEST_IF_PREREQS_NOT_MET(rmi_features);
 
 	/* Initialise memory test structures */
 
diff --git a/tftf/tests/tests-realm-payload.mk b/tftf/tests/tests-realm-payload.mk
index add6a7f..5859d31 100644
--- a/tftf/tests/tests-realm-payload.mk
+++ b/tftf/tests/tests-realm-payload.mk
@@ -62,6 +62,7 @@
 	$(addprefix lib/pcie/,	\
 		pcie.c		\
 		pcie_doe.c	\
+		pcie_dvsec_rmeda.c	\
 	)
 
 ifeq (${ENABLE_REALM_PAYLOAD_TESTS},1)
diff --git a/tftf/tests/tests-realm-payload.xml b/tftf/tests/tests-realm-payload.xml
index 064f988..c9dc0cb 100644
--- a/tftf/tests/tests-realm-payload.xml
+++ b/tftf/tests/tests-realm-payload.xml
@@ -173,8 +173,8 @@
 	  <!-- Test cases related to Dev Mem Map and Unmap -->
 	  <testcase name="Realm payload Dev Mem Map and Unmap"
 	  function="host_realm_dev_mem_map_unmap" />
-	  <!-- Invoke RMI calls related to DA PDEV/VDEV management -->
-	  <testcase name="Invoke RMI DA ABIs "
-	  function="host_invoke_rmi_da_flow" />
+	  <!-- Invoke DA workflow on PCIe off-chip device -->
+	  <testcase name="DA workflow on all PCIe off-chip devices"
+	  function="host_da_workflow_on_all_offchip_devices" />
   </testsuite>
 </testsuites>