CXL spec 3.1 section 8.2.9.9.5.3 describes media operations commands. CXL devices supports media operations discovery command.
Signed-off-by: Vinayak Holikatti <vinayak...@samsung.com> --- hw/cxl/cxl-mailbox-utils.c | 130 ++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 9c7ea5bc35..2315d07fb1 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -87,8 +87,9 @@ enum { #define GET_LSA 0x2 #define SET_LSA 0x3 SANITIZE = 0x44, - #define OVERWRITE 0x0 - #define SECURE_ERASE 0x1 + #define OVERWRITE 0x0 + #define SECURE_ERASE 0x1 + #define MEDIA_OPERATIONS 0x2 PERSISTENT_MEM = 0x45, #define GET_SECURITY_STATE 0x0 MEDIA_AND_POISON = 0x43, @@ -1721,6 +1722,127 @@ static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd, return CXL_MBOX_BG_STARTED; } +enum { + MEDIA_OP_GENERAL = 0x0, + MEDIA_OP_SANITIZE = 0x1, + MEDIA_OP_CLASS_MAX, +} MEDIA_OPERATION_CLASS; + +enum { + MEDIA_OP_SUB_DISCOVERY = 0x0, + MEDIA_OP_SUB_SANITIZE = 0x0, + MEDIA_OP_SUB_ZERO = 0x1, + MEDIA_OP_SUB_CLASS_MAX +} MEDIA_OPERATION_SUB_CLASS; + +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[0]; +}; + +#define MAX_SUPPORTED_OPS 3 +struct media_op_supported_list_entry media_op_matrix[MAX_SUPPORTED_OPS] = { + {0, 0}, + {1, 0}, + {1, 1} }; + +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; + union { + struct { + uint64_t starting_dpa; + uint64_t length; + } dpa_range_list[0]; + struct { + uint16_t start_index; + uint16_t num_supported_ops; + } discovery_osa; + }; + } QEMU_PACKED *media_op_in_pl = (void *)payload_in; + + uint8_t media_op_cl = media_op_in_pl->media_operation_class; + uint8_t media_op_subclass = media_op_in_pl->media_operation_subclass; + uint32_t dpa_range_count = media_op_in_pl->dpa_range_count; + + if (len_in < sizeof(*media_op_in_pl)) { + return CXL_MBOX_INVALID_PAYLOAD_LENGTH; + } + + switch (media_op_cl) { + case MEDIA_OP_GENERAL: + switch (media_op_subclass) { + case MEDIA_OP_SUB_DISCOVERY: + int count = 0; + struct media_op_discovery_out_pl *media_out_pl = + (void *)payload_out; + int num_ops = media_op_in_pl->discovery_osa.num_supported_ops; + int start_index = media_op_in_pl->discovery_osa.start_index; + + /* As per spec CXL 3.1 8.2.9.9.5.3 dpa_range_count */ + /* should be zero for discovery sub class command */ + if (dpa_range_count) { + return CXL_MBOX_INVALID_INPUT; + } + + if ((start_index >= MEDIA_OP_CLASS_MAX) || + (num_ops > MAX_SUPPORTED_OPS)) { + return CXL_MBOX_INVALID_INPUT; + } + + media_out_pl->dpa_range_granularity = CXL_CAPACITY_MULTIPLIER; + media_out_pl->total_supported_operations = MAX_SUPPORTED_OPS; + if (num_ops > 0) { + for (int i = start_index; i < MAX_SUPPORTED_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) { + goto disc_out; + } + } + } +disc_out: + media_out_pl->num_of_supported_operations = count; + *len_out = sizeof(struct media_op_discovery_out_pl) + + (sizeof(struct media_op_supported_list_entry) * count); + break; + default: + return CXL_MBOX_UNSUPPORTED; + } + break; + case MEDIA_OP_SANITIZE: + switch (media_op_subclass) { + + default: + return CXL_MBOX_UNSUPPORTED; + } + break; + default: + return CXL_MBOX_UNSUPPORTED; + } + + return CXL_MBOX_SUCCESS; +} + static CXLRetCode cmd_get_security_state(const struct cxl_cmd *cmd, uint8_t *payload_in, size_t len_in, @@ -2864,6 +2986,10 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { CXL_MBOX_SECURITY_STATE_CHANGE | CXL_MBOX_BACKGROUND_OPERATION | 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", cmd_get_security_state, 0, 0 }, [MEDIA_AND_POISON][GET_POISON_LIST] = { "MEDIA_AND_POISON_GET_POISON_LIST", -- 2.34.1