From patchwork Tue Jan 5 16:52:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422569 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JWv1Vn6z9sVq for ; Wed, 6 Jan 2021 03:55:06 +1100 (AEDT) Received: from localhost ([::1]:59926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpbp-00089Y-Vd for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 11:55:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40690) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpam-00089J-4C for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:53:56 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpaj-00012W-LJ for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:53:55 -0500 IronPort-SDR: Jm0F1gwMqf9ZuckuBdXA7YHbpgEKXzwzSpUlROWccr0bg08zHDuN/F0wmvZM13iqIPGULNT4q4 Sfv9VHKy2l2g== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629492" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629492" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:50 -0800 IronPort-SDR: Wgs42zxH37SYT9IKqYxff4sjVLkaXyQfjhgcf+c3Ue3bVF+WfaR7vbP2l0GsCz/tf1iAiX4JHg RuX4Omezx1sg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337929" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:49 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 01/32] Temp: Add the PCI_EXT_ID_DVSEC definition to the qemu pci_regs.h copy. Date: Tue, 5 Jan 2021 08:52:52 -0800 Message-Id: <20210105165323.783725-2-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Jonathan Cameron This hasn't yet been added to the linux kernel tree, so for purposes of this RFC just add it locally. Signed-off-by: Jonathan Cameron Signed-off-by: Ben Widawsky --- include/standard-headers/linux/pci_regs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index a95d55f9f2..5d0b79b9da 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -723,6 +723,7 @@ #define PCI_EXT_CAP_ID_DPC 0x1D /* Downstream Port Containment */ #define PCI_EXT_CAP_ID_L1SS 0x1E /* L1 PM Substates */ #define PCI_EXT_CAP_ID_PTM 0x1F /* Precision Time Measurement */ +#define PCI_EXT_CAP_ID_DVSEC 0x23 /* Designated Vendor-Specific */ #define PCI_EXT_CAP_ID_DLF 0x25 /* Data Link Feature */ #define PCI_EXT_CAP_ID_PL_16GT 0x26 /* Physical Layer 16.0 GT/s */ #define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_PL_16GT From patchwork Tue Jan 5 16:52:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422570 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JWv5yCnz9sVw for ; Wed, 6 Jan 2021 03:55:07 +1100 (AEDT) Received: from localhost ([::1]:60076 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpbt-0008ER-OX for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 11:55:05 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40718) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpao-0008AB-KZ for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:53:58 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpam-00012q-JB for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:53:58 -0500 IronPort-SDR: Zhj5SEXuFqGywNhm/8IHS0srPlwRKb1R4cOGQPF5TFCIC8fS3veTwqc3flSyR7FLSIVVUMd/Ps M/RfQG9E1NAg== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629494" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629494" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:50 -0800 IronPort-SDR: N8x/h3IgQW6Zt2KY2/Lax+LItUV9TvDaiaZi5DGl6Pc0FOkOKoAR7yaD7ypZY9r+/k6dcyObST LB4IifZLoV1A== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337931" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:49 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 02/32] hw/pci/cxl: Add a CXL component type (interface) Date: Tue, 5 Jan 2021 08:52:53 -0800 Message-Id: <20210105165323.783725-3-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A CXL component is a hardware entity that implements CXL component registers from the CXL 2.0 spec (8.2.3). Currently these represent 3 general types. 1. Host Bridge 2. Ports (root, upstream, downstream) 3. Devices (memory, other) A CXL component can be conceptually thought of as a PCIe device with extra functionality when enumerated and enabled. For this reason, CXL does here, and will continue to add on to existing PCI code paths. Host bridges will typically need to be handled specially and so they can implement this newly introduced interface or not. All other components should implement this interface. Implementing this interface allows the core pci code to treat these devices as special where appropriate. Signed-off-by: Ben Widawsky --- hw/pci/pci.c | 10 ++++++++++ include/hw/pci/pci.h | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index a6b0c5602e..50fc61c81f 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -194,6 +194,11 @@ static const TypeInfo pci_bus_info = { .class_init = pci_bus_class_init, }; +static const TypeInfo cxl_interface_info = { + .name = INTERFACE_CXL_DEVICE, + .parent = TYPE_INTERFACE, +}; + static const TypeInfo pcie_interface_info = { .name = INTERFACE_PCIE_DEVICE, .parent = TYPE_INTERFACE, @@ -2115,6 +2120,10 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; } + if (object_class_dynamic_cast(klass, INTERFACE_CXL_DEVICE)) { + pci_dev->cap_present |= QEMU_PCIE_CAP_CXL; + } + pci_dev = do_pci_register_device(pci_dev, object_get_typename(OBJECT(qdev)), pci_dev->devfn, errp); @@ -2841,6 +2850,7 @@ static void pci_register_types(void) type_register_static(&pci_bus_info); type_register_static(&pcie_bus_info); type_register_static(&conventional_pci_interface_info); + type_register_static(&cxl_interface_info); type_register_static(&pcie_interface_info); type_register_static(&pci_device_type_info); } diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 259f9c992d..f6b1eff446 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -194,6 +194,8 @@ enum { QEMU_PCIE_LNKSTA_DLLLA = (1 << QEMU_PCIE_LNKSTA_DLLLA_BITNR), #define QEMU_PCIE_EXTCAP_INIT_BITNR 9 QEMU_PCIE_EXTCAP_INIT = (1 << QEMU_PCIE_EXTCAP_INIT_BITNR), +#define QEMU_PCIE_CXL_BITNR 10 + QEMU_PCIE_CAP_CXL = (1 << QEMU_PCIE_CXL_BITNR), }; #define TYPE_PCI_DEVICE "pci-device" @@ -201,6 +203,12 @@ typedef struct PCIDeviceClass PCIDeviceClass; DECLARE_OBJ_CHECKERS(PCIDevice, PCIDeviceClass, PCI_DEVICE, TYPE_PCI_DEVICE) +/* + * Implemented by devices that can be plugged on CXL buses. In the spec, this is + * actually a "CXL Component, but we name it device to match the PCI naming. + */ +#define INTERFACE_CXL_DEVICE "cxl-device" + /* Implemented by devices that can be plugged on PCI Express buses */ #define INTERFACE_PCIE_DEVICE "pci-express-device" From patchwork Tue Jan 5 16:52:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422571 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JX33MLbz9sWM for ; Wed, 6 Jan 2021 03:55:15 +1100 (AEDT) Received: from localhost ([::1]:60132 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpc1-0008Fi-FS for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 11:55:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40722) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpap-0008Az-7V for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:53:59 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpam-00012W-0t for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:53:59 -0500 IronPort-SDR: h5i2TE5DZO5B0CsCEOYdgcYmU1POPgtzK0KgJ6GQcFen96gqxzEGsxN73PpzcT7r07Po78ksmQ djvVFjBkjmNA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629500" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629500" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:51 -0800 IronPort-SDR: YneYSoLt8zZqx3Azi+W9TBbT/A2881cIdNMODqX6/phKsOk/qrecyQAYRbg6iZN5v19p6Iww6o DOrfM0WiYC4Q== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337939" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:50 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 03/32] hw/cxl/component: Introduce CXL components (8.1.x, 8.2.5) Date: Tue, 5 Jan 2021 08:52:54 -0800 Message-Id: <20210105165323.783725-4-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A CXL 2.0 component is any entity in the CXL topology. All components have a analogous function in PCIe. Except for the CXL host bridge, all have a PCIe config space that is accessible via the common PCIe mechanisms. CXL components are enumerated via DVSEC fields in the extended PCIe header space. CXL components will minimally implement some subset of CXL.mem and CXL.cache registers defined in 8.2.5 of the CXL 2.0 specification. Two headers and a utility library are introduced to support the minimum functionality needed to enumerate components. The cxl_pci header manages bits associated with PCI, specifically the DVSEC and related fields. The cxl_component.h variant has data structures and APIs that are useful for drivers implementing any of the CXL 2.0 components. The library takes care of making use of the DVSEC bits and the CXL.[mem|cache] regisetrs. None of the mechanisms required to enumerate a CXL capable hostbridge are introduced at this point. Note that the CXL.mem and CXL.cache registers used are always 4B wide. It's possible in the future that this constraint will not hold. v2: Improve assertions in DVSEC creation (Jonathan) Use 'n' for HDM register offsets (Jonathan) Correct revision ID for extensions (Jonathan) Minor cleanups and clarifications (Jonathan) Signed-off-by: Ben Widawsky --- MAINTAINERS | 6 + hw/Kconfig | 1 + hw/cxl/Kconfig | 3 + hw/cxl/cxl-component-utils.c | 193 +++++++++++++++++++++++++++++++++ hw/cxl/meson.build | 3 + hw/meson.build | 1 + include/hw/cxl/cxl.h | 17 +++ include/hw/cxl/cxl_component.h | 187 ++++++++++++++++++++++++++++++++ include/hw/cxl/cxl_pci.h | 138 +++++++++++++++++++++++ 9 files changed, 549 insertions(+) create mode 100644 hw/cxl/Kconfig create mode 100644 hw/cxl/cxl-component-utils.c create mode 100644 hw/cxl/meson.build create mode 100644 include/hw/cxl/cxl.h create mode 100644 include/hw/cxl/cxl_component.h create mode 100644 include/hw/cxl/cxl_pci.h diff --git a/MAINTAINERS b/MAINTAINERS index 42fedf91e7..1f5fc033b4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2225,6 +2225,12 @@ F: qapi/block*.json F: qapi/transaction.json T: git https://repo.or.cz/qemu/armbru.git block-next +Compute Express Link +M: Ben Widawsky +S: Supported +F: hw/cxl/ +F: include/hw/cxl/ + Dirty Bitmaps M: Eric Blake M: Vladimir Sementsov-Ogievskiy diff --git a/hw/Kconfig b/hw/Kconfig index 5ad3c6b5a4..c03650c5ed 100644 --- a/hw/Kconfig +++ b/hw/Kconfig @@ -6,6 +6,7 @@ source audio/Kconfig source block/Kconfig source char/Kconfig source core/Kconfig +source cxl/Kconfig source display/Kconfig source dma/Kconfig source gpio/Kconfig diff --git a/hw/cxl/Kconfig b/hw/cxl/Kconfig new file mode 100644 index 0000000000..8e67519b16 --- /dev/null +++ b/hw/cxl/Kconfig @@ -0,0 +1,3 @@ +config CXL + bool + default y if PCI_EXPRESS diff --git a/hw/cxl/cxl-component-utils.c b/hw/cxl/cxl-component-utils.c new file mode 100644 index 0000000000..a95c16505c --- /dev/null +++ b/hw/cxl/cxl-component-utils.c @@ -0,0 +1,193 @@ +/* + * CXL Utility library for components + * + * Copyright(C) 2020 Intel Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/pci/pci.h" +#include "hw/cxl/cxl.h" + +static uint64_t cxl_cache_mem_read_reg(void *opaque, hwaddr offset, + unsigned size) +{ + CXLComponentState *cxl_cstate = opaque; + ComponentRegisters *cregs = &cxl_cstate->crb; + uint32_t *cache_mem = cregs->cache_mem_registers; + + if (size != 4) { + qemu_log_mask(LOG_UNIMP, "%uB component register read (RAZ)\n", size); + return 0; + } + + if (cregs->special_ops && cregs->special_ops->read) { + return cregs->special_ops->read(cxl_cstate, offset, size); + } else { + return cache_mem[offset >> 2]; + } +} + +static void cxl_cache_mem_write_reg(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ + CXLComponentState *cxl_cstate = opaque; + ComponentRegisters *cregs = &cxl_cstate->crb; + + if (size != 4) { + qemu_log_mask(LOG_UNIMP, "%uB component register write (WI)\n", size); + return; + } + + if (cregs->special_ops && cregs->special_ops->write) { + cregs->special_ops->write(cxl_cstate, offset, value, size); + } +} + +static const MemoryRegionOps cache_mem_ops = { + .read = cxl_cache_mem_read_reg, + .write = cxl_cache_mem_write_reg, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, + .impl = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + +void cxl_component_register_block_init(Object *obj, + CXLComponentState *cxl_cstate, + const char *type) +{ + ComponentRegisters *cregs = &cxl_cstate->crb; + + memory_region_init(&cregs->component_registers, obj, type, 0x10000); + memory_region_init_io(&cregs->io, obj, NULL, cregs, ".io", 0x1000); + memory_region_init_io(&cregs->cache_mem, obj, &cache_mem_ops, cregs, + ".cache_mem", 0x1000); + + memory_region_add_subregion(&cregs->component_registers, 0, &cregs->io); + memory_region_add_subregion(&cregs->component_registers, 0x1000, + &cregs->cache_mem); +} + +static void ras_init_common(uint32_t *reg_state) +{ + reg_state[R_CXL_RAS_UNC_ERR_STATUS] = 0; + reg_state[R_CXL_RAS_UNC_ERR_MASK] = 0x1efff; + reg_state[R_CXL_RAS_UNC_ERR_SEVERITY] = 0x1efff; + reg_state[R_CXL_RAS_COR_ERR_STATUS] = 0; + reg_state[R_CXL_RAS_COR_ERR_MASK] = 0x3f; + reg_state[R_CXL_RAS_ERR_CAP_CTRL] = 0; /* CXL switches and devices must set */ +} + +static void hdm_init_common(uint32_t *reg_state) +{ + ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_CAPABILITY, DECODER_COUNT, 0); + ARRAY_FIELD_DP32(reg_state, CXL_HDM_DECODER_GLOBAL_CONTROL, HDM_DECODER_ENABLE, 0); +} + +void cxl_component_register_init_common(uint32_t *reg_state, enum reg_type type) +{ + int caps = 0; + switch (type) { + case CXL2_DOWNSTREAM_PORT: + case CXL2_DEVICE: + /* CAP, RAS, Link */ + caps = 2; + break; + case CXL2_UPSTREAM_PORT: + case CXL2_TYPE3_DEVICE: + case CXL2_LOGICAL_DEVICE: + /* + HDM */ + caps = 3; + break; + case CXL2_ROOT_PORT: + /* + Extended Security, + Snoop */ + caps = 5; + break; + default: + abort(); + } + + memset(reg_state, 0, 0x1000); + + /* CXL Capability Header Register */ + ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ID, 1); + ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, VERSION, 1); + ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, 1); + ARRAY_FIELD_DP32(reg_state, CXL_CAPABILITY_HEADER, ARRAY_SIZE, caps); + + +#define init_cap_reg(reg, id, version) \ + do { \ + int which = R_CXL_##reg##_CAPABILITY_HEADER; \ + reg_state[which] = FIELD_DP32(reg_state[which], \ + CXL_##reg##_CAPABILITY_HEADER, ID, id); \ + reg_state[which] = \ + FIELD_DP32(reg_state[which], CXL_##reg##_CAPABILITY_HEADER, \ + VERSION, version); \ + reg_state[which] = \ + FIELD_DP32(reg_state[which], CXL_##reg##_CAPABILITY_HEADER, PTR, \ + CXL_##reg##_REGISTERS_OFFSET); \ + } while (0) + + init_cap_reg(RAS, 2, 1); + ras_init_common(reg_state); + + init_cap_reg(LINK, 4, 2); + + if (caps < 4) { + return; + } + + init_cap_reg(HDM, 5, 1); + hdm_init_common(reg_state); + + if (caps < 6) { + return; + } + + init_cap_reg(EXTSEC, 6, 1); + init_cap_reg(SNOOP, 8, 1); + +#undef init_cap_reg +} + +/* + * Helper to creates a DVSEC header for a CXL entity. The caller is responsible + * for tracking the valid offset. + * + * This function will build the DVSEC header on behalf of the caller and then + * copy in the remaining data for the vendor specific bits. + */ +void cxl_component_create_dvsec(CXLComponentState *cxl, uint16_t length, + uint16_t type, uint8_t rev, uint8_t *body) +{ + PCIDevice *pdev = cxl->pdev; + uint16_t offset = cxl->dvsec_offset; + + assert(offset >= PCI_CFG_SPACE_SIZE && + ((offset + length) < PCI_CFG_SPACE_EXP_SIZE)); + assert((length & 0xf000) == 0); + assert((rev & ~0xf) == 0); + + /* Create the DVSEC in the MCFG space */ + pcie_add_capability(pdev, PCI_EXT_CAP_ID_DVSEC, 1, offset, length); + pci_set_long(pdev->config + offset + PCIE_DVSEC_HEADER1_OFFSET, + (length << 20) | (rev << 16) | CXL_VENDOR_ID); + pci_set_word(pdev->config + offset + PCIE_DVSEC_ID_OFFSET, type); + memcpy(pdev->config + offset + sizeof(struct dvsec_header), + body + sizeof(struct dvsec_header), + length - sizeof(struct dvsec_header)); + + /* Update state for future DVSEC additions */ + range_init_nofail(&cxl->dvsecs[type], cxl->dvsec_offset, length); + cxl->dvsec_offset += length; +} diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build new file mode 100644 index 0000000000..00c3876a0f --- /dev/null +++ b/hw/cxl/meson.build @@ -0,0 +1,3 @@ +softmmu_ss.add(when: 'CONFIG_CXL', if_true: files( + 'cxl-component-utils.c', +)) diff --git a/hw/meson.build b/hw/meson.build index 010de7219c..3e440c341a 100644 --- a/hw/meson.build +++ b/hw/meson.build @@ -6,6 +6,7 @@ subdir('block') subdir('char') subdir('core') subdir('cpu') +subdir('cxl') subdir('display') subdir('dma') subdir('gpio') diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h new file mode 100644 index 0000000000..55f6cc30a5 --- /dev/null +++ b/include/hw/cxl/cxl.h @@ -0,0 +1,17 @@ +/* + * QEMU CXL Support + * + * Copyright (c) 2020 Intel + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#ifndef CXL_H +#define CXL_H + +#include "cxl_pci.h" +#include "cxl_component.h" + +#endif + diff --git a/include/hw/cxl/cxl_component.h b/include/hw/cxl/cxl_component.h new file mode 100644 index 0000000000..8b40360c22 --- /dev/null +++ b/include/hw/cxl/cxl_component.h @@ -0,0 +1,187 @@ +/* + * QEMU CXL Component + * + * Copyright (c) 2020 Intel + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#ifndef CXL_COMPONENT_H +#define CXL_COMPONENT_H + +/* CXL 2.0 - 8.2.4 */ +#define CXL2_COMPONENT_IO_REGION_SIZE 0x1000 +#define CXL2_COMPONENT_CM_REGION_SIZE 0x1000 +#define CXL2_COMPONENT_BLOCK_SIZE 0x10000 + +#include "qemu/range.h" +#include "qemu/typedefs.h" +#include "hw/register.h" + +enum reg_type { + CXL2_DEVICE, + CXL2_TYPE3_DEVICE, + CXL2_LOGICAL_DEVICE, + CXL2_ROOT_PORT, + CXL2_UPSTREAM_PORT, + CXL2_DOWNSTREAM_PORT +}; + +/* + * Capability registers are defined at the top of the CXL.cache/mem region and + * are packed. For our purposes we will always define the caps in the same + * order. + * CXL 2.0 - 8.2.5 Table 142 for details. + */ + +/* CXL 2.0 - 8.2.5.1 */ +REG32(CXL_CAPABILITY_HEADER, 0) + FIELD(CXL_CAPABILITY_HEADER, ID, 0, 16) + FIELD(CXL_CAPABILITY_HEADER, VERSION, 16, 4) + FIELD(CXL_CAPABILITY_HEADER, CACHE_MEM_VERSION, 20, 4) + FIELD(CXL_CAPABILITY_HEADER, ARRAY_SIZE, 24, 8) + +#define CXLx_CAPABILITY_HEADER(type, offset) \ + REG32(CXL_##type##_CAPABILITY_HEADER, offset) \ + FIELD(CXL_##type##_CAPABILITY_HEADER, ID, 0, 16) \ + FIELD(CXL_##type##_CAPABILITY_HEADER, VERSION, 16, 4) \ + FIELD(CXL_##type##_CAPABILITY_HEADER, PTR, 20, 12) +CXLx_CAPABILITY_HEADER(RAS, 0x4) +CXLx_CAPABILITY_HEADER(LINK, 0x8) +CXLx_CAPABILITY_HEADER(HDM, 0xc) +CXLx_CAPABILITY_HEADER(EXTSEC, 0x10) +CXLx_CAPABILITY_HEADER(SNOOP, 0x14) + +/* + * Capability structures contain the actual registers that the CXL component + * implements. Some of these are specific to certain types of components, but + * this implementation leaves enough space regardless. + */ +/* 8.2.5.9 - CXL RAS Capability Structure */ +#define CXL_RAS_REGISTERS_OFFSET 0x80 /* Give ample space for caps before this */ +#define CXL_RAS_REGISTERS_SIZE 0x58 +REG32(CXL_RAS_UNC_ERR_STATUS, CXL_RAS_REGISTERS_OFFSET) +REG32(CXL_RAS_UNC_ERR_MASK, CXL_RAS_REGISTERS_OFFSET + 0x4) +REG32(CXL_RAS_UNC_ERR_SEVERITY, CXL_RAS_REGISTERS_OFFSET + 0x8) +REG32(CXL_RAS_COR_ERR_STATUS, CXL_RAS_REGISTERS_OFFSET + 0xc) +REG32(CXL_RAS_COR_ERR_MASK, CXL_RAS_REGISTERS_OFFSET + 0x10) +REG32(CXL_RAS_ERR_CAP_CTRL, CXL_RAS_REGISTERS_OFFSET + 0x14) +/* Offset 0x18 - 0x58 reserved for RAS logs */ + +/* 8.2.5.10 - CXL Security Capability Structure */ +#define CXL_SEC_REGISTERS_OFFSET (CXL_RAS_REGISTERS_OFFSET + CXL_RAS_REGISTERS_SIZE) +#define CXL_SEC_REGISTERS_SIZE 0 /* We don't implement 1.1 downstream ports */ + +/* 8.2.5.11 - CXL Link Capability Structure */ +#define CXL_LINK_REGISTERS_OFFSET (CXL_SEC_REGISTERS_OFFSET + CXL_SEC_REGISTERS_SIZE) +#define CXL_LINK_REGISTERS_SIZE 0x38 + +/* 8.2.5.12 - CXL HDM Decoder Capability Structure */ +#define HDM_DECODE_MAX 10 /* 8.2.5.12.1 */ +#define CXL_HDM_REGISTERS_OFFSET \ + (CXL_LINK_REGISTERS_OFFSET + CXL_LINK_REGISTERS_SIZE) /* 8.2.5.12 */ +#define CXL_HDM_REGISTERS_SIZE (0x20 + HDM_DECODE_MAX * 10) +#define HDM_DECODER_INIT(n) \ + REG32(CXL_HDM_DECODER##n##_BASE_LO, \ + CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x10) \ + FIELD(CXL_HDM_DECODER##n##_BASE_LO, L, 28, 4) \ + REG32(CXL_HDM_DECODER##n##_BASE_HI, \ + CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x14) \ + REG32(CXL_HDM_DECODER##n##_SIZE_LO, \ + CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x18) \ + REG32(CXL_HDM_DECODER##n##_SIZE_HI, \ + CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x1C) \ + REG32(CXL_HDM_DECODER##n##_CTRL, \ + CXL_HDM_REGISTERS_OFFSET + (0x20 * n) + 0x20) \ + FIELD(CXL_HDM_DECODER##n##_CTRL, IG, 0, 4) \ + FIELD(CXL_HDM_DECODER##n##_CTRL, IW, 4, 4) \ + FIELD(CXL_HDM_DECODER##n##_CTRL, LOCK_ON_COMMIT, 8, 1) \ + FIELD(CXL_HDM_DECODER##n##_CTRL, COMMIT, 9, 1) \ + FIELD(CXL_HDM_DECODER##n##_CTRL, COMMITTED, 10, 1) \ + FIELD(CXL_HDM_DECODER##n##_CTRL, ERROR, 11, 1) \ + FIELD(CXL_HDM_DECODER##n##_CTRL, TYPE, 12, 1) \ + REG32(CXL_HDM_DECODER##n##_TARGET_LIST_LO, 0x24) \ + REG32(CXL_HDM_DECODER##n##_TARGET_LIST_HI, 0x28) + +REG32(CXL_HDM_DECODER_CAPABILITY, 0) + FIELD(CXL_HDM_DECODER_CAPABILITY, DECODER_COUNT, 0, 4) + FIELD(CXL_HDM_DECODER_CAPABILITY, TARGET_COUNT, 4, 4) + FIELD(CXL_HDM_DECODER_CAPABILITY, INTERLEAVE_256B, 8, 1) + FIELD(CXL_HDM_DECODER_CAPABILITY, INTELEAVE_4K, 9, 1) + FIELD(CXL_HDM_DECODER_CAPABILITY, POISON_ON_ERR_CAP, 10, 1) +REG32(CXL_HDM_DECODER_GLOBAL_CONTROL, 0) + FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL, POISON_ON_ERR_EN, 0, 1) + FIELD(CXL_HDM_DECODER_GLOBAL_CONTROL, HDM_DECODER_ENABLE, 1, 1) + +HDM_DECODER_INIT(0); + +/* 8.2.5.13 - CXL Extended Security Capability Structure (Root complex only) */ +#define EXTSEC_ENTRY_MAX 256 +#define CXL_EXTSEC_REGISTERS_OFFSET (CXL_HDM_REGISTERS_OFFSET + CXL_HDM_REGISTERS_SIZE) +#define CXL_EXTSEC_REGISTERS_SIZE (8 * EXTSEC_ENTRY_MAX + 4) + +/* 8.2.5.14 - CXL IDE Capability Structure */ +#define CXL_IDE_REGISTERS_OFFSET (CXL_EXTSEC_REGISTERS_OFFSET + CXL_EXTSEC_REGISTERS_SIZE) +#define CXL_IDE_REGISTERS_SIZE 0 + +/* 8.2.5.15 - CXL Snoop Filter Capability Structure */ +#define CXL_SNOOP_REGISTERS_OFFSET (CXL_IDE_REGISTERS_OFFSET + CXL_IDE_REGISTERS_SIZE) +#define CXL_SNOOP_REGISTERS_SIZE 0x8 + +_Static_assert((CXL_SNOOP_REGISTERS_OFFSET + CXL_SNOOP_REGISTERS_SIZE) < 0x1000, + "No space for registers"); + +typedef struct component_registers { + /* + * Main memory region to be registered with QEMU core. + */ + MemoryRegion component_registers; + + /* + * 8.2.4 Table 141: + * 0x0000 - 0x0fff CXL.io registers + * 0x1000 - 0x1fff CXL.cache and CXL.mem + * 0x2000 - 0xdfff Implementation specific + * 0xe000 - 0xe3ff CXL ARB/MUX registers + * 0xe400 - 0xffff RSVD + */ + uint32_t io_registers[CXL2_COMPONENT_IO_REGION_SIZE >> 2]; + MemoryRegion io; + + uint32_t cache_mem_registers[CXL2_COMPONENT_CM_REGION_SIZE >> 2]; + MemoryRegion cache_mem; + + MemoryRegion impl_specific; + MemoryRegion arb_mux; + MemoryRegion rsvd; + + /* special_ops is used for any component that needs any specific handling */ + MemoryRegionOps *special_ops; +} ComponentRegisters; + +/* + * A CXL component represents all entities in a CXL hierarchy. This includes, + * host bridges, root ports, upstream/downstream switch ports, and devices + */ +typedef struct cxl_component { + ComponentRegisters crb; + union { + struct { + Range dvsecs[CXL20_MAX_DVSEC]; + uint16_t dvsec_offset; + struct PCIDevice *pdev; + }; + }; +} CXLComponentState; + +void cxl_component_register_block_init(Object *obj, + CXLComponentState *cxl_cstate, + const char *type); +void cxl_component_register_init_common(uint32_t *reg_state, + enum reg_type type); + +void cxl_component_create_dvsec(CXLComponentState *cxl_cstate, uint16_t length, + uint16_t type, uint8_t rev, uint8_t *body); + +#endif diff --git a/include/hw/cxl/cxl_pci.h b/include/hw/cxl/cxl_pci.h new file mode 100644 index 0000000000..a53c2e5ae7 --- /dev/null +++ b/include/hw/cxl/cxl_pci.h @@ -0,0 +1,138 @@ +/* + * QEMU CXL PCI interfaces + * + * Copyright (c) 2020 Intel + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#ifndef CXL_PCI_H +#define CXL_PCI_H + +#include "hw/pci/pci.h" +#include "hw/pci/pcie.h" + +#define CXL_VENDOR_ID 0x1e98 + +#define PCIE_DVSEC_HEADER1_OFFSET 0x4 /* Offset from start of extend cap */ +#define PCIE_DVSEC_ID_OFFSET 0x8 + +#define PCIE_CXL_DEVICE_DVSEC_LENGTH 0x38 +#define PCIE_CXL1_DEVICE_DVSEC_REVID 0 +#define PCIE_CXL2_DEVICE_DVSEC_REVID 1 + +#define EXTENSIONS_PORT_DVSEC_LENGTH 0x28 +#define EXTENSIONS_PORT_DVSEC_REVID 0 + +#define GPF_PORT_DVSEC_LENGTH 0x10 +#define GPF_PORT_DVSEC_REVID 0 + +#define PCIE_FLEXBUS_PORT_DVSEC_LENGTH_2_0 0x14 +#define PCIE_FLEXBUS_PORT_DVSEC_REVID_2_0 1 + +#define REG_LOC_DVSEC_LENGTH 0x24 +#define REG_LOC_DVSEC_REVID 0 + +enum { + PCIE_CXL_DEVICE_DVSEC = 0, + NON_CXL_FUNCTION_MAP_DVSEC = 2, + EXTENSIONS_PORT_DVSEC = 3, + GPF_PORT_DVSEC = 4, + GPF_DEVICE_DVSEC = 5, + PCIE_FLEXBUS_PORT_DVSEC = 7, + REG_LOC_DVSEC = 8, + MLD_DVSEC = 9, + CXL20_MAX_DVSEC +}; + +struct dvsec_header { + uint32_t cap_hdr; + uint32_t dv_hdr1; + uint16_t dv_hdr2; +} __attribute__((__packed__)); +_Static_assert(sizeof(struct dvsec_header) == 10, + "dvsec header size incorrect"); + +/* + * CXL 2.0 devices must implement certain DVSEC IDs, and can [optionally] + * implement others. + * + * CXL 2.0 Device: 0, [2], 5, 8 + * CXL 2.0 RP: 3, 4, 7, 8 + * CXL 2.0 Upstream Port: [2], 7, 8 + * CXL 2.0 Downstream Port: 3, 4, 7, 8 + */ + +/* CXL 2.0 - 8.1.5 (ID 0003) */ +struct extensions_dvsec_port { + struct dvsec_header hdr; + uint16_t status; + uint16_t control; + uint8_t alt_bus_base; + uint8_t alt_bus_limit; + uint16_t alt_memory_base; + uint16_t alt_memory_limit; + uint16_t alt_prefetch_base; + uint16_t alt_prefetch_limit; + uint32_t alt_prefetch_base_high; + uint32_t alt_prefetch_base_low; + uint32_t rcrb_base; + uint32_t rcrb_base_high; +}; +_Static_assert(sizeof(struct extensions_dvsec_port) == 0x28, + "extensions dvsec port size incorrect"); +#define PORT_CONTROL_OVERRIDE_OFFSET 0xc +#define PORT_CONTROL_UNMASK_SBR 1 +#define PORT_CONTROL_ALT_MEMID_EN 4 + +/* CXL 2.0 - 8.1.6 GPF DVSEC (ID 0004) */ +struct dvsec_port_gpf { + struct dvsec_header hdr; + uint16_t rsvd; + uint16_t phase1_ctrl; + uint16_t phase2_ctrl; +}; +_Static_assert(sizeof(struct dvsec_port_gpf) == 0x10, + "dvsec port GPF size incorrect"); + +/* CXL 2.0 - 8.1.8/8.2.1.3 Flexbus DVSEC (ID 0007) */ +struct dvsec_port_flexbus { + struct dvsec_header hdr; + uint16_t cap; + uint16_t ctrl; + uint16_t status; + uint32_t rcvd_mod_ts_data; +}; +_Static_assert(sizeof(struct dvsec_port_flexbus) == 0x14, + "dvsec port flexbus size incorrect"); + +/* CXL 2.0 - 8.1.9 Register Locator DVSEC (ID 0008) */ +struct dvsec_register_locator { + struct dvsec_header hdr; + uint16_t rsvd; + uint32_t reg0_base_lo; + uint32_t reg0_base_hi; + uint32_t reg1_base_lo; + uint32_t reg1_base_hi; + uint32_t reg2_base_lo; + uint32_t reg2_base_hi; +}; +_Static_assert(sizeof(struct dvsec_register_locator) == 0x24, + "dvsec register locator size incorrect"); + +/* BAR Equivalence Indicator */ +#define BEI_BAR_10H 0 +#define BEI_BAR_14H 1 +#define BEI_BAR_18H 2 +#define BEI_BAR_1cH 3 +#define BEI_BAR_20H 4 +#define BEI_BAR_24H 5 + +/* Register Block Identifier */ +#define RBI_EMPTY 0 +#define RBI_COMPONENT_REG (1 << 8) +#define RBI_BAR_VIRT_ACL (2 << 8) +#define RBI_CXL_DEVICE_REG (3 << 8) + +#endif From patchwork Tue Jan 5 16:52:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422574 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JcX5Jn6z9sVq for ; Wed, 6 Jan 2021 03:59:08 +1100 (AEDT) Received: from localhost ([::1]:40960 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpfm-0003x0-Oy for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 11:59:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40744) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpaq-0008DG-9P for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:00 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpam-00012E-O8 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:00 -0500 IronPort-SDR: TZefJloQwHnL+ZDjOOloMnivDf+CBXQYts1RyPPsvE7w3b8hqJtd3reNUcjlUfgpdG44+QaeqU inIF3Y3d4P3A== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629503" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629503" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:51 -0800 IronPort-SDR: naWRLgOymj+8354Es/4EIAM3veVe6oGFGpZY8fUE3Y63tAQzqNe+0vacp9h22Lj46DufBtoiln fA/XRVQbVDmw== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337942" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:51 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 04/32] hw/cxl/device: Introduce a CXL device (8.2.8) Date: Tue, 5 Jan 2021 08:52:55 -0800 Message-Id: <20210105165323.783725-5-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A CXL device is a type of CXL component. Conceptually, a CXL device would be a leaf node in a CXL topology. From an emulation perspective, CXL devices are the most complex and so the actual implementation is reserved for discrete commits. This new device type is specifically catered towards the eventually implementation of a Type3 CXL.mem device, 8.2.8.5 in the CXL 2.0 specification. v2: Remove error codes not yet used (Jonathan) Fix interrupt enable bit width (Jonathan) Add comment for weird register size (Jonathan) Remove commands/registers not yet used (Ben) Signed-off-by: Ben Widawsky --- include/hw/cxl/cxl.h | 1 + include/hw/cxl/cxl_device.h | 151 ++++++++++++++++++++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 include/hw/cxl/cxl_device.h diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index 55f6cc30a5..23f52c4cf9 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -12,6 +12,7 @@ #include "cxl_pci.h" #include "cxl_component.h" +#include "cxl_device.h" #endif diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h new file mode 100644 index 0000000000..38af43c1a6 --- /dev/null +++ b/include/hw/cxl/cxl_device.h @@ -0,0 +1,151 @@ +/* + * QEMU CXL Devices + * + * Copyright (c) 2020 Intel + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#ifndef CXL_DEVICE_H +#define CXL_DEVICE_H + +#include "hw/register.h" + +/* + * The following is how a CXL device's MMIO space is laid out. The only + * requirement from the spec is that the capabilities array and the capability + * headers start at offset 0 and are contiguously packed. The headers themselves + * provide offsets to the register fields. For this emulation, registers will + * start at offset 0x80 (m == 0x80). No secondary mailbox is implemented which + * means that n = m + sizeof(mailbox registers) + sizeof(device registers). + * + * This is roughly described in 8.2.8 Figure 138 of the CXL 2.0 spec. + * + * n + PAYLOAD_SIZE_MAX +---------------------------------+ + * | | + * ^ | | + * | | | + * | | | + * | | | + * | | Command Payload | + * | | | + * | | | + * | | | + * | | | + * | | | + * n +---------------------------------+ + * ^ | | + * | | Device Capability Registers | + * | | x, mailbox, y | + * | | | + * m +---------------------------------+ + * ^ | Device Capability Header y | + * | +---------------------------------+ + * | | Device Capability Header Mailbox| + * | +------------- -------------------- + * | | Device Capability Header x | + * | +---------------------------------+ + * | | | + * | | | + * | | Device Cap Array[0..n] | + * | | | + * | | | + * | | | + * 0 +---------------------------------+ + */ + +#define CXL_DEVICE_CAP_HDR1_OFFSET 0x10 /* Figure 138 */ +#define CXL_DEVICE_CAP_REG_SIZE 0x10 /* 8.2.8.2 */ + +#define CXL_DEVICE_REGISTERS_OFFSET 0x80 /* Read comment above */ +#define CXL_DEVICE_REGISTERS_LENGTH 0x8 /* 8.2.8.3.1 */ + +#define CXL_MAILBOX_REGISTERS_OFFSET \ + (CXL_DEVICE_REGISTERS_OFFSET + CXL_DEVICE_REGISTERS_LENGTH) +#define CXL_MAILBOX_REGISTERS_SIZE 0x20 +#define CXL_MAILBOX_PAYLOAD_SHIFT 11 +#define CXL_MAILBOX_MAX_PAYLOAD_SIZE (1 << CXL_MAILBOX_PAYLOAD_SHIFT) +#define CXL_MAILBOX_REGISTERS_LENGTH \ + (CXL_MAILBOX_REGISTERS_SIZE + CXL_MAILBOX_MAX_PAYLOAD_SIZE) + +typedef struct cxl_device_state { + /* Boss container and caps registers */ + MemoryRegion device_registers; + + struct { + MemoryRegion caps; + union { + uint8_t caps_reg_state[CXL_DEVICE_CAP_REG_SIZE * 4]; /* ARRAY + 3 CAPS */ + uint32_t caps_reg_state32[CXL_DEVICE_CAP_REG_SIZE >> 2]; + }; + }; + MemoryRegion device; + MemoryRegion mailbox; + + MemoryRegion *pmem; + MemoryRegion *vmem; +} CXLDeviceState; + +/* Initialize the register block for a device */ +void cxl_device_register_block_init(Object *obj, CXLDeviceState *dev); + +/* Set up default values for the register block */ +void cxl_device_register_init_common(CXLDeviceState *dev); + +/* CXL 2.0 - 8.2.8.1 */ +REG32(CXL_DEV_CAP_ARRAY, 0) /* 48b!?!?! */ + FIELD(CXL_DEV_CAP_ARRAY, CAP_ID, 0, 16) + FIELD(CXL_DEV_CAP_ARRAY, CAP_VERSION, 16, 8) +REG32(CXL_DEV_CAP_ARRAY2, 4) /* We're going to pretend it's 64b */ + FIELD(CXL_DEV_CAP_ARRAY2, CAP_COUNT, 0, 16) + +/* + * In the 8.2.8.2, this is listed as a 128b register, but in 8.2.8, it says: + * > No registers defined in Section 8.2.8 are larger than 64-bits wide so that + * > is the maximum access size allowed for these registers. If this rule is not + * > followed, the behavior is undefined + * + * Here we've chosen to make it 4 dwords. The spec allows any pow2 multiple + * access to be used for a register (2 qwords, 8 words, 128 bytes). + */ +#define CXL_DEVICE_CAPABILITY_HEADER_REGISTER(n, offset) \ + REG32(CXL_DEV_##n##_CAP_HDR0, offset) \ + FIELD(CXL_DEV_##n##_CAP_HDR0, CAP_ID, 0, 16) \ + FIELD(CXL_DEV_##n##_CAP_HDR0, CAP_VERSION, 16, 8) \ + REG32(CXL_DEV_##n##_CAP_HDR1, offset + 4) \ + FIELD(CXL_DEV_##n##_CAP_HDR1, CAP_OFFSET, 0, 32) \ + REG32(CXL_DEV_##n##_CAP_HDR2, offset + 8) \ + FIELD(CXL_DEV_##n##_CAP_HDR2, CAP_LENGTH, 0, 32) + +CXL_DEVICE_CAPABILITY_HEADER_REGISTER(DEVICE, CXL_DEVICE_CAP_HDR1_OFFSET) +CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MAILBOX, CXL_DEVICE_CAP_HDR1_OFFSET + \ + CXL_DEVICE_CAP_REG_SIZE) + +REG32(CXL_DEV_MAILBOX_CAP, 0) + FIELD(CXL_DEV_MAILBOX_CAP, PAYLOAD_SIZE, 0, 5) + FIELD(CXL_DEV_MAILBOX_CAP, INT_CAP, 5, 1) + FIELD(CXL_DEV_MAILBOX_CAP, BG_INT_CAP, 6, 1) + FIELD(CXL_DEV_MAILBOX_CAP, MSI_N, 7, 4) + +REG32(CXL_DEV_MAILBOX_CTRL, 4) + FIELD(CXL_DEV_MAILBOX_CTRL, DOORBELL, 0, 1) + FIELD(CXL_DEV_MAILBOX_CTRL, INT_EN, 1, 1) + FIELD(CXL_DEV_MAILBOX_CTRL, BG_INT_EN, 2, 1) + +/* XXX: actually a 64b register */ +REG32(CXL_DEV_MAILBOX_STS, 0x10) + FIELD(CXL_DEV_MAILBOX_STS, BG_OP, 0, 1) + FIELD(CXL_DEV_MAILBOX_STS, ERRNO, 32, 16) + FIELD(CXL_DEV_MAILBOX_STS, VENDOR_ERRNO, 48, 16) + +/* XXX: actually a 64b register */ +REG32(CXL_DEV_BG_CMD_STS, 0x18) + FIELD(CXL_DEV_BG_CMD_STS, BG, 0, 16) + FIELD(CXL_DEV_BG_CMD_STS, DONE, 16, 7) + FIELD(CXL_DEV_BG_CMD_STS, ERRNO, 32, 16) + FIELD(CXL_DEV_BG_CMD_STS, VENDOR_ERRNO, 48, 16) + +REG32(CXL_DEV_CMD_PAYLOAD, 0x20) + +#endif From patchwork Tue Jan 5 16:52:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422576 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jcn0dWVz9sVq for ; Wed, 6 Jan 2021 03:59:21 +1100 (AEDT) Received: from localhost ([::1]:40480 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpfx-0003jr-KX for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 11:59:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40754) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpaq-0008Ek-Tq for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:00 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpap-00012q-0x for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:00 -0500 IronPort-SDR: cHw9ilA4/IRPZAVqWOqrAM9qwhm7qrZRNVwFyl68QS3yGfjmfrrPRfo3J2kk/ozcKsmNlVIOk1 RKaYZaaFCQkQ== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629506" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629506" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:52 -0800 IronPort-SDR: 1E6wytqtjdsc3cLE6NmQBKBcj00p7P8yhYzNu3ugoesSp6bfHJH+Cp0lgBwkR/XrCHPDLiieEV pkZuNM0GJZdg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337946" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:51 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 05/32] hw/cxl/device: Implement the CAP array (8.2.8.1-2) Date: Tue, 5 Jan 2021 08:52:56 -0800 Message-Id: <20210105165323.783725-6-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This implements all device MMIO up to the first capability .That includes the CXL Device Capabilities Array Register, as well as all of the CXL Device Capability Header Registers. The latter are filled in as they are implemented in the following patches. v2: Break out register alignment checks (Jonathan) Signed-off-by: Ben Widawsky --- hw/cxl/cxl-device-utils.c | 72 +++++++++++++++++++++++++++++++++++++++ hw/cxl/meson.build | 1 + 2 files changed, 73 insertions(+) create mode 100644 hw/cxl/cxl-device-utils.c diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c new file mode 100644 index 0000000000..d1b1371e66 --- /dev/null +++ b/hw/cxl/cxl-device-utils.c @@ -0,0 +1,72 @@ +/* + * CXL Utility library for devices + * + * Copyright(C) 2020 Intel Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/cxl/cxl.h" + +static int cxl_device_check_register_alignment(hwaddr offset, unsigned size) +{ + if (unlikely(offset & (size - 1))) { + return 1; + } + + return 0; +} + +static uint64_t caps_reg_read(void *opaque, hwaddr offset, unsigned size) +{ + CXLDeviceState *cxl_dstate = opaque; + + if (cxl_device_check_register_alignment(offset, size)) { + qemu_log_mask(LOG_UNIMP, "Unaligned register read\n"); + return 0; + } + + return ldn_le_p(cxl_dstate->caps_reg_state + offset, size); +} + +static const MemoryRegionOps caps_ops = { + .read = caps_reg_read, + .write = NULL, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, +}; + +void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate) +{ + /* 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", + pow2ceil(CXL_MAILBOX_REGISTERS_LENGTH + CXL_MAILBOX_REGISTERS_OFFSET)); + + memory_region_init_io(&cxl_dstate->caps, obj, &caps_ops, cxl_dstate, + "cap-array", CXL_DEVICE_REGISTERS_OFFSET - 0); + + memory_region_add_subregion(&cxl_dstate->device_registers, 0, + &cxl_dstate->caps); +} + +void cxl_device_register_init_common(CXLDeviceState *cxl_dstate) +{ + uint32_t *cap_hdrs = cxl_dstate->caps_reg_state32; + const int cap_count = 0; + + /* CXL Device Capabilities Array Register */ + ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_ID, 0); + ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1); + ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY2, CAP_COUNT, cap_count); +} diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build index 00c3876a0f..47154d6850 100644 --- a/hw/cxl/meson.build +++ b/hw/cxl/meson.build @@ -1,3 +1,4 @@ softmmu_ss.add(when: 'CONFIG_CXL', if_true: files( 'cxl-component-utils.c', + 'cxl-device-utils.c', )) From patchwork Tue Jan 5 16:52:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422579 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jj64njFz9sVq for ; Wed, 6 Jan 2021 04:03:06 +1100 (AEDT) Received: from localhost ([::1]:49014 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpjc-0007cd-L3 for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:03:04 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40758) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpar-0008GS-I4 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:01 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpap-00012W-J5 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:01 -0500 IronPort-SDR: LJ9t86BsPZ7rv0kKae0uJ4bi4AwE+wcM7RJ6rdwaPFZFhmhdFz27c7Uzg03dc5uOKOCv4tUVpZ u24lhZYpgZsw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629511" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629511" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:53 -0800 IronPort-SDR: DMTH/CKFYM2ywGITJmv/2lw/DhJ3HPYAFIuT7eb2h5flVNyAcJqxdGlUtKKd/Umvga5UL/YpjB 9hacrm4bkKuA== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337953" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:52 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 06/32] hw/cxl/device: Add device status (8.2.8.3) Date: Tue, 5 Jan 2021 08:52:57 -0800 Message-Id: <20210105165323.783725-7-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This implements the CXL device status registers from 8.2.8.3.1 in the CXL 2.0 specification. It is capability ID 0001h. v2: Use the reg alignment helper (Jonathan) Add stubbed device_reg_init_common() (Ben) Signed-off-by: Ben Widawsky --- hw/cxl/cxl-device-utils.c | 38 ++++++++++++++++++++++++++++++++++++- include/hw/cxl/cxl_device.h | 16 ++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c index d1b1371e66..b86e5466bd 100644 --- a/hw/cxl/cxl-device-utils.c +++ b/hw/cxl/cxl-device-utils.c @@ -32,6 +32,32 @@ static uint64_t caps_reg_read(void *opaque, hwaddr offset, unsigned size) return ldn_le_p(cxl_dstate->caps_reg_state + offset, size); } +static uint64_t dev_reg_read(void *opaque, hwaddr offset, unsigned size) +{ + uint64_t retval = 0; + + if (cxl_device_check_register_alignment(offset, size)) { + qemu_log_mask(LOG_UNIMP, "Unaligned register read\n"); + return 0; + } + + return ldn_le_p(&retval, size); +} + +static const MemoryRegionOps dev_ops = { + .read = dev_reg_read, + .write = NULL, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, +}; + static const MemoryRegionOps caps_ops = { .read = caps_reg_read, .write = NULL, @@ -55,18 +81,28 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate) memory_region_init_io(&cxl_dstate->caps, obj, &caps_ops, cxl_dstate, "cap-array", CXL_DEVICE_REGISTERS_OFFSET - 0); + memory_region_init_io(&cxl_dstate->device, obj, &dev_ops, cxl_dstate, + "device-status", CXL_DEVICE_REGISTERS_LENGTH); memory_region_add_subregion(&cxl_dstate->device_registers, 0, &cxl_dstate->caps); + memory_region_add_subregion(&cxl_dstate->device_registers, + CXL_DEVICE_REGISTERS_OFFSET, + &cxl_dstate->device); } +static void device_reg_init_common(CXLDeviceState *cxl_dstate) { } + void cxl_device_register_init_common(CXLDeviceState *cxl_dstate) { uint32_t *cap_hdrs = cxl_dstate->caps_reg_state32; - const int cap_count = 0; + const int cap_count = 1; /* CXL Device Capabilities Array Register */ ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_ID, 0); ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_VERSION, 1); ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY2, CAP_COUNT, cap_count); + + cxl_device_cap_init(cxl_dstate, DEVICE, 1); + device_reg_init_common(cxl_dstate); } diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 38af43c1a6..3380fc9e7a 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -122,6 +122,22 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(DEVICE, CXL_DEVICE_CAP_HDR1_OFFSET) CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MAILBOX, CXL_DEVICE_CAP_HDR1_OFFSET + \ CXL_DEVICE_CAP_REG_SIZE) +#define cxl_device_cap_init(dstate, reg, cap_id) \ + do { \ + uint32_t *cap_hdrs = dstate->caps_reg_state32; \ + int which = R_CXL_DEV_##reg##_CAP_HDR0; \ + cap_hdrs[which] = \ + FIELD_DP32(cap_hdrs[which], CXL_DEV_##reg##_CAP_HDR0, CAP_ID, cap_id); \ + cap_hdrs[which] = FIELD_DP32( \ + cap_hdrs[which], CXL_DEV_##reg##_CAP_HDR0, CAP_VERSION, 1); \ + cap_hdrs[which + 1] = \ + FIELD_DP32(cap_hdrs[which + 1], CXL_DEV_##reg##_CAP_HDR1, \ + CAP_OFFSET, CXL_##reg##_REGISTERS_OFFSET); \ + cap_hdrs[which + 2] = \ + FIELD_DP32(cap_hdrs[which + 2], CXL_DEV_##reg##_CAP_HDR2, \ + CAP_LENGTH, CXL_##reg##_REGISTERS_LENGTH); \ + } while (0) + REG32(CXL_DEV_MAILBOX_CAP, 0) FIELD(CXL_DEV_MAILBOX_CAP, PAYLOAD_SIZE, 0, 5) FIELD(CXL_DEV_MAILBOX_CAP, INT_CAP, 5, 1) From patchwork Tue Jan 5 16:52:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422581 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jmm4Mfqz9sVw for ; Wed, 6 Jan 2021 04:06:14 +1100 (AEDT) Received: from localhost ([::1]:57488 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpmd-00031m-8j for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:06:11 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40794) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpat-0008Lf-K5 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:03 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpaq-00012E-NR for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:03 -0500 IronPort-SDR: VPAueL1MPwUqi4jq+QUapAYFQCw+80+9nK4WQWe69vPOsXz5LF5/FRPGsG9YPrOOib9XrOliov zX8KPRmrkC7A== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629513" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629513" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:53 -0800 IronPort-SDR: UfrhVHvBWBLhAUYE92Wpm3H0GkbmHEDQx4Z6eWeyaONFqz5eU84EQuIYNj2qezR5fgSJWB4taU 5XSnGQ48XGcw== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337958" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:53 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 07/32] hw/cxl/device: Implement basic mailbox (8.2.8.4) Date: Tue, 5 Jan 2021 08:52:58 -0800 Message-Id: <20210105165323.783725-8-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This is the beginning of implementing mailbox support for CXL 2.0 devices. v2: Use register alignment helper (Ben) Minor cleanups (Jonathan) Rename error codes to match spec (Jonathan) Update cap count from 1 to 2 (Jonathan) Add infra to support CEL (Ben) Add more of the actual mailbox handling from later patch (Ben) Signed-off-by: Ben Widawsky --- hw/cxl/cxl-device-utils.c | 122 ++++++++++++++++++++++++- hw/cxl/cxl-mailbox-utils.c | 173 ++++++++++++++++++++++++++++++++++++ hw/cxl/meson.build | 1 + include/hw/cxl/cxl.h | 3 + include/hw/cxl/cxl_device.h | 27 +++++- 5 files changed, 322 insertions(+), 4 deletions(-) create mode 100644 hw/cxl/cxl-mailbox-utils.c diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c index b86e5466bd..642e3c2617 100644 --- a/hw/cxl/cxl-device-utils.c +++ b/hw/cxl/cxl-device-utils.c @@ -44,6 +44,108 @@ static uint64_t dev_reg_read(void *opaque, hwaddr offset, unsigned size) return ldn_le_p(&retval, size); } +static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size) +{ + CXLDeviceState *cxl_dstate = opaque; + + if (cxl_device_check_register_alignment(offset, size)) { + qemu_log_mask(LOG_UNIMP, "Unaligned register read\n"); + return 0; + } + + return ldn_le_p(cxl_dstate->mbox_reg_state + offset, size); +} + +static void mailbox_mem_writel(uint32_t *reg_state, hwaddr offset, + uint64_t value) +{ + switch (offset) { + case A_CXL_DEV_MAILBOX_CTRL: + /* fallthrough */ + case A_CXL_DEV_MAILBOX_CAP: + /* RO register */ + break; + default: + qemu_log_mask(LOG_UNIMP, + "%s Unexpected 32-bit access to 0x%" PRIx64 " (WI)\n", + __func__, offset); + break; + } + + stl_le_p((uint8_t *)reg_state + offset, value); +} + +static void mailbox_mem_writeq(uint8_t *reg_state, hwaddr offset, + uint64_t value) +{ + switch (offset) { + case A_CXL_DEV_MAILBOX_CMD: + break; + case A_CXL_DEV_BG_CMD_STS: + /* BG not supported */ + /* fallthrough */ + case A_CXL_DEV_MAILBOX_STS: + /* Read only register, will get updated by the state machine */ + return; + default: + qemu_log_mask(LOG_UNIMP, + "%s Unexpected 64-bit access to 0x%" PRIx64 " (WI)\n", + __func__, offset); + return; + } + + stq_le_p(reg_state + offset, value); +} + +static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value, + unsigned size) +{ + CXLDeviceState *cxl_dstate = opaque; + + /* + * Lock is needed to prevent concurrent writes as well as to prevent writes + * coming in while the firmware is processing. Without background commands + * or the second mailbox implemented, this serves no purpose since the + * memory access is synchronized at a higher level (per memory region). + */ + RCU_READ_LOCK_GUARD(); + + switch (size) { + case 4: + if (unlikely(offset & (sizeof(uint32_t) - 1))) { + qemu_log_mask(LOG_UNIMP, "Unaligned register read\n"); + return; + } + mailbox_mem_writel(cxl_dstate->mbox_reg_state32, offset, value); + break; + case 8: + if (unlikely(offset & (sizeof(uint64_t) - 1))) { + qemu_log_mask(LOG_UNIMP, "Unaligned register read\n"); + return; + } + mailbox_mem_writeq(cxl_dstate->mbox_reg_state, offset, value); + break; + } + + if (ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL, + DOORBELL)) + cxl_process_mailbox(cxl_dstate); +} + +static const MemoryRegionOps mailbox_ops = { + .read = mailbox_reg_read, + .write = mailbox_reg_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, +}; + static const MemoryRegionOps dev_ops = { .read = dev_reg_read, .write = NULL, @@ -83,20 +185,33 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate) "cap-array", CXL_DEVICE_REGISTERS_OFFSET - 0); memory_region_init_io(&cxl_dstate->device, obj, &dev_ops, cxl_dstate, "device-status", CXL_DEVICE_REGISTERS_LENGTH); + memory_region_init_io(&cxl_dstate->mailbox, obj, &mailbox_ops, cxl_dstate, + "mailbox", CXL_MAILBOX_REGISTERS_LENGTH); memory_region_add_subregion(&cxl_dstate->device_registers, 0, &cxl_dstate->caps); memory_region_add_subregion(&cxl_dstate->device_registers, CXL_DEVICE_REGISTERS_OFFSET, &cxl_dstate->device); + memory_region_add_subregion(&cxl_dstate->device_registers, + CXL_MAILBOX_REGISTERS_OFFSET, + &cxl_dstate->mailbox); } 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 */ + 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; +} + void cxl_device_register_init_common(CXLDeviceState *cxl_dstate) { uint32_t *cap_hdrs = cxl_dstate->caps_reg_state32; - const int cap_count = 1; + const int cap_count = 2; /* CXL Device Capabilities Array Register */ ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_ID, 0); @@ -105,4 +220,9 @@ void cxl_device_register_init_common(CXLDeviceState *cxl_dstate) cxl_device_cap_init(cxl_dstate, DEVICE, 1); device_reg_init_common(cxl_dstate); + + cxl_device_cap_init(cxl_dstate, MAILBOX, 2); + mailbox_reg_init_common(cxl_dstate); + + assert(cxl_initialize_mailbox(cxl_dstate) == 0); } diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c new file mode 100644 index 0000000000..3a39c936de --- /dev/null +++ b/hw/cxl/cxl-mailbox-utils.c @@ -0,0 +1,173 @@ +/* + * CXL Utility library for mailbox interface + * + * Copyright(C) 2020 Intel Corporation. + * + * This work is licensed under the terms of the GNU GPL, version 2. See the + * COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/cxl/cxl.h" +#include "hw/pci/pci.h" +#include "qemu/log.h" +#include "qemu/uuid.h" + +/* + * How to add a new command, example. The command set FOO, with cmd BAR. + * 1. Add the command set and cmd to the enum. + * FOO = 0x7f, + * #define BAR 0 + * 2. Forward declare the handler. + * declare_mailbox_handler(FOO_BAR); + * 3. Add the command to the cxl_cmd_set[][] + * CXL_CMD(FOO, BAR, 0, 0), + * 4. Implement your handler + * define_mailbox_handler(FOO_BAR) { ... return CXL_MBOX_SUCCESS; } + * + * + * Writing the handler: + * The handler will provide the &struct cxl_cmd, the &CXLDeviceState, and the + * in/out length of the payload. The handler is responsible for consuming the + * payload from cmd->payload and operating upon it as necessary. It must then + * fill the output data into cmd->payload (overwriting what was there), + * setting the length, and returning a valid return code. + * + * XXX: The handler need not worry about endianess. The payload is read out of + * a register interface that already deals with it. + */ + +/* 8.2.8.4.5.1 Command Return Codes */ +typedef enum { + CXL_MBOX_SUCCESS = 0x0, + CXL_MBOX_BG_STARTED = 0x1, + CXL_MBOX_INVALID_INPUT = 0x2, + CXL_MBOX_UNSUPPORTED = 0x3, + CXL_MBOX_INTERNAL_ERROR = 0x4, + CXL_MBOX_RETRY_REQUIRED = 0x5, + CXL_MBOX_BUSY = 0x6, + CXL_MBOX_MEDIA_DISABLED = 0x7, + CXL_MBOX_FW_XFER_IN_PROGRESS = 0x8, + CXL_MBOX_FW_XFER_OUT_OF_ORDER = 0x9, + CXL_MBOX_FW_AUTH_FAILED = 0xa, + CXL_MBOX_FW_INVALID_SLOT = 0xb, + CXL_MBOX_FW_ROLLEDBACK = 0xc, + CXL_MBOX_FW_REST_REQD = 0xd, + CXL_MBOX_INVALID_HANDLE = 0xe, + CXL_MBOX_INVALID_PA = 0xf, + CXL_MBOX_INJECT_POISON_LIMIT = 0x10, + CXL_MBOX_PERMANENT_MEDIA_FAILURE = 0x11, + CXL_MBOX_ABORTED = 0x12, + CXL_MBOX_INVALID_SECURITY_STATE = 0x13, + CXL_MBOX_INCORRECT_PASSPHRASE = 0x14, + CXL_MBOX_UNSUPPORTED_MAILBOX = 0x15, + CXL_MBOX_INVALID_PAYLOAD_LENGTH = 0x16, + CXL_MBOX_MAX = 0x17 +} ret_code; + +struct cxl_cmd; +typedef ret_code (*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; +}; + +#define define_mailbox_handler(name) \ + static ret_code cmd_##name(struct cxl_cmd *cmd, \ + CXLDeviceState *cxl_dstate, uint16_t *len) +#define declare_mailbox_handler(name) define_mailbox_handler(name) + +#define CXL_CMD(s, c, in, cel_effect) \ + [s][c] = { stringify(s##_##c), cmd_##s##_##c, in, cel_effect } + +static struct cxl_cmd cxl_cmd_set[256][256] = {}; + +#undef CXL_CMD + +QemuUUID cel_uuid; + +void cxl_process_mailbox(CXLDeviceState *cxl_dstate) +{ + uint16_t ret = CXL_MBOX_SUCCESS; + struct cxl_cmd *cxl_cmd; + uint64_t status_reg; + opcode_handler h; + + /* + * current state of mailbox interface + * mbox_cap_reg = cxl_dstate->reg_state32[R_CXL_DEV_MAILBOX_CAP]; + * mbox_ctrl_reg = cxl_dstate->reg_state32[R_CXL_DEV_MAILBOX_CTRL]; + * status_reg = *(uint64_t *)&cxl_dstate->reg_state[A_CXL_DEV_MAILBOX_STS]; + */ + uint64_t command_reg = + *(uint64_t *)&cxl_dstate->mbox_reg_state[A_CXL_DEV_MAILBOX_CMD]; + + /* Check if we have to do anything */ + if (!ARRAY_FIELD_EX32(cxl_dstate->mbox_reg_state32, CXL_DEV_MAILBOX_CTRL, + DOORBELL)) { + qemu_log_mask(LOG_UNIMP, "Corrupt internal state for firmware\n"); + return; + } + + 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]; + h = cxl_cmd->handler; + if (!h) { + goto handled; + } + + if (len != cxl_cmd->in) { + ret = CXL_MBOX_INVALID_PAYLOAD_LENGTH; + } + + cxl_cmd->payload = cxl_dstate->mbox_reg_state + A_CXL_DEV_CMD_PAYLOAD; + ret = (*h)(cxl_cmd, cxl_dstate, &len); + assert(len <= cxl_dstate->payload_size); + +handled: + /* + * Set the return code + * XXX: it's a 64b register, but we're not setting the vendor, so we can get + * away with this + */ + 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); + + stq_le_p(cxl_dstate->mbox_reg_state + A_CXL_DEV_MAILBOX_CMD, command_reg); + stq_le_p(cxl_dstate->mbox_reg_state + A_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); +} + +int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate) +{ + const char *cel_uuidstr = "0da9c0b5-bf41-4b78-8f79-96b1623b3f17"; + + for (int i = 0; i < 256; i++) { + for (int j = 0; j < 256; j++) { + if (cxl_cmd_set[i][j].handler) { + struct cxl_cmd *c = &cxl_cmd_set[i][j]; + + cxl_dstate->cel_log[cxl_dstate->cel_size].opcode = (i << 8) | j; + cxl_dstate->cel_log[cxl_dstate->cel_size].effect = c->effect; + cxl_dstate->cel_size++; + } + } + } + + return qemu_uuid_parse(cel_uuidstr, &cel_uuid); +} diff --git a/hw/cxl/meson.build b/hw/cxl/meson.build index 47154d6850..0eca715d10 100644 --- a/hw/cxl/meson.build +++ b/hw/cxl/meson.build @@ -1,4 +1,5 @@ softmmu_ss.add(when: 'CONFIG_CXL', if_true: files( 'cxl-component-utils.c', 'cxl-device-utils.c', + 'cxl-mailbox-utils.c', )) diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index 23f52c4cf9..362cda40de 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -14,5 +14,8 @@ #include "cxl_component.h" #include "cxl_device.h" +#define COMPONENT_REG_BAR_IDX 0 +#define DEVICE_REG_BAR_IDX 2 + #endif diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index 3380fc9e7a..bdf990cec2 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -70,9 +70,10 @@ (CXL_MAILBOX_REGISTERS_SIZE + CXL_MAILBOX_MAX_PAYLOAD_SIZE) typedef struct cxl_device_state { - /* Boss container and caps registers */ + /* Main register container */ MemoryRegion device_registers; + MemoryRegion device; struct { MemoryRegion caps; union { @@ -80,8 +81,19 @@ typedef struct cxl_device_state { uint32_t caps_reg_state32[CXL_DEVICE_CAP_REG_SIZE >> 2]; }; }; - MemoryRegion device; - MemoryRegion mailbox; + struct { + MemoryRegion mailbox; + uint16_t payload_size; + union { + uint8_t mbox_reg_state[CXL_MAILBOX_REGISTERS_LENGTH]; + uint32_t mbox_reg_state32[CXL_MAILBOX_REGISTERS_LENGTH >> 2]; + }; + struct { + uint16_t opcode; + uint16_t effect; + } cel_log[1 << 16]; + size_t cel_size; + }; MemoryRegion *pmem; MemoryRegion *vmem; @@ -122,6 +134,9 @@ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(DEVICE, CXL_DEVICE_CAP_HDR1_OFFSET) CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MAILBOX, CXL_DEVICE_CAP_HDR1_OFFSET + \ CXL_DEVICE_CAP_REG_SIZE) +int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate); +void cxl_process_mailbox(CXLDeviceState *cxl_dstate); + #define cxl_device_cap_init(dstate, reg, cap_id) \ do { \ uint32_t *cap_hdrs = dstate->caps_reg_state32; \ @@ -149,6 +164,12 @@ REG32(CXL_DEV_MAILBOX_CTRL, 4) FIELD(CXL_DEV_MAILBOX_CTRL, INT_EN, 1, 1) FIELD(CXL_DEV_MAILBOX_CTRL, BG_INT_EN, 2, 1) +/* XXX: actually a 64b register */ +REG32(CXL_DEV_MAILBOX_CMD, 8) + FIELD(CXL_DEV_MAILBOX_CMD, COMMAND, 0, 8) + FIELD(CXL_DEV_MAILBOX_CMD, COMMAND_SET, 8, 8) + FIELD(CXL_DEV_MAILBOX_CMD, LENGTH, 16, 20) + /* XXX: actually a 64b register */ REG32(CXL_DEV_MAILBOX_STS, 0x10) FIELD(CXL_DEV_MAILBOX_STS, BG_OP, 0, 1) From patchwork Tue Jan 5 16:52:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422575 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JcY2ZPVz9sVw for ; Wed, 6 Jan 2021 03:59:09 +1100 (AEDT) Received: from localhost ([::1]:40080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpfn-0003Yi-9d for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 11:59:07 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40802) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpau-0008M9-1R for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:04 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpar-00012q-Bj for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:03 -0500 IronPort-SDR: zwazjJ27O9eaDNaj+jO6DW57kHO+DkqhrQAruz+RaBIfvS3U0ViBfMY7Cb/pGJQlmmHMzTvB0u 3tsnRVkuk71Q== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629517" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629517" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:53 -0800 IronPort-SDR: 3oVm3chEoXL3fnQczInXJUssYu8MAnKDk/h9Tn/kUiWzb+YZPrelC8+RFmjFXPj+Z/6IYlbvsG G+IS9MT6tBdg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337961" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:53 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 08/32] hw/cxl/device: Add memory devices (8.2.8.5) Date: Tue, 5 Jan 2021 08:52:59 -0800 Message-Id: <20210105165323.783725-9-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Memory devices implement extra capabilities on top of CXL devices. This adds support for that. A large part of memory devices is the mailbox/command interface. All of the mailbox handling is done in the mailbox-utils library. Longer term, new CXL devices that are being emulated may want to handle commands differently, and therefore would need a mechanism to opt in/out of the specific generic handlers. As such, this is considered sufficient for now, but may need more depth in the future. Signed-off-by: Ben Widawsky --- hw/cxl/cxl-device-utils.c | 52 ++++++++++++++++++++++++++++++++++++- hw/cxl/cxl-mailbox-utils.c | 24 +++++++++++++++++ include/hw/cxl/cxl_device.h | 16 ++++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c index 642e3c2617..c515d45d20 100644 --- a/hw/cxl/cxl-device-utils.c +++ b/hw/cxl/cxl-device-utils.c @@ -132,6 +132,45 @@ static void mailbox_reg_write(void *opaque, hwaddr offset, uint64_t value, cxl_process_mailbox(cxl_dstate); } +static uint64_t mdev_reg_read(void *opaque, hwaddr offset, unsigned size) +{ + uint64_t retval = 0; + + retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MEDIA_STATUS, 1); + retval = FIELD_DP64(retval, CXL_MEM_DEV_STS, MBOX_READY, 1); + + switch (size) { + case 4: + if (unlikely(offset & (sizeof(uint32_t) - 1))) { + qemu_log_mask(LOG_UNIMP, "Unaligned register read\n"); + return 0; + } + break; + case 8: + if (unlikely(offset & (sizeof(uint64_t) - 1))) { + qemu_log_mask(LOG_UNIMP, "Unaligned register read\n"); + return 0; + } + break; + } + + return ldn_le_p(&retval, size); +} + +static const MemoryRegionOps mdev_ops = { + .read = mdev_reg_read, + .write = NULL, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 4, + .max_access_size = 8, + }, +}; + static const MemoryRegionOps mailbox_ops = { .read = mailbox_reg_read, .write = mailbox_reg_write, @@ -187,6 +226,9 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate) "device-status", CXL_DEVICE_REGISTERS_LENGTH); memory_region_init_io(&cxl_dstate->mailbox, obj, &mailbox_ops, cxl_dstate, "mailbox", CXL_MAILBOX_REGISTERS_LENGTH); + memory_region_init_io(&cxl_dstate->memory_device, obj, &mdev_ops, + cxl_dstate, "memory device caps", + CXL_MEMORY_DEVICE_REGISTERS_LENGTH); memory_region_add_subregion(&cxl_dstate->device_registers, 0, &cxl_dstate->caps); @@ -196,6 +238,9 @@ void cxl_device_register_block_init(Object *obj, CXLDeviceState *cxl_dstate) memory_region_add_subregion(&cxl_dstate->device_registers, CXL_MAILBOX_REGISTERS_OFFSET, &cxl_dstate->mailbox); + memory_region_add_subregion(&cxl_dstate->device_registers, + CXL_MEMORY_DEVICE_REGISTERS_OFFSET, + &cxl_dstate->memory_device); } static void device_reg_init_common(CXLDeviceState *cxl_dstate) { } @@ -208,10 +253,12 @@ static void mailbox_reg_init_common(CXLDeviceState *cxl_dstate) cxl_dstate->payload_size = CXL_MAILBOX_MAX_PAYLOAD_SIZE; } +static void memdev_reg_init_common(CXLDeviceState *cxl_dstate) { } + void cxl_device_register_init_common(CXLDeviceState *cxl_dstate) { uint32_t *cap_hdrs = cxl_dstate->caps_reg_state32; - const int cap_count = 2; + const int cap_count = 3; /* CXL Device Capabilities Array Register */ ARRAY_FIELD_DP32(cap_hdrs, CXL_DEV_CAP_ARRAY, CAP_ID, 0); @@ -224,5 +271,8 @@ void cxl_device_register_init_common(CXLDeviceState *cxl_dstate) cxl_device_cap_init(cxl_dstate, MAILBOX, 2); mailbox_reg_init_common(cxl_dstate); + cxl_device_cap_init(cxl_dstate, MEMORY_DEVICE, 0x4000); + memdev_reg_init_common(cxl_dstate); + assert(cxl_initialize_mailbox(cxl_dstate) == 0); } diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 3a39c936de..0e94f5a95f 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -81,6 +81,30 @@ struct cxl_cmd { CXLDeviceState *cxl_dstate, uint16_t *len) #define declare_mailbox_handler(name) define_mailbox_handler(name) +#define define_mailbox_handler_zeroed(name, size) \ + uint16_t __zero##name = size; \ + static ret_code cmd_##name(struct cxl_cmd *cmd, \ + CXLDeviceState *cxl_dstate, uint16_t *len) \ + { \ + *len = __zero##name; \ + memset(cmd->payload, 0, *len); \ + return CXL_MBOX_SUCCESS; \ + } +#define define_mailbox_handler_const(name, data) \ + static ret_code cmd_##name(struct cxl_cmd *cmd, \ + CXLDeviceState *cxl_dstate, uint16_t *len) \ + { \ + *len = sizeof(data); \ + memcpy(cmd->payload, data, *len); \ + return CXL_MBOX_SUCCESS; \ + } +#define define_mailbox_handler_nop(name) \ + static ret_code cmd_##name(struct cxl_cmd *cmd, \ + CXLDeviceState *cxl_dstate, uint16_t *len) \ + { \ + return CXL_MBOX_SUCCESS; \ + } + #define CXL_CMD(s, c, in, cel_effect) \ [s][c] = { stringify(s##_##c), cmd_##s##_##c, in, cel_effect } diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index bdf990cec2..dd3f4572aa 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -69,11 +69,16 @@ #define CXL_MAILBOX_REGISTERS_LENGTH \ (CXL_MAILBOX_REGISTERS_SIZE + CXL_MAILBOX_MAX_PAYLOAD_SIZE) +#define CXL_MEMORY_DEVICE_REGISTERS_OFFSET \ + (CXL_MAILBOX_REGISTERS_OFFSET + CXL_MAILBOX_REGISTERS_LENGTH) +#define CXL_MEMORY_DEVICE_REGISTERS_LENGTH 0x8 + typedef struct cxl_device_state { /* Main register container */ MemoryRegion device_registers; MemoryRegion device; + MemoryRegion memory_device; struct { MemoryRegion caps; union { @@ -133,6 +138,9 @@ REG32(CXL_DEV_CAP_ARRAY2, 4) /* We're going to pretend it's 64b */ CXL_DEVICE_CAPABILITY_HEADER_REGISTER(DEVICE, CXL_DEVICE_CAP_HDR1_OFFSET) CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MAILBOX, CXL_DEVICE_CAP_HDR1_OFFSET + \ CXL_DEVICE_CAP_REG_SIZE) +CXL_DEVICE_CAPABILITY_HEADER_REGISTER(MEMORY_DEVICE, + CXL_DEVICE_CAP_HDR1_OFFSET + + CXL_DEVICE_CAP_REG_SIZE * 2) int cxl_initialize_mailbox(CXLDeviceState *cxl_dstate); void cxl_process_mailbox(CXLDeviceState *cxl_dstate); @@ -185,4 +193,12 @@ REG32(CXL_DEV_BG_CMD_STS, 0x18) REG32(CXL_DEV_CMD_PAYLOAD, 0x20) +/* XXX: actually a 64b registers */ +REG32(CXL_MEM_DEV_STS, 0) + FIELD(CXL_MEM_DEV_STS, FATAL, 0, 1) + FIELD(CXL_MEM_DEV_STS, FW_HALT, 1, 1) + FIELD(CXL_MEM_DEV_STS, MEDIA_STATUS, 2, 2) + FIELD(CXL_MEM_DEV_STS, MBOX_READY, 4, 1) + FIELD(CXL_MEM_DEV_STS, RESET_NEEDED, 5, 3) + #endif From patchwork Tue Jan 5 16:53:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422586 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JqM3wsbz9sVw for ; Wed, 6 Jan 2021 04:08:31 +1100 (AEDT) Received: from localhost ([::1]:37926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpor-0006zJ-Ia for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:08:29 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40810) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpau-0008Mi-Be for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:04 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpar-00012W-Se for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:04 -0500 IronPort-SDR: 4nAzFEI8Z+h/7LGCmBHMdx6MDNbAA4fxchP+0R8mrpeO6nLJphVluHW1HPVliQD1zjL7zkL39P 7hyXNdlX+xcQ== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629520" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629520" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:55 -0800 IronPort-SDR: iBCShpwGYthAfIEIII/1Q1900akwzVcsovnkGsnfJS9IFPkaU8W7LBClfZMKL14NgC0pYhHwoT sevytPuP3wmQ== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337970" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:53 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 09/32] hw/cxl/device: Add cheap EVENTS implementation (8.2.9.1) Date: Tue, 5 Jan 2021 08:53:00 -0800 Message-Id: <20210105165323.783725-10-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Using the previously implemented stubbed helpers, it is now possible to easily add the missing, required commands to the implementation. Signed-off-by: Ben Widawsky --- hw/cxl/cxl-mailbox-utils.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 0e94f5a95f..890e486ea1 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -37,6 +37,14 @@ * a register interface that already deals with it. */ +enum { + EVENTS = 0x01, + #define GET_RECORDS 0x0 + #define CLEAR_RECORDS 0x1 + #define GET_INTERRUPT_POLICY 0x2 + #define SET_INTERRUPT_POLICY 0x3 +}; + /* 8.2.8.4.5.1 Command Return Codes */ typedef enum { CXL_MBOX_SUCCESS = 0x0, @@ -105,10 +113,23 @@ struct cxl_cmd { return CXL_MBOX_SUCCESS; \ } +define_mailbox_handler_zeroed(EVENTS_GET_RECORDS, 0x20); +define_mailbox_handler_nop(EVENTS_CLEAR_RECORDS); +define_mailbox_handler_zeroed(EVENTS_GET_INTERRUPT_POLICY, 4); +define_mailbox_handler_nop(EVENTS_SET_INTERRUPT_POLICY); + +#define IMMEDIATE_CONFIG_CHANGE (1 << 1) +#define IMMEDIATE_LOG_CHANGE (1 << 4) + #define CXL_CMD(s, c, in, cel_effect) \ [s][c] = { stringify(s##_##c), cmd_##s##_##c, in, cel_effect } -static struct cxl_cmd cxl_cmd_set[256][256] = {}; +static struct cxl_cmd cxl_cmd_set[256][256] = { + CXL_CMD(EVENTS, GET_RECORDS, 1, 0), + CXL_CMD(EVENTS, CLEAR_RECORDS, ~0, IMMEDIATE_LOG_CHANGE), + CXL_CMD(EVENTS, GET_INTERRUPT_POLICY, 0, 0), + CXL_CMD(EVENTS, SET_INTERRUPT_POLICY, 4, IMMEDIATE_CONFIG_CHANGE), +}; #undef CXL_CMD From patchwork Tue Jan 5 16:53:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422590 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Js1210Wz9sVq for ; Wed, 6 Jan 2021 04:09:57 +1100 (AEDT) Received: from localhost ([::1]:46508 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpqE-0002Ty-RC for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:09:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:40994) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbE-0008Ux-3y for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:24 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpb4-00012q-D9 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:23 -0500 IronPort-SDR: YedEzilnz4nnyIRu4BoQGVoGFPHv5GuyahfjFjFPzGppDlpY2it1Gl8c4l1bBGzyC3hjWvgfzf GxwZ6zbwEFgg== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629527" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629527" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:55 -0800 IronPort-SDR: HRNrUOgytxpmzFDMZZkkit1gtg1YtO6zc7cApgCiTHifgVuAOENkbhLoajTToyNDgmqQ9MOt/l weMX8qyzTD0w== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337979" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:55 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 11/32] hw/cxl/device: Timestamp implementation (8.2.9.3) Date: Tue, 5 Jan 2021 08:53:02 -0800 Message-Id: <20210105165323.783725-12-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Per spec, timestamp appears to be a free-running counter from a value set by the host via the Set Timestamp command (0301h). There are references to the epoch, which seem like a red herring. Therefore, the implementation implements the timestamp as freerunning counter from the last value that was issued by the Set Timestamp command. Signed-off-by: Ben Widawsky --- hw/cxl/cxl-mailbox-utils.c | 52 +++++++++++++++++++++++++++++++++++++ include/hw/cxl/cxl_device.h | 6 +++++ 2 files changed, 58 insertions(+) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 890e486ea1..8b956d9e94 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -43,6 +43,9 @@ enum { #define CLEAR_RECORDS 0x1 #define GET_INTERRUPT_POLICY 0x2 #define SET_INTERRUPT_POLICY 0x3 + TIMESTAMP = 0x03, + #define GET 0x0 + #define SET 0x1 }; /* 8.2.8.4.5.1 Command Return Codes */ @@ -117,8 +120,11 @@ define_mailbox_handler_zeroed(EVENTS_GET_RECORDS, 0x20); define_mailbox_handler_nop(EVENTS_CLEAR_RECORDS); define_mailbox_handler_zeroed(EVENTS_GET_INTERRUPT_POLICY, 4); define_mailbox_handler_nop(EVENTS_SET_INTERRUPT_POLICY); +declare_mailbox_handler(TIMESTAMP_GET); +declare_mailbox_handler(TIMESTAMP_SET); #define IMMEDIATE_CONFIG_CHANGE (1 << 1) +#define IMMEDIATE_POLICY_CHANGE (1 << 3) #define IMMEDIATE_LOG_CHANGE (1 << 4) #define CXL_CMD(s, c, in, cel_effect) \ @@ -129,10 +135,56 @@ static struct cxl_cmd cxl_cmd_set[256][256] = { CXL_CMD(EVENTS, CLEAR_RECORDS, ~0, IMMEDIATE_LOG_CHANGE), CXL_CMD(EVENTS, GET_INTERRUPT_POLICY, 0, 0), CXL_CMD(EVENTS, SET_INTERRUPT_POLICY, 4, IMMEDIATE_CONFIG_CHANGE), + CXL_CMD(TIMESTAMP, GET, 0, 0), + CXL_CMD(TIMESTAMP, SET, 8, IMMEDIATE_POLICY_CHANGE), }; #undef CXL_CMD +/* + * 8.2.9.3.1 + */ +define_mailbox_handler(TIMESTAMP_GET) +{ + struct timespec ts; + + clock_gettime(CLOCK_REALTIME, &ts); + + cxl_dstate->timestamp.set = true; + cxl_dstate->timestamp.last_set = + ts.tv_sec * NANOSECONDS_PER_SECOND + ts.tv_nsec; + cxl_dstate->timestamp.host_set = *(uint64_t *)cmd->payload; + + *len = 8; + return CXL_MBOX_SUCCESS; +} + +/* + * 8.2.9.3.2 + */ +define_mailbox_handler(TIMESTAMP_SET) +{ + struct timespec ts; + uint64_t delta; + + if (!cxl_dstate->timestamp.set) { + *(uint64_t *)cmd->payload = 0; + goto done; + } + + /* First find the delta from the last time the host set the time. */ + clock_gettime(CLOCK_REALTIME, &ts); + delta = (ts.tv_sec * NANOSECONDS_PER_SECOND + ts.tv_nsec) - + cxl_dstate->timestamp.host_set; + + /* Then adjust the actual time */ + *(uint64_t *)cmd->payload = cxl_dstate->timestamp.host_set + delta; + +done: + *len = 8; + return CXL_MBOX_SUCCESS; +} + QemuUUID cel_uuid; void cxl_process_mailbox(CXLDeviceState *cxl_dstate) diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h index dd3f4572aa..25974b2416 100644 --- a/include/hw/cxl/cxl_device.h +++ b/include/hw/cxl/cxl_device.h @@ -100,6 +100,12 @@ typedef struct cxl_device_state { size_t cel_size; }; + struct { + bool set; + uint64_t last_set; + uint64_t host_set; + } timestamp; + MemoryRegion *pmem; MemoryRegion *vmem; } CXLDeviceState; From patchwork Tue Jan 5 16:53:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422578 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jht2VGCz9sVq for ; Wed, 6 Jan 2021 04:02:54 +1100 (AEDT) Received: from localhost ([::1]:48658 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpjQ-0007TS-C2 for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:02:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41014) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbE-000058-O4 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:24 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpb4-00012W-OS for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:24 -0500 IronPort-SDR: RM0YrypfPq+CAfd43L5Qpp2AOnYBHrBwQiXxRjYBidSb/pK/2nKu+4xfO84eRqzqFcYC0swyjk 5YNMvLHc9oKw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629530" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629530" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:56 -0800 IronPort-SDR: XFywwPy0gfIq7+mc1v4F6/xZrf5ynuMZmIICcJLzPCTEpNW2cXZasUWg7EQPkhNoM3Gng+ly2L hQw8dDN+l0bA== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337985" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:55 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 12/32] hw/cxl/device: Add log commands (8.2.9.4) + CEL Date: Tue, 5 Jan 2021 08:53:03 -0800 Message-Id: <20210105165323.783725-13-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" CXL specification provides for the ability to obtain logs from the device. Logs are either spec defined, like the "Command Effects Log" (CEL), or vendor specific. UUIDs are defined for all log types. The CEL is a mechanism to provide information to the host about which commands are supported. It is useful both to determine which spec'd optional commands are supported, as well as provide a list of vendor specified commands that might be used. The CEL is already created as part of mailbox initialization, but here it is now exported to hosts that use these log commands. Signed-off-by: Ben Widawsky --- hw/cxl/cxl-mailbox-utils.c | 75 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 8b956d9e94..f68ec5b5b9 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -46,6 +46,9 @@ enum { TIMESTAMP = 0x03, #define GET 0x0 #define SET 0x1 + LOGS = 0x04, + #define GET_SUPPORTED 0x0 + #define GET_LOG 0x1 }; /* 8.2.8.4.5.1 Command Return Codes */ @@ -122,6 +125,8 @@ define_mailbox_handler_zeroed(EVENTS_GET_INTERRUPT_POLICY, 4); define_mailbox_handler_nop(EVENTS_SET_INTERRUPT_POLICY); declare_mailbox_handler(TIMESTAMP_GET); declare_mailbox_handler(TIMESTAMP_SET); +declare_mailbox_handler(LOGS_GET_SUPPORTED); +declare_mailbox_handler(LOGS_GET_LOG); #define IMMEDIATE_CONFIG_CHANGE (1 << 1) #define IMMEDIATE_POLICY_CHANGE (1 << 3) @@ -137,6 +142,8 @@ static struct cxl_cmd cxl_cmd_set[256][256] = { CXL_CMD(EVENTS, SET_INTERRUPT_POLICY, 4, IMMEDIATE_CONFIG_CHANGE), CXL_CMD(TIMESTAMP, GET, 0, 0), CXL_CMD(TIMESTAMP, SET, 8, IMMEDIATE_POLICY_CHANGE), + CXL_CMD(LOGS, GET_SUPPORTED, 0, 0), + CXL_CMD(LOGS, GET_LOG, 0x18, 0), }; #undef CXL_CMD @@ -187,6 +194,74 @@ done: QemuUUID cel_uuid; +/* 8.2.9.4.1 */ +define_mailbox_handler(LOGS_GET_SUPPORTED) +{ + struct { + uint16_t entries; + uint8_t rsvd[6]; + struct { + QemuUUID uuid; + uint32_t size; + } log_entries[1]; + } __attribute__((packed)) *supported_logs; + _Static_assert(sizeof(*supported_logs) == 0x1c, "Bad supported log size"); + + supported_logs = (void *)cmd->payload; + + 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); + return CXL_MBOX_SUCCESS; +} + +/* 8.2.9.4.2 */ +define_mailbox_handler(LOGS_GET_LOG) +{ + struct { + union { + struct { + QemuUUID uuid; + uint32_t offset; + uint32_t length; + }; + }; + } __attribute__((packed, __aligned__(16))) *get_log; + + get_log = (void *)cmd->payload; + + /* + * 8.2.9.4.2 + * The device shall return Invalid Parameter if the Offset or Length + * fields attempt to access beyond the size of the log as reported by Get + * Supported Logs. + * + * XXX: Spec is wrong, "Invalid Parameter" isn't a thing. + * XXX: Spec doesn't address incorrect UUID incorrectness. + * + * The CEL buffer is large enough to fit all commands in the emulation, so + * 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) { + return CXL_MBOX_INVALID_INPUT; + } + + if (!qemu_uuid_is_equal(&get_log->uuid, &cel_uuid)) { + return CXL_MBOX_UNSUPPORTED; + } + + /* 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, + get_log->length); + + return CXL_MBOX_SUCCESS; +} + void cxl_process_mailbox(CXLDeviceState *cxl_dstate) { uint16_t ret = CXL_MBOX_SUCCESS; From patchwork Tue Jan 5 16:53:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422582 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jmq3hJkz9sVq for ; Wed, 6 Jan 2021 04:06:19 +1100 (AEDT) Received: from localhost ([::1]:57030 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpmj-0002mC-GE for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:06:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41026) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbE-00005k-Vd for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:24 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpb7-00012E-FR for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:24 -0500 IronPort-SDR: U0UsRED9aUrlzmag2WxEHNo83FfY9rIS8rOq91wadPmhttO5f9fZxKUfVUKkA3zUMDX9fOoC8o Cia80a2y8iFQ== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629531" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629531" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:56 -0800 IronPort-SDR: 5uRSWBtaH/UQh/aoIydictYhSlEZsoFD1jtCn8yeOTr75T7rD3u0cObPbiWkQsS//A0WwNC2dt F/SauRaWwbhQ== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346337994" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:56 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 13/32] hw/pxb: Use a type for realizing expanders Date: Tue, 5 Jan 2021 08:53:04 -0800 Message-Id: <20210105165323.783725-14-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This opens up the possibility for more types of expanders (other than PCI and PCIe). We'll need this to create a CXL expander. Signed-off-by: Ben Widawsky --- hw/pci-bridge/pci_expander_bridge.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index aedded1064..232b7ce305 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -24,6 +24,8 @@ #include "hw/boards.h" #include "qom/object.h" +enum BusType { PCI, PCIE }; + #define TYPE_PXB_BUS "pxb-bus" typedef struct PXBBus PXBBus; DECLARE_INSTANCE_CHECKER(PXBBus, PXB_BUS, @@ -214,7 +216,8 @@ static gint pxb_compare(gconstpointer a, gconstpointer b) 0; } -static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp) +static void pxb_dev_realize_common(PCIDevice *dev, enum BusType type, + Error **errp) { PXBDev *pxb = convert_to_pxb(dev); DeviceState *ds, *bds = NULL; @@ -239,7 +242,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, bool pcie, Error **errp) } ds = qdev_new(TYPE_PXB_HOST); - if (pcie) { + if (type == PCIE) { bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS); } else { bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS); @@ -287,7 +290,7 @@ static void pxb_dev_realize(PCIDevice *dev, Error **errp) return; } - pxb_dev_realize_common(dev, false, errp); + pxb_dev_realize_common(dev, PCI, errp); } static void pxb_dev_exitfn(PCIDevice *pci_dev) @@ -339,7 +342,7 @@ static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp) return; } - pxb_dev_realize_common(dev, true, errp); + pxb_dev_realize_common(dev, PCIE, errp); } static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data) From patchwork Tue Jan 5 16:53:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422592 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JwC3np9z9sVq for ; Wed, 6 Jan 2021 04:12:43 +1100 (AEDT) Received: from localhost ([::1]:54504 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpsu-0005tS-4G for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:12:40 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41222) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbQ-0000Hr-RY for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:36 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbO-00012q-G5 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:36 -0500 IronPort-SDR: t9BAU1Bs5W9pKONzhLe6Pbtg1Ge+aC0kgy3NfefW8dsujlR/TAnbLwuTZEaaJgsaZfp8PfgHka WHrXBGlhWuuw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629533" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629533" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:57 -0800 IronPort-SDR: a7q2AcGLjZBDVZnWSEaoZVdJZ7tmXgHnsEVlIeAl/c3oz8zIyZIOy/TvWp/G5XVUAsGe2lJsKk 9W9Hl++fKHKg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338002" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:56 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 14/32] hw/pci/cxl: Create a CXL bus type Date: Tue, 5 Jan 2021 08:53:05 -0800 Message-Id: <20210105165323.783725-15-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The easiest way to differentiate a CXL bus, and a PCIE bus is using a flag. A CXL bus, in hardware, is backward compatible with PCIE, and therefore the code tries pretty hard to keep them in sync as much as possible. The other way to implement this would be to try to cast the bus to the correct type. This is less code and useful for debugging via simply looking at the flags. Signed-off-by: Ben Widawsky --- hw/pci-bridge/pci_expander_bridge.c | 9 ++++++++- include/hw/pci/pci_bus.h | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 232b7ce305..88c45dc3b5 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -24,7 +24,7 @@ #include "hw/boards.h" #include "qom/object.h" -enum BusType { PCI, PCIE }; +enum BusType { PCI, PCIE, CXL }; #define TYPE_PXB_BUS "pxb-bus" typedef struct PXBBus PXBBus; @@ -35,6 +35,10 @@ DECLARE_INSTANCE_CHECKER(PXBBus, PXB_BUS, DECLARE_INSTANCE_CHECKER(PXBBus, PXB_PCIE_BUS, TYPE_PXB_PCIE_BUS) +#define TYPE_PXB_CXL_BUS "pxb-cxl-bus" +DECLARE_INSTANCE_CHECKER(PXBBus, PXB_CXL_BUS, + TYPE_PXB_CXL_BUS) + struct PXBBus { /*< private >*/ PCIBus parent_obj; @@ -244,6 +248,9 @@ static void pxb_dev_realize_common(PCIDevice *dev, enum BusType type, ds = qdev_new(TYPE_PXB_HOST); if (type == PCIE) { bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS); + } else if (type == CXL) { + bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_CXL_BUS); + bus->flags |= PCI_BUS_CXL; } else { bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS); bds = qdev_new("pci-bridge"); diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index 347440d42c..eb94e7e85c 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -24,6 +24,8 @@ enum PCIBusFlags { PCI_BUS_IS_ROOT = 0x0001, /* PCIe extended configuration space is accessible on this bus */ PCI_BUS_EXTENDED_CONFIG_SPACE = 0x0002, + /* This is a CXL Type BUS */ + PCI_BUS_CXL = 0x0004, }; struct PCIBus { @@ -53,6 +55,11 @@ struct PCIBus { Notifier machine_done; }; +static inline bool pci_bus_is_cxl(PCIBus *bus) +{ + return !!(bus->flags & PCI_BUS_CXL); +} + static inline bool pci_bus_is_root(PCIBus *bus) { return !!(bus->flags & PCI_BUS_IS_ROOT); From patchwork Tue Jan 5 16:53:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422587 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jqf22krz9sVq for ; Wed, 6 Jan 2021 04:08:46 +1100 (AEDT) Received: from localhost ([::1]:38146 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpp6-00075L-7l for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:08:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41226) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbR-0000Im-7K for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:37 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbP-00012W-4T for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:36 -0500 IronPort-SDR: BPbRzsyU54z+hKSbDGfMl3InzA/X/MrA09gCNW6vTcpsQKqIP8wPekjrmQwK2XOOy6NwnZQx7P 6T4RxrgPvztg== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629535" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629535" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:58 -0800 IronPort-SDR: A1KMrCaggsAAH9s5J4UQ/+5JmdiZfMHyq/pP3sOqZgZ2y4WFvGq6w4oPdaLN1I1ouweDWy68G0 Cxu7UJiJhkaQ== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338006" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:57 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 15/32] hw/pxb: Allow creation of a CXL PXB (host bridge) Date: Tue, 5 Jan 2021 08:53:06 -0800 Message-Id: <20210105165323.783725-16-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This works like adding a typical pxb device, except the name is 'pxb-cxl' instead of 'pxb-pcie'. An example command line would be as follows: -device pxb-cxl,id=cxl.0,bus="pcie.0",bus_nr=1 A CXL PXB is backward compatible with PCIe. What this means in practice is that an operating system that is unaware of CXL should still be able to enumerate this topology as if it were PCIe. One can create multiple CXL PXB host bridges, but a host bridge can only be connected to the main root bus. Host bridges cannot appear elsewhere in the topology. Note that as of this patch, the ACPI tables needed for the host bridge (specifically, an ACPI object in _SB named ACPI0016 and the CEDT) aren't created. So while this patch internally creates it, it cannot be properly used by an operating system or other system software. Upcoming patches will allow creating multiple host bridges. v2: Remove vendor and device ID (Ben) Signed-off-by: Ben Widawsky --- hw/pci-bridge/pci_expander_bridge.c | 67 ++++++++++++++++++++++++++++- hw/pci/pci.c | 7 +++ include/hw/pci/pci.h | 6 +++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 88c45dc3b5..b42592e1ff 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -56,6 +56,10 @@ DECLARE_INSTANCE_CHECKER(PXBDev, PXB_DEV, DECLARE_INSTANCE_CHECKER(PXBDev, PXB_PCIE_DEV, TYPE_PXB_PCIE_DEVICE) +#define TYPE_PXB_CXL_DEVICE "pxb-cxl" +DECLARE_INSTANCE_CHECKER(PXBDev, PXB_CXL_DEV, + TYPE_PXB_CXL_DEVICE) + struct PXBDev { /*< private >*/ PCIDevice parent_obj; @@ -67,6 +71,11 @@ struct PXBDev { static PXBDev *convert_to_pxb(PCIDevice *dev) { + /* A CXL PXB's parent bus is PCIe, so the normal check won't work */ + if (object_dynamic_cast(OBJECT(dev), TYPE_PXB_CXL_DEVICE)) { + return PXB_CXL_DEV(dev); + } + return pci_bus_is_express(pci_get_bus(dev)) ? PXB_PCIE_DEV(dev) : PXB_DEV(dev); } @@ -111,11 +120,20 @@ static const TypeInfo pxb_pcie_bus_info = { .class_init = pxb_bus_class_init, }; +static const TypeInfo pxb_cxl_bus_info = { + .name = TYPE_PXB_CXL_BUS, + .parent = TYPE_CXL_BUS, + .instance_size = sizeof(PXBBus), + .class_init = pxb_bus_class_init, +}; + static const char *pxb_host_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus) { - PXBBus *bus = pci_bus_is_express(rootbus) ? - PXB_PCIE_BUS(rootbus) : PXB_BUS(rootbus); + PXBBus *bus = pci_bus_is_cxl(rootbus) ? + PXB_CXL_BUS(rootbus) : + pci_bus_is_express(rootbus) ? PXB_PCIE_BUS(rootbus) : + PXB_BUS(rootbus); snprintf(bus->bus_path, 8, "0000:%02x", pxb_bus_num(rootbus)); return bus->bus_path; @@ -380,13 +398,58 @@ static const TypeInfo pxb_pcie_dev_info = { }, }; +static void pxb_cxl_dev_realize(PCIDevice *dev, Error **errp) +{ + /* A CXL PXB's parent bus is still PCIe */ + if (!pci_bus_is_express(pci_get_bus(dev))) { + error_setg(errp, "pxb-cxl devices cannot reside on a PCI bus"); + return; + } + + pxb_dev_realize_common(dev, CXL, errp); +} + +static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->realize = pxb_cxl_dev_realize; + k->exit = pxb_dev_exitfn; + /* + * XXX: These types of bridges don't actually show up in the hierarchy so + * vendor, device, class, etc. ids are intentionally left out. + */ + + dc->desc = "CXL Host Bridge"; + device_class_set_props(dc, pxb_dev_properties); + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + + /* Host bridges aren't hotpluggable. FIXME: spec reference */ + dc->hotpluggable = false; +} + +static const TypeInfo pxb_cxl_dev_info = { + .name = TYPE_PXB_CXL_DEVICE, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(PXBDev), + .class_init = pxb_cxl_dev_class_init, + .interfaces = + (InterfaceInfo[]){ + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + {}, + }, +}; + static void pxb_register_types(void) { type_register_static(&pxb_bus_info); type_register_static(&pxb_pcie_bus_info); + type_register_static(&pxb_cxl_bus_info); type_register_static(&pxb_host_info); type_register_static(&pxb_dev_info); type_register_static(&pxb_pcie_dev_info); + type_register_static(&pxb_cxl_dev_info); } type_init(pxb_register_types) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 50fc61c81f..fb454e2317 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -222,6 +222,12 @@ static const TypeInfo pcie_bus_info = { .class_init = pcie_bus_class_init, }; +static const TypeInfo cxl_bus_info = { + .name = TYPE_CXL_BUS, + .parent = TYPE_PCIE_BUS, + .class_init = pcie_bus_class_init, +}; + static PCIBus *pci_find_bus_nr(PCIBus *bus, int bus_num); static void pci_update_mappings(PCIDevice *d); static void pci_irq_handler(void *opaque, int irq_num, int level); @@ -2849,6 +2855,7 @@ static void pci_register_types(void) { type_register_static(&pci_bus_info); type_register_static(&pcie_bus_info); + type_register_static(&cxl_bus_info); type_register_static(&conventional_pci_interface_info); type_register_static(&cxl_interface_info); type_register_static(&pcie_interface_info); diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index f6b1eff446..c464597e53 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -405,6 +405,7 @@ typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin); #define TYPE_PCI_BUS "PCI" OBJECT_DECLARE_TYPE(PCIBus, PCIBusClass, PCI_BUS) #define TYPE_PCIE_BUS "PCIE" +#define TYPE_CXL_BUS "CXL" bool pci_bus_is_express(PCIBus *bus); @@ -753,6 +754,11 @@ static inline void pci_irq_pulse(PCIDevice *pci_dev) pci_irq_deassert(pci_dev); } +static inline int pci_is_cxl(const PCIDevice *d) +{ + return d->cap_present & QEMU_PCIE_CAP_CXL; +} + static inline int pci_is_express(const PCIDevice *d) { return d->cap_present & QEMU_PCI_CAP_EXPRESS; From patchwork Tue Jan 5 16:53:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422596 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JyP1kDzz9sVq for ; Wed, 6 Jan 2021 04:14:37 +1100 (AEDT) Received: from localhost ([::1]:34992 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpul-00016A-7u for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:14:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41244) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbT-0000Ky-5c for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:39 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbP-00012E-FN for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:38 -0500 IronPort-SDR: qnQSrAJSQflE8vfSQgqS1mGD6CE1nUhuQHcFHK4YpCp35SdDsTOOPagThuBKmaTaKcMwbNMSU6 Y8IAkIQ5V8Ww== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629538" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629538" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:58 -0800 IronPort-SDR: a3PIQDpm5Lbc/Bb+JtROi5zqLyTAzdbdQRbeR3r46rAmba/geQ14fVlr5N2gNhpPk+IhZXCUsJ wvH4aZ/BvDGA== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338009" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:58 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 16/32] qtest: allow DSDT acpi table changes Date: Tue, 5 Jan 2021 08:53:07 -0800 Message-Id: <20210105165323.783725-17-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Ben Widawsky --- tests/qtest/bios-tables-test-allowed-diff.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..5c695cdf37 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,22 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/pc/DSDT", +"tests/data/acpi/pc/DSDT.acpihmat", +"tests/data/acpi/pc/DSDT.bridge", +"tests/data/acpi/pc/DSDT.cphp", +"tests/data/acpi/pc/DSDT.dimmpxm", +"tests/data/acpi/pc/DSDT.hpbridge", +"tests/data/acpi/pc/DSDT.hpbrroot", +"tests/data/acpi/pc/DSDT.ipmikcs", +"tests/data/acpi/pc/DSDT.memhp", +"tests/data/acpi/pc/DSDT.numamem", +"tests/data/acpi/pc/DSDT.roothp", +"tests/data/acpi/q35/DSDT", +"tests/data/acpi/q35/DSDT.acpihmat", +"tests/data/acpi/q35/DSDT.bridge", +"tests/data/acpi/q35/DSDT.cphp", +"tests/data/acpi/q35/DSDT.dimmpxm", +"tests/data/acpi/q35/DSDT.ipmibt", +"tests/data/acpi/q35/DSDT.memhp", +"tests/data/acpi/q35/DSDT.mmio64", +"tests/data/acpi/q35/DSDT.numamem", +"tests/data/acpi/q35/DSDT.tis", From patchwork Tue Jan 5 16:53:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422577 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JdP3622z9sVq for ; Wed, 6 Jan 2021 03:59:53 +1100 (AEDT) Received: from localhost ([::1]:43716 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpgU-00054f-2i for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 11:59:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41390) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbe-0000UC-2e for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:51 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbc-00012q-0g for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:49 -0500 IronPort-SDR: vMw4kvIAY5r1pMBvzTexERTlNebpGDt5MxPbWRBfArYavNtN+y2aFoVRpYv5xI2XbgQ6gUGOrP KuKT1chTkIKA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629543" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629543" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:59 -0800 IronPort-SDR: 87x27tVelgx/c3k3EkCgEtq2wTuNzA0QxfV/bMAga5TGLsyDoc2BJuT2AEoapAWaT+ZwphizIC j9RFmcRCMMgg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338019" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:58 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 17/32] acpi/pci: Consolidate host bridge setup Date: Tue, 5 Jan 2021 08:53:08 -0800 Message-Id: <20210105165323.783725-18-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This cleanup will make it easier to add support for CXL to the mix. Signed-off-by: Ben Widawsky --- hw/i386/acpi-build.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index f18b71dea9..3c214bba67 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1194,6 +1194,20 @@ static void build_smb0(Aml *table, I2CBus *smbus, int devnr, int func) aml_append(table, scope); } +enum { PCI, PCIE }; +static void init_pci_acpi(Aml *dev, int uid, int type) +{ + if (type == PCI) { + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); + aml_append(dev, aml_name_decl("_UID", aml_int(uid))); + } else { + aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); + aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); + aml_append(dev, aml_name_decl("_UID", aml_int(uid))); + aml_append(dev, build_q35_osc_method()); + } +} + static void build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, @@ -1222,9 +1236,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, if (misc->is_piix4) { sb_scope = aml_scope("_SB"); dev = aml_device("PCI0"); - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); + init_pci_acpi(dev, 0, PCI); aml_append(dev, aml_name_decl("_ADR", aml_int(0))); - aml_append(dev, aml_name_decl("_UID", aml_int(0))); aml_append(sb_scope, dev); aml_append(dsdt, sb_scope); @@ -1238,11 +1251,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, } else { sb_scope = aml_scope("_SB"); dev = aml_device("PCI0"); - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); - aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); + init_pci_acpi(dev, 0, PCIE); aml_append(dev, aml_name_decl("_ADR", aml_int(0))); - aml_append(dev, aml_name_decl("_UID", aml_int(0))); - aml_append(dev, build_q35_osc_method()); aml_append(sb_scope, dev); if (pm->smi_on_cpuhp) { @@ -1345,15 +1355,8 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, scope = aml_scope("\\_SB"); dev = aml_device("PC%.02X", bus_num); - aml_append(dev, aml_name_decl("_UID", aml_int(bus_num))); aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num))); - if (pci_bus_is_express(bus)) { - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); - aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); - aml_append(dev, build_q35_osc_method()); - } else { - aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); - } + init_pci_acpi(dev, bus_num, pci_bus_is_express(bus) ? PCIE : PCI); if (numa_node != NUMA_NODE_UNASSIGNED) { aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node))); From patchwork Tue Jan 5 16:53:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422591 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Js62nVzz9sVq for ; Wed, 6 Jan 2021 04:10:02 +1100 (AEDT) Received: from localhost ([::1]:46760 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpqK-0002aK-BC for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:10:00 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41404) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbf-0000VD-Vt for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:51 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbc-00012W-38 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:51 -0500 IronPort-SDR: DA+XRGvb+J4iznz4Q8IUfSU3UT+fQiHUEg9kCo9c9+0wYnjjqRPJqgwA97xzKsI5JUYy2nz00f 33NWqyFuZWSA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629545" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629545" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:00 -0800 IronPort-SDR: y7BmYfgBNp8tnZIau7mDlg9SID2uOYdm84esRzc3i2CVrSsCItg7DTM58MtPLinejXzH6equAC oV26HFJguvrQ== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338023" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:59 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 18/32] tests/acpi: remove stale allowed tables Date: Tue, 5 Jan 2021 08:53:09 -0800 Message-Id: <20210105165323.783725-19-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -58 X-Spam_score: -5.9 X-Spam_bar: ----- X-Spam_report: (-5.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, TVD_SUBJ_WIPE_DEBT=1.004 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Scope (_SB) { Device (PCI0) { Name (_HID, EisaId ("PNP0A03") /* PCI Bus */) // _HID: Hardware ID - Name (_ADR, Zero) // _ADR: Address Name (_UID, Zero) // _UID: Unique ID + Name (_ADR, Zero) // _ADR: Address Signed-off-by: Ben Widawsky --- tests/data/acpi/pc/DSDT | Bin 5065 -> 5065 bytes tests/data/acpi/pc/DSDT.acpihmat | Bin 6390 -> 6390 bytes tests/data/acpi/pc/DSDT.bridge | Bin 6924 -> 6924 bytes tests/data/acpi/pc/DSDT.cphp | Bin 5529 -> 5529 bytes tests/data/acpi/pc/DSDT.dimmpxm | Bin 6719 -> 6719 bytes tests/data/acpi/pc/DSDT.hpbridge | Bin 5026 -> 5026 bytes tests/data/acpi/pc/DSDT.hpbrroot | Bin 3084 -> 3084 bytes tests/data/acpi/pc/DSDT.ipmikcs | Bin 5137 -> 5137 bytes tests/data/acpi/pc/DSDT.memhp | Bin 6424 -> 6424 bytes tests/data/acpi/pc/DSDT.numamem | Bin 5071 -> 5071 bytes tests/data/acpi/pc/DSDT.roothp | Bin 5261 -> 5261 bytes tests/data/acpi/q35/DSDT | Bin 7801 -> 7801 bytes tests/data/acpi/q35/DSDT.acpihmat | Bin 9126 -> 9126 bytes tests/data/acpi/q35/DSDT.bridge | Bin 7819 -> 7819 bytes tests/data/acpi/q35/DSDT.cphp | Bin 8265 -> 8265 bytes tests/data/acpi/q35/DSDT.dimmpxm | Bin 9455 -> 9455 bytes tests/data/acpi/q35/DSDT.ipmibt | Bin 7876 -> 7876 bytes tests/data/acpi/q35/DSDT.memhp | Bin 9160 -> 9160 bytes tests/data/acpi/q35/DSDT.mmio64 | Bin 8932 -> 8932 bytes tests/data/acpi/q35/DSDT.numamem | Bin 7807 -> 7807 bytes tests/qtest/bios-tables-test-allowed-diff.h | 21 -------------------- 21 files changed, 21 deletions(-) diff --git a/tests/data/acpi/pc/DSDT b/tests/data/acpi/pc/DSDT index f6173df1d598767a79aa34ad7585ad7d45c5d4f3..b516745128e3f1a297b6327e9057026a2d16229c 100644 GIT binary patch delta 20 bcmX@9eo}oxJ7=h;3j;^Iqf5}n36{bDOsEE~ delta 20 bcmX@9eo}oxJEx;d5CcbisHe-u36{bDOlAhI diff --git a/tests/data/acpi/pc/DSDT.acpihmat b/tests/data/acpi/pc/DSDT.acpihmat index 67f3f7249eaaa9404ebf0f2d0a324b8c8e3bd445..aeae285c6434ae6cf3c53660e34425727a497871 100644 GIT binary patch delta 20 bcmexn_|0%aJ7=h;3j;^Iqf5}n3271lRUHRT delta 20 bcmexn_|0%aJEx;d5CcbisHe-u3271lRNDtm diff --git a/tests/data/acpi/pc/DSDT.bridge b/tests/data/acpi/pc/DSDT.bridge index 643390f4c4138b37fc481656d3f555d0eeedcb02..4cd26a87dd11d96e10bf6de786b9d56ebfe0a4f9 100644 GIT binary patch delta 20 bcmeA%>oJ?q&Kc_I!oU&l=n}MXLX8vvMneXi delta 20 bcmeA%>oJ?q>k9#J~|B>glp^LX8vvMgaz# diff --git a/tests/data/acpi/pc/DSDT.cphp b/tests/data/acpi/pc/DSDT.cphp index 1ddcf7d8812f5d8d4d38fe7e7b35fd5885806046..fecb784812cbb2308ef58acf4a2c580f56d35c39 100644 GIT binary patch delta 20 bcmbQKJyUx^J7=h;3j;^Iqf5}n37nz;MY;wk delta 20 bcmbQKJyUx^JEx;d5CcbisHe-u37nz;MR*1% diff --git a/tests/data/acpi/pc/DSDT.dimmpxm b/tests/data/acpi/pc/DSDT.dimmpxm index c44385cc01879324738ffb7f997b8cdd762cbf97..f2c31e150ead16e4931367a6dab42704950a21e9 100644 GIT binary patch delta 20 bcmdmQvfpGvJ7=h;3j;^Iqf5}n3F{>RP4WjY delta 20 bcmdmQvfpGvJEx;d5CcbisHe-u3F{>RO|Sglp^LJcglp^!e3zkMNS6( diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT index d25cd7072932886d6967f4023faac1e1fa6e836c..17e2aebde98e0a3161d93e9b2e200737b13699ac 100644 GIT binary patch delta 21 dcmexq^V4R+R}_#>)Z#RX+z< diff --git a/tests/data/acpi/q35/DSDT.acpihmat b/tests/data/acpi/q35/DSDT.acpihmat index 722e06af83abcde203a2b96a8ec81fd3bab9fc98..7b3d659352a0923822f6a5db1dbd0a6ad853c446 100644 GIT binary patch delta 21 dcmZ4HzRZ2XR}__9y`WOK1lA diff --git a/tests/data/acpi/q35/DSDT.bridge b/tests/data/acpi/q35/DSDT.bridge index 06bac139d668ddfc7914e258b471a303c9dbd192..5961b55b1067c3090b2f1f4cd3386d71efee241d 100644 GIT binary patch delta 21 ccmeCS?Y5mTdE(4QHja2lmmr4CQjCSN09fk={{R30 delta 19 acmeCS?Y5mTnZ?m1h+*Qy=FL)!g|Yxf4F-?^ diff --git a/tests/data/acpi/q35/DSDT.cphp b/tests/data/acpi/q35/DSDT.cphp index 2b933ac482e6883efccbd7d6c96089602f2c0b4d..09c92d52f92bb346ed807945b9638cad958446f8 100644 GIT binary patch delta 21 dcmX@R}_>dONFPN@dc diff --git a/tests/data/acpi/q35/DSDT.dimmpxm b/tests/data/acpi/q35/DSDT.dimmpxm index bd8f8305b028ef20f9b6d1a0c69ac428d027e3d1..1da97afb32dddafefe7f27934acbcb7d56a67489 100644 GIT binary patch delta 21 dcmaFw`QCHFR}_UR4GFR)YuH diff --git a/tests/data/acpi/q35/DSDT.ipmibt b/tests/data/acpi/q35/DSDT.ipmibt index a8f868e23c25688ab1c0371016c071f23e9d732f..c7e68432b66e7b4d03284c882c65bbf3066825dc 100644 GIT binary patch delta 21 dcmX?Nd&G9aR}_u95`+PJ;(K diff --git a/tests/data/acpi/q35/DSDT.memhp b/tests/data/acpi/q35/DSDT.memhp index 9a802e4c67022386442976d5cb997ea3fc57b58f..3af457dd550461b2d2ea85aa85d7740452913b34 100644 GIT binary patch delta 21 dcmX@%e!_jiR}_u2TX4P;>`i diff --git a/tests/data/acpi/q35/DSDT.mmio64 b/tests/data/acpi/q35/DSDT.mmio64 index 948c2dc7264c31932b490ca00691a7c4d9aefdb0..a4d20f676ac173e6846dcd4e076220d512215963 100644 GIT binary patch delta 21 dcmaFj`owj@R}_o>Bw=R96SD diff --git a/tests/data/acpi/q35/DSDT.numamem b/tests/data/acpi/q35/DSDT.numamem index 44ec1b0af400da6d298284aa959aa38add7e6dd5..bbab0d10a2a064528519fa69e90c799430129b75 100644 GIT binary patch delta 21 dcmexw^WSE|R}_rpf{URwD;$ diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index 5c695cdf37..dfb8523c8b 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1,22 +1 @@ /* List of comma-separated changed AML files to ignore */ -"tests/data/acpi/pc/DSDT", -"tests/data/acpi/pc/DSDT.acpihmat", -"tests/data/acpi/pc/DSDT.bridge", -"tests/data/acpi/pc/DSDT.cphp", -"tests/data/acpi/pc/DSDT.dimmpxm", -"tests/data/acpi/pc/DSDT.hpbridge", -"tests/data/acpi/pc/DSDT.hpbrroot", -"tests/data/acpi/pc/DSDT.ipmikcs", -"tests/data/acpi/pc/DSDT.memhp", -"tests/data/acpi/pc/DSDT.numamem", -"tests/data/acpi/pc/DSDT.roothp", -"tests/data/acpi/q35/DSDT", -"tests/data/acpi/q35/DSDT.acpihmat", -"tests/data/acpi/q35/DSDT.bridge", -"tests/data/acpi/q35/DSDT.cphp", -"tests/data/acpi/q35/DSDT.dimmpxm", -"tests/data/acpi/q35/DSDT.ipmibt", -"tests/data/acpi/q35/DSDT.memhp", -"tests/data/acpi/q35/DSDT.mmio64", -"tests/data/acpi/q35/DSDT.numamem", -"tests/data/acpi/q35/DSDT.tis", From patchwork Tue Jan 5 16:53:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422595 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jy03wBsz9sVq for ; Wed, 6 Jan 2021 04:14:16 +1100 (AEDT) Received: from localhost ([::1]:35678 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpuQ-0001Nd-H3 for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:14:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41408) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbg-0000WF-AR for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:52 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbd-00012E-H1 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:52 -0500 IronPort-SDR: WpG+9QlwToE2uvmw4qlLCGrCa0gTgYNvhjl2alzyyGgCiF3U93N5KO9AxgxnPHk4lfnLTQodRA 5F+/PoJ3BCuw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629547" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629547" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:00 -0800 IronPort-SDR: 7es8giYrlAbj9CU/y2+kbnvV1pxPsRhwngo0E6lhQcFm1CEcuSr7NoswutUKjNHza3tZJymFPN J0PHqK2BJ6qg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338029" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:53:59 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 19/32] hw/pci: Plumb _UID through host bridges Date: Tue, 5 Jan 2021 08:53:10 -0800 Message-Id: <20210105165323.783725-20-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Currently, QEMU makes _UID equivalent to the bus number (_BBN). While there is nothing wrong with doing it this way, CXL spec has a heavy reliance on _UID to identify host bridges and there is no link to the bus number. Having a distinct UID solves two problems. The first is it gets us around the limitation of 256 (current max bus number). The second is it allows us to replicate hardware configurations where bus number and uid aren't equivalent. The latter has benefits for our development and debugging using QEMU. The other way to do this would be to implement the expanded bus numbering, but having an explicit uid makes more sense when trying to replicate real hardware configurations. The QEMU commandline to utilize this would be: -device pxb-cxl,id=cxl.0,bus="pcie.0",bus_nr=1,uid=x Signed-off-by: Ben Widawsky --- I'm guessing this patch will be somewhat controversial. For early CXL work, this can be dropped without too much heartache. --- hw/i386/acpi-build.c | 3 ++- hw/pci-bridge/pci_expander_bridge.c | 19 +++++++++++++++++++ hw/pci/pci.c | 11 +++++++++++ include/hw/pci/pci.h | 1 + include/hw/pci/pci_bus.h | 1 + 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 3c214bba67..26e4ddd025 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1343,6 +1343,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, QLIST_FOREACH(bus, &bus->child, sibling) { uint8_t bus_num = pci_bus_num(bus); uint8_t numa_node = pci_bus_numa_node(bus); + int32_t uid = pci_bus_uid(bus); /* look only for expander root buses */ if (!pci_bus_is_root(bus)) { @@ -1356,7 +1357,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, scope = aml_scope("\\_SB"); dev = aml_device("PC%.02X", bus_num); aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num))); - init_pci_acpi(dev, bus_num, pci_bus_is_express(bus) ? PCIE : PCI); + init_pci_acpi(dev, uid, pci_bus_is_express(bus) ? PCIE : PCI); if (numa_node != NUMA_NODE_UNASSIGNED) { aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node))); diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index b42592e1ff..5021b60435 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -67,6 +67,7 @@ struct PXBDev { uint8_t bus_nr; uint16_t numa_node; + int32_t uid; }; static PXBDev *convert_to_pxb(PCIDevice *dev) @@ -98,12 +99,20 @@ static uint16_t pxb_bus_numa_node(PCIBus *bus) return pxb->numa_node; } +static int32_t pxb_bus_uid(PCIBus *bus) +{ + PXBDev *pxb = convert_to_pxb(bus->parent_dev); + + return pxb->uid; +} + static void pxb_bus_class_init(ObjectClass *class, void *data) { PCIBusClass *pbc = PCI_BUS_CLASS(class); pbc->bus_num = pxb_bus_num; pbc->numa_node = pxb_bus_numa_node; + pbc->uid = pxb_bus_uid; } static const TypeInfo pxb_bus_info = { @@ -329,6 +338,7 @@ static Property pxb_dev_properties[] = { /* Note: 0 is not a legal PXB bus number. */ DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0), DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED), + DEFINE_PROP_INT32("uid", PXBDev, uid, -1), DEFINE_PROP_END_OF_LIST(), }; @@ -400,12 +410,21 @@ static const TypeInfo pxb_pcie_dev_info = { static void pxb_cxl_dev_realize(PCIDevice *dev, Error **errp) { + PXBDev *pxb = convert_to_pxb(dev); + /* A CXL PXB's parent bus is still PCIe */ if (!pci_bus_is_express(pci_get_bus(dev))) { error_setg(errp, "pxb-cxl devices cannot reside on a PCI bus"); return; } + if (pxb->uid < 0) { + error_setg(errp, "pxb-cxl devices must have a valid uid (0-2147483647)"); + return; + } + + /* FIXME: Check that uid doesn't collide with UIDs of other host bridges */ + pxb_dev_realize_common(dev, CXL, errp); } diff --git a/hw/pci/pci.c b/hw/pci/pci.c index fb454e2317..d2eae06e18 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -170,6 +170,11 @@ static uint16_t pcibus_numa_node(PCIBus *bus) return NUMA_NODE_UNASSIGNED; } +static int32_t pcibus_uid(PCIBus *bus) +{ + return -1; +} + static void pci_bus_class_init(ObjectClass *klass, void *data) { BusClass *k = BUS_CLASS(klass); @@ -184,6 +189,7 @@ static void pci_bus_class_init(ObjectClass *klass, void *data) pbc->bus_num = pcibus_num; pbc->numa_node = pcibus_numa_node; + pbc->uid = pcibus_uid; } static const TypeInfo pci_bus_info = { @@ -530,6 +536,11 @@ int pci_bus_numa_node(PCIBus *bus) return PCI_BUS_GET_CLASS(bus)->numa_node(bus); } +int pci_bus_uid(PCIBus *bus) +{ + return PCI_BUS_GET_CLASS(bus)->uid(bus); +} + static int get_pci_config_device(QEMUFile *f, void *pv, size_t size, const VMStateField *field) { diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index c464597e53..d65c2bceae 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -462,6 +462,7 @@ static inline int pci_dev_bus_num(const PCIDevice *dev) } int pci_bus_numa_node(PCIBus *bus); +int pci_bus_uid(PCIBus *bus); void pci_for_each_device(PCIBus *bus, int bus_num, void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque), void *opaque); diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index eb94e7e85c..3c9fbc55bb 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -17,6 +17,7 @@ struct PCIBusClass { int (*bus_num)(PCIBus *bus); uint16_t (*numa_node)(PCIBus *bus); + int32_t (*uid)(PCIBus *bus); }; enum PCIBusFlags { From patchwork Tue Jan 5 16:53:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422580 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JjX2b1Rz9sVw for ; Wed, 6 Jan 2021 04:03:28 +1100 (AEDT) Received: from localhost ([::1]:52282 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpjy-0000ck-Bj for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:03:26 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41574) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbq-0000nf-N2 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:02 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbo-00012q-H3 for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:02 -0500 IronPort-SDR: yIoPzcPcgGXbo/FuAcDJhbRFvGEYyIWpLt5pqO9fk4ZfKFVz8sXCO307EXTNBomgD4V6IZLtpp liSpy8v8XJ4g== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629551" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629551" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:01 -0800 IronPort-SDR: srId7JcmHfjrU7xA27JeGEICfcFjYt4c0Y7pDm69AC0VtJq+w8Am+jzasDySEQUQYBXYktlMEA Ej1tCW5LIPQQ== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338037" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:00 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 20/32] hw/cxl/component: Implement host bridge MMIO (8.2.5, table 142) Date: Tue, 5 Jan 2021 08:53:11 -0800 Message-Id: <20210105165323.783725-21-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" CXL host bridges themselves may have MMIO. Since host bridges don't have a BAR they are treated as special for MMIO. Signed-off-by: Ben Widawsky --- It's arbitrarily chosen here to pick 0xD0000000 as the base for the host bridge MMIO. I'm not sure what the right way to find free space for platform hardcoded things like this is. --- hw/pci-bridge/pci_expander_bridge.c | 53 ++++++++++++++++++++++++++++- include/hw/cxl/cxl.h | 2 ++ 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 5021b60435..226a8a5fff 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -17,6 +17,7 @@ #include "hw/pci/pci_host.h" #include "hw/qdev-properties.h" #include "hw/pci/pci_bridge.h" +#include "hw/cxl/cxl.h" #include "qemu/range.h" #include "qemu/error-report.h" #include "qemu/module.h" @@ -70,6 +71,12 @@ struct PXBDev { int32_t uid; }; +typedef struct CXLHost { + PCIHostState parent_obj; + + CXLComponentState cxl_cstate; +} CXLHost; + static PXBDev *convert_to_pxb(PCIDevice *dev) { /* A CXL PXB's parent bus is PCIe, so the normal check won't work */ @@ -85,6 +92,9 @@ static GList *pxb_dev_list; #define TYPE_PXB_HOST "pxb-host" +#define TYPE_PXB_CXL_HOST "pxb-cxl-host" +#define PXB_CXL_HOST(obj) OBJECT_CHECK(CXLHost, (obj), TYPE_PXB_CXL_HOST) + static int pxb_bus_num(PCIBus *bus) { PXBDev *pxb = convert_to_pxb(bus->parent_dev); @@ -198,6 +208,46 @@ static const TypeInfo pxb_host_info = { .class_init = pxb_host_class_init, }; +static void pxb_cxl_realize(DeviceState *dev, Error **errp) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + PCIHostState *phb = PCI_HOST_BRIDGE(dev); + CXLHost *cxl = PXB_CXL_HOST(dev); + CXLComponentState *cxl_cstate = &cxl->cxl_cstate; + struct MemoryRegion *mr = &cxl_cstate->crb.component_registers; + + cxl_component_register_block_init(OBJECT(dev), cxl_cstate, + TYPE_PXB_CXL_HOST); + sysbus_init_mmio(sbd, mr); + + /* FIXME: support multiple host bridges. */ + sysbus_mmio_map(sbd, 0, CXL_HOST_BASE + + memory_region_size(mr) * pci_bus_uid(phb->bus)); +} + +static void pxb_cxl_host_class_init(ObjectClass *class, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(class); + PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class); + + hc->root_bus_path = pxb_host_root_bus_path; + dc->fw_name = "cxl"; + dc->realize = pxb_cxl_realize; + /* Reason: Internal part of the pxb/pxb-pcie device, not usable by itself */ + dc->user_creatable = false; +} + +/* + * This is a device to handle the MMIO for a CXL host bridge. It does nothing + * else. + */ +static const TypeInfo cxl_host_info = { + .name = TYPE_PXB_CXL_HOST, + .parent = TYPE_PCI_HOST_BRIDGE, + .instance_size = sizeof(CXLHost), + .class_init = pxb_cxl_host_class_init, +}; + /* * Registers the PXB bus as a child of pci host root bus. */ @@ -272,7 +322,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, enum BusType type, dev_name = dev->qdev.id; } - ds = qdev_new(TYPE_PXB_HOST); + ds = qdev_new(type == CXL ? TYPE_PXB_CXL_HOST : TYPE_PXB_HOST); if (type == PCIE) { bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_PCIE_BUS); } else if (type == CXL) { @@ -466,6 +516,7 @@ static void pxb_register_types(void) type_register_static(&pxb_pcie_bus_info); type_register_static(&pxb_cxl_bus_info); type_register_static(&pxb_host_info); + type_register_static(&cxl_host_info); type_register_static(&pxb_dev_info); type_register_static(&pxb_pcie_dev_info); type_register_static(&pxb_cxl_dev_info); diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index 362cda40de..6bc344f205 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -17,5 +17,7 @@ #define COMPONENT_REG_BAR_IDX 0 #define DEVICE_REG_BAR_IDX 2 +#define CXL_HOST_BASE 0xD0000000 + #endif From patchwork Tue Jan 5 16:53:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422598 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9K1V3kZjz9sS8 for ; Wed, 6 Jan 2021 04:17:18 +1100 (AEDT) Received: from localhost ([::1]:44450 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpxM-0005E9-ES for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:17:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41598) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbs-0000rh-6S for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:04 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbq-00012W-Dq for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:03 -0500 IronPort-SDR: B7mOi5IJRPU3eI3xUb2xOmI1L/T8Bl8KLtrg5lk9l/YuxXuid8HHf+HAAoJZ6za7fXDRhy4zzY QWhTt902DsLg== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629554" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629554" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:02 -0800 IronPort-SDR: xKgrGV/5XCodHs7s9KaT9nWGGELu1yGaL15il2kcdV8mkOP0RIlHfJs16y54SPvpeoEpcAjGRn G/6QdxquroPw== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338041" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:01 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 21/32] acpi/pxb/cxl: Reserve host bridge MMIO Date: Tue, 5 Jan 2021 08:53:12 -0800 Message-Id: <20210105165323.783725-22-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" For all host bridges, reserve MMIO space with _CRS. The MMIO for the host bridge lives in a magically hard coded space in the system's physical address space. The standard mechanism to tell the OS about regions which can't be used for host bridges is _CRS. Signed-off-by: Ben Widawsky --- hw/i386/acpi-build.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 26e4ddd025..16cde677a0 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -28,6 +28,7 @@ #include "qemu/bitmap.h" #include "qemu/error-report.h" #include "hw/pci/pci.h" +#include "hw/cxl/cxl.h" #include "hw/core/cpu.h" #include "target/i386/cpu.h" #include "hw/misc/pvpanic.h" @@ -1194,7 +1195,7 @@ static void build_smb0(Aml *table, I2CBus *smbus, int devnr, int func) aml_append(table, scope); } -enum { PCI, PCIE }; +enum { PCI, PCIE, CXL }; static void init_pci_acpi(Aml *dev, int uid, int type) { if (type == PCI) { @@ -1344,20 +1345,28 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, uint8_t bus_num = pci_bus_num(bus); uint8_t numa_node = pci_bus_numa_node(bus); int32_t uid = pci_bus_uid(bus); + int type; /* look only for expander root buses */ if (!pci_bus_is_root(bus)) { continue; } + type = pci_bus_is_cxl(bus) ? CXL : + pci_bus_is_express(bus) ? PCIE : PCI; + if (bus_num < root_bus_limit) { root_bus_limit = bus_num - 1; } scope = aml_scope("\\_SB"); - dev = aml_device("PC%.02X", bus_num); + if (type == CXL) { + dev = aml_device("CXL%.01X", pci_bus_uid(bus)); + } else { + dev = aml_device("PC%.02X", bus_num); + } aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num))); - init_pci_acpi(dev, uid, pci_bus_is_express(bus) ? PCIE : PCI); + init_pci_acpi(dev, uid, type); if (numa_node != NUMA_NODE_UNASSIGNED) { aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node))); @@ -1368,6 +1377,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, aml_append(dev, aml_name_decl("_CRS", crs)); aml_append(scope, dev); aml_append(dsdt, scope); + + /* Handle the ranges for the PXB expanders */ + if (type == CXL) { + uint64_t base = CXL_HOST_BASE + uid * 0x10000; + crs_range_insert(crs_range_set.mem_ranges, base, + base + 0x10000 - 1); + } } } From patchwork Tue Jan 5 16:53:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422594 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JwM3lt6z9sVq for ; Wed, 6 Jan 2021 04:12:51 +1100 (AEDT) Received: from localhost ([::1]:55554 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpt3-0006L7-HE for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:12:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41606) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbs-0000tp-Vf for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:04 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbq-00012E-Pb for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:04 -0500 IronPort-SDR: KXIlyTrxyC1Wb96OV2mC4T0djdq7WAzzZMcnZ/y4sQsV3QPxCMqI4EJRMj/DeObP5TMdwGf+hv AyTssU7iEmmw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629558" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629558" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:02 -0800 IronPort-SDR: lOqAwoisGwNNzOBsuy64bc2RxU7iMrGKGSiQBvv/MqIh0sjQ6ClOgayVGxfnBL9FvVj/sM5n2F aNSlWtBHhUqA== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338047" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:02 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 22/32] hw/pxb/cxl: Add "windows" for host bridges Date: Tue, 5 Jan 2021 08:53:13 -0800 Message-Id: <20210105165323.783725-23-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" In a bare metal CXL capable system, system firmware will program physical address ranges on the host. This is done by programming internal registers that aren't typically known to OS. These address ranges might be contiguous or interleaved across host bridges. For a QEMU guest a new construct is introduced allowing passing a memory backend to the host bridge for this same purpose. Each memory backend needs to be passed to the host bridge as well as any device that will be emulating that memory (not implemented here). I'm hopeful the interleaving work in the link can be re-purposed here (see Link). An example to create a host bridges with a 512M window at 0x4c0000000 -object memory-backend-file,id=cxl-mem1,share,mem-path=cxl-type3,size=512M -device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52,uid=0,len-memory-base=1,memory-base\[0\]=0x4c0000000,memory\[0\]=cxl-mem1 Link: https://lists.nongnu.org/archive/html/qemu-devel/2020-08/msg03680.html Signed-off-by: Ben Widawsky --- hw/pci-bridge/pci_expander_bridge.c | 65 +++++++++++++++++++++++++++-- include/hw/cxl/cxl.h | 1 + 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 226a8a5fff..af1450c69d 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -69,12 +69,19 @@ struct PXBDev { uint8_t bus_nr; uint16_t numa_node; int32_t uid; + struct cxl_dev { + HostMemoryBackend *memory_window[CXL_WINDOW_MAX]; + + uint32_t num_windows; + hwaddr *window_base[CXL_WINDOW_MAX]; + } cxl; }; typedef struct CXLHost { PCIHostState parent_obj; CXLComponentState cxl_cstate; + PXBDev *dev; } CXLHost; static PXBDev *convert_to_pxb(PCIDevice *dev) @@ -213,16 +220,31 @@ static void pxb_cxl_realize(DeviceState *dev, Error **errp) SysBusDevice *sbd = SYS_BUS_DEVICE(dev); PCIHostState *phb = PCI_HOST_BRIDGE(dev); CXLHost *cxl = PXB_CXL_HOST(dev); + struct cxl_dev *cxl_dev = &cxl->dev->cxl; CXLComponentState *cxl_cstate = &cxl->cxl_cstate; struct MemoryRegion *mr = &cxl_cstate->crb.component_registers; + int uid = pci_bus_uid(phb->bus); cxl_component_register_block_init(OBJECT(dev), cxl_cstate, TYPE_PXB_CXL_HOST); sysbus_init_mmio(sbd, mr); - /* FIXME: support multiple host bridges. */ - sysbus_mmio_map(sbd, 0, CXL_HOST_BASE + - memory_region_size(mr) * pci_bus_uid(phb->bus)); + sysbus_mmio_map(sbd, 0, CXL_HOST_BASE + memory_region_size(mr) * uid); + + /* + * A CXL host bridge can exist without a fixed memory window, but it would + * only operate in legacy PCIe mode. + */ + if (!cxl_dev->memory_window[uid]) { + warn_report( + "CXL expander bridge created without window. Consider using %s", + "memdev[0]="); + return; + } + + mr = host_memory_backend_get_memory(cxl_dev->memory_window[uid]); + sysbus_init_mmio(sbd, mr); + sysbus_mmio_map(sbd, 1 + uid, *cxl_dev->window_base[uid]); } static void pxb_cxl_host_class_init(ObjectClass *class, void *data) @@ -328,6 +350,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, enum BusType type, } else if (type == CXL) { bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_CXL_BUS); bus->flags |= PCI_BUS_CXL; + PXB_CXL_HOST(ds)->dev = PXB_CXL_DEV(dev); } else { bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS); bds = qdev_new("pci-bridge"); @@ -389,6 +412,8 @@ static Property pxb_dev_properties[] = { DEFINE_PROP_UINT8("bus_nr", PXBDev, bus_nr, 0), DEFINE_PROP_UINT16("numa_node", PXBDev, numa_node, NUMA_NODE_UNASSIGNED), DEFINE_PROP_INT32("uid", PXBDev, uid, -1), + DEFINE_PROP_ARRAY("window-base", PXBDev, cxl.num_windows, cxl.window_base, + qdev_prop_uint64, hwaddr), DEFINE_PROP_END_OF_LIST(), }; @@ -460,7 +485,9 @@ static const TypeInfo pxb_pcie_dev_info = { static void pxb_cxl_dev_realize(PCIDevice *dev, Error **errp) { - PXBDev *pxb = convert_to_pxb(dev); + PXBDev *pxb = PXB_CXL_DEV(dev); + struct cxl_dev *cxl = &pxb->cxl; + int count = 0; /* A CXL PXB's parent bus is still PCIe */ if (!pci_bus_is_express(pci_get_bus(dev))) { @@ -476,6 +503,23 @@ static void pxb_cxl_dev_realize(PCIDevice *dev, Error **errp) /* FIXME: Check that uid doesn't collide with UIDs of other host bridges */ pxb_dev_realize_common(dev, CXL, errp); + + for (unsigned i = 0; i < CXL_WINDOW_MAX; i++) { + if (!cxl->memory_window[i]) { + continue; + } + + count++; + } + + if (!count) { + warn_report("memory-windows should be set when creating CXL host bridges"); + } + + if (count != cxl->num_windows) { + error_setg(errp, "window bases count (%d) must match window count (%d)", + cxl->num_windows, count); + } } static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data) @@ -496,6 +540,19 @@ static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data) /* Host bridges aren't hotpluggable. FIXME: spec reference */ dc->hotpluggable = false; + + /* + * Below is moral equivalent of: + * DEFINE_PROP_ARRAY("memdev", PXBDev, window_count, windows, + * qdev_prop_memory_device, HostMemoryBackend) + */ + for (unsigned i = 0; i < CXL_WINDOW_MAX; i++) { + g_autofree char *name = g_strdup_printf("memdev[%u]", i); + object_class_property_add_link(klass, name, TYPE_MEMORY_BACKEND, + offsetof(PXBDev, cxl.memory_window[i]), + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_STRONG); + } } static const TypeInfo pxb_cxl_dev_info = { diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index 6bc344f205..b1e5f4a8fa 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -18,6 +18,7 @@ #define DEVICE_REG_BAR_IDX 2 #define CXL_HOST_BASE 0xD0000000 +#define CXL_WINDOW_MAX 10 #endif From patchwork Tue Jan 5 16:53:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422597 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JyQ0dNsz9sVq for ; Wed, 6 Jan 2021 04:14:38 +1100 (AEDT) Received: from localhost ([::1]:36038 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpul-0001WN-2r for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:14:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41928) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpcC-00016n-1w for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:25 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpc1-00012q-4x for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:23 -0500 IronPort-SDR: c/NJVRNmPT4zTC3TgfRnLnuxa8iLY+oqhoSKO6EhMLA9xiwevKPRi4CUn4SrXpdeq/JpHlk44q TJlmBceRyFrA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629563" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629563" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:03 -0800 IronPort-SDR: 0Bmq/pRQ4uwLOvtdWmWpfaEHSp38VGqDPwm43ER+uD6xNrdcMCMyG2+tbYNZpBJiLd8wC12rSb q2IkjBYfEgmw== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338053" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:02 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 23/32] hw/cxl/rp: Add a root port Date: Tue, 5 Jan 2021 08:53:14 -0800 Message-Id: <20210105165323.783725-24-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This adds just enough of a root port implementation to be able to enumerate root ports (creating the required DVSEC entries). What's not here yet is the MMIO nor the ability to write some of the DVSEC entries. This can be added with the qemu commandline by adding a rootport to a specific CXL host bridge. For example: -device cxl-rp,id=rp0,bus="cxl.0",addr=0.0,chassis=4 Like the host bridge patch, the ACPI tables aren't generated at this point and so system software cannot use it. Signed-off-by: Ben Widawsky --- hw/pci-bridge/Kconfig | 5 + hw/pci-bridge/cxl_root_port.c | 231 +++++++++++++++++++++++++++++++++ hw/pci-bridge/meson.build | 1 + hw/pci-bridge/pcie_root_port.c | 6 +- hw/pci/pci.c | 4 +- 5 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 hw/pci-bridge/cxl_root_port.c diff --git a/hw/pci-bridge/Kconfig b/hw/pci-bridge/Kconfig index a51ec716f5..a821b531da 100644 --- a/hw/pci-bridge/Kconfig +++ b/hw/pci-bridge/Kconfig @@ -27,3 +27,8 @@ config DEC_PCI config SIMBA bool + +config CXL + bool + default y if PCI_EXPRESS && PXB + depends on PCI_EXPRESS && MSI_NONBROKEN && PXB diff --git a/hw/pci-bridge/cxl_root_port.c b/hw/pci-bridge/cxl_root_port.c new file mode 100644 index 0000000000..6c3b215bb3 --- /dev/null +++ b/hw/pci-bridge/cxl_root_port.c @@ -0,0 +1,231 @@ +/* + * CXL 2.0 Root Port Implementation + * + * Copyright(C) 2020 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qemu/range.h" +#include "hw/pci/pci_bridge.h" +#include "hw/pci/pcie_port.h" +#include "hw/qdev-properties.h" +#include "hw/sysbus.h" +#include "qapi/error.h" +#include "hw/cxl/cxl.h" + +#define CXL_ROOT_PORT_DID 0x7075 + +/* Copied from the gen root port which we derive */ +#define GEN_PCIE_ROOT_PORT_AER_OFFSET 0x100 +#define GEN_PCIE_ROOT_PORT_ACS_OFFSET \ + (GEN_PCIE_ROOT_PORT_AER_OFFSET + PCI_ERR_SIZEOF) +#define CXL_ROOT_PORT_DVSEC_OFFSET \ + (GEN_PCIE_ROOT_PORT_ACS_OFFSET + PCI_ACS_SIZEOF) + +typedef struct CXLRootPort { + /*< private >*/ + PCIESlot parent_obj; + + CXLComponentState cxl_cstate; + PCIResReserve res_reserve; +} CXLRootPort; + +#define TYPE_CXL_ROOT_PORT "cxl-rp" +DECLARE_INSTANCE_CHECKER(CXLRootPort, CXL_ROOT_PORT, TYPE_CXL_ROOT_PORT) + +static void latch_registers(CXLRootPort *crp) +{ + uint32_t *reg_state = crp->cxl_cstate.crb.cache_mem_registers; + + cxl_component_register_init_common(reg_state, CXL2_ROOT_PORT); +} + +static void build_dvsecs(CXLComponentState *cxl) +{ + uint8_t *dvsec; + + dvsec = (uint8_t *)&(struct extensions_dvsec_port){ 0 }; + cxl_component_create_dvsec(cxl, EXTENSIONS_PORT_DVSEC_LENGTH, + EXTENSIONS_PORT_DVSEC, + EXTENSIONS_PORT_DVSEC_REVID, dvsec); + + dvsec = (uint8_t *)&(struct dvsec_port_gpf){ + .rsvd = 0, + .phase1_ctrl = 1, /* 1μs timeout */ + .phase2_ctrl = 1, /* 1μs timeout */ + }; + cxl_component_create_dvsec(cxl, GPF_PORT_DVSEC_LENGTH, GPF_PORT_DVSEC, + GPF_PORT_DVSEC_REVID, dvsec); + + dvsec = (uint8_t *)&(struct dvsec_port_flexbus){ + .cap = 0x26, /* IO, Mem, non-MLD */ + .ctrl = 0, + .status = 0x26, /* same */ + .rcvd_mod_ts_data = 0xef, /* WTF? */ + }; + cxl_component_create_dvsec(cxl, PCIE_FLEXBUS_PORT_DVSEC_LENGTH_2_0, + PCIE_FLEXBUS_PORT_DVSEC, + PCIE_FLEXBUS_PORT_DVSEC_REVID_2_0, dvsec); + + dvsec = (uint8_t *)&(struct dvsec_register_locator){ + .rsvd = 0, + .reg0_base_lo = RBI_COMPONENT_REG | COMPONENT_REG_BAR_IDX, + .reg0_base_hi = 0, + }; + cxl_component_create_dvsec(cxl, REG_LOC_DVSEC_LENGTH, REG_LOC_DVSEC, + REG_LOC_DVSEC_REVID, dvsec); +} + +static void cxl_rp_realize(DeviceState *dev, Error **errp) +{ + PCIDevice *pci_dev = PCI_DEVICE(dev); + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev); + CXLRootPort *crp = CXL_ROOT_PORT(dev); + CXLComponentState *cxl_cstate = &crp->cxl_cstate; + ComponentRegisters *cregs = &cxl_cstate->crb; + MemoryRegion *component_bar = &cregs->component_registers; + Error *local_err = NULL; + + rpc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + int rc = + pci_bridge_qemu_reserve_cap_init(pci_dev, 0, crp->res_reserve, errp); + if (rc < 0) { + rpc->parent_class.exit(pci_dev); + return; + } + + if (!crp->res_reserve.io || crp->res_reserve.io == -1) { + pci_word_test_and_clear_mask(pci_dev->wmask + PCI_COMMAND, + PCI_COMMAND_IO); + pci_dev->wmask[PCI_IO_BASE] = 0; + pci_dev->wmask[PCI_IO_LIMIT] = 0; + } + + cxl_cstate->dvsec_offset = CXL_ROOT_PORT_DVSEC_OFFSET; + cxl_cstate->pdev = pci_dev; + build_dvsecs(&crp->cxl_cstate); + + cxl_component_register_block_init(OBJECT(pci_dev), cxl_cstate, + TYPE_CXL_ROOT_PORT); + + pci_register_bar(pci_dev, COMPONENT_REG_BAR_IDX, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64, + component_bar); +} + +static void cxl_rp_reset(DeviceState *dev) +{ + PCIERootPortClass *rpc = PCIE_ROOT_PORT_GET_CLASS(dev); + CXLRootPort *crp = CXL_ROOT_PORT(dev); + + rpc->parent_reset(dev); + + latch_registers(crp); +} + +static Property gen_rp_props[] = { + DEFINE_PROP_UINT32("bus-reserve", CXLRootPort, res_reserve.bus, -1), + DEFINE_PROP_SIZE("io-reserve", CXLRootPort, res_reserve.io, -1), + DEFINE_PROP_SIZE("mem-reserve", CXLRootPort, res_reserve.mem_non_pref, -1), + DEFINE_PROP_SIZE("pref32-reserve", CXLRootPort, res_reserve.mem_pref_32, + -1), + DEFINE_PROP_SIZE("pref64-reserve", CXLRootPort, res_reserve.mem_pref_64, + -1), + DEFINE_PROP_END_OF_LIST() +}; + +static void cxl_rp_dvsec_write_config(PCIDevice *dev, uint32_t addr, + uint32_t val, int len) +{ + CXLRootPort *crp = CXL_ROOT_PORT(dev); + + if (range_contains(&crp->cxl_cstate.dvsecs[EXTENSIONS_PORT_DVSEC], addr)) { + uint8_t *reg = &dev->config[addr]; + addr -= crp->cxl_cstate.dvsecs[EXTENSIONS_PORT_DVSEC].lob; + if (addr == PORT_CONTROL_OVERRIDE_OFFSET) { + if (pci_get_word(reg) & PORT_CONTROL_UNMASK_SBR) { + /* unmask SBR */ + } + if (pci_get_word(reg) & PORT_CONTROL_ALT_MEMID_EN) { + /* Alt Memory & ID Space Enable */ + } + } + } +} + +static void cxl_rp_write_config(PCIDevice *d, uint32_t address, uint32_t val, + int len) +{ + uint16_t slt_ctl, slt_sta; + + pcie_cap_slot_get(d, &slt_ctl, &slt_sta); + pci_bridge_write_config(d, address, val, len); + pcie_cap_flr_write_config(d, address, val, len); + pcie_cap_slot_write_config(d, slt_ctl, slt_sta, address, val, len); + pcie_aer_write_config(d, address, val, len); + + cxl_rp_dvsec_write_config(d, address, val, len); +} + +static void cxl_root_port_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PCIDeviceClass *k = PCI_DEVICE_CLASS(oc); + PCIERootPortClass *rpc = PCIE_ROOT_PORT_CLASS(oc); + + k->vendor_id = PCI_VENDOR_ID_INTEL; + k->device_id = CXL_ROOT_PORT_DID; + dc->desc = "CXL Root Port"; + k->revision = 0; + device_class_set_props(dc, gen_rp_props); + k->config_write = cxl_rp_write_config; + + device_class_set_parent_realize(dc, cxl_rp_realize, &rpc->parent_realize); + device_class_set_parent_reset(dc, cxl_rp_reset, &rpc->parent_reset); + + rpc->aer_offset = GEN_PCIE_ROOT_PORT_AER_OFFSET; + rpc->acs_offset = GEN_PCIE_ROOT_PORT_ACS_OFFSET; + + /* + * Explain + */ + dc->hotpluggable = false; +} + +static const TypeInfo cxl_root_port_info = { + .name = TYPE_CXL_ROOT_PORT, + .parent = TYPE_PCIE_ROOT_PORT, + .instance_size = sizeof(CXLRootPort), + .class_init = cxl_root_port_class_init, + .interfaces = (InterfaceInfo[]) { + { INTERFACE_CXL_DEVICE }, + { } + }, +}; + +static void cxl_register(void) +{ + type_register_static(&cxl_root_port_info); +} + +type_init(cxl_register); diff --git a/hw/pci-bridge/meson.build b/hw/pci-bridge/meson.build index daab8acf2a..b6d26a03d5 100644 --- a/hw/pci-bridge/meson.build +++ b/hw/pci-bridge/meson.build @@ -5,6 +5,7 @@ pci_ss.add(when: 'CONFIG_IOH3420', if_true: files('ioh3420.c')) pci_ss.add(when: 'CONFIG_PCIE_PORT', if_true: files('pcie_root_port.c', 'gen_pcie_root_port.c', 'pcie_pci_bridge.c')) pci_ss.add(when: 'CONFIG_PXB', if_true: files('pci_expander_bridge.c')) pci_ss.add(when: 'CONFIG_XIO3130', if_true: files('xio3130_upstream.c', 'xio3130_downstream.c')) +pci_ss.add(when: 'CONFIG_CXL', if_true: files('cxl_root_port.c')) # NewWorld PowerMac pci_ss.add(when: 'CONFIG_DEC_PCI', if_true: files('dec.c')) diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c index f1cfe9d14a..460e48269d 100644 --- a/hw/pci-bridge/pcie_root_port.c +++ b/hw/pci-bridge/pcie_root_port.c @@ -67,7 +67,11 @@ static void rp_realize(PCIDevice *d, Error **errp) int rc; pci_config_set_interrupt_pin(d->config, 1); - pci_bridge_initfn(d, TYPE_PCIE_BUS); + if (d->cap_present & QEMU_PCIE_CAP_CXL) { + pci_bridge_initfn(d, TYPE_CXL_BUS); + } else { + pci_bridge_initfn(d, TYPE_PCIE_BUS); + } pcie_port_init_reg(d); rc = pci_bridge_ssvid_init(d, rpc->ssvid_offset, dc->vendor_id, diff --git a/hw/pci/pci.c b/hw/pci/pci.c index d2eae06e18..ecc98938f9 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2692,7 +2692,9 @@ static void pci_device_class_base_init(ObjectClass *klass, void *data) object_class_dynamic_cast(klass, INTERFACE_CONVENTIONAL_PCI_DEVICE); ObjectClass *pcie = object_class_dynamic_cast(klass, INTERFACE_PCIE_DEVICE); - assert(conventional || pcie); + ObjectClass *cxl = + object_class_dynamic_cast(klass, INTERFACE_CXL_DEVICE); + assert(conventional || pcie || cxl); } } From patchwork Tue Jan 5 16:53:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422599 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9K1Z5L7tz9sS8 for ; Wed, 6 Jan 2021 04:17:22 +1100 (AEDT) Received: from localhost ([::1]:44740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpxQ-0005M7-JU for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:17:20 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41952) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpcF-00019G-9z for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:29 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpc2-00012W-Ky for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:27 -0500 IronPort-SDR: oXZcE3/973W0HzlofFM8jGIdns9YxwROIZG7KmNHQ9m8tUCDMlry68oCsr/rpQaY5ylN85gti+ o89nNzC607Dw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629569" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629569" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:04 -0800 IronPort-SDR: JAoy4UnEueZGltyKg5I0B6Y6VP8AIhDzz3K5wGXemh2YP2iBAS8PrWtWp8jOtl7nx4twGlq1hB CTjMh0lgSG2A== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338064" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:02 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 24/32] hw/cxl/device: Add a memory device (8.2.8.5) Date: Tue, 5 Jan 2021 08:53:15 -0800 Message-Id: <20210105165323.783725-25-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A CXL memory device (AKA Type 3) is a CXL component that contains some combination of volatile and persistent memory. It also implements the previously defined mailbox interface as well as the memory device firmware interface. The following example will create a 256M device in a 512M window: -object "memory-backend-file,id=cxl-mem1,share,mem-path=cxl-type3,size=512M" -device "cxl-type3,bus=rp0,memdev=cxl-mem1,id=cxl-pmem0,size=256M" Signed-off-by: Ben Widawsky --- hw/core/numa.c | 3 + hw/cxl/cxl-mailbox-utils.c | 41 ++++++ hw/i386/pc.c | 1 + hw/mem/Kconfig | 5 + hw/mem/cxl_type3.c | 262 +++++++++++++++++++++++++++++++++++++ hw/mem/meson.build | 1 + hw/pci/pcie.c | 30 +++++ include/hw/cxl/cxl.h | 2 + include/hw/cxl/cxl_pci.h | 22 ++++ include/hw/pci/pci_ids.h | 1 + monitor/hmp-cmds.c | 15 +++ qapi/machine.json | 1 + 12 files changed, 384 insertions(+) create mode 100644 hw/mem/cxl_type3.c diff --git a/hw/core/numa.c b/hw/core/numa.c index 68cee65f61..cd7df371e6 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -770,6 +770,9 @@ static void numa_stat_memory_devices(NumaNodeMem node_mem[]) node_mem[pcdimm_info->node].node_plugged_mem += pcdimm_info->size; break; + case MEMORY_DEVICE_INFO_KIND_CXL: + /* FINISHME */ + break; case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: vpi = value->u.virtio_pmem.data; /* TODO: once we support numa, assign to right node */ diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index f68ec5b5b9..eeb10b8943 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -49,6 +49,8 @@ enum { LOGS = 0x04, #define GET_SUPPORTED 0x0 #define GET_LOG 0x1 + IDENTIFY = 0x40, + #define MEMORY_DEVICE 0x0 }; /* 8.2.8.4.5.1 Command Return Codes */ @@ -127,6 +129,7 @@ declare_mailbox_handler(TIMESTAMP_GET); declare_mailbox_handler(TIMESTAMP_SET); declare_mailbox_handler(LOGS_GET_SUPPORTED); declare_mailbox_handler(LOGS_GET_LOG); +declare_mailbox_handler(IDENTIFY_MEMORY_DEVICE); #define IMMEDIATE_CONFIG_CHANGE (1 << 1) #define IMMEDIATE_POLICY_CHANGE (1 << 3) @@ -144,6 +147,7 @@ static struct cxl_cmd cxl_cmd_set[256][256] = { CXL_CMD(TIMESTAMP, SET, 8, IMMEDIATE_POLICY_CHANGE), CXL_CMD(LOGS, GET_SUPPORTED, 0, 0), CXL_CMD(LOGS, GET_LOG, 0x18, 0), + CXL_CMD(IDENTIFY, MEMORY_DEVICE, 0, 0), }; #undef CXL_CMD @@ -262,6 +266,43 @@ define_mailbox_handler(LOGS_GET_LOG) return CXL_MBOX_SUCCESS; } +/* 8.2.9.5.1.1 */ +define_mailbox_handler(IDENTIFY_MEMORY_DEVICE) +{ + struct { + char fw_revision[0x10]; + uint64_t total_capacity; + uint64_t volatile_capacity; + uint64_t persistent_capacity; + uint64_t partition_align; + uint16_t info_event_log_size; + uint16_t warning_event_log_size; + uint16_t failure_event_log_size; + uint16_t fatal_event_log_size; + uint32_t lsa_size; + uint8_t poison_list_max_mer[3]; + uint16_t inject_poison_limit; + uint8_t poison_caps; + uint8_t qos_telemetry_caps; + } __attribute__((packed)) *id; + _Static_assert(sizeof(*id) == 0x43, "Bad identify size"); + + if (memory_region_size(cxl_dstate->pmem) < (256 << 20)) { + return CXL_MBOX_INTERNAL_ERROR; + } + + id = (void *)cmd->payload; + memset(id, 0, sizeof(*id)); + + /* PMEM only */ + snprintf(id->fw_revision, 0x10, "BWFW VERSION %02d", 0); + id->total_capacity = memory_region_size(cxl_dstate->pmem); + id->persistent_capacity = memory_region_size(cxl_dstate->pmem); + + *len = sizeof(*id); + return CXL_MBOX_SUCCESS; +} + void cxl_process_mailbox(CXLDeviceState *cxl_dstate) { uint16_t ret = CXL_MBOX_SUCCESS; diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5458f61d10..5d41809b37 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -79,6 +79,7 @@ #include "acpi-build.h" #include "hw/mem/pc-dimm.h" #include "hw/mem/nvdimm.h" +#include "hw/cxl/cxl.h" #include "qapi/error.h" #include "qapi/qapi-visit-common.h" #include "qapi/visitor.h" diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig index a0ef2cf648..7d9d1ced3e 100644 --- a/hw/mem/Kconfig +++ b/hw/mem/Kconfig @@ -10,3 +10,8 @@ config NVDIMM default y depends on (PC || PSERIES || ARM_VIRT) select MEM_DEVICE + +config CXL_MEM_DEVICE + bool + default y if CXL + select MEM_DEVICE diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c new file mode 100644 index 0000000000..3985bb8d0b --- /dev/null +++ b/hw/mem/cxl_type3.c @@ -0,0 +1,262 @@ +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "qemu/error-report.h" +#include "hw/mem/memory-device.h" +#include "hw/mem/pc-dimm.h" +#include "hw/pci/pci.h" +#include "hw/qdev-properties.h" +#include "qapi/error.h" +#include "qemu/log.h" +#include "qemu/module.h" +#include "qemu/range.h" +#include "qemu/rcu.h" +#include "sysemu/hostmem.h" +#include "hw/cxl/cxl.h" + +typedef struct cxl_type3_dev { + /* Private */ + PCIDevice parent_obj; + + /* Properties */ + uint64_t size; + HostMemoryBackend *hostmem; + + /* State */ + CXLComponentState cxl_cstate; + CXLDeviceState cxl_dstate; +} CXLType3Dev; + +#define CT3(obj) OBJECT_CHECK(CXLType3Dev, (obj), TYPE_CXL_TYPE3_DEV) + +static void build_dvsecs(CXLType3Dev *ct3d) +{ + CXLComponentState *cxl_cstate = &ct3d->cxl_cstate; + uint8_t *dvsec; + + dvsec = (uint8_t *)&(struct dvsec_device){ + .cap = 0x1e, + .ctrl = 0x6, + .status2 = 0x2, + .range1_size_hi = 0, + .range1_size_lo = (2 << 5) | (2 << 2) | 0x3 | ct3d->size, + .range1_base_hi = 0, + .range1_base_lo = 0, + }; + cxl_component_create_dvsec(cxl_cstate, PCIE_CXL_DEVICE_DVSEC_LENGTH, + PCIE_CXL_DEVICE_DVSEC, + PCIE_CXL2_DEVICE_DVSEC_REVID, dvsec); + + dvsec = (uint8_t *)&(struct dvsec_register_locator){ + .rsvd = 0, + .reg0_base_lo = RBI_COMPONENT_REG | COMPONENT_REG_BAR_IDX, + .reg0_base_hi = 0, + .reg1_base_lo = RBI_CXL_DEVICE_REG | DEVICE_REG_BAR_IDX, + .reg1_base_hi = 0, + }; + cxl_component_create_dvsec(cxl_cstate, REG_LOC_DVSEC_LENGTH, REG_LOC_DVSEC, + REG_LOC_DVSEC_REVID, dvsec); +} + +static void ct3_instance_init(Object *obj) +{ + /* MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj); */ +} + +static void ct3_finalize(Object *obj) +{ + CXLType3Dev *ct3d = CT3(obj); + + g_free(ct3d->cxl_dstate.pmem); +} + +static void cxl_setup_memory(CXLType3Dev *ct3d, Error **errp) +{ + MemoryRegionSection mrs; + MemoryRegion *mr; + uint64_t offset = 0; + size_t remaining_size; + + if (!ct3d->hostmem) { + error_setg(errp, "memdev property must be set"); + return; + } + + /* FIXME: need to check mr is the host bridge's MR */ + mr = host_memory_backend_get_memory(ct3d->hostmem); + + /* Create our new subregion */ + ct3d->cxl_dstate.pmem = g_new(MemoryRegion, 1); + + /* Find the first free space in the window */ + WITH_RCU_READ_LOCK_GUARD() + { + mrs = memory_region_find(mr, offset, 1); + while (mrs.mr && mrs.mr != mr) { + offset += memory_region_size(mrs.mr); + mrs = memory_region_find(mr, offset, 1); + } + } + + remaining_size = memory_region_size(mr) - offset; + if (remaining_size < ct3d->size) { + g_free(ct3d->cxl_dstate.pmem); + error_setg(errp, + "Not enough free space (%zd) required for device (%" PRId64 ")", + remaining_size, ct3d->size); + } + + /* Register our subregion as non-volatile */ + memory_region_init_ram(ct3d->cxl_dstate.pmem, OBJECT(ct3d), + "cxl_type3-memory", ct3d->size, errp); + memory_region_set_nonvolatile(ct3d->cxl_dstate.pmem, true); + +#ifdef SET_PMEM_PADDR + memory_region_add_subregion(mr, offset, ct3d->cxl_dstate.pmem); +#endif +} + +static MemoryRegion *cxl_md_get_memory_region(MemoryDeviceState *md, + Error **errp) +{ + CXLType3Dev *ct3d = CT3(md); + + if (!ct3d->cxl_dstate.pmem) { + cxl_setup_memory(ct3d, errp); + } + + return ct3d->cxl_dstate.pmem; +} + +static void ct3_realize(PCIDevice *pci_dev, Error **errp) +{ + CXLType3Dev *ct3d = CT3(pci_dev); + CXLComponentState *cxl_cstate = &ct3d->cxl_cstate; + ComponentRegisters *regs = &cxl_cstate->crb; + MemoryRegion *mr = ®s->component_registers; + uint8_t *pci_conf = pci_dev->config; + + if (!ct3d->cxl_dstate.pmem) { + cxl_setup_memory(ct3d, errp); + } + + pci_config_set_prog_interface(pci_conf, 0x10); + pci_config_set_class(pci_conf, PCI_CLASS_MEMORY_CXL); + + pcie_endpoint_cap_init(pci_dev, 0x80); + cxl_cstate->dvsec_offset = 0x100; + + ct3d->cxl_cstate.pdev = pci_dev; + build_dvsecs(ct3d); + + cxl_component_register_block_init(OBJECT(pci_dev), cxl_cstate, + TYPE_CXL_TYPE3_DEV); + + pci_register_bar( + pci_dev, 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); + pci_register_bar(pci_dev, DEVICE_REG_BAR_IDX, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64, + &ct3d->cxl_dstate.device_registers); +} + +static uint64_t cxl_md_get_addr(const MemoryDeviceState *md) +{ + CXLType3Dev *ct3d = CT3(md); + + return memory_region_get_ram_addr(ct3d->cxl_dstate.pmem); +} + +static void cxl_md_set_addr(MemoryDeviceState *md, uint64_t addr, Error **errp) +{ + object_property_set_uint(OBJECT(md), "paddr", addr, errp); +} + +static void ct3d_reset(DeviceState *dev) +{ + CXLType3Dev *ct3d = CT3(dev); + uint32_t *reg_state = ct3d->cxl_cstate.crb.cache_mem_registers; + + cxl_component_register_init_common(reg_state, CXL2_TYPE3_DEVICE); + cxl_device_register_init_common(&ct3d->cxl_dstate); +} + +static Property ct3_props[] = { + DEFINE_PROP_SIZE("size", CXLType3Dev, size, -1), + DEFINE_PROP_LINK("memdev", CXLType3Dev, hostmem, TYPE_MEMORY_BACKEND, + HostMemoryBackend *), + DEFINE_PROP_END_OF_LIST(), +}; + +static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md, + MemoryDeviceInfo *info) +{ + PCDIMMDeviceInfo *di = g_new0(PCDIMMDeviceInfo, 1); + const DeviceClass *dc = DEVICE_GET_CLASS(md); + const DeviceState *dev = DEVICE(md); + CXLType3Dev *ct3d = CT3(md); + + if (dev->id) { + di->has_id = true; + di->id = g_strdup(dev->id); + } + di->hotplugged = dev->hotplugged; + di->hotpluggable = dc->hotpluggable; + di->addr = cxl_md_get_addr(md); + di->slot = 0; + di->node = 0; + di->size = memory_device_get_region_size(md, NULL); + di->memdev = object_get_canonical_path(OBJECT(ct3d->hostmem)); + + + info->u.cxl.data = di; + info->type = MEMORY_DEVICE_INFO_KIND_CXL; +} + +static void ct3_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); + MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc); + + pc->realize = ct3_realize; + pc->class_id = PCI_CLASS_STORAGE_EXPRESS; + pc->vendor_id = PCI_VENDOR_ID_INTEL; + pc->device_id = 0xd93; /* LVF for now */ + pc->revision = 1; + + set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); + dc->desc = "CXL PMEM Device (Type 3)"; + dc->reset = ct3d_reset; + device_class_set_props(dc, ct3_props); + + mdc->get_memory_region = cxl_md_get_memory_region; + mdc->get_addr = cxl_md_get_addr; + mdc->fill_device_info = pc_dimm_md_fill_device_info; + mdc->get_plugged_size = memory_device_get_region_size; + mdc->set_addr = cxl_md_set_addr; +} + +static const TypeInfo ct3d_info = { + .name = TYPE_CXL_TYPE3_DEV, + .parent = TYPE_PCI_DEVICE, + .class_init = ct3_class_init, + .instance_size = sizeof(CXLType3Dev), + .instance_init = ct3_instance_init, + .instance_finalize = ct3_finalize, + .interfaces = (InterfaceInfo[]) { + { TYPE_MEMORY_DEVICE }, + { INTERFACE_CXL_DEVICE }, + { INTERFACE_PCIE_DEVICE }, + {} + }, +}; + +static void ct3d_registers(void) +{ + type_register_static(&ct3d_info); +} + +type_init(ct3d_registers); diff --git a/hw/mem/meson.build b/hw/mem/meson.build index 0d22f2b572..d13c3ed117 100644 --- a/hw/mem/meson.build +++ b/hw/mem/meson.build @@ -3,5 +3,6 @@ mem_ss.add(files('memory-device.c')) mem_ss.add(when: 'CONFIG_DIMM', if_true: files('pc-dimm.c')) mem_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_mc.c')) mem_ss.add(when: 'CONFIG_NVDIMM', if_true: files('nvdimm.c')) +mem_ss.add(when: 'CONFIG_CXL_MEM_DEVICE', if_true: files('cxl_type3.c')) softmmu_ss.add_all(when: 'CONFIG_MEM_DEVICE', if_true: mem_ss) diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index d4010cf8f3..1ecf6f6a55 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" +#include "hw/mem/memory-device.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pcie.h" #include "hw/pci/msix.h" @@ -27,6 +28,8 @@ #include "hw/pci/pci_bus.h" #include "hw/pci/pcie_regs.h" #include "hw/pci/pcie_port.h" +#include "hw/cxl/cxl.h" +#include "hw/boards.h" #include "qemu/range.h" //#define DEBUG_PCIE @@ -419,6 +422,28 @@ void pcie_cap_slot_pre_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, } pcie_cap_slot_plug_common(PCI_DEVICE(hotplug_dev), dev, errp); + +#ifdef CXL_MEM_DEVICE + /* + * FIXME: + * if (object_dynamic_cast(OBJECT(dev), TYPE_CXL_TYPE3_DEV)) { + * HotplugHandler *hotplug_ctrl; + * Error *local_err = NULL; + * hotplug_ctrl = qdev_get_hotplug_handler(dev); + * if (hotplug_ctrl) { + * hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err); + * if (local_err) { + * error_propagate(errp, local_err); + * return; + * } + * } + */ + + if (object_dynamic_cast(OBJECT(dev), TYPE_CXL_TYPE3_DEV)) { + memory_device_pre_plug(MEMORY_DEVICE(dev), MACHINE(qdev_get_machine()), + NULL, errp); + } +#endif } void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, @@ -455,6 +480,11 @@ void pcie_cap_slot_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, pcie_cap_slot_event(hotplug_pdev, PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP); } + +#ifdef CXL_MEM_DEVICE + if (object_dynamic_cast(OBJECT(dev), TYPE_CXL_TYPE3_DEV)) + memory_device_plug(MEMORY_DEVICE(dev), MACHINE(qdev_get_machine())); +#endif } void pcie_cap_slot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index b1e5f4a8fa..809ed7de60 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -17,6 +17,8 @@ #define COMPONENT_REG_BAR_IDX 0 #define DEVICE_REG_BAR_IDX 2 +#define TYPE_CXL_TYPE3_DEV "cxl-type3" + #define CXL_HOST_BASE 0xD0000000 #define CXL_WINDOW_MAX 10 diff --git a/include/hw/cxl/cxl_pci.h b/include/hw/cxl/cxl_pci.h index a53c2e5ae7..9ec28c9feb 100644 --- a/include/hw/cxl/cxl_pci.h +++ b/include/hw/cxl/cxl_pci.h @@ -64,6 +64,28 @@ _Static_assert(sizeof(struct dvsec_header) == 10, * CXL 2.0 Downstream Port: 3, 4, 7, 8 */ +/* CXL 2.0 - 8.1.3 (ID 0001) */ +struct dvsec_device { + struct dvsec_header hdr; + uint16_t cap; + uint16_t ctrl; + uint16_t status; + uint16_t ctrl2; + uint16_t status2; + uint16_t lock; + uint16_t cap2; + uint32_t range1_size_hi; + uint32_t range1_size_lo; + uint32_t range1_base_hi; + uint32_t range1_base_lo; + uint32_t range2_size_hi; + uint32_t range2_size_lo; + uint32_t range2_base_hi; + uint32_t range2_base_lo; +}; +_Static_assert(sizeof(struct dvsec_device) == 0x38, + "dvsec device size incorrect"); + /* CXL 2.0 - 8.1.5 (ID 0003) */ struct extensions_dvsec_port { struct dvsec_header hdr; diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index 11f8ab7149..76bf3ed590 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -53,6 +53,7 @@ #define PCI_BASE_CLASS_MEMORY 0x05 #define PCI_CLASS_MEMORY_RAM 0x0500 #define PCI_CLASS_MEMORY_FLASH 0x0501 +#define PCI_CLASS_MEMORY_CXL 0x0502 #define PCI_CLASS_MEMORY_OTHER 0x0580 #define PCI_BASE_CLASS_BRIDGE 0x06 diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index 0dd594f92b..0f67bc61ce 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -1887,6 +1887,21 @@ void hmp_info_memory_devices(Monitor *mon, const QDict *qdict) monitor_printf(mon, " hotpluggable: %s\n", di->hotpluggable ? "true" : "false"); break; + case MEMORY_DEVICE_INFO_KIND_CXL: + di = value->u.cxl.data; + monitor_printf(mon, "Memory device [%s]: \"%s\"\n", + MemoryDeviceInfoKind_str(value->type), + di->id ? di->id : ""); + monitor_printf(mon, " addr: 0x%" PRIx64 "\n", di->addr); + monitor_printf(mon, " slot: %" PRId64 "\n", di->slot); + monitor_printf(mon, " node: %" PRId64 "\n", di->node); + monitor_printf(mon, " size: %" PRIu64 "\n", di->size); + monitor_printf(mon, " memdev: %s\n", di->memdev); + monitor_printf(mon, " hotplugged: %s\n", + di->hotplugged ? "true" : "false"); + monitor_printf(mon, " hotpluggable: %s\n", + di->hotpluggable ? "true" : "false"); + break; case MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM: vpi = value->u.virtio_pmem.data; monitor_printf(mon, "Memory device [%s]: \"%s\"\n", diff --git a/qapi/machine.json b/qapi/machine.json index 330189efe3..aa96d662bd 100644 --- a/qapi/machine.json +++ b/qapi/machine.json @@ -1394,6 +1394,7 @@ { 'union': 'MemoryDeviceInfo', 'data': { 'dimm': 'PCDIMMDeviceInfo', 'nvdimm': 'PCDIMMDeviceInfo', + 'cxl': 'PCDIMMDeviceInfo', 'virtio-pmem': 'VirtioPMEMDeviceInfo', 'virtio-mem': 'VirtioMEMDeviceInfo' } From patchwork Tue Jan 5 16:53:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422584 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JnN0fksz9sVq for ; Wed, 6 Jan 2021 04:06:48 +1100 (AEDT) Received: from localhost ([::1]:60762 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpnB-0004cz-3b for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:06:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41910) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpc8-00016f-QA for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:24 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpc3-00012E-Bg for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:20 -0500 IronPort-SDR: FTddpgbaXCsnlo1O3QlvkmfWr3rZuA+D3u2tOPQAIu+1K91LDDCePMgn130zpyRiWA/ZxOrmuh Kixq76Bg9CUw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629571" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629571" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:05 -0800 IronPort-SDR: i0NwePPMUZmUmyMrOd/06thRucyCPaLKFduDqhh82eL2XrPaksI7x6Xp5gqGzi/jH/1/vWuVCb ISNro/AHe/Hw== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338072" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:04 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 25/32] hw/cxl/device: Implement MMIO HDM decoding (8.2.5.12) Date: Tue, 5 Jan 2021 08:53:16 -0800 Message-Id: <20210105165323.783725-26-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" A device's volatile and persistent memory are known Host Defined Memory (HDM) regions. The mechanism by which the device is programmed to claim the addresses associated with those regions is through dedicated logic known as the HDM decoder. In order to allow the OS to properly program the HDMs, the HDM decoders must be modeled. There are two ways the HDM decoders can be implemented, the legacy mechanism is through the PCIe DVSEC programming from CXL 1.1 (8.1.3.8), and MMIO is found in 8.2.5.12 of the spec. For now, 8.1.3.8 is not implemented. Much of CXL device logic is implemented in cxl-utils. The HDM decoder however is implemented directly by the device implementation. The generic cxl-utils probably should be the correct place to put this since HDM decoders aren't unique to a type3 device. It is however easier at the moment, and requires less design consideration to simply implement it in the device, and figure out how to consolidate it later. Signed-off-by: Ben Widawsky --- hw/mem/cxl_type3.c | 82 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 5 deletions(-) diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index 3985bb8d0b..dee5a8884b 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -57,6 +57,71 @@ static void build_dvsecs(CXLType3Dev *ct3d) REG_LOC_DVSEC_REVID, dvsec); } +static void hdm_decoder_commit(CXLType3Dev *ct3d, int which) +{ + MemoryRegion *pmem = ct3d->cxl_dstate.pmem; + MemoryRegion *mr = host_memory_backend_get_memory(ct3d->hostmem); + Range window, device; + ComponentRegisters *cregs = &ct3d->cxl_cstate.crb; + uint32_t *cache_mem = cregs->cache_mem_registers; + uint64_t offset, size; + Error *err = NULL; + + assert(which == 0); + + ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, COMMIT, 0); + ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, ERROR, 0); + + offset = ((uint64_t)cache_mem[R_CXL_HDM_DECODER0_BASE_HI] << 32) | + cache_mem[R_CXL_HDM_DECODER0_BASE_LO]; + size = ((uint64_t)cache_mem[R_CXL_HDM_DECODER0_SIZE_HI] << 32) | + cache_mem[R_CXL_HDM_DECODER0_SIZE_LO]; + + range_init_nofail(&window, mr->addr, memory_region_size(mr)); + range_init_nofail(&device, offset, size); + + if (!range_contains_range(&window, &device)) { + ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, ERROR, 1); + return; + } + + memory_region_ram_resize(pmem, size, &err); + if (err) { + ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, ERROR, 1); + return; + } + + offset -= mr->addr; + memory_region_add_subregion(mr, offset, pmem); + + ARRAY_FIELD_DP32(cache_mem, CXL_HDM_DECODER0_CTRL, COMMITTED, 1); +} + +static void ct3d_reg_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) +{ + CXLComponentState *cxl_cstate = opaque; + ComponentRegisters *cregs = &cxl_cstate->crb; + CXLType3Dev *ct3d = container_of(cxl_cstate, CXLType3Dev, cxl_cstate); + uint32_t *cache_mem = cregs->cache_mem_registers; + bool should_commit = false; + int which_hdm = -1; + + assert(size == 4); + + switch (offset) { + case A_CXL_HDM_DECODER0_CTRL: + should_commit = FIELD_EX32(value, CXL_HDM_DECODER0_CTRL, COMMIT); + which_hdm = 0; + break; + default: + break; + } + + stl_le_p((uint8_t *)cache_mem + offset, value); + if (should_commit) + hdm_decoder_commit(ct3d, which_hdm); +} + static void ct3_instance_init(Object *obj) { /* MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj); */ @@ -65,7 +130,10 @@ static void ct3_instance_init(Object *obj) static void ct3_finalize(Object *obj) { CXLType3Dev *ct3d = CT3(obj); + CXLComponentState *cxl_cstate = &ct3d->cxl_cstate; + ComponentRegisters *regs = &cxl_cstate->crb; + g_free((void *)regs->special_ops); g_free(ct3d->cxl_dstate.pmem); } @@ -81,11 +149,12 @@ static void cxl_setup_memory(CXLType3Dev *ct3d, Error **errp) return; } - /* FIXME: need to check mr is the host bridge's MR */ - mr = host_memory_backend_get_memory(ct3d->hostmem); - /* Create our new subregion */ ct3d->cxl_dstate.pmem = g_new(MemoryRegion, 1); + memory_region_set_nonvolatile(ct3d->cxl_dstate.pmem, true); + + /* FIXME: need to check mr is the host bridge's MR */ + mr = host_memory_backend_get_memory(ct3d->hostmem); /* Find the first free space in the window */ WITH_RCU_READ_LOCK_GUARD() @@ -108,8 +177,6 @@ static void cxl_setup_memory(CXLType3Dev *ct3d, Error **errp) /* Register our subregion as non-volatile */ memory_region_init_ram(ct3d->cxl_dstate.pmem, OBJECT(ct3d), "cxl_type3-memory", ct3d->size, errp); - memory_region_set_nonvolatile(ct3d->cxl_dstate.pmem, true); - #ifdef SET_PMEM_PADDR memory_region_add_subregion(mr, offset, ct3d->cxl_dstate.pmem); #endif @@ -148,6 +215,11 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp) ct3d->cxl_cstate.pdev = pci_dev; build_dvsecs(ct3d); +#ifndef SET_PMEM_PADDR + regs->special_ops = g_new0(MemoryRegionOps, 1); + regs->special_ops->write = ct3d_reg_write; +#endif + cxl_component_register_block_init(OBJECT(pci_dev), cxl_cstate, TYPE_CXL_TYPE3_DEV); From patchwork Tue Jan 5 16:53:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422588 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jqz6YKPz9sWM for ; Wed, 6 Jan 2021 04:09:03 +1100 (AEDT) Received: from localhost ([::1]:41116 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwppN-00007m-Rf for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:09:01 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:42016) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpcS-0001Ga-Pa for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:43 -0500 Received: from mga11.intel.com ([192.55.52.93]:21242) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpcL-00012E-Rv for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:40 -0500 IronPort-SDR: iDnY5euDzfb2TdkB4sVao25mRE0XEGbg9tfd6gCKV2A2sn1O5lsEIPysltKLG3yTTAiwFvf8Mw pQ/rI656xwUw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629575" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629575" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:05 -0800 IronPort-SDR: XmmizUBilqklKTm4K3sxvMb5ASnqAtyEUCY1h/O1l9Yty+kzyd+CLq24Krq0P38as+/71VpX/g XA9ZoypPAe3Q== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338076" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:05 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 26/32] acpi/cxl: Add _OSC implementation (9.14.2) Date: Tue, 5 Jan 2021 08:53:17 -0800 Message-Id: <20210105165323.783725-27-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" CXL 2.0 specification adds 2 new dwords to the existing _OSC definition from PCIe. The new dwords are accessed with a new uuid. This implementation supports what is in the specification. We are currently in the process of trying to define a new definition for _OSC. See later work for an explanation. Signed-off-by: Ben Widawsky --- hw/acpi/Kconfig | 5 ++ hw/acpi/cxl.c | 104 ++++++++++++++++++++++++++++++++++++++++++ hw/acpi/meson.build | 1 + hw/i386/acpi-build.c | 12 ++++- include/hw/acpi/cxl.h | 23 ++++++++++ 5 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 hw/acpi/cxl.c create mode 100644 include/hw/acpi/cxl.h diff --git a/hw/acpi/Kconfig b/hw/acpi/Kconfig index 1932f66af8..b27907953e 100644 --- a/hw/acpi/Kconfig +++ b/hw/acpi/Kconfig @@ -5,6 +5,7 @@ config ACPI_X86 bool select ACPI select ACPI_NVDIMM + select ACPI_CXL select ACPI_CPU_HOTPLUG select ACPI_MEMORY_HOTPLUG select ACPI_HMAT @@ -42,3 +43,7 @@ config ACPI_VMGENID depends on PC config ACPI_HW_REDUCED + +config ACPI_CXL + bool + depends on ACPI diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c new file mode 100644 index 0000000000..7124d5a1a3 --- /dev/null +++ b/hw/acpi/cxl.c @@ -0,0 +1,104 @@ +/* + * CXL ACPI Implementation + * + * Copyright(C) 2020 Intel Corporation. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see + */ + +#include "qemu/osdep.h" +#include "hw/cxl/cxl.h" +#include "hw/acpi/acpi.h" +#include "hw/acpi/aml-build.h" +#include "hw/acpi/bios-linker-loader.h" +#include "hw/acpi/cxl.h" +#include "qapi/error.h" +#include "qemu/uuid.h" + +static Aml *__build_cxl_osc_method(void) +{ + Aml *method, *if_uuid, *else_uuid, *if_arg1_not_1, *if_cxl, *if_caps_masked; + Aml *a_ctrl = aml_local(0); + Aml *a_cdw1 = aml_name("CDW1"); + + method = aml_method("_OSC", 4, AML_NOTSERIALIZED); + aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); + + /* 9.14.2.1.4 */ + if_uuid = aml_if( + aml_lor(aml_equal(aml_arg(0), + aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")), + aml_equal(aml_arg(0), + aml_touuid("68F2D50B-C469-4D8A-BD3D-941A103FD3FC")))); + aml_append(if_uuid, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2")); + aml_append(if_uuid, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3")); + + aml_append(if_uuid, aml_store(aml_name("CDW3"), a_ctrl)); + + /* This is all the same as what's used for PCIe */ + aml_append(if_uuid, + aml_and(aml_name("CTRL"), aml_int(0x1F), aml_name("CTRL"))); + + if_arg1_not_1 = aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(0x1)))); + /* Unknown revision */ + aml_append(if_arg1_not_1, aml_or(a_cdw1, aml_int(0x08), a_cdw1)); + aml_append(if_uuid, if_arg1_not_1); + + if_caps_masked = aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl))); + /* Capability bits were masked */ + aml_append(if_caps_masked, aml_or(a_cdw1, aml_int(0x10), a_cdw1)); + aml_append(if_uuid, if_caps_masked); + + aml_append(if_uuid, aml_store(aml_name("CDW2"), aml_name("SUPP"))); + aml_append(if_uuid, aml_store(aml_name("CDW3"), aml_name("CTRL"))); + + if_cxl = aml_if(aml_equal( + aml_arg(0), aml_touuid("68F2D50B-C469-4D8A-BD3D-941A103FD3FC"))); + /* CXL support field */ + aml_append(if_cxl, aml_create_dword_field(aml_arg(3), aml_int(12), "CDW4")); + /* CXL capabilities */ + aml_append(if_cxl, aml_create_dword_field(aml_arg(3), aml_int(16), "CDW5")); + aml_append(if_cxl, aml_store(aml_name("CDW4"), aml_name("SUPC"))); + aml_append(if_cxl, aml_store(aml_name("CDW5"), aml_name("CTRC"))); + + /* CXL 2.0 Port/Device Register access */ + aml_append(if_cxl, + aml_or(aml_name("CDW5"), aml_int(0x1), aml_name("CDW5"))); + aml_append(if_uuid, if_cxl); + + /* Update DWORD3 (the return value) */ + aml_append(if_uuid, aml_store(a_ctrl, aml_name("CDW3"))); + + aml_append(if_uuid, aml_return(aml_arg(3))); + aml_append(method, if_uuid); + + else_uuid = aml_else(); + + /* unrecognized uuid */ + aml_append(else_uuid, + aml_or(aml_name("CDW1"), aml_int(0x4), aml_name("CDW1"))); + aml_append(else_uuid, aml_return(aml_arg(3))); + aml_append(method, else_uuid); + + return method; +} + +void build_cxl_osc_method(Aml *dev) +{ + aml_append(dev, aml_name_decl("SUPP", aml_int(0))); + aml_append(dev, aml_name_decl("CTRL", aml_int(0))); + aml_append(dev, aml_name_decl("SUPC", aml_int(0))); + aml_append(dev, aml_name_decl("CTRC", aml_int(0))); + aml_append(dev, __build_cxl_osc_method()); +} diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build index dd69577212..9f5c5ced28 100644 --- a/hw/acpi/meson.build +++ b/hw/acpi/meson.build @@ -10,6 +10,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_CPU_HOTPLUG', if_true: files('cpu_hotplug.c')) acpi_ss.add(when: 'CONFIG_ACPI_MEMORY_HOTPLUG', if_true: files('memory_hotplug.c')) acpi_ss.add(when: 'CONFIG_ACPI_NVDIMM', if_true: files('nvdimm.c')) acpi_ss.add(when: 'CONFIG_ACPI_PCI', if_true: files('pci.c')) +acpi_ss.add(when: 'CONFIG_ACPI_CXL', if_true: files('cxl.c')) acpi_ss.add(when: 'CONFIG_ACPI_VMGENID', if_true: files('vmgenid.c')) acpi_ss.add(when: 'CONFIG_ACPI_HW_REDUCED', if_true: files('generic_event_device.c')) acpi_ss.add(when: 'CONFIG_ACPI_HMAT', if_true: files('hmat.c')) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 16cde677a0..3eb07b9741 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -66,6 +66,7 @@ #include "hw/acpi/aml-build.h" #include "hw/acpi/utils.h" #include "hw/acpi/pci.h" +#include "hw/acpi/cxl.h" #include "qom/qom-qobject.h" #include "hw/i386/amd_iommu.h" @@ -1201,11 +1202,20 @@ static void init_pci_acpi(Aml *dev, int uid, int type) if (type == PCI) { aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); aml_append(dev, aml_name_decl("_UID", aml_int(uid))); - } else { + } else if (type == PCIE) { aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); aml_append(dev, aml_name_decl("_UID", aml_int(uid))); aml_append(dev, build_q35_osc_method()); + } else /* CXL */ { + struct Aml *pkg = aml_package(2); + + aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0016"))); + aml_append(pkg, aml_eisaid("PNP0A08")); + aml_append(pkg, aml_eisaid("PNP0A03")); + aml_append(dev, aml_name_decl("_CID", pkg)); + aml_append(dev, aml_name_decl("_UID", aml_int(uid))); + build_cxl_osc_method(dev); } } diff --git a/include/hw/acpi/cxl.h b/include/hw/acpi/cxl.h new file mode 100644 index 0000000000..7b8f3b8a2e --- /dev/null +++ b/include/hw/acpi/cxl.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2020 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + */ + +#ifndef HW_ACPI_CXL_H +#define HW_ACPI_CXL_H + +void build_cxl_osc_method(Aml *dev); + +#endif From patchwork Tue Jan 5 16:53:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422602 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9K3p2Txkz9sSs for ; Wed, 6 Jan 2021 04:19:18 +1100 (AEDT) Received: from localhost ([::1]:53082 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpzI-0000XO-Be for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:19:16 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:42074) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpcc-0001Hh-7z for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:51 -0500 Received: from mga11.intel.com ([192.55.52.93]:21251) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpcP-00012q-Ku for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:48 -0500 IronPort-SDR: ygCNHJ/1tHBuUetk5+HHGKbki8mZ4tjC4Np+1uB1ht8def4jYJyM1//B2K4a34LUbf/mZg7qyn kii7luWdU+UA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629582" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629582" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:06 -0800 IronPort-SDR: LRDIuHze4w8C4OwXi8Y2PcX2h8YU/ODZ5UHuX+dNMSznaEr7zqsoCrlhgL1I52OXCprKYoi+3z DggiQxonFvWg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338083" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:05 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 27/32] tests/acpi: allow CEDT table addition Date: Tue, 5 Jan 2021 08:53:18 -0800 Message-Id: <20210105165323.783725-28-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Ben Widawsky --- tests/data/acpi/pc/CEDT | 0 tests/data/acpi/q35/CEDT | 0 tests/qtest/bios-tables-test-allowed-diff.h | 2 ++ 3 files changed, 2 insertions(+) create mode 100644 tests/data/acpi/pc/CEDT create mode 100644 tests/data/acpi/q35/CEDT diff --git a/tests/data/acpi/pc/CEDT b/tests/data/acpi/pc/CEDT new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/data/acpi/q35/CEDT b/tests/data/acpi/q35/CEDT new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h index dfb8523c8b..9b07f1e1ff 100644 --- a/tests/qtest/bios-tables-test-allowed-diff.h +++ b/tests/qtest/bios-tables-test-allowed-diff.h @@ -1 +1,3 @@ /* List of comma-separated changed AML files to ignore */ +"tests/data/acpi/pc/CEDT", +"tests/data/acpi/q35/CEDT", From patchwork Tue Jan 5 16:53:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422606 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9K7D41M5z9sSs for ; Wed, 6 Jan 2021 04:22:16 +1100 (AEDT) Received: from localhost ([::1]:60120 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwq2A-0003id-HU for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:22:14 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:42110) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpce-0001IQ-CG for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:52 -0500 Received: from mga11.intel.com ([192.55.52.93]:21248) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpcQ-00012W-PB for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:55:51 -0500 IronPort-SDR: 9dyIny0vMF9DcS+Ofl/eGJwEheX77fUJPkHoSQXQvxpwhvkAL7je+9OjGCtDo+1x9Wu2Iqnyoi tmR27UqgzImA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="173629584" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="173629584" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:07 -0800 IronPort-SDR: CiqgcqYv72zvWsLX39IAKTTBju7Loi7Sh99FqLkpDC1soQe9WsTV7tEgGpVvM8HizJEZhP8DbY H1WEL6VL8Wqg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338088" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:06 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 28/32] acpi/cxl: Create the CEDT (9.14.1) Date: Tue, 5 Jan 2021 08:53:19 -0800 Message-Id: <20210105165323.783725-29-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=192.55.52.93; envelope-from=ben.widawsky@intel.com; helo=mga11.intel.com X-Spam_score_int: -68 X-Spam_score: -6.9 X-Spam_bar: ------ X-Spam_report: (-6.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The CXL Early Discovery Table is defined in the CXL 2.0 specification as a way for the OS to get CXL specific information from the system firmware. As of CXL 2.0 spec, only 1 sub structure is defined, the CXL Host Bridge Structure (CHBS) which is primarily useful for telling the OS exactly where the MMIO for the host bridge is. v2: Update CHBS to spec released definition Signed-off-by: Ben Widawsky --- hw/acpi/cxl.c | 69 +++++++++++++++++++++++++++++ hw/i386/acpi-build.c | 6 ++- hw/pci-bridge/pci_expander_bridge.c | 21 +-------- include/hw/acpi/cxl.h | 4 ++ include/hw/pci/pci_bridge.h | 25 +++++++++++ 5 files changed, 104 insertions(+), 21 deletions(-) diff --git a/hw/acpi/cxl.c b/hw/acpi/cxl.c index 7124d5a1a3..68db0fe3a8 100644 --- a/hw/acpi/cxl.c +++ b/hw/acpi/cxl.c @@ -18,14 +18,83 @@ */ #include "qemu/osdep.h" +#include "hw/sysbus.h" +#include "hw/pci/pci_bridge.h" +#include "hw/pci/pci_host.h" #include "hw/cxl/cxl.h" +#include "hw/mem/memory-device.h" #include "hw/acpi/acpi.h" #include "hw/acpi/aml-build.h" #include "hw/acpi/bios-linker-loader.h" #include "hw/acpi/cxl.h" +#include "hw/acpi/cxl.h" #include "qapi/error.h" #include "qemu/uuid.h" +static void cedt_build_chbs(GArray *table_data, PXBDev *cxl) +{ + SysBusDevice *sbd = SYS_BUS_DEVICE(cxl->cxl.cxl_host_bridge); + struct MemoryRegion *mr = sbd->mmio[0].memory; + + /* Type */ + build_append_int_noprefix(table_data, 0, 1); + + /* Reserved */ + build_append_int_noprefix(table_data, 0, 1); + + /* Record Length */ + build_append_int_noprefix(table_data, 32, 2); + + /* UID */ + build_append_int_noprefix(table_data, cxl->uid, 4); + + /* Version */ + build_append_int_noprefix(table_data, 1, 4); + + /* Reserved */ + build_append_int_noprefix(table_data, 0, 4); + + /* Base */ + build_append_int_noprefix(table_data, mr->addr, 8); + + /* Length */ + build_append_int_noprefix(table_data, memory_region_size(mr), 8); +} + +static int cxl_foreach_pxb_hb(Object *obj, void *opaque) +{ + Aml *cedt = opaque; + + if (object_dynamic_cast(obj, TYPE_PXB_CXL_DEVICE)) { + PXBDev *pxb = PXB_CXL_DEV(obj); + + cedt_build_chbs(cedt->buf, pxb); + } + + return 0; +} + +void cxl_build_cedt(GArray *table_offsets, GArray *table_data, + BIOSLinker *linker) +{ + const int cedt_start = table_data->len; + Aml *cedt; + + cedt = init_aml_allocator(); + + /* reserve space for CEDT header */ + acpi_add_table(table_offsets, table_data); + acpi_data_push(cedt->buf, sizeof(AcpiTableHeader)); + + object_child_foreach_recursive(object_get_root(), cxl_foreach_pxb_hb, cedt); + + /* copy AML table into ACPI tables blob and patch header there */ + g_array_append_vals(table_data, cedt->buf->data, cedt->buf->len); + build_header(linker, table_data, (void *)(table_data->data + cedt_start), + "CEDT", table_data->len - cedt_start, 1, NULL, NULL); + free_aml_allocator(); +} + static Aml *__build_cxl_osc_method(void) { Aml *method, *if_uuid, *else_uuid, *if_arg1_not_1, *if_cxl, *if_caps_masked; diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 3eb07b9741..49242eb8f3 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -75,6 +75,8 @@ #include "hw/acpi/ipmi.h" #include "hw/acpi/hmat.h" +#include "hw/acpi/cxl.h" + /* These are used to size the ACPI tables for -M pc-i440fx-1.7 and * -M pc-i440fx-2.0. Even if the actual amount of AML generated grows * a little bit, there should be plenty of free space since the DSDT @@ -1371,7 +1373,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, scope = aml_scope("\\_SB"); if (type == CXL) { - dev = aml_device("CXL%.01X", pci_bus_uid(bus)); + dev = aml_device("CXL%.01X", uid); } else { dev = aml_device("PC%.02X", bus_num); } @@ -2277,6 +2279,8 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) machine->nvdimms_state, machine->ram_slots); } + cxl_build_cedt(table_offsets, tables_blob, tables->linker); + acpi_add_table(table_offsets, tables_blob); build_waet(tables_blob, tables->linker); diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index af1450c69d..6458d5b76e 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -57,26 +57,6 @@ DECLARE_INSTANCE_CHECKER(PXBDev, PXB_DEV, DECLARE_INSTANCE_CHECKER(PXBDev, PXB_PCIE_DEV, TYPE_PXB_PCIE_DEVICE) -#define TYPE_PXB_CXL_DEVICE "pxb-cxl" -DECLARE_INSTANCE_CHECKER(PXBDev, PXB_CXL_DEV, - TYPE_PXB_CXL_DEVICE) - -struct PXBDev { - /*< private >*/ - PCIDevice parent_obj; - /*< public >*/ - - uint8_t bus_nr; - uint16_t numa_node; - int32_t uid; - struct cxl_dev { - HostMemoryBackend *memory_window[CXL_WINDOW_MAX]; - - uint32_t num_windows; - hwaddr *window_base[CXL_WINDOW_MAX]; - } cxl; -}; - typedef struct CXLHost { PCIHostState parent_obj; @@ -351,6 +331,7 @@ static void pxb_dev_realize_common(PCIDevice *dev, enum BusType type, bus = pci_root_bus_new(ds, dev_name, NULL, NULL, 0, TYPE_PXB_CXL_BUS); bus->flags |= PCI_BUS_CXL; PXB_CXL_HOST(ds)->dev = PXB_CXL_DEV(dev); + PXB_CXL_DEV(dev)->cxl.cxl_host_bridge = ds; } else { bus = pci_root_bus_new(ds, "pxb-internal", NULL, NULL, 0, TYPE_PXB_BUS); bds = qdev_new("pci-bridge"); diff --git a/include/hw/acpi/cxl.h b/include/hw/acpi/cxl.h index 7b8f3b8a2e..db2063f8c9 100644 --- a/include/hw/acpi/cxl.h +++ b/include/hw/acpi/cxl.h @@ -18,6 +18,10 @@ #ifndef HW_ACPI_CXL_H #define HW_ACPI_CXL_H +#include "hw/acpi/bios-linker-loader.h" + +void cxl_build_cedt(GArray *table_offsets, GArray *table_data, + BIOSLinker *linker); void build_cxl_osc_method(Aml *dev); #endif diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h index a94d350034..50dd7fdf33 100644 --- a/include/hw/pci/pci_bridge.h +++ b/include/hw/pci/pci_bridge.h @@ -28,6 +28,7 @@ #include "hw/pci/pci.h" #include "hw/pci/pci_bus.h" +#include "hw/cxl/cxl.h" #include "qom/object.h" typedef struct PCIBridgeWindows PCIBridgeWindows; @@ -81,6 +82,30 @@ struct PCIBridge { #define PCI_BRIDGE_DEV_PROP_MSI "msi" #define PCI_BRIDGE_DEV_PROP_SHPC "shpc" +struct PXBDev { + /*< private >*/ + PCIDevice parent_obj; + /*< public >*/ + + uint8_t bus_nr; + uint16_t numa_node; + int32_t uid; + + struct cxl_dev { + HostMemoryBackend *memory_window[CXL_WINDOW_MAX]; + + uint32_t num_windows; + hwaddr *window_base[CXL_WINDOW_MAX]; + + void *cxl_host_bridge; /* Pointer to a CXLHost */ + } cxl; +}; + +typedef struct PXBDev PXBDev; +#define TYPE_PXB_CXL_DEVICE "pxb-cxl" +DECLARE_INSTANCE_CHECKER(PXBDev, PXB_CXL_DEV, + TYPE_PXB_CXL_DEVICE) + int pci_bridge_ssvid_init(PCIDevice *dev, uint8_t offset, uint16_t svid, uint16_t ssid, Error **errp); From patchwork Tue Jan 5 16:53:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422585 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jq218lGz9sVq for ; Wed, 6 Jan 2021 04:08:14 +1100 (AEDT) Received: from localhost ([::1]:37316 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpoa-0006eX-39 for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:08:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41138) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbN-0000HJ-0x for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:35 -0500 Received: from mga18.intel.com ([134.134.136.126]:10387) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbH-000195-IQ for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:32 -0500 IronPort-SDR: 84Ti8YL7uJAvCsqNLz577idqOejXHg3eRGedkJqOwNKstvfwCVKYLNXli2olAiNuGwFoMNtyR6 tb12UdpsJVwA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="164841151" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="164841151" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:12 -0800 IronPort-SDR: 60KzVmDWpPTUMtpSTdWxUZ+gDvYuSz13YZv4f6iG+7aB93e7l85uphEE5QTsZKuWCxGE8Lnb3u x+AlnEfQ6Kvg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338092" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:07 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 29/32] Temp: acpi/cxl: Add ACPI0017 (CEDT awareness) Date: Tue, 5 Jan 2021 08:53:20 -0800 Message-Id: <20210105165323.783725-30-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.126; envelope-from=ben.widawsky@intel.com; helo=mga18.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This represents Intel's proposal for how the system firmware can notify Linux that the CEDT exists and provides a driver attach point. It is not in the CXL 2.0 specification as of now. CXL 2.0 specification adds an _HID, ACPI0016, for CXL capable host bridges, with a _CID of PNP0A08 (PCIe host bridge). CXL aware software is able to use this initiate the proper _OSC method, and get the _UID which is referenced by the CEDT. Therefore the existence of an ACPI0016 device allows a CXL aware driver perform the necessary actions. For a CXL capable OS, this works. For a CXL unaware OS, this works. The motivation for ACPI0017 is to provide the possibility of having a Linux CXL module that can work on a legacy Linux kernel. Linux core PCI/ACPI which won't be built as a module, will see the _CID of PNP0A08 and bind a driver to it. If we later loaded a driver for ACPI0016, Linux won't be able to bind it to the hardware because it has already bound the PNP0A08 driver. The ACPI0017 device is an opportunity to have an object to bind a driver will be used by a Linux driver to walk the CXL topology and do everything that we would have preferred to do with ACPI0016. There is another motivation for an ACPI0017 device which isn't implemented here. An operating system needs an attach point for a non-volatile region provider that understands cross-hostbridge interleaving. Since QEMU emulation doesn't support interleaving yet, this is more important on the OS side, for now. Signed-off-by: Ben Widawsky --- hw/i386/acpi-build.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 49242eb8f3..470dd7ddf4 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1221,6 +1221,19 @@ static void init_pci_acpi(Aml *dev, int uid, int type) } } +static void build_acpi0017(Aml *table) +{ + Aml *dev; + Aml *scope; + + scope = aml_scope("_SB"); + dev = aml_device("CXLM"); + aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0017"))); + + aml_append(scope, dev); + aml_append(table, scope); +} + static void build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, @@ -1237,6 +1250,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, int root_bus_limit = 0xFF; PCIBus *bus = NULL; TPMIf *tpm = tpm_find(); + bool cxl_present = false; int i; VMBusBridge *vmbus_bridge = vmbus_bridge_find(); @@ -1392,6 +1406,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, /* Handle the ranges for the PXB expanders */ if (type == CXL) { + cxl_present = true; uint64_t base = CXL_HOST_BASE + uid * 0x10000; crs_range_insert(crs_range_set.mem_ranges, base, base + 0x10000 - 1); @@ -1399,6 +1414,10 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, } } + if (cxl_present) { + build_acpi0017(dsdt); + } + /* * At this point crs_range_set has all the ranges used by pci * busses *other* than PCI0. These ranges will be excluded from From patchwork Tue Jan 5 16:53:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422583 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jmz3lXbz9sWM for ; Wed, 6 Jan 2021 04:06:27 +1100 (AEDT) Received: from localhost ([::1]:57878 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpmr-0003DZ-GO for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:06:25 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41104) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbH-0000EE-PV for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:27 -0500 Received: from mga18.intel.com ([134.134.136.126]:10374) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbG-00016I-4Y for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:27 -0500 IronPort-SDR: r1cJyt0Jgiy6u0lJ2c2MYoIiduCuI9uhWbusqqyPhUtGZu/k3iXDpruya865BKU/Z2RG7zdIUa Psq+TszNQjhw== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="164841150" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="164841150" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:12 -0800 IronPort-SDR: nP0XrYh9l03GOgYTnUVr7ATti1O5rH1Uc5/8yjcfwDKTS1Ei8NMurK/cR8xZb3hGlvrwMUE+9J tuahxtsjsSRA== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338095" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:07 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 30/32] tests/acpi: Add new CEDT files Date: Tue, 5 Jan 2021 08:53:21 -0800 Message-Id: <20210105165323.783725-31-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.126; envelope-from=ben.widawsky@intel.com; helo=mga18.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Ben Widawsky --- tests/data/acpi/pc/CEDT | Bin 0 -> 36 bytes tests/data/acpi/q35/CEDT | Bin 0 -> 36 bytes tests/qtest/bios-tables-test-allowed-diff.h | 2 -- 3 files changed, 2 deletions(-) diff --git a/tests/data/acpi/pc/CEDT b/tests/data/acpi/pc/CEDT index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ebf9b54b0b27d9efca53359c3c2e560511f0e165 100644 GIT binary patch literal 36 kcmZ>EbqP^nU|?X};NEbqP^nU|?X};N X-Patchwork-Id: 1422589 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9Jrp5ggjz9sVq for ; Wed, 6 Jan 2021 04:09:46 +1100 (AEDT) Received: from localhost ([::1]:45860 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpq4-0002E0-Qf for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:09:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41174) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbP-0000Hk-MT for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:36 -0500 Received: from mga18.intel.com ([134.134.136.126]:10374) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbI-00016I-5k for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:35 -0500 IronPort-SDR: VEf1fdsr5SGx3w6kzD0UX0bnVPFI6qZw8HzCmMekOB3unqVwKfIrSELipziFDIjGukCNnrk1Hi YA532U25f2qA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="164841152" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="164841152" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:12 -0800 IronPort-SDR: RwYDGOvaCRpbT/2UtfrO3khqc9H+O/UoHKCiuox9I/+EqDeg1cDKjbzO0mqCxcucWd0wFa7bbv 0LgLfRHINiLg== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338101" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:08 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 31/32] WIP: i386/cxl: Initialize a host bridge Date: Tue, 5 Jan 2021 08:53:22 -0800 Message-Id: <20210105165323.783725-32-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.126; envelope-from=ben.widawsky@intel.com; helo=mga18.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch allows initializing the primary host bridge as a CXL capable hostbridge. Signed-off-by: Ben Widawsky --- This patch is WIP. --- hw/arm/virt.c | 1 + hw/core/machine.c | 26 ++++++++++++++++++++++++++ hw/i386/acpi-build.c | 8 +++++++- hw/i386/microvm.c | 1 + hw/i386/pc.c | 1 + hw/ppc/spapr.c | 2 ++ include/hw/boards.h | 2 ++ include/hw/cxl/cxl.h | 4 ++++ 8 files changed, 44 insertions(+), 1 deletion(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 96985917d3..c9d6636efa 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2481,6 +2481,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) hc->unplug_request = virt_machine_device_unplug_request_cb; hc->unplug = virt_machine_device_unplug_cb; mc->nvdimm_supported = true; + mc->cxl_supported = false; mc->auto_enable_numa_with_memhp = true; mc->auto_enable_numa_with_memdev = true; mc->default_ram_id = "mach-virt.ram"; diff --git a/hw/core/machine.c b/hw/core/machine.c index de3b8f1b31..c739803854 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -30,6 +30,7 @@ #include "sysemu/qtest.h" #include "hw/pci/pci.h" #include "hw/mem/nvdimm.h" +#include "hw/cxl/cxl.h" #include "migration/global_state.h" #include "migration/vmstate.h" @@ -502,6 +503,20 @@ static void machine_set_nvdimm_persistence(Object *obj, const char *value, nvdimms_state->persistence_string = g_strdup(value); } +static bool machine_get_cxl(Object *obj, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + return ms->cxl_devices_state->is_enabled; +} + +static void machine_set_cxl(Object *obj, bool value, Error **errp) +{ + MachineState *ms = MACHINE(obj); + + ms->cxl_devices_state->is_enabled = value; +} + void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type) { QAPI_LIST_PREPEND(mc->allowed_dynamic_sysbus_devices, g_strdup(type)); @@ -903,6 +918,16 @@ static void machine_initfn(Object *obj) "Valid values are cpu, mem-ctrl"); } + if (mc->cxl_supported) { + Object *obj = OBJECT(ms); + + ms->cxl_devices_state = g_new0(CXLState, 1); + object_property_add_bool(obj, "cxl", machine_get_cxl, machine_set_cxl); + object_property_set_description(obj, "cxl", + "Set on/off to enable/disable " + "CXL instantiation"); + } + if (mc->cpu_index_to_instance_props && mc->get_default_cpu_node_id) { ms->numa_state = g_new0(NumaState, 1); object_property_add_bool(obj, "hmat", @@ -939,6 +964,7 @@ static void machine_finalize(Object *obj) g_free(ms->device_memory); g_free(ms->nvdimms_state); g_free(ms->numa_state); + g_free(ms->cxl_devices_state); } bool machine_usb(MachineState *machine) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 470dd7ddf4..90d52e7774 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -53,6 +53,7 @@ #include "sysemu/numa.h" #include "sysemu/reset.h" #include "hw/hyperv/vmbus-bridge.h" +#include "hw/cxl/cxl.h" /* Supported chipsets: */ #include "hw/southbridge/piix.h" @@ -1277,8 +1278,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, build_piix4_pci0_int(dsdt); } else { sb_scope = aml_scope("_SB"); + /* + * XXX: CXL spec calls this "CXL0", but that would require lots of + * changes throughout and so even for CXL enabled, we call it "PCI0" + */ dev = aml_device("PCI0"); - init_pci_acpi(dev, 0, PCIE); + init_pci_acpi(dev, 0, + machine->cxl_devices_state->is_enabled ? CXL : PCIE); aml_append(dev, aml_name_decl("_ADR", aml_int(0))); aml_append(sb_scope, dev); diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index edf2b0f061..970b299a69 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -688,6 +688,7 @@ static void microvm_class_init(ObjectClass *oc, void *data) mc->auto_enable_numa_with_memdev = false; mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE; mc->nvdimm_supported = false; + mc->cxl_supported = false; mc->default_ram_id = "microvm.ram"; /* Avoid relying too much on kernel components */ diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5d41809b37..7350eeea9c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1725,6 +1725,7 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) hc->unplug = pc_machine_device_unplug_cb; mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE; mc->nvdimm_supported = true; + mc->cxl_supported = true; mc->default_ram_id = "pc.ram"; object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size", diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 489cefcb81..b5ea497403 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4442,6 +4442,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("power9_v2.0"); mc->has_hotpluggable_cpus = true; mc->nvdimm_supported = true; + mc->cxl_supported = false; smc->resize_hpt_default = SPAPR_RESIZE_HPT_ENABLED; fwc->get_dev_path = spapr_get_fw_dev_path; nc->nmi_monitor_handler = spapr_nmi; @@ -4602,6 +4603,7 @@ static void spapr_machine_4_2_class_options(MachineClass *mc) smc->default_caps.caps[SPAPR_CAP_FWNMI] = SPAPR_CAP_OFF; smc->rma_limit = 16 * GiB; mc->nvdimm_supported = false; + mc->cxl_supported = false; } DEFINE_SPAPR_MACHINE(4_2, "4.2", false); diff --git a/include/hw/boards.h b/include/hw/boards.h index 17b1f3f0b9..808f73e134 100644 --- a/include/hw/boards.h +++ b/include/hw/boards.h @@ -206,6 +206,7 @@ struct MachineClass { bool ignore_boot_device_suffixes; bool smbus_no_migration_support; bool nvdimm_supported; + bool cxl_supported; bool numa_mem_supported; bool auto_enable_numa; const char *default_ram_id; @@ -292,6 +293,7 @@ struct MachineState { CPUArchIdList *possible_cpus; CpuTopology smp; struct NVDIMMState *nvdimms_state; + struct CXLState *cxl_devices_state; struct NumaState *numa_state; }; diff --git a/include/hw/cxl/cxl.h b/include/hw/cxl/cxl.h index 809ed7de60..6961e47076 100644 --- a/include/hw/cxl/cxl.h +++ b/include/hw/cxl/cxl.h @@ -22,5 +22,9 @@ #define CXL_HOST_BASE 0xD0000000 #define CXL_WINDOW_MAX 10 +typedef struct CXLState { + bool is_enabled; +} CXLState; + #endif From patchwork Tue Jan 5 16:53:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Widawsky X-Patchwork-Id: 1422593 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=intel.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4D9JwH5RP4z9sVq for ; Wed, 6 Jan 2021 04:12:47 +1100 (AEDT) Received: from localhost ([::1]:55146 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kwpsz-0006B6-O5 for incoming@patchwork.ozlabs.org; Tue, 05 Jan 2021 12:12:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:41054) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpbF-00007d-NC for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:25 -0500 Received: from mga18.intel.com ([134.134.136.126]:10374) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kwpb8-00016I-9k for qemu-devel@nongnu.org; Tue, 05 Jan 2021 11:54:25 -0500 IronPort-SDR: juQ0oZcSkcVoHgn678ne9Kkp3nbQkFtidSgxwCgfnVSoycHWOtMv5LNMhMK5vGVth8pNQ/WJBY yIaLGpT9AxIA== X-IronPort-AV: E=McAfee;i="6000,8403,9855"; a="164841153" X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="164841153" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:12 -0800 IronPort-SDR: +gO12oiaYGaQsoESvR0OtVzPkOSh5p19tV0GfExwLy9qarhQmVOZ3em0pxd89d25CfqXQpQ1lJ oUkdjEJtWF2w== X-IronPort-AV: E=Sophos;i="5.78,477,1599548400"; d="scan'208";a="346338105" Received: from tgeddam-mobl.amr.corp.intel.com (HELO bwidawsk-mobl5.local) ([10.252.140.57]) by orsmga003-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Jan 2021 08:54:08 -0800 From: Ben Widawsky To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 32/32] qtest/cxl: Add very basic sanity tests Date: Tue, 5 Jan 2021 08:53:23 -0800 Message-Id: <20210105165323.783725-33-ben.widawsky@intel.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210105165323.783725-1-ben.widawsky@intel.com> References: <20210105165323.783725-1-ben.widawsky@intel.com> MIME-Version: 1.0 Received-SPF: pass client-ip=134.134.136.126; envelope-from=ben.widawsky@intel.com; helo=mga18.intel.com X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Huth , Ben Widawsky , "Michael S. Tsirkin" , Vishal Verma , Chris Browy , =?utf-8?q?Philippe_Mathieu-Daud?= =?utf-8?q?=C3=A9?= , Jonathan Cameron , Prashant V Agarwal , Dan Williams Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Ben Widawsky --- tests/qtest/cxl-test.c | 93 +++++++++++++++++++++++++++++++++++++++++ tests/qtest/meson.build | 4 ++ 2 files changed, 97 insertions(+) create mode 100644 tests/qtest/cxl-test.c diff --git a/tests/qtest/cxl-test.c b/tests/qtest/cxl-test.c new file mode 100644 index 0000000000..00eca14faa --- /dev/null +++ b/tests/qtest/cxl-test.c @@ -0,0 +1,93 @@ +/* + * QTest testcase for CXL + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "libqtest-single.h" + +#define QEMU_PXB_CMD "-machine q35 -object memory-backend-file,id=cxl-mem1," \ + "share,mem-path=%s,size=512M " \ + "-device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52,uid=0," \ + "len-window-base=1,window-base[0]=0x4c0000000,memdev[0]=cxl-mem1" +#define QEMU_RP "-device cxl-rp,id=rp0,bus=cxl.0,addr=0.0,chassis=0,slot=0" + +#define QEMU_T3D "-device cxl-type3,bus=rp0,memdev=cxl-mem1,id=cxl-pmem0,size=256M" + +static void cxl_basic_hb(void) +{ + qtest_start("-machine q35,cxl"); + qtest_end(); +} + +static void cxl_basic_pxb(void) +{ + qtest_start("-machine q35 -device pxb-cxl,bus=pcie.0,uid=0"); + qtest_end(); +} + +static void cxl_pxb_with_window(void) +{ + GString *cmdline; + char template[] = "/tmp/cxl-test-XXXXXX"; + const char *tmpfs; + + tmpfs = mkdtemp(template); + + cmdline = g_string_new(NULL); + g_string_printf(cmdline, QEMU_PXB_CMD, tmpfs); + + qtest_start(cmdline->str); + qtest_end(); + + g_string_free(cmdline, TRUE); +} + +static void cxl_root_port(void) +{ + GString *cmdline; + char template[] = "/tmp/cxl-test-XXXXXX"; + const char *tmpfs; + + tmpfs = mkdtemp(template); + + cmdline = g_string_new(NULL); + g_string_printf(cmdline, QEMU_PXB_CMD " %s", tmpfs, QEMU_RP); + + qtest_start(cmdline->str); + qtest_end(); + + g_string_free(cmdline, TRUE); +} + +static void cxl_t3d(void) +{ + GString *cmdline; + char template[] = "/tmp/cxl-test-XXXXXX"; + const char *tmpfs; + + tmpfs = mkdtemp(template); + + cmdline = g_string_new(NULL); + g_string_printf(cmdline, QEMU_PXB_CMD " %s %s", tmpfs, QEMU_RP, QEMU_T3D); + + qtest_start(cmdline->str); + qtest_end(); + + g_string_free(cmdline, TRUE); +} + +int main(int argc, char **argv) +{ + g_test_init(&argc, &argv, NULL); + + qtest_add_func("/pci/cxl/basic_hostbridge", cxl_basic_hb); + qtest_add_func("/pci/cxl/basic_pxb", cxl_basic_pxb); + qtest_add_func("/pci/cxl/pxb_with_window", cxl_pxb_with_window); + qtest_add_func("/pci/cxl/root_port", cxl_root_port); + qtest_add_func("/pci/cxl/type3_device", cxl_t3d); + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 6a67c538be..6ab14fc79a 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -22,6 +22,9 @@ qtests_pci = \ (config_all_devices.has_key('CONFIG_VGA') ? ['display-vga-test'] : []) + \ (config_all_devices.has_key('CONFIG_IVSHMEM_DEVICE') ? ['ivshmem-test'] : []) +qtests_cxl = \ + (config_all_devices.has_key('CONFIG_CXL') ? ['cxl-test'] : []) + qtests_i386 = \ (slirp.found() ? ['pxe-test', 'test-netfilter'] : []) + \ (config_host.has_key('CONFIG_POSIX') ? ['test-filter-mirror'] : []) + \ @@ -47,6 +50,7 @@ qtests_i386 = \ (config_all_devices.has_key('CONFIG_TPM_TIS_ISA') ? ['tpm-tis-swtpm-test'] : []) + \ (config_all_devices.has_key('CONFIG_RTL8139_PCI') ? ['rtl8139-test'] : []) + \ qtests_pci + \ + qtests_cxl + \ ['fdc-test', 'ide-test', 'hd-geo-test',