qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 3/3] hw/cxl: introduce CXL type-2 device emulation


From: Zhi Wang
Subject: Re: [PATCH 3/3] hw/cxl: introduce CXL type-2 device emulation
Date: Thu, 12 Dec 2024 18:33:08 +0000

On 12/12/2024 19.02, Alejandro Lucero Palau wrote:
> 
> On 12/12/24 13:04, Zhi Wang wrote:
>> From: Zhi Wang <zhiwang@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.weiny@intel.com>
>> Signed-off-by: Zhi Wang <zhiwang@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.ni@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 = &regs->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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]