* [PATCH 01/19] hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances constant
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-27 19:27 ` Fan Ni
2023-09-25 16:11 ` [PATCH 02/19] hw/cxl/mbox: Split mailbox command payload into separate input and output Jonathan Cameron via
` (19 subsequent siblings)
20 siblings, 1 reply; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Putting the pointer in the structure for command handling puts a single
variable element inside an otherwise constant structure. Move it out as
a directly passed variable and take the cxl_cmd structures constant.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl_device.h | 13 ++++
hw/cxl/cxl-mailbox-utils.c | 121 +++++++++++++++++++-----------------
2 files changed, 78 insertions(+), 56 deletions(-)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 007ddaf078..556953469c 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -111,6 +111,18 @@ typedef enum {
CXL_MBOX_MAX = 0x17
} CXLRetCode;
+typedef struct cxl_device_state CXLDeviceState;
+struct cxl_cmd;
+typedef CXLRetCode (*opcode_handler)(const struct cxl_cmd *cmd,
+ uint8_t *payload,
+ CXLDeviceState *cxl_dstate, uint16_t *len);
+struct cxl_cmd {
+ const char *name;
+ opcode_handler handler;
+ ssize_t in;
+ uint16_t effect; /* Reported in CEL */
+};
+
typedef struct CXLEvent {
CXLEventRecordRaw data;
QSIMPLEQ_ENTRY(CXLEvent) node;
@@ -178,6 +190,7 @@ typedef struct cxl_device_state {
uint64_t pmem_size;
uint64_t vmem_size;
+ const struct cxl_cmd (*cxl_cmd_set)[256];
CXLEventLog event_logs[CXL_EVENT_TYPE_MAX];
} CXLDeviceState;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index ab082ec9de..c02de06943 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -69,18 +69,9 @@ enum {
#define CLEAR_POISON 0x2
};
-struct cxl_cmd;
-typedef CXLRetCode (*opcode_handler)(struct cxl_cmd *cmd,
- CXLDeviceState *cxl_dstate, uint16_t *len);
-struct cxl_cmd {
- const char *name;
- opcode_handler handler;
- ssize_t in;
- uint16_t effect; /* Reported in CEL */
- uint8_t *payload;
-};
-static CXLRetCode cmd_events_get_records(struct cxl_cmd *cmd,
+static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxlds,
uint16_t *len)
{
@@ -92,9 +83,9 @@ static CXLRetCode cmd_events_get_records(struct cxl_cmd *cmd,
return CXL_MBOX_INVALID_INPUT;
}
- log_type = *((uint8_t *)cmd->payload);
+ log_type = payload[0];
- pl = (CXLGetEventPayload *)cmd->payload;
+ pl = (CXLGetEventPayload *)payload;
memset(pl, 0, sizeof(*pl));
max_recs = (cxlds->payload_size - CXL_EVENT_PAYLOAD_HDR_SIZE) /
@@ -106,25 +97,27 @@ static CXLRetCode cmd_events_get_records(struct cxl_cmd *cmd,
return cxl_event_get_records(cxlds, pl, log_type, max_recs, len);
}
-static CXLRetCode cmd_events_clear_records(struct cxl_cmd *cmd,
+static CXLRetCode cmd_events_clear_records(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxlds,
uint16_t *len)
{
CXLClearEventPayload *pl;
- pl = (CXLClearEventPayload *)cmd->payload;
+ pl = (CXLClearEventPayload *)payload;
*len = 0;
return cxl_event_clear_records(cxlds, pl);
}
-static CXLRetCode cmd_events_get_interrupt_policy(struct cxl_cmd *cmd,
+static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxlds,
uint16_t *len)
{
CXLEventInterruptPolicy *policy;
CXLEventLog *log;
- policy = (CXLEventInterruptPolicy *)cmd->payload;
+ policy = (CXLEventInterruptPolicy *)payload;
memset(policy, 0, sizeof(*policy));
log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
@@ -157,7 +150,8 @@ static CXLRetCode cmd_events_get_interrupt_policy(struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
-static CXLRetCode cmd_events_set_interrupt_policy(struct cxl_cmd *cmd,
+static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxlds,
uint16_t *len)
{
@@ -168,7 +162,7 @@ static CXLRetCode cmd_events_set_interrupt_policy(struct cxl_cmd *cmd,
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
- policy = (CXLEventInterruptPolicy *)cmd->payload;
+ policy = (CXLEventInterruptPolicy *)payload;
log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
log->irq_enabled = (policy->info_settings & CXL_EVENT_INT_MODE_MASK) ==
@@ -200,7 +194,8 @@ static CXLRetCode cmd_events_set_interrupt_policy(struct cxl_cmd *cmd,
}
/* 8.2.9.2.1 */
-static CXLRetCode cmd_firmware_update_get_info(struct cxl_cmd *cmd,
+static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -221,7 +216,7 @@ static CXLRetCode cmd_firmware_update_get_info(struct cxl_cmd *cmd,
return CXL_MBOX_INTERNAL_ERROR;
}
- fw_info = (void *)cmd->payload;
+ fw_info = (void *)payload;
memset(fw_info, 0, sizeof(*fw_info));
fw_info->slots_supported = 2;
@@ -234,27 +229,29 @@ static CXLRetCode cmd_firmware_update_get_info(struct cxl_cmd *cmd,
}
/* 8.2.9.3.1 */
-static CXLRetCode cmd_timestamp_get(struct cxl_cmd *cmd,
+static CXLRetCode cmd_timestamp_get(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
uint64_t final_time = cxl_device_get_timestamp(cxl_dstate);
- stq_le_p(cmd->payload, final_time);
+ stq_le_p(payload, final_time);
*len = 8;
return CXL_MBOX_SUCCESS;
}
/* 8.2.9.3.2 */
-static CXLRetCode cmd_timestamp_set(struct cxl_cmd *cmd,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+static CXLRetCode cmd_timestamp_set(const struct cxl_cmd *cmd,
+ uint8_t *payload,
+ CXLDeviceState *cxl_dstate,
+ uint16_t *len)
{
cxl_dstate->timestamp.set = true;
cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)cmd->payload);
+ cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)payload);
*len = 0;
return CXL_MBOX_SUCCESS;
@@ -267,7 +264,8 @@ static const QemuUUID cel_uuid = {
};
/* 8.2.9.4.1 */
-static CXLRetCode cmd_logs_get_supported(struct cxl_cmd *cmd,
+static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -278,7 +276,7 @@ static CXLRetCode cmd_logs_get_supported(struct cxl_cmd *cmd,
QemuUUID uuid;
uint32_t size;
} log_entries[1];
- } QEMU_PACKED *supported_logs = (void *)cmd->payload;
+ } QEMU_PACKED *supported_logs = (void *)payload;
QEMU_BUILD_BUG_ON(sizeof(*supported_logs) != 0x1c);
supported_logs->entries = 1;
@@ -290,7 +288,8 @@ static CXLRetCode cmd_logs_get_supported(struct cxl_cmd *cmd,
}
/* 8.2.9.4.2 */
-static CXLRetCode cmd_logs_get_log(struct cxl_cmd *cmd,
+static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -298,7 +297,9 @@ static CXLRetCode cmd_logs_get_log(struct cxl_cmd *cmd,
QemuUUID uuid;
uint32_t offset;
uint32_t length;
- } QEMU_PACKED QEMU_ALIGNED(16) *get_log = (void *)cmd->payload;
+ } QEMU_PACKED QEMU_ALIGNED(16) *get_log;
+
+ get_log = (void *)payload;
/*
* 8.2.9.4.2
@@ -324,14 +325,15 @@ static CXLRetCode cmd_logs_get_log(struct cxl_cmd *cmd,
/* Store off everything to local variables so we can wipe out the payload */
*len = get_log->length;
- memmove(cmd->payload, cxl_dstate->cel_log + get_log->offset,
+ memmove(payload, cxl_dstate->cel_log + get_log->offset,
get_log->length);
return CXL_MBOX_SUCCESS;
}
/* 8.2.9.5.1.1 */
-static CXLRetCode cmd_identify_memory_device(struct cxl_cmd *cmd,
+static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -361,7 +363,7 @@ static CXLRetCode cmd_identify_memory_device(struct cxl_cmd *cmd,
return CXL_MBOX_INTERNAL_ERROR;
}
- id = (void *)cmd->payload;
+ id = (void *)payload;
memset(id, 0, sizeof(*id));
snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0);
@@ -382,7 +384,8 @@ static CXLRetCode cmd_identify_memory_device(struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
-static CXLRetCode cmd_ccls_get_partition_info(struct cxl_cmd *cmd,
+static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -391,7 +394,7 @@ static CXLRetCode cmd_ccls_get_partition_info(struct cxl_cmd *cmd,
uint64_t active_pmem;
uint64_t next_vmem;
uint64_t next_pmem;
- } QEMU_PACKED *part_info = (void *)cmd->payload;
+ } QEMU_PACKED *part_info = (void *)payload;
QEMU_BUILD_BUG_ON(sizeof(*part_info) != 0x20);
if ((!QEMU_IS_ALIGNED(cxl_dstate->vmem_size, CXL_CAPACITY_MULTIPLIER)) ||
@@ -414,7 +417,8 @@ static CXLRetCode cmd_ccls_get_partition_info(struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
-static CXLRetCode cmd_ccls_get_lsa(struct cxl_cmd *cmd,
+static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -426,7 +430,7 @@ static CXLRetCode cmd_ccls_get_lsa(struct cxl_cmd *cmd,
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
uint32_t offset, length;
- get_lsa = (void *)cmd->payload;
+ get_lsa = (void *)payload;
offset = get_lsa->offset;
length = get_lsa->length;
@@ -439,7 +443,8 @@ static CXLRetCode cmd_ccls_get_lsa(struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
-static CXLRetCode cmd_ccls_set_lsa(struct cxl_cmd *cmd,
+static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -448,7 +453,7 @@ static CXLRetCode cmd_ccls_set_lsa(struct cxl_cmd *cmd,
uint32_t rsvd;
uint8_t data[];
} QEMU_PACKED;
- struct set_lsa_pl *set_lsa_payload = (void *)cmd->payload;
+ struct set_lsa_pl *set_lsa_payload = (void *)payload;
CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
const size_t hdr_len = offsetof(struct set_lsa_pl, data);
@@ -474,7 +479,8 @@ static CXLRetCode cmd_ccls_set_lsa(struct cxl_cmd *cmd,
* make this stateful. We may want to allow longer poison lists to aid
* testing that kernel functionality.
*/
-static CXLRetCode cmd_media_get_poison_list(struct cxl_cmd *cmd,
+static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len)
{
@@ -496,8 +502,8 @@ static CXLRetCode cmd_media_get_poison_list(struct cxl_cmd *cmd,
} QEMU_PACKED records[];
} QEMU_PACKED;
- struct get_poison_list_pl *in = (void *)cmd->payload;
- struct get_poison_list_out_pl *out = (void *)cmd->payload;
+ struct get_poison_list_pl *in = (void *)payload;
+ struct get_poison_list_out_pl *out = (void *)payload;
CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
uint16_t record_count = 0, i = 0;
uint64_t query_start, query_length;
@@ -550,7 +556,8 @@ static CXLRetCode cmd_media_get_poison_list(struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
-static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
+static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len_unused)
{
@@ -560,7 +567,7 @@ static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
struct inject_poison_pl {
uint64_t dpa;
};
- struct inject_poison_pl *in = (void *)cmd->payload;
+ struct inject_poison_pl *in = (void *)payload;
uint64_t dpa = ldq_le_p(&in->dpa);
CXLPoison *p;
@@ -589,7 +596,8 @@ static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
-static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
+static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
+ uint8_t *payload,
CXLDeviceState *cxl_dstate,
uint16_t *len_unused)
{
@@ -603,7 +611,7 @@ static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
CXLPoison *ent;
uint64_t dpa;
- struct clear_poison_pl *in = (void *)cmd->payload;
+ struct clear_poison_pl *in = (void *)payload;
dpa = ldq_le_p(&in->dpa);
if (dpa + CXL_CACHE_LINE_SIZE > cxl_dstate->mem_size) {
@@ -673,7 +681,7 @@ static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
#define IMMEDIATE_POLICY_CHANGE (1 << 3)
#define IMMEDIATE_LOG_CHANGE (1 << 4)
-static struct cxl_cmd cxl_cmd_set[256][256] = {
+static const struct cxl_cmd cxl_cmd_set[256][256] = {
[EVENTS][GET_RECORDS] = { "EVENTS_GET_RECORDS",
cmd_events_get_records, 1, 0 },
[EVENTS][CLEAR_RECORDS] = { "EVENTS_CLEAR_RECORDS",
@@ -709,21 +717,21 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
{
uint16_t ret = CXL_MBOX_SUCCESS;
- struct cxl_cmd *cxl_cmd;
- uint64_t status_reg;
+ const struct cxl_cmd *cxl_cmd;
+ uint64_t status_reg = 0;
opcode_handler h;
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 = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, LENGTH);
- cxl_cmd = &cxl_cmd_set[set][cmd];
+ uint8_t *pl = cxl_dstate->mbox_reg_state + A_CXL_DEV_CMD_PAYLOAD;
+
+ cxl_cmd = &cxl_dstate->cxl_cmd_set[set][cmd];
h = cxl_cmd->handler;
if (h) {
if (len == cxl_cmd->in || cxl_cmd->in == ~0) {
- cxl_cmd->payload = cxl_dstate->mbox_reg_state +
- A_CXL_DEV_CMD_PAYLOAD;
- ret = (*h)(cxl_cmd, cxl_dstate, &len);
+ ret = (*h)(cxl_cmd, pl, cxl_dstate, &len);
assert(len <= cxl_dstate->payload_size);
} else {
ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
@@ -752,10 +760,11 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate)
{
+ cxl_dstate->cxl_cmd_set = cxl_cmd_set;
for (int set = 0; set < 256; set++) {
for (int cmd = 0; cmd < 256; cmd++) {
- if (cxl_cmd_set[set][cmd].handler) {
- struct cxl_cmd *c = &cxl_cmd_set[set][cmd];
+ if (cxl_dstate->cxl_cmd_set[set][cmd].handler) {
+ const struct cxl_cmd *c = &cxl_dstate->cxl_cmd_set[set][cmd];
struct cel_log *log =
&cxl_dstate->cel_log[cxl_dstate->cel_size];
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 01/19] hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances constant
2023-09-25 16:11 ` [PATCH 01/19] hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances constant Jonathan Cameron via
@ 2023-09-27 19:27 ` Fan Ni
0 siblings, 0 replies; 32+ messages in thread
From: Fan Ni @ 2023-09-27 19:27 UTC (permalink / raw)
To: Jonathan Cameron
Cc: qemu-devel@nongnu.org, linux-cxl@vger.kernel.org, Michael Tsirkin,
linuxarm@huawei.com, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, Sep 25, 2023 at 05:11:06PM +0100, Jonathan Cameron wrote:
> Putting the pointer in the structure for command handling puts a single
> variable element inside an otherwise constant structure. Move it out as
> a directly passed variable and take the cxl_cmd structures constant.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
Reviewed-by: Fan Ni <fan.ni@samsung.com>
> include/hw/cxl/cxl_device.h | 13 ++++
> hw/cxl/cxl-mailbox-utils.c | 121 +++++++++++++++++++-----------------
> 2 files changed, 78 insertions(+), 56 deletions(-)
>
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index 007ddaf078..556953469c 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -111,6 +111,18 @@ typedef enum {
> CXL_MBOX_MAX = 0x17
> } CXLRetCode;
>
> +typedef struct cxl_device_state CXLDeviceState;
> +struct cxl_cmd;
> +typedef CXLRetCode (*opcode_handler)(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> + CXLDeviceState *cxl_dstate, uint16_t *len);
> +struct cxl_cmd {
> + const char *name;
> + opcode_handler handler;
> + ssize_t in;
> + uint16_t effect; /* Reported in CEL */
> +};
> +
> typedef struct CXLEvent {
> CXLEventRecordRaw data;
> QSIMPLEQ_ENTRY(CXLEvent) node;
> @@ -178,6 +190,7 @@ typedef struct cxl_device_state {
> uint64_t pmem_size;
> uint64_t vmem_size;
>
> + const struct cxl_cmd (*cxl_cmd_set)[256];
> CXLEventLog event_logs[CXL_EVENT_TYPE_MAX];
> } CXLDeviceState;
>
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index ab082ec9de..c02de06943 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -69,18 +69,9 @@ enum {
> #define CLEAR_POISON 0x2
> };
>
> -struct cxl_cmd;
> -typedef CXLRetCode (*opcode_handler)(struct cxl_cmd *cmd,
> - CXLDeviceState *cxl_dstate, uint16_t *len);
> -struct cxl_cmd {
> - const char *name;
> - opcode_handler handler;
> - ssize_t in;
> - uint16_t effect; /* Reported in CEL */
> - uint8_t *payload;
> -};
>
> -static CXLRetCode cmd_events_get_records(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxlds,
> uint16_t *len)
> {
> @@ -92,9 +83,9 @@ static CXLRetCode cmd_events_get_records(struct cxl_cmd *cmd,
> return CXL_MBOX_INVALID_INPUT;
> }
>
> - log_type = *((uint8_t *)cmd->payload);
> + log_type = payload[0];
>
> - pl = (CXLGetEventPayload *)cmd->payload;
> + pl = (CXLGetEventPayload *)payload;
> memset(pl, 0, sizeof(*pl));
>
> max_recs = (cxlds->payload_size - CXL_EVENT_PAYLOAD_HDR_SIZE) /
> @@ -106,25 +97,27 @@ static CXLRetCode cmd_events_get_records(struct cxl_cmd *cmd,
> return cxl_event_get_records(cxlds, pl, log_type, max_recs, len);
> }
>
> -static CXLRetCode cmd_events_clear_records(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_events_clear_records(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxlds,
> uint16_t *len)
> {
> CXLClearEventPayload *pl;
>
> - pl = (CXLClearEventPayload *)cmd->payload;
> + pl = (CXLClearEventPayload *)payload;
> *len = 0;
> return cxl_event_clear_records(cxlds, pl);
> }
>
> -static CXLRetCode cmd_events_get_interrupt_policy(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxlds,
> uint16_t *len)
> {
> CXLEventInterruptPolicy *policy;
> CXLEventLog *log;
>
> - policy = (CXLEventInterruptPolicy *)cmd->payload;
> + policy = (CXLEventInterruptPolicy *)payload;
> memset(policy, 0, sizeof(*policy));
>
> log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
> @@ -157,7 +150,8 @@ static CXLRetCode cmd_events_get_interrupt_policy(struct cxl_cmd *cmd,
> return CXL_MBOX_SUCCESS;
> }
>
> -static CXLRetCode cmd_events_set_interrupt_policy(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxlds,
> uint16_t *len)
> {
> @@ -168,7 +162,7 @@ static CXLRetCode cmd_events_set_interrupt_policy(struct cxl_cmd *cmd,
> return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
> }
>
> - policy = (CXLEventInterruptPolicy *)cmd->payload;
> + policy = (CXLEventInterruptPolicy *)payload;
>
> log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
> log->irq_enabled = (policy->info_settings & CXL_EVENT_INT_MODE_MASK) ==
> @@ -200,7 +194,8 @@ static CXLRetCode cmd_events_set_interrupt_policy(struct cxl_cmd *cmd,
> }
>
> /* 8.2.9.2.1 */
> -static CXLRetCode cmd_firmware_update_get_info(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -221,7 +216,7 @@ static CXLRetCode cmd_firmware_update_get_info(struct cxl_cmd *cmd,
> return CXL_MBOX_INTERNAL_ERROR;
> }
>
> - fw_info = (void *)cmd->payload;
> + fw_info = (void *)payload;
> memset(fw_info, 0, sizeof(*fw_info));
>
> fw_info->slots_supported = 2;
> @@ -234,27 +229,29 @@ static CXLRetCode cmd_firmware_update_get_info(struct cxl_cmd *cmd,
> }
>
> /* 8.2.9.3.1 */
> -static CXLRetCode cmd_timestamp_get(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_timestamp_get(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> uint64_t final_time = cxl_device_get_timestamp(cxl_dstate);
>
> - stq_le_p(cmd->payload, final_time);
> + stq_le_p(payload, final_time);
> *len = 8;
>
> return CXL_MBOX_SUCCESS;
> }
>
> /* 8.2.9.3.2 */
> -static CXLRetCode cmd_timestamp_set(struct cxl_cmd *cmd,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> +static CXLRetCode cmd_timestamp_set(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> + CXLDeviceState *cxl_dstate,
> + uint16_t *len)
> {
> cxl_dstate->timestamp.set = true;
> cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>
> - cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)cmd->payload);
> + cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)payload);
>
> *len = 0;
> return CXL_MBOX_SUCCESS;
> @@ -267,7 +264,8 @@ static const QemuUUID cel_uuid = {
> };
>
> /* 8.2.9.4.1 */
> -static CXLRetCode cmd_logs_get_supported(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -278,7 +276,7 @@ static CXLRetCode cmd_logs_get_supported(struct cxl_cmd *cmd,
> QemuUUID uuid;
> uint32_t size;
> } log_entries[1];
> - } QEMU_PACKED *supported_logs = (void *)cmd->payload;
> + } QEMU_PACKED *supported_logs = (void *)payload;
> QEMU_BUILD_BUG_ON(sizeof(*supported_logs) != 0x1c);
>
> supported_logs->entries = 1;
> @@ -290,7 +288,8 @@ static CXLRetCode cmd_logs_get_supported(struct cxl_cmd *cmd,
> }
>
> /* 8.2.9.4.2 */
> -static CXLRetCode cmd_logs_get_log(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -298,7 +297,9 @@ static CXLRetCode cmd_logs_get_log(struct cxl_cmd *cmd,
> QemuUUID uuid;
> uint32_t offset;
> uint32_t length;
> - } QEMU_PACKED QEMU_ALIGNED(16) *get_log = (void *)cmd->payload;
> + } QEMU_PACKED QEMU_ALIGNED(16) *get_log;
> +
> + get_log = (void *)payload;
>
> /*
> * 8.2.9.4.2
> @@ -324,14 +325,15 @@ static CXLRetCode cmd_logs_get_log(struct cxl_cmd *cmd,
> /* Store off everything to local variables so we can wipe out the payload */
> *len = get_log->length;
>
> - memmove(cmd->payload, cxl_dstate->cel_log + get_log->offset,
> + memmove(payload, cxl_dstate->cel_log + get_log->offset,
> get_log->length);
>
> return CXL_MBOX_SUCCESS;
> }
>
> /* 8.2.9.5.1.1 */
> -static CXLRetCode cmd_identify_memory_device(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -361,7 +363,7 @@ static CXLRetCode cmd_identify_memory_device(struct cxl_cmd *cmd,
> return CXL_MBOX_INTERNAL_ERROR;
> }
>
> - id = (void *)cmd->payload;
> + id = (void *)payload;
> memset(id, 0, sizeof(*id));
>
> snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0);
> @@ -382,7 +384,8 @@ static CXLRetCode cmd_identify_memory_device(struct cxl_cmd *cmd,
> return CXL_MBOX_SUCCESS;
> }
>
> -static CXLRetCode cmd_ccls_get_partition_info(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -391,7 +394,7 @@ static CXLRetCode cmd_ccls_get_partition_info(struct cxl_cmd *cmd,
> uint64_t active_pmem;
> uint64_t next_vmem;
> uint64_t next_pmem;
> - } QEMU_PACKED *part_info = (void *)cmd->payload;
> + } QEMU_PACKED *part_info = (void *)payload;
> QEMU_BUILD_BUG_ON(sizeof(*part_info) != 0x20);
>
> if ((!QEMU_IS_ALIGNED(cxl_dstate->vmem_size, CXL_CAPACITY_MULTIPLIER)) ||
> @@ -414,7 +417,8 @@ static CXLRetCode cmd_ccls_get_partition_info(struct cxl_cmd *cmd,
> return CXL_MBOX_SUCCESS;
> }
>
> -static CXLRetCode cmd_ccls_get_lsa(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -426,7 +430,7 @@ static CXLRetCode cmd_ccls_get_lsa(struct cxl_cmd *cmd,
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> uint32_t offset, length;
>
> - get_lsa = (void *)cmd->payload;
> + get_lsa = (void *)payload;
> offset = get_lsa->offset;
> length = get_lsa->length;
>
> @@ -439,7 +443,8 @@ static CXLRetCode cmd_ccls_get_lsa(struct cxl_cmd *cmd,
> return CXL_MBOX_SUCCESS;
> }
>
> -static CXLRetCode cmd_ccls_set_lsa(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -448,7 +453,7 @@ static CXLRetCode cmd_ccls_set_lsa(struct cxl_cmd *cmd,
> uint32_t rsvd;
> uint8_t data[];
> } QEMU_PACKED;
> - struct set_lsa_pl *set_lsa_payload = (void *)cmd->payload;
> + struct set_lsa_pl *set_lsa_payload = (void *)payload;
> CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> const size_t hdr_len = offsetof(struct set_lsa_pl, data);
> @@ -474,7 +479,8 @@ static CXLRetCode cmd_ccls_set_lsa(struct cxl_cmd *cmd,
> * make this stateful. We may want to allow longer poison lists to aid
> * testing that kernel functionality.
> */
> -static CXLRetCode cmd_media_get_poison_list(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len)
> {
> @@ -496,8 +502,8 @@ static CXLRetCode cmd_media_get_poison_list(struct cxl_cmd *cmd,
> } QEMU_PACKED records[];
> } QEMU_PACKED;
>
> - struct get_poison_list_pl *in = (void *)cmd->payload;
> - struct get_poison_list_out_pl *out = (void *)cmd->payload;
> + struct get_poison_list_pl *in = (void *)payload;
> + struct get_poison_list_out_pl *out = (void *)payload;
> CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> uint16_t record_count = 0, i = 0;
> uint64_t query_start, query_length;
> @@ -550,7 +556,8 @@ static CXLRetCode cmd_media_get_poison_list(struct cxl_cmd *cmd,
> return CXL_MBOX_SUCCESS;
> }
>
> -static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len_unused)
> {
> @@ -560,7 +567,7 @@ static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
> struct inject_poison_pl {
> uint64_t dpa;
> };
> - struct inject_poison_pl *in = (void *)cmd->payload;
> + struct inject_poison_pl *in = (void *)payload;
> uint64_t dpa = ldq_le_p(&in->dpa);
> CXLPoison *p;
>
> @@ -589,7 +596,8 @@ static CXLRetCode cmd_media_inject_poison(struct cxl_cmd *cmd,
> return CXL_MBOX_SUCCESS;
> }
>
> -static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
> +static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
> + uint8_t *payload,
> CXLDeviceState *cxl_dstate,
> uint16_t *len_unused)
> {
> @@ -603,7 +611,7 @@ static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
> CXLPoison *ent;
> uint64_t dpa;
>
> - struct clear_poison_pl *in = (void *)cmd->payload;
> + struct clear_poison_pl *in = (void *)payload;
>
> dpa = ldq_le_p(&in->dpa);
> if (dpa + CXL_CACHE_LINE_SIZE > cxl_dstate->mem_size) {
> @@ -673,7 +681,7 @@ static CXLRetCode cmd_media_clear_poison(struct cxl_cmd *cmd,
> #define IMMEDIATE_POLICY_CHANGE (1 << 3)
> #define IMMEDIATE_LOG_CHANGE (1 << 4)
>
> -static struct cxl_cmd cxl_cmd_set[256][256] = {
> +static const struct cxl_cmd cxl_cmd_set[256][256] = {
> [EVENTS][GET_RECORDS] = { "EVENTS_GET_RECORDS",
> cmd_events_get_records, 1, 0 },
> [EVENTS][CLEAR_RECORDS] = { "EVENTS_CLEAR_RECORDS",
> @@ -709,21 +717,21 @@ static struct cxl_cmd cxl_cmd_set[256][256] = {
> void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
> {
> uint16_t ret = CXL_MBOX_SUCCESS;
> - struct cxl_cmd *cxl_cmd;
> - uint64_t status_reg;
> + const struct cxl_cmd *cxl_cmd;
> + uint64_t status_reg = 0;
> opcode_handler h;
> 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 = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, LENGTH);
> - cxl_cmd = &cxl_cmd_set[set][cmd];
> + uint8_t *pl = cxl_dstate->mbox_reg_state + A_CXL_DEV_CMD_PAYLOAD;
> +
> + cxl_cmd = &cxl_dstate->cxl_cmd_set[set][cmd];
> h = cxl_cmd->handler;
> if (h) {
> if (len == cxl_cmd->in || cxl_cmd->in == ~0) {
> - cxl_cmd->payload = cxl_dstate->mbox_reg_state +
> - A_CXL_DEV_CMD_PAYLOAD;
> - ret = (*h)(cxl_cmd, cxl_dstate, &len);
> + ret = (*h)(cxl_cmd, pl, cxl_dstate, &len);
> assert(len <= cxl_dstate->payload_size);
> } else {
> ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
> @@ -752,10 +760,11 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
>
> void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate)
> {
> + cxl_dstate->cxl_cmd_set = cxl_cmd_set;
> for (int set = 0; set < 256; set++) {
> for (int cmd = 0; cmd < 256; cmd++) {
> - if (cxl_cmd_set[set][cmd].handler) {
> - struct cxl_cmd *c = &cxl_cmd_set[set][cmd];
> + if (cxl_dstate->cxl_cmd_set[set][cmd].handler) {
> + const struct cxl_cmd *c = &cxl_dstate->cxl_cmd_set[set][cmd];
> struct cel_log *log =
> &cxl_dstate->cel_log[cxl_dstate->cel_size];
>
> --
> 2.39.2
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 02/19] hw/cxl/mbox: Split mailbox command payload into separate input and output
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 01/19] hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances constant Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-27 22:58 ` Fan Ni
2023-09-25 16:11 ` [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState Jonathan Cameron via
` (18 subsequent siblings)
20 siblings, 1 reply; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
New CCI types that will be supported shortly do not have a single buffer
used in both directions. As such, split it up. For CXL mailboxes the two
pointers will be aliases of the same memory so all callbacks must allow
for that.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl_device.h | 7 +-
hw/cxl/cxl-events.c | 2 +-
hw/cxl/cxl-mailbox-utils.c | 222 +++++++++++++++++++++---------------
3 files changed, 132 insertions(+), 99 deletions(-)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 556953469c..d7a2c4009e 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -114,8 +114,9 @@ typedef enum {
typedef struct cxl_device_state CXLDeviceState;
struct cxl_cmd;
typedef CXLRetCode (*opcode_handler)(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate, uint16_t *len);
+ uint8_t *payload_in, size_t len_in,
+ uint8_t *payload_out, size_t *len_out,
+ CXLDeviceState *cxl_dstate);
struct cxl_cmd {
const char *name;
opcode_handler handler;
@@ -390,7 +391,7 @@ bool cxl_event_insert(CXLDeviceState *cxlds, CXLEventLogType log_type,
CXLEventRecordRaw *event);
CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl,
uint8_t log_type, int max_recs,
- uint16_t *len);
+ size_t *len);
CXLRetCode cxl_event_clear_records(CXLDeviceState *cxlds,
CXLClearEventPayload *pl);
diff --git a/hw/cxl/cxl-events.c b/hw/cxl/cxl-events.c
index e2172b94b9..bee6dfaf14 100644
--- a/hw/cxl/cxl-events.c
+++ b/hw/cxl/cxl-events.c
@@ -143,7 +143,7 @@ bool cxl_event_insert(CXLDeviceState *cxlds, CXLEventLogType log_type,
CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl,
uint8_t log_type, int max_recs,
- uint16_t *len)
+ size_t *len)
{
CXLEventLog *log;
CXLEvent *entry;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index c02de06943..4bdbc2ee83 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -71,9 +71,9 @@ enum {
static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxlds,
- uint16_t *len)
+ uint8_t *payload_in, size_t len_in,
+ uint8_t *payload_out, size_t *len_out,
+ CXLDeviceState *cxlds)
{
CXLGetEventPayload *pl;
uint8_t log_type;
@@ -83,9 +83,9 @@ static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
return CXL_MBOX_INVALID_INPUT;
}
- log_type = payload[0];
+ log_type = payload_in[0];
- pl = (CXLGetEventPayload *)payload;
+ pl = (CXLGetEventPayload *)payload_out;
memset(pl, 0, sizeof(*pl));
max_recs = (cxlds->payload_size - CXL_EVENT_PAYLOAD_HDR_SIZE) /
@@ -94,30 +94,34 @@ static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
max_recs = 0xFFFF;
}
- return cxl_event_get_records(cxlds, pl, log_type, max_recs, len);
+ return cxl_event_get_records(cxlds, pl, log_type, max_recs, len_out);
}
static CXLRetCode cmd_events_clear_records(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxlds,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxlds)
{
CXLClearEventPayload *pl;
- pl = (CXLClearEventPayload *)payload;
- *len = 0;
+ pl = (CXLClearEventPayload *)payload_in;
+ *len_out = 0;
return cxl_event_clear_records(cxlds, pl);
}
static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxlds,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxlds)
{
CXLEventInterruptPolicy *policy;
CXLEventLog *log;
- policy = (CXLEventInterruptPolicy *)payload;
+ policy = (CXLEventInterruptPolicy *)payload_out;
memset(policy, 0, sizeof(*policy));
log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
@@ -146,23 +150,25 @@ static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
policy->dyn_cap_settings = CXL_INT_MSI_MSIX;
}
- *len = sizeof(*policy);
+ *len_out = sizeof(*policy);
return CXL_MBOX_SUCCESS;
}
static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxlds,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxlds)
{
CXLEventInterruptPolicy *policy;
CXLEventLog *log;
- if (*len < CXL_EVENT_INT_SETTING_MIN_LEN) {
+ if (len_in < CXL_EVENT_INT_SETTING_MIN_LEN) {
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
- policy = (CXLEventInterruptPolicy *)payload;
+ policy = (CXLEventInterruptPolicy *)payload_in;
log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
log->irq_enabled = (policy->info_settings & CXL_EVENT_INT_MODE_MASK) ==
@@ -181,7 +187,7 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
CXL_INT_MSI_MSIX;
/* DCD is optional */
- if (*len < sizeof(*policy)) {
+ if (len_in < sizeof(*policy)) {
return CXL_MBOX_SUCCESS;
}
@@ -189,15 +195,17 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
log->irq_enabled = (policy->dyn_cap_settings & CXL_EVENT_INT_MODE_MASK) ==
CXL_INT_MSI_MSIX;
- *len = sizeof(*policy);
+ *len_out = 0;
return CXL_MBOX_SUCCESS;
}
/* 8.2.9.2.1 */
static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct {
uint8_t slots_supported;
@@ -216,7 +224,7 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
return CXL_MBOX_INTERNAL_ERROR;
}
- fw_info = (void *)payload;
+ fw_info = (void *)payload_out;
memset(fw_info, 0, sizeof(*fw_info));
fw_info->slots_supported = 2;
@@ -224,36 +232,40 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
fw_info->caps = 0;
pstrcpy(fw_info->fw_rev1, sizeof(fw_info->fw_rev1), "BWFW VERSION 0");
- *len = sizeof(*fw_info);
+ *len_out = sizeof(*fw_info);
return CXL_MBOX_SUCCESS;
}
/* 8.2.9.3.1 */
static CXLRetCode cmd_timestamp_get(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
uint64_t final_time = cxl_device_get_timestamp(cxl_dstate);
- stq_le_p(payload, final_time);
- *len = 8;
+ stq_le_p(payload_out, final_time);
+ *len_out = 8;
return CXL_MBOX_SUCCESS;
}
/* 8.2.9.3.2 */
static CXLRetCode cmd_timestamp_set(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
cxl_dstate->timestamp.set = true;
cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
- cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)payload);
+ cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)payload_in);
- *len = 0;
+ *len_out = 0;
return CXL_MBOX_SUCCESS;
}
@@ -265,9 +277,11 @@ static const QemuUUID cel_uuid = {
/* 8.2.9.4.1 */
static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct {
uint16_t entries;
@@ -276,22 +290,24 @@ static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
QemuUUID uuid;
uint32_t size;
} log_entries[1];
- } QEMU_PACKED *supported_logs = (void *)payload;
+ } QEMU_PACKED *supported_logs = (void *)payload_out;
QEMU_BUILD_BUG_ON(sizeof(*supported_logs) != 0x1c);
supported_logs->entries = 1;
supported_logs->log_entries[0].uuid = cel_uuid;
supported_logs->log_entries[0].size = 4 * cxl_dstate->cel_size;
- *len = sizeof(*supported_logs);
+ *len_out = sizeof(*supported_logs);
return CXL_MBOX_SUCCESS;
}
/* 8.2.9.4.2 */
static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct {
QemuUUID uuid;
@@ -299,7 +315,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
uint32_t length;
} QEMU_PACKED QEMU_ALIGNED(16) *get_log;
- get_log = (void *)payload;
+ get_log = (void *)payload_in;
/*
* 8.2.9.4.2
@@ -323,19 +339,21 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
}
/* Store off everything to local variables so we can wipe out the payload */
- *len = get_log->length;
+ *len_out = get_log->length;
- memmove(payload, cxl_dstate->cel_log + get_log->offset,
- get_log->length);
+ memmove(payload_out, cxl_dstate->cel_log + get_log->offset,
+ get_log->length);
return CXL_MBOX_SUCCESS;
}
/* 8.2.9.5.1.1 */
static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct {
char fw_revision[0x10];
@@ -363,7 +381,7 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
return CXL_MBOX_INTERNAL_ERROR;
}
- id = (void *)payload;
+ id = (void *)payload_out;
memset(id, 0, sizeof(*id));
snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0);
@@ -380,21 +398,23 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
/* No limit - so limited by main poison record limit */
stw_le_p(&id->inject_poison_limit, 0);
- *len = sizeof(*id);
+ *len_out = sizeof(*id);
return CXL_MBOX_SUCCESS;
}
static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct {
uint64_t active_vmem;
uint64_t active_pmem;
uint64_t next_vmem;
uint64_t next_pmem;
- } QEMU_PACKED *part_info = (void *)payload;
+ } QEMU_PACKED *part_info = (void *)payload_out;
QEMU_BUILD_BUG_ON(sizeof(*part_info) != 0x20);
if ((!QEMU_IS_ALIGNED(cxl_dstate->vmem_size, CXL_CAPACITY_MULTIPLIER)) ||
@@ -413,14 +433,16 @@ static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
cxl_dstate->pmem_size / CXL_CAPACITY_MULTIPLIER);
stq_le_p(&part_info->next_pmem, 0);
- *len = sizeof(*part_info);
+ *len_out = sizeof(*part_info);
return CXL_MBOX_SUCCESS;
}
static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct {
uint32_t offset;
@@ -430,46 +452,47 @@ static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
uint32_t offset, length;
- get_lsa = (void *)payload;
+ get_lsa = (void *)payload_in;
offset = get_lsa->offset;
length = get_lsa->length;
if (offset + length > cvc->get_lsa_size(ct3d)) {
- *len = 0;
+ *len_out = 0;
return CXL_MBOX_INVALID_INPUT;
}
- *len = cvc->get_lsa(ct3d, get_lsa, length, offset);
+ *len_out = cvc->get_lsa(ct3d, payload_out, length, offset);
return CXL_MBOX_SUCCESS;
}
static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct set_lsa_pl {
uint32_t offset;
uint32_t rsvd;
uint8_t data[];
} QEMU_PACKED;
- struct set_lsa_pl *set_lsa_payload = (void *)payload;
+ struct set_lsa_pl *set_lsa_payload = (void *)payload_in;
CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
const size_t hdr_len = offsetof(struct set_lsa_pl, data);
- uint16_t plen = *len;
- *len = 0;
- if (!plen) {
+ *len_out = 0;
+ if (!len_in) {
return CXL_MBOX_SUCCESS;
}
- if (set_lsa_payload->offset + plen > cvc->get_lsa_size(ct3d) + hdr_len) {
+ if (set_lsa_payload->offset + len_in > cvc->get_lsa_size(ct3d) + hdr_len) {
return CXL_MBOX_INVALID_INPUT;
}
- plen -= hdr_len;
+ len_in -= hdr_len;
- cvc->set_lsa(ct3d, set_lsa_payload->data, plen, set_lsa_payload->offset);
+ cvc->set_lsa(ct3d, set_lsa_payload->data, len_in, set_lsa_payload->offset);
return CXL_MBOX_SUCCESS;
}
@@ -480,9 +503,11 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
* testing that kernel functionality.
*/
static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
struct get_poison_list_pl {
uint64_t pa;
@@ -502,8 +527,8 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
} QEMU_PACKED records[];
} QEMU_PACKED;
- struct get_poison_list_pl *in = (void *)payload;
- struct get_poison_list_out_pl *out = (void *)payload;
+ struct get_poison_list_pl *in = (void *)payload_in;
+ struct get_poison_list_out_pl *out = (void *)payload_out;
CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
uint16_t record_count = 0, i = 0;
uint64_t query_start, query_length;
@@ -552,14 +577,16 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
stq_le_p(&out->overflow_timestamp, ct3d->poison_list_overflow_ts);
}
stw_le_p(&out->count, record_count);
- *len = out_pl_len;
+ *len_out = out_pl_len;
return CXL_MBOX_SUCCESS;
}
static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len_unused)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
CXLPoisonList *poison_list = &ct3d->poison_list;
@@ -567,7 +594,7 @@ static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
struct inject_poison_pl {
uint64_t dpa;
};
- struct inject_poison_pl *in = (void *)payload;
+ struct inject_poison_pl *in = (void *)payload_in;
uint64_t dpa = ldq_le_p(&in->dpa);
CXLPoison *p;
@@ -592,14 +619,17 @@ static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
*/
QLIST_INSERT_HEAD(poison_list, p, node);
ct3d->poison_list_cnt++;
+ *len_out = 0;
return CXL_MBOX_SUCCESS;
}
static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
- uint8_t *payload,
- CXLDeviceState *cxl_dstate,
- uint16_t *len_unused)
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLDeviceState *cxl_dstate)
{
CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
CXLPoisonList *poison_list = &ct3d->poison_list;
@@ -611,7 +641,7 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
CXLPoison *ent;
uint64_t dpa;
- struct clear_poison_pl *in = (void *)payload;
+ struct clear_poison_pl *in = (void *)payload_in;
dpa = ldq_le_p(&in->dpa);
if (dpa + CXL_CACHE_LINE_SIZE > cxl_dstate->mem_size) {
@@ -672,6 +702,7 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
}
/* Any fragments have been added, free original entry */
g_free(ent);
+ *len_out = 0;
return CXL_MBOX_SUCCESS;
}
@@ -724,15 +755,16 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
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 = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, LENGTH);
+ 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;
+ size_t len_out = 0;
cxl_cmd = &cxl_dstate->cxl_cmd_set[set][cmd];
h = cxl_cmd->handler;
if (h) {
- if (len == cxl_cmd->in || cxl_cmd->in == ~0) {
- ret = (*h)(cxl_cmd, pl, cxl_dstate, &len);
- assert(len <= cxl_dstate->payload_size);
+ if (len_in == cxl_cmd->in || cxl_cmd->in == ~0) {
+ ret = (*h)(cxl_cmd, pl, len_in, pl, &len_out, cxl_dstate);
+ assert(len_out <= cxl_dstate->payload_size);
} else {
ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
@@ -748,7 +780,7 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
/* 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);
+ 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;
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 02/19] hw/cxl/mbox: Split mailbox command payload into separate input and output
2023-09-25 16:11 ` [PATCH 02/19] hw/cxl/mbox: Split mailbox command payload into separate input and output Jonathan Cameron via
@ 2023-09-27 22:58 ` Fan Ni
0 siblings, 0 replies; 32+ messages in thread
From: Fan Ni @ 2023-09-27 22:58 UTC (permalink / raw)
To: Jonathan Cameron
Cc: qemu-devel@nongnu.org, linux-cxl@vger.kernel.org, Michael Tsirkin,
linuxarm@huawei.com, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, Sep 25, 2023 at 05:11:07PM +0100, Jonathan Cameron wrote:
> New CCI types that will be supported shortly do not have a single buffer
> used in both directions. As such, split it up. For CXL mailboxes the two
> pointers will be aliases of the same memory so all callbacks must allow
> for that.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
Reviewed-by: Fan Ni <fan.ni@samsung.com>
> include/hw/cxl/cxl_device.h | 7 +-
> hw/cxl/cxl-events.c | 2 +-
> hw/cxl/cxl-mailbox-utils.c | 222 +++++++++++++++++++++---------------
> 3 files changed, 132 insertions(+), 99 deletions(-)
>
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index 556953469c..d7a2c4009e 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -114,8 +114,9 @@ typedef enum {
> typedef struct cxl_device_state CXLDeviceState;
> struct cxl_cmd;
> typedef CXLRetCode (*opcode_handler)(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate, uint16_t *len);
> + uint8_t *payload_in, size_t len_in,
> + uint8_t *payload_out, size_t *len_out,
> + CXLDeviceState *cxl_dstate);
> struct cxl_cmd {
> const char *name;
> opcode_handler handler;
> @@ -390,7 +391,7 @@ bool cxl_event_insert(CXLDeviceState *cxlds, CXLEventLogType log_type,
> CXLEventRecordRaw *event);
> CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl,
> uint8_t log_type, int max_recs,
> - uint16_t *len);
> + size_t *len);
> CXLRetCode cxl_event_clear_records(CXLDeviceState *cxlds,
> CXLClearEventPayload *pl);
>
> diff --git a/hw/cxl/cxl-events.c b/hw/cxl/cxl-events.c
> index e2172b94b9..bee6dfaf14 100644
> --- a/hw/cxl/cxl-events.c
> +++ b/hw/cxl/cxl-events.c
> @@ -143,7 +143,7 @@ bool cxl_event_insert(CXLDeviceState *cxlds, CXLEventLogType log_type,
>
> CXLRetCode cxl_event_get_records(CXLDeviceState *cxlds, CXLGetEventPayload *pl,
> uint8_t log_type, int max_recs,
> - uint16_t *len)
> + size_t *len)
> {
> CXLEventLog *log;
> CXLEvent *entry;
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index c02de06943..4bdbc2ee83 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -71,9 +71,9 @@ enum {
>
>
> static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxlds,
> - uint16_t *len)
> + uint8_t *payload_in, size_t len_in,
> + uint8_t *payload_out, size_t *len_out,
> + CXLDeviceState *cxlds)
> {
> CXLGetEventPayload *pl;
> uint8_t log_type;
> @@ -83,9 +83,9 @@ static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
> return CXL_MBOX_INVALID_INPUT;
> }
>
> - log_type = payload[0];
> + log_type = payload_in[0];
>
> - pl = (CXLGetEventPayload *)payload;
> + pl = (CXLGetEventPayload *)payload_out;
> memset(pl, 0, sizeof(*pl));
>
> max_recs = (cxlds->payload_size - CXL_EVENT_PAYLOAD_HDR_SIZE) /
> @@ -94,30 +94,34 @@ static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
> max_recs = 0xFFFF;
> }
>
> - return cxl_event_get_records(cxlds, pl, log_type, max_recs, len);
> + return cxl_event_get_records(cxlds, pl, log_type, max_recs, len_out);
> }
>
> static CXLRetCode cmd_events_clear_records(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxlds,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxlds)
> {
> CXLClearEventPayload *pl;
>
> - pl = (CXLClearEventPayload *)payload;
> - *len = 0;
> + pl = (CXLClearEventPayload *)payload_in;
> + *len_out = 0;
> return cxl_event_clear_records(cxlds, pl);
> }
>
> static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxlds,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxlds)
> {
> CXLEventInterruptPolicy *policy;
> CXLEventLog *log;
>
> - policy = (CXLEventInterruptPolicy *)payload;
> + policy = (CXLEventInterruptPolicy *)payload_out;
> memset(policy, 0, sizeof(*policy));
>
> log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
> @@ -146,23 +150,25 @@ static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
> policy->dyn_cap_settings = CXL_INT_MSI_MSIX;
> }
>
> - *len = sizeof(*policy);
> + *len_out = sizeof(*policy);
> return CXL_MBOX_SUCCESS;
> }
>
> static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxlds,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxlds)
> {
> CXLEventInterruptPolicy *policy;
> CXLEventLog *log;
>
> - if (*len < CXL_EVENT_INT_SETTING_MIN_LEN) {
> + if (len_in < CXL_EVENT_INT_SETTING_MIN_LEN) {
> return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
> }
>
> - policy = (CXLEventInterruptPolicy *)payload;
> + policy = (CXLEventInterruptPolicy *)payload_in;
>
> log = &cxlds->event_logs[CXL_EVENT_TYPE_INFO];
> log->irq_enabled = (policy->info_settings & CXL_EVENT_INT_MODE_MASK) ==
> @@ -181,7 +187,7 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
> CXL_INT_MSI_MSIX;
>
> /* DCD is optional */
> - if (*len < sizeof(*policy)) {
> + if (len_in < sizeof(*policy)) {
> return CXL_MBOX_SUCCESS;
> }
>
> @@ -189,15 +195,17 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
> log->irq_enabled = (policy->dyn_cap_settings & CXL_EVENT_INT_MODE_MASK) ==
> CXL_INT_MSI_MSIX;
>
> - *len = sizeof(*policy);
> + *len_out = 0;
> return CXL_MBOX_SUCCESS;
> }
>
> /* 8.2.9.2.1 */
> static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct {
> uint8_t slots_supported;
> @@ -216,7 +224,7 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
> return CXL_MBOX_INTERNAL_ERROR;
> }
>
> - fw_info = (void *)payload;
> + fw_info = (void *)payload_out;
> memset(fw_info, 0, sizeof(*fw_info));
>
> fw_info->slots_supported = 2;
> @@ -224,36 +232,40 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
> fw_info->caps = 0;
> pstrcpy(fw_info->fw_rev1, sizeof(fw_info->fw_rev1), "BWFW VERSION 0");
>
> - *len = sizeof(*fw_info);
> + *len_out = sizeof(*fw_info);
> return CXL_MBOX_SUCCESS;
> }
>
> /* 8.2.9.3.1 */
> static CXLRetCode cmd_timestamp_get(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> uint64_t final_time = cxl_device_get_timestamp(cxl_dstate);
>
> - stq_le_p(payload, final_time);
> - *len = 8;
> + stq_le_p(payload_out, final_time);
> + *len_out = 8;
>
> return CXL_MBOX_SUCCESS;
> }
>
> /* 8.2.9.3.2 */
> static CXLRetCode cmd_timestamp_set(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> cxl_dstate->timestamp.set = true;
> cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>
> - cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)payload);
> + cxl_dstate->timestamp.host_set = le64_to_cpu(*(uint64_t *)payload_in);
>
> - *len = 0;
> + *len_out = 0;
> return CXL_MBOX_SUCCESS;
> }
>
> @@ -265,9 +277,11 @@ static const QemuUUID cel_uuid = {
>
> /* 8.2.9.4.1 */
> static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct {
> uint16_t entries;
> @@ -276,22 +290,24 @@ static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
> QemuUUID uuid;
> uint32_t size;
> } log_entries[1];
> - } QEMU_PACKED *supported_logs = (void *)payload;
> + } QEMU_PACKED *supported_logs = (void *)payload_out;
> QEMU_BUILD_BUG_ON(sizeof(*supported_logs) != 0x1c);
>
> supported_logs->entries = 1;
> supported_logs->log_entries[0].uuid = cel_uuid;
> supported_logs->log_entries[0].size = 4 * cxl_dstate->cel_size;
>
> - *len = sizeof(*supported_logs);
> + *len_out = sizeof(*supported_logs);
> return CXL_MBOX_SUCCESS;
> }
>
> /* 8.2.9.4.2 */
> static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct {
> QemuUUID uuid;
> @@ -299,7 +315,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
> uint32_t length;
> } QEMU_PACKED QEMU_ALIGNED(16) *get_log;
>
> - get_log = (void *)payload;
> + get_log = (void *)payload_in;
>
> /*
> * 8.2.9.4.2
> @@ -323,19 +339,21 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
> }
>
> /* Store off everything to local variables so we can wipe out the payload */
> - *len = get_log->length;
> + *len_out = get_log->length;
>
> - memmove(payload, cxl_dstate->cel_log + get_log->offset,
> - get_log->length);
> + memmove(payload_out, cxl_dstate->cel_log + get_log->offset,
> + get_log->length);
>
> return CXL_MBOX_SUCCESS;
> }
>
> /* 8.2.9.5.1.1 */
> static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct {
> char fw_revision[0x10];
> @@ -363,7 +381,7 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
> return CXL_MBOX_INTERNAL_ERROR;
> }
>
> - id = (void *)payload;
> + id = (void *)payload_out;
> memset(id, 0, sizeof(*id));
>
> snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0);
> @@ -380,21 +398,23 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
> /* No limit - so limited by main poison record limit */
> stw_le_p(&id->inject_poison_limit, 0);
>
> - *len = sizeof(*id);
> + *len_out = sizeof(*id);
> return CXL_MBOX_SUCCESS;
> }
>
> static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct {
> uint64_t active_vmem;
> uint64_t active_pmem;
> uint64_t next_vmem;
> uint64_t next_pmem;
> - } QEMU_PACKED *part_info = (void *)payload;
> + } QEMU_PACKED *part_info = (void *)payload_out;
> QEMU_BUILD_BUG_ON(sizeof(*part_info) != 0x20);
>
> if ((!QEMU_IS_ALIGNED(cxl_dstate->vmem_size, CXL_CAPACITY_MULTIPLIER)) ||
> @@ -413,14 +433,16 @@ static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
> cxl_dstate->pmem_size / CXL_CAPACITY_MULTIPLIER);
> stq_le_p(&part_info->next_pmem, 0);
>
> - *len = sizeof(*part_info);
> + *len_out = sizeof(*part_info);
> return CXL_MBOX_SUCCESS;
> }
>
> static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct {
> uint32_t offset;
> @@ -430,46 +452,47 @@ static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> uint32_t offset, length;
>
> - get_lsa = (void *)payload;
> + get_lsa = (void *)payload_in;
> offset = get_lsa->offset;
> length = get_lsa->length;
>
> if (offset + length > cvc->get_lsa_size(ct3d)) {
> - *len = 0;
> + *len_out = 0;
> return CXL_MBOX_INVALID_INPUT;
> }
>
> - *len = cvc->get_lsa(ct3d, get_lsa, length, offset);
> + *len_out = cvc->get_lsa(ct3d, payload_out, length, offset);
> return CXL_MBOX_SUCCESS;
> }
>
> static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct set_lsa_pl {
> uint32_t offset;
> uint32_t rsvd;
> uint8_t data[];
> } QEMU_PACKED;
> - struct set_lsa_pl *set_lsa_payload = (void *)payload;
> + struct set_lsa_pl *set_lsa_payload = (void *)payload_in;
> CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> const size_t hdr_len = offsetof(struct set_lsa_pl, data);
> - uint16_t plen = *len;
>
> - *len = 0;
> - if (!plen) {
> + *len_out = 0;
> + if (!len_in) {
> return CXL_MBOX_SUCCESS;
> }
>
> - if (set_lsa_payload->offset + plen > cvc->get_lsa_size(ct3d) + hdr_len) {
> + if (set_lsa_payload->offset + len_in > cvc->get_lsa_size(ct3d) + hdr_len) {
> return CXL_MBOX_INVALID_INPUT;
> }
> - plen -= hdr_len;
> + len_in -= hdr_len;
>
> - cvc->set_lsa(ct3d, set_lsa_payload->data, plen, set_lsa_payload->offset);
> + cvc->set_lsa(ct3d, set_lsa_payload->data, len_in, set_lsa_payload->offset);
> return CXL_MBOX_SUCCESS;
> }
>
> @@ -480,9 +503,11 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
> * testing that kernel functionality.
> */
> static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> struct get_poison_list_pl {
> uint64_t pa;
> @@ -502,8 +527,8 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
> } QEMU_PACKED records[];
> } QEMU_PACKED;
>
> - struct get_poison_list_pl *in = (void *)payload;
> - struct get_poison_list_out_pl *out = (void *)payload;
> + struct get_poison_list_pl *in = (void *)payload_in;
> + struct get_poison_list_out_pl *out = (void *)payload_out;
> CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> uint16_t record_count = 0, i = 0;
> uint64_t query_start, query_length;
> @@ -552,14 +577,16 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
> stq_le_p(&out->overflow_timestamp, ct3d->poison_list_overflow_ts);
> }
> stw_le_p(&out->count, record_count);
> - *len = out_pl_len;
> + *len_out = out_pl_len;
> return CXL_MBOX_SUCCESS;
> }
>
> static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len_unused)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> CXLPoisonList *poison_list = &ct3d->poison_list;
> @@ -567,7 +594,7 @@ static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
> struct inject_poison_pl {
> uint64_t dpa;
> };
> - struct inject_poison_pl *in = (void *)payload;
> + struct inject_poison_pl *in = (void *)payload_in;
> uint64_t dpa = ldq_le_p(&in->dpa);
> CXLPoison *p;
>
> @@ -592,14 +619,17 @@ static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
> */
> QLIST_INSERT_HEAD(poison_list, p, node);
> ct3d->poison_list_cnt++;
> + *len_out = 0;
>
> return CXL_MBOX_SUCCESS;
> }
>
> static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
> - uint8_t *payload,
> - CXLDeviceState *cxl_dstate,
> - uint16_t *len_unused)
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLDeviceState *cxl_dstate)
> {
> CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> CXLPoisonList *poison_list = &ct3d->poison_list;
> @@ -611,7 +641,7 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
> CXLPoison *ent;
> uint64_t dpa;
>
> - struct clear_poison_pl *in = (void *)payload;
> + struct clear_poison_pl *in = (void *)payload_in;
>
> dpa = ldq_le_p(&in->dpa);
> if (dpa + CXL_CACHE_LINE_SIZE > cxl_dstate->mem_size) {
> @@ -672,6 +702,7 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
> }
> /* Any fragments have been added, free original entry */
> g_free(ent);
> + *len_out = 0;
>
> return CXL_MBOX_SUCCESS;
> }
> @@ -724,15 +755,16 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
>
> 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 = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, LENGTH);
> + 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;
> + size_t len_out = 0;
>
> cxl_cmd = &cxl_dstate->cxl_cmd_set[set][cmd];
> h = cxl_cmd->handler;
> if (h) {
> - if (len == cxl_cmd->in || cxl_cmd->in == ~0) {
> - ret = (*h)(cxl_cmd, pl, cxl_dstate, &len);
> - assert(len <= cxl_dstate->payload_size);
> + if (len_in == cxl_cmd->in || cxl_cmd->in == ~0) {
> + ret = (*h)(cxl_cmd, pl, len_in, pl, &len_out, cxl_dstate);
> + assert(len_out <= cxl_dstate->payload_size);
> } else {
> ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
> }
> @@ -748,7 +780,7 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
> /* 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);
> + 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;
> --
> 2.39.2
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 01/19] hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances constant Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 02/19] hw/cxl/mbox: Split mailbox command payload into separate input and output Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-28 17:44 ` Fan Ni
2023-10-16 15:59 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing Jonathan Cameron via
` (17 subsequent siblings)
20 siblings, 2 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Enables having multiple CCIs per devices. Each CCI (mailbox) has it's own
state and command list, so they can't share a single structure.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl_device.h | 45 ++++++++++++++----
hw/cxl/cxl-device-utils.c | 31 +++++++++---
hw/cxl/cxl-mailbox-utils.c | 94 ++++++++++++++++++++++---------------
hw/mem/cxl_type3.c | 5 +-
4 files changed, 119 insertions(+), 56 deletions(-)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index d7a2c4009e..c883d9dd8f 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -111,12 +111,13 @@ typedef enum {
CXL_MBOX_MAX = 0x17
} CXLRetCode;
+typedef struct CXLCCI CXLCCI;
typedef struct cxl_device_state CXLDeviceState;
struct cxl_cmd;
typedef CXLRetCode (*opcode_handler)(const struct cxl_cmd *cmd,
uint8_t *payload_in, size_t len_in,
uint8_t *payload_out, size_t *len_out,
- CXLDeviceState *cxl_dstate);
+ CXLCCI *cci);
struct cxl_cmd {
const char *name;
opcode_handler handler;
@@ -140,6 +141,31 @@ typedef struct CXLEventLog {
QSIMPLEQ_HEAD(, CXLEvent) events;
} CXLEventLog;
+typedef struct CXLCCI {
+ const struct cxl_cmd (*cxl_cmd_set)[256];
+ struct cel_log {
+ uint16_t opcode;
+ uint16_t effect;
+ } cel_log[1 << 16];
+ size_t cel_size;
+
+ /* background command handling (times in ms) */
+ struct {
+ uint16_t opcode;
+ uint16_t complete_pct;
+ uint16_t ret_code; /* Current value of retcode */
+ uint64_t starttime;
+ /* set by each bg cmd, cleared by the bg_timer when complete */
+ uint64_t runtime;
+ QEMUTimer *timer;
+ } bg;
+ size_t payload_max;
+ /* Pointer to device hosting the CCI */
+ DeviceState *d;
+ /* Pointer to the device hosting the protocol conversion */
+ DeviceState *intf;
+} CXLCCI;
+
typedef struct cxl_device_state {
MemoryRegion device_registers;
@@ -173,11 +199,6 @@ typedef struct cxl_device_state {
uint32_t mbox_reg_state32[CXL_MAILBOX_REGISTERS_LENGTH / 4];
uint64_t mbox_reg_state64[CXL_MAILBOX_REGISTERS_LENGTH / 8];
};
- struct cel_log {
- uint16_t opcode;
- uint16_t effect;
- } cel_log[1 << 16];
- size_t cel_size;
};
struct {
@@ -196,10 +217,12 @@ typedef struct cxl_device_state {
} CXLDeviceState;
/* Initialize the register block for a device */
-void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev);
+void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev,
+ CXLCCI *cci);
+typedef struct CXLType3Dev CXLType3Dev;
/* Set up default values for the register block */
-void cxl_device_register_init_common(CXLDeviceState *dev);
+void cxl_device_register_init_t3(CXLType3Dev *ct3d);
/*
* CXL 2.0 - 8.2.8.1 including errata F4
@@ -245,8 +268,9 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
CXL_DEVICE_CAP_HDR1_OFFSET +
CXL_DEVICE_CAP_REG_SIZE * 2)
-void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate);
-void cxl_process_mailbox(CXLDeviceState *cxl_dstate);
+void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
+void cxl_init_cci(CXLCCI *cci, size_t payload_max);
+void cxl_process_mailbox(CXLCCI *cci);
#define cxl_device_cap_init(dstate, reg, cap_id, ver) \
do { \
@@ -347,6 +371,7 @@ struct CXLType3Dev {
AddressSpace hostpmem_as;
CXLComponentState cxl_cstate;
CXLDeviceState cxl_dstate;
+ CXLCCI cci; /* Primary PCI mailbox CCI */
/* DOE */
DOECap doe_cdat;
diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index eb7195272e..327949a805 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -62,7 +62,14 @@ static uint64_t dev_reg_read(void *opaque, hwaddr offset, unsigned size)
static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
{
- CXLDeviceState *cxl_dstate = opaque;
+ CXLDeviceState *cxl_dstate;
+ CXLCCI *cci = opaque;
+
+ if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
+ cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
+ } else {
+ return 0;
+ }
switch (size) {
case 1:
@@ -123,7 +130,14 @@ static void mailbox_mem_writeq(uint64_t *reg_state, hwaddr offset,
static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
unsigned size)
{
- CXLDeviceState *cxl_dstate = opaque;
+ CXLDeviceState *cxl_dstate;
+ CXLCCI *cci = opaque;
+
+ if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
+ cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
+ } else {
+ return;
+ }
if (offset >= A_CXL_DEV_CMD_PAYLOAD) {
memcpy(cxl_dstate->mbox_reg_state + offset, &value, size);
@@ -143,7 +157,7 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
DOORBELL)) {
- cxl_process_mailbox(cxl_dstate);
+ cxl_process_mailbox(cci);
}
}
@@ -223,7 +237,8 @@ static const MemoryRegionOps caps_ops = {
},
};
-void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate)
+void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate,
+ CXLCCI *cci)
{
/* This will be a BAR, so needs to be rounded up to pow2 for PCI spec */
memory_region_init(&cxl_dstate->device_registers, obj, "device-registers",
@@ -233,7 +248,7 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate)
"cap-array", CXL_CAPS_SIZE);
memory_region_init_io(&cxl_dstate->device, obj, &dev_ops, cxl_dstate,
"device-status", CXL_DEVICE_STATUS_REGISTERS_LENGTH);
- memory_region_init_io(&cxl_dstate->mailbox, obj, &mailbox_ops, cxl_dstate,
+ memory_region_init_io(&cxl_dstate->mailbox, obj, &mailbox_ops, cci,
"mailbox", CXL_MAILBOX_REGISTERS_LENGTH);
memory_region_init_io(&cxl_dstate->memory_device, obj, &mdev_ops,
cxl_dstate, "memory device caps",
@@ -284,8 +299,9 @@ static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { }
-void cxl_device_register_init_common(CXLDeviceState *cxl_dstate)
+void cxl_device_register_init_t3(CXLType3Dev *ct3d)
{
+ CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
uint64_t *cap_h = cxl_dstate->caps_reg_state64;
const int cap_count = 3;
@@ -303,7 +319,8 @@ void cxl_device_register_init_common(CXLDeviceState *cxl_dstate)
cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000, 1);
memdev_reg_init_common(cxl_dstate);
- cxl_initialize_mailbox(cxl_dstate);
+ cxl_initialize_mailbox_t3(&ct3d->cci, DEVICE(ct3d),
+ CXL_MAILBOX_MAX_PAYLOAD_SIZE);
}
uint64_t cxl_device_get_timestamp(CXLDeviceState *cxl_dstate)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 4bdbc2ee83..376367c118 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -73,8 +73,9 @@ enum {
static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
uint8_t *payload_in, size_t len_in,
uint8_t *payload_out, size_t *len_out,
- CXLDeviceState *cxlds)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
CXLGetEventPayload *pl;
uint8_t log_type;
int max_recs;
@@ -102,8 +103,9 @@ static CXLRetCode cmd_events_clear_records(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxlds)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
CXLClearEventPayload *pl;
pl = (CXLClearEventPayload *)payload_in;
@@ -116,8 +118,9 @@ static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxlds)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
CXLEventInterruptPolicy *policy;
CXLEventLog *log;
@@ -159,8 +162,9 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxlds)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
CXLEventInterruptPolicy *policy;
CXLEventLog *log;
@@ -205,8 +209,9 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
size_t len,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
struct {
uint8_t slots_supported;
uint8_t slot_info;
@@ -242,8 +247,9 @@ static CXLRetCode cmd_timestamp_get(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
uint64_t final_time = cxl_device_get_timestamp(cxl_dstate);
stq_le_p(payload_out, final_time);
@@ -258,8 +264,10 @@ static CXLRetCode cmd_timestamp_set(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
+
cxl_dstate->timestamp.set = true;
cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
@@ -281,7 +289,7 @@ static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
struct {
uint16_t entries;
@@ -295,7 +303,7 @@ static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
supported_logs->entries = 1;
supported_logs->log_entries[0].uuid = cel_uuid;
- supported_logs->log_entries[0].size = 4 * cxl_dstate->cel_size;
+ supported_logs->log_entries[0].size = 4 * cci->cel_size;
*len_out = sizeof(*supported_logs);
return CXL_MBOX_SUCCESS;
@@ -307,7 +315,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
struct {
QemuUUID uuid;
@@ -330,7 +338,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
* the only possible failure would be if the mailbox itself isn't big
* enough.
*/
- if (get_log->offset + get_log->length > cxl_dstate->payload_size) {
+ if (get_log->offset + get_log->length > cci->payload_max) {
return CXL_MBOX_INVALID_INPUT;
}
@@ -341,8 +349,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
/* Store off everything to local variables so we can wipe out the payload */
*len_out = get_log->length;
- memmove(payload_out, cxl_dstate->cel_log + get_log->offset,
- get_log->length);
+ memmove(payload_out, cci->cel_log + get_log->offset, get_log->length);
return CXL_MBOX_SUCCESS;
}
@@ -353,7 +360,7 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
struct {
char fw_revision[0x10];
@@ -372,9 +379,9 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
uint8_t qos_telemetry_caps;
} QEMU_PACKED *id;
QEMU_BUILD_BUG_ON(sizeof(*id) != 0x43);
-
- CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
+ CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
if ((!QEMU_IS_ALIGNED(cxl_dstate->vmem_size, CXL_CAPACITY_MULTIPLIER)) ||
(!QEMU_IS_ALIGNED(cxl_dstate->pmem_size, CXL_CAPACITY_MULTIPLIER))) {
@@ -407,8 +414,9 @@ static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
+ CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
struct {
uint64_t active_vmem;
uint64_t active_pmem;
@@ -442,13 +450,13 @@ static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
struct {
uint32_t offset;
uint32_t length;
} QEMU_PACKED *get_lsa;
- CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
uint32_t offset, length;
@@ -470,7 +478,7 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
struct set_lsa_pl {
uint32_t offset;
@@ -478,7 +486,7 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
uint8_t data[];
} QEMU_PACKED;
struct set_lsa_pl *set_lsa_payload = (void *)payload_in;
- CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
const size_t hdr_len = offsetof(struct set_lsa_pl, data);
@@ -507,7 +515,7 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
struct get_poison_list_pl {
uint64_t pa;
@@ -529,7 +537,7 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
struct get_poison_list_pl *in = (void *)payload_in;
struct get_poison_list_out_pl *out = (void *)payload_out;
- CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
uint16_t record_count = 0, i = 0;
uint64_t query_start, query_length;
CXLPoisonList *poison_list = &ct3d->poison_list;
@@ -586,9 +594,9 @@ static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
- CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
CXLPoisonList *poison_list = &ct3d->poison_list;
CXLPoison *ent;
struct inject_poison_pl {
@@ -629,9 +637,10 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
size_t len_in,
uint8_t *payload_out,
size_t *len_out,
- CXLDeviceState *cxl_dstate)
+ CXLCCI *cci)
{
- CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+ CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
CXLPoisonList *poison_list = &ct3d->poison_list;
CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
struct clear_poison_pl {
@@ -745,12 +754,13 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
cmd_media_clear_poison, 72, 0 },
};
-void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
+void cxl_process_mailbox(CXLCCI *cci)
{
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);
@@ -759,12 +769,12 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
uint8_t *pl = cxl_dstate->mbox_reg_state + A_CXL_DEV_CMD_PAYLOAD;
size_t len_out = 0;
- cxl_cmd = &cxl_dstate->cxl_cmd_set[set][cmd];
+ 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, cxl_dstate);
- assert(len_out <= cxl_dstate->payload_size);
+ ret = (*h)(cxl_cmd, pl, len_in, pl, &len_out, cci);
+ assert(len_out <= cci->payload_max);
} else {
ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
@@ -790,20 +800,30 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
DOORBELL, 0);
}
-void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate)
+void cxl_init_cci(CXLCCI *cci, size_t payload_max)
{
- cxl_dstate->cxl_cmd_set = cxl_cmd_set;
+ cci->payload_max = payload_max;
for (int set = 0; set < 256; set++) {
for (int cmd = 0; cmd < 256; cmd++) {
- if (cxl_dstate->cxl_cmd_set[set][cmd].handler) {
- const struct cxl_cmd *c = &cxl_dstate->cxl_cmd_set[set][cmd];
+ if (cci->cxl_cmd_set[set][cmd].handler) {
+ const struct cxl_cmd *c = &cci->cxl_cmd_set[set][cmd];
struct cel_log *log =
- &cxl_dstate->cel_log[cxl_dstate->cel_size];
+ &cci->cel_log[cci->cel_size];
log->opcode = (set << 8) | cmd;
log->effect = c->effect;
- cxl_dstate->cel_size++;
+ cci->cel_size++;
}
}
}
}
+
+void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max)
+{
+ cci->cxl_cmd_set = cxl_cmd_set;
+ cci->d = d;
+
+ /* No separation for PCI MB as protocol handled in PCI device */
+ cci->intf = d;
+ cxl_init_cci(cci, payload_max);
+}
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 18ad853f5b..0529745786 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -716,7 +716,8 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
pci_dev, CXL_COMPONENT_REG_BAR_IDX,
PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, mr);
- cxl_device_register_block_init(OBJECT(pci_dev), &ct3d->cxl_dstate);
+ cxl_device_register_block_init(OBJECT(pci_dev), &ct3d->cxl_dstate,
+ &ct3d->cci);
pci_register_bar(pci_dev, CXL_DEVICE_REG_BAR_IDX,
PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_TYPE_64,
@@ -922,7 +923,7 @@ static void ct3d_reset(DeviceState *dev)
uint32_t *write_msk = ct3d->cxl_cstate.crb.cache_mem_regs_write_mask;
cxl_component_register_init_common(reg_state, write_msk, CXL2_TYPE3_DEVICE);
- cxl_device_register_init_common(&ct3d->cxl_dstate);
+ cxl_device_register_init_t3(ct3d);
}
static Property ct3_props[] = {
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState
2023-09-25 16:11 ` [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState Jonathan Cameron via
@ 2023-09-28 17:44 ` Fan Ni
2023-10-16 15:59 ` Jonathan Cameron via
1 sibling, 0 replies; 32+ messages in thread
From: Fan Ni @ 2023-09-28 17:44 UTC (permalink / raw)
To: Jonathan Cameron
Cc: qemu-devel, linux-cxl, Michael Tsirkin, linuxarm, Fan Ni,
Philippe Mathieu-Daud?, Davidlohr Bueso, Gregory Price,
Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, Sep 25, 2023 at 05:11:08PM +0100, Jonathan Cameron wrote:
> Enables having multiple CCIs per devices. Each CCI (mailbox) has it's own
> state and command list, so they can't share a single structure.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
Reviewed-by: Fan Ni <fan.ni@samsung.com>
> include/hw/cxl/cxl_device.h | 45 ++++++++++++++----
> hw/cxl/cxl-device-utils.c | 31 +++++++++---
> hw/cxl/cxl-mailbox-utils.c | 94 ++++++++++++++++++++++---------------
> hw/mem/cxl_type3.c | 5 +-
> 4 files changed, 119 insertions(+), 56 deletions(-)
>
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index d7a2c4009e..c883d9dd8f 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -111,12 +111,13 @@ typedef enum {
> CXL_MBOX_MAX = 0x17
> } CXLRetCode;
>
> +typedef struct CXLCCI CXLCCI;
> typedef struct cxl_device_state CXLDeviceState;
> struct cxl_cmd;
> typedef CXLRetCode (*opcode_handler)(const struct cxl_cmd *cmd,
> uint8_t *payload_in, size_t len_in,
> uint8_t *payload_out, size_t *len_out,
> - CXLDeviceState *cxl_dstate);
> + CXLCCI *cci);
> struct cxl_cmd {
> const char *name;
> opcode_handler handler;
> @@ -140,6 +141,31 @@ typedef struct CXLEventLog {
> QSIMPLEQ_HEAD(, CXLEvent) events;
> } CXLEventLog;
>
> +typedef struct CXLCCI {
> + const struct cxl_cmd (*cxl_cmd_set)[256];
> + struct cel_log {
> + uint16_t opcode;
> + uint16_t effect;
> + } cel_log[1 << 16];
> + size_t cel_size;
> +
> + /* background command handling (times in ms) */
> + struct {
> + uint16_t opcode;
> + uint16_t complete_pct;
> + uint16_t ret_code; /* Current value of retcode */
> + uint64_t starttime;
> + /* set by each bg cmd, cleared by the bg_timer when complete */
> + uint64_t runtime;
> + QEMUTimer *timer;
> + } bg;
> + size_t payload_max;
> + /* Pointer to device hosting the CCI */
> + DeviceState *d;
> + /* Pointer to the device hosting the protocol conversion */
> + DeviceState *intf;
> +} CXLCCI;
> +
> typedef struct cxl_device_state {
> MemoryRegion device_registers;
>
> @@ -173,11 +199,6 @@ typedef struct cxl_device_state {
> uint32_t mbox_reg_state32[CXL_MAILBOX_REGISTERS_LENGTH / 4];
> uint64_t mbox_reg_state64[CXL_MAILBOX_REGISTERS_LENGTH / 8];
> };
> - struct cel_log {
> - uint16_t opcode;
> - uint16_t effect;
> - } cel_log[1 << 16];
> - size_t cel_size;
> };
>
> struct {
> @@ -196,10 +217,12 @@ typedef struct cxl_device_state {
> } CXLDeviceState;
>
> /* Initialize the register block for a device */
> -void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev);
> +void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev,
> + CXLCCI *cci);
>
> +typedef struct CXLType3Dev CXLType3Dev;
> /* Set up default values for the register block */
> -void cxl_device_register_init_common(CXLDeviceState *dev);
> +void cxl_device_register_init_t3(CXLType3Dev *ct3d);
>
> /*
> * CXL 2.0 - 8.2.8.1 including errata F4
> @@ -245,8 +268,9 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
> CXL_DEVICE_CAP_HDR1_OFFSET +
> CXL_DEVICE_CAP_REG_SIZE * 2)
>
> -void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate);
> -void cxl_process_mailbox(CXLDeviceState *cxl_dstate);
> +void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
> +void cxl_init_cci(CXLCCI *cci, size_t payload_max);
> +void cxl_process_mailbox(CXLCCI *cci);
>
> #define cxl_device_cap_init(dstate, reg, cap_id, ver) \
> do { \
> @@ -347,6 +371,7 @@ struct CXLType3Dev {
> AddressSpace hostpmem_as;
> CXLComponentState cxl_cstate;
> CXLDeviceState cxl_dstate;
> + CXLCCI cci; /* Primary PCI mailbox CCI */
>
> /* DOE */
> DOECap doe_cdat;
> diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
> index eb7195272e..327949a805 100644
> --- a/hw/cxl/cxl-device-utils.c
> +++ b/hw/cxl/cxl-device-utils.c
> @@ -62,7 +62,14 @@ static uint64_t dev_reg_read(void *opaque, hwaddr offset, unsigned size)
>
> static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
> {
> - CXLDeviceState *cxl_dstate = opaque;
> + CXLDeviceState *cxl_dstate;
> + CXLCCI *cci = opaque;
> +
> + if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
> + cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
> + } else {
> + return 0;
> + }
>
> switch (size) {
> case 1:
> @@ -123,7 +130,14 @@ static void mailbox_mem_writeq(uint64_t *reg_state, hwaddr offset,
> static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
> unsigned size)
> {
> - CXLDeviceState *cxl_dstate = opaque;
> + CXLDeviceState *cxl_dstate;
> + CXLCCI *cci = opaque;
> +
> + if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
> + cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
> + } else {
> + return;
> + }
>
> if (offset >= A_CXL_DEV_CMD_PAYLOAD) {
> memcpy(cxl_dstate->mbox_reg_state + offset, &value, size);
> @@ -143,7 +157,7 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
>
> if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
> DOORBELL)) {
> - cxl_process_mailbox(cxl_dstate);
> + cxl_process_mailbox(cci);
> }
> }
>
> @@ -223,7 +237,8 @@ static const MemoryRegionOps caps_ops = {
> },
> };
>
> -void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate)
> +void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate,
> + CXLCCI *cci)
> {
> /* This will be a BAR, so needs to be rounded up to pow2 for PCI spec */
> memory_region_init(&cxl_dstate->device_registers, obj, "device-registers",
> @@ -233,7 +248,7 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate)
> "cap-array", CXL_CAPS_SIZE);
> memory_region_init_io(&cxl_dstate->device, obj, &dev_ops, cxl_dstate,
> "device-status", CXL_DEVICE_STATUS_REGISTERS_LENGTH);
> - memory_region_init_io(&cxl_dstate->mailbox, obj, &mailbox_ops, cxl_dstate,
> + memory_region_init_io(&cxl_dstate->mailbox, obj, &mailbox_ops, cci,
> "mailbox", CXL_MAILBOX_REGISTERS_LENGTH);
> memory_region_init_io(&cxl_dstate->memory_device, obj, &mdev_ops,
> cxl_dstate, "memory device caps",
> @@ -284,8 +299,9 @@ static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
>
> static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { }
>
> -void cxl_device_register_init_common(CXLDeviceState *cxl_dstate)
> +void cxl_device_register_init_t3(CXLType3Dev *ct3d)
> {
> + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
> uint64_t *cap_h = cxl_dstate->caps_reg_state64;
> const int cap_count = 3;
>
> @@ -303,7 +319,8 @@ void cxl_device_register_init_common(CXLDeviceState *cxl_dstate)
> cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000, 1);
> memdev_reg_init_common(cxl_dstate);
>
> - cxl_initialize_mailbox(cxl_dstate);
> + cxl_initialize_mailbox_t3(&ct3d->cci, DEVICE(ct3d),
> + CXL_MAILBOX_MAX_PAYLOAD_SIZE);
> }
>
> uint64_t cxl_device_get_timestamp(CXLDeviceState *cxl_dstate)
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index 4bdbc2ee83..376367c118 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -73,8 +73,9 @@ enum {
> static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
> uint8_t *payload_in, size_t len_in,
> uint8_t *payload_out, size_t *len_out,
> - CXLDeviceState *cxlds)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
> CXLGetEventPayload *pl;
> uint8_t log_type;
> int max_recs;
> @@ -102,8 +103,9 @@ static CXLRetCode cmd_events_clear_records(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxlds)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
> CXLClearEventPayload *pl;
>
> pl = (CXLClearEventPayload *)payload_in;
> @@ -116,8 +118,9 @@ static CXLRetCode cmd_events_get_interrupt_policy(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxlds)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
> CXLEventInterruptPolicy *policy;
> CXLEventLog *log;
>
> @@ -159,8 +162,9 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxlds)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxlds = &CXL_TYPE3(cci->d)->cxl_dstate;
> CXLEventInterruptPolicy *policy;
> CXLEventLog *log;
>
> @@ -205,8 +209,9 @@ static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
> size_t len,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
> struct {
> uint8_t slots_supported;
> uint8_t slot_info;
> @@ -242,8 +247,9 @@ static CXLRetCode cmd_timestamp_get(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
> uint64_t final_time = cxl_device_get_timestamp(cxl_dstate);
>
> stq_le_p(payload_out, final_time);
> @@ -258,8 +264,10 @@ static CXLRetCode cmd_timestamp_set(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
> +
> cxl_dstate->timestamp.set = true;
> cxl_dstate->timestamp.last_set = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>
> @@ -281,7 +289,7 @@ static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> struct {
> uint16_t entries;
> @@ -295,7 +303,7 @@ static CXLRetCode cmd_logs_get_supported(const struct cxl_cmd *cmd,
>
> supported_logs->entries = 1;
> supported_logs->log_entries[0].uuid = cel_uuid;
> - supported_logs->log_entries[0].size = 4 * cxl_dstate->cel_size;
> + supported_logs->log_entries[0].size = 4 * cci->cel_size;
>
> *len_out = sizeof(*supported_logs);
> return CXL_MBOX_SUCCESS;
> @@ -307,7 +315,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> struct {
> QemuUUID uuid;
> @@ -330,7 +338,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
> * the only possible failure would be if the mailbox itself isn't big
> * enough.
> */
> - if (get_log->offset + get_log->length > cxl_dstate->payload_size) {
> + if (get_log->offset + get_log->length > cci->payload_max) {
> return CXL_MBOX_INVALID_INPUT;
> }
>
> @@ -341,8 +349,7 @@ static CXLRetCode cmd_logs_get_log(const struct cxl_cmd *cmd,
> /* Store off everything to local variables so we can wipe out the payload */
> *len_out = get_log->length;
>
> - memmove(payload_out, cxl_dstate->cel_log + get_log->offset,
> - get_log->length);
> + memmove(payload_out, cci->cel_log + get_log->offset, get_log->length);
>
> return CXL_MBOX_SUCCESS;
> }
> @@ -353,7 +360,7 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> struct {
> char fw_revision[0x10];
> @@ -372,9 +379,9 @@ static CXLRetCode cmd_identify_memory_device(const struct cxl_cmd *cmd,
> uint8_t qos_telemetry_caps;
> } QEMU_PACKED *id;
> QEMU_BUILD_BUG_ON(sizeof(*id) != 0x43);
> -
> - CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
>
> if ((!QEMU_IS_ALIGNED(cxl_dstate->vmem_size, CXL_CAPACITY_MULTIPLIER)) ||
> (!QEMU_IS_ALIGNED(cxl_dstate->pmem_size, CXL_CAPACITY_MULTIPLIER))) {
> @@ -407,8 +414,9 @@ static CXLRetCode cmd_ccls_get_partition_info(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> + CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
> struct {
> uint64_t active_vmem;
> uint64_t active_pmem;
> @@ -442,13 +450,13 @@ static CXLRetCode cmd_ccls_get_lsa(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> struct {
> uint32_t offset;
> uint32_t length;
> } QEMU_PACKED *get_lsa;
> - CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> uint32_t offset, length;
>
> @@ -470,7 +478,7 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> struct set_lsa_pl {
> uint32_t offset;
> @@ -478,7 +486,7 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
> uint8_t data[];
> } QEMU_PACKED;
> struct set_lsa_pl *set_lsa_payload = (void *)payload_in;
> - CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> const size_t hdr_len = offsetof(struct set_lsa_pl, data);
>
> @@ -507,7 +515,7 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> struct get_poison_list_pl {
> uint64_t pa;
> @@ -529,7 +537,7 @@ static CXLRetCode cmd_media_get_poison_list(const struct cxl_cmd *cmd,
>
> struct get_poison_list_pl *in = (void *)payload_in;
> struct get_poison_list_out_pl *out = (void *)payload_out;
> - CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> uint16_t record_count = 0, i = 0;
> uint64_t query_start, query_length;
> CXLPoisonList *poison_list = &ct3d->poison_list;
> @@ -586,9 +594,9 @@ static CXLRetCode cmd_media_inject_poison(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> - CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> CXLPoisonList *poison_list = &ct3d->poison_list;
> CXLPoison *ent;
> struct inject_poison_pl {
> @@ -629,9 +637,10 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
> size_t len_in,
> uint8_t *payload_out,
> size_t *len_out,
> - CXLDeviceState *cxl_dstate)
> + CXLCCI *cci)
> {
> - CXLType3Dev *ct3d = container_of(cxl_dstate, CXLType3Dev, cxl_dstate);
> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
> + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
> CXLPoisonList *poison_list = &ct3d->poison_list;
> CXLType3Class *cvc = CXL_TYPE3_GET_CLASS(ct3d);
> struct clear_poison_pl {
> @@ -745,12 +754,13 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
> cmd_media_clear_poison, 72, 0 },
> };
>
> -void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
> +void cxl_process_mailbox(CXLCCI *cci)
> {
> 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);
> @@ -759,12 +769,12 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
> uint8_t *pl = cxl_dstate->mbox_reg_state + A_CXL_DEV_CMD_PAYLOAD;
> size_t len_out = 0;
>
> - cxl_cmd = &cxl_dstate->cxl_cmd_set[set][cmd];
> + 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, cxl_dstate);
> - assert(len_out <= cxl_dstate->payload_size);
> + ret = (*h)(cxl_cmd, pl, len_in, pl, &len_out, cci);
> + assert(len_out <= cci->payload_max);
> } else {
> ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH;
> }
> @@ -790,20 +800,30 @@ void cxl_process_mailbox(CXLDeviceState *cxl_dstate)
> DOORBELL, 0);
> }
>
> -void cxl_initialize_mailbox(CXLDeviceState *cxl_dstate)
> +void cxl_init_cci(CXLCCI *cci, size_t payload_max)
> {
> - cxl_dstate->cxl_cmd_set = cxl_cmd_set;
> + cci->payload_max = payload_max;
> for (int set = 0; set < 256; set++) {
> for (int cmd = 0; cmd < 256; cmd++) {
> - if (cxl_dstate->cxl_cmd_set[set][cmd].handler) {
> - const struct cxl_cmd *c = &cxl_dstate->cxl_cmd_set[set][cmd];
> + if (cci->cxl_cmd_set[set][cmd].handler) {
> + const struct cxl_cmd *c = &cci->cxl_cmd_set[set][cmd];
> struct cel_log *log =
> - &cxl_dstate->cel_log[cxl_dstate->cel_size];
> + &cci->cel_log[cci->cel_size];
>
> log->opcode = (set << 8) | cmd;
> log->effect = c->effect;
> - cxl_dstate->cel_size++;
> + cci->cel_size++;
> }
> }
> }
> }
> +
> +void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max)
> +{
> + cci->cxl_cmd_set = cxl_cmd_set;
> + cci->d = d;
> +
> + /* No separation for PCI MB as protocol handled in PCI device */
> + cci->intf = d;
> + cxl_init_cci(cci, payload_max);
> +}
> diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
> index 18ad853f5b..0529745786 100644
> --- a/hw/mem/cxl_type3.c
> +++ b/hw/mem/cxl_type3.c
> @@ -716,7 +716,8 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp)
> pci_dev, CXL_COMPONENT_REG_BAR_IDX,
> PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64, mr);
>
> - cxl_device_register_block_init(OBJECT(pci_dev), &ct3d->cxl_dstate);
> + cxl_device_register_block_init(OBJECT(pci_dev), &ct3d->cxl_dstate,
> + &ct3d->cci);
> pci_register_bar(pci_dev, CXL_DEVICE_REG_BAR_IDX,
> PCI_BASE_ADDRESS_SPACE_MEMORY |
> PCI_BASE_ADDRESS_MEM_TYPE_64,
> @@ -922,7 +923,7 @@ static void ct3d_reset(DeviceState *dev)
> uint32_t *write_msk = ct3d->cxl_cstate.crb.cache_mem_regs_write_mask;
>
> cxl_component_register_init_common(reg_state, write_msk, CXL2_TYPE3_DEVICE);
> - cxl_device_register_init_common(&ct3d->cxl_dstate);
> + cxl_device_register_init_t3(ct3d);
> }
>
> static Property ct3_props[] = {
> --
> 2.39.2
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState
2023-09-25 16:11 ` [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState Jonathan Cameron via
2023-09-28 17:44 ` Fan Ni
@ 2023-10-16 15:59 ` Jonathan Cameron via
2023-10-16 15:59 ` Jonathan Cameron
1 sibling, 1 reply; 32+ messages in thread
From: Jonathan Cameron via @ 2023-10-16 15:59 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, 25 Sep 2023 17:11:08 +0100
Jonathan Cameron <Jonathan.Cameron@huawei.com> wrote:
> Enables having multiple CCIs per devices. Each CCI (mailbox) has it's own
> state and command list, so they can't share a single structure.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
I made a mess of reordering patches, so some of Davidlohr's BG ops
patch ended up in this one and the next patch. I'll put that back
where it should be in v2.
>
> +typedef struct CXLCCI {
> + const struct cxl_cmd (*cxl_cmd_set)[256];
> + struct cel_log {
> + uint16_t opcode;
> + uint16_t effect;
> + } cel_log[1 << 16];
> + size_t cel_size;
> +
> + /* background command handling (times in ms) */
> + struct {
> + uint16_t opcode;
> + uint16_t complete_pct;
> + uint16_t ret_code; /* Current value of retcode */
> + uint64_t starttime;
> + /* set by each bg cmd, cleared by the bg_timer when complete */
> + uint64_t runtime;
> + QEMUTimer *timer;
> + } bg;
We don't have bg ops yet!
> + size_t payload_max;
> + /* Pointer to device hosting the CCI */
> + DeviceState *d;
> + /* Pointer to the device hosting the protocol conversion */
> + DeviceState *intf;
> +} CXLCCI;
> +
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState
2023-10-16 15:59 ` Jonathan Cameron via
@ 2023-10-16 15:59 ` Jonathan Cameron
0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron @ 2023-10-16 15:59 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, 25 Sep 2023 17:11:08 +0100
Jonathan Cameron <Jonathan.Cameron@huawei.com> wrote:
> Enables having multiple CCIs per devices. Each CCI (mailbox) has it's own
> state and command list, so they can't share a single structure.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
I made a mess of reordering patches, so some of Davidlohr's BG ops
patch ended up in this one and the next patch. I'll put that back
where it should be in v2.
>
> +typedef struct CXLCCI {
> + const struct cxl_cmd (*cxl_cmd_set)[256];
> + struct cel_log {
> + uint16_t opcode;
> + uint16_t effect;
> + } cel_log[1 << 16];
> + size_t cel_size;
> +
> + /* background command handling (times in ms) */
> + struct {
> + uint16_t opcode;
> + uint16_t complete_pct;
> + uint16_t ret_code; /* Current value of retcode */
> + uint64_t starttime;
> + /* set by each bg cmd, cleared by the bg_timer when complete */
> + uint64_t runtime;
> + QEMUTimer *timer;
> + } bg;
We don't have bg ops yet!
> + size_t payload_max;
> + /* Pointer to device hosting the CCI */
> + DeviceState *d;
> + /* Pointer to the device hosting the protocol conversion */
> + DeviceState *intf;
> +} CXLCCI;
> +
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (2 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-28 18:21 ` Fan Ni
2023-09-25 16:11 ` [PATCH 05/19] hw/pci-bridge/cxl_upstream: Move defintion of device to header Jonathan Cameron via
` (16 subsequent siblings)
20 siblings, 1 reply; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
By moving the parts of the mailbox command handling that are CCI type
specific out to the caller, make the main handling code generic. Rename it
to cxl_process_cci_message() to reflect this new generality.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl_device.h | 5 +++-
hw/cxl/cxl-device-utils.c | 51 ++++++++++++++++++++++++++++++++++++-
hw/cxl/cxl-mailbox-utils.c | 43 ++++++++-----------------------
3 files changed, 64 insertions(+), 35 deletions(-)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index c883d9dd8f..0e3f6c3c0b 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -270,7 +270,10 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
void cxl_init_cci(CXLCCI *cci, size_t payload_max);
-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);
#define cxl_device_cap_init(dstate, reg, cap_id, ver) \
do { \
diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 327949a805..f3a6e17154 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -79,6 +79,25 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
case 4:
return cxl_dstate->mbox_reg_state32[offset / size];
case 8:
+ if (offset == A_CXL_DEV_BG_CMD_STS) {
+ uint64_t bg_status_reg;
+ bg_status_reg = FIELD_DP64(0, CXL_DEV_BG_CMD_STS, OP,
+ cci->bg.opcode);
+ bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
+ PERCENTAGE_COMP, cci->bg.complete_pct);
+ bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
+ RET_CODE, cci->bg.ret_code);
+ /* endian? */
+ cxl_dstate->mbox_reg_state64[offset / size] = bg_status_reg;
+ }
+ if (offset == A_CXL_DEV_MAILBOX_STS) {
+ uint64_t status_reg = cxl_dstate->mbox_reg_state64[offset / size];
+ if (cci->bg.complete_pct) {
+ status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP,
+ 0);
+ cxl_dstate->mbox_reg_state64[offset / size] = status_reg;
+ }
+ }
return cxl_dstate->mbox_reg_state64[offset / size];
default:
g_assert_not_reached();
@@ -157,7 +176,37 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
DOORBELL)) {
- cxl_process_mailbox(cci);
+ uint64_t command_reg =
+ cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD];
+ uint8_t cmd_set = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD,
+ COMMAND_SET);
+ uint8_t cmd = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND);
+ size_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;
+ size_t len_out;
+ uint64_t status_reg;
+ bool bg_started;
+ int rc;
+
+ rc = cxl_process_cci_message(cci, cmd_set, cmd, len_in, pl,
+ &len_out, pl, &bg_started);
+
+ /* Set bg and the return code */
+ status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP,
+ bg_started ? 1 : 0);
+ status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, ERRNO, rc);
+ /* Set the return length */
+ command_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_CMD, COMMAND_SET, cmd_set);
+ command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD,
+ COMMAND, cmd);
+ 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;
+ /* Tell the host we're done */
+ ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
+ DOORBELL, 0);
}
}
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 376367c118..239acc659d 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -754,50 +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;
- size_t len_out = 0;
+ *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)
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing
2023-09-25 16:11 ` [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing Jonathan Cameron via
@ 2023-09-28 18:21 ` Fan Ni
2023-10-13 16:17 ` Jonathan Cameron via
0 siblings, 1 reply; 32+ messages in thread
From: Fan Ni @ 2023-09-28 18:21 UTC (permalink / raw)
To: Jonathan Cameron
Cc: qemu-devel, linux-cxl, Michael Tsirkin, linuxarm, Fan Ni,
Philippe Mathieu-Daud?, Davidlohr Bueso, Gregory Price,
Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, Sep 25, 2023 at 05:11:09PM +0100, Jonathan Cameron wrote:
> By moving the parts of the mailbox command handling that are CCI type
> specific out to the caller, make the main handling code generic. Rename it
> to cxl_process_cci_message() to reflect this new generality.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
Reviewed-by: Fan Ni <fan.ni@samsung.com>
> include/hw/cxl/cxl_device.h | 5 +++-
> hw/cxl/cxl-device-utils.c | 51 ++++++++++++++++++++++++++++++++++++-
> hw/cxl/cxl-mailbox-utils.c | 43 ++++++++-----------------------
> 3 files changed, 64 insertions(+), 35 deletions(-)
>
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index c883d9dd8f..0e3f6c3c0b 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -270,7 +270,10 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
>
> void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
> void cxl_init_cci(CXLCCI *cci, size_t payload_max);
> -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);
>
> #define cxl_device_cap_init(dstate, reg, cap_id, ver) \
> do { \
> diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
> index 327949a805..f3a6e17154 100644
> --- a/hw/cxl/cxl-device-utils.c
> +++ b/hw/cxl/cxl-device-utils.c
> @@ -79,6 +79,25 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
> case 4:
> return cxl_dstate->mbox_reg_state32[offset / size];
> case 8:
> + if (offset == A_CXL_DEV_BG_CMD_STS) {
> + uint64_t bg_status_reg;
> + bg_status_reg = FIELD_DP64(0, CXL_DEV_BG_CMD_STS, OP,
> + cci->bg.opcode);
> + bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
> + PERCENTAGE_COMP, cci->bg.complete_pct);
> + bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
> + RET_CODE, cci->bg.ret_code);
> + /* endian? */
> + cxl_dstate->mbox_reg_state64[offset / size] = bg_status_reg;
> + }
> + if (offset == A_CXL_DEV_MAILBOX_STS) {
> + uint64_t status_reg = cxl_dstate->mbox_reg_state64[offset / size];
> + if (cci->bg.complete_pct) {
> + status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP,
> + 0);
> + cxl_dstate->mbox_reg_state64[offset / size] = status_reg;
> + }
> + }
> return cxl_dstate->mbox_reg_state64[offset / size];
> default:
> g_assert_not_reached();
> @@ -157,7 +176,37 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
>
> if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
> DOORBELL)) {
> - cxl_process_mailbox(cci);
> + uint64_t command_reg =
> + cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD];
> + uint8_t cmd_set = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD,
> + COMMAND_SET);
> + uint8_t cmd = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND);
> + size_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;
> + size_t len_out;
> + uint64_t status_reg;
> + bool bg_started;
> + int rc;
> +
> + rc = cxl_process_cci_message(cci, cmd_set, cmd, len_in, pl,
> + &len_out, pl, &bg_started);
> +
> + /* Set bg and the return code */
> + status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP,
> + bg_started ? 1 : 0);
> + status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, ERRNO, rc);
> + /* Set the return length */
> + command_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_CMD, COMMAND_SET, cmd_set);
> + command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD,
> + COMMAND, cmd);
> + 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;
> + /* Tell the host we're done */
> + ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
> + DOORBELL, 0);
> }
> }
>
> diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> index 376367c118..239acc659d 100644
> --- a/hw/cxl/cxl-mailbox-utils.c
> +++ b/hw/cxl/cxl-mailbox-utils.c
> @@ -754,50 +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;
> - size_t len_out = 0;
>
> + *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)
> --
> 2.39.2
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing
2023-09-28 18:21 ` Fan Ni
@ 2023-10-13 16:17 ` Jonathan Cameron via
2023-10-13 16:17 ` Jonathan Cameron
0 siblings, 1 reply; 32+ messages in thread
From: Jonathan Cameron via @ 2023-10-13 16:17 UTC (permalink / raw)
To: Fan Ni
Cc: qemu-devel, linux-cxl, Michael Tsirkin, linuxarm, Fan Ni,
Philippe Mathieu-Daud?, Davidlohr Bueso, Gregory Price,
Klaus Jensen, Corey Minyard, Klaus Jensen
On Thu, 28 Sep 2023 11:21:31 -0700
Fan Ni <fan.ni@gmx.us> wrote:
> On Mon, Sep 25, 2023 at 05:11:09PM +0100, Jonathan Cameron wrote:
> > By moving the parts of the mailbox command handling that are CCI type
> > specific out to the caller, make the main handling code generic. Rename it
> > to cxl_process_cci_message() to reflect this new generality.
> >
> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > ---
>
> Reviewed-by: Fan Ni <fan.ni@samsung.com>
Thanks!
Unfortunately I've changed how this works for v2.
The aliasing of the mailbox buffer into both the input and output
payload lead to an annoying bug when I was implementing
Get Physical Port State via a tunnel from the Switch CCI.
Having wasted too much time (as I'd forgotten this aliased) I've
changed this code to take a snapshot of the input data instead.
Cleanup is simplified using a g_autofree().
I should be ready to post a new version early next week with this
in place.
Generally I've expanded my testing and the supported commands
etc so hit a bunch of cases where the many many length values in nested
tunneling (there are 5+ IIRC) either didn't correspond to each other
or weren't being read.
I'm not sure a uf real implementation is obliged to check the stuff
that is redundant information, but we probably want QEMU to do so.
Jonathan
>
> > include/hw/cxl/cxl_device.h | 5 +++-
> > hw/cxl/cxl-device-utils.c | 51 ++++++++++++++++++++++++++++++++++++-
> > hw/cxl/cxl-mailbox-utils.c | 43 ++++++++-----------------------
> > 3 files changed, 64 insertions(+), 35 deletions(-)
> >
> > diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> > index c883d9dd8f..0e3f6c3c0b 100644
> > --- a/include/hw/cxl/cxl_device.h
> > +++ b/include/hw/cxl/cxl_device.h
> > @@ -270,7 +270,10 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
> >
> > void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
> > void cxl_init_cci(CXLCCI *cci, size_t payload_max);
> > -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);
> >
> > #define cxl_device_cap_init(dstate, reg, cap_id, ver) \
> > do { \
> > diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
> > index 327949a805..f3a6e17154 100644
> > --- a/hw/cxl/cxl-device-utils.c
> > +++ b/hw/cxl/cxl-device-utils.c
> > @@ -79,6 +79,25 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
> > case 4:
> > return cxl_dstate->mbox_reg_state32[offset / size];
> > case 8:
> > + if (offset == A_CXL_DEV_BG_CMD_STS) {
> > + uint64_t bg_status_reg;
> > + bg_status_reg = FIELD_DP64(0, CXL_DEV_BG_CMD_STS, OP,
> > + cci->bg.opcode);
> > + bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
> > + PERCENTAGE_COMP, cci->bg.complete_pct);
> > + bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
> > + RET_CODE, cci->bg.ret_code);
> > + /* endian? */
> > + cxl_dstate->mbox_reg_state64[offset / size] = bg_status_reg;
> > + }
> > + if (offset == A_CXL_DEV_MAILBOX_STS) {
> > + uint64_t status_reg = cxl_dstate->mbox_reg_state64[offset / size];
> > + if (cci->bg.complete_pct) {
> > + status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP,
> > + 0);
> > + cxl_dstate->mbox_reg_state64[offset / size] = status_reg;
> > + }
> > + }
> > return cxl_dstate->mbox_reg_state64[offset / size];
> > default:
> > g_assert_not_reached();
> > @@ -157,7 +176,37 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
> >
> > if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
> > DOORBELL)) {
> > - cxl_process_mailbox(cci);
> > + uint64_t command_reg =
> > + cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD];
> > + uint8_t cmd_set = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD,
> > + COMMAND_SET);
> > + uint8_t cmd = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND);
> > + size_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;
> > + size_t len_out;
> > + uint64_t status_reg;
> > + bool bg_started;
> > + int rc;
> > +
> > + rc = cxl_process_cci_message(cci, cmd_set, cmd, len_in, pl,
> > + &len_out, pl, &bg_started);
> > +
> > + /* Set bg and the return code */
> > + status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP,
> > + bg_started ? 1 : 0);
> > + status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, ERRNO, rc);
> > + /* Set the return length */
> > + command_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_CMD, COMMAND_SET, cmd_set);
> > + command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD,
> > + COMMAND, cmd);
> > + 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;
> > + /* Tell the host we're done */
> > + ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
> > + DOORBELL, 0);
> > }
> > }
> >
> > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> > index 376367c118..239acc659d 100644
> > --- a/hw/cxl/cxl-mailbox-utils.c
> > +++ b/hw/cxl/cxl-mailbox-utils.c
> > @@ -754,50 +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;
> > - size_t len_out = 0;
> >
> > + *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)
> > --
> > 2.39.2
> >
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing
2023-10-13 16:17 ` Jonathan Cameron via
@ 2023-10-13 16:17 ` Jonathan Cameron
0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron @ 2023-10-13 16:17 UTC (permalink / raw)
To: Fan Ni
Cc: qemu-devel, linux-cxl, Michael Tsirkin, linuxarm, Fan Ni,
Philippe Mathieu-Daud?, Davidlohr Bueso, Gregory Price,
Klaus Jensen, Corey Minyard, Klaus Jensen
On Thu, 28 Sep 2023 11:21:31 -0700
Fan Ni <fan.ni@gmx.us> wrote:
> On Mon, Sep 25, 2023 at 05:11:09PM +0100, Jonathan Cameron wrote:
> > By moving the parts of the mailbox command handling that are CCI type
> > specific out to the caller, make the main handling code generic. Rename it
> > to cxl_process_cci_message() to reflect this new generality.
> >
> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > ---
>
> Reviewed-by: Fan Ni <fan.ni@samsung.com>
Thanks!
Unfortunately I've changed how this works for v2.
The aliasing of the mailbox buffer into both the input and output
payload lead to an annoying bug when I was implementing
Get Physical Port State via a tunnel from the Switch CCI.
Having wasted too much time (as I'd forgotten this aliased) I've
changed this code to take a snapshot of the input data instead.
Cleanup is simplified using a g_autofree().
I should be ready to post a new version early next week with this
in place.
Generally I've expanded my testing and the supported commands
etc so hit a bunch of cases where the many many length values in nested
tunneling (there are 5+ IIRC) either didn't correspond to each other
or weren't being read.
I'm not sure a uf real implementation is obliged to check the stuff
that is redundant information, but we probably want QEMU to do so.
Jonathan
>
> > include/hw/cxl/cxl_device.h | 5 +++-
> > hw/cxl/cxl-device-utils.c | 51 ++++++++++++++++++++++++++++++++++++-
> > hw/cxl/cxl-mailbox-utils.c | 43 ++++++++-----------------------
> > 3 files changed, 64 insertions(+), 35 deletions(-)
> >
> > diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> > index c883d9dd8f..0e3f6c3c0b 100644
> > --- a/include/hw/cxl/cxl_device.h
> > +++ b/include/hw/cxl/cxl_device.h
> > @@ -270,7 +270,10 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
> >
> > void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
> > void cxl_init_cci(CXLCCI *cci, size_t payload_max);
> > -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);
> >
> > #define cxl_device_cap_init(dstate, reg, cap_id, ver) \
> > do { \
> > diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
> > index 327949a805..f3a6e17154 100644
> > --- a/hw/cxl/cxl-device-utils.c
> > +++ b/hw/cxl/cxl-device-utils.c
> > @@ -79,6 +79,25 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
> > case 4:
> > return cxl_dstate->mbox_reg_state32[offset / size];
> > case 8:
> > + if (offset == A_CXL_DEV_BG_CMD_STS) {
> > + uint64_t bg_status_reg;
> > + bg_status_reg = FIELD_DP64(0, CXL_DEV_BG_CMD_STS, OP,
> > + cci->bg.opcode);
> > + bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
> > + PERCENTAGE_COMP, cci->bg.complete_pct);
> > + bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
> > + RET_CODE, cci->bg.ret_code);
> > + /* endian? */
> > + cxl_dstate->mbox_reg_state64[offset / size] = bg_status_reg;
> > + }
> > + if (offset == A_CXL_DEV_MAILBOX_STS) {
> > + uint64_t status_reg = cxl_dstate->mbox_reg_state64[offset / size];
> > + if (cci->bg.complete_pct) {
> > + status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP,
> > + 0);
> > + cxl_dstate->mbox_reg_state64[offset / size] = status_reg;
> > + }
> > + }
> > return cxl_dstate->mbox_reg_state64[offset / size];
> > default:
> > g_assert_not_reached();
> > @@ -157,7 +176,37 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
> >
> > if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
> > DOORBELL)) {
> > - cxl_process_mailbox(cci);
> > + uint64_t command_reg =
> > + cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_CMD];
> > + uint8_t cmd_set = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD,
> > + COMMAND_SET);
> > + uint8_t cmd = FIELD_EX64(command_reg, CXL_DEV_MAILBOX_CMD, COMMAND);
> > + size_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;
> > + size_t len_out;
> > + uint64_t status_reg;
> > + bool bg_started;
> > + int rc;
> > +
> > + rc = cxl_process_cci_message(cci, cmd_set, cmd, len_in, pl,
> > + &len_out, pl, &bg_started);
> > +
> > + /* Set bg and the return code */
> > + status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP,
> > + bg_started ? 1 : 0);
> > + status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, ERRNO, rc);
> > + /* Set the return length */
> > + command_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_CMD, COMMAND_SET, cmd_set);
> > + command_reg = FIELD_DP64(command_reg, CXL_DEV_MAILBOX_CMD,
> > + COMMAND, cmd);
> > + 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;
> > + /* Tell the host we're done */
> > + ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL,
> > + DOORBELL, 0);
> > }
> > }
> >
> > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
> > index 376367c118..239acc659d 100644
> > --- a/hw/cxl/cxl-mailbox-utils.c
> > +++ b/hw/cxl/cxl-mailbox-utils.c
> > @@ -754,50 +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;
> > - size_t len_out = 0;
> >
> > + *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)
> > --
> > 2.39.2
> >
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 05/19] hw/pci-bridge/cxl_upstream: Move defintion of device to header.
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (3 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-28 18:26 ` Fan Ni
2023-09-25 16:11 ` [PATCH 06/19] hw/cxl/i2c_mctp_cxl: Initial device emulation Jonathan Cameron via
` (15 subsequent siblings)
20 siblings, 1 reply; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
To avoid repetition of switch upstream port specific data in the
CXLDeviceState structure it will be necessary to access the switch USP
specific data from mailbox callbacks. Hence move it to cxl_device.h so it
is no longer an opaque structure.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/pci-bridge/cxl_upstream_port.h | 18 ++++++++++++++++++
hw/pci-bridge/cxl_upstream.c | 11 +----------
2 files changed, 19 insertions(+), 10 deletions(-)
diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bridge/cxl_upstream_port.h
new file mode 100644
index 0000000000..b02aa8f659
--- /dev/null
+++ b/include/hw/pci-bridge/cxl_upstream_port.h
@@ -0,0 +1,18 @@
+
+#ifndef CXL_USP_H
+#define CXL_USP_H
+#include "hw/pci/pcie.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/cxl/cxl.h"
+
+typedef struct CXLUpstreamPort {
+ /*< private >*/
+ PCIEPort parent_obj;
+
+ /*< public >*/
+ CXLComponentState cxl_cstate;
+ DOECap doe_cdat;
+ uint64_t sn;
+} CXLUpstreamPort;
+
+#endif /* CXL_SUP_H */
diff --git a/hw/pci-bridge/cxl_upstream.c b/hw/pci-bridge/cxl_upstream.c
index b81bb5fec9..36737189c6 100644
--- a/hw/pci-bridge/cxl_upstream.c
+++ b/hw/pci-bridge/cxl_upstream.c
@@ -14,6 +14,7 @@
#include "hw/pci/msi.h"
#include "hw/pci/pcie.h"
#include "hw/pci/pcie_port.h"
+#include "hw/pci-bridge/cxl_upstream_port.h"
/*
* Null value of all Fs suggested by IEEE RA guidelines for use of
* EU, OUI and CID
@@ -30,16 +31,6 @@
#define CXL_UPSTREAM_PORT_DVSEC_OFFSET \
(CXL_UPSTREAM_PORT_SN_OFFSET + PCI_EXT_CAP_DSN_SIZEOF)
-typedef struct CXLUpstreamPort {
- /*< private >*/
- PCIEPort parent_obj;
-
- /*< public >*/
- CXLComponentState cxl_cstate;
- DOECap doe_cdat;
- uint64_t sn;
-} CXLUpstreamPort;
-
CXLComponentState *cxl_usp_to_cstate(CXLUpstreamPort *usp)
{
return &usp->cxl_cstate;
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 05/19] hw/pci-bridge/cxl_upstream: Move defintion of device to header.
2023-09-25 16:11 ` [PATCH 05/19] hw/pci-bridge/cxl_upstream: Move defintion of device to header Jonathan Cameron via
@ 2023-09-28 18:26 ` Fan Ni
0 siblings, 0 replies; 32+ messages in thread
From: Fan Ni @ 2023-09-28 18:26 UTC (permalink / raw)
To: Jonathan Cameron
Cc: qemu-devel, linux-cxl, Michael Tsirkin, linuxarm, Fan Ni,
Philippe Mathieu-Daud?, Davidlohr Bueso, Gregory Price,
Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, Sep 25, 2023 at 05:11:10PM +0100, Jonathan Cameron wrote:
> To avoid repetition of switch upstream port specific data in the
> CXLDeviceState structure it will be necessary to access the switch USP
> specific data from mailbox callbacks. Hence move it to cxl_device.h so it
> is no longer an opaque structure.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> ---
Reviewed-by: Fan Ni <fan.ni@samsung.com>
> include/hw/pci-bridge/cxl_upstream_port.h | 18 ++++++++++++++++++
> hw/pci-bridge/cxl_upstream.c | 11 +----------
> 2 files changed, 19 insertions(+), 10 deletions(-)
>
> diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bridge/cxl_upstream_port.h
> new file mode 100644
> index 0000000000..b02aa8f659
> --- /dev/null
> +++ b/include/hw/pci-bridge/cxl_upstream_port.h
> @@ -0,0 +1,18 @@
> +
> +#ifndef CXL_USP_H
> +#define CXL_USP_H
> +#include "hw/pci/pcie.h"
> +#include "hw/pci/pcie_port.h"
> +#include "hw/cxl/cxl.h"
> +
> +typedef struct CXLUpstreamPort {
> + /*< private >*/
> + PCIEPort parent_obj;
> +
> + /*< public >*/
> + CXLComponentState cxl_cstate;
> + DOECap doe_cdat;
> + uint64_t sn;
> +} CXLUpstreamPort;
> +
> +#endif /* CXL_SUP_H */
> diff --git a/hw/pci-bridge/cxl_upstream.c b/hw/pci-bridge/cxl_upstream.c
> index b81bb5fec9..36737189c6 100644
> --- a/hw/pci-bridge/cxl_upstream.c
> +++ b/hw/pci-bridge/cxl_upstream.c
> @@ -14,6 +14,7 @@
> #include "hw/pci/msi.h"
> #include "hw/pci/pcie.h"
> #include "hw/pci/pcie_port.h"
> +#include "hw/pci-bridge/cxl_upstream_port.h"
> /*
> * Null value of all Fs suggested by IEEE RA guidelines for use of
> * EU, OUI and CID
> @@ -30,16 +31,6 @@
> #define CXL_UPSTREAM_PORT_DVSEC_OFFSET \
> (CXL_UPSTREAM_PORT_SN_OFFSET + PCI_EXT_CAP_DSN_SIZEOF)
>
> -typedef struct CXLUpstreamPort {
> - /*< private >*/
> - PCIEPort parent_obj;
> -
> - /*< public >*/
> - CXLComponentState cxl_cstate;
> - DOECap doe_cdat;
> - uint64_t sn;
> -} CXLUpstreamPort;
> -
> CXLComponentState *cxl_usp_to_cstate(CXLUpstreamPort *usp)
> {
> return &usp->cxl_cstate;
> --
> 2.39.2
>
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 06/19] hw/cxl/i2c_mctp_cxl: Initial device emulation
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (4 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 05/19] hw/pci-bridge/cxl_upstream: Move defintion of device to header Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 07/19] hw/cxl/mbox: Add Information and Status / Identify command Jonathan Cameron via
` (14 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
The CCI and Fabric Manager APIs are used to configure CXL switches and
devices. DMTF has defined an MCTP binding specification to carry these
messages. The end goal of this work is to hook this up to emulated CXL
switches and devices to allow control of the configuration.
Since this relies on i2c target mode, this can currently only be used with
an SoC that includes the Aspeed I2C controller.
Note, no commands supported at this point.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
Updated to use the v6 MCTP patch set.
Can be tested in similar fashion to NVME-mi (or using the
out of tree patches to add the aspeed-i2c controller to other
i386/pc and arm/virt.
---
include/hw/cxl/cxl_device.h | 5 +
include/hw/pci-bridge/cxl_upstream_port.h | 1 +
hw/cxl/cxl-mailbox-utils.c | 24 ++
hw/cxl/i2c_mctp_cxl.c | 290 ++++++++++++++++++++++
hw/cxl/Kconfig | 4 +
hw/cxl/meson.build | 1 +
6 files changed, 325 insertions(+)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index 0e3f6c3c0b..ba74908da5 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -274,6 +274,10 @@ 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);
+void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
+ size_t payload_max);
+void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
+ size_t payload_max);
#define cxl_device_cap_init(dstate, reg, cap_id, ver) \
do { \
@@ -375,6 +379,7 @@ struct CXLType3Dev {
CXLComponentState cxl_cstate;
CXLDeviceState cxl_dstate;
CXLCCI cci; /* Primary PCI mailbox CCI */
+ CXLCCI oob_mctp_cci; /* Initialized only if targetted */
/* DOE */
DOECap doe_cdat;
diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bridge/cxl_upstream_port.h
index b02aa8f659..15db8c8582 100644
--- a/include/hw/pci-bridge/cxl_upstream_port.h
+++ b/include/hw/pci-bridge/cxl_upstream_port.h
@@ -11,6 +11,7 @@ typedef struct CXLUpstreamPort {
/*< public >*/
CXLComponentState cxl_cstate;
+ CXLCCI mctpcci;
DOECap doe_cdat;
uint64_t sn;
} CXLUpstreamPort;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 239acc659d..27b6828d4f 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -804,3 +804,27 @@ void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max)
cci->intf = d;
cxl_init_cci(cci, payload_max);
}
+
+static const struct cxl_cmd cxl_cmd_set_t3_mctp[256][256] = {
+};
+
+void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
+ size_t payload_max)
+{
+ cci->cxl_cmd_set = cxl_cmd_set_t3_mctp;
+ cci->d = d;
+ cci->intf = intf;
+ cxl_init_cci(cci, payload_max);
+}
+
+static const struct cxl_cmd cxl_cmd_set_usp_mctp[256][256] = {
+};
+
+void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
+ size_t payload_max)
+{
+ cci->cxl_cmd_set = cxl_cmd_set_usp_mctp;
+ cci->d = d;
+ cci->intf = intf;
+ cxl_init_cci(cci, payload_max);
+}
diff --git a/hw/cxl/i2c_mctp_cxl.c b/hw/cxl/i2c_mctp_cxl.c
new file mode 100644
index 0000000000..a55448c8fe
--- /dev/null
+++ b/hw/cxl/i2c_mctp_cxl.c
@@ -0,0 +1,290 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Emulation of a CXL Switch Fabric Management interface over MCTP over I2C.
+ *
+ * Copyright (c) 2023 Huawei Technologies.
+ *
+ * Reference list:
+ * From www.dmtf.org
+ * DSP0236 Management Component Transport Protocol (MCTP) Base Specification
+ * 1.3.0
+ * DPS0234 CXL Fabric Manager API over MCTP Binding Specification 1.0.0
+ * DSP0281 CXL Type 3 Deivce Component Command Interface over MCTP Binding
+ * Specification (note some commands apply to switches as well)
+ * From www.computeexpresslink.org
+ * Compute Express Link (CXL) Specification revision 3.0 Version 1.0
+ */
+
+#include "qemu/osdep.h"
+#include "hw/i2c/i2c.h"
+#include "hw/i2c/mctp.h"
+#include "net/mctp.h"
+#include "hw/irq.h"
+#include "migration/vmstate.h"
+#include "qapi/error.h"
+#include "hw/cxl/cxl.h"
+#include "hw/pci-bridge/cxl_upstream_port.h"
+#include "hw/pci/pcie.h"
+#include "hw/pci/pcie_port.h"
+#include "hw/qdev-properties.h"
+#include "hw/registerfields.h"
+
+#define TYPE_I2C_MCTP_CXL "i2c_mctp_cxl"
+
+/* DMTF DSP0234 CXL Fabric Manager API over MCTP Binding Specification */
+#define MCTP_MT_CXL_FMAPI 0x7
+/*
+ * DMTF DSP0281 CXL Type 3 Deivce Component Command Interface over MCTP
+ * Binding Specification
+ */
+#define MCTP_MT_CXL_TYPE3 0x8
+
+/* FMAPI binding specification defined */
+#define MCTP_CXL_MAX_MSG_LEN 1088
+
+/* Implementation choice - may make this configurable */
+#define MCTP_CXL_MAILBOX_BYTES 512
+
+typedef struct CXLMCTPMessage {
+ /*
+ * DSP0236 (MCTP Base) Integrity Check + Message Type
+ * DSP0234/DSP0281 (CXL bindings) state no Integrity Check
+ * so just the message type.
+ */
+ uint8_t message_type;
+ /* Remaing fields from CXL r3.0 Table 7-14 CCI Message Format */
+ uint8_t category;
+ uint8_t tag;
+ uint8_t rsvd;
+ /*
+ * CXL r3.0 - Table 8-36 Generic Component Command Opcodes:
+ * Command opcode is split into two sub fields
+ */
+ uint8_t command;
+ uint8_t command_set;
+ uint8_t pl_length[3];
+ uint16_t rc;
+ uint16_t vendor_status;
+ uint8_t payload[];
+} QEMU_PACKED CXLMCTPMessage;
+
+enum cxl_dev_type {
+ cxl_type3,
+ cxl_switch,
+};
+
+struct I2C_MCTP_CXL_State {
+ MCTPI2CEndpoint mctp;
+ PCIDevice *target;
+ CXLCCI *cci;
+ enum cxl_dev_type type;
+ size_t len;
+ int64_t pos;
+ uint8_t buffer[MCTP_CXL_MAX_MSG_LEN];
+ uint8_t scratch[MCTP_CXL_MAX_MSG_LEN];
+};
+
+OBJECT_DECLARE_SIMPLE_TYPE(I2C_MCTP_CXL_State, I2C_MCTP_CXL)
+
+static Property i2c_mctp_cxl_props[] = {
+ DEFINE_PROP_LINK("target", I2C_MCTP_CXL_State,
+ target, TYPE_PCI_DEVICE, PCIDevice *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static size_t i2c_mctp_cxl_get_buf(MCTPI2CEndpoint *mctp,
+ const uint8_t **buf,
+ size_t maxlen,
+ uint8_t *mctp_flags)
+{
+ I2C_MCTP_CXL_State *s = I2C_MCTP_CXL(mctp);
+ size_t len;
+
+ len = MIN(maxlen, s->len - s->pos);
+
+ if (len == 0) {
+ return 0;
+ }
+
+ if (s->pos == 0) {
+ *mctp_flags = FIELD_DP8(*mctp_flags, MCTP_H_FLAGS, SOM, 1);
+ }
+
+ *buf = s->scratch + s->pos;
+ s->pos += len;
+
+ if (s->pos == s->len) {
+ *mctp_flags = FIELD_DP8(*mctp_flags, MCTP_H_FLAGS, EOM, 1);
+
+ s->pos = s->len = 0;
+ }
+
+ return len;
+}
+
+static int i2c_mctp_cxl_put_buf(MCTPI2CEndpoint *mctp,
+ uint8_t *buf, size_t len)
+{
+ I2C_MCTP_CXL_State *s = I2C_MCTP_CXL(mctp);
+
+ if (s->len + len > MCTP_CXL_MAX_MSG_LEN) {
+ return -1;
+ }
+
+ memcpy(s->buffer + s->len, buf, len);
+ s->len += len;
+
+ return 0;
+}
+
+static size_t i2c_mctp_cxl_get_types(MCTPI2CEndpoint *mctp,
+ const uint8_t **data)
+{
+ static const uint8_t buf[] = {
+ 0x0, /* Success */
+ 2, /* Message types in list - supported in addition to control */
+ MCTP_MT_CXL_FMAPI,
+ MCTP_MT_CXL_TYPE3,
+ };
+ *data = buf;
+
+ return sizeof(buf);
+}
+
+static void i2c_mctp_cxl_reset_message(MCTPI2CEndpoint *mctp)
+{
+ I2C_MCTP_CXL_State *s = I2C_MCTP_CXL(mctp);
+
+ s->len = 0;
+}
+
+static void i2c_mctp_cxl_handle_message(MCTPI2CEndpoint *mctp)
+{
+ I2C_MCTP_CXL_State *s = I2C_MCTP_CXL(mctp);
+ CXLMCTPMessage *msg = (CXLMCTPMessage *)s->buffer;
+ CXLMCTPMessage *buf = (CXLMCTPMessage *)s->scratch;
+
+ *buf = (CXLMCTPMessage) {
+ .message_type = msg->message_type,
+ .category = 1,
+ .tag = msg->tag,
+ .command = msg->command,
+ .command_set = msg->command_set,
+ };
+ s->pos = sizeof(buf);
+
+ if (s->cci) {
+ bool bg_started;
+ size_t len_out = 0;
+ size_t len_in;
+ int rc;
+
+ /*
+ * Check the message types - there are two because in theory
+ * the opcodes for different device types could overlap in future.
+ * In practice that hasn't happened yet, but best to keep to the
+ * specifications.
+ *
+ * The binding specifications are not closely coupled to the
+ * CXL specification which makes interpretation tricky.
+ *
+ * Assumption that no non type3 commands sets will be defined below
+ * the FM-API (there is a lot more room above).
+ *
+ * For both bindings, command sets < 0x40 are valid.
+ * For Type3 they start at 0x40 - we allow up to start of FMAPI
+ * For FMAPI they start at 0x51 - we allow up to 0x56.
+ */
+
+ if (!((msg->message_type == MCTP_MT_CXL_TYPE3 ||
+ msg->message_type == MCTP_MT_CXL_FMAPI) &&
+ msg->command_set < 0x40) &&
+ !(msg->message_type == MCTP_MT_CXL_TYPE3 &&
+ msg->command_set > 0x40 && msg->command_set < 0x51) &&
+ !(msg->message_type == MCTP_MT_CXL_FMAPI &&
+ msg->command_set >= 0x51 && msg->command_set < 0x56)) {
+ buf->rc = CXL_MBOX_UNSUPPORTED;
+ st24_le_p(buf->pl_length, len_out);
+ s->pos = 0;
+ i2c_mctp_schedule_send(mctp);
+ return;
+ }
+
+ len_in = msg->pl_length[2] << 16 | msg->pl_length[1] << 8 |
+ msg->pl_length[0];
+
+ rc = cxl_process_cci_message(s->cci, msg->command_set, msg->command,
+ len_in, msg->payload,
+ &len_out,
+ s->scratch + sizeof(CXLMCTPMessage),
+ &bg_started);
+ buf->rc = rc;
+ s->len += len_out;
+ st24_le_p(buf->pl_length, len_out);
+ s->pos = 0;
+ i2c_mctp_schedule_send(mctp);
+ } else {
+ g_assert_not_reached(); /* The cci must be hooked up */
+ }
+}
+
+static void i2c_mctp_cxl_realize(DeviceState *d, Error **errp)
+{
+ I2C_MCTP_CXL_State *s = I2C_MCTP_CXL(d);
+
+ /* Check this is a type we support */
+ if (object_dynamic_cast(OBJECT(s->target), TYPE_CXL_USP)) {
+ CXLUpstreamPort *usp = CXL_USP(s->target);
+
+ s->type = cxl_switch;
+ s->cci = &usp->mctpcci;
+
+ cxl_initialize_usp_mctpcci(s->cci, DEVICE(s->target), d,
+ MCTP_CXL_MAILBOX_BYTES);
+
+ return;
+ }
+
+ if (object_dynamic_cast(OBJECT(s->target), TYPE_CXL_TYPE3)) {
+ CXLType3Dev *ct3d = CXL_TYPE3(s->target);
+
+ s->type = cxl_type3;
+ s->cci = &ct3d->oob_mctp_cci;
+
+ cxl_initialize_t3_mctpcci(s->cci, DEVICE(s->target), d,
+ MCTP_CXL_MAILBOX_BYTES);
+ return;
+ }
+
+ error_setg(errp, "Unhandled target type for CXL MCTP EP");
+}
+
+static void i2c_mctp_cxl_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ MCTPI2CEndpointClass *mc = MCTP_I2C_ENDPOINT_CLASS(klass);
+
+ dc->realize = i2c_mctp_cxl_realize;
+ mc->get_types = i2c_mctp_cxl_get_types;
+ mc->get_buf = i2c_mctp_cxl_get_buf;
+ mc->put_buf = i2c_mctp_cxl_put_buf;
+
+ mc->handle = i2c_mctp_cxl_handle_message;
+ mc->reset = i2c_mctp_cxl_reset_message;
+ device_class_set_props(dc, i2c_mctp_cxl_props);
+}
+
+static const TypeInfo i2c_mctp_cxl_info = {
+ .name = TYPE_I2C_MCTP_CXL,
+ .parent = TYPE_MCTP_I2C_ENDPOINT,
+ .instance_size = sizeof(I2C_MCTP_CXL_State),
+ .class_init = i2c_mctp_cxl_class_init,
+};
+
+static void i2c_mctp_cxl_register_types(void)
+{
+ type_register_static(&i2c_mctp_cxl_info);
+}
+
+type_init(i2c_mctp_cxl_register_types)
diff --git a/hw/cxl/Kconfig b/hw/cxl/Kconfig
index 8e67519b16..bc259fdf67 100644
--- a/hw/cxl/Kconfig
+++ b/hw/cxl/Kconfig
@@ -1,3 +1,7 @@
config CXL
bool
default y if PCI_EXPRESS
+
+config I2C_MCTP_CXL
+ bool
+ default y if CXL && I2C_MCTP
diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
index e261ff3881..0152a2b190 100644
--- a/hw/cxl/meson.build
+++ b/hw/cxl/meson.build
@@ -10,5 +10,6 @@ system_ss.add(when: 'CONFIG_CXL',
if_false: files(
'cxl-host-stubs.c',
))
+system_ss.add(when: 'CONFIG_I2C_MCTP_CXL', if_true: files('i2c_mctp_cxl.c'))
system_ss.add(when: 'CONFIG_ALL', if_true: files('cxl-host-stubs.c'))
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 07/19] hw/cxl/mbox: Add Information and Status / Identify command
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (5 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 06/19] hw/cxl/i2c_mctp_cxl: Initial device emulation Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 08/19] docs: cxl: Add example commandline for MCTP CXL CCIs Jonathan Cameron via
` (13 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Add this command that is only available via out of band CCIs. It replicates
information that can be discovered inband via PCI config space.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 48 ++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 27b6828d4f..84dc9d8963 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -11,6 +11,7 @@
#include "hw/cxl/cxl.h"
#include "hw/cxl/cxl_events.h"
#include "hw/pci/pci.h"
+#include "hw/pci-bridge/cxl_upstream_port.h"
#include "qemu/cutils.h"
#include "qemu/log.h"
#include "qemu/units.h"
@@ -44,6 +45,8 @@
*/
enum {
+ INFOSTAT = 0x00,
+ #define IS_IDENTIFY 0x1
EVENTS = 0x01,
#define GET_RECORDS 0x0
#define CLEAR_RECORDS 0x1
@@ -203,6 +206,49 @@ static CXLRetCode cmd_events_set_interrupt_policy(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+/* CXL r3.0 section 8.2.9.1.1: Identify (Opcode 0001h) */
+static CXLRetCode cmd_infostat_identify(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ PCIDeviceClass *class = PCI_DEVICE_GET_CLASS(cci->d);
+ struct {
+ uint16_t pcie_vid;
+ uint16_t pcie_did;
+ uint16_t pcie_subsys_vid;
+ uint16_t pcie_subsys_id;
+ uint64_t sn;
+ uint8_t max_message_size;
+ uint8_t component_type;
+ } QEMU_PACKED *is_identify;
+ QEMU_BUILD_BUG_ON(sizeof(*is_identify) != 18);
+
+ is_identify = (void *)payload_out;
+ memset(is_identify, 0, sizeof(*is_identify));
+ is_identify->pcie_vid = class->vendor_id;
+ is_identify->pcie_did = class->device_id;
+ if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_USP)) {
+ is_identify->sn = CXL_USP(cci->d)->sn;
+ /* Subsystem info not defined for a USP */
+ is_identify->pcie_subsys_vid = 0;
+ is_identify->pcie_subsys_id = 0;
+ is_identify->component_type = 0x0; /* Switch */
+ } else if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_TYPE3)) {
+ is_identify->sn = CXL_TYPE3(cci->d)->sn;
+ is_identify->pcie_subsys_vid = class->subsystem_vendor_id;
+ is_identify->pcie_subsys_id = class->subsystem_id;
+ is_identify->component_type = 0x3; /* Type 3 */
+ }
+
+ /* TODO: Allow this to vary across different CCIs */
+ is_identify->max_message_size = 9; /* 512 bytes - MCTP_CXL_MAILBOX_BYTES */
+ *len_out = sizeof(*is_identify);
+ return CXL_MBOX_SUCCESS;
+}
+
/* 8.2.9.2.1 */
static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
uint8_t *payload_in,
@@ -806,6 +852,7 @@ void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max)
}
static const struct cxl_cmd cxl_cmd_set_t3_mctp[256][256] = {
+ [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
};
void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
@@ -818,6 +865,7 @@ void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
}
static const struct cxl_cmd cxl_cmd_set_usp_mctp[256][256] = {
+ [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
};
void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 08/19] docs: cxl: Add example commandline for MCTP CXL CCIs
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (6 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 07/19] hw/cxl/mbox: Add Information and Status / Identify command Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 09/19] hw/cxl/mbox: Add Physical Switch Identify command Jonathan Cameron via
` (12 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Add initial documentation for the MCTP over I2C management device. At
current time this can only be used with the Aspeed I2C controller which
is only available in aspeed SoCs, though can be added to other
emulated boards.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
docs/system/devices/cxl.rst | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/docs/system/devices/cxl.rst b/docs/system/devices/cxl.rst
index 6ab5f72473..dfe5577599 100644
--- a/docs/system/devices/cxl.rst
+++ b/docs/system/devices/cxl.rst
@@ -406,6 +406,33 @@ OS management of CXL memory devices as described here.
* CONFIG_CXL_PORT
* CONFIG_CXL_REGION
+
+CCI access via MCTP over I2C
+----------------------------
+
+In order to make use of this device, an I2C controller that supports MCTP
+is required. The aspeed-i2c controller is an example of such a controller.
+
+Both CXL switches and CXL Type 3 devices support configuration via
+MCTP access to Component Command Interfaces (CCIs) on the devices.
+
+Example configuration:
+
+ -device cxl-upstream,port=33,bus=root_port0,id=us0,multifunction=on,addr=0.0,sn=12345678 \
+ -device cxl-downstream,port=0,bus=us0,id=swport0,chassis=0,slot=4 \
+ -device cxl-downstream,port=1,bus=us0,id=swport1,chassis=0,slot=5 \
+ -device cxl-downstream,port=2,bus=us0,id=swport2,chassis=0,slot=6 \
+ -device cxl-type3,bus=swport0,persistent-memdev=cxl-mem1,id=cxl-pmem0,lsa=cxl-lsa1,sn=3 \
+ -device cxl-type3,bus=swport1,persistent-memdev=cxl-mem2,id=cxl-pmem1,lsa=cxl-lsa2,sn=4 \
+ -device cxl-type3,bus=swport2,persistent-memdev=cxl-mem3,id=cxl-pmem2,lsa=cxl-lsa3,sn=5 \
+ -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=4,target=us0 \
+ -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=5,target=cxl-pmem0 \
+ -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=6,target=cxl-pmem1 \
+ -device i2c_mctp_cxl,bus=aspeed.i2c.bus.0,address=7,target=cxl-pmem2
+
+Guest OS communication with the MCTP CCI can then be established using standard
+MCTP configuration tools.
+
References
----------
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 09/19] hw/cxl/mbox: Add Physical Switch Identify command.
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (7 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 08/19] docs: cxl: Add example commandline for MCTP CXL CCIs Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 10/19] hw/cxl: Add a switch mailbox CCI function Jonathan Cameron via
` (11 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Enable it for MCTP CCI for the switch. Will shortly be enabled for switch
CCI as well.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl.h | 6 ++++
hw/cxl/cxl-mailbox-utils.c | 65 ++++++++++++++++++++++++++++++++++
hw/pci-bridge/cxl_downstream.c | 4 +--
3 files changed, 72 insertions(+), 3 deletions(-)
diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h
index 4944725849..75e47b6864 100644
--- a/include/hw/cxl/cxl.h
+++ b/include/hw/cxl/cxl.h
@@ -61,4 +61,10 @@ OBJECT_DECLARE_SIMPLE_TYPE(CXLHost, PXB_CXL_HOST)
typedef struct CXLUpstreamPort CXLUpstreamPort;
DECLARE_INSTANCE_CHECKER(CXLUpstreamPort, CXL_USP, TYPE_CXL_USP)
CXLComponentState *cxl_usp_to_cstate(CXLUpstreamPort *usp);
+
+#define TYPE_CXL_DSP "cxl-downstream"
+
+typedef struct CXLDownstreamPort CXLDownstreamPort;
+DECLARE_INSTANCE_CHECKER(CXLDownstreamPort, CXL_DSP, TYPE_CXL_DSP)
+
#endif
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 84dc9d8963..e319cfccf7 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -70,6 +70,8 @@ enum {
#define GET_POISON_LIST 0x0
#define INJECT_POISON 0x1
#define CLEAR_POISON 0x2
+ PHYSICAL_SWITCH = 0x51,
+ #define IDENTIFY_SWITCH_DEVICE 0x0
};
@@ -249,6 +251,67 @@ static CXLRetCode cmd_infostat_identify(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+static void cxl_set_dsp_active_bm(PCIBus *b, PCIDevice *d,
+ void *private)
+{
+ uint8_t *bm = private;
+ if (object_dynamic_cast(OBJECT(d), TYPE_CXL_DSP)) {
+ uint8_t port = PCIE_PORT(d)->port;
+ bm[port / 8] |= 1 << (port % 8);
+ }
+}
+
+/* CXL r3 8.2.9.1.1 */
+static CXLRetCode cmd_identify_switch_device(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ PCIEPort *usp = PCIE_PORT(cci->d);
+ PCIBus *bus = &PCI_BRIDGE(cci->d)->sec_bus;
+ int num_phys_ports = pcie_count_ds_ports(bus);
+
+ struct cxl_fmapi_ident_switch_dev_resp_pl {
+ uint8_t ingress_port_id;
+ uint8_t rsvd;
+ uint8_t num_physical_ports;
+ uint8_t num_vcss;
+ uint8_t active_port_bitmask[0x20];
+ uint8_t active_vcs_bitmask[0x20];
+ uint16_t total_vppbs;
+ uint16_t bound_vppbs;
+ uint8_t num_hdm_decoders_per_usp;
+ } QEMU_PACKED *out;
+ QEMU_BUILD_BUG_ON(sizeof(*out) != 0x49);
+
+ out = (struct cxl_fmapi_ident_switch_dev_resp_pl *)payload_out;
+ *out = (struct cxl_fmapi_ident_switch_dev_resp_pl) {
+ .num_physical_ports = num_phys_ports + 1, /* 1 USP */
+ .num_vcss = 1, /* Not yet support multiple VCS - potentialy tricky */
+ .active_vcs_bitmask[0] = 0x1,
+ .total_vppbs = num_phys_ports + 1,
+ .bound_vppbs = num_phys_ports + 1,
+ .num_hdm_decoders_per_usp = 4,
+ };
+
+ /* Depends on the CCI type */
+ if (object_dynamic_cast(OBJECT(cci->intf), TYPE_PCIE_PORT)) {
+ out->ingress_port_id = PCIE_PORT(cci->intf)->port;
+ } else {
+ /* MCTP? */
+ out->ingress_port_id = 0;
+ }
+
+ pci_for_each_device_under_bus(bus, cxl_set_dsp_active_bm,
+ out->active_port_bitmask);
+ out->active_port_bitmask[usp->port / 8] |= (1 << usp->port % 8);
+
+ *len_out = sizeof(*out);
+
+ return CXL_MBOX_SUCCESS;
+}
/* 8.2.9.2.1 */
static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
uint8_t *payload_in,
@@ -866,6 +929,8 @@ void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
static const struct cxl_cmd cxl_cmd_set_usp_mctp[256][256] = {
[INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
+ [PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] = {"IDENTIFY_SWITCH_DEVICE",
+ cmd_identify_switch_device, 0, 0x49 },
};
void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
diff --git a/hw/pci-bridge/cxl_downstream.c b/hw/pci-bridge/cxl_downstream.c
index 8c0f759add..8d99e1e96d 100644
--- a/hw/pci-bridge/cxl_downstream.c
+++ b/hw/pci-bridge/cxl_downstream.c
@@ -13,6 +13,7 @@
#include "hw/pci/msi.h"
#include "hw/pci/pcie.h"
#include "hw/pci/pcie_port.h"
+#include "hw/cxl/cxl.h"
#include "qapi/error.h"
typedef struct CXLDownstreamPort {
@@ -23,9 +24,6 @@ typedef struct CXLDownstreamPort {
CXLComponentState cxl_cstate;
} CXLDownstreamPort;
-#define TYPE_CXL_DSP "cxl-downstream"
-DECLARE_INSTANCE_CHECKER(CXLDownstreamPort, CXL_DSP, TYPE_CXL_DSP)
-
#define CXL_DOWNSTREAM_PORT_MSI_OFFSET 0x70
#define CXL_DOWNSTREAM_PORT_MSI_NR_VECTOR 1
#define CXL_DOWNSTREAM_PORT_EXP_OFFSET 0x90
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 10/19] hw/cxl: Add a switch mailbox CCI function
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (8 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 09/19] hw/cxl/mbox: Add Physical Switch Identify command Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 11/19] hw/pci-bridge/cxl_downstream: Set default link width and link speed Jonathan Cameron via
` (10 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
CXL switch CCIs were added in CXL r3.0. They are a PCI function,
identified by class code that provides a CXL mailbox (identical
to that previously defined for CXL type 3 memory devices) over which
various FM-API commands may be used. Whilst the intent of this
feature is enable switch control from a BMC attached to a switch
upstream port, it is also useful to allow emulation of this feature
on the upstream port connected to a host using the CXL devices as
this greatly simplifies testing.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
- Use assigned Huawei VID and Device ID pair for this emulated device.
---
include/hw/cxl/cxl_component.h | 3 +-
include/hw/cxl/cxl_device.h | 15 +++
include/hw/pci-bridge/cxl_upstream_port.h | 1 +
hw/cxl/cxl-device-utils.c | 27 ++++++
hw/cxl/cxl-mailbox-utils.c | 21 ++++
hw/cxl/switch-mailbox-cci.c | 111 ++++++++++++++++++++++
hw/cxl/meson.build | 1 +
7 files changed, 178 insertions(+), 1 deletion(-)
diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h
index e52dd8d2b9..5227a8e833 100644
--- a/include/hw/cxl/cxl_component.h
+++ b/include/hw/cxl/cxl_component.h
@@ -26,7 +26,8 @@ enum reg_type {
CXL2_LOGICAL_DEVICE,
CXL2_ROOT_PORT,
CXL2_UPSTREAM_PORT,
- CXL2_DOWNSTREAM_PORT
+ CXL2_DOWNSTREAM_PORT,
+ CXL3_SWITCH_MAILBOX_CCI,
};
/*
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index ba74908da5..a99a7e6274 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -221,8 +221,10 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev,
CXLCCI *cci);
typedef struct CXLType3Dev CXLType3Dev;
+typedef struct CSWMBCCIDev CSWMBCCIDev;
/* Set up default values for the register block */
void cxl_device_register_init_t3(CXLType3Dev *ct3d);
+void cxl_device_register_init_swcci(CSWMBCCIDev *sw);
/*
* CXL 2.0 - 8.2.8.1 including errata F4
@@ -269,6 +271,8 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE,
CXL_DEVICE_CAP_REG_SIZE * 2)
void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max);
+void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf,
+ DeviceState *d, size_t payload_max);
void cxl_init_cci(CXLCCI *cci, size_t payload_max);
int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
size_t len_in, uint8_t *pl_in,
@@ -412,6 +416,17 @@ struct CXLType3Class {
uint8_t *data);
};
+struct CSWMBCCIDev {
+ PCIDevice parent_obj;
+ PCIDevice *target;
+ CXLComponentState cxl_cstate;
+ CXLDeviceState cxl_dstate;
+ CXLCCI *cci;
+};
+
+#define TYPE_CXL_SWITCH_MAILBOX_CCI "cxl-switch-mailbox-cci"
+OBJECT_DECLARE_TYPE(CSWMBCCIDev, CSWMBCCIClass, CXL_SWITCH_MAILBOX_CCI)
+
MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data,
unsigned size, MemTxAttrs attrs);
MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data,
diff --git a/include/hw/pci-bridge/cxl_upstream_port.h b/include/hw/pci-bridge/cxl_upstream_port.h
index 15db8c8582..7275102cfa 100644
--- a/include/hw/pci-bridge/cxl_upstream_port.h
+++ b/include/hw/pci-bridge/cxl_upstream_port.h
@@ -12,6 +12,7 @@ typedef struct CXLUpstreamPort {
/*< public >*/
CXLComponentState cxl_cstate;
CXLCCI mctpcci;
+ CXLCCI swcci;
DOECap doe_cdat;
uint64_t sn;
} CXLUpstreamPort;
diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index f3a6e17154..3dd45fb262 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -67,6 +67,9 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size)
if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
+ } else if (object_dynamic_cast(OBJECT(cci->intf),
+ TYPE_CXL_SWITCH_MAILBOX_CCI)) {
+ cxl_dstate = &CXL_SWITCH_MAILBOX_CCI(cci->intf)->cxl_dstate;
} else {
return 0;
}
@@ -154,6 +157,9 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value,
if (object_dynamic_cast(OBJECT(cci->intf), TYPE_CXL_TYPE3)) {
cxl_dstate = &CXL_TYPE3(cci->intf)->cxl_dstate;
+ } else if (object_dynamic_cast(OBJECT(cci->intf),
+ TYPE_CXL_SWITCH_MAILBOX_CCI)) {
+ cxl_dstate = &CXL_SWITCH_MAILBOX_CCI(cci->intf)->cxl_dstate;
} else {
return;
}
@@ -372,6 +378,27 @@ void cxl_device_register_init_t3(CXLType3Dev *ct3d)
CXL_MAILBOX_MAX_PAYLOAD_SIZE);
}
+void cxl_device_register_init_swcci(CSWMBCCIDev *sw)
+{
+ CXLDeviceState *cxl_dstate = &sw->cxl_dstate;
+ uint64_t *cap_h = cxl_dstate->caps_reg_state64;
+ const int cap_count = 3;
+
+ /* CXL Device Capabilities Array Register */
+ ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_ID, 0);
+ ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1);
+ ARRAY_FIELD_DP64(cap_h, CXL_DEV_CAP_ARRAY, CAP_COUNT, cap_count);
+
+ cxl_device_cap_init(cxl_dstate, DEVICE_STATUS, 1, 2);
+ device_reg_init_common(cxl_dstate);
+
+ cxl_device_cap_init(cxl_dstate, MAILBOX, 2, 1);
+ mailbox_reg_init_common(cxl_dstate);
+
+ cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000, 1);
+ memdev_reg_init_common(cxl_dstate);
+}
+
uint64_t cxl_device_get_timestamp(CXLDeviceState *cxl_dstate)
{
uint64_t time, delta;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index e319cfccf7..9d5b5dadbd 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -863,6 +863,18 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
cmd_media_clear_poison, 72, 0 },
};
+static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
+ [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
+ [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 },
+ [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 8,
+ IMMEDIATE_POLICY_CHANGE },
+ [LOGS][GET_SUPPORTED] = { "LOGS_GET_SUPPORTED", cmd_logs_get_supported, 0,
+ 0 },
+ [LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 },
+ [PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] = {"IDENTIFY_SWITCH_DEVICE",
+ cmd_identify_switch_device, 0, 0x49 },
+};
+
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)
@@ -904,6 +916,15 @@ void cxl_init_cci(CXLCCI *cci, size_t payload_max)
}
}
+void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf,
+ DeviceState *d, size_t payload_max)
+{
+ cci->cxl_cmd_set = cxl_cmd_set_sw;
+ cci->d = d;
+ cci->intf = intf;
+ cxl_init_cci(cci, payload_max);
+}
+
void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max)
{
cci->cxl_cmd_set = cxl_cmd_set;
diff --git a/hw/cxl/switch-mailbox-cci.c b/hw/cxl/switch-mailbox-cci.c
new file mode 100644
index 0000000000..ba399c6240
--- /dev/null
+++ b/hw/cxl/switch-mailbox-cci.c
@@ -0,0 +1,111 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Emulation of a CXL Switch Mailbox CCI PCIe function.
+ *
+ * Copyright (c) 2023 Huawei Technologies.
+ *
+ * From www.computeexpresslink.org
+ * Compute Express Link (CXL) Specification revision 3.0 Version 1.0
+ */
+#include "qemu/osdep.h"
+#include "hw/pci/pci.h"
+#include "hw/pci-bridge/cxl_upstream_port.h"
+#include "qapi/error.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+#include "hw/qdev-properties.h"
+#include "hw/cxl/cxl.h"
+
+static void cswmbcci_reset(DeviceState *dev)
+{
+ CSWMBCCIDev *cswmb = CXL_SWITCH_MAILBOX_CCI(dev);
+ cxl_device_register_init_swcci(cswmb);
+}
+
+static void cswbcci_realize(PCIDevice *pci_dev, Error **errp)
+{
+ CSWMBCCIDev *cswmb = CXL_SWITCH_MAILBOX_CCI(pci_dev);
+ CXLComponentState *cxl_cstate = &cswmb->cxl_cstate;
+ CXLDeviceState *cxl_dstate = &cswmb->cxl_dstate;
+ CXLDVSECRegisterLocator *regloc_dvsec;
+ CXLUpstreamPort *usp;
+
+ if (!cswmb->target) {
+ error_setg(errp, "Target not set");
+ return;
+ }
+ usp = CXL_USP(cswmb->target);
+
+ pcie_endpoint_cap_init(pci_dev, 0x80);
+ cxl_cstate->dvsec_offset = 0x100;
+ cxl_cstate->pdev = pci_dev;
+ cswmb->cci = &usp->swcci;
+ cxl_device_register_block_init(OBJECT(pci_dev), cxl_dstate, cswmb->cci);
+ pci_register_bar(pci_dev, 0,
+ PCI_BASE_ADDRESS_SPACE_MEMORY |
+ PCI_BASE_ADDRESS_MEM_TYPE_64,
+ &cxl_dstate->device_registers);
+ regloc_dvsec = &(CXLDVSECRegisterLocator) {
+ .rsvd = 0,
+ .reg0_base_lo = RBI_CXL_DEVICE_REG | 0,
+ .reg0_base_hi = 0,
+ };
+ cxl_component_create_dvsec(cxl_cstate, CXL3_SWITCH_MAILBOX_CCI,
+ REG_LOC_DVSEC_LENGTH, REG_LOC_DVSEC,
+ REG_LOC_DVSEC_REVID, (uint8_t *)regloc_dvsec);
+
+ cxl_initialize_mailbox_swcci(cswmb->cci, DEVICE(pci_dev),
+ DEVICE(cswmb->target),
+ CXL_MAILBOX_MAX_PAYLOAD_SIZE);
+}
+
+static void cswmbcci_exit(PCIDevice *pci_dev)
+{
+ /* Nothing to do here yet */
+}
+
+static Property cxl_switch_cci_props[] = {
+ DEFINE_PROP_LINK("target", CSWMBCCIDev,
+ target, TYPE_CXL_USP, PCIDevice *),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void cswmbcci_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc);
+
+ pc->realize = cswbcci_realize;
+ pc->exit = cswmbcci_exit;
+ /* Serial bus, CXL Switch CCI */
+ pc->class_id = 0x0c0b;
+ /*
+ * Huawei Technologies
+ * CXL Switch Mailbox CCI - DID assigned for emulation only.
+ * No real hardware will ever use this ID.
+ */
+ pc->vendor_id = 0x19e5;
+ pc->device_id = 0xa123;
+ pc->revision = 0;
+ dc->desc = "CXL Switch Mailbox CCI";
+ dc->reset = cswmbcci_reset;
+ device_class_set_props(dc, cxl_switch_cci_props);
+}
+
+static const TypeInfo cswmbcci_info = {
+ .name = TYPE_CXL_SWITCH_MAILBOX_CCI,
+ .parent = TYPE_PCI_DEVICE,
+ .class_init = cswmbcci_class_init,
+ .instance_size = sizeof(CSWMBCCIDev),
+ .interfaces = (InterfaceInfo[]) {
+ { INTERFACE_PCIE_DEVICE },
+ { }
+ },
+};
+
+static void cxl_switch_mailbox_cci_register(void)
+{
+ type_register_static(&cswmbcci_info);
+}
+type_init(cxl_switch_mailbox_cci_register);
diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build
index 0152a2b190..7c96e73320 100644
--- a/hw/cxl/meson.build
+++ b/hw/cxl/meson.build
@@ -6,6 +6,7 @@ system_ss.add(when: 'CONFIG_CXL',
'cxl-host.c',
'cxl-cdat.c',
'cxl-events.c',
+ 'switch-mailbox-cci.c',
),
if_false: files(
'cxl-host-stubs.c',
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 11/19] hw/pci-bridge/cxl_downstream: Set default link width and link speed
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (9 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 10/19] hw/cxl: Add a switch mailbox CCI function Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 12/19] hw/cxl: Implement Physical Ports status retrieval Jonathan Cameron via
` (9 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Without these being set the PCIE Link Capabilities register has
invalid values in these two fields.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/pci-bridge/cxl_downstream.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/hw/pci-bridge/cxl_downstream.c b/hw/pci-bridge/cxl_downstream.c
index 8d99e1e96d..405a133eef 100644
--- a/hw/pci-bridge/cxl_downstream.c
+++ b/hw/pci-bridge/cxl_downstream.c
@@ -210,6 +210,19 @@ static void cxl_dsp_exitfn(PCIDevice *d)
pci_bridge_exitfn(d);
}
+static void cxl_dsp_instance_post_init(Object *obj)
+{
+ PCIESlot *s = PCIE_SLOT(obj);
+
+ if (!s->speed) {
+ s->speed = QEMU_PCI_EXP_LNK_2_5GT;
+ }
+
+ if (!s->width) {
+ s->width = QEMU_PCI_EXP_LNK_X1;
+ }
+}
+
static void cxl_dsp_class_init(ObjectClass *oc, void *data)
{
DeviceClass *dc = DEVICE_CLASS(oc);
@@ -230,6 +243,7 @@ static const TypeInfo cxl_dsp_info = {
.name = TYPE_CXL_DSP,
.instance_size = sizeof(CXLDownstreamPort),
.parent = TYPE_PCIE_SLOT,
+ .instance_post_init = cxl_dsp_instance_post_init,
.class_init = cxl_dsp_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 12/19] hw/cxl: Implement Physical Ports status retrieval
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (10 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 11/19] hw/pci-bridge/cxl_downstream: Set default link width and link speed Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-27 13:55 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 13/19] hw/cxl/mbox: Add Get Background Operation Status Command Jonathan Cameron via
` (8 subsequent siblings)
20 siblings, 1 reply; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Add this command for both the Switch CCI and the MCTP CCI found
in switch upstream ports.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 121 +++++++++++++++++++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 9d5b5dadbd..26fb0192a9 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -72,6 +72,7 @@ enum {
#define CLEAR_POISON 0x2
PHYSICAL_SWITCH = 0x51,
#define IDENTIFY_SWITCH_DEVICE 0x0
+ #define GET_PHYSICAL_PORT_STATE 0x1
};
@@ -312,6 +313,122 @@ static CXLRetCode cmd_identify_switch_device(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+
+/* CXL r3.0 Section 7.6.7.1.2: Get Physical Port State (Opcode 5101h) */
+static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ /* CXL r3.0 Table 7-18: Get Physical Port State Request Payload */
+ struct cxl_fmapi_get_phys_port_state_req_pl {
+ uint8_t num_ports;
+ uint8_t ports[];
+ } QEMU_PACKED *in;
+
+ /*
+ * CXL r3.0 Table 7-20: Get Physical Port State Port Information Block
+ * Format
+ */
+ struct cxl_fmapi_port_state_info_block {
+ uint8_t port_id;
+ uint8_t config_state;
+ uint8_t connected_device_cxl_version;
+ uint8_t rsv1;
+ uint8_t connected_device_type;
+ uint8_t port_cxl_version_bitmask;
+ uint8_t max_link_width;
+ uint8_t negotiated_link_width;
+ uint8_t supported_link_speeds_vector;
+ uint8_t max_link_speed;
+ uint8_t current_link_speed;
+ uint8_t ltssm_state;
+ uint8_t first_lane_num;
+ uint16_t link_state;
+ uint8_t supported_ld_count;
+ } QEMU_PACKED;
+
+ /* CXL r3.0 Table 7-19: Get Physical Port State Response Payload */
+ struct cxl_fmapi_get_phys_port_state_resp_pl {
+ uint8_t num_ports;
+ uint8_t rsv1[3];
+ struct cxl_fmapi_port_state_info_block ports[];
+ } QEMU_PACKED *out;
+ PCIBus *bus = &PCI_BRIDGE(cci->d)->sec_bus;
+ PCIEPort *usp = PCIE_PORT(cci->d);
+ size_t pl_size;
+ int i;
+
+ in = (struct cxl_fmapi_get_phys_port_state_req_pl *)payload_in;
+ out = (struct cxl_fmapi_get_phys_port_state_resp_pl *)payload_out;
+
+ /* Check if what was requested can fit */
+ if (sizeof(*out) + sizeof(*out->ports) * in->num_ports > cci->payload_max) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ /* For success there should be a match for each requested */
+ out->num_ports = in->num_ports;
+
+ for (i = 0; i < in->num_ports; i++) {
+ struct cxl_fmapi_port_state_info_block *port;
+ /* First try to match on downstream port */
+ PCIDevice *port_dev;
+ uint16_t lnkcap, lnkcap2, lnksta;
+
+ port = &out->ports[i];
+
+ port_dev = pcie_find_port_by_pn(bus, in->ports[i]);
+ if (port_dev) { /* DSP */
+ port->config_state = 3;
+ port->connected_device_type = 4; /* TODO: Check. CXL type 3 */
+ port->supported_ld_count = 3;
+ } else if (usp->port == in->ports[i]) { /* USP */
+ port_dev = PCI_DEVICE(usp);
+ port->config_state = 4;
+ port->connected_device_type = 0;
+ } else {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ port->port_id = in->ports[i];
+ /* Information on status of this port in lnksta, lnkcap */
+ if (!port_dev->exp.exp_cap) {
+ return CXL_MBOX_INTERNAL_ERROR;
+ }
+ lnksta = port_dev->config_read(port_dev,
+ port_dev->exp.exp_cap + PCI_EXP_LNKSTA,
+ sizeof(lnksta));
+ lnkcap = port_dev->config_read(port_dev,
+ port_dev->exp.exp_cap + PCI_EXP_LNKCAP,
+ sizeof(lnkcap));
+ lnkcap2 = port_dev->config_read(port_dev,
+ port_dev->exp.exp_cap + PCI_EXP_LNKCAP2,
+ sizeof(lnkcap2));
+
+ port->max_link_width = (lnkcap & PCI_EXP_LNKCAP_MLW) >> 4;
+ port->negotiated_link_width = (lnksta & PCI_EXP_LNKSTA_NLW) >> 4;
+ /* No definition for SLS field in linux/pci_regs.h */
+ port->supported_link_speeds_vector = (lnkcap2 & 0xFE) >> 1;
+ port->max_link_speed = lnkcap & PCI_EXP_LNKCAP_SLS;
+ port->current_link_speed = lnksta & PCI_EXP_LNKSTA_CLS;
+ /* TODO: Track down if we can get the rest of the info */
+ port->ltssm_state = 0x7;
+ port->first_lane_num = 0;
+ port->link_state = 0;
+ port->port_cxl_version_bitmask = 0x2;
+ port->connected_device_cxl_version = 0x2;
+ }
+
+ pl_size = sizeof(out) + sizeof(*out->ports) * in->num_ports;
+
+ *len_out = pl_size;
+
+ return CXL_MBOX_SUCCESS;
+}
+
/* 8.2.9.2.1 */
static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
uint8_t *payload_in,
@@ -873,6 +990,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
[LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 },
[PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] = {"IDENTIFY_SWITCH_DEVICE",
cmd_identify_switch_device, 0, 0x49 },
+ [PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] = { "SWITCH_PHYSICAL_PORT_STATS",
+ cmd_get_physical_port_state, ~0, ~0 },
};
int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
@@ -952,6 +1071,8 @@ static const struct cxl_cmd cxl_cmd_set_usp_mctp[256][256] = {
[INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
[PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] = {"IDENTIFY_SWITCH_DEVICE",
cmd_identify_switch_device, 0, 0x49 },
+ [PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] = { "SWITCH_PHYSICAL_PORT_STATS",
+ cmd_get_physical_port_state, ~0, ~0 },
};
void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 12/19] hw/cxl: Implement Physical Ports status retrieval
2023-09-25 16:11 ` [PATCH 12/19] hw/cxl: Implement Physical Ports status retrieval Jonathan Cameron via
@ 2023-09-27 13:55 ` Jonathan Cameron via
0 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-27 13:55 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
...
> +/* CXL r3.0 Section 7.6.7.1.2: Get Physical Port State (Opcode 5101h) */
> +static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
> + uint8_t *payload_in,
> + size_t len_in,
> + uint8_t *payload_out,
> + size_t *len_out,
> + CXLCCI *cci)
> +{
> + /* CXL r3.0 Table 7-18: Get Physical Port State Request Payload */
> + struct cxl_fmapi_get_phys_port_state_req_pl {
> + uint8_t num_ports;
> + uint8_t ports[];
> + } QEMU_PACKED *in;
> +
> + /*
> + * CXL r3.0 Table 7-20: Get Physical Port State Port Information Block
> + * Format
> + */
> + struct cxl_fmapi_port_state_info_block {
> + uint8_t port_id;
> + uint8_t config_state;
> + uint8_t connected_device_cxl_version;
> + uint8_t rsv1;
> + uint8_t connected_device_type;
> + uint8_t port_cxl_version_bitmask;
> + uint8_t max_link_width;
> + uint8_t negotiated_link_width;
> + uint8_t supported_link_speeds_vector;
> + uint8_t max_link_speed;
> + uint8_t current_link_speed;
> + uint8_t ltssm_state;
> + uint8_t first_lane_num;
> + uint16_t link_state;
> + uint8_t supported_ld_count;
> + } QEMU_PACKED;
> +
> + /* CXL r3.0 Table 7-19: Get Physical Port State Response Payload */
> + struct cxl_fmapi_get_phys_port_state_resp_pl {
> + uint8_t num_ports;
> + uint8_t rsv1[3];
> + struct cxl_fmapi_port_state_info_block ports[];
> + } QEMU_PACKED *out;
...
> +
> + pl_size = sizeof(out) + sizeof(*out->ports) * in->num_ports;
In cleaning up up my tests I added a missing check on the pl size.
First term should be sizeof(*out)
> +
> + *len_out = pl_size;
> +
> + return CXL_MBOX_SUCCESS;
> +}
> +
^ permalink raw reply [flat|nested] 32+ messages in thread
* [PATCH 13/19] hw/cxl/mbox: Add Get Background Operation Status Command
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (11 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 12/19] hw/cxl: Implement Physical Ports status retrieval Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 14/19] hw/cxl/mbox: Add support for background operations Jonathan Cameron via
` (7 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
For now, provide this command on type 3 main mailbox only.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 26fb0192a9..d9785f324a 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -47,6 +47,7 @@
enum {
INFOSTAT = 0x00,
#define IS_IDENTIFY 0x1
+ #define BACKGROUND_OPERATION_STATUS 0x2
EVENTS = 0x01,
#define GET_RECORDS 0x0
#define CLEAR_RECORDS 0x1
@@ -429,6 +430,36 @@ static CXLRetCode cmd_get_physical_port_state(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+/* CXL r3.0 8.2.9.1.2 */
+static CXLRetCode cmd_infostat_bg_op_sts(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 status;
+ uint8_t rsvd;
+ uint16_t opcode;
+ uint16_t returncode;
+ uint16_t vendor_ext_status;
+ } QEMU_PACKED *bg_op_status;
+ QEMU_BUILD_BUG_ON(sizeof(*bg_op_status) != 8);
+
+ bg_op_status = (void *)payload_out;
+ memset(bg_op_status, 0, sizeof(*bg_op_status));
+ bg_op_status->status = cci->bg.complete_pct << 1;
+ if (cci->bg.runtime > 0) {
+ bg_op_status->status |= 1U << 0;
+ }
+ bg_op_status->opcode = cci->bg.opcode;
+ bg_op_status->returncode = cci->bg.ret_code;
+ *len_out = sizeof(*bg_op_status);
+
+ return CXL_MBOX_SUCCESS;
+}
+
/* 8.2.9.2.1 */
static CXLRetCode cmd_firmware_update_get_info(const struct cxl_cmd *cmd,
uint8_t *payload_in,
@@ -982,6 +1013,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
[INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
+ [INFOSTAT][BACKGROUND_OPERATION_STATUS] = { "BACKGROUND_OPERATION_STATUS",
+ cmd_infostat_bg_op_sts, 0, 8 },
[TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 },
[TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 8,
IMMEDIATE_POLICY_CHANGE },
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 14/19] hw/cxl/mbox: Add support for background operations
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (12 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 13/19] hw/cxl/mbox: Add Get Background Operation Status Command Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 15/19] hw/cxl/mbox: Wire up interrupts for background completion Jonathan Cameron via
` (6 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
From: Davidlohr Bueso <dave@stgolabs.net>
Support background commands in the mailbox, and update
cmd_infostat_bg_op_sts() accordingly. This patch does not implement mbox
interrupts upon completion, so the kernel driver must rely on polling to
know when the operation is done.
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-device-utils.c | 5 +--
hw/cxl/cxl-mailbox-utils.c | 92 +++++++++++++++++++++++++++++++++++++-
2 files changed, 93 insertions(+), 4 deletions(-)
diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 3dd45fb262..88f0256c79 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -133,8 +133,7 @@ static void mailbox_mem_writeq(uint64_t *reg_state, hwaddr offset,
case A_CXL_DEV_MAILBOX_CMD:
break;
case A_CXL_DEV_BG_CMD_STS:
- /* BG not supported */
- /* fallthrough */
+ break;
case A_CXL_DEV_MAILBOX_STS:
/* Read only register, will get updated by the state machine */
return;
@@ -346,7 +345,7 @@ static void device_reg_init_common(CXLDeviceState *cxl_dstate)
static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
{
- /* 2048 payload size, with no interrupt or background support */
+ /* 2048 payload size, with no interrupt */
ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
PAYLOAD_SIZE, CXL_MAILBOX_PAYLOAD_SHIFT);
cxl_dstate->payload_size = CXL_MAILBOX_MAX_PAYLOAD_SIZE;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index d9785f324a..63acbc1214 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -977,6 +977,8 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd,
#define IMMEDIATE_DATA_CHANGE (1 << 2)
#define IMMEDIATE_POLICY_CHANGE (1 << 3)
#define IMMEDIATE_LOG_CHANGE (1 << 4)
+#define SECURITY_STATE_CHANGE (1 << 5)
+#define BACKGROUND_OPERATION (1 << 6)
static const struct cxl_cmd cxl_cmd_set[256][256] = {
[EVENTS][GET_RECORDS] = { "EVENTS_GET_RECORDS",
@@ -1027,10 +1029,19 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
cmd_get_physical_port_state, ~0, ~0 },
};
+/*
+ * While the command is executing in the background, the device should
+ * update the percentage complete in the Background Command Status Register
+ * at least once per second.
+ */
+
+#define CXL_MBOX_BG_UPDATE_FREQ 1000UL
+
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)
{
+ int ret;
const struct cxl_cmd *cxl_cmd;
opcode_handler h;
@@ -1047,7 +1058,81 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
}
- return (*h)(cxl_cmd, pl_in, len_in, pl_out, len_out, cci);
+ /* Only one bg command at a time */
+ if ((cxl_cmd->effect & BACKGROUND_OPERATION) &&
+ cci->bg.runtime > 0) {
+ return CXL_MBOX_BUSY;
+ }
+
+ ret = (*h)(cxl_cmd, pl_in, len_in, pl_out, len_out, cci);
+ if ((cxl_cmd->effect & BACKGROUND_OPERATION) &&
+ ret == CXL_MBOX_BG_STARTED) {
+ *bg_started = true;
+ } else {
+ *bg_started = false;
+ }
+
+ /* Set bg and the return code */
+ if (*bg_started) {
+ uint64_t now;
+
+ cci->bg.opcode = (set << 8) | cmd;
+
+ cci->bg.complete_pct = 0;
+ cci->bg.ret_code = 0;
+
+ now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+ cci->bg.starttime = now;
+ timer_mod(cci->bg.timer, now + CXL_MBOX_BG_UPDATE_FREQ);
+ }
+
+ return ret;
+}
+
+static void bg_timercb(void *opaque)
+{
+ CXLCCI *cci = opaque;
+ CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
+ uint64_t bg_status_reg = 0;
+ uint64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
+ uint64_t total_time = cci->bg.starttime + cci->bg.runtime;
+
+ assert(cci->bg.runtime > 0);
+ bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
+ OP, cci->bg.opcode);
+
+ if (now >= total_time) { /* we are done */
+ uint64_t status_reg;
+ uint16_t ret = CXL_MBOX_SUCCESS;
+
+ cci->bg.complete_pct = 100;
+ /* Clear bg */
+ status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP, 0);
+ cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_STS] = status_reg;
+
+ bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
+ RET_CODE, ret);
+
+ /* TODO add ad-hoc cmd succesful completion handling */
+
+ qemu_log("Background command %04xh finished: %s\n",
+ cci->bg.opcode,
+ ret == CXL_MBOX_SUCCESS ? "success" : "aborted");
+ } else {
+ /* estimate only */
+ cci->bg.complete_pct = 100 * now / total_time;
+ timer_mod(cci->bg.timer, now + CXL_MBOX_BG_UPDATE_FREQ);
+ }
+
+ bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
+ PERCENTAGE_COMP, cci->bg.complete_pct);
+ cxl_dstate->mbox_reg_state64[R_CXL_DEV_BG_CMD_STS] = bg_status_reg;
+
+ if (cci->bg.complete_pct == 100) {
+ cci->bg.starttime = 0;
+ /* registers are updated, allow new bg-capable cmds */
+ cci->bg.runtime = 0;
+ }
}
void cxl_init_cci(CXLCCI *cci, size_t payload_max)
@@ -1066,6 +1151,11 @@ void cxl_init_cci(CXLCCI *cci, size_t payload_max)
}
}
}
+ cci->bg.complete_pct = 0;
+ cci->bg.starttime = 0;
+ cci->bg.runtime = 0;
+ cci->bg.timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,
+ bg_timercb, cci);
}
void cxl_initialize_mailbox_swcci(CXLCCI *cci, DeviceState *intf,
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 15/19] hw/cxl/mbox: Wire up interrupts for background completion
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (13 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 14/19] hw/cxl/mbox: Add support for background operations Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 16/19] hw/cxl: Add support for device sanitation Jonathan Cameron via
` (5 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
From: Davidlohr Bueso <dave@stgolabs.net>
Notify when the background operation is done. Note that for now background
commands are only supported on the main Type 3 mailbox.
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl_device.h | 1 +
hw/cxl/cxl-device-utils.c | 10 +++++++++-
hw/cxl/cxl-mailbox-utils.c | 31 ++++++++++++++-----------------
3 files changed, 24 insertions(+), 18 deletions(-)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index a99a7e6274..b7fa57fd14 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -193,6 +193,7 @@ typedef struct cxl_device_state {
struct {
MemoryRegion mailbox;
uint16_t payload_size;
+ uint8_t mbox_msi_n;
union {
uint8_t mbox_reg_state[CXL_MAILBOX_REGISTERS_LENGTH];
uint16_t mbox_reg_state16[CXL_MAILBOX_REGISTERS_LENGTH / 2];
diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c
index 88f0256c79..41763688ce 100644
--- a/hw/cxl/cxl-device-utils.c
+++ b/hw/cxl/cxl-device-utils.c
@@ -345,10 +345,18 @@ static void device_reg_init_common(CXLDeviceState *cxl_dstate)
static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate)
{
- /* 2048 payload size, with no interrupt */
+ const uint8_t msi_n = 9;
+
+ /* 2048 payload size */
ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
PAYLOAD_SIZE, CXL_MAILBOX_PAYLOAD_SHIFT);
cxl_dstate->payload_size = CXL_MAILBOX_MAX_PAYLOAD_SIZE;
+ /* irq support */
+ ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
+ BG_INT_CAP, 1);
+ ARRAY_FIELD_DP32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CAP,
+ MSI_N, msi_n);
+ cxl_dstate->mbox_msi_n = msi_n;
}
static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { }
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 63acbc1214..3db86b4da7 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -8,6 +8,8 @@
*/
#include "qemu/osdep.h"
+#include "hw/pci/msi.h"
+#include "hw/pci/msix.h"
#include "hw/cxl/cxl.h"
#include "hw/cxl/cxl_events.h"
#include "hw/pci/pci.h"
@@ -1092,28 +1094,16 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
static void bg_timercb(void *opaque)
{
CXLCCI *cci = opaque;
- CXLDeviceState *cxl_dstate = &CXL_TYPE3(cci->d)->cxl_dstate;
- uint64_t bg_status_reg = 0;
uint64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL);
uint64_t total_time = cci->bg.starttime + cci->bg.runtime;
assert(cci->bg.runtime > 0);
- bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
- OP, cci->bg.opcode);
if (now >= total_time) { /* we are done */
- uint64_t status_reg;
uint16_t ret = CXL_MBOX_SUCCESS;
cci->bg.complete_pct = 100;
- /* Clear bg */
- status_reg = FIELD_DP64(0, CXL_DEV_MAILBOX_STS, BG_OP, 0);
- cxl_dstate->mbox_reg_state64[R_CXL_DEV_MAILBOX_STS] = status_reg;
-
- bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
- RET_CODE, ret);
-
- /* TODO add ad-hoc cmd succesful completion handling */
+ cci->bg.ret_code = ret;
qemu_log("Background command %04xh finished: %s\n",
cci->bg.opcode,
@@ -1124,14 +1114,21 @@ static void bg_timercb(void *opaque)
timer_mod(cci->bg.timer, now + CXL_MBOX_BG_UPDATE_FREQ);
}
- bg_status_reg = FIELD_DP64(bg_status_reg, CXL_DEV_BG_CMD_STS,
- PERCENTAGE_COMP, cci->bg.complete_pct);
- cxl_dstate->mbox_reg_state64[R_CXL_DEV_BG_CMD_STS] = bg_status_reg;
-
if (cci->bg.complete_pct == 100) {
+ /* TODO: generalize to switch CCI */
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+ CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate;
+ PCIDevice *pdev = PCI_DEVICE(cci->d);
+
cci->bg.starttime = 0;
/* registers are updated, allow new bg-capable cmds */
cci->bg.runtime = 0;
+
+ if (msix_enabled(pdev)) {
+ msix_notify(pdev, cxl_dstate->mbox_msi_n);
+ } else if (msi_enabled(pdev)) {
+ msi_notify(pdev, cxl_dstate->mbox_msi_n);
+ }
}
}
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 16/19] hw/cxl: Add support for device sanitation
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (14 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 15/19] hw/cxl/mbox: Wire up interrupts for background completion Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 17/19] hw/cxl/type3: Cleanup multiple CXL_TYPE3() calls in read/write functions Jonathan Cameron via
` (4 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
From: Davidlohr Bueso <dave@stgolabs.net>
Make use of the background operations through the sanitize command, per CXL
3.0 specs. Traditionally run times can be rather long, depending on the
size of the media.
Estimate times based on:
https://pmem.io/documents/NVDIMM_DSM_Interface-V1.8.pdf
Signed-off-by: Davidlohr Bueso <dave@stgolabs.net>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl_device.h | 17 +++++
hw/cxl/cxl-mailbox-utils.c | 140 ++++++++++++++++++++++++++++++++++++
hw/mem/cxl_type3.c | 10 +++
3 files changed, 167 insertions(+)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index b7fa57fd14..dfa25a0837 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -347,6 +347,23 @@ REG64(CXL_MEM_DEV_STS, 0)
FIELD(CXL_MEM_DEV_STS, MBOX_READY, 4, 1)
FIELD(CXL_MEM_DEV_STS, RESET_NEEDED, 5, 3)
+static inline void __toggle_media(CXLDeviceState *cxl_dstate, int val)
+{
+ uint64_t dev_status_reg;
+
+ dev_status_reg = FIELD_DP64(0, CXL_MEM_DEV_STS, MEDIA_STATUS, val);
+ cxl_dstate->mbox_reg_state64[R_CXL_MEM_DEV_STS] = dev_status_reg;
+}
+#define cxl_dev_disable_media(cxlds) \
+ do { __toggle_media((cxlds), 0x3); } while (0)
+#define cxl_dev_enable_media(cxlds) \
+ do { __toggle_media((cxlds), 0x1); } while (0)
+
+static inline bool sanitize_running(CXLCCI *cci)
+{
+ return !!cci->bg.runtime && cci->bg.opcode == 0x4400;
+}
+
typedef struct CXLError {
QTAILQ_ENTRY(CXLError) node;
int type; /* Error code as per FE definition */
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 3db86b4da7..644dd97727 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -18,6 +18,7 @@
#include "qemu/log.h"
#include "qemu/units.h"
#include "qemu/uuid.h"
+#include "sysemu/hostmem.h"
#define CXL_CAPACITY_MULTIPLIER (256 * MiB)
@@ -69,6 +70,9 @@ enum {
#define GET_PARTITION_INFO 0x0
#define GET_LSA 0x2
#define SET_LSA 0x3
+ SANITIZE = 0x44,
+ #define OVERWRITE 0x0
+ #define SECURE_ERASE 0x1
MEDIA_AND_POISON = 0x43,
#define GET_POISON_LIST 0x0
#define INJECT_POISON 0x1
@@ -763,6 +767,108 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd,
return CXL_MBOX_SUCCESS;
}
+/* Perform the actual device zeroing */
+static void __do_sanitization(CXLType3Dev *ct3d)
+{
+ MemoryRegion *mr;
+
+ if (ct3d->hostvmem) {
+ mr = host_memory_backend_get_memory(ct3d->hostvmem);
+ if (mr) {
+ void *hostmem = memory_region_get_ram_ptr(mr);
+ memset(hostmem, 0, memory_region_size(mr));
+ }
+ }
+
+ if (ct3d->hostpmem) {
+ mr = host_memory_backend_get_memory(ct3d->hostpmem);
+ if (mr) {
+ void *hostmem = memory_region_get_ram_ptr(mr);
+ memset(hostmem, 0, memory_region_size(mr));
+ }
+ }
+ if (ct3d->lsa) {
+ mr = host_memory_backend_get_memory(ct3d->lsa);
+ if (mr) {
+ void *lsa = memory_region_get_ram_ptr(mr);
+ memset(lsa, 0, memory_region_size(mr));
+ }
+ }
+}
+
+/*
+ * CXL 3.0 spec section 8.2.9.8.5.1 - Sanitize.
+ *
+ * Once the Sanitize command has started successfully, the device shall be
+ * placed in the media disabled state. If the command fails or is interrupted
+ * by a reset or power failure, it shall remain in the media disabled state
+ * until a successful Sanitize command has been completed. During this state:
+ *
+ * 1. Memory writes to the device will have no effect, and all memory reads
+ * will return random values (no user data returned, even for locations that
+ * the failed Sanitize operation didn’t sanitize yet).
+ *
+ * 2. Mailbox commands shall still be processed in the disabled state, except
+ * that commands that access Sanitized areas shall fail with the Media Disabled
+ * error code.
+ */
+static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+ uint64_t total_mem; /* in Mb */
+ int secs;
+
+ total_mem = (ct3d->cxl_dstate.vmem_size + ct3d->cxl_dstate.pmem_size) >> 20;
+ if (total_mem <= 512) {
+ secs = 4;
+ } else if (total_mem <= 1024) {
+ secs = 8;
+ } else if (total_mem <= 2 * 1024) {
+ secs = 15;
+ } else if (total_mem <= 4 * 1024) {
+ secs = 30;
+ } else if (total_mem <= 8 * 1024) {
+ secs = 60;
+ } else if (total_mem <= 16 * 1024) {
+ secs = 2 * 60;
+ } else if (total_mem <= 32 * 1024) {
+ secs = 4 * 60;
+ } else if (total_mem <= 64 * 1024) {
+ secs = 8 * 60;
+ } else if (total_mem <= 128 * 1024) {
+ secs = 15 * 60;
+ } else if (total_mem <= 256 * 1024) {
+ secs = 30 * 60;
+ } else if (total_mem <= 512 * 1024) {
+ secs = 60 * 60;
+ } else if (total_mem <= 1024 * 1024) {
+ secs = 120 * 60;
+ } else {
+ secs = 240 * 60; /* max 4 hrs */
+ }
+
+ /* EBUSY other bg cmds as of now */
+ cci->bg.runtime = secs * 1000UL;
+ *len_out = 0;
+
+ cxl_dev_disable_media(&ct3d->cxl_dstate);
+
+ if (secs > 2) {
+ /* sanitize when done */
+ return CXL_MBOX_BG_STARTED;
+ } else {
+ __do_sanitization(ct3d);
+ cxl_dev_enable_media(&ct3d->cxl_dstate);
+
+ return CXL_MBOX_SUCCESS;
+ }
+}
+
/*
* This is very inefficient, but good enough for now!
* Also the payload will always fit, so no need to handle the MORE flag and
@@ -1007,6 +1113,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
[CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 8, 0 },
[CCLS][SET_LSA] = { "CCLS_SET_LSA", cmd_ccls_set_lsa,
~0, IMMEDIATE_CONFIG_CHANGE | IMMEDIATE_DATA_CHANGE },
+ [SANITIZE][OVERWRITE] = { "SANITIZE_OVERWRITE", cmd_sanitize_overwrite, 0,
+ IMMEDIATE_DATA_CHANGE | SECURITY_STATE_CHANGE | BACKGROUND_OPERATION },
[MEDIA_AND_POISON][GET_POISON_LIST] = { "MEDIA_AND_POISON_GET_POISON_LIST",
cmd_media_get_poison_list, 16, 0 },
[MEDIA_AND_POISON][INJECT_POISON] = { "MEDIA_AND_POISON_INJECT_POISON",
@@ -1066,6 +1174,21 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
return CXL_MBOX_BUSY;
}
+ /* forbid any selected commands while overwriting */
+ if (sanitize_running(cci)) {
+ if (h == cmd_events_get_records ||
+ h == cmd_ccls_get_partition_info ||
+ h == cmd_ccls_set_lsa ||
+ h == cmd_ccls_get_lsa ||
+ h == cmd_logs_get_log ||
+ h == cmd_media_get_poison_list ||
+ h == cmd_media_inject_poison ||
+ h == cmd_media_clear_poison ||
+ h == cmd_sanitize_overwrite) {
+ return CXL_MBOX_MEDIA_DISABLED;
+ }
+ }
+
ret = (*h)(cxl_cmd, pl_in, len_in, pl_out, len_out, cci);
if ((cxl_cmd->effect & BACKGROUND_OPERATION) &&
ret == CXL_MBOX_BG_STARTED) {
@@ -1104,6 +1227,23 @@ static void bg_timercb(void *opaque)
cci->bg.complete_pct = 100;
cci->bg.ret_code = ret;
+ if (ret == CXL_MBOX_SUCCESS) {
+ switch (cci->bg.opcode) {
+ case 0x4400: /* sanitize */
+ {
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+
+ __do_sanitization(ct3d);
+ cxl_dev_enable_media(&ct3d->cxl_dstate);
+ }
+ break;
+ case 0x4304: /* TODO: scan media */
+ break;
+ default:
+ __builtin_unreachable();
+ break;
+ }
+ }
qemu_log("Background command %04xh finished: %s\n",
cci->bg.opcode,
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index 0529745786..cc8220592f 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -23,6 +23,7 @@
#include "qemu/pmem.h"
#include "qemu/range.h"
#include "qemu/rcu.h"
+#include "qemu/guest-random.h"
#include "sysemu/hostmem.h"
#include "sysemu/numa.h"
#include "hw/cxl/cxl.h"
@@ -897,6 +898,11 @@ MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data,
return MEMTX_ERROR;
}
+ if (sanitize_running(&CXL_TYPE3(d)->cci)) {
+ qemu_guest_getrandom_nofail(data, size);
+ return MEMTX_OK;
+ }
+
return address_space_read(as, dpa_offset, attrs, data, size);
}
@@ -913,6 +919,10 @@ MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data,
return MEMTX_ERROR;
}
+ if (sanitize_running(&CXL_TYPE3(d)->cci)) {
+ return MEMTX_OK;
+ }
+
return address_space_write(as, dpa_offset, attrs, &data, size);
}
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 17/19] hw/cxl/type3: Cleanup multiple CXL_TYPE3() calls in read/write functions
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (15 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 16/19] hw/cxl: Add support for device sanitation Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 18/19] hw/cxl: Add dummy security state get Jonathan Cameron via
` (3 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
From: Gregory Price <gourry.memverge@gmail.com>
Call CXL_TYPE3 once at top of function to avoid multiple invocations.
Signed-off-by: Gregory Price <gregory.price@memverge.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/mem/cxl_type3.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index cc8220592f..a766c64575 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -888,17 +888,18 @@ static int cxl_type3_hpa_to_as_and_dpa(CXLType3Dev *ct3d,
MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data,
unsigned size, MemTxAttrs attrs)
{
+ CXLType3Dev *ct3d = CXL_TYPE3(d);
uint64_t dpa_offset = 0;
AddressSpace *as = NULL;
int res;
- res = cxl_type3_hpa_to_as_and_dpa(CXL_TYPE3(d), host_addr, size,
+ res = cxl_type3_hpa_to_as_and_dpa(ct3d, host_addr, size,
&as, &dpa_offset);
if (res) {
return MEMTX_ERROR;
}
- if (sanitize_running(&CXL_TYPE3(d)->cci)) {
+ if (sanitize_running(&ct3d->cci)) {
qemu_guest_getrandom_nofail(data, size);
return MEMTX_OK;
}
@@ -909,17 +910,18 @@ MemTxResult cxl_type3_read(PCIDevice *d, hwaddr host_addr, uint64_t *data,
MemTxResult cxl_type3_write(PCIDevice *d, hwaddr host_addr, uint64_t data,
unsigned size, MemTxAttrs attrs)
{
+ CXLType3Dev *ct3d = CXL_TYPE3(d);
uint64_t dpa_offset = 0;
AddressSpace *as = NULL;
int res;
- res = cxl_type3_hpa_to_as_and_dpa(CXL_TYPE3(d), host_addr, size,
+ res = cxl_type3_hpa_to_as_and_dpa(ct3d, host_addr, size,
&as, &dpa_offset);
if (res) {
return MEMTX_ERROR;
}
- if (sanitize_running(&CXL_TYPE3(d)->cci)) {
+ if (sanitize_running(&ct3d->cci)) {
return MEMTX_OK;
}
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 18/19] hw/cxl: Add dummy security state get
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (16 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 17/19] hw/cxl/type3: Cleanup multiple CXL_TYPE3() calls in read/write functions Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:11 ` [PATCH 19/19] hw/cxl: Add tunneled command support to mailbox for switch cci/mctp Jonathan Cameron via
` (2 subsequent siblings)
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
Needed to allow the santize comamnds to be tested with proposed Linux Kernel
support. Default value + no control of the security state will work for now.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
hw/cxl/cxl-mailbox-utils.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index 644dd97727..f40f12f0de 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -73,6 +73,8 @@ enum {
SANITIZE = 0x44,
#define OVERWRITE 0x0
#define SECURE_ERASE 0x1
+ PERSISTENT_MEM = 0x45,
+ #define GET_SECURITY_STATE 0x0
MEDIA_AND_POISON = 0x43,
#define GET_POISON_LIST 0x0
#define INJECT_POISON 0x1
@@ -869,6 +871,19 @@ static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd,
}
}
+static CXLRetCode cmd_get_security_state(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ uint32_t *state = (uint32_t *)payload_out;
+
+ *state = 0;
+ *len_out = 4;
+ return CXL_MBOX_SUCCESS;
+}
/*
* This is very inefficient, but good enough for now!
* Also the payload will always fit, so no need to handle the MORE flag and
@@ -1115,6 +1130,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = {
~0, IMMEDIATE_CONFIG_CHANGE | IMMEDIATE_DATA_CHANGE },
[SANITIZE][OVERWRITE] = { "SANITIZE_OVERWRITE", cmd_sanitize_overwrite, 0,
IMMEDIATE_DATA_CHANGE | SECURITY_STATE_CHANGE | 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",
cmd_media_get_poison_list, 16, 0 },
[MEDIA_AND_POISON][INJECT_POISON] = { "MEDIA_AND_POISON_INJECT_POISON",
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* [PATCH 19/19] hw/cxl: Add tunneled command support to mailbox for switch cci/mctp.
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (17 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 18/19] hw/cxl: Add dummy security state get Jonathan Cameron via
@ 2023-09-25 16:11 ` Jonathan Cameron via
2023-09-25 16:50 ` [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
2023-09-28 18:12 ` Gregory Price
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:11 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin
Cc: linuxarm, Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
The implementation of tunneling makes the choice that our Type 3 device is
a Logical Device (LD) of a Multi-Logical Device (MLD) that just happens to
only have one LD for now.
Tunneling is supported from a Switch Mailbox CCI or via MCTP over I2C
connected to the switch mctp CCI via an outer level to the FM owned LD in
the MLD Type 3 device. From there an inner tunnel may be used to access
particular LDs.
Protocol wise, the following is what happens in a real system but we
don't emulate the transports - just the destinations and the payloads.
( Host -> Switch Mailbox CCI - in band FM-API mailbox command
or
Host -> Switch MCTP CCI - MCTP over I2C using the CXL FM-API
MCTP Binding.
)
then (if a tunnel command)
Switch -> Type 3 FM Owned LD - MCTP over PCI VDM using the
CXL FM-API binding (addressed by switch port)
then (if next command also a tunnel)
Type 3 FM Owned LD to LD0 via internal transport
(addressed by LD number)
or
Host to Type 3 FM Owned MCTP CCI - MCTP over I2C using the
CXL FM-API MCTP Binding.
thn (if next comamnd alstunnel)
Type 3 FM Owned LD to LD0 via internal transport.
(addressed by LD number)
It is worth noting that the tunneling commands over PCI VDM
presumably use the FM-API MCTP binding not the CXL Memory
Device Binding so it may not be possible to issue tunneled
commands to an SLD. This and the near term usecase of
controlling DCD motivated the decision to emulate an MLD
from the start.
Additional commands will need to be added to make this
useful beyond testing the tunneling works.
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
---
include/hw/cxl/cxl_device.h | 10 +++
hw/cxl/cxl-mailbox-utils.c | 152 ++++++++++++++++++++++++++++++++++++
hw/mem/cxl_type3.c | 11 +++
3 files changed, 173 insertions(+)
diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
index dfa25a0837..f9d921e8e4 100644
--- a/include/hw/cxl/cxl_device.h
+++ b/include/hw/cxl/cxl_device.h
@@ -281,6 +281,13 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd,
bool *bg_started);
void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
size_t payload_max);
+void cxl_initialize_t3_fm_owned_ld_mctpcci(CXLCCI *cci, DeviceState *d,
+ DeviceState *intf,
+ size_t payload_max);
+
+void cxl_initialize_t3_ld_cci(CXLCCI *cci, DeviceState *d,
+ DeviceState *intf, size_t payload_max);
+
void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
size_t payload_max);
@@ -402,6 +409,9 @@ struct CXLType3Dev {
CXLDeviceState cxl_dstate;
CXLCCI cci; /* Primary PCI mailbox CCI */
CXLCCI oob_mctp_cci; /* Initialized only if targetted */
+ /* Always intialized as no way to know if a VDM might show up */
+ CXLCCI vdm_fm_owned_ld_mctp_cci;
+ CXLCCI ld0_cci;
/* DOE */
DOECap doe_cdat;
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c
index f40f12f0de..467735395d 100644
--- a/hw/cxl/cxl-mailbox-utils.c
+++ b/hw/cxl/cxl-mailbox-utils.c
@@ -82,8 +82,125 @@ enum {
PHYSICAL_SWITCH = 0x51,
#define IDENTIFY_SWITCH_DEVICE 0x0
#define GET_PHYSICAL_PORT_STATE 0x1
+ TUNNEL = 0x53,
+ #define MANAGEMENT_COMMAND 0x0
};
+/* CCI Message Format CXL r3.0 Figure 7-19 */
+typedef struct CXLCCIMessage {
+ uint8_t category;
+#define CXL_CCI_CAT_REQ 0
+#define CXL_CCI_CAT_RSP 1
+ uint8_t tag;
+ uint8_t resv1;
+ uint8_t command;
+ uint8_t command_set;
+ uint8_t pl_length[3];
+ uint16_t rc;
+ uint16_t vendor_specific;
+ uint8_t payload[];
+} QEMU_PACKED CXLCCIMessage;
+
+/* This command is only defined to an MLD FM Owned LD or an MHD */
+static CXLRetCode cmd_tunnel_management_cmd(const struct cxl_cmd *cmd,
+ uint8_t *payload_in,
+ size_t len_in,
+ uint8_t *payload_out,
+ size_t *len_out,
+ CXLCCI *cci)
+{
+ PCIDevice *tunnel_target;
+ CXLCCI *target_cci;
+ struct {
+ uint8_t port_or_ld_id;
+ uint8_t target_type;
+ uint16_t size;
+ CXLCCIMessage ccimessage;
+ } QEMU_PACKED *in;
+ struct {
+ uint16_t resp_len;
+ uint8_t resv[2];
+ CXLCCIMessage ccimessage;
+ } QEMU_PACKED *out;
+ size_t pl_length, length_out;
+ bool bg_started;
+ int rc;
+
+ if (cmd->in < sizeof(*in)) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ in = (void *)payload_in;
+ out = (void *)payload_out;
+
+ /* Enough room for minimum sized message - no payload */
+ if (in->size < sizeof(in->ccimessage)) {
+ return CXL_MBOX_INVALID_PAYLOAD_LENGTH;
+ }
+ if (in->ccimessage.category != CXL_CCI_CAT_REQ) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ if (in->target_type != 0) {
+ qemu_log_mask(LOG_UNIMP,
+ "Tunneled Command sent to no existent FM-LD");
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ /*
+ * Target of a tunnel unfortunately depends on type of CCI readint
+ * the message.
+ * If in a switch, then it's the port number.
+ * If in an MLD it is the ld number.
+ * If in an MHD target type indicate where we are going.
+ */
+ if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_TYPE3)) {
+ CXLType3Dev *ct3d = CXL_TYPE3(cci->d);
+ if (in->port_or_ld_id != 0) {
+ /* Only pretending to have one for now! */
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ target_cci = &ct3d->ld0_cci;
+ } else if (object_dynamic_cast(OBJECT(cci->d), TYPE_CXL_USP)) {
+ CXLUpstreamPort *usp = CXL_USP(cci->d);
+
+ tunnel_target = pcie_find_port_by_pn(&PCI_BRIDGE(usp)->sec_bus,
+ in->port_or_ld_id);
+ if (!tunnel_target) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ tunnel_target =
+ pci_bridge_get_sec_bus(PCI_BRIDGE(tunnel_target))->devices[0];
+ if (!tunnel_target) {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ if (object_dynamic_cast(OBJECT(tunnel_target), TYPE_CXL_TYPE3)) {
+ CXLType3Dev *ct3d = CXL_TYPE3(tunnel_target);
+ /* Tunneled VDMs always land on FM Owned LD */
+ target_cci = &ct3d->vdm_fm_owned_ld_mctp_cci;
+ } else {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+ } else {
+ return CXL_MBOX_INVALID_INPUT;
+ }
+
+ pl_length = in->ccimessage.pl_length[2] << 16 |
+ in->ccimessage.pl_length[1] << 8 | in->ccimessage.pl_length[0];
+ rc = cxl_process_cci_message(target_cci,
+ in->ccimessage.command_set,
+ in->ccimessage.command,
+ pl_length, in->ccimessage.payload,
+ &length_out, out->ccimessage.payload,
+ &bg_started);
+ /* Payload should be in place. Rest of CCI header and needs filling */
+ out->resp_len = length_out + sizeof(CXLCCIMessage);
+ st24_le_p(out->ccimessage.pl_length, length_out);
+ out->ccimessage.rc = rc;
+ out->ccimessage.category = CXL_CCI_CAT_RSP;
+ *len_out = length_out + sizeof(*out);
+
+ return CXL_MBOX_SUCCESS;
+}
static CXLRetCode cmd_events_get_records(const struct cxl_cmd *cmd,
uint8_t *payload_in, size_t len_in,
@@ -1154,6 +1271,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = {
cmd_identify_switch_device, 0, 0x49 },
[PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] = { "SWITCH_PHYSICAL_PORT_STATS",
cmd_get_physical_port_state, ~0, ~0 },
+ [TUNNEL][MANAGEMENT_COMMAND] = { "TUNNEL_MANAGEMENT_COMMAND",
+ cmd_tunnel_management_cmd, ~0, ~0 },
};
/*
@@ -1333,6 +1452,8 @@ void cxl_initialize_mailbox_t3(CXLCCI *cci, DeviceState *d, size_t payload_max)
static const struct cxl_cmd cxl_cmd_set_t3_mctp[256][256] = {
[INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
+ [TUNNEL][MANAGEMENT_COMMAND] = { "TUNNEL_MANAGEMENT_COMMAND",
+ cmd_tunnel_management_cmd, ~0, ~0 },
};
void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
@@ -1344,12 +1465,43 @@ void cxl_initialize_t3_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
cxl_init_cci(cci, payload_max);
}
+static const struct cxl_cmd cxl_cmd_set_t3_ld[256][256] = {
+ [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
+};
+
+void cxl_initialize_t3_ld_cci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
+ size_t payload_max)
+{
+ cci->cxl_cmd_set = cxl_cmd_set_t3_ld;
+ cci->d = d;
+ cci->intf = intf;
+ cxl_init_cci(cci, payload_max);
+}
+
+static const struct cxl_cmd cxl_cmd_set_t3_fm_owned_ld_mctp[256][256] = {
+ [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
+ [TUNNEL][MANAGEMENT_COMMAND] = { "TUNNEL_MANAGEMENT_COMMAND",
+ cmd_tunnel_management_cmd, ~0, ~0 },
+};
+
+void cxl_initialize_t3_fm_owned_ld_mctpcci(CXLCCI *cci, DeviceState *d,
+ DeviceState *intf,
+ size_t payload_max)
+{
+ cci->cxl_cmd_set = cxl_cmd_set_t3_fm_owned_ld_mctp;
+ cci->d = d;
+ cci->intf = intf;
+ cxl_init_cci(cci, payload_max);
+}
+
static const struct cxl_cmd cxl_cmd_set_usp_mctp[256][256] = {
[INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 18 },
[PHYSICAL_SWITCH][IDENTIFY_SWITCH_DEVICE] = {"IDENTIFY_SWITCH_DEVICE",
cmd_identify_switch_device, 0, 0x49 },
[PHYSICAL_SWITCH][GET_PHYSICAL_PORT_STATE] = { "SWITCH_PHYSICAL_PORT_STATS",
cmd_get_physical_port_state, ~0, ~0 },
+ [TUNNEL][MANAGEMENT_COMMAND] = { "TUNNEL_MANAGEMENT_COMMAND",
+ cmd_tunnel_management_cmd, ~0, ~0 },
};
void cxl_initialize_usp_mctpcci(CXLCCI *cci, DeviceState *d, DeviceState *intf,
diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
index a766c64575..52647b4ac7 100644
--- a/hw/mem/cxl_type3.c
+++ b/hw/mem/cxl_type3.c
@@ -936,6 +936,17 @@ static void ct3d_reset(DeviceState *dev)
cxl_component_register_init_common(reg_state, write_msk, CXL2_TYPE3_DEVICE);
cxl_device_register_init_t3(ct3d);
+
+ /*
+ * Bring up an endpoint to target with MCTP over VDM.
+ * This device is emulating an MLD with single LD for now.
+ */
+ cxl_initialize_t3_fm_owned_ld_mctpcci(&ct3d->vdm_fm_owned_ld_mctp_cci,
+ DEVICE(ct3d), DEVICE(ct3d),
+ 512); /* Max payload made up */
+ cxl_initialize_t3_ld_cci(&ct3d->ld0_cci, DEVICE(ct3d), DEVICE(ct3d),
+ 512); /* Max payload made up */
+
}
static Property ct3_props[] = {
--
2.39.2
^ permalink raw reply related [flat|nested] 32+ messages in thread
* Re: [PATCH 00/19] QEMU: CXL mailbox rework and features
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (18 preceding siblings ...)
2023-09-25 16:11 ` [PATCH 19/19] hw/cxl: Add tunneled command support to mailbox for switch cci/mctp Jonathan Cameron via
@ 2023-09-25 16:50 ` Jonathan Cameron via
2023-09-28 18:12 ` Gregory Price
20 siblings, 0 replies; 32+ messages in thread
From: Jonathan Cameron via @ 2023-09-25 16:50 UTC (permalink / raw)
To: qemu-devel, linux-cxl, Michael Tsirkin, linuxarm
Cc: Fan Ni, Philippe Mathieu-Daudé, Davidlohr Bueso,
Gregory Price, Klaus Jensen, Corey Minyard, Klaus Jensen
On Mon, 25 Sep 2023 17:11:05 +0100
Jonathan Cameron <Jonathan.Cameron@huawei.com> wrote:
> Based on: [PATCH] hw/cxl: Fix local variable shadowing of cap_hdrs
> Based on: [PATCH v2 0/3] hw/cxl: Add dummy ACPI QTG DSM
Missed one.
Based on: [PATCH v4 0/4] hw/cxl: Support emulating 4 HDM decoders throughout topology
> Based on: [PATCH V2] hw/pci-bridge/cxl-upstream: Add serial number extended capability support
> Based on: [PATCH v3 0/4] hw/cxl: Line length reduction and related
> Based on: [PATCH v6 0/3] hw/{i2c,nvme}: mctp endpoint, nvme management interface model
>
> I'm assuming this last dependency will go via a different tree though there
> is an outstanding request for tests. That equally applies to the CXL setup,
> but there are lot of moving parts. I'll experiment with basic testing
> of the MCTP I2C device whilst this is being reviewed.
>
> Based on: Message ID: 20230904161847.18468-1-Jonathan.Cameron@huawei.com
Based on: Message ID: 20230913132523.29780-1-Jonathan.Cameron@huawei.com
> Based on: Message ID: 20230913133615.29876-1-Jonathan.Cameron@huawei.com
> Based on: Message ID: 20230919093434.1194-1-Jonathan.Cameron@huawei.com
> Based on: Message ID: 20230925152258.5444-1-Jonathan.Cameron@huawei.com
And to match above, the above should have been first.
> Based on: Message ID: 20230914-nmi-i2c-v6-0-11bbb4f74d18@samsung.com
So should be
Based on: [PATCH] hw/cxl: Fix local variable shadowing of cap_hdrs
Based on: [PATCH v2 0/3] hw/cxl: Add dummy ACPI QTG DSM
Based on: [PATCH v4 0/4] hw/cxl: Support emulating 4 HDM decoders throughout topology
Based on: [PATCH V2] hw/pci-bridge/cxl-upstream: Add serial number extended capability support
Based on: [PATCH v3 0/4] hw/cxl: Line length reduction and related
Based on: [PATCH v6 0/3] hw/{i2c,nvme}: mctp endpoint, nvme management interface model
Based on: Message ID: 20230904161847.18468-1-Jonathan.Cameron@huawei.com
Based on: Message ID: 20230904161847.18468-1-Jonathan.Cameron@huawei.com
Based on: Message ID: 20230913132523.29780-1-Jonathan.Cameron@huawei.com
Based on: Message ID: 20230913133615.29876-1-Jonathan.Cameron@huawei.com
Based on: Message ID: 20230919093434.1194-1-Jonathan.Cameron@huawei.com
Based on: Message ID: 20230914-nmi-i2c-v6-0-11bbb4f74d18@samsung.com
Sorry about that.
Jonathan
^ permalink raw reply [flat|nested] 32+ messages in thread
* Re: [PATCH 00/19] QEMU: CXL mailbox rework and features
2023-09-25 16:11 [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
` (19 preceding siblings ...)
2023-09-25 16:50 ` [PATCH 00/19] QEMU: CXL mailbox rework and features Jonathan Cameron via
@ 2023-09-28 18:12 ` Gregory Price
20 siblings, 0 replies; 32+ messages in thread
From: Gregory Price @ 2023-09-28 18:12 UTC (permalink / raw)
To: Jonathan Cameron
Cc: qemu-devel, linux-cxl, Michael Tsirkin, linuxarm, Fan Ni,
Philippe Mathieu-Daudé, Davidlohr Bueso, Klaus Jensen,
Corey Minyard, Klaus Jensen
On Mon, Sep 25, 2023 at 05:11:05PM +0100, Jonathan Cameron wrote:
> I've been carrying most of this series on our CXL staging tree
> https://gitlab.com/jic23/qemu for some time and a lot of more recent
> work around Multi Head Devices and Dynamic Capacity that we need for
> Linux kernel enabling are backed up behind it. Hence I reorganized my
> queue to try and land this before other less 'central' features such
> as CXL PMUs and arm/virt support.
...
>
> Jonathan Cameron (15):
> hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances
> constant
> hw/cxl/mbox: Split mailbox command payload into separate input and
> output
> hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState
> hw/cxl/mbox: Generalize the CCI command processing
> hw/pci-bridge/cxl_upstream: Move defintion of device to header.
To save some list spam, I can't say i've reviewed and tested the entire
set, but this patch series to help model the Niagara work so please add
my tags as appropriate to the above.
Reviewed-by: Gregory Price <gregory.price@memverge.com>
Tested-by: Gregory Price <gregory.price@memverge.com>
~Gregory
^ permalink raw reply [flat|nested] 32+ messages in thread