All of lore.kernel.org
 help / color / mirror / Atom feed
From: Igor Mammedov <imammedo@redhat.com>
To: Ben Widawsky <ben.widawsky@intel.com>
Cc: "Thomas Huth" <thuth@redhat.com>,
	"Michael S. Tsirkin" <mst@redhat.com>,
	"Vishal Verma" <vishal.l.verma@intel.com>,
	"Chris Browy" <cbrowy@avery-design.com>,
	"Philippe Mathieu-Daudé" <f4bug@amsat.org>,
	qemu-devel@nongnu.org,
	"Jonathan Cameron" <Jonathan.Cameron@Huawei.com>,
	"Prashant V Agarwal" <agpr123@gmail.com>,
	"Dan Williams" <dan.j.williams@intel.com>
Subject: Re: [RFC PATCH v2 24/32] hw/cxl/device: Add a memory device (8.2.8.5)
Date: Wed, 27 Jan 2021 22:03:12 +0100	[thread overview]
Message-ID: <20210127220312.6850abe2@redhat.com> (raw)
In-Reply-To: <20210105165323.783725-25-ben.widawsky@intel.com>

On Tue,  5 Jan 2021 08:53:15 -0800
Ben Widawsky <ben.widawsky@intel.com> wrote:

> A CXL memory device (AKA Type 3) is a CXL component that contains some
> combination of volatile and persistent memory. It also implements the
> previously defined mailbox interface as well as the memory device
> firmware interface.
> 
> The following example will create a 256M device in a 512M window:
> 
> -object "memory-backend-file,id=cxl-mem1,share,mem-path=cxl-type3,size=512M"
> -device "cxl-type3,bus=rp0,memdev=cxl-mem1,id=cxl-pmem0,size=256M"

I'd expect whole backend used by frontend, so one would not need "size" property
on frontend (like we do with memory devices).
So question is why it partially uses memdev?


