Browse Source

hw/cxl/cxl-mailbox-utils: Add support for Media operations discovery commands cxl r3.2 (8.2.10.9.5.3)

CXL spec 3.2 section 8.2.10.9.5.3 describes media operations commands.
CXL devices supports media operations discovery command.

Signed-off-by: Vinayak Holikatti <vinayak.kh@samsung.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Message-Id: <20250305092501.191929-4-Jonathan.Cameron@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
pull/291/head
Vinayak Holikatti 1 year ago
committed by Michael S. Tsirkin
parent
commit
77a8e9fe0e
  1. 125
      hw/cxl/cxl-mailbox-utils.c

125
hw/cxl/cxl-mailbox-utils.c

@ -89,6 +89,7 @@ enum {
SANITIZE = 0x44, SANITIZE = 0x44,
#define OVERWRITE 0x0 #define OVERWRITE 0x0
#define SECURE_ERASE 0x1 #define SECURE_ERASE 0x1
#define MEDIA_OPERATIONS 0x2
PERSISTENT_MEM = 0x45, PERSISTENT_MEM = 0x45,
#define GET_SECURITY_STATE 0x0 #define GET_SECURITY_STATE 0x0
MEDIA_AND_POISON = 0x43, MEDIA_AND_POISON = 0x43,
@ -1705,6 +1706,126 @@ static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd,
return CXL_MBOX_BG_STARTED; return CXL_MBOX_BG_STARTED;
} }
enum {
MEDIA_OP_CLASS_GENERAL = 0x0,
#define MEDIA_OP_GEN_SUBC_DISCOVERY 0x0
MEDIA_OP_CLASS_SANITIZE = 0x1,
#define MEDIA_OP_SAN_SUBC_SANITIZE 0x0
#define MEDIA_OP_SAN_SUBC_ZERO 0x1
};
struct media_op_supported_list_entry {
uint8_t media_op_class;
uint8_t media_op_subclass;
};
struct media_op_discovery_out_pl {
uint64_t dpa_range_granularity;
uint16_t total_supported_operations;
uint16_t num_of_supported_operations;
struct media_op_supported_list_entry entry[];
} QEMU_PACKED;
static const struct media_op_supported_list_entry media_op_matrix[] = {
{ MEDIA_OP_CLASS_GENERAL, MEDIA_OP_GEN_SUBC_DISCOVERY },
{ MEDIA_OP_CLASS_SANITIZE, MEDIA_OP_SAN_SUBC_SANITIZE },
{ MEDIA_OP_CLASS_SANITIZE, MEDIA_OP_SAN_SUBC_ZERO },
};
static CXLRetCode media_operations_discovery(uint8_t *payload_in,
size_t len_in,
uint8_t *payload_out,
size_t *len_out)
{
struct {
uint8_t media_operation_class;
uint8_t media_operation_subclass;
uint8_t rsvd[2];
uint32_t dpa_range_count;
struct {
uint16_t start_index;
uint16_t num_ops;
} discovery_osa;
} QEMU_PACKED *media_op_in_disc_pl = (void *)payload_in;
struct media_op_discovery_out_pl *media_out_pl =
(struct media_op_discovery_out_pl *)payload_out;
int num_ops, start_index, i;
int count = 0;
if (len_in < sizeof(*media_op_in_disc_pl)) {
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
num_ops = media_op_in_disc_pl->discovery_osa.num_ops;
start_index = media_op_in_disc_pl->discovery_osa.start_index;
/*
* As per spec CXL r3.2 8.2.10.9.5.3 dpa_range_count should be zero and
* start index should not exceed the total number of entries for discovery
* sub class command.
*/
if (media_op_in_disc_pl->dpa_range_count ||
start_index > ARRAY_SIZE(media_op_matrix)) {
return CXL_MBOX_INVALID_INPUT;
}
media_out_pl->dpa_range_granularity = CXL_CACHE_LINE_SIZE;
media_out_pl->total_supported_operations =
ARRAY_SIZE(media_op_matrix);
if (num_ops > 0) {
for (i = start_index; i < start_index + num_ops; i++) {
media_out_pl->entry[count].media_op_class =
media_op_matrix[i].media_op_class;
media_out_pl->entry[count].media_op_subclass =
media_op_matrix[i].media_op_subclass;
count++;
if (count == num_ops) {
break;
}
}
}
media_out_pl->num_of_supported_operations = count;
*len_out = sizeof(*media_out_pl) + count * sizeof(*media_out_pl->entry);
return CXL_MBOX_SUCCESS;
}
static CXLRetCode cmd_media_operations(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 media_operation_class;
uint8_t media_operation_subclass;
uint8_t rsvd[2];
uint32_t dpa_range_count;
} QEMU_PACKED *media_op_in_common_pl = (void *)payload_in;
uint8_t media_op_cl = 0;
uint8_t media_op_subclass = 0;
if (len_in < sizeof(*media_op_in_common_pl)) {
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
media_op_cl = media_op_in_common_pl->media_operation_class;
media_op_subclass = media_op_in_common_pl->media_operation_subclass;
switch (media_op_cl) {
case MEDIA_OP_CLASS_GENERAL:
if (media_op_subclass != MEDIA_OP_GEN_SUBC_DISCOVERY) {
return CXL_MBOX_UNSUPPORTED;
}
return media_operations_discovery(payload_in, len_in, payload_out,
len_out);
default:
return CXL_MBOX_UNSUPPORTED;
}
}
static CXLRetCode cmd_get_security_state(const struct cxl_cmd *cmd, static CXLRetCode cmd_get_security_state(const struct cxl_cmd *cmd,
uint8_t *payload_in, uint8_t *payload_in,
size_t len_in, size_t len_in,
@ -2850,6 +2971,10 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
CXL_MBOX_SECURITY_STATE_CHANGE | CXL_MBOX_SECURITY_STATE_CHANGE |
CXL_MBOX_BACKGROUND_OPERATION | CXL_MBOX_BACKGROUND_OPERATION |
CXL_MBOX_BACKGROUND_OPERATION_ABORT)}, CXL_MBOX_BACKGROUND_OPERATION_ABORT)},
[SANITIZE][MEDIA_OPERATIONS] = { "MEDIA_OPERATIONS", cmd_media_operations,
~0,
(CXL_MBOX_IMMEDIATE_DATA_CHANGE |
CXL_MBOX_BACKGROUND_OPERATION)},
[PERSISTENT_MEM][GET_SECURITY_STATE] = { "GET_SECURITY_STATE", [PERSISTENT_MEM][GET_SECURITY_STATE] = { "GET_SECURITY_STATE",
cmd_get_security_state, 0, 0 }, cmd_get_security_state, 0, 0 },
[MEDIA_AND_POISON][GET_POISON_LIST] = { "MEDIA_AND_POISON_GET_POISON_LIST", [MEDIA_AND_POISON][GET_POISON_LIST] = { "MEDIA_AND_POISON_GET_POISON_LIST",

Loading…
Cancel
Save