From patchwork Tue Jun 25 11:27:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 167701 Delivered-To: patch@linaro.org Received: by 2002:ac9:6410:0:0:0:0:0 with SMTP id r16csp4869301ock; Tue, 25 Jun 2019 04:29:18 -0700 (PDT) X-Google-Smtp-Source: APXvYqwMraljACwUSEjodjboZSbWQTgGpV4luWatkNfhGjUS60RuLjXiwxXS1gfGQGfKJqRYr+DR X-Received: by 2002:a17:906:5255:: with SMTP id y21mr61515592ejm.253.1561462158773; Tue, 25 Jun 2019 04:29:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561462158; cv=none; d=google.com; s=arc-20160816; b=utZYBQDg1JwikUnxGZQxtdW0krmNg6txLxYpkoEB8PT+oyjYzpy+rb9kVexm79IuNB m/BeYIqOJVyKF3Nun6VpjCTJ8OPkM8Y6jOgi8Wxlpc6Xv58nH0NHfIopVR1eIUBLT02B m9HEgDNLvK77x/JwFgiG8MpHSAUKx4JeE/t9C57nmbx6h/R/VviLv31TcnV0wTF3mR8d cAN+K2ruHLd44whGPgXUROk+03MXpnvf4dMjtq2jy/EpSiR6+9q9+R7Dd3i+y2o4TgGX jzvt1cNMQV02UAQMpBodDnj6UdxTIVTrJ9AkjMfN013SrpbLeDHAt5CpAjEfRcGCL/AA iFXw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from; bh=AX0pOlAnoRhNCilNvemgiHPoqZSbF6HHLGMGzYBjws4=; b=zmqJd2KNJGRAYp/hFXK3LWKU8D6kvEUz/KfD3YQpxIP9s5ZZBUsxGyWX4SwdNbIPsc R4fsSc8/tzz4lPjgBLsrzYZsrgEpfKJixDXbUENVtXe1nscdmQIzp75P05mw4JpeejOo Sq9nOs9uZTqXb94jvOyeIrLoNYsfPunsatGXOo50tuKjvufuTjXWCcc5Zsvyyod4Ar7j XGeCOImJ0lwcaISrac67r7DyhXq7//V+7K8h+QQmns6OX+H/y1k7wzMvMR9LewGzifHO CyRN6c1IvplpwWD7m9O0FqW0/PHiaZt7W8lv+LJ0aeeOFFtgtdn0rz9CGfiv28r8DSSb 8cJA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id r5si158361edm.368.2019.06.25.04.29.18 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 04:29:18 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:58968 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjdV-0007Dv-Oy for patch@linaro.org; Tue, 25 Jun 2019 07:29:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53618) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjd8-0006qj-TL for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:28:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfjd7-00046K-Tn for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:28:54 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:2244 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfjd5-0003q0-DT; Tue, 25 Jun 2019 07:28:51 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 29B65258D9C69BBF49A5; Tue, 25 Jun 2019 19:28:43 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.439.0; Tue, 25 Jun 2019 19:28:32 +0800 From: Jonathan Cameron To: QEMU Developers Date: Tue, 25 Jun 2019 19:27:46 +0800 Message-ID: <20190625112752.83188-2-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> References: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [RFC PATCH 1/7] Temp: Add the PCI_EXT_ID_DVSEC definition to the qemu pci_regs.h copy. 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: Peter Maydell , jcm@redhat.com, linuxarm@huawei.com, Auger Eric , qemu-arm , Jonathan Cameron Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" 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 --- include/standard-headers/linux/pci_regs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h index 27164769d1..224b52e62b 100644 --- a/include/standard-headers/linux/pci_regs.h +++ b/include/standard-headers/linux/pci_regs.h @@ -709,7 +709,8 @@ #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_MAX PCI_EXT_CAP_ID_PTM +#define PCI_EXT_CAP_ID_DVSEC 0x23 /* Designated Vendor-Specific */ +#define PCI_EXT_CAP_ID_MAX PCI_EXT_CAP_ID_DVSEC #define PCI_EXT_CAP_DSN_SIZEOF 12 #define PCI_EXT_CAP_MCAST_ENDPOINT_SIZEOF 40 From patchwork Tue Jun 25 11:27:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 167702 Delivered-To: patch@linaro.org Received: by 2002:ac9:6410:0:0:0:0:0 with SMTP id r16csp4871491ock; Tue, 25 Jun 2019 04:31:32 -0700 (PDT) X-Google-Smtp-Source: APXvYqzH6JVXyDjpeqMpCUyhBBdWyfugfBA8m+yYNvC53JCh4XYYv/IA3655TA3Etl6lcWnR7SSE X-Received: by 2002:a17:906:82c4:: with SMTP id a4mr14296796ejy.178.1561462292356; Tue, 25 Jun 2019 04:31:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561462292; cv=none; d=google.com; s=arc-20160816; b=Ywp2vLARHHcFokgIqA8w6aXYGEv4XON/fcf8Ih4MdQdjZNk2GZa4C+DBm9tFt9CpZM jbPqZ3N6Fg5inzeM/K+X60alQgF9OxxIQGxv2EymV1+of5IJqlqirwjHatim9R/bSgoC aBihmVvISN49e1VXn7XhMdHGTTN0xTH16hLc3vM/PTFbVd8s9eMApbeUPC7cjc3qKoD4 HvDabauCrEwUOjTTUw01YoIq+W+F4znhKHqTdLI6GE/mVk2F9IrBC6oQXYAdVvfoEdVz 89a40jnePY7rciER8SDiQBmY/SA5HxmvHnzaUZ5p+TUVLIy+2F4ertpODttd7EJQAHCD NMaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from; bh=qMcxO4raslvVJG6txQX0mMT0wpxkNdyDdLmdGkGclPM=; b=0yDxgmeCvw62AqIWmM/6tha1yshxlND7busqwuT/eBTSxJwudVoM6Dp+OuZt7i1gA/ SFEO7KtdKZ2vAWzMwVFCyys9Kgz7JKbkvRFqJXuAWKG4EDVQMg2LuHNPsLb5U9SL2AU+ wfhdWzzqSfwImE5Hgna8UdCyDOzomnLKXnKca7/o3YUJ1yGMk4Dzk44yMVMeUngpWQnn 3OD0tMT1i9o8veGgljF6JtHqBXnUxBswI746sws9Q9Lcw6Ri5d9SYlyRGv8fiebd70Km yWblNISp7mz+mlsWdcOwt0juPCjSnlMxrJ3lLfwgu3nGhd/l2Sc3w/9P9Pach977CmAA 1xZg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id b49si225313edb.204.2019.06.25.04.31.30 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 04:31:32 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:58988 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjfd-0001tr-8r for patch@linaro.org; Tue, 25 Jun 2019 07:31:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53616) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjd8-0006qi-PN for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:28:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfjd7-000469-SE for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:28:54 -0400 Received: from szxga05-in.huawei.com ([45.249.212.191]:2245 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfjd5-0003pz-DL; Tue, 25 Jun 2019 07:28:51 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 24C6874FDD6BAC980AD9; Tue, 25 Jun 2019 19:28:43 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.439.0; Tue, 25 Jun 2019 19:28:34 +0800 From: Jonathan Cameron To: QEMU Developers Date: Tue, 25 Jun 2019 19:27:47 +0800 Message-ID: <20190625112752.83188-3-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> References: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [RFC PATCH 2/7] pci: Add Huawei vendor ID and Huawei Emulated CCIX Device IDs. 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: Peter Maydell , jcm@redhat.com, linuxarm@huawei.com, Auger Eric , qemu-arm , Jonathan Cameron Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" These device IDs have been allocated for emulated only devices, giving us more flexibility than would be possible by emulating real devices. They will be used for the CCIX PCIe configuration space emulation modules that follow. Signed-off-by: Jonathan Cameron --- include/hw/pci/pci_ids.h | 5 +++++ 1 file changed, 5 insertions(+) -- 2.20.1 diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index 0abe27a53a..f49be07328 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -220,6 +220,11 @@ #define PCI_VENDOR_ID_FREESCALE 0x1957 #define PCI_DEVICE_ID_MPC8533E 0x0030 +#define PCI_VENDOR_ID_HUAWEI 0x19E5 +#define PCI_DEVICE_ID_HUAWEI_CCIX_UP 0xA260 +#define PCI_DEVICE_ID_HUAWEI_CCIX_DOWN 0xA261 +#define PCI_DEVICE_ID_HUAWEI_CCIX_EP 0xA262 + #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82378 0x0484 #define PCI_DEVICE_ID_INTEL_82441 0x1237 From patchwork Tue Jun 25 11:27:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 167710 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp5435225ilk; Tue, 25 Jun 2019 04:36:06 -0700 (PDT) X-Google-Smtp-Source: APXvYqzbR/BknibJnAkZLvVoQ8oRZmaIgpAHTekIlXRa0x6eBAQvB7+M5CrcaW87ma0FnDxF9mQX X-Received: by 2002:a17:906:3e86:: with SMTP id a6mr107217228ejj.254.1561462566575; Tue, 25 Jun 2019 04:36:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561462566; cv=none; d=google.com; s=arc-20160816; b=xfR7co5pyTi8eoMRO+AgNf1fvVhZxmn7Z6lAVdDO4EqRKUUsY2yQsMbhhrKVD7Gt7q GdjPmL4LM/u4HAsNQUFzKS9PhIASxXbi9OFd3emEbCUF82ZvCgkb9XTEaAuHQUTAYN2d kHZnoPvri58g7Ufpqw2JqYqAKoCnn8YO2QUT56W3Yq6CJv8Y5Z+VZR+TT+kCTKCvBeeb Id20L5KboSUXiEPoPjPG+YZq5nVjukuVaIgdVZQcAkz9Sa/lXeOwRZioRqfxlU4RQuh6 L2ic2r6x97euoqdVPMxPO8/ketAibDfA/94Vgi/Aze8cPkI5CvzMeyLk4jWIF8DyMoUI 9/vw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from; bh=kat0ECfLEM6bc3fE5drNu9U1gUpmMvghszAQ5qD54Ng=; b=EubQhqv+q8ScU4YF6khpZbPf8r7+JNSEco9HX/+Pv8e9EYY0y26PqArdQ37jKTGJ8D NfHFycjIVWZFPGeXdTslHR8g/nIcWNpJSuFnZFY2+a8HRkqJbx0rVDMRFoqHTMNSZmC6 rlXQw16Dlh7FOHY8wPCIqDRiPgiVFy0V7C8vX2hRzAirrp1xyWUARo8AtbVwc2hWmo1j Q6w49rYroZg33otDYL9BLatZb5RZ7BBeX2Wn6UU6NnBBg3rtg3nsfYqJmyJjoNUsIsaq Gk1lzFirxKeFiRSeYViAY+HlQPmR5BXQgQSGIEb1agUPUOyhZ1X/NICFNLFT3qX1QTw2 a1+A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id z39si201962edd.331.2019.06.25.04.36.06 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 04:36:06 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:59038 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjk5-0006Ax-Cv for patch@linaro.org; Tue, 25 Jun 2019 07:36:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53826) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjdR-0007Vo-2R for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfjdM-0004Oo-66 for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:12 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:52888 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfjd5-0003xV-KU; Tue, 25 Jun 2019 07:28:57 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 4702790BD5F52C0CB68A; Tue, 25 Jun 2019 19:28:48 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.439.0; Tue, 25 Jun 2019 19:28:37 +0800 From: Jonathan Cameron To: QEMU Developers Date: Tue, 25 Jun 2019 19:27:48 +0800 Message-ID: <20190625112752.83188-4-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> References: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 Subject: [Qemu-devel] [RFC PATCH 3/7] pci: CCIX config space emulation library. 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: Peter Maydell , jcm@redhat.com, linuxarm@huawei.com, Auger Eric , qemu-arm , Jonathan Cameron Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" The nature of the complex topologies supported by CCIX means that it will be sometime before it is possible to construct many of the interesting cases in hardware, and it will be extermely hard to exercise all of the combinations whilst developing firwmare and drivers. To that end, the intent of this library and following device emulations is to allow the construction of complex CCIX toplogies via their overlaying on PCIe. The CCIX topologies are configured through CCIX specific PCIe DVSEC capabillity and control structures. A typical mesh capable CCIX device will overlay onto N upstream PCIe switch ports, M downstream PCIe switch ports, function 0 EPs which are not PCIe switch upstream ports, P functions 1+ which have additional CCIX protocol elements described and Q functions 1+ which respresent acceleration functions, with no CCIX protocol elements (these look to be normal PCIe functions so are not covered by this patch set). Signed-off-by: Jonathan Cameron --- hw/pci/Kconfig | 3 + hw/pci/Makefile.objs | 1 + hw/pci/ccix_lib.c | 1299 ++++++++++++++++++++++++++++++++++++++ include/hw/misc/ccix.h | 28 + include/hw/pci/pci_ids.h | 2 + 5 files changed, 1333 insertions(+) -- 2.20.1 diff --git a/hw/pci/Kconfig b/hw/pci/Kconfig index 77f8b005ff..605f8dcd18 100644 --- a/hw/pci/Kconfig +++ b/hw/pci/Kconfig @@ -13,3 +13,6 @@ config MSI_NONBROKEN # or support it and have a good implementation. See commit # 47d2b0f33c664533b8dbd5cb17faa8e6a01afe1f. bool + +config CCIX_LIB + bool diff --git a/hw/pci/Makefile.objs b/hw/pci/Makefile.objs index 8642fab622..efc17ff4dd 100644 --- a/hw/pci/Makefile.objs +++ b/hw/pci/Makefile.objs @@ -13,3 +13,4 @@ common-obj-$(CONFIG_PCI) += ccix_per.o common-obj-$(call lnot,$(CONFIG_PCI)) += pci-stub.o common-obj-$(CONFIG_ALL) += pci-stub.o +common-obj-$(CONFIG_CCIX_LIB) += ccix_lib.o diff --git a/hw/pci/ccix_lib.c b/hw/pci/ccix_lib.c new file mode 100644 index 0000000000..544f90077d --- /dev/null +++ b/hw/pci/ccix_lib.c @@ -0,0 +1,1299 @@ +/* + * CCIX configuration space creation library + * + * Copyright (c) 2019 Huawei + * Author: Jonathan Cameron + * + * Portions copied from pci-testdev.c + * Copyright (c) 2012 Red Hat Inc. + * Author: Michael S. Tsirkin + * + * 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 . + */ +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/pci/pci.h" +#include "qemu/event_notifier.h" +#include "sysemu/kvm.h" +#include "hw/misc/ccix.h" + +/* Leave space for the SR-IDM and SW portal if enabled */ +#define CCIX_COMMON_CAP_MAX_SIZE 10 * sizeof(uint32_t) + +#define CM_CAP_DW1_MULTIPORT_CAP_OFF 0 +#define CM_CAP_DW1_MULTIPORT_CAP_M 0x00000007 +#define CM_CAP_DW1_VERSION_CAP_OFF 22 +#define CM_CAP_DW1_VERSION_CAP_M 0x00C00000 +#define CM_CAP_DW1_DEVID_OFF 24 +#define CM_CAP_DW1_DEVID_M 0xFF000000 + +#define CM_CAP_DW2_DISC_READY_CAP_OFF 0 +#define CM_CAP_DW2_PART_CS_CAP_OFF 1 +#define CM_CAP_DW2_PORT_AG_CAP_OFF 2 +#define CM_CAP_DW2_CL_SIZE_CAP_OFF 3 +#define CM_CAP_DW2_ADDR_W_CAP_OFF 4 +#define CM_CAP_DW2_MH_CAP_OFF 7 +#define CM_CAP_DW2_SW_PORT_CAP_OFF 8 +#define CM_CAP_DW2_SAM_ALIGN_CAP_OFF 9 +#define CM_CAP_DW2_READY_TIME_VAL_OFF 19 +#define CM_CAP_DW2_READY_TIME_SCALE_OFF 28 + +/* COMMON_CAP III is reserved */ +#define CM_CAP_DW4_DEV_ERR_LOG_OFFSET_OFF 20 +#define CM_CAP_DW5_IDM_OFFSET_OFF 20 +#define CM_CAP_DW6_RSAM_SIZE_OFF 0 +#define CM_CAP_DW6_RSAM_OFFSET_OFF 20 +#define CM_CAP_DW7_HSAM_SIZE_OFF 0 +#define CM_CAP_DW7_HSAM_OFFSET_OFF 20 +#define CM_CAP_DW8_SR_OFFSET_OFF 20 +#define CM_CAP_DW9_SW_PORTAL_OFF 0 + +#define CM_CTL_DW1_DEVICE_EN_OFF 0 +#define CM_CTL_DW1_PRIMARY_PORT_EN_OFF 1 +#define CM_CTL_DW1_MESH_EN_OFF 2 +#define CM_CTL_DW1_PORT_AG_EN_OFF 4 +#define CM_CTL_DW1_IDM_TABLE_VALID_OFF 5 +#define CM_CTL_DW1_RSAM_TABLE_VALID_OFF 6 +#define CM_CTL_DW1_HSAM_TABLE_VALID_OFF 7 +#define CM_CTL_DW1_SW_PORT_ENABLE_OFF 8 +#define CM_CTL_DW1_ERR_AGENT_ID_OFF 16 +#define CM_CTL_DW1_ERR_AGENT_ID_M 0x003F0000 +#define CM_CTL_DW1_DEVID_OFF 24 +#define CM_CTL_DW1_DEVID_M 0xFF000000 + +#define CM_CTL_DW2_PART_CS_EN_OFF 1 +#define CM_CTL_DW2_CL_SIZE_EN_OFF 3 +#define CM_CTL_DW2_ADDR_W_EN_OFF 4 +#define CM_CTL_DW2_ADDR_W_EN_M 0x00000070 + +#define CCIX_PORT_CAP_SIZE 5 * sizeof(uint32_t) + +#define PT_CAP_DW1_DISC_READY_OFF 0 +#define PT_CAP_DW1_OPT_HEADER_OFF 1 +#define PT_CAP_DW1_P2P_FORWARDING_OFF 5 +#define PT_CAP_DW1_LINKS_OFF 7 +#define PT_CAP_DW1_LINKS_M 0x00001F80 +#define PT_CAP_DW1_PSAM_ENTRIES_OFF 13 +#define PT_CAP_DW1_PSAM_ENTRIES_M 0x0007E000 +#define PT_CAP_DW1_PORTID_OFF 27 +#define PT_CAP_DW1_PORTID_M 0xF8000000 + +/* not including PSAM */ +#define CCIX_PORT_CTL_SIZE 5 * sizeof(uint32_t) + +#define PT_CTL_DW1_PORT_EN_OFF 0 +#define PT_CTL_DW1_OPT_HEADER_EN_OFF 1 +#define PT_CTL_DW1_LINKS_EN_OFF 7 +#define PT_CTL_DW1_LINKS_EN_M 0x00001F80 +#define PT_CTL_DW1_PSAM_ENTRIES_EN_OFF 13 +#define PT_CTL_DW1_PSAM_ENTRIES_EN_M 0x0007E000 + +#define CCIX_LINK_CAP_SIZE 6 * sizeof(uint32_t) + +#define LK_CAP_DW1_DISC_READY_OFF 0 +#define LK_CAP_DW1_CREDIT_TYPE_OFF 1 +#define LK_CAP_DW1_MESSAGE_PACKING_OFF 2 +#define LK_CAP_DW1_NOCOMPACK_OFF 6 +#define LK_CAP_DW1_MAX_PKT_SIZE_OFF 7 +#define LK_CAP_DW1_MAX_PKT_SIZE_M 0x00000038 +#define LK_CAP_DW2_MAX_MEM_REQ_SEND_OFF 0 +#define LK_CAP_DW2_MAX_MEM_REQ_SEND_M 0x000003FF +#define LK_CAP_DW2_MAX_SNP_REQ_SEND_OFF 10 +#define LK_CAP_DW2_MAX_SNP_REQ_SEND_M 0x000FFC00 +#define LK_CAP_DW2_MAX_DAT_REQ_SEND_OFF 20 +#define LK_CAP_DW2_MAX_DAT_REQ_SEND_M 0x3FF00000 +#define LK_CAP_DW3_MAX_MEM_REQ_RECV_OFF 0 +#define LK_CAP_DW3_MAX_MEM_REQ_RECV_M 0x000003FF +#define LK_CAP_DW3_MAX_SNP_REQ_RECV_OFF 10 +#define LK_CAP_DW3_MAX_SNP_REQ_RECV_M 0x000FFC00 +#define LK_CAP_DW3_MAX_DAT_REQ_RECV_OFF 20 +#define LK_CAP_DW3_MAX_DAT_REQ_RECV_M 0x3FF00000 +#define LK_CAP_DW4_MAX_MISC_REQ_SEND_CAP_OFF 0 +#define LK_CAP_DW4_MAX_MISC_REQ_RECV_CAP_OFF 10 + +/* Not including per link */ +#define CCIX_LINK_CTL_SIZE 1 * sizeof(uint32_t) +/* Not including BcastFwdCntlVctr, including Tranport ID map */ +#define CCIX_LINK_CTL_PER_LINK_SIZE (6 + 1) * sizeof(uint32_t) + +/* Per link controls */ +#define LK_CTL_DW1_LINK_EN_OFF 0 +#define LK_CTL_DW1_CREDIT_EN_OFF 1 +#define LK_CTL_DW1_MESSAGE_PACKING_EN_OFF 2 +#define LK_CTL_DW1_NO_COMP_ACK_EN_OFF 6 +#define LK_CTL_DW1_MAX_PKT_SIZE_EN_OFF 7 +#define LK_CTL_DW1_MAX_PKT_SIZE_EN_M 0x00000380 +#define LK_CTL_DW1_LINK_ENT_ADDR_TYPE_OFF 10 + +#define CCIX_RA_CAP_SIZE 3 * sizeof(uint32_t) + +#define RA_CAP_DW1_RA_DISC_RDY_STAT_OFF 0 +#define RA_CAP_DW1_RA_CACHE_FLUSH_TIME_VALUE_OFF 19 +#define RA_CAP_DW1_RA_CACHE_FLUSH_TIME_VALUE_M 0x0FF80000 +#define RA_CAP_DW1_RA_CACHE_FLUSH_TIME_SCALE_OFF 28 +#define RA_CAP_DW1_RA_CACHE_FLUSH_TIME_SCALE_M 0x70000000 +#define RA_CAP_DW1_RA_CACHE_FLUSH_STA_OFF 31 + +#define RA_CAP_DW2_RA_ERROR_LOG_OFFSET_OFF 20 + +#define CCIX_RA_CTL_SIZE 4 * sizeof(uint32_t) + +#define RA_CTL_DW1_EN_OFF 0 +#define RA_CTL_DW1_SNOOP_RESP_EN_OFF 1 +#define RA_CTL_DW1_CACHE_FLUSH_EN_OFF 14 +#define RA_CTL_DW1_CACHE_EN_OFF 15 +#define RA_CTL_DW1_RAID_OFF 26 +#define RA_CTL_DW1_RAID_M 0xFC000000 + +/* Excluding pool entries */ +#define CCIX_HA_CAP_SIZE 3 * sizeof(uint32_t) + +#define HA_CAP_DW1_HA_DISC_RD_STAT_OFF 0 +#define HA_CAP_DW1_NUM_HA_IDS_OFF 1 +#define HA_CAP_DW1_HA_MEM_POOL_CAP_OFF 8 +#define HA_CAP_DW1_HA_QACK_OFF 14 +#define HA_CAP_DW1_HA_HW_QACK_CAP_OFF 15 +#define HA_CAP_DW1_HA_MEM_EXP_CAP_OFF 16 +#define HA_CAP_DW1_HA_EVICT_HINT_CAP_OFF 17 +#define HA_CAP_DW1_HA_WRITE_EVICT_FULL_HIT_CAP_OFF 18 +#define HA_CAP_DW1_MEM_POOL_READY_TIME_VALUE_OFF 19 +#define HA_CAP_DW1_MEM_POOL_READY_TIME_VALUE_M 0x0FF80000 +#define HA_CAP_DW1_MEM_POOL_READY_TIME_SCALE_OFF 28 +#define HA_CAP_DW1_MEM_POOL_READY_TIME_SCALE_M 0x70000000 +#define HA_CAP_DW1_MEM_POOL_READY_STA_OFF 31 + +#define HA_CAP_DW2_HA_ERROR_LOG_OFF 20 + +#define MEM_POOL_CAP_DW1_READY_STA_OFF 0 +#define MEM_POOL_CAP_DW1_GEN_MEM_TYPE_OFF 1 +enum { + mem_type_other = 0, + mem_type_expan, + mem_type_hole, + mem_type_rom, + mem_type_volatile, + mem_type_non_volatile, + mem_type_device, +}; + +#define MEM_POOL_CAP_DW1_SPEC_MEM_TYPE_OFF 4 +enum { + mem_spec_other = 0, + mem_spec_sram, + mem_spec_ddr, + mem_spec_nvdimm_f, + mem_spec_nvdimm_n, + mem_spec_hbm, + mem_spec_flash, +}; +#define MEM_POOL_CAP_DW1_ADDR_CAP_OFF 7 +#define MEM_POOL_CAP_DW1_MEM_ATTR_OFF 8 +#define MEM_POOL_CAP_DW1_MEM_ATTR_DEV 0x0 +#define MEM_POOL_CAP_DW1_MEM_ATTR_NONCACHE 0x4 +#define MEM_POOL_CAP_DW1_MEM_ATTR_NORMAL 0x5 +#define MEM_POOL_CAP_DW1_MEM_EXT_ATTR_OFF 11 +#define MEM_POOL_CAP_DW1_MEM_EXT_ATTR_NONE 0x0 +#define MEM_POOL_CAP_DW1_MEM_EXT_ATTR_PRIVATE 0x1 +#define MEM_POOL_CAP_DW1_MEM_POOL_SIZE_L_CAP_OFF 16 + +#define MEM_POOL_CAP_DW2_MEM_POOL_SIZE_H_CAP_OFF 0 + +/* Not including HAID or HBAT entries */ +#define CCIX_HA_CTL_SIZE 6 * sizeof(uint32_t) +#define CCIX_HAID_ENTRY_SIZE 1 * sizeof(uint32_t) +#define CCIX_BAT_ENTRY_SIZE 2 * sizeof(uint32_t) + +#define CCIX_POOL_CAP_SIZE 2 * sizeof(uint32_t) +#define CCIX_GUID_SIZE 5 * sizeof(uint32_t) +#define CCIX_SAM_ENTRY_SIZE 3 * sizeof(uint32_t) +#define CCIX_GUID_DW0 0xC3CB993B +#define CCIX_GUID_DW1 0x02C4436F +#define CCIX_GUID_DW2 0x9B68D271 +#define CCIX_GUID_DW3 0xF2E8CA31 +#define CCIX_GUID_DW4_VERSION_OFF 0 + +/* HACK - What is the best way to do this in Qemu? */ +CCIXState *CCIXFuncs[256]; + +typedef void (*am_cb_t)(PCIDevice *d, CCIXState *s, uint16_t offset, + uint16_t cap_start_offset, uint32_t val); +struct am { + uint16_t offset; + uint16_t cap_start_offset; + am_cb_t am_cb; +}; + +static int am_cmp(const void *ap, const void *bp) +{ + const uint16_t *a; + const uint16_t *b; + + a = ap; + b = bp; + + return *a - *b; +} + +void initialize_ccixstate(CCIXState *s, PCIDevice *d) +{ + s->am_tree = g_tree_new(am_cmp); + s->pci_dev = d; +} + +static void am_table_add(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start_offset, am_cb_t cb) +{ + struct am *entry = g_malloc0(sizeof *entry); + + if (entry) { + entry->offset = offset; + entry->cap_start_offset = cap_start_offset; + entry->am_cb = cb; + g_tree_insert(s->am_tree, &entry->offset, entry); + } +} + +void ccix_write_config(PCIDevice *pci_dev, CCIXState *s, uint32_t addr, uint32_t val_in, int l) +{ + uint64_t key = addr; + struct am *entry = g_tree_lookup(s->am_tree, &key); + + if (entry && entry->offset == addr) + entry->am_cb(pci_dev, s, addr, entry->cap_start_offset, val_in); +} + +#define CCIX_COMP_ID_GENERAL 0x0000 +#define CCIX_COMP_ID_TDL_DVSEC 0x0001 +#define CCIX_COMP_ID_PRL_DVSEC 0x0002 +#define CCIX_COMP_ID_PRL_COMMON 0x0003 +#define CCIX_COMP_ID_PRL_PORT 0x0004 +#define CCIX_COMP_ID_PRL_LINK 0x0005 +#define CCIX_COMP_ID_HA 0x0006 +#define CCIX_COMP_ID_RA 0x0008 +#define CCIX_COMP_ID_SA 0x000A + +#define CCIX_DVSEC_CAP_POS_OFFSET 0x0C +#define CCIX_DVSEC_CTR_POS_OFFSET 0x10 + +static void ccix_dvsec_fill_dvsec_header(PCIDevice *pci_dev, uint16_t offset, + uint16_t cap_size, + uint16_t cap_offset, + uint16_t control_size, + uint16_t control_offset) +{ + uint32_t *dword_addr; + + dword_addr = (uint32_t *)(pci_dev->config + offset + + CCIX_DVSEC_CAP_POS_OFFSET); + *dword_addr = cap_size | (cap_offset << 20); + dword_addr = (uint32_t *)(pci_dev->config + offset + + CCIX_DVSEC_CTR_POS_OFFSET); + *dword_addr = control_size | (control_offset << 20); +} + +static void ccix_fill_cap_header(PCIDevice *pci_dev, uint16_t cap_offset, + uint16_t ccix_comp, uint16_t next_offset) +{ + uint8_t ver = 1; + uint32_t *dword_addr; + + dword_addr = (uint32_t *)(pci_dev->config + cap_offset); + *dword_addr = ccix_comp | (ver << 16) | (next_offset << 20); +} + +static void ra_ctl_dw1_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t cur_val, new_val = 0; + bool ra_en_cur, ra_en_req; + uint32_t capval; + bool ra_snoop_resp_en_cur, ra_snoop_resp_en_req; + bool ra_cache_flush_en_cur, ra_cache_flush_en_req; + bool ra_cache_en_cur, ra_cache_en_req; + uint8_t raid_cur, raid_req; + + cur_val = pci_get_long(pci_dev->config + offset); + ra_en_cur = cur_val & (1 << RA_CTL_DW1_EN_OFF); + ra_en_req = req_val & (1 << RA_CTL_DW1_EN_OFF); + + if (ra_en_cur != ra_en_req) + printf("Changing RA Enable to %d\n", ra_en_req); + + if (ra_en_req) + new_val = (1 << RA_CTL_DW1_EN_OFF); + + ra_snoop_resp_en_cur = cur_val & (1 << RA_CTL_DW1_SNOOP_RESP_EN_OFF); + ra_snoop_resp_en_req = req_val & (1 << RA_CTL_DW1_SNOOP_RESP_EN_OFF); + + if (ra_snoop_resp_en_cur != ra_snoop_resp_en_req) + printf("Changing RA Snoop REsp Enabled to %d\n", + ra_snoop_resp_en_req); + + if (ra_snoop_resp_en_req) + new_val |= (1 << RA_CTL_DW1_SNOOP_RESP_EN_OFF); + + ra_cache_flush_en_cur = cur_val & (1 << RA_CTL_DW1_CACHE_FLUSH_EN_OFF); + ra_cache_flush_en_req = req_val & (1 << RA_CTL_DW1_CACHE_FLUSH_EN_OFF); + if (ra_cache_flush_en_cur != ra_cache_flush_en_req) { + printf("Enabling or disabling a cache flush %d\n", + ra_cache_flush_en_req); + + //Make the cache flush status update instantaneous for now + capval = pci_get_long(pci_dev->config + cap_start + 0x4); + if (ra_cache_flush_en_req) + capval |= (1 << RA_CAP_DW1_RA_CACHE_FLUSH_STA_OFF); + else + capval &= ~ (1 << RA_CAP_DW1_RA_CACHE_FLUSH_STA_OFF); + pci_set_long(pci_dev->config + cap_start + 0x4, capval); + } + if (ra_cache_flush_en_req) + new_val |= (1 << RA_CTL_DW1_CACHE_FLUSH_EN_OFF); + + ra_cache_en_cur = cur_val & (1 << RA_CTL_DW1_CACHE_EN_OFF); + ra_cache_en_req = req_val & (1 << RA_CTL_DW1_CACHE_EN_OFF); + if (ra_cache_en_cur != ra_cache_en_req) + printf("Enabling of disabling the RA cache %d\n", ra_cache_en_req); + + if (ra_cache_en_req) + new_val |= (1 << RA_CTL_DW1_CACHE_EN_OFF); + + raid_cur = (cur_val & RA_CTL_DW1_RAID_M) >> RA_CTL_DW1_RAID_OFF; + raid_req = (req_val & RA_CTL_DW1_RAID_M) >> RA_CTL_DW1_RAID_OFF; + if (raid_cur != raid_req) + printf("RA ID changing from %u to %u\n", raid_cur, raid_req); + + new_val |= (raid_req << RA_CTL_DW1_RAID_OFF) & RA_CTL_DW1_RAID_M; + + pci_set_long(pci_dev->config + offset, new_val); +} + + +static void comncntl1_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t cur_val, new_val = 0; + bool dev_en_req, dev_en_cur; + bool pp_en_req, pp_en_cur; + bool id_val_req, id_val_cur; + bool rsam_val_req, rsam_val_cur; + uint8_t eaid_req, eaid_cur; + uint8_t devid_req, devid_cur; + int i; + uint32_t capval; + + cur_val = pci_get_long(pci_dev->config + offset); + + dev_en_req = req_val & (1 << CM_CTL_DW1_DEVICE_EN_OFF); + dev_en_cur = cur_val & (1 << CM_CTL_DW1_DEVICE_EN_OFF); + if (dev_en_req != dev_en_cur) { + printf("Dev enable changing to %d\n", dev_en_req); + /* Now I need to set it on all devices */ + if (s->ccix_dev_name) + for (i = 0; i < sizeof(CCIXFuncs)/sizeof(*CCIXFuncs); i++) { + if (!CCIXFuncs[i] || !CCIXFuncs[i]->ccix_dev_name) + continue; + if (CCIXFuncs[i] != s && !strcmp(CCIXFuncs[i]->ccix_dev_name, s->ccix_dev_name)) { + pci_set_long(CCIXFuncs[i]->pci_dev->config + CCIXFuncs[i]->enable_offset, + pci_get_word(CCIXFuncs[i]->pci_dev->config + CCIXFuncs[i]->enable_offset) | 0x1); + } + } + } + if (dev_en_req) + new_val |= (1 << CM_CTL_DW1_DEVICE_EN_OFF); + + pp_en_req = req_val & (1 << CM_CTL_DW1_PRIMARY_PORT_EN_OFF); + pp_en_cur = cur_val & (1 << CM_CTL_DW1_PRIMARY_PORT_EN_OFF); + if (pp_en_req != pp_en_cur) + printf("Primary port enable changing to %d\n", pp_en_req); + if (pp_en_req) + new_val |= (1 << CM_CTL_DW1_PRIMARY_PORT_EN_OFF); + /* NOT DOING MESH ENABLE FOR NOW */ + /* NOT DOING PORT AG FOR NOW */ + + id_val_req = req_val & (1 << CM_CTL_DW1_IDM_TABLE_VALID_OFF); + id_val_cur = cur_val & (1 << CM_CTL_DW1_IDM_TABLE_VALID_OFF); + if (id_val_req != id_val_cur) + printf("Validity of IDM changing to %d\n", id_val_req); + if (id_val_req) + new_val |= (1 << CM_CTL_DW1_IDM_TABLE_VALID_OFF); + + rsam_val_req = req_val & (1 << CM_CTL_DW1_RSAM_TABLE_VALID_OFF); + rsam_val_cur = cur_val & (1 << CM_CTL_DW1_RSAM_TABLE_VALID_OFF); + if (rsam_val_req != rsam_val_cur) + printf("RSAM valid changing to %d\n", rsam_val_req); + if (rsam_val_req) + new_val |= (1 << CM_CTL_DW1_RSAM_TABLE_VALID_OFF); + /* NOT DOING HSAM FOR NOW */ + /* NOT DOING SW SERVICES PORTAL FOR NOW */ + + eaid_req = (req_val & CM_CTL_DW1_ERR_AGENT_ID_M) >> + CM_CTL_DW1_ERR_AGENT_ID_OFF; + eaid_cur = (cur_val & CM_CTL_DW1_ERR_AGENT_ID_M) >> + CM_CTL_DW1_ERR_AGENT_ID_OFF; + if (eaid_req != eaid_cur) + printf("EAID for device changing from %d to %d\n", + eaid_cur, eaid_req); + new_val |= eaid_req << CM_CTL_DW1_ERR_AGENT_ID_OFF; + + devid_req = (req_val & CM_CTL_DW1_DEVID_M) >> CM_CTL_DW1_DEVID_OFF; + devid_cur = (cur_val & CM_CTL_DW1_DEVID_M) >> CM_CTL_DW1_DEVID_OFF; + if (devid_req != devid_cur) { + printf("DEVID changing from %d to %d, updating status\n", + devid_cur, devid_req); + + capval = pci_get_long(pci_dev->config + cap_start + 0x4); + capval &= ~CM_CAP_DW1_DEVID_M; + capval |= (uint32_t)devid_req << CM_CAP_DW1_DEVID_OFF; + pci_set_long(pci_dev->config + cap_start + 4, capval); + + if (s->ccix_dev_name) + for (i = 0; i < sizeof(CCIXFuncs)/sizeof(*CCIXFuncs); i++) { + if (!CCIXFuncs[i] || !CCIXFuncs[i]->ccix_dev_name) + continue; + if (CCIXFuncs[i] != s && !strcmp(CCIXFuncs[i]->ccix_dev_name, s->ccix_dev_name)) { + capval = pci_get_long(CCIXFuncs[i]->pci_dev->config + CCIXFuncs[i]->enable_offset); + capval &= ~CM_CAP_DW1_DEVID_M; + capval |= (uint32_t)devid_req << CM_CAP_DW1_DEVID_OFF; + pci_set_long(CCIXFuncs[i]->pci_dev->config + CCIXFuncs[i]->enable_offset, capval); + } + } + } + new_val |= (uint32_t)devid_req << CM_CTL_DW1_DEVID_OFF; + + pci_set_long(pci_dev->config + offset, new_val); +} + +static void comncntl2_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t cur_val, new_val = 0; + bool partial_cur, partial_req; + uint32_t addrw_cur, addrw_req; + + cur_val = pci_get_long(pci_dev->config + offset); + + partial_cur = cur_val & (1 << CM_CTL_DW2_PART_CS_EN_OFF); + partial_req = req_val & (1 << CM_CTL_DW2_PART_CS_EN_OFF); + if (partial_cur != partial_req) + printf("Changing Partial Cache enable to %d\n", partial_req); + if (partial_req) + new_val = (1 << CM_CTL_DW2_PART_CS_EN_OFF); + /* Cacheline size 128 not yet supported */ + + addrw_cur = (cur_val & CM_CTL_DW2_ADDR_W_EN_M) >> CM_CTL_DW2_ADDR_W_EN_OFF; + addrw_req = (req_val & CM_CTL_DW2_ADDR_W_EN_M) >> CM_CTL_DW2_ADDR_W_EN_OFF; + /* No sanity checking yet */ + if (addrw_cur != addrw_req) + printf("Changing Address Width to %d\n", addrw_req); + new_val = (addrw_req << CM_CTL_DW2_ADDR_W_EN_OFF); + + pci_set_long(pci_dev->config + offset, new_val); +} + +static void port_ctl_dw1_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t cur_val; + uint32_t new_val = 0; + bool en_req, en_cur; + bool opt_req, opt_cur; + uint32_t links_req, links_cur; + uint32_t psam_req, psam_cur; + + cur_val = pci_get_long(pci_dev->config + offset); + en_cur = cur_val & (1 << PT_CTL_DW1_PORT_EN_OFF); + en_req = req_val & (1 << PT_CTL_DW1_PORT_EN_OFF); + if (en_cur != en_req) + printf("Enabling of port changing to %d\n", en_req); + if (en_req) + new_val |= (1 << PT_CTL_DW1_PORT_EN_OFF); + + opt_cur = cur_val & (1 << PT_CTL_DW1_OPT_HEADER_EN_OFF); + opt_req = req_val & (1 << PT_CTL_DW1_OPT_HEADER_EN_OFF); + if (opt_cur != opt_req) + printf("Enabling of optimized header changing to %d\n", opt_req); + if (opt_req) + new_val |= (1 << PT_CTL_DW1_OPT_HEADER_EN_OFF); + + links_cur = (cur_val & PT_CTL_DW1_LINKS_EN_M) >> PT_CTL_DW1_LINKS_EN_OFF; + links_req = (req_val & PT_CTL_DW1_LINKS_EN_M) >> PT_CTL_DW1_LINKS_EN_OFF; + if (links_cur != links_req) + printf("Number of enabled links changing from %d to %d\n", + links_cur, links_req); + new_val |= (links_req << PT_CTL_DW1_LINKS_EN_OFF); + + psam_cur = (cur_val & PT_CTL_DW1_PSAM_ENTRIES_EN_M) >> + PT_CTL_DW1_PSAM_ENTRIES_EN_OFF; + psam_req = (req_val & PT_CTL_DW1_PSAM_ENTRIES_EN_M) >> + PT_CTL_DW1_PSAM_ENTRIES_EN_OFF; + if (psam_cur != psam_req) + printf("Number of psam entries changing from %d to %d\n", + psam_cur, psam_req); + new_val |= (psam_req << PT_CTL_DW1_PSAM_ENTRIES_EN_OFF); + + pci_set_long(pci_dev->config + offset, new_val); +} + +static void lk_ctl_dw1_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t cur_val; + uint32_t new_val = 0; + bool en_cur, en_req; + bool cred_en_cur, cred_en_req; + bool mpack_en_cur, mpack_en_req; + bool nocompack_cur, nocompack_req; + uint32_t maxpkt_cur, maxpkt_req; + bool addr_type_cur, addr_type_req; + + cur_val = pci_get_long(pci_dev->config + offset); + + en_cur = cur_val & (1 << LK_CTL_DW1_LINK_EN_OFF); + en_req = req_val & (1 << LK_CTL_DW1_LINK_EN_OFF); + if (en_cur != en_req) + printf("Changing link enabled status to %d\n", en_req); + if (en_req) + new_val |= (1 << LK_CTL_DW1_LINK_EN_OFF); + + cred_en_cur = cur_val & (1 << LK_CTL_DW1_CREDIT_EN_OFF); + cred_en_req = req_val & (1 << LK_CTL_DW1_CREDIT_EN_OFF); + if (cred_en_cur != cred_en_req) + printf("Changing link credit enable status to %d\n", cred_en_cur); + if (cred_en_req) + new_val |= (1 << LK_CTL_DW1_CREDIT_EN_OFF); + + mpack_en_cur = cur_val & (1 << LK_CTL_DW1_MESSAGE_PACKING_EN_OFF); + mpack_en_req = req_val & (1 << LK_CTL_DW1_MESSAGE_PACKING_EN_OFF); + if (mpack_en_cur != mpack_en_req) + printf("Changing message packing enable to %d\n", mpack_en_req); + if (mpack_en_req) + new_val |= (1 << LK_CTL_DW1_MESSAGE_PACKING_EN_OFF); + nocompack_cur = cur_val & (1 << LK_CTL_DW1_NO_COMP_ACK_EN_OFF); + nocompack_req = req_val & (1 << LK_CTL_DW1_NO_COMP_ACK_EN_OFF); + if (nocompack_cur != nocompack_req) + printf("Setting nocompack for link to %d\n", nocompack_req); + if (nocompack_req) + new_val |= (1 << LK_CTL_DW1_NO_COMP_ACK_EN_OFF); + + maxpkt_cur = (cur_val & LK_CTL_DW1_MAX_PKT_SIZE_EN_M) >> + LK_CTL_DW1_MAX_PKT_SIZE_EN_OFF; + maxpkt_req = (req_val & LK_CTL_DW1_MAX_PKT_SIZE_EN_M) >> + LK_CTL_DW1_MAX_PKT_SIZE_EN_OFF; + if (maxpkt_cur != maxpkt_req) + printf("Changing max packet size on link from %d to %d\n", + maxpkt_cur, maxpkt_req); + new_val |= maxpkt_req << LK_CTL_DW1_MAX_PKT_SIZE_EN_OFF; + + addr_type_cur = cur_val & (1 << LK_CTL_DW1_LINK_ENT_ADDR_TYPE_OFF); + addr_type_req = req_val & (1 << LK_CTL_DW1_LINK_ENT_ADDR_TYPE_OFF); + if (addr_type_cur != addr_type_req) + printf("Link Entry Address Type changed to %d\n", addr_type_req); + if (addr_type_req) + new_val |= (1 << LK_CTL_DW1_LINK_ENT_ADDR_TYPE_OFF); + + pci_set_long(pci_dev->config + offset, new_val); +} + +static void lk_ctl_dw2_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t new_val = req_val; + /* TODO */ + pci_set_long(pci_dev->config + offset, new_val); +} + +static void lk_ctl_dw3_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t new_val = req_val; + /* TODO */ + pci_set_long(pci_dev->config + offset, new_val); +} + +static void lk_ctl_dw4_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + uint32_t new_val = req_val; + /* TODO */ + pci_set_long(pci_dev->config + offset, new_val); +} + +static void idm_entry_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + /* No sanity checking */ + printf("Setting idm entry\n"); + pci_set_long(pci_dev->config + offset, req_val); +} + +static void psam_entry_dw0_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + /* No sanity checking */ + printf("Setting psam entry dw0\n"); + pci_set_long(pci_dev->config + offset, req_val); +} + +static void psam_entry_dw1_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + /* No sanity checking */ + printf("Setting psam entry dw1\n"); + pci_set_long(pci_dev->config + offset, req_val); +} + +static void psam_entry_dw2_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + /* No sanity checking */ + printf("Setting psam entry dw2\n"); + pci_set_long(pci_dev->config + offset, req_val); +} + + +static void sam_entry_dw0_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + /* No sanity checking */ + printf("Setting sam entry dw0\n"); + pci_set_long(pci_dev->config + offset, req_val); +} + +static void sam_entry_dw1_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + /* No sanity checking */ + printf("Setting sam entry dw1\n"); + pci_set_long(pci_dev->config + offset, req_val); +} + +static void sam_entry_dw2_set(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, + uint16_t cap_start, uint32_t req_val) +{ + /* No sanity checking */ + printf("Setting sam entry dw2\n"); + pci_set_long(pci_dev->config + offset, req_val); +} + +static void ccix_prl_common_cap(PCIDevice *pci_dev, + CCIXState *s, + uint16_t this_cap_offset, + uint16_t next_cap_offset, + uint16_t device_err_log_offset, + uint16_t idm_table_offset, + uint16_t rsam_offset, uint16_t rsam_size, + uint16_t hsam_offset, uint16_t hsam_size, + uint16_t sr_table_offset, + uint16_t sw_portal_offset) +{ + uint32_t *cap_start = (uint32_t *)(pci_dev->config + this_cap_offset); + uint32_t multiport_dev_cap; + + /* Put in our first capability */ + ccix_fill_cap_header(pci_dev, this_cap_offset, CCIX_COMP_ID_PRL_COMMON, + next_cap_offset); + /* ComnCapStat1 */ + if (s->flags & (1 << PRIMARY_PORT_BIT)) + multiport_dev_cap = 0x7; + else + multiport_dev_cap = 0x5; + + *(cap_start + 1) = (multiport_dev_cap << CM_CAP_DW1_MULTIPORT_CAP_OFF) | + (0 << CM_CAP_DW1_VERSION_CAP_OFF) | + (0 << CM_CAP_DW1_DEVID_OFF); + /* ComnCapStat2 */ + *(cap_start + 2) = (1 << CM_CAP_DW2_DISC_READY_CAP_OFF) | + (0 << CM_CAP_DW2_PART_CS_CAP_OFF) | + (0 << CM_CAP_DW2_PORT_AG_CAP_OFF) | + /* 64 byte only */ + (0 << CM_CAP_DW2_CL_SIZE_CAP_OFF) | + /* 48 bit addressing only */ + (0 << CM_CAP_DW2_ADDR_W_CAP_OFF) | + /* No multihop port aggregation */ + (0 << CM_CAP_DW2_MH_CAP_OFF) | + ((sw_portal_offset ? 1 : 0) << CM_CAP_DW2_SW_PORT_CAP_OFF) | + /* Natural alignment over 4GB */ + (1 << CM_CAP_DW2_SAM_ALIGN_CAP_OFF) | + /* random time values */ + (3 << CM_CAP_DW2_READY_TIME_VAL_OFF) | + (1 << CM_CAP_DW2_READY_TIME_SCALE_OFF); + /* ComnCapStat3 */ + *(cap_start + 3) = 0; + /* Device Error Log Offset */ + *(cap_start + 4) = device_err_log_offset << CM_CAP_DW4_DEV_ERR_LOG_OFFSET_OFF; + *(cap_start + 5) = idm_table_offset << CM_CAP_DW5_IDM_OFFSET_OFF; + *(cap_start + 6) = (rsam_size << CM_CAP_DW6_RSAM_SIZE_OFF) | + (rsam_offset << CM_CAP_DW6_RSAM_OFFSET_OFF); + *(cap_start + 7) = (hsam_size << CM_CAP_DW7_HSAM_SIZE_OFF) | + (hsam_offset << CM_CAP_DW7_HSAM_OFFSET_OFF); + *(cap_start + 8) = sr_table_offset << CM_CAP_DW8_SR_OFFSET_OFF; + *(cap_start + 9) = sw_portal_offset << CM_CAP_DW9_SW_PORTAL_OFF; +} + +static void ccix_prl_ra_cap(PCIDevice *pci_dev, + uint16_t this_cap_offset, + uint16_t next_cap_offset, + uint16_t error_log_offset) +{ + uint32_t *cap_start = (uint32_t *)(pci_dev->config + this_cap_offset); + + ccix_fill_cap_header(pci_dev, this_cap_offset, CCIX_COMP_ID_RA, next_cap_offset); + *(cap_start + 1) = (1 << RA_CAP_DW1_RA_DISC_RDY_STAT_OFF) | + /* Some example values follow */ + (3 << RA_CAP_DW1_RA_CACHE_FLUSH_TIME_VALUE_OFF) | + (1 << RA_CAP_DW1_RA_CACHE_FLUSH_TIME_SCALE_OFF) | + (0 << RA_CAP_DW1_RA_CACHE_FLUSH_STA_OFF); + + *(cap_start + 2) = (error_log_offset << RA_CAP_DW2_RA_ERROR_LOG_OFFSET_OFF); +} + +static void ccix_prl_ha_cap(PCIDevice *pci_dev, + uint16_t this_cap_offset, + uint16_t next_cap_offset, + uint16_t error_log_offset, + uint8_t num_ids, + uint8_t num_pools) +{ + uint32_t *cap_start = (uint32_t *)(pci_dev->config + this_cap_offset); + int i; + + ccix_fill_cap_header(pci_dev, this_cap_offset, CCIX_COMP_ID_HA, next_cap_offset); + *(cap_start + 1) = (1 << HA_CAP_DW1_HA_DISC_RD_STAT_OFF) | + ((num_ids - 1) << HA_CAP_DW1_NUM_HA_IDS_OFF) | + (num_pools << HA_CAP_DW1_HA_MEM_POOL_CAP_OFF) | + (0 << HA_CAP_DW1_HA_QACK_OFF) | + (0 << HA_CAP_DW1_HA_HW_QACK_CAP_OFF) | + (0 << HA_CAP_DW1_HA_MEM_EXP_CAP_OFF) | /* No support for SAs being homed here */ + (0 << HA_CAP_DW1_HA_EVICT_HINT_CAP_OFF) | + (0 << HA_CAP_DW1_HA_WRITE_EVICT_FULL_HIT_CAP_OFF) | + (3 << HA_CAP_DW1_MEM_POOL_READY_TIME_VALUE_OFF) | + (4 << HA_CAP_DW1_MEM_POOL_READY_TIME_SCALE_OFF) | + (1 << HA_CAP_DW1_MEM_POOL_READY_STA_OFF); + *(cap_start + 2) = error_log_offset << HA_CAP_DW2_HA_ERROR_LOG_OFF; + + for (i = 0; i < num_pools; i++) { + *(cap_start + 3 + i * 2) = (1 << MEM_POOL_CAP_DW1_READY_STA_OFF) | + (mem_type_volatile << MEM_POOL_CAP_DW1_GEN_MEM_TYPE_OFF) | + (mem_spec_hbm << MEM_POOL_CAP_DW1_SPEC_MEM_TYPE_OFF) | + (0 << MEM_POOL_CAP_DW1_ADDR_CAP_OFF) | + (MEM_POOL_CAP_DW1_MEM_ATTR_NORMAL << MEM_POOL_CAP_DW1_MEM_ATTR_OFF) | + (MEM_POOL_CAP_DW1_MEM_EXT_ATTR_NONE << MEM_POOL_CAP_DW1_MEM_EXT_ATTR_OFF) | + (0xFFFF << MEM_POOL_CAP_DW1_MEM_POOL_SIZE_L_CAP_OFF); + *(cap_start + 3 + i * 2 + 1) = 0xF << MEM_POOL_CAP_DW2_MEM_POOL_SIZE_H_CAP_OFF; + } +} + +static void ccix_prl_port_cap(PCIDevice *pci_dev, + CCIXState *s, + uint16_t this_cap_offset, + uint16_t next_cap_offset, + uint16_t error_log_offset) +{ + uint32_t *cap_start = (uint32_t *)(pci_dev->config + this_cap_offset); + + ccix_fill_cap_header(pci_dev, this_cap_offset, CCIX_COMP_ID_PRL_PORT, + next_cap_offset); + *(cap_start + 1) = (1 << PT_CAP_DW1_DISC_READY_OFF) | + (1 << PT_CAP_DW1_OPT_HEADER_OFF) | + (0 << PT_CAP_DW1_P2P_FORWARDING_OFF) | + (s->num_links << PT_CAP_DW1_LINKS_OFF) | + (s->psam_entries << PT_CAP_DW1_PSAM_ENTRIES_OFF) | + ((s->port_id & 0xf) << PT_CAP_DW1_PORTID_OFF); + *(cap_start + 2) = 0; /* No Port AG */ + *(cap_start + 3) = 0; /* No Port FW */ + *(cap_start + 4) = error_log_offset << 20; +} + +static void ccix_prl_link_cap(PCIDevice *pci_dev, + uint16_t this_cap_offset, + uint16_t next_cap_offset, + uint16_t error_log_offset) +{ + uint32_t *cap_start = (uint32_t *)(pci_dev->config + this_cap_offset); + + ccix_fill_cap_header(pci_dev, this_cap_offset, CCIX_COMP_ID_PRL_LINK, + next_cap_offset); + + *(cap_start + 1) = (1 << LK_CAP_DW1_DISC_READY_OFF) | + (0 << LK_CAP_DW1_CREDIT_TYPE_OFF) | + (1 << LK_CAP_DW1_MESSAGE_PACKING_OFF) | + (0 << LK_CAP_DW1_NOCOMPACK_OFF) | + (2 << LK_CAP_DW1_MAX_PKT_SIZE_OFF); + + *(cap_start + 2) = (3 << LK_CAP_DW2_MAX_MEM_REQ_SEND_OFF) | + (4 << LK_CAP_DW2_MAX_SNP_REQ_SEND_OFF) | + (5 << LK_CAP_DW2_MAX_DAT_REQ_SEND_OFF); + *(cap_start + 3) = (6 << LK_CAP_DW3_MAX_MEM_REQ_RECV_OFF) | + (7 << LK_CAP_DW3_MAX_SNP_REQ_RECV_OFF) | + (8 << LK_CAP_DW3_MAX_DAT_REQ_RECV_OFF); + *(cap_start + 4) = (9 << LK_CAP_DW4_MAX_MISC_REQ_SEND_CAP_OFF) | + (10 << LK_CAP_DW4_MAX_MISC_REQ_RECV_CAP_OFF); + *(cap_start + 5) = error_log_offset << 20; +} + +static void ccix_prl_common_ctl(PCIDevice *pci_dev, + CCIXState *s, + uint16_t this_ctl_offset, + uint16_t next_ctl_offset) +{ + uint32_t *ctl_start = (uint32_t *)(pci_dev->config + this_ctl_offset); + + ccix_fill_cap_header(pci_dev, this_ctl_offset, CCIX_COMP_ID_PRL_COMMON, + next_ctl_offset); + /* ComnCntl1 */ + *(ctl_start + 1) = (0 << CM_CTL_DW1_DEVICE_EN_OFF) | + (0 << CM_CTL_DW1_PRIMARY_PORT_EN_OFF) | + (0 << CM_CTL_DW1_MESH_EN_OFF) | + (0 << CM_CTL_DW1_PORT_AG_EN_OFF) | + (0 << CM_CTL_DW1_IDM_TABLE_VALID_OFF) | + (0 << CM_CTL_DW1_RSAM_TABLE_VALID_OFF) | + (0 << CM_CTL_DW1_HSAM_TABLE_VALID_OFF) | + (0 << CM_CTL_DW1_SW_PORT_ENABLE_OFF) | + (0 << CM_CTL_DW1_ERR_AGENT_ID_OFF) | + (0 << CM_CTL_DW1_DEVID_OFF); + am_table_add(pci_dev, s, this_ctl_offset + 4, this_ctl_offset, comncntl1_set); + s->enable_offset = this_ctl_offset + 4; + /* ComnCtl2 */ + *(ctl_start + 2) = 0; // No support for anything in here yet. + am_table_add(pci_dev, s, this_ctl_offset + 8, this_ctl_offset, comncntl2_set); + /* No snoop request hash mask yet */ + /* No SW Service Portal yet */ +} + +static void ccix_prl_ra_ctl(PCIDevice *pci_dev, + CCIXState *s, + uint16_t this_ctl_offset, + uint16_t next_ctl_offset, + uint16_t ra_id) +{ + uint32_t *ctl_start = (uint32_t *)(pci_dev->config + this_ctl_offset); + + ccix_fill_cap_header(pci_dev, this_ctl_offset, CCIX_COMP_ID_RA, + next_ctl_offset); + + *(ctl_start + 1) = (0 << RA_CTL_DW1_EN_OFF) | + (0 << RA_CTL_DW1_SNOOP_RESP_EN_OFF) | + (0 << RA_CTL_DW1_CACHE_FLUSH_EN_OFF) | + (0 << RA_CTL_DW1_CACHE_EN_OFF) | + (0 << RA_CTL_DW1_RAID_OFF); + am_table_add(pci_dev, s, this_ctl_offset + 4, this_ctl_offset, ra_ctl_dw1_set); +} + +static void ccix_prl_ha_ctl(PCIDevice *pci_dev, + CCIXState *s, + uint16_t this_ctl_offset, + uint16_t next_ctl_offset, + uint16_t num_ids, + uint16_t num_pools) +{ + uint32_t *ctl_start = (uint32_t *)(pci_dev->config + this_ctl_offset); + + ccix_fill_cap_header(pci_dev, this_ctl_offset, CCIX_COMP_ID_HA, + next_ctl_offset); + *(ctl_start + 1) = 0; +} + +static void ccix_prl_port_ctl(PCIDevice *pci_dev, + CCIXState *s, + uint16_t this_ctl_offset, + uint16_t next_ctl_offset, + uint8_t psam_table_entries) +{ + uint8_t i; + uint32_t *ctl_start = (uint32_t *)(pci_dev->config + this_ctl_offset); + + ccix_fill_cap_header(pci_dev, this_ctl_offset, CCIX_COMP_ID_PRL_PORT, + next_ctl_offset); + /* Port Control */ + *(ctl_start + 1) = 0; + am_table_add(pci_dev, s, this_ctl_offset + 4, this_ctl_offset, port_ctl_dw1_set); + + for (i = 0; i < psam_table_entries; i++) { + am_table_add(pci_dev, s, this_ctl_offset + 0x14 + (3 * i + 0) * 4, + 0, psam_entry_dw0_set); + am_table_add(pci_dev, s, this_ctl_offset + 0x14 + (3 * i + 1) * 4, + 0, psam_entry_dw1_set); + am_table_add(pci_dev, s, this_ctl_offset + 0x14 + (3 * i + 2) * 4, + 0, psam_entry_dw2_set); + } +} + +static void ccix_prl_link_ctl(PCIDevice *pci_dev, + CCIXState *s, + uint16_t this_ctl_offset, + uint16_t next_ctl_offset, + uint8_t num_links) +{ + uint32_t *ctl_start = (uint32_t *)(pci_dev->config + this_ctl_offset); + uint8_t i; + + ccix_fill_cap_header(pci_dev, this_ctl_offset, CCIX_COMP_ID_PRL_LINK, + next_ctl_offset); + + for (i = 0; i < num_links; i++) { + /* LinkAttrCntl for link i */ + *(ctl_start + 1 + i * 6) = 0; + am_table_add(pci_dev, s, this_ctl_offset + 4 + i * 24, 0, lk_ctl_dw1_set); + /* LinkMaxCreditCntl for link i */ + *(ctl_start + 1 + i * 6 + 1) = 0; + am_table_add(pci_dev, s, this_ctl_offset + 4 + i * 24 + 4, 0, lk_ctl_dw2_set); + *(ctl_start + 1 + i * 6 + 2) = 0; + am_table_add(pci_dev, s, this_ctl_offset + 4 + i * 24 + 8, 0, lk_ctl_dw3_set); + *(ctl_start + 1 + i * 6 + 3) = 0; + am_table_add(pci_dev, s, this_ctl_offset + 4 + i * 24 + 0xC, 0, lk_ctl_dw4_set); + + /* error fields - to do */ + *(ctl_start + 1 + i * 24 + 4) = 0; + *(ctl_start + 1 + i * 24 + 5) = 0; + } + /* transport id */ + for (i = 0; i < num_links; i++) + //to check + *(ctl_start + 1 + num_links * 6 + 4 * i) = 0; +} + +static void ccix_idm(PCIDevice *pci_dev, CCIXState *s, uint16_t offset) +{ + int i; + + for (i = 0; i < 64; i++) + am_table_add(pci_dev, s, offset + i * 4, 0, idm_entry_set); +} + +static void ccix_sam(PCIDevice *pci_dev, CCIXState *s, uint16_t offset, uint8_t entries) +{ + int i; + + for (i = 0; i < entries; i++) { + am_table_add(pci_dev, s, offset + 3 * i * 4, 0, sam_entry_dw0_set); + am_table_add(pci_dev, s, offset + (3 * i + 1) * 4, 0, sam_entry_dw1_set); + am_table_add(pci_dev, s, offset + (3 * i + 2) * 4, 0, sam_entry_dw2_set); + } +} +static void ccix_guid(PCIDevice *pci_dev, uint16_t offset) +{ + uint32_t *start = (uint32_t *)(pci_dev->config + offset); + + *(start) = CCIX_GUID_DW0; + *(start + 1) = CCIX_GUID_DW1; + *(start + 2) = CCIX_GUID_DW2; + *(start + 3) = CCIX_GUID_DW3; + *(start + 4) = 1 << CCIX_GUID_DW4_VERSION_OFF; +} + +/*FIXME: Is this generic enough that we should put it in the PCIe core */ + +#define CCIX_DVSEC_HEADER_SIZE 0x14 +#define PCIE_DVSEC_HEADER_OFFSET 0x4 /* Offset from start of extend cap */ +#define PCIE_DVSEC_ID_OFFSET 0x8 +static void pcie_add_dvsec(PCIDevice *pci_dev, uint16_t offset, + uint16_t size, uint16_t vendor_id, uint16_t dvsec_id, + uint16_t ccix_guid_offset) +{ + uint16_t *word_addr; + + pcie_add_capability(pci_dev, PCI_EXT_CAP_ID_DVSEC, 1, offset, size); + pci_set_word(pci_dev->config + offset + PCIE_DVSEC_HEADER_OFFSET, + vendor_id); + word_addr = (uint16_t *)(pci_dev->config + offset + PCIE_DVSEC_HEADER_OFFSET + 2); + *word_addr = 0x1 | (size << 4); + + word_addr = (uint16_t *)(pci_dev->config + offset + PCIE_DVSEC_ID_OFFSET); + *word_addr = dvsec_id; + word_addr = (uint16_t *)(pci_dev->config + offset + PCIE_DVSEC_ID_OFFSET + 2); + *word_addr = (ccix_guid_offset << 4); +} + +void ccix_set_port(CCIXState *s) +{ + s->flags |= (1 << CCIX_IS_PORT); + /* Enforce rule of how many psam entries if links is greater than 1 */ + if ((s->num_links > 1) && + (s->psam_entries < s->num_links + 1)) { + printf("Increased psam entries to minimum allowed\n"); + s->psam_entries = s->num_links + 1; + } +} + +enum ccix_entry_type { + common_cap, + ra_cap, + ha_cap, + port_cap, + link_cap, + end_cap, + common_ctl, + ra_ctl, + ha_ctl, + port_ctl, + link_ctl, + end_ctl, + idm_table, + sr_table, + rsam, + hsam, + guid, +}; + +struct ccix_cap { + uint16_t size; + uint16_t offset; + enum ccix_entry_type type; +}; + +static void ccix_add_cap(GList **l, enum ccix_entry_type type, uint16_t size) +{ + struct ccix_cap *c; + + c = malloc(sizeof(*c)); + c->type = type; + c->size = size; + *l = g_list_append(*l, c); +} + +uint16_t ccix_add_prldvsec(PCIDevice *pci_dev, CCIXState *s, uint16_t offset) +{ + /* Runtime configuration of the following is not yet implemented */ + uint16_t ha_num_pools = 2; + uint16_t ha_num_ids = 8; + /* Error log not yet implemented */ + uint16_t error_log_offset = 0; + uint16_t idm_offset = 0; + uint16_t sr_offset = 0; + uint16_t rsam_offset = 0; + uint16_t hsam_offset = 0; + uint16_t guid_offset = 0; + uint16_t max_offset = 0; + uint16_t next_offset; + uint16_t cap_size = 0; + uint16_t cap_offset; + uint16_t ctl_size = 0; + uint16_t ctl_offset; + struct ccix_cap *c; + GList *li; + GList *cap_list = NULL; + GList *ctl_list = NULL; + GList *other_list = NULL; + int i; + + /* + * Build up lists of the CCIX capabilities, controls and other blocks so that we + * can work out their layout in config space before writing the header. + */ + ccix_add_cap(&cap_list, common_cap, CCIX_COMMON_CAP_MAX_SIZE); + if (s->flags & (1 << PRIMARY_PORT_BIT)) + ccix_add_cap(&ctl_list, common_ctl, 0x10); + for (i = 0; i < s->num_ras; i++) { + ccix_add_cap(&cap_list, ra_cap, CCIX_RA_CAP_SIZE); + ccix_add_cap(&ctl_list, ra_ctl, CCIX_RA_CTL_SIZE); + } + for (i = 0; i < s->num_has; i++) { + ccix_add_cap(&cap_list, ha_cap, CCIX_HA_CAP_SIZE + CCIX_POOL_CAP_SIZE * ha_num_pools); + ccix_add_cap(&ctl_list, ha_ctl, + CCIX_HA_CTL_SIZE + + (ha_num_ids + 3) / 4 * CCIX_HAID_ENTRY_SIZE + + ha_num_pools * CCIX_BAT_ENTRY_SIZE); + } + + /* Only functions with CCIX ports may have port and link structures */ + if (s->flags & (1 << CCIX_IS_PORT)) { + ccix_add_cap(&cap_list, port_cap, CCIX_PORT_CAP_SIZE); + ccix_add_cap(&ctl_list, port_ctl, + CCIX_PORT_CTL_SIZE + 12 * s->psam_entries); + ccix_add_cap(&cap_list, link_cap, CCIX_LINK_CAP_SIZE); + ccix_add_cap(&ctl_list, link_ctl, + CCIX_LINK_CTL_SIZE + CCIX_LINK_CTL_PER_LINK_SIZE * s->num_links); + } + + if (s->flags & (1 << PRIMARY_PORT_BIT)) { + ccix_add_cap(&other_list, idm_table, 64 * 4); + if (s->rsam_entries) + ccix_add_cap(&other_list, rsam, CCIX_SAM_ENTRY_SIZE * s->rsam_entries); + if (s->hsam_entries) + ccix_add_cap(&other_list, hsam, CCIX_SAM_ENTRY_SIZE * s->hsam_entries); + ccix_add_cap(&other_list, guid, CCIX_GUID_SIZE); + } + + cap_offset = offset + CCIX_DVSEC_HEADER_SIZE; + next_offset = cap_offset; + for (li = cap_list; li != NULL; li = li->next) { + c = (struct ccix_cap *)li->data; + c->offset = next_offset; + if (li->next == NULL) + next_offset = 0; + else { + next_offset = c->offset + c->size; + } + cap_size += c->size; + max_offset = c->offset + c->size; + } + + next_offset = max_offset; + ctl_offset = max_offset; + for (li = ctl_list; li != NULL; li = li->next) { + c = (struct ccix_cap *)li->data; + c->offset = next_offset; + if (li->next == NULL) + next_offset = 0; + else + next_offset = c->offset + c->size; + + max_offset = c->offset + c->size; + ctl_size += c->size; + } + + next_offset = max_offset; + for (li = other_list; li != NULL; li = li->next) { + c = (struct ccix_cap *)li->data; + c->offset = next_offset; + switch (c->type) { + case + idm_table: idm_offset = c->offset; + break; + case sr_table: + sr_offset = c->offset; + break; + case hsam: + hsam_offset = c->offset; + break; + case rsam: + rsam_offset = c->offset; + break; + case guid: + guid_offset = c->offset; + break; + default: + break; + } + if (li->next == NULL) + next_offset = 0; + else + next_offset = c->offset + c->size; + max_offset = c->offset + c->size; + } + + /* Will eventually take some description and make a prl. For now one RA */ + pcie_add_dvsec(pci_dev, offset, max_offset - offset, PCI_VENDOR_ID_CCIX, + CCIX_COMP_ID_PRL_DVSEC, guid_offset); + + ccix_dvsec_fill_dvsec_header(pci_dev, offset, cap_size, cap_offset, + ctl_size, ctl_offset); + + for (li = cap_list; li != NULL; li = li->next) { + c = (struct ccix_cap *)li->data; + if (li->next) + next_offset = ((struct ccix_cap *)(li->next->data))->offset; + else + next_offset = 0; + switch (c->type) { + case common_cap: + ccix_prl_common_cap(pci_dev, s, c->offset, next_offset, + 0, /* No support for device error log */ + idm_offset, + rsam_offset, CCIX_SAM_ENTRY_SIZE * s->rsam_entries, + hsam_offset, CCIX_SAM_ENTRY_SIZE * s->hsam_entries, + sr_offset, + 0 /* No support for sw portal */); + break; + case ra_cap: + ccix_prl_ra_cap(pci_dev, c->offset, next_offset, error_log_offset); + break; + case ha_cap: + ccix_prl_ha_cap(pci_dev, c->offset, next_offset, error_log_offset, + ha_num_ids, ha_num_pools); + break; + case port_cap: + ccix_prl_port_cap(pci_dev, s, c->offset, next_offset, error_log_offset); + break; + case link_cap: + ccix_prl_link_cap(pci_dev, c->offset, next_offset, error_log_offset); + break; + default: + break; + } + } + + for (li = ctl_list; li != NULL; li = li->next) { + c = (struct ccix_cap *)li->data; + if (li->next) + next_offset = ((struct ccix_cap *)(li->next->data))->offset; + else + next_offset =0; + switch (c->type) { + case common_ctl: + ccix_prl_common_ctl(pci_dev, s, c->offset, next_offset); + break; + case ra_ctl: + ccix_prl_ra_ctl(pci_dev, s, c->offset, next_offset, 0); + break; + case ha_ctl: + ccix_prl_ha_ctl(pci_dev, s, c->offset, next_offset, ha_num_ids, ha_num_pools); + break; + case port_ctl: + ccix_prl_port_ctl(pci_dev, s, c->offset, next_offset, s->psam_entries); + break; + case link_ctl: + ccix_prl_link_ctl(pci_dev, s, c->offset, next_offset, s->num_links); + break; + default: + break; + } + } + + for (li = other_list; li != NULL; li = li->next) { + c = (struct ccix_cap *)li->data; + switch(c->type) { + case idm_table: + ccix_idm(pci_dev, s, c->offset); + break; + case sr_table: + ccix_idm(pci_dev, s, c->offset); + break; + case rsam: + ccix_sam(pci_dev, s, c->offset, s->rsam_entries); + break; + case hsam: + ccix_sam(pci_dev, s, c->offset, s->hsam_entries); + break; + case guid: + ccix_guid(pci_dev, c->offset); + break; + default: + break; + } + } + return max_offset; +} + +uint16_t ccix_add_tdldvsec(PCIDevice *pci_dev, uint16_t offset) +{ + const uint16_t dvsec_size = 17 * sizeof(uint32_t); + + pcie_add_dvsec(pci_dev, offset, dvsec_size, PCI_VENDOR_ID_CCIX, + CCIX_COMP_ID_TDL_DVSEC, 0); + + return offset + dvsec_size; +} + +void ccix_register(CCIXState *s) +{ + int i; + + if (s->ccix_dev_name) + for (i = 0; i < sizeof(CCIXFuncs)/sizeof(*CCIXFuncs); i++) + if (!CCIXFuncs[i]) { + CCIXFuncs[i] = s; + break; + } +} diff --git a/include/hw/misc/ccix.h b/include/hw/misc/ccix.h new file mode 100644 index 0000000000..94aa904b53 --- /dev/null +++ b/include/hw/misc/ccix.h @@ -0,0 +1,28 @@ + +#include "hw/pci/pcie_port.h" +typedef struct CCIXState { + GTree *am_tree; +#define PRIMARY_PORT_BIT 0 +#define CCIX_IS_PORT 1 + uint32_t flags; + char *ccix_dev_name; + uint8_t port_id; + uint8_t num_links; + uint8_t psam_entries; + uint8_t num_ras; + uint8_t num_has; + uint8_t rsam_entries; + uint8_t hsam_entries; + PCIDevice *pci_dev; + uint16_t enable_offset; +} CCIXState; + +extern CCIXState *CCIXFuncs[256]; + +uint16_t ccix_add_prldvsec(PCIDevice *pci_dev, CCIXState *s, uint16_t offset); +void ccix_write_config(PCIDevice *pci_dev, CCIXState *s, uint32_t addr, uint32_t val_in, int l); +uint16_t ccix_add_tdldvsec(PCIDevice *pci_dev, uint16_t offset); +void initialize_ccixstate(CCIXState *s, PCIDevice *pci_dev); +void ccix_register(CCIXState *s); + +void ccix_set_port(CCIXState *s); diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h index f49be07328..19675fdac1 100644 --- a/include/hw/pci/pci_ids.h +++ b/include/hw/pci/pci_ids.h @@ -225,6 +225,8 @@ #define PCI_DEVICE_ID_HUAWEI_CCIX_DOWN 0xA261 #define PCI_DEVICE_ID_HUAWEI_CCIX_EP 0xA262 +#define PCI_VENDOR_ID_CCIX 0x1e2c + #define PCI_VENDOR_ID_INTEL 0x8086 #define PCI_DEVICE_ID_INTEL_82378 0x0484 #define PCI_DEVICE_ID_INTEL_82441 0x1237 From patchwork Tue Jun 25 11:27:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 167709 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp5434578ilk; Tue, 25 Jun 2019 04:35:35 -0700 (PDT) X-Google-Smtp-Source: APXvYqyKReKW10yoZgkxUas7X/Z3cEiabWsOcws8dpofR/CIL5c9hxXbDzm+oArtn2jhzP4LeQE9 X-Received: by 2002:a50:9203:: with SMTP id i3mr153729903eda.302.1561462534917; Tue, 25 Jun 2019 04:35:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561462534; cv=none; d=google.com; s=arc-20160816; b=vwI0j7Z7S9i2KgeybAauj/jDr7bHTKcJkRyTkP6sVH2KHz4mxGv31RvVcWD+9wNvt7 WBGo6yeLBCBQttq3uUng+1Oai8JKc/sc0l2C6A2cYXkSqGVx8lyfUX08pwPy+jmCt9K+ KJeXwCGTEPsKlamzTybAQZOAbWXuUokDheV5R9XT208AYbNv6mcmESxKtpkt+0s/BD/v WSFax+WoopQtYtGIXsEwz3Ij8faiOAtsQ3wmHYjLiq7F8uRizyRA3Q4iiYupUh8o22LM CKQGJhIfIZmBLCNBQ00iyLPthavak8agHz/oRNs+RFww5lVYwxiPvpy1mGyBSrSSjmzs C4vA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from; bh=05cl7/W4z4ceUmzbYGffcWPbMb1dFWGCSz7UiMCwGrk=; b=ygprJd98jtfPvw13Ga+42D3p0Boi3oa0449Vua11Vmkr5c9mg7ZhigZ447YXhakGJa NqxKpkpPuOHi8PpTWfB+DlFVRSYlROv82Pb10E1wG84wxAinZiV6GdNKF5Itd0BcZCKs J6N2B033veRrPYtAwDwuxzUHDjcaQBeVOCyoyNBTYiSWMRwvX5Va7cq6vhfBVZfUECIo qb7qU9gAyjBWh7FC6Amdspg8rjXGPn2frAkWydGa9tORJm1WUn77lAOcQLf13KUjJ95k A/9rrq8Z+7lX+gEmoVPctLy/Ari2Ml2kzwYBm6vTmsMNRPlObj3G5wGc50E50a683+ka Wkvg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id v1si162845ejk.50.2019.06.25.04.35.34 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 04:35:34 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:59030 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjjZ-0005QO-TC for patch@linaro.org; Tue, 25 Jun 2019 07:35:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53682) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjdC-0006xk-FN for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfjdA-0004A8-L3 for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:28:58 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:52884 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfjd6-0003xB-Dt; Tue, 25 Jun 2019 07:28:53 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 4F9DDCE1D6C9A67333DF; Tue, 25 Jun 2019 19:28:48 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.439.0; Tue, 25 Jun 2019 19:28:39 +0800 From: Jonathan Cameron To: QEMU Developers Date: Tue, 25 Jun 2019 19:27:49 +0800 Message-ID: <20190625112752.83188-5-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> References: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 Subject: [Qemu-devel] [RFC PATCH 4/7] pci-bridge: CCIX capable PCIE/CCIX switch upstream port. 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: Peter Maydell , jcm@redhat.com, linuxarm@huawei.com, Auger Eric , qemu-arm , Jonathan Cameron Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Note that these occur as function 0 within CCIX devices that have many other elements in the PCIE topology. This driver has around 100 lines of code copied directly from the xio3130-upstream.c file. There are various options to avoid this: 1) Expose the xio3130 functions so this module can just call them. 2) Create a library for the code that is shared. 3) Don't worry too much about it as it's likely they will diverge overtime as we extend the CCIX driver. Signed-off-by: Jonathan Cameron --- hw/pci-bridge/Kconfig | 5 + hw/pci-bridge/Makefile.objs | 1 + hw/pci-bridge/ccix_upstream.c | 197 ++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+) -- 2.20.1 diff --git a/hw/pci-bridge/Kconfig b/hw/pci-bridge/Kconfig index a51ec716f5..f6ff8975a5 100644 --- a/hw/pci-bridge/Kconfig +++ b/hw/pci-bridge/Kconfig @@ -27,3 +27,8 @@ config DEC_PCI config SIMBA bool + +config CCIX_SWITCH + default y if CCIX_EP + depends on PCI_EXPRESS && MSI_NONBROKEN + select CCIX_LIB diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs index 47065f87d9..e266e39fed 100644 --- a/hw/pci-bridge/Makefile.objs +++ b/hw/pci-bridge/Makefile.objs @@ -8,3 +8,4 @@ common-obj-$(CONFIG_I82801B11) += i82801b11.o common-obj-$(CONFIG_DEC_PCI) += dec.o # Sun4u common-obj-$(CONFIG_SIMBA) += simba.o +common-obj-$(CONFIG_CCIX_SWITCH) += ccix_upstream.o diff --git a/hw/pci-bridge/ccix_upstream.c b/hw/pci-bridge/ccix_upstream.c new file mode 100644 index 0000000000..f2b8441fba --- /dev/null +++ b/hw/pci-bridge/ccix_upstream.c @@ -0,0 +1,197 @@ +/* + * ccix_upstream.c + * CCIX / pci express upstream port switch + * + * Copyright (c) 2019 Jonathan Camerom + * Huawei + * Based on: xio3130_downstream.c + * Copyright (c) 2010 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * 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 . + */ + +#include "qemu/osdep.h" +#include "hw/pci/pci_ids.h" +#include "hw/pci/msi.h" +#include "hw/pci/pcie.h" +#include "hw/pci/pcie_port.h" +#include "hw/misc/ccix.h" +#include "qemu/module.h" + +/* + * As no CCIX devices have publically available specs, just use + * the xio3130 elements for the PCIe specific parts. + */ +#define XIO3130_REVISION 0x2 +#define XIO3130_MSI_OFFSET 0x70 +#define XIO3130_MSI_SUPPORTED_FLAGS PCI_MSI_FLAGS_64BIT +#define XIO3130_MSI_NR_VECTOR 1 +#define XIO3130_SSVID_OFFSET 0x80 +#define XIO3130_SSVID_SVID 0 +#define XIO3130_SSVID_SSID 0 +#define XIO3130_EXP_OFFSET 0x90 +#define XIO3130_AER_OFFSET 0x100 + +#define TYPE_CCIX_UP_PORT "ccix-upstream-port" + +#define CCIX_UP_DEV(obj) OBJECT_CHECK(CCIXUpPortState, (obj), TYPE_CCIX_UP_PORT) + +typedef struct CCIXUpPortState { + PCIEPort parent_obj; + struct CCIXState s; +} CCIXUpPortState; + +static void ccix_upstream_port_write_config(PCIDevice *d, uint32_t address, + uint32_t val, int len) +{ + CCIXUpPortState *s = CCIX_UP_DEV(d); + pci_bridge_write_config(d, address, val, len); + pcie_cap_flr_write_config(d, address, val, len); + pcie_aer_write_config(d, address, val, len); + ccix_write_config(d, &s->s, address, val, len); +} + +static void xio3130_upstream_reset(DeviceState *qdev) +{ + PCIDevice *d = PCI_DEVICE(qdev); + + pci_bridge_reset(qdev); + pcie_cap_deverr_reset(d); +} + +static void ccix_upstream_port_realize(PCIDevice *d, Error **errp) +{ + CCIXUpPortState *s = CCIX_UP_DEV(d); + PCIEPort *p = PCIE_PORT(d); + uint32_t offset = 0x180; + int rc; + + pci_bridge_initfn(d, TYPE_PCIE_BUS); + pcie_port_init_reg(d); + + rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR, + XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, + XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, + errp); + if (rc < 0) { + assert(rc == -ENOTSUP); + goto err_bridge; + } + + rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET, + XIO3130_SSVID_SVID, XIO3130_SSVID_SSID, + errp); + if (rc < 0) { + goto err_bridge; + } + + rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_UPSTREAM, + p->port, errp); + if (rc < 0) { + goto err_msi; + } + pcie_cap_flr_init(d); + pcie_cap_deverr_init(d); + + rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET, + PCI_ERR_SIZEOF, errp); + if (rc < 0) { + goto err; + } + initialize_ccixstate(&s->s, d); + ccix_set_port(&s->s); + offset = ccix_add_prldvsec(d, &s->s, offset); + ccix_register(&s->s); + + return; + +err: + pcie_cap_exit(d); +err_msi: + msi_uninit(d); +err_bridge: + pci_bridge_exitfn(d); +} + +static Property ccix_props[] = { + DEFINE_PROP_STRING("ccix_device", CCIXUpPortState, s.ccix_dev_name), + DEFINE_PROP_BIT("primaryport", CCIXUpPortState, s.flags, PRIMARY_PORT_BIT, true), + DEFINE_PROP_UINT8("port_id", CCIXUpPortState, s.port_id, 0), + DEFINE_PROP_UINT8("num_links", CCIXUpPortState, s.num_links, 1), + DEFINE_PROP_UINT8("psam_entries", CCIXUpPortState, s.psam_entries, 0), + DEFINE_PROP_UINT8("request_agents", CCIXUpPortState, s.num_ras, 0), + DEFINE_PROP_UINT8("home_agents", CCIXUpPortState, s.num_has, 0), + DEFINE_PROP_UINT8("hsam_entries", CCIXUpPortState, s.hsam_entries, 0), + DEFINE_PROP_UINT8("rsam_entries", CCIXUpPortState, s.rsam_entries, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ccix_upstream_exitfn(PCIDevice *d) +{ + pcie_aer_exit(d); + pcie_cap_exit(d); + msi_uninit(d); + pci_bridge_exitfn(d); +} + +static const VMStateDescription vmstate_ccix_upstream = { + .name = "ccix-upstream-port", + .priority = MIG_PRI_PCI_BUS, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj.parent_obj, PCIEPort), + VMSTATE_STRUCT(parent_obj.parent_obj.exp.aer_log, PCIEPort, 0, + vmstate_pcie_aer_log, PCIEAERLog), + VMSTATE_END_OF_LIST() + } +}; + +static void ccix_upstream_port_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->is_bridge = true; + k->config_write = ccix_upstream_port_write_config; + k->realize = ccix_upstream_port_realize; + k->exit = ccix_upstream_exitfn; + k->vendor_id = PCI_VENDOR_ID_HUAWEI; + k->device_id = PCI_DEVICE_ID_HUAWEI_CCIX_UP; + k->revision = 1; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->desc = "CCIX / PCIe switch upstream port"; + dc->props = ccix_props; + dc->reset = xio3130_upstream_reset; + dc->vmsd = &vmstate_ccix_upstream; +} + +static const TypeInfo ccix_upstream_port_info = { + .name = TYPE_CCIX_UP_PORT, + .parent = TYPE_PCIE_PORT, + .class_init = ccix_upstream_port_init, + .instance_size = sizeof(CCIXUpPortState), + .interfaces = (InterfaceInfo[]) { + { INTERFACE_PCIE_DEVICE }, + { } + }, +}; + +static void ccix_upstream_register_types(void) +{ + type_register_static(&ccix_upstream_port_info); +} + +type_init(ccix_upstream_register_types) From patchwork Tue Jun 25 11:27:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 167703 Delivered-To: patch@linaro.org Received: by 2002:ac9:6410:0:0:0:0:0 with SMTP id r16csp4871998ock; Tue, 25 Jun 2019 04:32:03 -0700 (PDT) X-Google-Smtp-Source: APXvYqywHAREZemVQZtFc96Nhl2ZWnpw9HO+NC8XS4UO4XfFRM1dt7KdDhXDHdaJ4cKZi+3I9oGG X-Received: by 2002:a50:a3f5:: with SMTP id t50mr40778608edb.273.1561462323846; Tue, 25 Jun 2019 04:32:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561462323; cv=none; d=google.com; s=arc-20160816; b=bZFSToC0Vy0mw2llBWu8h4Gx8iq/rsCucS628DyDRf97+hjiPGS/jz8OmtntjNwguj qFMR7apBtfKy3FOKlnW5QFwj5RqwbK8CYzkDdlj07/B+dg71///zo8jaj/9qdx14XnuG FC13uwkAsPlwqU5Ldh7Csz7g5aZZkKyQ5alWbe+SxDqBiA/7nEPgiXtEYKOn1K8x4ibC 5/pJM4BGWFT808P5WqQBoEqru1SF4yyBj0Vtb8m1ZkLZS+qHlDY8ZtDl5KFn6SNotkz4 FSU6GuzLlXo7BGFR4vcDdUJzGAHIYSBbFKH1ixW94nl7dXlI5tyQRVf8TwDx1EzwVici amYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from; bh=0Of383u8KnwHEsqWqlolo5JRT6gmT/bOwCwH6dgTb+s=; b=Q4RlUR3R5P7z/+8FFkeeuObjNo1E9y9yOorLGw/aYb0hLt8tN1ipgxSgJgNDPIFXsd 5lmnD1bQno3EStltsNGqf8WICkHt3qO5sJohY1pLgY6aW46wYUaz0AgqUSlB1hg6GjCq ofVDgLqMaJ1FviAmQNl4cjjViRaNmuumSd0XfrTR8IyY/iYFYsxdEnTj6jujZOhY2Enl UR3Xhw6arQs+ZGH4Rv5ekc6N15opeqdZeErc4d/adhyXlLsHRJ8dNGpc3PdF2QqzD0sm dky3uy5anKthYitKkJsZ/vMhdRMmDCJb7vTy0q5NM/dKhqRMliFLuwaD9FicTQ/M4qM9 tSpg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id 58si170548edz.364.2019.06.25.04.32.03 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 04:32:03 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:58992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjgA-0002Hq-Pe for patch@linaro.org; Tue, 25 Jun 2019 07:32:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53742) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjdF-000745-AE for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfjdD-0004EA-Gu for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:01 -0400 Received: from szxga07-in.huawei.com ([45.249.212.35]:52882 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfjd7-0003xA-BG; Tue, 25 Jun 2019 07:28:55 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 3FD502AD529BF46919CB; Tue, 25 Jun 2019 19:28:48 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.439.0; Tue, 25 Jun 2019 19:28:41 +0800 From: Jonathan Cameron To: QEMU Developers Date: Tue, 25 Jun 2019 19:27:50 +0800 Message-ID: <20190625112752.83188-6-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> References: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.35 Subject: [Qemu-devel] [RFC PATCH 5/7] pci-bridge: CCIX capable PCIE/CCIX switch downstream port 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: Peter Maydell , jcm@redhat.com, linuxarm@huawei.com, Auger Eric , qemu-arm , Jonathan Cameron Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Note that this is simply emulation of the configuration space. Has the same issue with cut and paste code as the upstream port driver. Solution likely to be the same. Signed-off-by: Jonathan Cameron --- hw/pci-bridge/Makefile.objs | 2 +- hw/pci-bridge/ccix_downstream.c | 222 ++++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/hw/pci-bridge/Makefile.objs b/hw/pci-bridge/Makefile.objs index e266e39fed..78a49fb90b 100644 --- a/hw/pci-bridge/Makefile.objs +++ b/hw/pci-bridge/Makefile.objs @@ -8,4 +8,4 @@ common-obj-$(CONFIG_I82801B11) += i82801b11.o common-obj-$(CONFIG_DEC_PCI) += dec.o # Sun4u common-obj-$(CONFIG_SIMBA) += simba.o -common-obj-$(CONFIG_CCIX_SWITCH) += ccix_upstream.o +common-obj-$(CONFIG_CCIX_SWITCH) += ccix_upstream.o ccix_downstream.o diff --git a/hw/pci-bridge/ccix_downstream.c b/hw/pci-bridge/ccix_downstream.c new file mode 100644 index 0000000000..92c66431e2 --- /dev/null +++ b/hw/pci-bridge/ccix_downstream.c @@ -0,0 +1,222 @@ +/* + * ccix_downstream.c + * A PCIe downstream switch port with CCIX support. + * + * Copyright (c) 2019 Jonathan Cameron + * Huawei + * Based on: xio3130_downstream.c + * Copyright (c) 2010 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * 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 . + */ + +#include "qemu/osdep.h" +#include "hw/pci/pci_ids.h" +#include "hw/pci/msi.h" +#include "hw/pci/pcie.h" +#include "hw/pci/pcie_port.h" +#include "qapi/error.h" +#include "hw/misc/ccix.h" +#include "qemu/module.h" + +/* + * No public spec is available for a CCIX downstream port so for + * now use the values from teh xio3130 pcie downstream port + */ +#define XIO3130_MSI_OFFSET 0x70 +#define XIO3130_MSI_SUPPORTED_FLAGS PCI_MSI_FLAGS_64BIT +#define XIO3130_MSI_NR_VECTOR 1 +#define XIO3130_SSVID_OFFSET 0x80 +#define XIO3130_SSVID_SVID 0 +#define XIO3130_SSVID_SSID 0 +#define XIO3130_EXP_OFFSET 0x90 +#define XIO3130_AER_OFFSET 0x100 + +#define TYPE_CCIX_DOWN_PORT "ccix-downstream-port" + +#define CCIX_DOWN_DEV(obj) OBJECT_CHECK(CCIXDownPortState, (obj), TYPE_CCIX_DOWN_PORT) + +typedef struct CCIXDownPortState { + PCIESlot parent_obj; + struct CCIXState s; +} CCIXDownPortState; + +static void ccix_downstream_write_config(PCIDevice *d, uint32_t address, + uint32_t val, int len) +{ + CCIXDownPortState *s = CCIX_DOWN_DEV(d); + + pci_bridge_write_config(d, address, val, len); + pcie_cap_flr_write_config(d, address, val, len); + pcie_cap_slot_write_config(d, address, val, len); + pcie_aer_write_config(d, address, val, len); + ccix_write_config(d, &s->s, address, val, len); +} + +static void ccix_downstream_reset(DeviceState *qdev) +{ + PCIDevice *d = PCI_DEVICE(qdev); + + pcie_cap_deverr_reset(d); + pcie_cap_slot_reset(d); + pcie_cap_arifwd_reset(d); + pci_bridge_reset(qdev); +} + +static void ccix_downstream_realize(PCIDevice *d, Error **errp) +{ + PCIEPort *p = PCIE_PORT(d); + PCIESlot *s = PCIE_SLOT(d); + CCIXDownPortState *cs = CCIX_DOWN_DEV(d); + /* Allow space for existing extended capabilities from xio3130 */ + uint32_t offset = 0x180; + int rc; + + pci_bridge_initfn(d, TYPE_PCIE_BUS); + pcie_port_init_reg(d); + + rc = msi_init(d, XIO3130_MSI_OFFSET, XIO3130_MSI_NR_VECTOR, + XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_64BIT, + XIO3130_MSI_SUPPORTED_FLAGS & PCI_MSI_FLAGS_MASKBIT, + errp); + if (rc < 0) { + assert(rc == -ENOTSUP); + goto err_bridge; + } + + rc = pci_bridge_ssvid_init(d, XIO3130_SSVID_OFFSET, + XIO3130_SSVID_SVID, XIO3130_SSVID_SSID, + errp); + if (rc < 0) { + goto err_bridge; + } + + rc = pcie_cap_init(d, XIO3130_EXP_OFFSET, PCI_EXP_TYPE_DOWNSTREAM, + p->port, errp); + if (rc < 0) { + goto err_msi; + } + pcie_cap_flr_init(d); + pcie_cap_deverr_init(d); + pcie_cap_slot_init(d, s->slot); + pcie_cap_arifwd_init(d); + + pcie_chassis_create(s->chassis); + rc = pcie_chassis_add_slot(s); + if (rc < 0) { + error_setg(errp, "Can't add chassis slot, error %d", rc); + goto err_pcie_cap; + } + + rc = pcie_aer_init(d, PCI_ERR_VER, XIO3130_AER_OFFSET, + PCI_ERR_SIZEOF, errp); + if (rc < 0) { + goto err; + } + initialize_ccixstate(&cs->s, d); + ccix_set_port(&cs->s); + offset = ccix_add_prldvsec(d, &cs->s, offset); + ccix_add_tdldvsec(d, offset); + ccix_register(&cs->s); + + return; + +err: + pcie_chassis_del_slot(s); +err_pcie_cap: + pcie_cap_exit(d); +err_msi: + msi_uninit(d); +err_bridge: + pci_bridge_exitfn(d); +} + +static void ccix_downstream_exitfn(PCIDevice *d) +{ + PCIESlot *s = PCIE_SLOT(d); + + pcie_aer_exit(d); + pcie_chassis_del_slot(s); + pcie_cap_exit(d); + msi_uninit(d); + pci_bridge_exitfn(d); +} + +static Property ccix_props[] = { + DEFINE_PROP_STRING("ccix_device", CCIXDownPortState, s.ccix_dev_name), + DEFINE_PROP_BIT("primaryport", CCIXDownPortState, s.flags, PRIMARY_PORT_BIT, false), + DEFINE_PROP_UINT8("port_id", CCIXDownPortState, s.port_id, 0), + DEFINE_PROP_UINT8("num_links", CCIXDownPortState, s.num_links, 1), + DEFINE_PROP_UINT8("psam_entries", CCIXDownPortState, s.psam_entries, 0), + DEFINE_PROP_UINT8("request_agents", CCIXDownPortState, s.num_ras, 0), + DEFINE_PROP_UINT8("home_agents", CCIXDownPortState, s.num_has, 0), + DEFINE_PROP_UINT8("hsam_entries", CCIXDownPortState, s.hsam_entries, 0), + DEFINE_PROP_UINT8("rsam_entries", CCIXDownPortState, s.rsam_entries, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static const VMStateDescription vmstate_ccix_downstream = { + .name = "ccix-downstream-port", + .priority = MIG_PRI_PCI_BUS, + .version_id = 1, + .minimum_version_id = 1, + .post_load = pcie_cap_slot_post_load, + .fields = (VMStateField[]) { + VMSTATE_PCI_DEVICE(parent_obj.parent_obj.parent_obj, PCIESlot), + VMSTATE_STRUCT(parent_obj.parent_obj.parent_obj.exp.aer_log, + PCIESlot, 0, vmstate_pcie_aer_log, PCIEAERLog), + VMSTATE_END_OF_LIST() + } +}; + + +static void ccix_downstream_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->is_bridge = true; + k->config_write = ccix_downstream_write_config; + k->realize = ccix_downstream_realize; + k->exit = ccix_downstream_exitfn; + /* Temp values for the RFC */ + k->vendor_id = PCI_VENDOR_ID_HUAWEI; + k->device_id = PCI_DEVICE_ID_HUAWEI_CCIX_DOWN;; + k->revision = 1; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->desc = "CCIX / PCIE switch downstream port"; + dc->reset = ccix_downstream_reset; + dc->vmsd = &vmstate_ccix_downstream; + dc->props = ccix_props; +} + +static const TypeInfo ccix_downstream_info = { + .name = TYPE_CCIX_DOWN_PORT, + .parent = TYPE_PCIE_SLOT, + .class_init = ccix_downstream_class_init, + .instance_size = sizeof(CCIXDownPortState), + .interfaces = (InterfaceInfo[]) { + { INTERFACE_PCIE_DEVICE }, + { } + }, +}; + +static void ccix_downstream_register_types(void) +{ + type_register_static(&ccix_downstream_info); +} + +type_init(ccix_downstream_register_types) + From patchwork Tue Jun 25 11:27:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 167711 Delivered-To: patch@linaro.org Received: by 2002:a92:4782:0:0:0:0:0 with SMTP id e2csp5437642ilk; Tue, 25 Jun 2019 04:38:25 -0700 (PDT) X-Google-Smtp-Source: APXvYqx13mDpZrx9gYJaVyTyUHQ8q8/Ag/lc+ssXP/WIjp6Rs28xdgcHAku9RawHcHwnAJvmquB5 X-Received: by 2002:a17:906:158c:: with SMTP id k12mr25048747ejd.83.1561462705736; Tue, 25 Jun 2019 04:38:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561462705; cv=none; d=google.com; s=arc-20160816; b=dUQ7N/3hWE2xRZ1r4nGCoJ5P8ZX7HpyHfRDIokdFz9ZZP2IR/3f+MyWCtek8aN8ejE u9tIjNP5VVo8sFvhJFumo3K5JuASJtnfqAwxvUfQeN7tfYHH/2K2EJOmuPIa6c8DkZBk AEYInpU82WYzOSURagVLsZWrA6U24FihtMUTvjq+OzXK6Gwhl1Lkk2eVpqEp5vXpZDon gUcd0gaSwKA2XTANH90fDp6TpIaOhURi6m44R/bUYQyj+4N7cbfgCvJJUsaA3+LcD1Hh GDM9rfwzbGV7YGtOrs7N0pF6fcoSwI7/RqutOOpCvTEdzgqzB4IQfxbMvoDcQ+s08kWn OY4A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from; bh=vny0JeLY8068lnZq3ri7O4TG7cP/R0bH/2O5Tk6SOxU=; b=acsBOiV9yoojny99x7P8yXzOmEv3yfRtqyeC+M0SQGhlrKo3CHgC9ZXK3qiHkYpucg FZAY6QOvmsHxxilet2AOpy8S2xmhFaBZtWGT+R8bJ7O7LnFhfNvoua4MdkSTJ+XX9Bcd CnoUxxHK8R42Mf8A+NRdjUnvz/rtuwU/bSBJHmuQeglelwcy/dLRQj7w0FTg24EhRrEE 46yBLN2W6G4lyOFhhKsJF5kcCxxRVutJI5eG5UFfYMES4ZFqEYpak13y15Up+9wKB0d8 ErNC+lzfrdoyGxOpbJfCemdPSWEg8Sc/d+v/XNw+4GIF3CuENYoMdem7J0G3qG+0dtJe KBHw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id p2si150189ejf.202.2019.06.25.04.38.25 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 04:38:25 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:59064 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjmK-0000VZ-P3 for patch@linaro.org; Tue, 25 Jun 2019 07:38:24 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53761) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjdG-000775-Ma for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfjdF-0004Gi-31 for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:02 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:43142 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfjdA-000472-LJ; Tue, 25 Jun 2019 07:28:57 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 46FF97BF38E2C0BCB813; Tue, 25 Jun 2019 19:28:53 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.439.0; Tue, 25 Jun 2019 19:28:44 +0800 From: Jonathan Cameron To: QEMU Developers Date: Tue, 25 Jun 2019 19:27:51 +0800 Message-ID: <20190625112752.83188-7-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> References: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [RFC PATCH 6/7] misc: CCIX endpoint function 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: Peter Maydell , jcm@redhat.com, linuxarm@huawei.com, Auger Eric , qemu-arm , Jonathan Cameron Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" This handles the case where a given function is not also a PCIe topology upstream or downstream port. This include, non function 0 functions on upstream ports and any function on a device without a PCIe switch. Note that this doesn't exclude the possibility of this being the upstream port of a CCIX layer switch. Signed-off-by: Jonathan Cameron --- hw/misc/Kconfig | 5 ++ hw/misc/Makefile.objs | 1 + hw/misc/ccix-ep.c | 112 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 118 insertions(+) -- 2.20.1 diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig index 385e1b0cec..7aba167999 100644 --- a/hw/misc/Kconfig +++ b/hw/misc/Kconfig @@ -118,3 +118,8 @@ config AUX select I2C source macio/Kconfig + +config CCIX_EP + bool + select CCIX_LIB + \ No newline at end of file diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 77b9df9796..56a6cb3591 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -6,6 +6,7 @@ common-obj-$(CONFIG_ISA_DEBUG) += debugexit.o common-obj-$(CONFIG_SGA) += sga.o common-obj-$(CONFIG_ISA_TESTDEV) += pc-testdev.o common-obj-$(CONFIG_PCI_TESTDEV) += pci-testdev.o +common-obj-$(CONFIG_CCIX_EP) += ccix-ep.o common-obj-$(CONFIG_EDU) += edu.o common-obj-$(CONFIG_PCA9552) += pca9552.o diff --git a/hw/misc/ccix-ep.c b/hw/misc/ccix-ep.c new file mode 100644 index 0000000000..40a5b22dd8 --- /dev/null +++ b/hw/misc/ccix-ep.c @@ -0,0 +1,112 @@ +/* + * CCIX EP configuration space test device + * + * Copyright (c) 2019 Huawei + * Author: Jonathan Cameron + * + * Portions copied from pci-testdev.c + * Copyright (c) 2012 Red Hat Inc. + * Author: Michael S. Tsirkin + * + * 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 . + */ +#include "qemu/osdep.h" +#include "hw/hw.h" +#include "hw/pci/pci.h" +#include "qemu/event_notifier.h" +#include "sysemu/kvm.h" +#include "hw/misc/ccix.h" +#include "qemu/module.h" + +typedef struct CCIXEpState { + PCIDevice parent_obj; + struct CCIXState s; + +} CCIXEpState; + +#define TYPE_CCIX_EP "ccix-ep" +#define CCIX_EP_DEV(obj) OBJECT_CHECK(CCIXEpState, (obj), TYPE_CCIX_EP) + +static void ccix_ep_write_config(PCIDevice *pci_dev, uint32_t addr, + uint32_t val_in, int l) +{ + CCIXEpState *s = CCIX_EP_DEV(pci_dev); + + ccix_write_config(pci_dev, &s->s, addr, val_in, l); + pci_default_write_config(pci_dev, addr, val_in, l); +} + +static void ccix_ep_realize(PCIDevice *pci_dev, Error **errp) +{ + CCIXEpState *s = CCIX_EP_DEV(pci_dev); + int offset = PCI_CONFIG_SPACE_SIZE; + + if (PCI_FUNC(pci_dev->devfn) == 0) + ccix_set_port(&s->s); + initialize_ccixstate(&s->s, pci_dev); + pci_dev->config_write = ccix_ep_write_config; + pcie_endpoint_cap_init(pci_dev, 0); + offset = ccix_add_prldvsec(pci_dev, &s->s, offset); + if (s->s.flags & (1 << CCIX_IS_PORT)) + ccix_add_tdldvsec(pci_dev, offset); + + pci_dev->config[PCI_INTERRUPT_PIN] = 0; /* no interrupt pin */ + ccix_register(&s->s); +} + +static Property ccix_props[] = { + DEFINE_PROP_STRING("ccix_device", CCIXEpState, s.ccix_dev_name), + DEFINE_PROP_BIT("primaryport", CCIXEpState, s.flags, PRIMARY_PORT_BIT, true), + DEFINE_PROP_UINT8("port_id", CCIXEpState, s.port_id, 0), + DEFINE_PROP_UINT8("num_links", CCIXEpState, s.num_links, 1), + DEFINE_PROP_UINT8("psam_entries", CCIXEpState, s.psam_entries, 0), + DEFINE_PROP_UINT8("request_agents", CCIXEpState, s.num_ras, 0), + DEFINE_PROP_UINT8("home_agents", CCIXEpState, s.num_has, 0), + DEFINE_PROP_UINT8("hsam_entries", CCIXEpState, s.hsam_entries, 0), + DEFINE_PROP_UINT8("rsam_entries", CCIXEpState, s.rsam_entries, 0), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ccix_ep_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); + + k->realize = ccix_ep_realize; + k->vendor_id = PCI_VENDOR_ID_HUAWEI; + k->device_id = PCI_DEVICE_ID_HUAWEI_CCIX_EP; + k->revision = 0x00; + k->class_id = PCI_CLASS_OTHERS; + dc->desc = "CCIX EP Test Device"; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + dc->props = ccix_props; +} + +static const TypeInfo ccix_ep_info = { + .name = TYPE_CCIX_EP, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(CCIXEpState), + .class_init = ccix_ep_class_init, + .interfaces = (InterfaceInfo[]) { + { INTERFACE_PCIE_DEVICE }, + { }, + }, +}; + +static void ccix_register_types(void) +{ + type_register_static(&ccix_ep_info); +} + +type_init(ccix_register_types) From patchwork Tue Jun 25 11:27:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Cameron X-Patchwork-Id: 167704 Delivered-To: patch@linaro.org Received: by 2002:ac9:6410:0:0:0:0:0 with SMTP id r16csp4872299ock; Tue, 25 Jun 2019 04:32:22 -0700 (PDT) X-Google-Smtp-Source: APXvYqxIz5ki2yeF40lQIFIMbCEnNB4NKdD1Q/gE4sfogRB6keiPXdZ9HK/eC0eX6ptwkCPV4H1s X-Received: by 2002:a50:adec:: with SMTP id b41mr15484710edd.102.1561462342001; Tue, 25 Jun 2019 04:32:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1561462341; cv=none; d=google.com; s=arc-20160816; b=ZYYetgAfrhDV3JEpeHiXTOyc2UHjbjVyG2eP9tueoJ9BfNRNqTHr6CHHANwxcAidIj e3NN/kk9kxzny36j0uRaF2quGkOSh/T7401gIKC4eopTT4iTKCxP8R6+LyWqYggXwXuU D2tjgEaZuUfkr6h/YXaYc2OEsA73loB9JKUPbsk7WiYwoUmxamJ5FZS3aW4veFlpKXxS YapS2y2kZbXB6WSY6gQjrkP6D6kRaT2UexayPC58QAUR350YIQ69X6GHaQIUu/Nlcyir x9IeAhmLAt2OfUfjYlCxQsVHrzYU8ptZ9IYE0nseU+kkS07HWLkZgqvuG48hckW3M66N gsnQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from; bh=69jW7mbjQYW9ccov3gXjLPT5UAXOUyBx/gCsq3TvDJE=; b=pZjdqwCmWPYF6agducPBJptvkXYvKhiBEhZru8rchvJHsn6pwUCPN4qWGlJwpSNMOU x8ED9YinuTmcJxf9TfLBKqu/SuDG2BCaFbVA1KaKteDbOcLfm7zDziq4hNHtDnaZOhqp 88qI16kPgNhETyD0Wor+Uj6Fna54RjckhRrbDkK2kK331tg9RtdtHAPxa2NJ1mKEPUOm hQhK0/vFfsSygaVgw6SxidYKQf7uwaT+gQxdgJujqGoHy8A16x3+6FUqhzSyG9I5ig7z BoTXSssDzQjy92aLC+9alBf2Lbu3VMjl+4vKhodFdbGQH9RSs11x8eEhSrViwRJm3riX msZg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id g28si181239edc.275.2019.06.25.04.32.21 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 25 Jun 2019 04:32:21 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:59012 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjgT-0002vS-00 for patch@linaro.org; Tue, 25 Jun 2019 07:32:21 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53721) by lists.gnu.org with esmtp (Exim 4.86_2) (envelope-from ) id 1hfjdE-00071Z-9U for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hfjdD-0004Dw-9b for qemu-devel@nongnu.org; Tue, 25 Jun 2019 07:29:00 -0400 Received: from szxga06-in.huawei.com ([45.249.212.32]:43144 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hfjdA-000473-Eq; Tue, 25 Jun 2019 07:28:56 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 4D2265566C1C50019565; Tue, 25 Jun 2019 19:28:53 +0800 (CST) Received: from lhrphicprd00229.huawei.com (10.123.41.22) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.439.0; Tue, 25 Jun 2019 19:28:46 +0800 From: Jonathan Cameron To: QEMU Developers Date: Tue, 25 Jun 2019 19:27:52 +0800 Message-ID: <20190625112752.83188-8-Jonathan.Cameron@huawei.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> References: <20190625112752.83188-1-Jonathan.Cameron@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.123.41.22] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [RFC PATCH 7/7] Temp: Add to ARM64 makefiles for testing 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: Peter Maydell , jcm@redhat.com, linuxarm@huawei.com, Auger Eric , qemu-arm , Jonathan Cameron Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Jonathan Cameron --- default-configs/arm-softmmu.mak | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 2.20.1 diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak index 3158e1a10a..d5d4c8ecf1 100644 --- a/default-configs/arm-softmmu.mak +++ b/default-configs/arm-softmmu.mak @@ -41,4 +41,5 @@ CONFIG_FSL_IMX7=y CONFIG_FSL_IMX6UL=y CONFIG_SEMIHOSTING=y CONFIG_ACPI_APEI=y - +CONFIG_CCIX_LIB=y +CONFIG_CCIX_EP=y \ No newline at end of file