From nobody Thu Nov 14 07:05:01 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1689614689; cv=none; d=zohomail.com; s=zohoarc; b=myAnNgXbkLov47GEcLCoRjQsg2GRwwYC98Uk8k+rq2BfZCqoCQC8BZPvbQ32rTKoxdyhahPkZDh9Sdymd1i4+tgmheOhwb+jd1qs8MgV6QDAabUK1n/cbTtlzRMEH8OjUaP4FuOZp9uTj6fi9/yL7Tlq2XbWH7q0XoZT6CYCTWI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1689614689; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:References:Sender:Subject:To; bh=WqPVfuPTIvaq7HcSlRjF6YWRgHg6f2cz/NSezTxhvNk=; b=litlnjQeWkgElGxjZGuVDfW6W0V8/dLRInudPGG3+MjeZSjb7TfMJJJVJr35ojzgl8KYBeI33qplBR9pB+SBlqHf6g85TDgj6wWHn/Ja1rCMD3U5m2Gf7E6+VbbV5c0qwxgpbyUZp9p38rMZvI+qo8A/R8Ig3tQ7DHuXAyRx1qg= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1689614689973280.4743023144581; Mon, 17 Jul 2023 10:24:49 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qLRxZ-0008B9-Dm; Mon, 17 Jul 2023 13:24:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qLRxX-00082R-6x for qemu-devel@nongnu.org; Mon, 17 Jul 2023 13:24:31 -0400 Received: from frasgout.his.huawei.com ([185.176.79.56]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qLRxT-0005cz-5o for qemu-devel@nongnu.org; Mon, 17 Jul 2023 13:24:30 -0400 Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.200]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4R4TP76RNDz67nKD; Tue, 18 Jul 2023 01:20:27 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 17 Jul 2023 18:24:23 +0100 To: , Dan Williams , CC: , Alison Schofield , Ira Weiny , Dave Jiang , Davidlohr Bueso , Viacheslav Dubeyko , Shesha Bhushan Sreenivasamurthy , Fan Ni , Michael Tsirkin , Jonathan Zhang , Klaus Jensen Subject: [RFC PATCH 15/17] hw/cxl: Add a switch mailbox CCI function. Date: Mon, 17 Jul 2023 18:16:44 +0100 Message-ID: <20230717171646.8972-16-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230717171646.8972-1-Jonathan.Cameron@huawei.com> References: <20230717171646.8972-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=185.176.79.56; envelope-from=jonathan.cameron@huawei.com; helo=frasgout.his.huawei.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-to: Jonathan Cameron From: Jonathan Cameron via Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1689614692277100003 Content-Type: text/plain; charset="utf-8" CXL switch CCIs were added in CXL r3.0. They are a PCI function, identified by class code that provides a CXL mailbox (identical to that previously defined for CXL type 3 memory devices) over which various FM-API commands may be used. Whilst the intent of this feature is enable switch control from a BMC attached to a switch upstream port, it is also useful to allow emulation of this feature on the upstream port connected to a host using the CXL devices as this greatly simplifies testing. Signed-off-by: Jonathan Cameron --- include/hw/cxl/cxl.h | 6 + include/hw/cxl/cxl_component.h | 3 +- include/hw/cxl/cxl_device.h | 15 +++ include/hw/pci-bridge/cxl_upstream_port.h | 1 + hw/cxl/cxl-device-utils.c | 25 +++++ hw/cxl/cxl-mailbox-utils.c | 129 ++++++++++++++++++++++ hw/cxl/switch-mailbox-cci.c | 98 ++++++++++++++++ hw/pci-bridge/cxl_downstream.c | 5 +- hw/cxl/meson.build | 1 + 9 files changed, 279 insertions(+), 4 deletions(-) diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index cd7567d6a8..69484f2553 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -63,4 +63,10 @@ OBJECT_DECLARE_SIMPLE_TYPE(CXLHost, PXB_CXL_HOST) typedef struct CXLUpstreamPort CXLUpstreamPort; DECLARE_INSTANCE_CHECKER(CXLUpstreamPort, CXL_USP, TYPE_CXL_USP) CXLComponentState *cxl_usp_to_cstate(CXLUpstreamPort *usp); + +#define TYPE_CXL_DSP "cxl-downstream" + +typedef struct CXLDownstreamPort CXLDownstreamPort; +DECLARE_INSTANCE_CHECKER(CXLDownstreamPort, CXL_DSP, TYPE_CXL_DSP) + #endif diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h index c355192b7c..52b6a2d67f 100644 --- a/include/hw/cxl/cxl_component.h +++ b/include/hw/cxl/cxl_component.h @@ -26,7 +26,8 @@ enum reg_type { CXL2_LOGICAL_DEVICE, CXL2_ROOT_PORT, CXL2_UPSTREAM_PORT, - CXL2_DOWNSTREAM_PORT + CXL2_DOWNSTREAM_PORT, + CXL3_SWITCH_MAILBOX_CCI, }; =20 /* diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index c49ff7e9b3..215383ba37 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -244,8 +244,10 @@ void cxl_device_register_block_init(Object *obj, CXLDe= viceState *dev, CXLCCI *cci); =20 typedef struct CXLType3Dev CXLType3Dev; +typedef struct CSWMBCCIDev CSWMBCCIDev; /* Set up default values for the register block */ void cxl_device_register_init_t3(CXLType3Dev *ct3d); +void cxl_device_register_init_swcci(CSWMBCCIDev *sw); =20 /* * CXL 2.0 - 8.2.8.1 including errata F4 @@ -292,6 +294,8 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE, CXL_DEVICE_CAP_REG_SIZE * 2) =20 void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload= _max); +void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf, + DeviceState *d, size_t payload_max); void cxl_init_cci(CXLCCI *cci, size_t payload_max); int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd, size_t len_in, uint8_t *pl_in, @@ -437,6 +441,17 @@ struct CXLType3Class { bool (*set_cacheline)(CXLType3Dev *ct3d, uint64_t dpa_offset, uint8_t = *data); }; =20 +struct CSWMBCCIDev { + PCIDevice parent_obj; + PCIDevice *target; + CXLComponentState cxl_cstate; + CXLDeviceState cxl_dstate; + CXLCCI *cci; +}; + +#define TYPE_CXL_SWITCH_MAILBOX_CCI "cxl-switch-mailbox-cci" +OBJECT_DECLARE_TYPE(CSWMBCCIDev, CSWMBCCIClass, CXL_SWITCH_MAILBOX_CCI) + MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data, unsigned size, MemTxAttrs attrs); MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data, diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bri= dge/cxl_upstream_port.h index 15db8c8582..7275102cfa 100644 --- a/include/hw/pci-bridge/cxl_upstream_port.h +++ b/include/hw/pci-bridge/cxl_upstream_port.h @@ -12,6 +12,7 @@ typedef struct CXLUpstreamPort { /*< public >*/ CXLComponentState cxl_cstate; CXLCCI mctpcci; + CXLCCI swcci; DOECap doe_cdat; uint64_t sn; } CXLUpstreamPort; diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c index 7dbc8b72d7..658321fa4a 100644 --- a/hw/cxl/cxl-device-utils.c +++ b/hw/cxl/cxl-device-utils.c @@ -64,6 +64,8 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr off= set, unsigned size) =20 if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) { cxl_dstate =3D &CXL_TYPE3(cci->intf)->cxl_dstate; + } else if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_SWITCH_MAIL= BOX_CCI)) { + cxl_dstate =3D &CXL_SWITCH_MAILBOX_CCI(cci->intf)->cxl_dstate; } else { return 0; } @@ -148,6 +150,8 @@ static void mailbox_reg_write(void *opaque, hwaddr offs= et, uint64_t value, =20 if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) { cxl_dstate =3D &CXL_TYPE3(cci->intf)->cxl_dstate; + } else if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_SWITCH_MAIL= BOX_CCI)) { + cxl_dstate =3D &CXL_SWITCH_MAILBOX_CCI(cci->intf)->cxl_dstate; } else { return; } @@ -361,6 +365,27 @@ void cxl_device_register_init_t3(CXLType3Dev *ct3d) CXL_MAILBOX_MAX_PAYLOAD_SIZE); } =20 +void cxl_device_register_init_swcci(CSWMBCCIDev *sw) +{ + CXLDeviceState *cxl_dstate =3D &sw->cxl_dstate; + uint64_t *cap_hdrs =3D cxl_dstate->caps_reg_state64; + const int cap_count =3D 3; + + /* CXL Device Capabilities Array Register */ + ARRAY_FIELD_DP64(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_ID, 0); + ARRAY_FIELD_DP64(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1); + ARRAY_FIELD_DP64(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_COUNT, cap_count); + + cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1, 2); + device_reg_init_common(cxl_dstate); + + cxl_device_cap_init(cxl_dstate, MAILBOX, 2, 1); + mailbox_reg_init_common(cxl_dstate); + + cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000, 1); + memdev_reg_init_common(cxl_dstate); +} + uint64_t cxl_device_get_timestamp(CXLDeviceState *cxl_dstate) { uint64_t time, delta; diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 2d3d19dce8..9c1020d9ab 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -47,6 +47,7 @@ enum { INFOSTAT =3D 0x00, #define IS_IDENTIFY 0x1 + #define BACKGROUND_OPERATION_STATUS 0x2 EVENTS =3D 0x01, #define GET_RECORDS 0x0 #define CLEAR_RECORDS 0x1 @@ -70,6 +71,8 @@ enum { #define GET_POISON_LIST 0x0 #define INJECT_POISON 0x1 #define CLEAR_POISON 0x2 + PHYSICAL_SWITCH =3D 0x51, + #define IDENTIFY_SWITCH_DEVICE 0x0 }; =20 =20 @@ -205,6 +208,7 @@ static CXLRetCode cmd_events_set_interrupt_policy(const= struct cxl_cmd *cmd, *len_out =3D 0; return CXL_MBOX_SUCCESS; } + /* CXL r3 8.2.9.1.1 */ static CXLRetCode cmd_infostat_identify(const struct cxl_cmd *cmd, uint8_t *payload_in, @@ -252,6 +256,97 @@ static CXLRetCode cmd_infostat_identify(const struct c= xl_cmd *cmd, return CXL_MBOX_SUCCESS; } =20 +static void cxl_set_dsp_active_bm(PCIBus *b, PCIDevice *d, + void *private) +{ + uint8_t *bm =3D private; + if (object_dynamic_cast(OBJECT(d), TYPE_CXL_DSP)) { + uint8_t port =3D PCIE_PORT(d)->port; + bm[port / 8] |=3D 1 << (port % 8); + } +} + +/* CXL r3 8.2.9.1.1 */ +static CXLRetCode cmd_identify_switch_device(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + PCIEPort *usp =3D PCIE_PORT(cci->d); + PCIBus *bus =3D &PCI_BRIDGE(cci->d)->sec_bus; + int num_phys_ports =3D pcie_count_ds_ports(bus); + + struct cxl_fmapi_ident_switch_dev_resp_pl { + uint8_t ingress_port_id; + uint8_t rsvd; + uint8_t num_physical_ports; + uint8_t num_vcss; + uint8_t active_port_bitmask[0x20]; + uint8_t active_vcs_bitmask[0x20]; + uint16_t total_vppbs; + uint16_t bound_vppbs; + uint8_t num_hdm_decoders_per_usp; + } QEMU_PACKED *out; + QEMU_BUILD_BUG_ON(sizeof(*out) !=3D 0x49); + + out =3D (struct cxl_fmapi_ident_switch_dev_resp_pl *)payload_out; + *out =3D (struct cxl_fmapi_ident_switch_dev_resp_pl) { + .num_physical_ports =3D num_phys_ports + 1, /* 1 USP */ + .num_vcss =3D 1, /* Not yet support multiple VCS - potentialy tric= ky */ + .active_vcs_bitmask[0] =3D 0x1, + .total_vppbs =3D num_phys_ports + 1, + .bound_vppbs =3D num_phys_ports + 1, + .num_hdm_decoders_per_usp =3D 4, + }; + + /* Depends on the CCI type */ + if (object_dynamic_cast(OBJECT(cci->intf), TYPE_PCIE_PORT)) { + out->ingress_port_id =3D PCIE_PORT(cci->intf)->port; + } else { + /* MCTP? */ + out->ingress_port_id =3D 0; + } + =20 + pci_for_each_device_under_bus(bus, cxl_set_dsp_active_bm, + out->active_port_bitmask); + out->active_port_bitmask[usp->port / 8] |=3D (1 << usp->port % 8); + + *len_out =3D sizeof(*out); + + return CXL_MBOX_SUCCESS; +} + +/* CXL r3.0 8.2.9.1.2 */ +static CXLRetCode cmd_infostat_bg_op_sts(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + struct { + uint8_t status; + uint8_t rsvd; + uint16_t opcode; + uint16_t returncode; + uint16_t vendor_ext_status; + } QEMU_PACKED *bg_op_status; + QEMU_BUILD_BUG_ON(sizeof(*bg_op_status) !=3D 8); + + bg_op_status =3D (void *)payload_out; + memset(bg_op_status, 0, sizeof(*bg_op_status)); + bg_op_status->status =3D cci->bg.complete_pct << 1; + if (cci->bg.runtime > 0) { + bg_op_status->status |=3D 1U << 0; + } + bg_op_status->opcode =3D cci->bg.opcode; + bg_op_status->returncode =3D cci->bg.ret_code; + *len_out =3D sizeof(*bg_op_status); + return CXL_MBOX_SUCCESS; +} + /* 8.2.9.2.1 */ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd, uint8_t *payload_in, @@ -796,6 +891,30 @@ static const struct cxl_cmd cxl_cmd_set[256][256] =3D { cmd_media_clear_poison, 72, 0 }, }; =20 +static const struct cxl_cmd cxl_cmd_set_sw[256][256] =3D { + [INFOSTAT][IS_IDENTIFY] =3D { "IDENTIFY", cmd_infostat_identify, 0, 18= }, + [INFOSTAT][BACKGROUND_OPERATION_STATUS] =3D { "BACKGROUND_OPERATION_ST= ATUS", + cmd_infostat_bg_op_sts, 0, 8 }, + /* + * TODO get / set response message limit - requires all messages over + * 256 bytes to support chunking. + */ + [TIMESTAMP][GET] =3D { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 }, + [TIMESTAMP][SET] =3D { "TIMESTAMP_SET", cmd_timestamp_set, 8, IMMEDIAT= E_POLICY_CHANGE }, + [LOGS][GET_SUPPORTED] =3D { "LOGS_GET_SUPPORTED", cmd_logs_get_support= ed, 0, 0 }, + [LOGS][GET_LOG] =3D { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 }, + [PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] =3D {"IDENTIFY_SWITCH_DEVICE= ", + cmd_identify_switch_device, 0, 0x49 }, +}; + +/* + * While the command is executing in the background, the device should + * update the percentage complete in the Background Command Status Register + * at least once per second. + */ + +#define CXL_MBOX_BG_UPDATE_FREQ 1000UL + int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd, size_t len_in, uint8_t *pl_in, size_t *len_out, uint8_t *pl_out, bool *bg_started) @@ -836,6 +955,14 @@ void cxl_init_cci(CXLCCI *cci, size_t payload_max) } } =20 +void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf, DeviceSt= ate *d, size_t payload_max) +{ + cci->cxl_cmd_set =3D cxl_cmd_set_sw; + cci->d =3D d; + cci->intf =3D intf; + cxl_init_cci(cci, payload_max); +} + void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload= _max) { cci->cxl_cmd_set =3D cxl_cmd_set; @@ -861,6 +988,8 @@ void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState= *d, DeviceState *intf, =20 static const struct cxl_cmd cxl_cmd_set_usp_mctp[256][256] =3D { [INFOSTAT][IS_IDENTIFY] =3D { "IDENTIFY", cmd_infostat_identify, 0, 18= }, + [PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] =3D {"IDENTIFY_SWITCH_DEVICE= ", + cmd_identify_switch_device, 0, 0x49 }, }; =20 void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *= intf, size_t payload_max) diff --git a/hw/cxl/switch-mailbox-cci.c b/hw/cxl/switch-mailbox-cci.c new file mode 100644 index 0000000000..278d979d80 --- /dev/null +++ b/hw/cxl/switch-mailbox-cci.c @@ -0,0 +1,98 @@ +#include "qemu/osdep.h" +#include "hw/pci/pci.h" +#include "hw/pci-bridge/cxl_upstream_port.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "hw/qdev-properties.h" +#include "hw/cxl/cxl.h" + +struct CSWMBCCIClass { + PCIDeviceClass parent_class; +}; + +static void cswmbcci_reset(DeviceState *dev) +{ + CSWMBCCIDev *cswmb =3D CXL_SWITCH_MAILBOX_CCI(dev); + cxl_device_register_init_swcci(cswmb); +} + +static void cswbcci_realize(PCIDevice *pci_dev, Error **errp) +{ + CSWMBCCIDev *cswmb =3D CXL_SWITCH_MAILBOX_CCI(pci_dev); + CXLComponentState *cxl_cstate =3D &cswmb->cxl_cstate; + CXLDeviceState *cxl_dstate =3D &cswmb->cxl_dstate; + CXLDVSECRegisterLocator *regloc_dvsec; + CXLUpstreamPort *usp; +=20 + if (!cswmb->target) { + error_setg(errp, "Target not set"); + return; + } + usp =3D CXL_USP(cswmb->target); + + pcie_endpoint_cap_init(pci_dev, 0x80); + cxl_cstate->dvsec_offset =3D 0x100; + cxl_cstate->pdev =3D pci_dev; + cswmb->cci =3D &usp->swcci; + cxl_device_register_block_init(OBJECT(pci_dev), cxl_dstate, cswmb->cci= ); + pci_register_bar(pci_dev, 0, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64, + &cxl_dstate->device_registers); + regloc_dvsec =3D &(CXLDVSECRegisterLocator) { + .rsvd =3D 0, + .reg_base[0].lo =3D RBI_CXL_DEVICE_REG | 0, + .reg_base[0].hi =3D 0, + }; + cxl_component_create_dvsec(cxl_cstate, CXL3_SWITCH_MAILBOX_CCI, + REG_LOC_DVSEC_LENGTH, REG_LOC_DVSEC, + REG_LOC_DVSEC_REVID, (uint8_t *)regloc_dvse= c); + + cxl_initialize_mailbox_swcci(cswmb->cci, DEVICE(pci_dev), DEVICE(cswmb= ->target), + CXL_MAILBOX_MAX_PAYLOAD_SIZE); +} + +static void cswmbcci_exit(PCIDevice *pci_dev) +{ +} + +static Property cxl_switch_cci_props[] =3D { + DEFINE_PROP_LINK("target", CSWMBCCIDev, + target, TYPE_CXL_USP, PCIDevice *), + DEFINE_PROP_END_OF_LIST(), +}; + +static void cswmbcci_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(oc); + PCIDeviceClass *pc =3D PCI_DEVICE_CLASS(oc); + + pc->realize =3D cswbcci_realize; + pc->exit =3D cswmbcci_exit; + pc->class_id =3D 0x0c0b; /* Serial bus, CXL Switch CCI */ + pc->vendor_id =3D 0x19e5; + pc->device_id =3D 0xbeef; /* FIXME - assign a valid ID for this functi= on */ + pc->revision =3D 0; + dc->desc =3D "CXL Switch Mailbox CCI"; + dc->reset =3D cswmbcci_reset; + device_class_set_props(dc, cxl_switch_cci_props); +} + +static const TypeInfo cswmbcci_info =3D { + .name =3D TYPE_CXL_SWITCH_MAILBOX_CCI, + .parent =3D TYPE_PCI_DEVICE, + .class_size =3D sizeof(struct CSWMBCCIClass), + .class_init =3D cswmbcci_class_init, + .instance_size =3D sizeof(CSWMBCCIDev), + .interfaces =3D (InterfaceInfo[]) { + { INTERFACE_PCIE_DEVICE }, + { } + }, +}; + +static void cxl_switch_mailbox_cci_register(void) +{ + type_register_static(&cswmbcci_info); +} +type_init(cxl_switch_mailbox_cci_register); diff --git a/hw/pci-bridge/cxl_downstream.c b/hw/pci-bridge/cxl_downstream.c index 7eb1981be3..573c583be4 100644 --- a/hw/pci-bridge/cxl_downstream.c +++ b/hw/pci-bridge/cxl_downstream.c @@ -13,7 +13,9 @@ #include "hw/pci/msi.h" #include "hw/pci/pcie.h" #include "hw/pci/pcie_port.h" +#include "hw/cxl/cxl.h" #include "qapi/error.h" +#include "hw/cxl/cxl.h" =20 typedef struct CXLDownstreamPort { /*< private >*/ @@ -23,9 +25,6 @@ typedef struct CXLDownstreamPort { CXLComponentState cxl_cstate; } CXLDownstreamPort; =20 -#define TYPE_CXL_DSP "cxl-downstream" -DECLARE_INSTANCE_CHECKER(CXLDownstreamPort, CXL_DSP, TYPE_CXL_DSP) - #define CXL_DOWNSTREAM_PORT_MSI_OFFSET 0x70 #define CXL_DOWNSTREAM_PORT_MSI_NR_VECTOR 1 #define CXL_DOWNSTREAM_PORT_EXP_OFFSET 0x90 diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build index 7a885e7b84..1393821fc4 100644 --- a/hw/cxl/meson.build +++ b/hw/cxl/meson.build @@ -7,6 +7,7 @@ system_ss.add(when: 'CONFIG_CXL', 'cxl-cdat.c', 'cxl-events.c', 'cxl-cpmu.c', + 'switch-mailbox-cci.c', ), if_false: files( 'cxl-host-stubs.c', --=20 2.39.2