diff options
author | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2023-10-23 17:07:57 +0100 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2023-11-07 03:39:11 -0500 |
commit | 3314efd276ada18cc0b8beb70b8943f8deb872b7 (patch) | |
tree | 973b50a03aa62b42b754278a3de5a496b75b0609 /hw/cxl | |
parent | 6cf416c176f11bc093fcc1818d6c9a95136f4c59 (diff) | |
download | qemu-3314efd276ada18cc0b8beb70b8943f8deb872b7.zip qemu-3314efd276ada18cc0b8beb70b8943f8deb872b7.tar.gz qemu-3314efd276ada18cc0b8beb70b8943f8deb872b7.tar.bz2 |
hw/cxl/mbox: Add Physical Switch Identify command.
Enable it for the switch CCI.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20231023160806.13206-9-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/cxl')
-rw-r--r-- | hw/cxl/cxl-mailbox-utils.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 6741698..6ada49d 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -70,6 +70,8 @@ enum { #define GET_POISON_LIST 0x0 #define INJECT_POISON 0x1 #define CLEAR_POISON 0x2 + PHYSICAL_SWITCH = 0x51, + #define IDENTIFY_SWITCH_DEVICE 0x0 }; @@ -257,6 +259,67 @@ static CXLRetCode cmd_infostat_identify(const struct cxl_cmd *cmd, return CXL_MBOX_SUCCESS; } +static void cxl_set_dsp_active_bm(PCIBus *b, PCIDevice *d, + void *private) +{ + uint8_t *bm = private; + if (object_dynamic_cast(OBJECT(d), TYPE_CXL_DSP)) { + uint8_t port = PCIE_PORT(d)->port; + bm[port / 8] |= 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 = PCIE_PORT(cci->d); + PCIBus *bus = &PCI_BRIDGE(cci->d)->sec_bus; + int num_phys_ports = 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) != 0x49); + + out = (struct cxl_fmapi_ident_switch_dev_resp_pl *)payload_out; + *out = (struct cxl_fmapi_ident_switch_dev_resp_pl) { + .num_physical_ports = num_phys_ports + 1, /* 1 USP */ + .num_vcss = 1, /* Not yet support multiple VCS - potentialy tricky */ + .active_vcs_bitmask[0] = 0x1, + .total_vppbs = num_phys_ports + 1, + .bound_vppbs = num_phys_ports + 1, + .num_hdm_decoders_per_usp = 4, + }; + + /* Depends on the CCI type */ + if (object_dynamic_cast(OBJECT(cci->intf), TYPE_PCIE_PORT)) { + out->ingress_port_id = PCIE_PORT(cci->intf)->port; + } else { + /* MCTP? */ + out->ingress_port_id = 0; + } + + pci_for_each_device_under_bus(bus, cxl_set_dsp_active_bm, + out->active_port_bitmask); + out->active_port_bitmask[usp->port / 8] |= (1 << usp->port % 8); + + *len_out = sizeof(*out); + + 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, @@ -816,6 +879,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = { [LOGS][GET_SUPPORTED] = { "LOGS_GET_SUPPORTED", cmd_logs_get_supported, 0, 0 }, [LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 }, + [PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] = { "IDENTIFY_SWITCH_DEVICE", + cmd_identify_switch_device, 0, 0 }, }; int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd, |