From nobody Fri Nov 7 02:18:01 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 154516272656463.97823379512761; Tue, 18 Dec 2018 11:52:06 -0800 (PST) Received: from localhost ([::1]:54860 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gZI7T-0005A9-PB for importer@patchew.org; Tue, 18 Dec 2018 11:21:19 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54130) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gZHys-0005kG-2g for qemu-devel@nongnu.org; Tue, 18 Dec 2018 11:12:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gZHyq-0002Ns-UB for qemu-devel@nongnu.org; Tue, 18 Dec 2018 11:12:26 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47128) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gZHyq-0002NN-LH for qemu-devel@nongnu.org; Tue, 18 Dec 2018 11:12:24 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C8363C0669CF; Tue, 18 Dec 2018 16:12:23 +0000 (UTC) Received: from redhat.com (ovpn-120-67.rdu2.redhat.com [10.10.120.67]) by smtp.corp.redhat.com (Postfix) with SMTP id 3DECC27C35; Tue, 18 Dec 2018 16:12:20 +0000 (UTC) Date: Tue, 18 Dec 2018 11:12:19 -0500 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Message-ID: <20181218161008.3882-13-mst@redhat.com> References: <20181218161008.3882-1-mst@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20181218161008.3882-1-mst@redhat.com> X-Mutt-Fcc: =sent X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 18 Dec 2018 16:12:23 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 12/30] qapi: Define PCIe link speed and width properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Geoffrey McRae , Peter Maydell , Alex Williamson , Markus Armbruster Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Alex Williamson Create properties to be able to define speeds and widths for PCIe links. The only tricky bit here is that our get and set callbacks translate from the fixed QAPI automagic enums to those we define in PCI code to represent the actual register segment value. Cc: Eric Blake Tested-by: Geoffrey McRae Reviewed-by: Markus Armbruster Signed-off-by: Alex Williamson Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- qapi/common.json | 42 +++++++++ include/hw/qdev-properties.h | 8 ++ hw/core/qdev-properties.c | 176 +++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) diff --git a/qapi/common.json b/qapi/common.json index 021174f04e..99d313ef3b 100644 --- a/qapi/common.json +++ b/qapi/common.json @@ -127,6 +127,48 @@ { 'enum': 'OffAutoPCIBAR', 'data': [ 'off', 'auto', 'bar0', 'bar1', 'bar2', 'bar3', 'bar4', 'bar5' = ] } =20 +## +# @PCIELinkSpeed: +# +# An enumeration of PCIe link speeds in units of GT/s +# +# @2_5: 2.5GT/s +# +# @5: 5.0GT/s +# +# @8: 8.0GT/s +# +# @16: 16.0GT/s +# +# Since: 4.0 +## +{ 'enum': 'PCIELinkSpeed', + 'data': [ '2_5', '5', '8', '16' ] } + +## +# @PCIELinkWidth: +# +# An enumeration of PCIe link width +# +# @1: x1 +# +# @2: x2 +# +# @4: x4 +# +# @8: x8 +# +# @12: x12 +# +# @16: x16 +# +# @32: x32 +# +# Since: 4.0 +## +{ 'enum': 'PCIELinkWidth', + 'data': [ '1', '2', '4', '8', '12', '16', '32' ] } + ## # @SysEmuTarget: # diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h index 3ab9cd2eb6..b6758c852e 100644 --- a/include/hw/qdev-properties.h +++ b/include/hw/qdev-properties.h @@ -36,6 +36,8 @@ extern const PropertyInfo qdev_prop_uuid; extern const PropertyInfo qdev_prop_arraylen; extern const PropertyInfo qdev_prop_link; extern const PropertyInfo qdev_prop_off_auto_pcibar; +extern const PropertyInfo qdev_prop_pcie_link_speed; +extern const PropertyInfo qdev_prop_pcie_link_width; =20 #define DEFINE_PROP(_name, _state, _field, _prop, _type) { \ .name =3D (_name), \ @@ -217,6 +219,12 @@ extern const PropertyInfo qdev_prop_off_auto_pcibar; #define DEFINE_PROP_OFF_AUTO_PCIBAR(_n, _s, _f, _d) \ DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_off_auto_pcibar, \ OffAutoPCIBAR) +#define DEFINE_PROP_PCIE_LINK_SPEED(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_speed, \ + PCIExpLinkSpeed) +#define DEFINE_PROP_PCIE_LINK_WIDTH(_n, _s, _f, _d) \ + DEFINE_PROP_SIGNED(_n, _s, _f, _d, qdev_prop_pcie_link_width, \ + PCIExpLinkWidth) =20 #define DEFINE_PROP_UUID(_name, _state, _field) { \ .name =3D (_name), \ diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c index bd84c4ea4c..943dc2654b 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -1297,3 +1297,179 @@ const PropertyInfo qdev_prop_off_auto_pcibar =3D { .set =3D set_enum, .set_default_value =3D set_default_value_enum, }; + +/* --- PCIELinkSpeed 2_5/5/8/16 -- */ + +static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *na= me, + void *opaque, Error **errp) +{ + DeviceState *dev =3D DEVICE(obj); + Property *prop =3D opaque; + PCIExpLinkSpeed *p =3D qdev_get_prop_ptr(dev, prop); + int speed; + + switch (*p) { + case QEMU_PCI_EXP_LNK_2_5GT: + speed =3D PCIE_LINK_SPEED_2_5; + break; + case QEMU_PCI_EXP_LNK_5GT: + speed =3D PCIE_LINK_SPEED_5; + break; + case QEMU_PCI_EXP_LNK_8GT: + speed =3D PCIE_LINK_SPEED_8; + break; + case QEMU_PCI_EXP_LNK_16GT: + speed =3D PCIE_LINK_SPEED_16; + break; + default: + /* Unreachable */ + abort(); + } + + visit_type_enum(v, prop->name, &speed, prop->info->enum_table, errp); +} + +static void set_prop_pcielinkspeed(Object *obj, Visitor *v, const char *na= me, + void *opaque, Error **errp) +{ + DeviceState *dev =3D DEVICE(obj); + Property *prop =3D opaque; + PCIExpLinkSpeed *p =3D qdev_get_prop_ptr(dev, prop); + int speed; + Error *local_err =3D NULL; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_enum(v, prop->name, &speed, prop->info->enum_table, &local_= err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + switch (speed) { + case PCIE_LINK_SPEED_2_5: + *p =3D QEMU_PCI_EXP_LNK_2_5GT; + break; + case PCIE_LINK_SPEED_5: + *p =3D QEMU_PCI_EXP_LNK_5GT; + break; + case PCIE_LINK_SPEED_8: + *p =3D QEMU_PCI_EXP_LNK_8GT; + break; + case PCIE_LINK_SPEED_16: + *p =3D QEMU_PCI_EXP_LNK_16GT; + break; + default: + /* Unreachable */ + abort(); + } +} + +const PropertyInfo qdev_prop_pcie_link_speed =3D { + .name =3D "PCIELinkSpeed", + .description =3D "2_5/5/8/16", + .enum_table =3D &PCIELinkSpeed_lookup, + .get =3D get_prop_pcielinkspeed, + .set =3D set_prop_pcielinkspeed, + .set_default_value =3D set_default_value_enum, +}; + +/* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */ + +static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *na= me, + void *opaque, Error **errp) +{ + DeviceState *dev =3D DEVICE(obj); + Property *prop =3D opaque; + PCIExpLinkWidth *p =3D qdev_get_prop_ptr(dev, prop); + int width; + + switch (*p) { + case QEMU_PCI_EXP_LNK_X1: + width =3D PCIE_LINK_WIDTH_1; + break; + case QEMU_PCI_EXP_LNK_X2: + width =3D PCIE_LINK_WIDTH_2; + break; + case QEMU_PCI_EXP_LNK_X4: + width =3D PCIE_LINK_WIDTH_4; + break; + case QEMU_PCI_EXP_LNK_X8: + width =3D PCIE_LINK_WIDTH_8; + break; + case QEMU_PCI_EXP_LNK_X12: + width =3D PCIE_LINK_WIDTH_12; + break; + case QEMU_PCI_EXP_LNK_X16: + width =3D PCIE_LINK_WIDTH_16; + break; + case QEMU_PCI_EXP_LNK_X32: + width =3D PCIE_LINK_WIDTH_32; + break; + default: + /* Unreachable */ + abort(); + } + + visit_type_enum(v, prop->name, &width, prop->info->enum_table, errp); +} + +static void set_prop_pcielinkwidth(Object *obj, Visitor *v, const char *na= me, + void *opaque, Error **errp) +{ + DeviceState *dev =3D DEVICE(obj); + Property *prop =3D opaque; + PCIExpLinkWidth *p =3D qdev_get_prop_ptr(dev, prop); + int width; + Error *local_err =3D NULL; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_enum(v, prop->name, &width, prop->info->enum_table, &local_= err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + switch (width) { + case PCIE_LINK_WIDTH_1: + *p =3D QEMU_PCI_EXP_LNK_X1; + break; + case PCIE_LINK_WIDTH_2: + *p =3D QEMU_PCI_EXP_LNK_X2; + break; + case PCIE_LINK_WIDTH_4: + *p =3D QEMU_PCI_EXP_LNK_X4; + break; + case PCIE_LINK_WIDTH_8: + *p =3D QEMU_PCI_EXP_LNK_X8; + break; + case PCIE_LINK_WIDTH_12: + *p =3D QEMU_PCI_EXP_LNK_X12; + break; + case PCIE_LINK_WIDTH_16: + *p =3D QEMU_PCI_EXP_LNK_X16; + break; + case PCIE_LINK_WIDTH_32: + *p =3D QEMU_PCI_EXP_LNK_X32; + break; + default: + /* Unreachable */ + abort(); + } +} + +const PropertyInfo qdev_prop_pcie_link_width =3D { + .name =3D "PCIELinkWidth", + .description =3D "1/2/4/8/12/16/32", + .enum_table =3D &PCIELinkWidth_lookup, + .get =3D get_prop_pcielinkwidth, + .set =3D set_prop_pcielinkwidth, + .set_default_value =3D set_default_value_enum, +}; --=20 MST