> Signed-off-by: Ben Widawsky <ben.widawsky@intel.com>
> ---
>  hw/core/numa.c             |   3 +
>  hw/cxl/cxl-mailbox-utils.c |  41 ++++++
>  hw/i386/pc.c               |   1 +
>  hw/mem/Kconfig             |   5 +
>  hw/mem/cxl_type3.c         | 262 +++++++++++++++++++++++++++++++++++++
>  hw/mem/meson.build         |   1 +
>  hw/pci/pcie.c              |  30 +++++
>  include/hw/cxl/cxl.h       |   2 +
>  include/hw/cxl/cxl_pci.h   |  22 ++++
>  include/hw/pci/pci_ids.h   |   1 +
>  monitor/hmp-cmds.c         |  15 +++
>  qapi/machine.json          |   1 +
>  12 files changed, 384 insertions(+)
>  create mode 100644 hw/mem/cxl_type3.c
> 
> diff --git a/hw/core/numa.c b/hw/core/numa.c
> index 68cee65f61..cd7df371e6 100644
> --- a/hw/core/numa.c
> +++ b/hw/core/numa.c
> @@ -770,6 +770,9 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[])
>                  node_mem[pcdimm_info->node].node_plugged_mem +=
>                      pcdimm_info->size;
>                  break;
> +            case MEMORY_DEVICE_INFO_KIND_CXL:
> +                /* FINISHME */
> +                break;
>              case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
>                  vpi = value->u.virtio_pmem.data;
>                  /* TODO: once we support numa, assign to right node */
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index f68ec5b5b9..eeb10b8943 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -49,6 +49,8 @@ enum {
>      LOGS        = 0x04,
>          #define GET_SUPPORTED 0x0
>          #define GET_LOG       0x1
> +    IDENTIFY    = 0x40,
> +        #define MEMORY_DEVICE 0x0
>  };
>  
>  /* 8.2.8.4.5.1 Command Return Codes */
> @@ -127,6 +129,7 @@ declare_mailbox_handler(TIMESTAMP_GET);
>  declare_mailbox_handler(TIMESTAMP_SET);
>  declare_mailbox_handler(LOGS_GET_SUPPORTED);
>  declare_mailbox_handler(LOGS_GET_LOG);
> +declare_mailbox_handler(IDENTIFY_MEMORY_DEVICE);
>  
>  #define IMMEDIATE_CONFIG_CHANGE (1 << 1)
>  #define IMMEDIATE_POLICY_CHANGE (1 << 3)
> @@ -144,6 +147,7 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
>      CXL_CMD(TIMESTAMP, SET, 8, IMMEDIATE_POLICY_CHANGE),
>      CXL_CMD(LOGS, GET_SUPPORTED, 0, 0),
>      CXL_CMD(LOGS, GET_LOG, 0x18, 0),
> +    CXL_CMD(IDENTIFY, MEMORY_DEVICE, 0, 0),
>  };
>  
>  #undef CXL_CMD
> @@ -262,6 +266,43 @@ define_mailbox_handler(LOGS_GET_LOG)
>      return CXL_MBOX_SUCCESS;
>  }
>  
> +/* 8.2.9.5.1.1 */
> +define_mailbox_handler(IDENTIFY_MEMORY_DEVICE)
> +{
> +    struct {
> +        char fw_revision[0x10];
> +        uint64_t total_capacity;
> +        uint64_t volatile_capacity;
> +        uint64_t persistent_capacity;
> +        uint64_t partition_align;
> +        uint16_t info_event_log_size;
> +        uint16_t warning_event_log_size;
> +        uint16_t failure_event_log_size;
> +        uint16_t fatal_event_log_size;
> +        uint32_t lsa_size;
> +        uint8_t poison_list_max_mer[3];
> +        uint16_t inject_poison_limit;
> +        uint8_t poison_caps;
> +        uint8_t qos_telemetry_caps;
> +    } __attribute__((packed)) *id;
> +    _Static_assert(sizeof(*id) == 0x43, "Bad identify size");
> +
> +    if (memory_region_size(cxl_dstate->pmem) < (256 << 20)) {
> +        return CXL_MBOX_INTERNAL_ERROR;
> +    }
> +
> +    id = (void *)cmd->payload;
> +    memset(id, 0, sizeof(*id));
> +
> +    /* PMEM only */
> +    snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0);
> +    id->total_capacity = memory_region_size(cxl_dstate->pmem);
> +    id->persistent_capacity = memory_region_size(cxl_dstate->pmem);
> +
> +    *len = sizeof(*id);
> +    return CXL_MBOX_SUCCESS;
> +}
> +
>  void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
>  {
>      uint16_t ret = CXL_MBOX_SUCCESS;
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 5458f61d10..5d41809b37 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -79,6 +79,7 @@
>  #include "acpi-build.h"
>  #include "hw/mem/pc-dimm.h"
>  #include "hw/mem/nvdimm.h"
> +#include "hw/cxl/cxl.h"
>  #include "qapi/error.h"
>  #include "qapi/qapi-visit-common.h"
>  #include "qapi/visitor.h"
> diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig
> index a0ef2cf648..7d9d1ced3e 100644
> --- a/hw/mem/Kconfig
> +++ b/hw/mem/Kconfig
> @@ -10,3 +10,8 @@ config NVDIMM
>      default y
>      depends on (PC || PSERIES || ARM_VIRT)
>      select MEM_DEVICE
> +
> +config CXL_MEM_DEVICE
> +    bool
> +    default y if CXL
> +    select MEM_DEVICE
> diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
> new file mode 100644
> index 0000000000..3985bb8d0b
> --- /dev/null
> +++ b/hw/mem/cxl_type3.c
> @@ -0,0 +1,262 @@
> +#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 "qapi/error.h"
> +#include "qemu/log.h"
> +#include "qemu/module.h"
> +#include "qemu/range.h"
> +#include "qemu/rcu.h"
> +#include "sysemu/hostmem.h"
> +#include "hw/cxl/cxl.h"
> +
> +typedef struct cxl_type3_dev {
> +    /* Private */
> +    PCIDevice parent_obj;
> +
> +    /* Properties */
> +    uint64_t size;
> +    HostMemoryBackend *hostmem;
> +
> +    /* State */
> +    CXLComponentState cxl_cstate;
> +    CXLDeviceState cxl_dstate;
> +} CXLType3Dev;
> +
> +#define CT3(obj) OBJECT_CHECK(CXLType3Dev, (obj), TYPE_CXL_TYPE3_DEV)
> +
> +static void build_dvsecs(CXLType3Dev *ct3d)
> +{
> +    CXLComponentState *cxl_cstate = &ct3d->cxl_cstate;
> +    uint8_t *dvsec;
> +
> +    dvsec = (uint8_t *)&(struct dvsec_device){
> +        .cap = 0x1e,
> +        .ctrl = 0x6,
> +        .status2 = 0x2,
> +        .range1_size_hi = 0,
> +        .range1_size_lo = (2 << 5) | (2 << 2) | 0x3 | ct3d->size,
> +        .range1_base_hi = 0,
> +        .range1_base_lo = 0,
> +    };
> +    cxl_component_create_dvsec(cxl_cstate, PCIE_CXL_DEVICE_DVSEC_LENGTH,
> +                               PCIE_CXL_DEVICE_DVSEC,
> +                               PCIE_CXL2_DEVICE_DVSEC_REVID, dvsec);
> +
> +    dvsec = (uint8_t *)&(struct dvsec_register_locator){
> +        .rsvd         = 0,
> +        .reg0_base_lo = RBI_COMPONENT_REG | COMPONENT_REG_BAR_IDX,
> +        .reg0_base_hi = 0,
> +        .reg1_base_lo = RBI_CXL_DEVICE_REG | DEVICE_REG_BAR_IDX,
> +        .reg1_base_hi = 0,
> +    };
> +    cxl_component_create_dvsec(cxl_cstate, REG_LOC_DVSEC_LENGTH, REG_LOC_DVSEC,
> +                               REG_LOC_DVSEC_REVID, dvsec);
> +}
> +
> +static void ct3_instance_init(Object *obj)
> +{
> +    /* MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj); */
> +}
> +
> +static void ct3_finalize(Object *obj)
> +{
> +    CXLType3Dev *ct3d = CT3(obj);
> +
> +    g_free(ct3d->cxl_dstate.pmem);
> +}
> +
> +static void cxl_setup_memory(CXLType3Dev *ct3d, Error **errp)
> +{
> +    MemoryRegionSection mrs;
> +    MemoryRegion *mr;
> +    uint64_t offset = 0;
> +    size_t remaining_size;
> +
> +    if (!ct3d->hostmem) {
> +        error_setg(errp, "memdev property must be set");
> +        return;
> +    }
> +
> +    /* FIXME: need to check mr is the host bridge's MR */
> +    mr = host_memory_backend_get_memory(ct3d->hostmem);
> +
> +    /* Create our new subregion */
> +    ct3d->cxl_dstate.pmem = g_new(MemoryRegion, 1);
> +
> +    /* Find the first free space in the window */
> +    WITH_RCU_READ_LOCK_GUARD()
> +    {
> +        mrs = memory_region_find(mr, offset, 1);
> +        while (mrs.mr && mrs.mr != mr) {
> +            offset += memory_region_size(mrs.mr);
> +            mrs = memory_region_find(mr, offset, 1);
> +        }
> +    }
> +
> +    remaining_size = memory_region_size(mr) - offset;
> +    if (remaining_size < ct3d->size) {
> +        g_free(ct3d->cxl_dstate.pmem);
> +        error_setg(errp,
> +                   "Not enough free space (%zd) required for device (%" PRId64  ")",
> +                   remaining_size, ct3d->size);
> +    }
> +
> +    /* Register our subregion as non-volatile */
> +    memory_region_init_ram(ct3d->cxl_dstate.pmem, OBJECT(ct3d),
> +                           "cxl_type3-memory", ct3d->size, errp);
this allocates ct3d->size of anon RAM, was this an intention?
If yes, can you clarify why extra RAM is used instead of using what
backend provides?

> +    memory_region_set_nonvolatile(ct3d->cxl_dstate.pmem, true);

> +#ifdef SET_PMEM_PADDR
> +    memory_region_add_subregion(mr, offset, ct3d->cxl_dstate.pmem);
> +#endif
What this hunk is supposed to do, why it's ifdef-ed?


> +}
> +
> +static MemoryRegion *cxl_md_get_memory_region(MemoryDeviceState *md,
> +                                              Error **errp)
> +{
> +    CXLType3Dev *ct3d = CT3(md);
> +
> +    if (!ct3d->cxl_dstate.pmem) {
> +        cxl_setup_memory(ct3d, errp);
> +    }
> +
> +    return ct3d->cxl_dstate.pmem;
> +}
> +
> +static void ct3_realize(PCIDevice *pci_dev, Error **errp)
> +{
> +    CXLType3Dev *ct3d = CT3(pci_dev);
> +    CXLComponentState *cxl_cstate = &ct3d->cxl_cstate;
> +    ComponentRegisters *regs = &cxl_cstate->crb;
> +    MemoryRegion *mr = &regs->component_registers;
> +    uint8_t *pci_conf = pci_dev->config;
> +
> +    if (!ct3d->cxl_dstate.pmem) {
> +        cxl_setup_memory(ct3d, errp);
> +    }
> +
> +    pci_config_set_prog_interface(pci_conf, 0x10);
> +    pci_config_set_class(pci_conf, PCI_CLASS_MEMORY_CXL);
> +
> +    pcie_endpoint_cap_init(pci_dev, 0x80);
> +    cxl_cstate->dvsec_offset = 0x100;
> +
> +    ct3d->cxl_cstate.pdev = pci_dev;
> +    build_dvsecs(ct3d);
> +
> +    cxl_component_register_block_init(OBJECT(pci_dev), cxl_cstate,
> +                                      TYPE_CXL_TYPE3_DEV);
> +
> +    pci_register_bar(
> +        pci_dev, COMPONENT_REG_BAR_IDX,
> +        PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, mr);
> +
> +    cxl_device_register_block_init(OBJECT(pci_dev), &ct3d->cxl_dstate);
> +    pci_register_bar(pci_dev, DEVICE_REG_BAR_IDX,
> +                     PCI_BASE_ADDRESS_SPACE_MEMORY |
> +                         PCI_BASE_ADDRESS_MEM_TYPE_64,
> +                     &ct3d->cxl_dstate.device_registers);
> +}
> +
> +static uint64_t cxl_md_get_addr(const MemoryDeviceState *md)
> +{
> +    CXLType3Dev *ct3d = CT3(md);
> +
> +    return memory_region_get_ram_addr(ct3d->cxl_dstate.pmem);
> +}
> +
> +static void cxl_md_set_addr(MemoryDeviceState *md, uint64_t addr, Error **errp)
> +{
> +    object_property_set_uint(OBJECT(md), "paddr", addr, errp);
> +}
> +
> +static void ct3d_reset(DeviceState *dev)
> +{
> +    CXLType3Dev *ct3d = CT3(dev);
> +    uint32_t *reg_state = ct3d->cxl_cstate.crb.cache_mem_registers;
> +
> +    cxl_component_register_init_common(reg_state, CXL2_TYPE3_DEVICE);
> +    cxl_device_register_init_common(&ct3d->cxl_dstate);
> +}
> +
> +static Property ct3_props[] = {
> +    DEFINE_PROP_SIZE("size", CXLType3Dev, size, -1),
> +    DEFINE_PROP_LINK("memdev", CXLType3Dev, hostmem, TYPE_MEMORY_BACKEND,
> +                     HostMemoryBackend *),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md,
> +                                        MemoryDeviceInfo *info)
> +{
> +    PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1);
> +    const DeviceClass *dc = DEVICE_GET_CLASS(md);
> +    const DeviceState *dev = DEVICE(md);
> +    CXLType3Dev *ct3d = CT3(md);
> +
> +    if (dev->id) {
> +        di->has_id = true;
> +        di->id = g_strdup(dev->id);
> +    }
> +    di->hotplugged = dev->hotplugged;
> +    di->hotpluggable = dc->hotpluggable;
> +    di->addr = cxl_md_get_addr(md);
> +    di->slot = 0;
> +    di->node = 0;
> +    di->size = memory_device_get_region_size(md, NULL);
> +    di->memdev = object_get_canonical_path(OBJECT(ct3d->hostmem));
> +
> +
> +    info->u.cxl.data = di;
> +    info->type = MEMORY_DEVICE_INFO_KIND_CXL;
> +}
> +
> +static void ct3_class_init(ObjectClass *oc, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(oc);
> +    PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc);
> +    MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
> +
> +    pc->realize = ct3_realize;
> +    pc->class_id = PCI_CLASS_STORAGE_EXPRESS;
> +    pc->vendor_id = PCI_VENDOR_ID_INTEL;
> +    pc->device_id = 0xd93; /* LVF for now */
> +    pc->revision = 1;
> +
> +    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
> +    dc->desc = "CXL PMEM Device (Type 3)";
> +    dc->reset = ct3d_reset;
> +    device_class_set_props(dc, ct3_props);
> +
> +    mdc->get_memory_region = cxl_md_get_memory_region;
> +    mdc->get_addr = cxl_md_get_addr;
> +    mdc->fill_device_info = pc_dimm_md_fill_device_info;
> +    mdc->get_plugged_size = memory_device_get_region_size;
> +    mdc->set_addr = cxl_md_set_addr;
> +}
> +
> +static const TypeInfo ct3d_info = {
> +    .name = TYPE_CXL_TYPE3_DEV,
> +    .parent = TYPE_PCI_DEVICE,
> +    .class_init = ct3_class_init,
> +    .instance_size = sizeof(CXLType3Dev),
> +    .instance_init = ct3_instance_init,
> +    .instance_finalize = ct3_finalize,
> +    .interfaces = (InterfaceInfo[]) {
> +        { TYPE_MEMORY_DEVICE },
> +        { INTERFACE_CXL_DEVICE },
> +        { INTERFACE_PCIE_DEVICE },
> +        {}
> +    },
> +};
> +
> +static void ct3d_registers(void)
> +{
> +    type_register_static(&ct3d_info);
> +}
> +
> +type_init(ct3d_registers);
> diff --git a/hw/mem/meson.build b/hw/mem/meson.build
> index 0d22f2b572..d13c3ed117 100644
> --- a/hw/mem/meson.build
> +++ b/hw/mem/meson.build
> @@ -3,5 +3,6 @@ mem_ss.add(files('memory-device.c'))
>  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'))
>  
>  softmmu_ss.add_all(when: 'CONFIG_MEM_DEVICE', if_true: mem_ss)
> diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
> index d4010cf8f3..1ecf6f6a55 100644
> --- a/hw/pci/pcie.c
> +++ b/hw/pci/pcie.c
> @@ -20,6 +20,7 @@
>  
>  #include "qemu/osdep.h"
>  #include "qapi/error.h"
> +#include "hw/mem/memory-device.h"
>  #include "hw/pci/pci_bridge.h"
>  #include "hw/pci/pcie.h"
>  #include "hw/pci/msix.h"
> @@ -27,6 +28,8 @@
>  #include "hw/pci/pci_bus.h"
>  #include "hw/pci/pcie_regs.h"
>  #include "hw/pci/pcie_port.h"
> +#include "hw/cxl/cxl.h"
> +#include "hw/boards.h"
>  #include "qemu/range.h"
>  
>  //#define DEBUG_PCIE
> @@ -419,6 +422,28 @@ void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
>      }
>  
>      pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, errp);
> +
> +#ifdef CXL_MEM_DEVICE
> +    /*
> +     * FIXME:
> +     * if (object_dynamic_cast(OBJECT(dev), TYPE_CXL_TYPE3_DEV)) {
> +     *    HotplugHandler *hotplug_ctrl;
> +     *   Error *local_err = NULL;
> +     *  hotplug_ctrl = qdev_get_hotplug_handler(dev);
> +     *  if (hotplug_ctrl) {
> +     *      hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err);
> +     *      if (local_err) {
> +     *          error_propagate(errp, local_err);
> +     *          return;
> +     *      }
> +     *  }
> +     */
> +    if (object_dynamic_cast(OBJECT(dev), TYPE_CXL_TYPE3_DEV)) {
> +        memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(qdev_get_machine()),
> +                               NULL, errp);
> +    }

