On 12/12/2024 19.02, Alejandro Lucero Palau wrote: > > On 12/12/24 13:04, Zhi Wang wrote: >> From: Zhi Wang <zhiw...@kernel.org> >> >> Introduce a CXL type-2 device emulation that provides a minimum base for >> testing kernel CXL core type-2 support and CXL type-2 virtualization. It >> is also a good base for introducing the more emulated features. >> >> Currently, it only supports: >> >> - Emulating component registers with HDM decoders. >> - Volatile memory backend and emualtion of region access. >> >> The emulation is aimed to not tightly coupled with the current CXL type-3 >> emulation since many advanced CXL type-3 emulation features are not >> implemented in a CXL type-2 device. >> >> Co-developed-by: Ira Weiny <ira.we...@intel.com> >> Signed-off-by: Zhi Wang <zhiw...@kernel.org> >> --- >> MAINTAINERS | 1 + >> docs/system/devices/cxl.rst | 11 ++ >> hw/cxl/cxl-component-utils.c | 2 + >> hw/cxl/cxl-host.c | 19 +- >> hw/mem/Kconfig | 5 + >> hw/mem/cxl_accel.c | 319 +++++++++++++++++++++++++++++++++ >> hw/mem/meson.build | 1 + >> include/hw/cxl/cxl_component.h | 1 + >> include/hw/cxl/cxl_device.h | 25 +++ >> include/hw/pci/pci_ids.h | 1 + >> 10 files changed, 382 insertions(+), 3 deletions(-) >> create mode 100644 hw/mem/cxl_accel.c >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index aaf0505a21..72a6a505eb 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -2914,6 +2914,7 @@ R: Fan Ni <fan...@samsung.com> >> S: Supported >> F: hw/cxl/ >> F: hw/mem/cxl_type3.c >> +F: hw/mem/cxl_accel.c >> F: include/hw/cxl/ >> F: qapi/cxl.json >> diff --git a/docs/system/devices/cxl.rst b/docs/system/devices/cxl.rst >> index 882b036f5e..13cc2417f2 100644 >> --- a/docs/system/devices/cxl.rst >> +++ b/docs/system/devices/cxl.rst >> @@ -332,6 +332,17 @@ The same volatile setup may optionally include an >> LSA region:: >> -device cxl-type3,bus=root_port13,volatile-memdev=vmem0,lsa=cxl- >> lsa0,id=cxl-vmem0 \ >> -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G >> +A very simple setup with just one directly attached CXL Type 2 >> Volatile Memory >> +Accelerator device:: >> + >> + qemu-system-x86_64 -M q35,cxl=on -m 4G,maxmem=8G,slots=8 -smp 4 \ >> + ... >> + -object memory-backend-ram,id=vmem0,share=on,size=256M \ >> + -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1 \ >> + -device cxl-rp,port=0,bus=cxl.1,id=root_port13,chassis=0,slot=2 \ >> + -device cxl-accel,bus=root_port13,volatile-memdev=vmem0,id=cxl- >> accel0 \ >> + -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G >> + >> A setup suitable for 4 way interleave. Only one fixed window >> provided, to enable 2 way >> interleave across 2 CXL host bridges. Each host bridge has 2 CXL >> Root Ports, with >> the CXL Type3 device directly attached (no switches).:: >> diff --git a/hw/cxl/cxl-component-utils.c b/hw/cxl/cxl-component-utils.c >> index 355103d165..717ef117ac 100644 >> --- a/hw/cxl/cxl-component-utils.c >> +++ b/hw/cxl/cxl-component-utils.c >> @@ -262,6 +262,7 @@ static void hdm_init_common(uint32_t *reg_state, >> uint32_t *write_msk, >> write_msk[R_CXL_HDM_DECODER0_CTRL + i * hdm_inc] = 0x13ff; > > > You are not changing this write, but I did, based on Type3 or Type2: > > > - write_msk[R_CXL_HDM_DECODER0_CTRL + i * 0x20] = 0x13ff; > + if (type == CXL2_TYPE2_DEVICE) > + /* Bit 12 Target Range Type 0= HDM-D or HDM-DB */ > + /* Bit 10 says memory already commited */ > + write_msk[R_CXL_HDM_DECODER0_CTRL + i * 0x20] = 0x7ff; > + else > + /* Bit 12 Target Range Type 1= HDM-H aka Host Only > Coherent Address Range */ > + write_msk[R_CXL_HDM_DECODER0_CTRL + i * 0x20] = 0x13ff; > > > It has been a while since I did work on this, but I guess I did so > because it was needed. But maybe I'm wrong ... > > Bit 10 was something I needed for emulating what we had in the real > device, but bit 12 looks something we should set, although maybe it is > only informative.
Interesting. We can think about how to custom the mask via params. It might be helpful that you can show a list of the stuff you wish to custom. I understand they are hacks for validation? since Bit 12 is only RWL for HB, USP of switches in the spec. > > >> if (type == CXL2_DEVICE || >> type == CXL2_TYPE3_DEVICE || >> + type == CXL3_TYPE2_DEVICE || >> type == CXL2_LOGICAL_DEVICE) { >> write_msk[R_CXL_HDM_DECODER0_TARGET_LIST_LO + i * >> hdm_inc] = >> 0xf0000000; >> @@ -293,6 +294,7 @@ void cxl_component_register_init_common(uint32_t >> *reg_state, >> case CXL2_UPSTREAM_PORT: >> case CXL2_TYPE3_DEVICE: >> case CXL2_LOGICAL_DEVICE: >> + case CXL3_TYPE2_DEVICE: >> /* + HDM */ >> caps = 3; >> break; >> diff --git a/hw/cxl/cxl-host.c b/hw/cxl/cxl-host.c >> index e9f2543c43..e603a3f2fc 100644 >> --- a/hw/cxl/cxl-host.c >> +++ b/hw/cxl/cxl-host.c >> @@ -201,7 +201,8 @@ static PCIDevice >> *cxl_cfmws_find_device(CXLFixedWindow *fw, hwaddr addr) >> return NULL; >> } >> - if (object_dynamic_cast(OBJECT(d), TYPE_CXL_TYPE3)) { >> + if (object_dynamic_cast(OBJECT(d), TYPE_CXL_TYPE3) || >> + object_dynamic_cast(OBJECT(d), TYPE_CXL_ACCEL)) { >> return d; >> } >> @@ -256,7 +257,13 @@ static MemTxResult cxl_read_cfmws(void *opaque, >> hwaddr addr, uint64_t *data, >> return MEMTX_ERROR; >> } >> - return cxl_type3_read(d, addr + fw->base, data, size, attrs); >> + if (object_dynamic_cast(OBJECT(d), TYPE_CXL_TYPE3)) { >> + return cxl_type3_read(d, addr + fw->base, data, size, attrs); >> + } else if (object_dynamic_cast(OBJECT(d), TYPE_CXL_ACCEL)) { >> + return cxl_accel_read(d, addr + fw->base, data, size, attrs); >> + } >> + >> + return MEMTX_ERROR; >> } >> static MemTxResult cxl_write_cfmws(void *opaque, hwaddr addr, >> @@ -272,7 +279,13 @@ static MemTxResult cxl_write_cfmws(void *opaque, >> hwaddr addr, >> return MEMTX_OK; >> } >> - return cxl_type3_write(d, addr + fw->base, data, size, attrs); >> + if (object_dynamic_cast(OBJECT(d), TYPE_CXL_TYPE3)) { >> + return cxl_type3_write(d, addr + fw->base, data, size, attrs); >> + } else if (object_dynamic_cast(OBJECT(d), TYPE_CXL_ACCEL)) { >> + return cxl_accel_write(d, addr + fw->base, data, size, attrs); >> + } >> + >> + return MEMTX_ERROR; >> } >> const MemoryRegionOps cfmws_ops = { >> diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig >> index 73c5ae8ad9..1f7d08c17d 100644 >> --- a/hw/mem/Kconfig >> +++ b/hw/mem/Kconfig >> @@ -16,3 +16,8 @@ config CXL_MEM_DEVICE >> bool >> default y if CXL >> select MEM_DEVICE >> + >> +config CXL_ACCEL_DEVICE >> + bool >> + default y if CXL >> + select MEM_DEVICE >> diff --git a/hw/mem/cxl_accel.c b/hw/mem/cxl_accel.c >> new file mode 100644 >> index 0000000000..770072126d >> --- /dev/null >> +++ b/hw/mem/cxl_accel.c >> @@ -0,0 +1,319 @@ >> +/* >> + * CXL accel (type-2) device >> + * >> + * Copyright(C) 2024 NVIDIA Corporation. >> + * >> + * This work is licensed under the terms of the GNU GPL, version 2. >> See the >> + * COPYING file in the top-level directory. >> + * >> + * SPDX-License-Identifier: GPL-v2-only >> + */ >> + >> +#include "qemu/osdep.h" >> +#include "qemu/units.h" >> +#include "qemu/error-report.h" >> +#include "hw/mem/memory-device.h" >> +#include "hw/mem/pc-dimm.h" >> +#include "hw/pci/pci.h" >> +#include "hw/qdev-properties.h" >> +#include "hw/qdev-properties-system.h" >> +#include "qemu/log.h" >> +#include "qemu/module.h" >> +#include "qemu/range.h" >> +#include "sysemu/hostmem.h" >> +#include "sysemu/numa.h" >> +#include "hw/cxl/cxl.h" >> +#include "hw/pci/msix.h" >> + >> +static void update_dvsecs(CXLAccelDev *acceld) >> +{ >> + CXLComponentState *cxl_cstate = &acceld->cxl_cstate; >> + uint8_t *dvsec; >> + uint32_t range1_size_hi = 0, range1_size_lo = 0, >> + range1_base_hi = 0, range1_base_lo = 0; >> + >> + if (acceld->hostvmem) { >> + range1_size_hi = acceld->hostvmem->size >> 32; >> + range1_size_lo = (2 << 5) | (2 << 2) | 0x3 | >> + (acceld->hostvmem->size & 0xF0000000); >> + } >> + >> + dvsec = (uint8_t *)&(CXLDVSECDevice){ >> + .cap = 0x1e, >> + .ctrl = 0x2, >> + .status2 = 0x2, >> + .range1_size_hi = range1_size_hi, >> + .range1_size_lo = range1_size_lo, >> + .range1_base_hi = range1_base_hi, >> + .range1_base_lo = range1_base_lo, >> + }; >> + cxl_component_update_dvsec(cxl_cstate, PCIE_CXL_DEVICE_DVSEC_LENGTH, >> + PCIE_CXL_DEVICE_DVSEC, dvsec); >> + >> + dvsec = (uint8_t *)&(CXLDVSECRegisterLocator){ >> + .rsvd = 0, >> + .reg0_base_lo = RBI_COMPONENT_REG | CXL_COMPONENT_REG_BAR_IDX, >> + .reg0_base_hi = 0, >> + }; >> + cxl_component_update_dvsec(cxl_cstate, REG_LOC_DVSEC_LENGTH, >> + REG_LOC_DVSEC, dvsec); >> + >> + dvsec = (uint8_t *)&(CXLDVSECPortFlexBus){ >> + .cap = 0x26, /* 68B, IO, Mem, non-MLD */ >> + .ctrl = 0x02, /* IO always enabled */ >> + .status = 0x26, /* same as capabilities */ >> + .rcvd_mod_ts_data_phase1 = 0xef, /* WTF? */ >> + }; >> + cxl_component_update_dvsec(cxl_cstate, >> PCIE_CXL3_FLEXBUS_PORT_DVSEC_LENGTH, >> + PCIE_FLEXBUS_PORT_DVSEC, dvsec); >> +} >> + >> +static void build_dvsecs(CXLAccelDev *acceld) >> +{ >> + CXLComponentState *cxl_cstate = &acceld->cxl_cstate; >> + >> + cxl_component_create_dvsec(cxl_cstate, CXL3_TYPE2_DEVICE, >> + PCIE_CXL_DEVICE_DVSEC_LENGTH, >> + PCIE_CXL_DEVICE_DVSEC, >> + PCIE_CXL31_DEVICE_DVSEC_REVID, NULL); >> + >> + cxl_component_create_dvsec(cxl_cstate, CXL3_TYPE2_DEVICE, >> + REG_LOC_DVSEC_LENGTH, REG_LOC_DVSEC, >> + REG_LOC_DVSEC_REVID, NULL); >> + >> + cxl_component_create_dvsec(cxl_cstate, CXL3_TYPE2_DEVICE, >> + PCIE_CXL3_FLEXBUS_PORT_DVSEC_LENGTH, >> + PCIE_FLEXBUS_PORT_DVSEC, >> + PCIE_CXL3_FLEXBUS_PORT_DVSEC_REVID, >> NULL); >> + update_dvsecs(acceld); >> +} >> + >> +static bool cxl_accel_dpa(CXLAccelDev *acceld, hwaddr host_addr, >> uint64_t *dpa) >> +{ >> + return cxl_host_addr_to_dpa(&acceld->cxl_cstate, host_addr, dpa); >> +} >> + >> +static int cxl_accel_hpa_to_as_and_dpa(CXLAccelDev *acceld, >> + hwaddr host_addr, >> + unsigned int size, >> + AddressSpace **as, >> + uint64_t *dpa_offset) >> +{ >> + MemoryRegion *vmr = NULL; >> + uint64_t vmr_size = 0; >> + >> + if (!acceld->hostvmem) { >> + return -ENODEV; >> + } >> + >> + vmr = host_memory_backend_get_memory(acceld->hostvmem); >> + if (!vmr) { >> + return -ENODEV; >> + } >> + >> + vmr_size = memory_region_size(vmr); >> + >> + if (!cxl_accel_dpa(acceld, host_addr, dpa_offset)) { >> + return -EINVAL; >> + } >> + >> + if (*dpa_offset >= vmr_size) { >> + return -EINVAL; >> + } >> + >> + *as = &acceld->hostvmem_as; >> + return 0; >> +} >> + >> +MemTxResult cxl_accel_read(PCIDevice *d, hwaddr host_addr, uint64_t >> *data, >> + unsigned size, MemTxAttrs attrs) >> +{ >> + CXLAccelDev *acceld = CXL_ACCEL(d); >> + uint64_t dpa_offset = 0; >> + AddressSpace *as = NULL; >> + int res; >> + >> + res = cxl_accel_hpa_to_as_and_dpa(acceld, host_addr, size, >> + &as, &dpa_offset); >> + if (res) { >> + return MEMTX_ERROR; >> + } >> + >> + return address_space_read(as, dpa_offset, attrs, data, size); >> +} >> + >> +MemTxResult cxl_accel_write(PCIDevice *d, hwaddr host_addr, uint64_t >> data, >> + unsigned size, MemTxAttrs attrs) >> +{ >> + CXLAccelDev *acceld = CXL_ACCEL(d); >> + uint64_t dpa_offset = 0; >> + AddressSpace *as = NULL; >> + int res; >> + >> + res = cxl_accel_hpa_to_as_and_dpa(acceld, host_addr, size, >> + &as, &dpa_offset); >> + if (res) { >> + return MEMTX_ERROR; >> + } >> + >> + return address_space_write(as, dpa_offset, attrs, &data, size); >> +} >> + >> +static void clean_memory(PCIDevice *pci_dev) >> +{ >> + CXLAccelDev *acceld = CXL_ACCEL(pci_dev); >> + >> + if (acceld->hostvmem) { >> + address_space_destroy(&acceld->hostvmem_as); >> + } >> +} >> + >> +static bool setup_memory(PCIDevice *pci_dev, Error **errp) >> +{ >> + CXLAccelDev *acceld = CXL_ACCEL(pci_dev); >> + >> + if (acceld->hostvmem) { >> + MemoryRegion *vmr; >> + char *v_name; >> + >> + vmr = host_memory_backend_get_memory(acceld->hostvmem); >> + if (!vmr) { >> + error_setg(errp, "volatile memdev must have backing >> device"); >> + return false; >> + } >> + if (host_memory_backend_is_mapped(acceld->hostvmem)) { >> + error_setg(errp, "memory backend %s can't be used >> multiple times.", >> + object_get_canonical_path_component(OBJECT(acceld- >> >hostvmem))); >> + return false; >> + } >> + memory_region_set_nonvolatile(vmr, false); >> + memory_region_set_enabled(vmr, true); >> + host_memory_backend_set_mapped(acceld->hostvmem, true); >> + v_name = g_strdup("cxl-accel-dpa-vmem-space"); >> + address_space_init(&acceld->hostvmem_as, vmr, v_name); >> + g_free(v_name); >> + } >> + return true; >> +} >> + >> +static void setup_cxl_regs(PCIDevice *pci_dev) >> +{ >> + CXLAccelDev *acceld = CXL_ACCEL(pci_dev); >> + CXLComponentState *cxl_cstate = &acceld->cxl_cstate; >> + ComponentRegisters *regs = &cxl_cstate->crb; >> + MemoryRegion *mr = ®s->component_registers; >> + >> + cxl_cstate->dvsec_offset = 0x100; >> + cxl_cstate->pdev = pci_dev; >> + >> + build_dvsecs(acceld); >> + >> + cxl_component_register_block_init(OBJECT(pci_dev), cxl_cstate, >> + TYPE_CXL_ACCEL); >> + >> + pci_register_bar( >> + pci_dev, CXL_COMPONENT_REG_BAR_IDX, >> + PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, >> mr); >> +} >> + >> +#define MSIX_NUM 6 >> + >> +static int setup_msix(PCIDevice *pci_dev) >> +{ >> + int i, rc; >> + >> + /* MSI(-X) Initialization */ >> + rc = msix_init_exclusive_bar(pci_dev, MSIX_NUM, 4, NULL); >> + if (rc) { >> + return rc; >> + } >> + >> + for (i = 0; i < MSIX_NUM; i++) { >> + msix_vector_use(pci_dev, i); >> + } >> + return 0; >> +} >> + >> +static void cxl_accel_realize(PCIDevice *pci_dev, Error **errp) >> +{ >> + ERRP_GUARD(); >> + int rc; >> + uint8_t *pci_conf = pci_dev->config; >> + >> + if (!setup_memory(pci_dev, errp)) { >> + return; >> + } >> + >> + pci_config_set_prog_interface(pci_conf, 0x10); >> + pcie_endpoint_cap_init(pci_dev, 0x80); >> + >> + setup_cxl_regs(pci_dev); >> + >> + /* MSI(-X) Initialization */ >> + rc = setup_msix(pci_dev); >> + if (rc) { >> + clean_memory(pci_dev); >> + return; >> + } >> +} >> + >> +static void cxl_accel_exit(PCIDevice *pci_dev) >> +{ >> + clean_memory(pci_dev); >> +} >> + >> +static void cxl_accel_reset(DeviceState *dev) >> +{ >> + CXLAccelDev *acceld = CXL_ACCEL(dev); >> + CXLComponentState *cxl_cstate = &acceld->cxl_cstate; >> + uint32_t *reg_state = cxl_cstate->crb.cache_mem_registers; >> + uint32_t *write_msk = cxl_cstate->crb.cache_mem_regs_write_mask; >> + >> + update_dvsecs(acceld); >> + cxl_component_register_init_common(reg_state, write_msk, >> CXL3_TYPE2_DEVICE); >> +} >> + >> +static Property cxl_accel_props[] = { >> + DEFINE_PROP_LINK("volatile-memdev", CXLAccelDev, hostvmem, >> + TYPE_MEMORY_BACKEND, HostMemoryBackend *), >> + DEFINE_PROP_END_OF_LIST(), >> +}; >> + >> +static void cxl_accel_class_init(ObjectClass *oc, void *data) >> +{ >> + DeviceClass *dc = DEVICE_CLASS(oc); >> + PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); >> + >> + pc->realize = cxl_accel_realize; >> + pc->exit = cxl_accel_exit; >> + >> + pc->class_id = PCI_CLASS_CXL_QEMU_ACCEL; >> + pc->vendor_id = PCI_VENDOR_ID_INTEL; >> + pc->device_id = 0xd94; >> + pc->revision = 1; >> + >> + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); >> + dc->desc = "CXL Accelerator Device (Type 2)"; >> + device_class_set_legacy_reset(dc, cxl_accel_reset); >> + device_class_set_props(dc, cxl_accel_props); >> +} >> + >> +static const TypeInfo cxl_accel_dev_info = { >> + .name = TYPE_CXL_ACCEL, >> + .parent = TYPE_PCI_DEVICE, >> + .class_size = sizeof(struct CXLAccelClass), >> + .class_init = cxl_accel_class_init, >> + .instance_size = sizeof(CXLAccelDev), >> + .interfaces = (InterfaceInfo[]) { >> + { INTERFACE_CXL_DEVICE }, >> + { INTERFACE_PCIE_DEVICE }, >> + {} >> + }, >> +}; >> + >> +static void cxl_accel_dev_registers(void) >> +{ >> + type_register_static(&cxl_accel_dev_info); >> +} >> + >> +type_init(cxl_accel_dev_registers); >> diff --git a/hw/mem/meson.build b/hw/mem/meson.build >> index 1c1c6da24b..36a395dbb6 100644 >> --- a/hw/mem/meson.build >> +++ b/hw/mem/meson.build >> @@ -4,6 +4,7 @@ mem_ss.add(when: 'CONFIG_DIMM', if_true: files('pc- >> dimm.c')) >> mem_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_mc.c')) >> mem_ss.add(when: 'CONFIG_NVDIMM', if_true: files('nvdimm.c')) >> mem_ss.add(when: 'CONFIG_CXL_MEM_DEVICE', if_true: >> files('cxl_type3.c')) >> +mem_ss.add(when: 'CONFIG_CXL_ACCEL_DEVICE', if_true: >> files('cxl_accel.c')) >> system_ss.add(when: 'CONFIG_CXL_MEM_DEVICE', if_false: >> files('cxl_type3_stubs.c')) >> system_ss.add(when: 'CONFIG_MEM_DEVICE', if_false: files('memory- >> device-stubs.c')) >> diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/ >> cxl_component.h >> index 30fe4bfa24..0e78db26b8 100644 >> --- a/include/hw/cxl/cxl_component.h >> +++ b/include/hw/cxl/cxl_component.h >> @@ -29,6 +29,7 @@ enum reg_type { >> CXL2_UPSTREAM_PORT, >> CXL2_DOWNSTREAM_PORT, >> CXL3_SWITCH_MAILBOX_CCI, >> + CXL3_TYPE2_DEVICE, >> }; >> /* >> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h >> index 561b375dc8..ac26b264da 100644 >> --- a/include/hw/cxl/cxl_device.h >> +++ b/include/hw/cxl/cxl_device.h >> @@ -630,6 +630,26 @@ struct CSWMBCCIDev { >> CXLCCI *cci; >> }; >> +struct CXLAccelDev { >> + /* Private */ >> + PCIDevice parent_obj; >> + >> + /* Properties */ >> + HostMemoryBackend *hostvmem; >> + >> + /* State */ >> + AddressSpace hostvmem_as; >> + CXLComponentState cxl_cstate; >> +}; >> + >> +struct CXLAccelClass { >> + /* Private */ >> + PCIDeviceClass parent_class; >> +}; >> + >> +#define TYPE_CXL_ACCEL "cxl-accel" >> +OBJECT_DECLARE_TYPE(CXLAccelDev, CXLAccelClass, CXL_ACCEL) >> + >> #define TYPE_CXL_SWITCH_MAILBOX_CCI "cxl-switch-mailbox-cci" >> OBJECT_DECLARE_TYPE(CSWMBCCIDev, CSWMBCCIClass, CXL_SWITCH_MAILBOX_CCI) >> @@ -638,6 +658,11 @@ MemTxResult cxl_type3_read(PCIDevice *d, hwaddr >> host_addr, uint64_t *data, >> MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t >> data, >> unsigned size, MemTxAttrs attrs); >> +MemTxResult cxl_accel_read(PCIDevice *d, hwaddr host_addr, uint64_t >> *data, >> + unsigned size, MemTxAttrs attrs); >> +MemTxResult cxl_accel_write(PCIDevice *d, hwaddr host_addr, uint64_t >> data, >> + unsigned size, MemTxAttrs attrs); >> + >> uint64_t cxl_device_get_timestamp(CXLDeviceState *cxlds); >> void cxl_event_init(CXLDeviceState *cxlds, int start_msg_num); >> diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h >> index f1a53fea8d..08bc469316 100644 >> --- a/include/hw/pci/pci_ids.h >> +++ b/include/hw/pci/pci_ids.h >> @@ -55,6 +55,7 @@ >> #define PCI_CLASS_MEMORY_RAM 0x0500 >> #define PCI_CLASS_MEMORY_FLASH 0x0501 >> #define PCI_CLASS_MEMORY_CXL 0x0502 >> +#define PCI_CLASS_CXL_QEMU_ACCEL 0x0503 >> #define PCI_CLASS_MEMORY_OTHER 0x0580 >> #define PCI_BASE_CLASS_BRIDGE 0x06