Skip to content

Commit

Permalink
hw/cxl/mbox: Add Information and Status / Identify command
Browse files Browse the repository at this point in the history
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 <Jonathan.Cameron@huawei.com>

Message-Id: <20231023160806.13206-8-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
  • Loading branch information
jic23 authored and mstsirkin committed Nov 7, 2023
1 parent 4a58330 commit 6cf416c
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions hw/cxl/cxl-mailbox-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -44,6 +45,8 @@
*/

enum {
INFOSTAT = 0x00,
#define IS_IDENTIFY 0x1
EVENTS = 0x01,
#define GET_RECORDS 0x0
#define CLEAR_RECORDS 0x1
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 },
Expand Down

0 comments on commit 6cf416c

Please sign in to comment.