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>
This commit is contained in:
parent
1000158f03
commit
77a8e9fe0e
1 changed files with 125 additions and 0 deletions
|
|
@ -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…
Add table
Add a link
Reference in a new issue