From 6cf416c176f11bc093fcc1818d6c9a95136f4c59 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 23 Oct 2023 17:07:56 +0100 Subject: hw/cxl/mbox: Add Information and Status / Identify command Add this command that is only available via out of band CCIs. It replicates information that can be discovered inband via PCI config space. Signed-off-by: Jonathan Cameron Message-Id: <20231023160806.13206-8-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/cxl/cxl-mailbox-utils.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 28ea02f..6741698 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -11,6 +11,7 @@ #include "hw/cxl/cxl.h" #include "hw/cxl/cxl_events.h" #include "hw/pci/pci.h" +#include "hw/pci-bridge/cxl_upstream_port.h" #include "qemu/cutils.h" #include "qemu/log.h" #include "qemu/units.h" @@ -44,6 +45,8 @@ */ enum { + INFOSTAT = 0x00, + #define IS_IDENTIFY 0x1 EVENTS = 0x01, #define GET_RECORDS 0x0 #define CLEAR_RECORDS 0x1 @@ -203,6 +206,57 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd, return CXL_MBOX_SUCCESS; } +/* CXL r3.0 section 8.2.9.1.1: Identify (Opcode 0001h) */ +static CXLRetCode cmd_infostat_identify(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + PCIDeviceClass *class = PCI_DEVICE_GET_CLASS(cci->d); + struct { + uint16_t pcie_vid; + uint16_t pcie_did; + uint16_t pcie_subsys_vid; + uint16_t pcie_subsys_id; + uint64_t sn; + uint8_t max_message_size; + uint8_t component_type; + } QEMU_PACKED *is_identify; + QEMU_BUILD_BUG_ON(sizeof(*is_identify) != 18); + + is_identify = (void *)payload_out; + memset(is_identify, 0, sizeof(*is_identify)); + is_identify->pcie_vid = class->vendor_id; + is_identify->pcie_did = class->device_id; + if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_USP)) { + is_identify->sn = CXL_USP(cci->d)->sn; + /* Subsystem info not defined for a USP */ + is_identify->pcie_subsys_vid = 0; + is_identify->pcie_subsys_id = 0; + is_identify->component_type = 0x0; /* Switch */ + } else if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_TYPE3)) { + PCIDevice *pci_dev = PCI_DEVICE(cci->d); + + is_identify->sn = CXL_TYPE3(cci->d)->sn; + /* + * We can't always use class->subsystem_vendor_id as + * it is not set if the defaults are used. + */ + is_identify->pcie_subsys_vid = + pci_get_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID); + is_identify->pcie_subsys_id = + pci_get_word(pci_dev->config + PCI_SUBSYSTEM_ID); + is_identify->component_type = 0x3; /* Type 3 */ + } + + /* TODO: Allow this to vary across different CCIs */ + is_identify->max_message_size = 9; /* 512 bytes - MCTP_CXL_MAILBOX_BYTES */ + *len_out = sizeof(*is_identify); + 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, @@ -755,6 +809,7 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { }; static const struct cxl_cmd cxl_cmd_set_sw[256][256] = { + [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 0 }, [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 }, [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 0, IMMEDIATE_POLICY_CHANGE }, -- cgit v1.1