From patchwork Mon Sep 25 16:11:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398103 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id F09B1CE7A9B for ; Mon, 25 Sep 2023 16:12:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231226AbjIYQMG (ORCPT ); Mon, 25 Sep 2023 12:12:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35932 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233168AbjIYQMF (ORCPT ); Mon, 25 Sep 2023 12:12:05 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BF4E1C0 for ; Mon, 25 Sep 2023 09:11:55 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSS04LF6z6K9h6; Tue, 26 Sep 2023 00:06:56 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:11:53 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 01/19] hw/cxl/mbox: Pull the payload out of struct cxl_cmd and make instances constant Date: Mon, 25 Sep 2023 17:11:06 +0100 Message-ID: <20230925161124.18940-2-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 Reviewed-by: Fan Ni --- 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]; From patchwork Mon Sep 25 16:11:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398104 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 66C93CE7A9B for ; Mon, 25 Sep 2023 16:12:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233252AbjIYQMh (ORCPT ); Mon, 25 Sep 2023 12:12:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46644 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233303AbjIYQMf (ORCPT ); Mon, 25 Sep 2023 12:12:35 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6A225192 for ; Mon, 25 Sep 2023 09:12:26 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSSb0bd3z6K9gY; Tue, 26 Sep 2023 00:07:27 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:12:23 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 02/19] hw/cxl/mbox: Split mailbox command payload into separate input and output Date: Mon, 25 Sep 2023 17:11:07 +0100 Message-ID: <20230925161124.18940-3-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 Reviewed-by: Fan Ni --- 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; From patchwork Mon Sep 25 16:11:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398105 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5537BCE7A9A for ; Mon, 25 Sep 2023 16:13:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233152AbjIYQNG (ORCPT ); Mon, 25 Sep 2023 12:13:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37692 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233186AbjIYQNG (ORCPT ); Mon, 25 Sep 2023 12:13:06 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82F90116 for ; Mon, 25 Sep 2023 09:12:57 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.206]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSYX1RZhz6K86R; Tue, 26 Sep 2023 00:11:44 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:12:54 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 03/19] hw/cxl/mbox: Pull the CCI definition out of the CXLDeviceState Date: Mon, 25 Sep 2023 17:11:08 +0100 Message-ID: <20230925161124.18940-4-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 Reviewed-by: Fan Ni --- 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[] = { From patchwork Mon Sep 25 16:11:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398106 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5A2AECE7A9B for ; Mon, 25 Sep 2023 16:13:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231698AbjIYQNe (ORCPT ); Mon, 25 Sep 2023 12:13:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50776 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229437AbjIYQNd (ORCPT ); Mon, 25 Sep 2023 12:13:33 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2CAA4B6 for ; Mon, 25 Sep 2023 09:13:27 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.200]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSXq6cb7z6DBCm; Tue, 26 Sep 2023 00:11:07 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:13:24 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 04/19] hw/cxl/mbox: Generalize the CCI command processing Date: Mon, 25 Sep 2023 17:11:09 +0100 Message-ID: <20230925161124.18940-5-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 Reviewed-by: Fan Ni --- 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) From patchwork Mon Sep 25 16:11:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398107 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9F406CE7A9B for ; Mon, 25 Sep 2023 16:13:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231689AbjIYQOE (ORCPT ); Mon, 25 Sep 2023 12:14:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229437AbjIYQOD (ORCPT ); Mon, 25 Sep 2023 12:14:03 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A86ADB6 for ; Mon, 25 Sep 2023 09:13:57 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.206]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSYQ3tBBz6DBBV; Tue, 26 Sep 2023 00:11:38 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:13:55 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 05/19] hw/pci-bridge/cxl_upstream: Move defintion of device to header. Date: Mon, 25 Sep 2023 17:11:10 +0100 Message-ID: <20230925161124.18940-6-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 Reviewed-by: Fan Ni --- 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; From patchwork Mon Sep 25 16:11:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398108 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CBCF1CE7A9B for ; Mon, 25 Sep 2023 16:14:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229437AbjIYQOg (ORCPT ); Mon, 25 Sep 2023 12:14:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41476 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232936AbjIYQOf (ORCPT ); Mon, 25 Sep 2023 12:14:35 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 660DA112 for ; Mon, 25 Sep 2023 09:14:28 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.201]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSbH2QLMz6K7Yb; Tue, 26 Sep 2023 00:13:15 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:14:25 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 06/19] hw/cxl/i2c_mctp_cxl: Initial device emulation Date: Mon, 25 Sep 2023 17:11:11 +0100 Message-ID: <20230925161124.18940-7-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 --- 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')) From patchwork Mon Sep 25 16:11:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398119 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1A886CE7A9B for ; Mon, 25 Sep 2023 16:15:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232936AbjIYQPF (ORCPT ); Mon, 25 Sep 2023 12:15:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57754 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231698AbjIYQPF (ORCPT ); Mon, 25 Sep 2023 12:15:05 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D57C292 for ; Mon, 25 Sep 2023 09:14:58 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.206]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSZb5BqSz6DBCx; Tue, 26 Sep 2023 00:12:39 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:14:56 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 07/19] hw/cxl/mbox: Add Information and Status / Identify command Date: Mon, 25 Sep 2023 17:11:12 +0100 Message-ID: <20230925161124.18940-8-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 --- 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, From patchwork Mon Sep 25 16:11:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398120 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90B65CE7A9A for ; Mon, 25 Sep 2023 16:15:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231698AbjIYQPi (ORCPT ); Mon, 25 Sep 2023 12:15:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54282 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231689AbjIYQPg (ORCPT ); Mon, 25 Sep 2023 12:15:36 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 46746CE for ; Mon, 25 Sep 2023 09:15:29 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.206]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSbB0zKVz6DBCq; Tue, 26 Sep 2023 00:13:10 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:15:27 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 08/19] docs: cxl: Add example commandline for MCTP CXL CCIs Date: Mon, 25 Sep 2023 17:11:13 +0100 Message-ID: <20230925161124.18940-9-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 --- 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 ---------- From patchwork Mon Sep 25 16:11:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398121 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B0D4ACE7A9A for ; Mon, 25 Sep 2023 16:16:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232723AbjIYQQH (ORCPT ); Mon, 25 Sep 2023 12:16:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55934 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231689AbjIYQQG (ORCPT ); Mon, 25 Sep 2023 12:16:06 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CC41992 for ; Mon, 25 Sep 2023 09:15:59 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSXh4xZ6z6K9py; Tue, 26 Sep 2023 00:11:00 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:15:57 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 09/19] hw/cxl/mbox: Add Physical Switch Identify command. Date: Mon, 25 Sep 2023 17:11:14 +0100 Message-ID: <20230925161124.18940-10-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Enable it for MCTP CCI for the switch. Will shortly be enabled for switch CCI as well. Signed-off-by: Jonathan Cameron --- 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 From patchwork Mon Sep 25 16:11:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398122 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E74A4CE7A9B for ; Mon, 25 Sep 2023 16:16:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231226AbjIYQQi (ORCPT ); Mon, 25 Sep 2023 12:16:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38736 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233148AbjIYQQh (ORCPT ); Mon, 25 Sep 2023 12:16:37 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51781CE for ; Mon, 25 Sep 2023 09:16:30 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.201]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvScM0hSDz6DBCn; Tue, 26 Sep 2023 00:14:11 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:16:28 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 10/19] hw/cxl: Add a switch mailbox CCI function Date: Mon, 25 Sep 2023 17:11:15 +0100 Message-ID: <20230925161124.18940-11-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 --- - 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', From patchwork Mon Sep 25 16:11:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398123 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 581A9CE7A9A for ; Mon, 25 Sep 2023 16:17:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229437AbjIYQRH (ORCPT ); Mon, 25 Sep 2023 12:17:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232767AbjIYQRG (ORCPT ); Mon, 25 Sep 2023 12:17:06 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB055B6 for ; Mon, 25 Sep 2023 09:17:00 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.201]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSfC5ypQz6K9PP; Tue, 26 Sep 2023 00:15:47 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:16:58 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 11/19] hw/pci-bridge/cxl_downstream: Set default link width and link speed Date: Mon, 25 Sep 2023 17:11:16 +0100 Message-ID: <20230925161124.18940-12-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Without these being set the PCIE Link Capabilities register has invalid values in these two fields. Signed-off-by: Jonathan Cameron --- 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 }, From patchwork Mon Sep 25 16:11:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398124 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90F13CE7A9A for ; Mon, 25 Sep 2023 16:17:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231698AbjIYQRl (ORCPT ); Mon, 25 Sep 2023 12:17:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42588 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232946AbjIYQRi (ORCPT ); Mon, 25 Sep 2023 12:17:38 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3B486B8 for ; Mon, 25 Sep 2023 09:17:31 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSfp2Jnlz67M6q; Tue, 26 Sep 2023 00:16:18 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:17:28 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 12/19] hw/cxl: Implement Physical Ports status retrieval Date: Mon, 25 Sep 2023 17:11:17 +0100 Message-ID: <20230925161124.18940-13-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org Add this command for both the Switch CCI and the MCTP CCI found in switch upstream ports. Signed-off-by: Jonathan Cameron --- 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, From patchwork Mon Sep 25 16:11:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398125 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9414ACE7A9A for ; Mon, 25 Sep 2023 16:18:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233148AbjIYQSJ (ORCPT ); Mon, 25 Sep 2023 12:18:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50630 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232767AbjIYQSI (ORCPT ); Mon, 25 Sep 2023 12:18:08 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98932B8 for ; Mon, 25 Sep 2023 09:18:01 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.201]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSgN5VxYz6K9lL; Tue, 26 Sep 2023 00:16:48 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:17:59 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 13/19] hw/cxl/mbox: Add Get Background Operation Status Command Date: Mon, 25 Sep 2023 17:11:18 +0100 Message-ID: <20230925161124.18940-14-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org For now, provide this command on type 3 main mailbox only. Signed-off-by: Jonathan Cameron --- 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 }, From patchwork Mon Sep 25 16:11:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398126 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60887CE7A9E for ; Mon, 25 Sep 2023 16:18:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231226AbjIYQSj (ORCPT ); Mon, 25 Sep 2023 12:18:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53694 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229437AbjIYQSj (ORCPT ); Mon, 25 Sep 2023 12:18:39 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 26A6CE8 for ; Mon, 25 Sep 2023 09:18:32 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.206]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSbd0HsXz6K9qs; Tue, 26 Sep 2023 00:13:33 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:18:29 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 14/19] hw/cxl/mbox: Add support for background operations Date: Mon, 25 Sep 2023 17:11:19 +0100 Message-ID: <20230925161124.18940-15-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Davidlohr Bueso 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 Signed-off-by: Jonathan Cameron --- 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, From patchwork Mon Sep 25 16:11:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398127 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 864F9CE7A9D for ; Mon, 25 Sep 2023 16:19:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231689AbjIYQTK (ORCPT ); Mon, 25 Sep 2023 12:19:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229437AbjIYQTJ (ORCPT ); Mon, 25 Sep 2023 12:19:09 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C0730B8 for ; Mon, 25 Sep 2023 09:19:02 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvShY6SFyz6K7VL; Tue, 26 Sep 2023 00:17:49 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:19:00 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 15/19] hw/cxl/mbox: Wire up interrupts for background completion Date: Mon, 25 Sep 2023 17:11:20 +0100 Message-ID: <20230925161124.18940-16-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Davidlohr Bueso 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 Signed-off-by: Jonathan Cameron --- 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); + } } } From patchwork Mon Sep 25 16:11:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398133 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8D488CE7A9A for ; Mon, 25 Sep 2023 16:19:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233205AbjIYQTm (ORCPT ); Mon, 25 Sep 2023 12:19:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233216AbjIYQTl (ORCPT ); Mon, 25 Sep 2023 12:19:41 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3D9F2FB for ; Mon, 25 Sep 2023 09:19:33 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSj82SbPz6K9bX; Tue, 26 Sep 2023 00:18:20 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:19:30 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 16/19] hw/cxl: Add support for device sanitation Date: Mon, 25 Sep 2023 17:11:21 +0100 Message-ID: <20230925161124.18940-17-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Davidlohr Bueso 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 Signed-off-by: Jonathan Cameron --- 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); } From patchwork Mon Sep 25 16:11:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398134 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B418CE7A9D for ; Mon, 25 Sep 2023 16:20:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232723AbjIYQUK (ORCPT ); Mon, 25 Sep 2023 12:20:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229437AbjIYQUK (ORCPT ); Mon, 25 Sep 2023 12:20:10 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0279EB8 for ; Mon, 25 Sep 2023 09:20:04 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSdN5yPdz6K9qp; Tue, 26 Sep 2023 00:15:04 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:20:01 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 17/19] hw/cxl/type3: Cleanup multiple CXL_TYPE3() calls in read/write functions Date: Mon, 25 Sep 2023 17:11:22 +0100 Message-ID: <20230925161124.18940-18-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org From: Gregory Price Call CXL_TYPE3 once at top of function to avoid multiple invocations. Signed-off-by: Gregory Price Signed-off-by: Jonathan Cameron --- 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; } From patchwork Mon Sep 25 16:11:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398135 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C44ECE7A9D for ; Mon, 25 Sep 2023 16:20:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231226AbjIYQUk (ORCPT ); Mon, 25 Sep 2023 12:20:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232767AbjIYQUk (ORCPT ); Mon, 25 Sep 2023 12:20:40 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B5BEB8 for ; Mon, 25 Sep 2023 09:20:34 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.201]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSdz0YDTz6K9qw; Tue, 26 Sep 2023 00:15:35 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:20:32 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 18/19] hw/cxl: Add dummy security state get Date: Mon, 25 Sep 2023 17:11:23 +0100 Message-ID: <20230925161124.18940-19-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 --- 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", From patchwork Mon Sep 25 16:11:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13398136 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C44CCE7A9D for ; Mon, 25 Sep 2023 16:21:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233192AbjIYQVO (ORCPT ); Mon, 25 Sep 2023 12:21:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39380 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233241AbjIYQVM (ORCPT ); Mon, 25 Sep 2023 12:21:12 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4D42010C for ; Mon, 25 Sep 2023 09:21:05 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4RvSkw2fQKz6K9px; Tue, 26 Sep 2023 00:19:52 +0800 (CST) Received: from SecurePC-101-06.china.huawei.com (10.122.247.231) by lhrpeml500005.china.huawei.com (7.191.163.240) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.31; Mon, 25 Sep 2023 17:21:03 +0100 From: Jonathan Cameron To: , , Michael Tsirkin CC: , Fan Ni , =?utf-8?q?Philippe_M?= =?utf-8?q?athieu-Daud=C3=A9?= , Davidlohr Bueso , Gregory Price , Klaus Jensen , Corey Minyard , Klaus Jensen Subject: [PATCH 19/19] hw/cxl: Add tunneled command support to mailbox for switch cci/mctp. Date: Mon, 25 Sep 2023 17:11:24 +0100 Message-ID: <20230925161124.18940-20-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> References: <20230925161124.18940-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml100001.china.huawei.com (7.191.160.183) To lhrpeml500005.china.huawei.com (7.191.163.240) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-cxl@vger.kernel.org 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 --- 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[] = {