aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnisa Su <anisa.su@samsung.com>2025-07-14 18:45:04 +0100
committerMichael S. Tsirkin <mst@redhat.com>2025-07-15 02:56:40 -0400
commit21af9a917eca69996891dcbb93edcb6c5c53e52c (patch)
tree563d90e5ecf8823bd124f94cd04ec2b0760a207c
parent1befc7bde30d2e09f20a44584aaefdfa31f60074 (diff)
downloadqemu-21af9a917eca69996891dcbb93edcb6c5c53e52c.zip
qemu-21af9a917eca69996891dcbb93edcb6c5c53e52c.tar.gz
qemu-21af9a917eca69996891dcbb93edcb6c5c53e52c.tar.bz2
hw/cxl: mailbox-utils: 0x5603 - FMAPI Get DC Region Extent Lists
FM DCD Management command 0x5603 implemented per CXL r3.2 Spec Section 7.6.7.6.4 Very similar to previously implemented command 0x4801. Reviewed-by: Fan Ni <fan.ni@samsung.com> Signed-off-by: Anisa Su <anisa.su@samsung.com> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Message-Id: <20250714174509.1984430-9-Jonathan.Cameron@huawei.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--hw/cxl/cxl-mailbox-utils.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index b4a0f7d..4b0fdbb 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -123,6 +123,7 @@ enum {
#define GET_DCD_INFO 0x0
#define GET_HOST_DC_REGION_CONFIG 0x1
#define SET_DC_REGION_CONFIG 0x2
+ #define GET_DC_REGION_EXTENT_LIST 0x3
};
/* CCI Message Format CXL r3.1 Figure 7-19 */
@@ -3470,6 +3471,79 @@ static CXLRetCode cmd_fm_set_dc_region_config(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+/* CXL r3.2 section 7.6.7.6.4: Get DC Region Extent Lists (Opcode 5603h) */
+static CXLRetCode cmd_fm_get_dc_region_extent_list(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ struct {
+ uint16_t host_id;
+ uint8_t rsvd[2];
+ uint32_t extent_cnt;
+ uint32_t start_extent_id;
+ } QEMU_PACKED *in = (void *)payload_in;
+ struct {
+ uint16_t host_id;
+ uint8_t rsvd[2];
+ uint32_t start_extent_id;
+ uint32_t extents_returned;
+ uint32_t total_extents;
+ uint32_t list_generation_num;
+ uint8_t rsvd2[4];
+ CXLDCExtentRaw records[];
+ } QEMU_PACKED *out = (void *)payload_out;
+ QEMU_BUILD_BUG_ON(sizeof(*in) != 0xc);
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+ CXLDCExtent *ent;
+ CXLDCExtentRaw *out_rec;
+ uint16_t record_count = 0, record_done = 0, i = 0;
+ uint16_t out_pl_len, max_size;
+
+ if (in->host_id != 0) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ if (in->start_extent_id > ct3d->dc.nr_extents_accepted) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ record_count = MIN(in->extent_cnt,
+ ct3d->dc.nr_extents_accepted - in->start_extent_id);
+ max_size = CXL_MAILBOX_MAX_PAYLOAD_SIZE - sizeof(*out);
+ record_count = MIN(record_count, max_size / sizeof(out->records[0]));
+ out_pl_len = sizeof(*out) + record_count * sizeof(out->records[0]);
+
+ stw_le_p(&out->host_id, in->host_id);
+ stl_le_p(&out->start_extent_id, in->start_extent_id);
+ stl_le_p(&out->extents_returned, record_count);
+ stl_le_p(&out->total_extents, ct3d->dc.nr_extents_accepted);
+ stl_le_p(&out->list_generation_num, ct3d->dc.ext_list_gen_seq);
+
+ if (record_count > 0) {
+ QTAILQ_FOREACH(ent, &ct3d->dc.extents, node) {
+ if (i++ < in->start_extent_id) {
+ continue;
+ }
+ out_rec = &out->records[record_done];
+ stq_le_p(&out_rec->start_dpa, ent->start_dpa);
+ stq_le_p(&out_rec->len, ent->len);
+ memcpy(&out_rec->tag, ent->tag, 0x10);
+ stw_le_p(&out_rec->shared_seq, ent->shared_seq);
+
+ record_done++;
+ if (record_done == record_count) {
+ break;
+ }
+ }
+ }
+
+ *len_out = out_pl_len;
+ return CXL_MBOX_SUCCESS;
+}
+
static const struct cxl_cmd cxl_cmd_set[256][256] = {
[INFOSTAT][BACKGROUND_OPERATION_ABORT] = { "BACKGROUND_OPERATION_ABORT",
cmd_infostat_bg_op_abort, 0, 0 },
@@ -3595,6 +3669,8 @@ static const struct cxl_cmd cxl_cmd_set_fm_dcd[256][256] = {
CXL_MBOX_CONFIG_CHANGE_CXL_RESET |
CXL_MBOX_IMMEDIATE_CONFIG_CHANGE |
CXL_MBOX_IMMEDIATE_DATA_CHANGE) },
+ [FMAPI_DCD_MGMT][GET_DC_REGION_EXTENT_LIST] = { "GET_DC_REGION_EXTENT_LIST",
+ cmd_fm_get_dc_region_extent_list, 12, 0 },
};
/*