|
@@ -754,58 +754,27 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
|
|
|
cmd_media_clear_poison, 72, 0 },
|
|
|
};
|
|
|
|
|
|
-void cxl_process_mailbox(CXLCCI *cci)
|
|
|
+int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
|
|
|
+ size_t len_in, uint8_t *pl_in, size_t *len_out,
|
|
|
+ uint8_t *pl_out, bool *bg_started)
|
|
|
{
|
|
|
- uint16_t ret = CXL_MBOX_SUCCESS;
|
|
|
const struct cxl_cmd *cxl_cmd;
|
|
|
- uint64_t status_reg = 0;
|
|
|
opcode_handler h;
|
|
|
- CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
|
|
|
- uint64_t command_reg = cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD];
|
|
|
-
|
|
|
- uint8_t set = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND_SET);
|
|
|
- uint8_t cmd = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND);
|
|
|
- uint16_t len_in = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, LENGTH);
|
|
|
- uint8_t *pl = cxl_dstate->mbox_reg_state + A_CXL_DEV_CMD_PAYLOAD;
|
|
|
- /*
|
|
|
- * Copy taken to avoid need for individual command handlers to care
|
|
|
- * about aliasing.
|
|
|
- */
|
|
|
- g_autofree uint8_t *pl_in_copy = NULL;
|
|
|
- size_t len_out = 0;
|
|
|
|
|
|
- pl_in_copy = g_memdup2(pl, len_in);
|
|
|
- /* Avoid stale data - including from earlier commands */
|
|
|
- memset(pl, 0, CXL_MAILBOX_MAX_PAYLOAD_SIZE);
|
|
|
+ *len_out = 0;
|
|
|
cxl_cmd = &cci->cxl_cmd_set[set][cmd];
|
|
|
h = cxl_cmd->handler;
|
|
|
- if (h) {
|
|
|
- if (len_in == cxl_cmd->in || cxl_cmd->in == ~0) {
|
|
|
- ret = (*h)(cxl_cmd, pl, len_in, pl, &len_out, cci);
|
|
|
- assert(len_out <= cci->payload_max);
|
|
|
- } else {
|
|
|
- ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
|
|
|
- }
|
|
|
- } else {
|
|
|
+ if (!h) {
|
|
|
qemu_log_mask(LOG_UNIMP, "Command %04xh not implemented\n",
|
|
|
set << 8 | cmd);
|
|
|
- ret = CXL_MBOX_UNSUPPORTED;
|
|
|
+ return CXL_MBOX_UNSUPPORTED;
|
|
|
}
|
|
|
|
|
|
- /* Set the return code */
|
|
|
- status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, ERRNO, ret);
|
|
|
-
|
|
|
- /* Set the return length */
|
|
|
- command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND_SET, 0);
|
|
|
- command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND, 0);
|
|
|
- command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD, LENGTH, len_out);
|
|
|
-
|
|
|
- cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD] = command_reg;
|
|
|
- cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_STS] = status_reg;
|
|
|
+ if (len_in != cxl_cmd->in && cxl_cmd->in != ~0) {
|
|
|
+ return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
|
|
|
+ }
|
|
|
|
|
|
- /* Tell the host we're done */
|
|
|
- ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
|
|
|
- DOORBELL, 0);
|
|
|
+ return (*h)(cxl_cmd, pl_in, len_in, pl_out, len_out, cci);
|
|
|
}
|
|
|
|
|
|
void cxl_init_cci(CXLCCI *cci, size_t payload_max)
|