why use MEMORY_DEVICE interface instead of exposing memory as PCI BAR?

> +#endif
>  }
>  
>  void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
> @@ -455,6 +480,11 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
>          pcie_cap_slot_event(hotplug_pdev,
>                              PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP);
>      }
> +
> +#ifdef CXL_MEM_DEVICE
> +    if (object_dynamic_cast(OBJECT(dev), TYPE_CXL_TYPE3_DEV))
> +        memory_device_plug(MEMORY_DEVICE(dev), MACHINE(qdev_get_machine()));
> +#endif
>  }
>  
>  void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
> diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
> index b1e5f4a8fa..809ed7de60 100644
> --- a/include/hw/cxl/cxl.h
> +++ b/include/hw/cxl/cxl.h
> @@ -17,6 +17,8 @@
>  #define COMPONENT_REG_BAR_IDX 0
>  #define DEVICE_REG_BAR_IDX 2
>  
> +#define TYPE_CXL_TYPE3_DEV "cxl-type3"
> +
>  #define CXL_HOST_BASE 0xD0000000
>  #define CXL_WINDOW_MAX 10
>  
> diff --git a/include/hw/cxl/cxl_pci.h b/include/hw/cxl/cxl_pci.h
> index a53c2e5ae7..9ec28c9feb 100644
> --- a/include/hw/cxl/cxl_pci.h
> +++ b/include/hw/cxl/cxl_pci.h
> @@ -64,6 +64,28 @@ _Static_assert(sizeof(struct dvsec_header) == 10,
>   * CXL 2.0 Downstream Port: 3, 4, 7, 8
>   */
>  
> +/* CXL 2.0 - 8.1.3 (ID 0001) */
> +struct dvsec_device {
> +    struct dvsec_header hdr;
> +    uint16_t cap;
> +    uint16_t ctrl;
> +    uint16_t status;
> +    uint16_t ctrl2;
> +    uint16_t status2;
> +    uint16_t lock;
> +    uint16_t cap2;
> +    uint32_t range1_size_hi;
> +    uint32_t range1_size_lo;
> +    uint32_t range1_base_hi;
> +    uint32_t range1_base_lo;
> +    uint32_t range2_size_hi;
> +    uint32_t range2_size_lo;
> +    uint32_t range2_base_hi;
> +    uint32_t range2_base_lo;
> +};
> +_Static_assert(sizeof(struct dvsec_device) == 0x38,
> +               "dvsec device size incorrect");
> +
>  /* CXL 2.0 - 8.1.5 (ID 0003) */
>  struct extensions_dvsec_port {
>      struct dvsec_header hdr;
> diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
> index 11f8ab7149..76bf3ed590 100644
> --- a/include/hw/pci/pci_ids.h
> +++ b/include/hw/pci/pci_ids.h
> @@ -53,6 +53,7 @@
>  #define PCI_BASE_CLASS_MEMORY            0x05
>  #define PCI_CLASS_MEMORY_RAM             0x0500
>  #define PCI_CLASS_MEMORY_FLASH           0x0501
> +#define PCI_CLASS_MEMORY_CXL             0x0502
>  #define PCI_CLASS_MEMORY_OTHER           0x0580
>  
>  #define PCI_BASE_CLASS_BRIDGE            0x06
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index 0dd594f92b..0f67bc61ce 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -1887,6 +1887,21 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict)
>                  monitor_printf(mon, "  hotpluggable: %s\n",
>                                 di->hotpluggable ? "true" : "false");
>                  break;
> +            case MEMORY_DEVICE_INFO_KIND_CXL:
> +                di = value->u.cxl.data;
> +                monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
> +                               MemoryDeviceInfoKind_str(value->type),
> +                               di->id ? di->id : "");
> +                monitor_printf(mon, "  addr: 0x%" PRIx64 "\n", di->addr);
> +                monitor_printf(mon, "  slot: %" PRId64 "\n", di->slot);
> +                monitor_printf(mon, "  node: %" PRId64 "\n", di->node);
> +                monitor_printf(mon, "  size: %" PRIu64 "\n", di->size);
> +                monitor_printf(mon, "  memdev: %s\n", di->memdev);
> +                monitor_printf(mon, "  hotplugged: %s\n",
> +                               di->hotplugged ? "true" : "false");
> +                monitor_printf(mon, "  hotpluggable: %s\n",
> +                               di->hotpluggable ? "true" : "false");
> +                break;
>              case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM:
>                  vpi = value->u.virtio_pmem.data;
>                  monitor_printf(mon, "Memory device [%s]: \"%s\"\n",
> diff --git a/qapi/machine.json b/qapi/machine.json
> index 330189efe3..aa96d662bd 100644
> --- a/qapi/machine.json
> +++ b/qapi/machine.json
> @@ -1394,6 +1394,7 @@
>  { 'union': 'MemoryDeviceInfo',
>    'data': { 'dimm': 'PCDIMMDeviceInfo',
>              'nvdimm': 'PCDIMMDeviceInfo',
> +            'cxl': 'PCDIMMDeviceInfo',
>              'virtio-pmem': 'VirtioPMEMDeviceInfo',
>              'virtio-mem': 'VirtioMEMDeviceInfo'
>            }



  reply	other threads:[~2021-01-27 21:06 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-01-05 16:52 [RFC PATCH v2 00/32] CXL 2.0 Support Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 01/32] Temp: Add the PCI_EXT_ID_DVSEC definition to the qemu pci_regs.h copy Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 02/32] hw/pci/cxl: Add a CXL component type (interface) Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 03/32] hw/cxl/component: Introduce CXL components (8.1.x, 8.2.5) Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 04/32] hw/cxl/device: Introduce a CXL device (8.2.8) Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 05/32] hw/cxl/device: Implement the CAP array (8.2.8.1-2) Ben Widawsky
