aboutsummaryrefslogtreecommitdiff
path: root/hw/core/qdev-properties.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/core/qdev-properties.c')
-rw-r--r--hw/core/qdev-properties.c176
1 files changed, 176 insertions, 0 deletions
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 = {
.set = set_enum,
.set_default_value = set_default_value_enum,
};
+
+/* --- PCIELinkSpeed 2_5/5/8/16 -- */
+
+static void get_prop_pcielinkspeed(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+ int speed;
+
+ switch (*p) {
+ case QEMU_PCI_EXP_LNK_2_5GT:
+ speed = PCIE_LINK_SPEED_2_5;
+ break;
+ case QEMU_PCI_EXP_LNK_5GT:
+ speed = PCIE_LINK_SPEED_5;
+ break;
+ case QEMU_PCI_EXP_LNK_8GT:
+ speed = PCIE_LINK_SPEED_8;
+ break;
+ case QEMU_PCI_EXP_LNK_16GT:
+ speed = 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 *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkSpeed *p = qdev_get_prop_ptr(dev, prop);
+ int speed;
+ Error *local_err = 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 = QEMU_PCI_EXP_LNK_2_5GT;
+ break;
+ case PCIE_LINK_SPEED_5:
+ *p = QEMU_PCI_EXP_LNK_5GT;
+ break;
+ case PCIE_LINK_SPEED_8:
+ *p = QEMU_PCI_EXP_LNK_8GT;
+ break;
+ case PCIE_LINK_SPEED_16:
+ *p = QEMU_PCI_EXP_LNK_16GT;
+ break;
+ default:
+ /* Unreachable */
+ abort();
+ }
+}
+
+const PropertyInfo qdev_prop_pcie_link_speed = {
+ .name = "PCIELinkSpeed",
+ .description = "2_5/5/8/16",
+ .enum_table = &PCIELinkSpeed_lookup,
+ .get = get_prop_pcielinkspeed,
+ .set = set_prop_pcielinkspeed,
+ .set_default_value = set_default_value_enum,
+};
+
+/* --- PCIELinkWidth 1/2/4/8/12/16/32 -- */
+
+static void get_prop_pcielinkwidth(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+ int width;
+
+ switch (*p) {
+ case QEMU_PCI_EXP_LNK_X1:
+ width = PCIE_LINK_WIDTH_1;
+ break;
+ case QEMU_PCI_EXP_LNK_X2:
+ width = PCIE_LINK_WIDTH_2;
+ break;
+ case QEMU_PCI_EXP_LNK_X4:
+ width = PCIE_LINK_WIDTH_4;
+ break;
+ case QEMU_PCI_EXP_LNK_X8:
+ width = PCIE_LINK_WIDTH_8;
+ break;
+ case QEMU_PCI_EXP_LNK_X12:
+ width = PCIE_LINK_WIDTH_12;
+ break;
+ case QEMU_PCI_EXP_LNK_X16:
+ width = PCIE_LINK_WIDTH_16;
+ break;
+ case QEMU_PCI_EXP_LNK_X32:
+ width = 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 *name,
+ void *opaque, Error **errp)
+{
+ DeviceState *dev = DEVICE(obj);
+ Property *prop = opaque;
+ PCIExpLinkWidth *p = qdev_get_prop_ptr(dev, prop);
+ int width;
+ Error *local_err = 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 = QEMU_PCI_EXP_LNK_X1;
+ break;
+ case PCIE_LINK_WIDTH_2:
+ *p = QEMU_PCI_EXP_LNK_X2;
+ break;
+ case PCIE_LINK_WIDTH_4:
+ *p = QEMU_PCI_EXP_LNK_X4;
+ break;
+ case PCIE_LINK_WIDTH_8:
+ *p = QEMU_PCI_EXP_LNK_X8;
+ break;
+ case PCIE_LINK_WIDTH_12:
+ *p = QEMU_PCI_EXP_LNK_X12;
+ break;
+ case PCIE_LINK_WIDTH_16:
+ *p = QEMU_PCI_EXP_LNK_X16;
+ break;
+ case PCIE_LINK_WIDTH_32:
+ *p = QEMU_PCI_EXP_LNK_X32;
+ break;
+ default:
+ /* Unreachable */
+ abort();
+ }
+}
+
+const PropertyInfo qdev_prop_pcie_link_width = {
+ .name = "PCIELinkWidth",
+ .description = "1/2/4/8/12/16/32",
+ .enum_table = &PCIELinkWidth_lookup,
+ .get = get_prop_pcielinkwidth,
+ .set = set_prop_pcielinkwidth,
+ .set_default_value = set_default_value_enum,
+};