hw/cxl: mailbox-utils: 0x5600 - FMAPI Get DCD Info

FM DCD Management command 0x5600 implemented per CXL 3.2 Spec Section 7.6.7.6.1.

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-3-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Anisa Su 2025-07-14 18:44:58 +01:00 committed by Michael S. Tsirkin
parent fe63feb7e8
commit 9fde6eb39d
3 changed files with 64 additions and 0 deletions

View file

@ -23,6 +23,7 @@
#include "qemu/uuid.h"
#include "system/hostmem.h"
#include "qemu/range.h"
#include "qapi/qapi-types-cxl.h"
#define CXL_CAPACITY_MULTIPLIER (256 * MiB)
#define CXL_DC_EVENT_LOG_SIZE 8
@ -117,6 +118,8 @@ enum {
#define GET_PHYSICAL_PORT_STATE 0x1
TUNNEL = 0x53,
#define MANAGEMENT_COMMAND 0x0
FMAPI_DCD_MGMT = 0x56,
#define GET_DCD_INFO 0x0
};
/* CCI Message Format CXL r3.1 Figure 7-19 */
@ -3237,6 +3240,52 @@ static CXLRetCode cmd_dcd_release_dyn_cap(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
/* CXL r3.2 section 7.6.7.6.1: Get DCD Info (Opcode 5600h) */
static CXLRetCode cmd_fm_get_dcd_info(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 num_hosts;
uint8_t num_regions_supported;
uint8_t rsvd1[2];
uint16_t supported_add_sel_policy_bitmask;
uint8_t rsvd2[2];
uint16_t supported_removal_policy_bitmask;
uint8_t sanitize_on_release_bitmask;
uint8_t rsvd3;
uint64_t total_dynamic_capacity;
uint64_t region_blk_size_bitmasks[8];
} QEMU_PACKED *out = (void *)payload_out;
CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
CXLDCRegion *region;
int i;
out->num_hosts = 1;
out->num_regions_supported = ct3d->dc.num_regions;
stw_le_p(&out->supported_add_sel_policy_bitmask,
BIT(CXL_EXTENT_SELECTION_POLICY_PRESCRIPTIVE));
stw_le_p(&out->supported_removal_policy_bitmask,
BIT(CXL_EXTENT_REMOVAL_POLICY_PRESCRIPTIVE));
out->sanitize_on_release_bitmask = 0;
stq_le_p(&out->total_dynamic_capacity,
ct3d->dc.total_capacity / CXL_CAPACITY_MULTIPLIER);
for (i = 0; i < ct3d->dc.num_regions; i++) {
region = &ct3d->dc.regions[i];
memcpy(&out->region_blk_size_bitmasks[i],
&region->supported_blk_size_bitmask,
sizeof(out->region_blk_size_bitmasks[i]));
}
*len_out = sizeof(*out);
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 },
@ -3350,6 +3399,11 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
cmd_tunnel_management_cmd, ~0, 0 },
};
static const struct cxl_cmd cxl_cmd_set_fm_dcd[256][256] = {
[FMAPI_DCD_MGMT][GET_DCD_INFO] = { "GET_DCD_INFO",
cmd_fm_get_dcd_info, 0, 0 },
};
/*
* While the command is executing in the background, the device should
* update the percentage complete in the Background Command Status Register
@ -3624,7 +3678,12 @@ void cxl_initialize_t3_fm_owned_ld_mctpcci(CXLCCI *cci, DeviceState *d,
DeviceState *intf,
size_t payload_max)
{
CXLType3Dev *ct3d = CXL_TYPE3(d);
cxl_copy_cci_commands(cci, cxl_cmd_set_t3_fm_owned_ld_mctp);
if (ct3d->dc.num_regions) {
cxl_copy_cci_commands(cci, cxl_cmd_set_fm_dcd);
}
cci->d = d;
cci->intf = intf;
cxl_init_cci(cci, payload_max);

View file

@ -8,6 +8,7 @@
*
* SPDX-License-Identifier: GPL-v2-only
*/
#include <math.h>
#include "qemu/osdep.h"
#include "qemu/units.h"
@ -634,6 +635,8 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)
uint64_t region_len;
uint64_t decode_len;
uint64_t blk_size = 2 * MiB;
/* Only 1 block size is supported for now. */
uint64_t supported_blk_size_bitmask = blk_size;
CXLDCRegion *region;
MemoryRegion *mr;
uint64_t dc_size;
@ -679,6 +682,7 @@ static bool cxl_create_dc_regions(CXLType3Dev *ct3d, Error **errp)
.block_size = blk_size,
/* dsmad_handle set when creating CDAT table entries */
.flags = 0,
.supported_blk_size_bitmask = supported_blk_size_bitmask,
};
ct3d->dc.total_capacity += region->len;
region->blk_bitmap = bitmap_new(region->len / region->block_size);

View file

@ -530,6 +530,7 @@ typedef struct CXLDCRegion {
uint32_t dsmadhandle;
uint8_t flags;
unsigned long *blk_bitmap;
uint64_t supported_blk_size_bitmask;
} CXLDCRegion;
typedef struct CXLSetFeatureInfo {