2021-01-06 13:28   ` Jonathan Cameron
2021-01-06 16:49     ` Ben Widawsky
2021-01-06 17:06       ` Jonathan Cameron
2021-01-06 17:09         ` Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 06/32] hw/cxl/device: Add device status (8.2.8.3) Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 07/32] hw/cxl/device: Implement basic mailbox (8.2.8.4) Ben Widawsky
2021-01-06 13:21   ` Jonathan Cameron
2021-01-06 16:31     ` Ben Widawsky
2021-01-06 17:40     ` [Linuxarm] " Jonathan Cameron
2021-01-06 18:05       ` Ben Widawsky
2021-01-06 19:08         ` Ben Widawsky
2021-01-08  5:36           ` Ben Widawsky
2021-01-05 16:52 ` [RFC PATCH v2 08/32] hw/cxl/device: Add memory devices (8.2.8.5) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 09/32] hw/cxl/device: Add cheap EVENTS implementation (8.2.9.1) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 10/32] hw/cxl/device: Placeholder for firmware commands Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 11/32] hw/cxl/device: Timestamp implementation (8.2.9.3) Ben Widawsky
2021-01-05 17:12   ` Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 12/32] hw/cxl/device: Add log commands (8.2.9.4) + CEL Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 13/32] hw/pxb: Use a type for realizing expanders Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 14/32] hw/pci/cxl: Create a CXL bus type Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 15/32] hw/pxb: Allow creation of a CXL PXB (host bridge) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 16/32] qtest: allow DSDT acpi table changes Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 17/32] acpi/pci: Consolidate host bridge setup Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 18/32] tests/acpi: remove stale allowed tables Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 19/32] hw/pci: Plumb _UID through host bridges Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 20/32] hw/cxl/component: Implement host bridge MMIO (8.2.5, table 142) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 21/32] acpi/pxb/cxl: Reserve host bridge MMIO Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 22/32] hw/pxb/cxl: Add "windows" for host bridges Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 23/32] hw/cxl/rp: Add a root port Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 24/32] hw/cxl/device: Add a memory device (8.2.8.5) Ben Widawsky
2021-01-27 21:03   ` Igor Mammedov [this message]
2021-01-27 21:11     ` Ben Widawsky
2021-01-27 21:21       ` Igor Mammedov
2021-01-27 21:30         ` Ben Widawsky
2021-01-27 21:26     ` Ben Widawsky
2021-01-28 10:25       ` Jonathan Cameron
2021-01-28 15:03         ` Ben Widawsky
2021-01-28 15:14           ` Ben Widawsky
2021-01-28 16:51             ` Ben Widawsky
2021-01-28 16:58               ` Ben Widawsky
2021-01-28 17:40                 ` Jonathan Cameron
2021-01-05 16:53 ` [RFC PATCH v2 25/32] hw/cxl/device: Implement MMIO HDM decoding (8.2.5.12) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 26/32] acpi/cxl: Add _OSC implementation (9.14.2) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 27/32] tests/acpi: allow CEDT table addition Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 28/32] acpi/cxl: Create the CEDT (9.14.1) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 29/32] Temp: acpi/cxl: Add ACPI0017 (CEDT awareness) Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 30/32] tests/acpi: Add new CEDT files Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 31/32] WIP: i386/cxl: Initialize a host bridge Ben Widawsky
2021-01-05 16:53 ` [RFC PATCH v2 32/32] qtest/cxl: Add very basic sanity tests Ben Widawsky
2021-01-08 18:44 ` [RFC PATCH v2 00/32] CXL 2.0 Support Jonathan Cameron
2021-01-08 18:51   ` Ben Widawsky

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210127220312.6850abe2@redhat.com \
    --to=imammedo@redhat.com \
    --cc=Jonathan.Cameron@Huawei.com \
    --cc=agpr123@gmail.com \
    --cc=ben.widawsky@intel.com \
    --cc=cbrowy@avery-design.com \
    --cc=dan.j.williams@intel.com \
    --cc=f4bug@amsat.org \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thuth@redhat.com \
    --cc=vishal.l.verma@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.