diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index dee5a8884b..3449f02090 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -4,6 +4,7 @@
 #include "hw/mem/memory-device.h"
 #include "hw/mem/pc-dimm.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/doe.h"
 #include "hw/qdev-properties.h"
 #include "qapi/error.h"
 #include "qemu/log.h"
@@ -11,6 +12,7 @@
 #include "qemu/range.h"
 #include "qemu/rcu.h"
 #include "sysemu/hostmem.h"
+#include "sysemu/numa.h"
 #include "hw/cxl/cxl.h"
 
 typedef struct cxl_type3_dev {
@@ -21,6 +23,9 @@ typedef struct cxl_type3_dev {
     uint64_t size;
     HostMemoryBackend *hostmem;
 
+    PCIEDOE doe;
+    CXLCDAT cdat;
+
     /* State */
     CXLComponentState cxl_cstate;
     CXLDeviceState cxl_dstate;
@@ -28,7 +33,7 @@ typedef struct cxl_type3_dev {
 
 #define CT3(obj) OBJECT_CHECK(CXLType3Dev, (obj), TYPE_CXL_TYPE3_DEV)
 
-static void build_dvsecs(CXLType3Dev *ct3d)
+static int build_dvsecs(CXLType3Dev *ct3d)
 {
     CXLComponentState *cxl_cstate = &ct3d->cxl_cstate;
     uint8_t *dvsec;
@@ -55,6 +60,7 @@ static void build_dvsecs(CXLType3Dev *ct3d)
     };
     cxl_component_create_dvsec(cxl_cstate, REG_LOC_DVSEC_LENGTH, REG_LOC_DVSEC,
                                REG_LOC_DVSEC_REVID, dvsec);
+    return cxl_cstate->dvsec_offset;
 }
 
 static void hdm_decoder_commit(CXLType3Dev *ct3d, int which)
@@ -201,6 +207,7 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
     ComponentRegisters *regs = &cxl_cstate->crb;
     MemoryRegion *mr = &regs->component_registers;
     uint8_t *pci_conf = pci_dev->config;
+    int offset;
 
     if (!ct3d->cxl_dstate.pmem) {
         cxl_setup_memory(ct3d, errp);
@@ -213,7 +220,21 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
     cxl_cstate->dvsec_offset = 0x100;
 
     ct3d->cxl_cstate.pdev = pci_dev;
-    build_dvsecs(ct3d);
+    offset = build_dvsecs(ct3d);
+
+    /* Build DOE - no interrupt for now */
+    offset = pcie_doe_ecap(&ct3d->doe, pci_dev, offset);
+    doe_add_message_handler(&ct3d->doe, 0x1e98, 0x2, &cxl_table_access,
+                            &ct3d->cdat);
+
+    /* Store entires of CDAT  for read back from DOE */
+    cdat_add_dsmas(&ct3d->cdat, 0, CDAT_DSMAS_FLAG_NV, 0x3345000000,
+                   0x0001000000);
+    cdat_add_dsmas(&ct3d->cdat, 1, 0, 0x33460000000, 0x00010000000);
+    cdat_add_dslbis(&ct3d->cdat, 0, HMAT_LB_MEM_MEMORY,
+                    (uint8_t)HMAT_LB_DATA_ACCESS_LATENCY,
+                    1000, /* microsecs */
+                    90, 0, 0);
 
 #ifndef SET_PMEM_PADDR
     regs->special_ops = g_new0(MemoryRegionOps, 1);
@@ -287,6 +308,28 @@ static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md,
     info->type = MEMORY_DEVICE_INFO_KIND_CXL;
 }
 
+static void ct3d_config_write(PCIDevice *pci_dev, uint32_t addr, uint32_t val, int len)
+{
+    CXLType3Dev *ct3d = CT3(pci_dev);
+
+    pci_default_write_config(pci_dev, addr, val, len);
+    pcie_doe_write(&ct3d->doe, addr, val, len);
+
+}
+
+static uint32_t ct3d_config_read(PCIDevice *pci_dev, uint32_t addr, int len)
+{
+    CXLType3Dev *ct3d = CT3(pci_dev);
+    int found = 0;
+    uint32_t val;
+
+    val = pcie_doe_read(&ct3d->doe, addr, len, &found);
+    if (found) {
+        return val;
+    }
+    return pci_default_read_config(pci_dev, addr, len);
+}
+
 static void ct3_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -298,6 +341,8 @@ static void ct3_class_init(ObjectClass *oc, void *data)
     pc->vendor_id = PCI_VENDOR_ID_INTEL;
     pc->device_id = 0xd93; /* LVF for now */
     pc->revision = 1;
+    pc->config_write = ct3d_config_write;
+    pc->config_read = ct3d_config_read;
 
     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
     dc->desc = "CXL PMEM Device (Type 3)";
diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
index 6961e47076..ec3b4d7398 100644
--- a/include/hw/cxl/cxl.h
+++ b/include/hw/cxl/cxl.h
@@ -13,6 +13,7 @@
 #include "cxl_pci.h"
 #include "cxl_component.h"
 #include "cxl_device.h"
+#include "cxl_cdat.h"
 
 #define COMPONENT_REG_BAR_IDX 0
 #define DEVICE_REG_BAR_IDX 2
