From patchwork Thu May 25 16:08:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13255433 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 B7D51C7EE29 for ; Thu, 25 May 2023 16:10:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229543AbjEYQK0 (ORCPT ); Thu, 25 May 2023 12:10:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54402 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231397AbjEYQKZ (ORCPT ); Thu, 25 May 2023 12:10:25 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21E1FE54 for ; Thu, 25 May 2023 09:09:53 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4QRtDL5gJBz6J7BX; Fri, 26 May 2023 00:04:50 +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.23; Thu, 25 May 2023 17:09:29 +0100 From: Jonathan Cameron To: , Fan Ni CC: Niyas Sait , Klaus Jensen , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , "Michael S . Tsirkin" , Jeremy Kerr , Matt Johnston , Shesha Bhushan Sreenivasamurthy , , , "Viacheslav A . Dubeyko" , Peter Maydell Subject: [RFC PATCH 1/6] hw/acpi/aml-build: add function for i2c slave device serial bus description Date: Thu, 25 May 2023 17:08:54 +0100 Message-ID: <20230525160859.32517-2-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> References: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml500004.china.huawei.com (7.191.163.9) 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 Signed-off-by: Jonathan Cameron --- include/hw/acpi/aml-build.h | 1 + hw/acpi/aml-build.c | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h index fc2b949fb5..28db028b17 100644 --- a/include/hw/acpi/aml-build.h +++ b/include/hw/acpi/aml-build.h @@ -382,6 +382,7 @@ Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz, uint8_t channel); Aml *aml_sleep(uint64_t msec); Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source); +Aml *aml_i2c_slv_serial_bus_device(uint16_t address, const char *resource_source); /* Block AML object primitives */ Aml *aml_scope(const char *name_format, ...) G_GNUC_PRINTF(1, 2); diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c index 918cbb5b9d..22d7ecd753 100644 --- a/hw/acpi/aml-build.c +++ b/hw/acpi/aml-build.c @@ -2478,3 +2478,20 @@ Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source) return var; } + +/* ACPI 5.0: 6.4.3.8.2.1 I2C Serial Bus Connection Resource Descriptor */ +Aml *aml_i2c_slv_serial_bus_device(uint16_t address, const char *resource_source) +{ + uint16_t resource_source_len = strlen(resource_source) + 1; + Aml *var = aml_serial_bus_device(AML_SERIAL_BUS_TYPE_I2C, 1, 0, 1, + 6, resource_source_len); + + /* Connection Speed. Just set to 100K for now, it doesn't really matter. */ + build_append_int_noprefix(var->buf, 100000, 4); + build_append_int_noprefix(var->buf, address, sizeof(address)); + + /* This is a string, not a name, so just copy it directly in. */ + g_array_append_vals(var->buf, resource_source, resource_source_len); + + return var; +} From patchwork Thu May 25 16:08:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13255434 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 55A0BC77B7A for ; Thu, 25 May 2023 16:11:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229885AbjEYQLJ (ORCPT ); Thu, 25 May 2023 12:11:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232918AbjEYQLH (ORCPT ); Thu, 25 May 2023 12:11:07 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2092E7B for ; Thu, 25 May 2023 09:10:44 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.207]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4QRtJ05J5cz67fjF; Fri, 26 May 2023 00:08: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.23; Thu, 25 May 2023 17:10:00 +0100 From: Jonathan Cameron To: , Fan Ni CC: Niyas Sait , Klaus Jensen , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , "Michael S . Tsirkin" , Jeremy Kerr , Matt Johnston , Shesha Bhushan Sreenivasamurthy , , , "Viacheslav A . Dubeyko" , Peter Maydell Subject: [RFC PATCH 2/6] HACK: arm/virt: Add aspeed-i2c controller and MCTP EP to enable MCTP testing Date: Thu, 25 May 2023 17:08:55 +0100 Message-ID: <20230525160859.32517-3-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> References: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml500004.china.huawei.com (7.191.163.9) 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 As the only I2C emulation in QEMU that supports being both a master and a slave, suitable for MCTP over i2c is aspeed-i2c add this controller to the arm virt model and hook up our new i2c_mctp_cxl_fmapi device. The current Linux driver for aspeed-i2c has a hard requirement on a reset controller. Throw down the simplest reset controller I could find so as to avoid need to make any changes to the kernel code. Patch also builds appropriate device tree. Signed-off-by: Jonathan Cameron --- include/hw/arm/virt.h | 2 + hw/arm/virt.c | 92 +++++++++++++++++++++++++++++++++++++++++-- hw/arm/Kconfig | 1 + 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 9fc582fc5f..ea3a64f4a8 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -72,6 +72,8 @@ enum { VIRT_SMMU, VIRT_UART, VIRT_MMIO, + VIRT_I2C, + VIRT_RESET_FAKE, VIRT_RTC, VIRT_FW_CFG, VIRT_PCIE, diff --git a/hw/arm/virt.c b/hw/arm/virt.c index f0be654cef..b664c849fa 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -85,6 +85,8 @@ #include "hw/cxl/cxl.h" #include "hw/cxl/cxl_host.h" #include "qemu/guest-random.h" +#include "hw/i2c/i2c.h" +#include "hw/i2c/aspeed_i2c.h" #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ @@ -161,6 +163,8 @@ static const MemMapEntry base_memmap[] = { [VIRT_PVTIME] = { 0x090a0000, 0x00010000 }, [VIRT_SECURE_GPIO] = { 0x090b0000, 0x00001000 }, [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, + [VIRT_I2C] = { 0x0b000000, 0x00004000 }, + [VIRT_RESET_FAKE] = { 0x0b004000, 0x00000010 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 }, [VIRT_SECURE_MEM] = { 0x0e000000, 0x01000000 }, @@ -203,6 +207,7 @@ static const int a15irqmap[] = { [VIRT_GPIO] = 7, [VIRT_SECURE_UART] = 8, [VIRT_ACPI_GED] = 9, + [VIRT_I2C] = 10, [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */ [VIRT_SMMU] = 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */ @@ -2275,6 +2280,85 @@ static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem) } } +static void create_mctp(MachineState *ms) +{ + VirtMachineState *vms = VIRT_MACHINE(ms); + MemoryRegion *sysmem = get_system_memory(); + AspeedI2CState *aspeedi2c; + struct DeviceState *dev; + char *nodename_i2c_master; + char *nodename_i2c_sub; + char *nodename_reset; + uint32_t clk_phandle, reset_phandle; + MemoryRegion *sysmem2; + + dev = qdev_new("aspeed.i2c-ast2600"); + aspeedi2c = ASPEED_I2C(dev); + object_property_set_link(OBJECT(dev), "dram", OBJECT(ms->ram), + &error_fatal); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, vms->memmap[VIRT_I2C].base); + sysbus_connect_irq(SYS_BUS_DEVICE(&aspeedi2c->busses[0]), 0, + qdev_get_gpio_in(vms->gic, vms->irqmap[VIRT_I2C])); + + /* I2C bus DT */ + reset_phandle = qemu_fdt_alloc_phandle(ms->fdt); + nodename_reset = g_strdup_printf("/reset@%" PRIx64, + vms->memmap[VIRT_RESET_FAKE].base); + qemu_fdt_add_subnode(ms->fdt, nodename_reset); + qemu_fdt_setprop_string(ms->fdt, nodename_reset, + "compatible", "snps,dw-low-reset"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename_reset, "reg", + 2, vms->memmap[VIRT_RESET_FAKE].base, + 2, vms->memmap[VIRT_RESET_FAKE].size); + qemu_fdt_setprop_cell(ms->fdt, nodename_reset, "#reset-cells", 0x1); + qemu_fdt_setprop_cell(ms->fdt, nodename_reset, "phandle", reset_phandle); + sysmem2 = g_new(MemoryRegion, 1); + memory_region_init_ram(sysmem2, NULL, "reset", + vms->memmap[VIRT_RESET_FAKE].size, NULL); + memory_region_add_subregion(sysmem, + vms->memmap[VIRT_RESET_FAKE].base, sysmem2); + + clk_phandle = qemu_fdt_alloc_phandle(ms->fdt); + + qemu_fdt_add_subnode(ms->fdt, "/mclk"); + qemu_fdt_setprop_string(ms->fdt, "/mclk", "compatible", "fixed-clock"); + qemu_fdt_setprop_cell(ms->fdt, "/mclk", "#clock-cells", 0x0); + qemu_fdt_setprop_cell(ms->fdt, "/mclk", "clock-frequency", 24000); + qemu_fdt_setprop_string(ms->fdt, "/mclk", "clock-output-names", "bobsclk"); + qemu_fdt_setprop_cell(ms->fdt, "/mclk", "phandle", clk_phandle); + + nodename_i2c_master = g_strdup_printf("/i2c@%" PRIx64, + vms->memmap[VIRT_I2C].base); + qemu_fdt_add_subnode(ms->fdt, nodename_i2c_master); + qemu_fdt_setprop_string(ms->fdt, nodename_i2c_master, + "compatible", "aspeed,ast2600-i2c-bus"); + qemu_fdt_setprop_cells(ms->fdt, nodename_i2c_master, "multi-master"); + qemu_fdt_setprop_cell(ms->fdt, nodename_i2c_master, "#size-cells", 0); + qemu_fdt_setprop_cell(ms->fdt, nodename_i2c_master, "#address-cells", 1); + qemu_fdt_setprop_cell(ms->fdt, nodename_i2c_master, "clocks", clk_phandle); + qemu_fdt_setprop_string(ms->fdt, nodename_i2c_master, + "clock-names", "bobsclk"); + qemu_fdt_setprop(ms->fdt, nodename_i2c_master, "mctp-controller", NULL, 0); + qemu_fdt_setprop_cells(ms->fdt, nodename_i2c_master, + "interrupts", GIC_FDT_IRQ_TYPE_SPI, + vms->irqmap[VIRT_I2C], GIC_FDT_IRQ_FLAGS_LEVEL_HI); + /* Offset to the first bus is 0x80, next one at 0x100 etc */ + qemu_fdt_setprop_sized_cells(ms->fdt, nodename_i2c_master, "reg", + 2, vms->memmap[VIRT_I2C].base + 0x80, + 2, 0x80); + qemu_fdt_setprop_cells(ms->fdt, nodename_i2c_master, + "resets", reset_phandle, 0); + + nodename_i2c_sub = g_strdup_printf("/i2c@%" PRIx64 "/mctp@%" PRIx64, + vms->memmap[VIRT_I2C].base, 0x50l); + qemu_fdt_add_subnode(ms->fdt, nodename_i2c_sub); + qemu_fdt_setprop_string(ms->fdt, nodename_i2c_sub, + "compatible", "mctp-i2c-controller"); + qemu_fdt_setprop_sized_cells(ms->fdt, nodename_i2c_sub, + "reg", 1, 0x50 | 0x40000000); +} + static void machvirt_init(MachineState *machine) { VirtMachineState *vms = VIRT_MACHINE(machine); @@ -2565,9 +2649,11 @@ static void machvirt_init(MachineState *machine) create_gpio_devices(vms, VIRT_SECURE_GPIO, secure_sysmem); } - /* connect powerdown request */ - vms->powerdown_notifier.notify = virt_powerdown_req; - qemu_register_powerdown_notifier(&vms->powerdown_notifier); + create_mctp(machine); + + /* connect powerdown request */ + vms->powerdown_notifier.notify = virt_powerdown_req; + qemu_register_powerdown_notifier(&vms->powerdown_notifier); /* Create mmio transports, so the user can create virtio backends * (which will be automatically plugged in to the transports). If diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index 223597ff13..298134ce85 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -32,6 +32,7 @@ config ARM_VIRT select VIRTIO_MEM_SUPPORTED select ACPI_CXL select ACPI_HMAT + select I2C_MCTP_CXL_FMAPI config CHEETAH bool From patchwork Thu May 25 16:08:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13255435 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 34939C77B7A for ; Thu, 25 May 2023 16:11:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231279AbjEYQL0 (ORCPT ); Thu, 25 May 2023 12:11:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231397AbjEYQLY (ORCPT ); Thu, 25 May 2023 12:11:24 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5F962E5E for ; Thu, 25 May 2023 09:10:58 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.200]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4QRtFX0VSFz6J6w8; Fri, 26 May 2023 00:05: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.23; Thu, 25 May 2023 17:10:31 +0100 From: Jonathan Cameron To: , Fan Ni CC: Niyas Sait , Klaus Jensen , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , "Michael S . Tsirkin" , Jeremy Kerr , Matt Johnston , Shesha Bhushan Sreenivasamurthy , , , "Viacheslav A . Dubeyko" , Peter Maydell Subject: [RFC PATCH 3/6] HACK: hw/arm/virt: Add ACPI support for aspeed-i2c / mctp Date: Thu, 25 May 2023 17:08:56 +0100 Message-ID: <20230525160859.32517-4-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> References: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml500001.china.huawei.com (7.191.163.213) 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 this for FM-API testing for CXL devices via MCTP over I2C Example DSDT block: Device (MCTP) { Name (_HID, "PRP0001") // _HID: Hardware ID Name (_DSD, Package (0x02) // _DSD: Device-Specific Data { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, Package (0x03) { Package (0x02) { "compatible", "aspeed,ast2600-i2c-bus" }, Package (0x02) { "bus-frequency", 0x00061A80 }, Package (0x02) { "mctp-controller", One } } }) Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { Memory32Fixed (ReadWrite, 0x0B000080, // Address Base 0x00000080, // Address Length ) Interrupt (ResourceConsumer, Level, ActiveHigh, Exclusive, ,, ) { 0x0000002A, } }) } Device (MCTS) { Name (_HID, "PRP0001") // _HID: Hardware ID Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { I2cSerialBusV2 (0x0050, DeviceInitiated, 0x000186A0, AddressingMode7Bit, "\\_SB.MCTP", 0x00, ResourceProducer, , Exclusive, ) }) Name (_DSD, Package (0x02) // _DSD: Device-Specific Data { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, Package (0x01) { Package (0x02) { "compatible", "mctp-i2c-controller" } } }) } Tests not updated given I'm not currently proposing this for upstream. Signed-off-by: Jonathan Cameron --- hw/arm/virt-acpi-build.c | 60 ++++++++++++++++++++++++++++++++++++++++ hw/i2c/meson.build | 2 +- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 939a736342..2c170f75a3 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -77,6 +77,65 @@ static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms) } } +static void acpi_dsdt_add_mctp(Aml *scope, VirtMachineState *vms) +{ + uint32_t interrupt = vms->irqmap[VIRT_I2C] + ARM_SPI_BASE; + Aml *main_dev = aml_device("MCTP"); + Aml *sub_dev = aml_device("MCTS"); + Aml *dsd_pkg = aml_package(2); + Aml *props_pkg = aml_package(3); + Aml *pkg = aml_package(2); + Aml *crs = aml_resource_template(); + + aml_append(main_dev, aml_name_decl("_HID", aml_string("PRP0001"))); + + aml_append(pkg, aml_string("compatible")); + aml_append(pkg, aml_string("aspeed,ast2600-i2c-bus")); + aml_append(props_pkg, pkg); + + pkg = aml_package(2); + aml_append(pkg, aml_string("bus-frequency")); + aml_append(pkg, aml_int(400000)); + aml_append(props_pkg, pkg); + + pkg = aml_package(2); + aml_append(pkg, aml_string("mctp-controller")); + aml_append(pkg, aml_int(1)); + aml_append(props_pkg, pkg); + + aml_append(dsd_pkg, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); + aml_append(dsd_pkg, props_pkg); + aml_append(main_dev, aml_name_decl("_DSD", dsd_pkg)); + + aml_append(crs, aml_memory32_fixed(vms->memmap[VIRT_I2C].base + 0x80, + 0x80, AML_READ_WRITE)); + aml_append(crs, + aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, &interrupt, 1)); + aml_append(main_dev, aml_name_decl("_CRS", crs)); + + aml_append(sub_dev, aml_name_decl("_HID", aml_string("PRP0001"))); + + dsd_pkg = aml_package(2); + aml_append(dsd_pkg, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); + + props_pkg = aml_package(1); + + pkg = aml_package(2); + aml_append(pkg, aml_string("compatible")); + aml_append(pkg, aml_string("mctp-i2c-controller")); + aml_append(props_pkg, pkg); + aml_append(dsd_pkg, props_pkg); + + crs = aml_resource_template(); + aml_append(crs, aml_i2c_slv_serial_bus_device(0x50, "\\_SB.MCTP")); + aml_append(sub_dev, aml_name_decl("_CRS", crs)); + aml_append(sub_dev, aml_name_decl("_DSD", dsd_pkg)); + + aml_append(scope, main_dev); + aml_append(scope, sub_dev); +} + static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, uint32_t uart_irq) { @@ -887,6 +946,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) */ scope = aml_scope("\\_SB"); acpi_dsdt_add_cpus(scope, vms); + acpi_dsdt_add_mctp(scope, vms); acpi_dsdt_add_uart(scope, &memmap[VIRT_UART], (irqmap[VIRT_UART] + ARM_SPI_BASE)); if (vmc->acpi_expose_flash) { diff --git a/hw/i2c/meson.build b/hw/i2c/meson.build index fd1f9022fd..08fbbc1831 100644 --- a/hw/i2c/meson.build +++ b/hw/i2c/meson.build @@ -4,7 +4,7 @@ i2c_ss.add(when: 'CONFIG_MCTP_I2C', if_true: files('mctp.c')) i2c_ss.add(when: 'CONFIG_SMBUS', if_true: files('smbus_slave.c', 'smbus_master.c')) i2c_ss.add(when: 'CONFIG_ACPI_SMBUS', if_true: files('pm_smbus.c')) i2c_ss.add(when: 'CONFIG_ACPI_ICH9', if_true: files('smbus_ich9.c')) -i2c_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_i2c.c')) +i2c_ss.add(when: 'CONFIG_I2C', if_true: files('aspeed_i2c.c')) i2c_ss.add(when: 'CONFIG_BITBANG_I2C', if_true: files('bitbang_i2c.c')) i2c_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_i2c.c')) i2c_ss.add(when: 'CONFIG_IMX_I2C', if_true: files('imx_i2c.c')) From patchwork Thu May 25 16:08:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13255436 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 7C3C0C7EE29 for ; Thu, 25 May 2023 16:11:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232800AbjEYQLw (ORCPT ); Thu, 25 May 2023 12:11:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233104AbjEYQLv (ORCPT ); Thu, 25 May 2023 12:11:51 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0A23CE4C for ; Thu, 25 May 2023 09:11:20 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4QRtKB0YmFz67lKM; Fri, 26 May 2023 00:09:02 +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.23; Thu, 25 May 2023 17:11:01 +0100 From: Jonathan Cameron To: , Fan Ni CC: Niyas Sait , Klaus Jensen , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , "Michael S . Tsirkin" , Jeremy Kerr , Matt Johnston , Shesha Bhushan Sreenivasamurthy , , , "Viacheslav A . Dubeyko" , Peter Maydell Subject: [RFC PATCH 4/6] HACK: hw/i386/pc: Add Aspeed i2c controller + MCTP with ACPI tables Date: Thu, 25 May 2023 17:08:57 +0100 Message-ID: <20230525160859.32517-5-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> References: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml500004.china.huawei.com (7.191.163.9) 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 devices provide a standard Fabric Management API - FM-API. See CXL specification r3.0 from https://www.computeexpresslink.org In many real setups that will be used by a separate host from the one actually using the CXL devices (BMC or similar) but it is helpful to be able to use the main CXL emulation and the Fabric Management emulation on a single host. This 'hack' enables that (with minor kernel driver changes). There are many many things wrong with how this is done but for now it enables use of this aspeed controller with ACPI FW on an x86 host. That is useful for testing MCTP over I2C. If anyone has either: 1) Docs for an I2C controller with MCTP support that might actually appear on an x86 host. 2) A nice solution for how wrap this up in a device whilst minimising kernel changes. 3) A guide / reference example to how to do the interrupt 'right' (I'm an ARM focused developer so got lost in the x86 interrupt stuff). then let me know. For now this works and I will carry it out of tree on gitlab.com/jic23/qemu. DSDT blob - as this is a hack I haven't included test updates Scope (_SB) { Device (MCTP) { Name (_HID, "PRP0001") // _HID: Hardware ID Name (_DSD, Package (0x02) // _DSD: Device-Specific Data { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, Package (0x03) { Package (0x02) { "compatible", "aspeed,ast2600-i2c-bus" }, Package (0x02) { "bus-frequency", 0x00061A80 }, Package (0x02) { "mctp-controller", One } } }) Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, NonCacheable, ReadWrite, 0x0000000000000000, // Granularity 0x00000004800FC080, // Range Minimum 0x00000004800FC0FF, // Range Maximum 0x0000000000000000, // Translation Offset 0x0000000000000080, // Length ,, , AddressRangeMemory, TypeStatic) Interrupt (ResourceConsumer, Level, ActiveHigh, Shared, ,, ) { 0x00000007, } }) } Device (MCTS) { Name (_HID, "PRP0001") // _HID: Hardware ID Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings { I2cSerialBusV2 (0x0050, DeviceInitiated, 0x000186A0, AddressingMode7Bit, "\\_SB.MCTP", 0x00, ResourceProducer, , Exclusive, ) }) Name (_DSD, Package (0x02) // _DSD: Device-Specific Data { ToUUID ("daffd814-6eba-4d8c-8a91-bc9bbf4aa301") /* Device Properties for _DSD */, Package (0x01) { Package (0x02) { "compatible", "mctp-i2c-controller" } } }) } } To add devices to the bus use something like: -device i2c_mctp_cxl_switch,bus=aspeed.i2c.bus.0,address=4,target=us0 Signed-off-by: Jonathan Cameron --- include/hw/i386/pc.h | 1 + hw/i386/acpi-build.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ hw/i386/pc.c | 20 +++++++++++++- hw/i386/Kconfig | 1 + 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index c661e9cc80..2050dabc5f 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -56,6 +56,7 @@ typedef struct PCMachineState { SGXEPCState sgx_epc; CXLState cxl_devices_state; + hwaddr i2c_base; } PCMachineState; #define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device" diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index d0c8e8f045..511a637114 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1424,6 +1424,68 @@ static void build_acpi0017(Aml *table) aml_append(table, scope); } +static void acpi_dsdt_add_mctp(Aml *scope, PCMachineState *pcms) +{ + uint32_t interrupt = 7; + Aml *main_dev = aml_device("MCTP"); + Aml *sub_dev = aml_device("MCTS"); + Aml *dsd_pkg = aml_package(2); + Aml *props_pkg = aml_package(3); + Aml *pkg = aml_package(2); + Aml *crs = aml_resource_template(); + + aml_append(main_dev, aml_name_decl("_HID", aml_string("PRP0001"))); + + aml_append(pkg, aml_string("compatible")); + aml_append(pkg, aml_string("aspeed,ast2600-i2c-bus")); + aml_append(props_pkg, pkg); + + pkg = aml_package(2); + aml_append(pkg, aml_string("bus-frequency")); + aml_append(pkg, aml_int(400000)); + aml_append(props_pkg, pkg); + + pkg = aml_package(2); + aml_append(pkg, aml_string("mctp-controller")); + aml_append(pkg, aml_int(1)); + aml_append(props_pkg, pkg); + + aml_append(dsd_pkg, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); + aml_append(dsd_pkg, props_pkg); + aml_append(main_dev, aml_name_decl("_DSD", dsd_pkg)); + + aml_append(crs, aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, + AML_MAX_FIXED, AML_NON_CACHEABLE, + AML_READ_WRITE, 0, pcms->i2c_base + 0x80, + pcms->i2c_base + 0x80 + 0x80 - 1, + 0, 0x80)); + aml_append(crs, + aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, + AML_SHARED, &interrupt, 1)); + aml_append(main_dev, aml_name_decl("_CRS", crs)); + + aml_append(sub_dev, aml_name_decl("_HID", aml_string("PRP0001"))); + + dsd_pkg = aml_package(2); + aml_append(dsd_pkg, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301")); + + props_pkg = aml_package(1); + + pkg = aml_package(2); + aml_append(pkg, aml_string("compatible")); + aml_append(pkg, aml_string("mctp-i2c-controller")); + aml_append(props_pkg, pkg); + aml_append(dsd_pkg, props_pkg); + + crs = aml_resource_template(); + aml_append(crs, aml_i2c_slv_serial_bus_device(0x50, "\\_SB.MCTP")); + aml_append(sub_dev, aml_name_decl("_CRS", crs)); + aml_append(sub_dev, aml_name_decl("_DSD", dsd_pkg)); + + aml_append(scope, main_dev); + aml_append(scope, sub_dev); +} + /* * Precompute the crs ranges and bus numbers that will be used in PXB entries * in PXB SSDT. @@ -1652,6 +1714,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, build_hpet_aml(dsdt); } + sb_scope = aml_scope("_SB"); + acpi_dsdt_add_mctp(sb_scope, pcms); + aml_append(dsdt, sb_scope); if (vmbus_bridge) { sb_scope = aml_scope("_SB"); aml_append(sb_scope, build_vmbus_device_aml(vmbus_bridge)); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index bb62c994fa..6d77c8970e 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -95,6 +95,7 @@ #include "hw/i386/kvm/xen_gnttab.h" #include "hw/i386/kvm/xen_xenstore.h" #include "hw/mem/memory-device.h" +#include "hw/i2c/aspeed_i2c.h" #include "sysemu/replay.h" #include "target/i386/cpu.h" #include "e820_memory_layout.h" @@ -1083,6 +1084,8 @@ void pc_memory_init(PCMachineState *pcms, memory_region_init(mr, OBJECT(machine), "cxl_host_reg", cxl_size); memory_region_add_subregion(system_memory, cxl_base, mr); cxl_resv_end = cxl_base + cxl_size; + pcms->i2c_base = cxl_resv_end - 0x4000; + if (pcms->cxl_devices_state.fixed_windows) { hwaddr cxl_fmw_base; GList *it; @@ -1166,7 +1169,7 @@ uint64_t pc_pci_hole64_start(void) ram_addr_t size = 0; if (pcms->cxl_devices_state.is_enabled) { - hole64_start = pc_get_cxl_range_end(pcms); + hole64_start = pc_get_cxl_range_end(pcms) + 0x4000; } else if (pcmc->has_reserved_memory && (ms->ram_size < ms->maxram_size)) { pc_get_device_memory_range(pcms, &hole64_start, &size); if (!pcmc->broken_reserved_end) { @@ -1360,6 +1363,21 @@ void pc_basic_device_init(struct PCMachineState *pcms, /* Super I/O */ pc_superio_init(isa_bus, create_fdctrl, pcms->i8042_enabled, pcms->vmport != ON_OFF_AUTO_ON); + + { + AspeedI2CState *aspeed_i2c; + struct DeviceState *dev; + + dev = qdev_new("aspeed.i2c-ast2600"); + aspeed_i2c = ASPEED_I2C(dev); + object_property_set_link(OBJECT(dev), "dram", + OBJECT(MACHINE(pcms)->ram), &error_fatal); + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); + sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, pcms->i2c_base); + /* Hack ;) - Steal unused interrupt 7 */ + sysbus_connect_irq(SYS_BUS_DEVICE(&aspeed_i2c->busses[0]), 0, + x86ms->gsi[7]); + } } void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index 9051083c1e..31e1958368 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -45,6 +45,7 @@ config PC select ACPI_VMGENID select VIRTIO_PMEM_SUPPORTED select VIRTIO_MEM_SUPPORTED + select I2C_MCTP_CXL_FMAPI config PC_PCI bool From patchwork Thu May 25 16:08:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13255437 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 3A4A5C77B7A for ; Thu, 25 May 2023 16:12:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233837AbjEYQMK (ORCPT ); Thu, 25 May 2023 12:12:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234289AbjEYQMH (ORCPT ); Thu, 25 May 2023 12:12:07 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 769631A4 for ; Thu, 25 May 2023 09:11:44 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.226]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4QRtKm67hYz67kvQ; Fri, 26 May 2023 00:09:32 +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.23; Thu, 25 May 2023 17:11:32 +0100 From: Jonathan Cameron To: , Fan Ni CC: Niyas Sait , Klaus Jensen , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , "Michael S . Tsirkin" , Jeremy Kerr , Matt Johnston , Shesha Bhushan Sreenivasamurthy , , , "Viacheslav A . Dubeyko" , Peter Maydell Subject: [RFC PATCH 5/6] misc/i2c_mctp_cxl: Initial device emulation Date: Thu, 25 May 2023 17:08:58 +0100 Message-ID: <20230525160859.32517-6-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> References: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml500004.china.huawei.com (7.191.163.9) 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. Signed-off-by: Jonathan Cameron --- include/hw/cxl/cxl_fmapi.h | 102 ++++++++++ hw/cxl/i2c_mctp_cxl.c | 369 +++++++++++++++++++++++++++++++++++++ hw/arm/Kconfig | 3 +- hw/cxl/Kconfig | 3 + hw/cxl/meson.build | 1 + hw/i386/Kconfig | 3 +- hw/misc/meson.build | 1 + 7 files changed, 480 insertions(+), 2 deletions(-) diff --git a/include/hw/cxl/cxl_fmapi.h b/include/hw/cxl/cxl_fmapi.h new file mode 100644 index 0000000000..d5195a9fcc --- /dev/null +++ b/include/hw/cxl/cxl_fmapi.h @@ -0,0 +1,102 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * CXL Fabric Manager API definitions + * + * Copyright (c) 2023 Huawei Technologies. + * + * Refs to: Compute Express Link (CXL) Specification revision 3.0 Version 1.0 + * from www.computeexpresslink.org + * + * FM-API commands can be carried over various transports (MCTP, switch-CCI etc) + * so define the payloads in a common header. + */ + +#ifndef CXL_FMAPI_H +#define CXL_FMAPI_H + +#include "qemu/osdep.h" + +/* + * TODO: Confirm which commands sent via FM-API binding and which via Type 3 CCI + * binding. For now I'm assuming only stuff in the FM-API table goes via + * FM-API. + */ + +/* + * CXL r3.0 Table 8-36 Generic Component Command Opcodes + */ + +/* CXL r3.0 8.2.9.1.1 Identify (Opcode 0001h) */ +#define CXL_CCI_CMD_SET_INFOSTAT 0x00 +#define CXL_CCI_INFOSTAT_IDENTIFY 0x01 + +struct cxl_cci_infostat_identify_resp_pl { + uint16_t vendor_id; + uint16_t device_id; + uint16_t subsystem_vendor_id; + uint16_t subsystem_id; + uint8_t serial_num[8]; + uint8_t max_msg; + uint8_t component_type; +}; + +/* + * CXL r3.0 7.6.7 Fabric Management Application Programming Interface + */ +#define CXL_FMAPI_CMD_SET_PHYSICAL_SWITCH 0x51 +#define CXL_FMAPI_PHYSICAL_SWITCH_IDENTIFY_SWITCH 0x00 +#define CXL_FMAPI_GET_PHYSICAL_PORT_STATE 0x01 + +/* + * CXL r3.0 7.6.7.1.1 Identify Switch Device (Opcode 5100h) + */ +struct cxl_fmapi_ident_switch_dev_resp_pl { + uint8_t ingres_port_id; + uint8_t rsv1; + uint8_t num_physical_ports; + uint8_t num_vcs; + uint8_t active_port_bitmask[32]; + uint8_t active_vcs_bitmask[32]; + uint16_t num_total_vppb; + uint16_t num_active_vppb; + uint8_t num_hdm_decoders; +} QEMU_PACKED; + +/* + * CXL r3.0 7.6.7.1.2 Get Physical Port State (Opcode 5101h) + */ + +/* 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; /* CHECK. may get too large for MCTP message size */ + uint8_t ports[]; +} QEMU_PACKED; + +/* 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; + +#endif /* CXL_FMAPI_H */ diff --git a/hw/cxl/i2c_mctp_cxl.c b/hw/cxl/i2c_mctp_cxl.c new file mode 100644 index 0000000000..8ce4c25eef --- /dev/null +++ b/hw/cxl/i2c_mctp_cxl.c @@ -0,0 +1,369 @@ +/* + * 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 "hw/irq.h" +#include "migration/vmstate.h" +#include "qapi/error.h" +#include "hw/cxl/cxl.h" +#include "hw/cxl/cxl_fmapi.h" +#include "hw/pci/pcie.h" +#include "hw/pci/pcie_port.h" +#include "hw/qdev-properties.h" + +#define TYPE_I2C_MCTP_CXL "i2c_mctp_cxl" + +#define MCTP_CXL_MAX_MSG_LEN 1088 /* CXL FMAPI binding spec */ + +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 vendor_tatus; + uint16_t rc; + uint8_t payload[]; +} QEMU_PACKED CXLMCTPMessage; + +enum cxl_dev_type { + cxl_type3, + cxl_switch, +}; + +struct I2C_MCTP_CXL_State { + MCTPI2CEndpoint mctp; + PCIDevice *target; + 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 void cxl_cci_cmd_set_info_and_status_parse(I2C_MCTP_CXL_State *s, + CXLMCTPMessage *msg) +{ + CXLMCTPMessage *out = (void *)s->scratch; + PCIDeviceClass *class = PCI_DEVICE_GET_CLASS(s->target); + + switch (msg->command) { + case CXL_CCI_INFOSTAT_IDENTIFY: + { + struct cxl_cci_infostat_identify_resp_pl *pl = + (struct cxl_cci_infostat_identify_resp_pl *)&s->scratch[s->pos]; + + *pl = (struct cxl_cci_infostat_identify_resp_pl) { + .vendor_id = class->vendor_id, + .device_id = class->device_id, + .subsystem_vendor_id = class->subsystem_vendor_id, + .subsystem_id = class->subsystem_id, + /* TODO : Get serial number - a bit fiddly */ + .max_msg = 9, /* 512 - no need to chunk mctp for this */ + }; + switch (s->type) { + case cxl_type3: + pl->component_type = 0x3; + break; + case cxl_switch: + pl->component_type = 0x0; + break; + } + + s->len += sizeof(*pl); + out->rc = CXL_MBOX_SUCCESS; + return; + } + + default: + out->rc = CXL_MBOX_UNSUPPORTED; + return; + } +} + +/* May make sense to push some of this to individual device emulation */ +static void cxl_fmapi_cmd_set_physical_switch_parse(I2C_MCTP_CXL_State *s, + CXLMCTPMessage *msg) +{ + CXLMCTPMessage *out = (void *)s->scratch; + + if (s->type != cxl_switch) { + /* TODO: Rename return codes as used for this as well as mailbox */ + out->rc = CXL_MBOX_UNSUPPORTED; + return; + } + + switch (msg->command) { + case CXL_FMAPI_PHYSICAL_SWITCH_IDENTIFY_SWITCH: + { + PCIEPort *usp = PCIE_PORT(s->target); + PCIBus *bus = &PCI_BRIDGE(s->target)->sec_bus; + struct cxl_fmapi_ident_switch_dev_resp_pl *pl = + (struct cxl_fmapi_ident_switch_dev_resp_pl *)&s->scratch[s->pos]; + int num_phys_ports = pcie_count_ds_ports(bus); + int devfn; + + *pl = (struct cxl_fmapi_ident_switch_dev_resp_pl) { + /* TODO: Should be parameterized to support multiple instances */ + .ingres_port_id = 0, + .num_physical_ports = num_phys_ports + 1, /* 1 USP */ + .num_vcs = 1, /* Not yet support multiple VCS - potentialy tricky */ + .active_vcs_bitmask[0] = 0x1, + .num_total_vppb = num_phys_ports + 1, + .num_active_vppb = num_phys_ports + 1, + .num_hdm_decoders = 4, + }; + + /* Fill in the active ports bitmask with all USP and DSP port numbers */ + for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) { + PCIDevice *d = bus->devices[devfn]; + + if (!d || !pci_is_express(d) || !d->exp.exp_cap) { + continue; + } + if (object_dynamic_cast(OBJECT(d), TYPE_PCIE_PORT)) { + PCIEPort *port = PCIE_PORT(d); + uint8_t portnum = port->port; + pl->active_port_bitmask[portnum / 8] |= (1 << portnum % 8); + } + } + pl->active_port_bitmask[usp->port / 8] |= (1 << usp->port % 8); + + s->len += sizeof(*pl); + out->rc = CXL_MBOX_SUCCESS; + + return; + } + + case CXL_FMAPI_GET_PHYSICAL_PORT_STATE: + { + size_t pl_size; + uint8_t num_ports = msg->payload[0]; + int num_phys_ports = pcie_count_ds_ports(&PCI_BRIDGE(s->target)->sec_bus); + struct cxl_fmapi_get_phys_port_state_resp_pl *pl = + (struct cxl_fmapi_get_phys_port_state_resp_pl *)&s->scratch[s->pos]; + int i; + + /* TODO: Should match against particular ports requested... */ + pl->num_ports = num_phys_ports; + for (i = 0; i < pl->num_ports; i++) { + struct cxl_fmapi_port_state_info_block *port; + port = &pl->ports[i]; + port->port_id = i; /* TODO: Right port number */ + if (port->port_id < 1) { /* 1 upstream ports */ + port->config_state = 4; + port->connected_device_type = 0; + } else { /* remainder downstream ports */ + port->config_state = 3; + port->connected_device_type = 4; /* TODO: Check. CXL type 3 */ + port->supported_ld_count = 3; + } + port->connected_device_cxl_version = 2; + port->port_cxl_version_bitmask = 0x2; + port->max_link_width = 0x10; /* x16 */ + port->negotiated_link_width = 0x10; + port->supported_link_speeds_vector = 0x1c; /* 8, 16, 32 GT/s */ + port->max_link_speed = 5; + port->current_link_speed = 5; /* 32 */ + port->ltssm_state = 0x7; /* L2 */ + port->first_lane_num = 0; + port->link_state = 0; + } + + pl_size = sizeof(pl) + sizeof(*pl->ports) * num_ports; + + st24_le_p(out->pl_length, pl_size); + s->len += pl_size; + msg->rc = CXL_MBOX_SUCCESS; + + return; + } + + default: + msg->rc = CXL_MBOX_UNSUPPORTED; + return; + } +} + +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_message_bytes(MCTPI2CEndpoint *mctp, + 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 |= MCTP_H_FLAGS_SOM; + } + + memcpy(buf, s->scratch + s->pos, len); + s->pos += len; + + if (s->pos == s->len) { + *mctp_flags |= MCTP_H_FLAGS_EOM; + + s->pos = s->len = 0; + } + + return len; +} + +static int i2c_mctp_cxl_put_message_bytes(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_message_types(MCTPI2CEndpoint *mctp, + uint8_t *data, + size_t maxlen) +{ + uint8_t buf[] = { + 0x0, 0x7, 0x8, /* Control, CXL FM-API and CXL CCI */ + }; + + memcpy(data, buf, sizeof(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 = { + .message_type = msg->message_type, + .category = 1, + .tag = msg->tag, + .command = msg->command, + .command_set = msg->command_set, + }; + + memcpy(s->scratch, &buf, sizeof(buf)); + s->pos = sizeof(buf); + + switch (msg->message_type) { + case 0x7: + switch (msg->command_set) { + case CXL_FMAPI_CMD_SET_PHYSICAL_SWITCH: + cxl_fmapi_cmd_set_physical_switch_parse(s, msg); + break; + } + break; + case 0x8: + switch (msg->command_set) { + case CXL_CCI_CMD_SET_INFOSTAT: + cxl_cci_cmd_set_info_and_status_parse(s, msg); + break; + } + break; + } + s->pos = 0; + + i2c_mctp_schedule_send(mctp); +} + +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)) { + s->type = cxl_switch; + return; + } + + if (object_dynamic_cast(OBJECT(s->target), TYPE_CXL_TYPE3)) { + s->type = cxl_type3; + 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_message_types = i2c_mctp_cxl_get_message_types; + mc->get_message_bytes = i2c_mctp_cxl_get_message_bytes; + mc->put_message_bytes = i2c_mctp_cxl_put_message_bytes; + + mc->handle_message = i2c_mctp_cxl_handle_message; + mc->reset_message = 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/arm/Kconfig b/hw/arm/Kconfig index 298134ce85..f0c6f91abe 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -32,7 +32,8 @@ config ARM_VIRT select VIRTIO_MEM_SUPPORTED select ACPI_CXL select ACPI_HMAT - select I2C_MCTP_CXL_FMAPI + select MCTP_I2C + select I2C_MCTP_CXL config CHEETAH bool diff --git a/hw/cxl/Kconfig b/hw/cxl/Kconfig index 8e67519b16..c9b2e46bac 100644 --- a/hw/cxl/Kconfig +++ b/hw/cxl/Kconfig @@ -1,3 +1,6 @@ config CXL bool default y if PCI_EXPRESS + +config I2C_MCTP_CXL + bool diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build index 99ee564ce8..5fba90e5b5 100644 --- a/hw/cxl/meson.build +++ b/hw/cxl/meson.build @@ -12,5 +12,6 @@ softmmu_ss.add(when: 'CONFIG_CXL', if_false: files( 'cxl-host-stubs.c', )) +softmmu_ss.add(when: 'CONFIG_I2C_MCTP_CXL', if_true: files('i2c_mctp_cxl.c')) softmmu_ss.add(when: 'CONFIG_ALL', if_true: files('cxl-host-stubs.c')) diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index 31e1958368..9644e81254 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -45,7 +45,8 @@ config PC select ACPI_VMGENID select VIRTIO_PMEM_SUPPORTED select VIRTIO_MEM_SUPPORTED - select I2C_MCTP_CXL_FMAPI + select MCTP_I2C + select I2C_MCTP_CXL config PC_PCI bool diff --git a/hw/misc/meson.build b/hw/misc/meson.build index a40245ad44..ce5891716b 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -128,6 +128,7 @@ softmmu_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_rng.c')) softmmu_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_ahb_apb_pnp.c')) + softmmu_ss.add(when: 'CONFIG_I2C', if_true: files('i2c-echo.c')) specific_ss.add(when: 'CONFIG_AVR_POWER', if_true: files('avr_power.c')) From patchwork Thu May 25 16:08:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 13255438 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 2A9B8C7EE2D for ; Thu, 25 May 2023 16:12:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234155AbjEYQMf (ORCPT ); Thu, 25 May 2023 12:12:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233760AbjEYQMe (ORCPT ); Thu, 25 May 2023 12:12:34 -0400 Received: from frasgout.his.huawei.com (frasgout.his.huawei.com [185.176.79.56]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A96F710CC for ; Thu, 25 May 2023 09:12:05 -0700 (PDT) Received: from lhrpeml500005.china.huawei.com (unknown [172.18.147.206]) by frasgout.his.huawei.com (SkyGuard) with ESMTP id 4QRtHJ05QTz6J71d; Fri, 26 May 2023 00:07:23 +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.23; Thu, 25 May 2023 17:12:03 +0100 From: Jonathan Cameron To: , Fan Ni CC: Niyas Sait , Klaus Jensen , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , "Michael S . Tsirkin" , Jeremy Kerr , Matt Johnston , Shesha Bhushan Sreenivasamurthy , , , "Viacheslav A . Dubeyko" , Peter Maydell Subject: [RFC PATCH 6/6] docs: cxl: Add example commandline for MCTP CXL CCIs Date: Thu, 25 May 2023 17:08:59 +0100 Message-ID: <20230525160859.32517-7-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> References: <20230525160859.32517-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.122.247.231] X-ClientProxiedBy: lhrpeml500004.china.huawei.com (7.191.163.9) 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 A lot more needed here on what these are for and what can be done with them. 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 f12011e230..5374b44f43 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 +---------------------------- + +TODO: Add some more info here on what this actually is. + +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 \ + -machine cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=1k \ + -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 + +Communication with the MCTP CCI can then be established using standard MCTP configuration +tools. + References ----------