All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
@ 2014-06-12  6:22 Eduardo Habkost
  2014-06-12  8:02 ` Igor Mammedov
  2014-06-12  8:13 ` Michael S. Tsirkin
  0 siblings, 2 replies; 10+ messages in thread
From: Eduardo Habkost @ 2014-06-12  6:22 UTC (permalink / raw)
  To: qemu-devel, Michael S. Tsirkin
  Cc: Alexander Graf, Anthony Liguori, Andreas Färber, Don Slutz,
	Marcel Apfelbaum

This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
definitions to corresponding class registration code.

Having the PC code converted to pure QOM registration code will help us
move PC-specific machine state that is currently held in static
variables inside PC machine objects, and reduce duplication between
pc_piix.c and pc_q35.c.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/i386/pc.c         |  13 ++
 hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
 hw/i386/pc_q35.c     | 171 +++++++++++++------
 include/hw/i386/pc.h |  20 ++-
 4 files changed, 465 insertions(+), 212 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 32d1632..56720cd 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
         gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
     }
 }
+
+static TypeInfo pc_machine_type_info = {
+        .name       = TYPE_PC_MACHINE,
+        .parent     = TYPE_MACHINE,
+        .abstract   = true,
+};
+
+static void pc_machine_init(void)
+{
+    type_register_static(&pc_machine_type_info);
+}
+
+type_init(pc_machine_init);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a48e263..d4b4033 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -392,81 +392,140 @@ static void pc_xen_hvm_init(MachineState *machine)
 }
 #endif
 
-#define PC_I440FX_MACHINE_OPTIONS \
-    PC_DEFAULT_MACHINE_OPTIONS, \
-    .desc = "Standard PC (i440FX + PIIX, 1996)", \
-    .hot_add_cpu = pc_hot_add_cpu
-
-#define PC_I440FX_2_1_MACHINE_OPTIONS                           \
-    PC_I440FX_MACHINE_OPTIONS,                                  \
-    .default_machine_opts = "firmware=bios-256k.bin"
-
-static QEMUMachine pc_i440fx_machine_v2_1 = {
-    PC_I440FX_2_1_MACHINE_OPTIONS,
-    .name = "pc-i440fx-2.1",
-    .alias = "pc",
-    .init = pc_init_pci,
-    .is_default = 1,
+static void pc_i440fx_machine_options(MachineClass *mc)
+{
+    pc_default_machine_options(mc);
+    mc->desc = "Standard PC (i440FX + PIIX, 1996)";
+    mc->hot_add_cpu = pc_hot_add_cpu;
+}
+
+static void pc_i440fx_2_1_machine_options(MachineClass *mc)
+{
+    pc_i440fx_machine_options(mc);
+    mc->default_machine_opts = "firmware=bios-256k.bin";
+}
+
+static void pc_i440fx_machine_v2_1_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    pc_i440fx_2_1_machine_options(mc);
+    mc->alias = "pc";
+    mc->init = pc_init_pci;
+    mc->is_default = 1;
+    mc->name = "pc-i440fx-2.1";
+}
+
+static TypeInfo pc_i440fx_machine_v2_1_type_info = {
+    .name = "pc-i440fx-2.1" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_i440fx_machine_v2_1_class_init,
 };
 
-#define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS
+#define pc_i440fx_2_0_machine_options pc_i440fx_2_1_machine_options
 
-static QEMUMachine pc_i440fx_machine_v2_0 = {
-    PC_I440FX_2_0_MACHINE_OPTIONS,
-    .name = "pc-i440fx-2.0",
-    .init = pc_init_pci_2_0,
-    .compat_props = (GlobalProperty[]) {
+static void pc_i440fx_machine_v2_0_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_2_0,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_2_0_machine_options(mc);
+    mc->init = pc_init_pci_2_0;
+    mc->compat_props = compat_props;
+    mc->name = "pc-i440fx-2.0";
+}
+
+static TypeInfo pc_i440fx_machine_v2_0_type_info = {
+    .name = "pc-i440fx-2.0" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_i440fx_machine_v2_0_class_init,
 };
 
-#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
+#define pc_i440fx_1_7_machine_options pc_i440fx_machine_options
 
-static QEMUMachine pc_i440fx_machine_v1_7 = {
-    PC_I440FX_1_7_MACHINE_OPTIONS,
-    .name = "pc-i440fx-1.7",
-    .init = pc_init_pci_1_7,
-    .compat_props = (GlobalProperty[]) {
+static void pc_i440fx_machine_v1_7_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_7,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_1_7_machine_options(mc);
+    mc->init = pc_init_pci_1_7;
+    mc->compat_props = compat_props;
+    mc->name = "pc-i440fx-1.7";
+}
+
+static TypeInfo pc_i440fx_machine_v1_7_type_info = {
+    .name = "pc-i440fx-1.7" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_i440fx_machine_v1_7_class_init,
 };
 
-#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
+#define pc_i440fx_1_6_machine_options pc_i440fx_machine_options
 
-static QEMUMachine pc_i440fx_machine_v1_6 = {
-    PC_I440FX_1_6_MACHINE_OPTIONS,
-    .name = "pc-i440fx-1.6",
-    .init = pc_init_pci_1_6,
-    .compat_props = (GlobalProperty[]) {
+static void pc_i440fx_machine_v1_6_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_6,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_1_6_machine_options(mc);
+    mc->init = pc_init_pci_1_6;
+    mc->compat_props = compat_props;
+    mc->name = "pc-i440fx-1.6";
+}
+
+static TypeInfo pc_i440fx_machine_v1_6_type_info = {
+    .name = "pc-i440fx-1.6" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_i440fx_machine_v1_6_class_init,
 };
 
-static QEMUMachine pc_i440fx_machine_v1_5 = {
-    PC_I440FX_1_6_MACHINE_OPTIONS,
-    .name = "pc-i440fx-1.5",
-    .init = pc_init_pci_1_5,
-    .compat_props = (GlobalProperty[]) {
+static void pc_i440fx_machine_v1_5_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_5,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_1_6_machine_options(mc);
+    mc->init = pc_init_pci_1_5;
+    mc->compat_props = compat_props;
+    mc->name = "pc-i440fx-1.5";
+}
+
+static TypeInfo pc_i440fx_machine_v1_5_type_info = {
+    .name = "pc-i440fx-1.5" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_i440fx_machine_v1_5_class_init,
 };
 
-#define PC_I440FX_1_4_MACHINE_OPTIONS \
-    PC_I440FX_1_6_MACHINE_OPTIONS, \
-    .hot_add_cpu = NULL
+static void pc_i440fx_1_4_machine_options(MachineClass *mc)
+{
+    pc_i440fx_1_6_machine_options(mc);
+    mc->hot_add_cpu = NULL;
+}
 
-static QEMUMachine pc_i440fx_machine_v1_4 = {
-    PC_I440FX_1_4_MACHINE_OPTIONS,
-    .name = "pc-i440fx-1.4",
-    .init = pc_init_pci_1_4,
-    .compat_props = (GlobalProperty[]) {
+static void pc_i440fx_machine_v1_4_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_4,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_1_4_machine_options(mc);
+    mc->init = pc_init_pci_1_4;
+    mc->compat_props = compat_props;
+    mc->name = "pc-i440fx-1.4";
+}
+
+static TypeInfo pc_i440fx_machine_v1_4_type_info = {
+    .name = "pc-i440fx-1.4" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_i440fx_machine_v1_4_class_init,
 };
 
 #define PC_COMPAT_1_3 \
@@ -489,14 +548,23 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
             .value    = "off",\
         }
 
-static QEMUMachine pc_machine_v1_3 = {
-    PC_I440FX_1_4_MACHINE_OPTIONS,
-    .name = "pc-1.3",
-    .init = pc_init_pci_1_3,
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v1_3_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_3,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_1_4_machine_options(mc);
+    mc->init = pc_init_pci_1_3;
+    mc->compat_props = compat_props;
+    mc->name = "pc-1.3";
+}
+
+static TypeInfo pc_machine_v1_3_type_info = {
+    .name = "pc-1.3" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v1_3_class_init,
 };
 
 #define PC_COMPAT_1_2 \
@@ -527,17 +595,28 @@ static QEMUMachine pc_machine_v1_3 = {
             .value    = "off",\
         }
 
-#define PC_I440FX_1_2_MACHINE_OPTIONS \
-    PC_I440FX_1_4_MACHINE_OPTIONS, \
-    .init = pc_init_pci_1_2
+static void pc_i440fx_1_2_machine_options(MachineClass *mc)
+{
+    pc_i440fx_1_4_machine_options(mc);
+    mc->init = pc_init_pci_1_2;
+}
 
-static QEMUMachine pc_machine_v1_2 = {
-    PC_I440FX_1_2_MACHINE_OPTIONS,
-    .name = "pc-1.2",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v1_2_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_2,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_1_2_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->name = "pc-1.2";
+}
+
+static TypeInfo pc_machine_v1_2_type_info = {
+    .name = "pc-1.2" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v1_2_class_init,
 };
 
 #define PC_COMPAT_1_1 \
@@ -572,13 +651,22 @@ static QEMUMachine pc_machine_v1_2 = {
             .value    = "off",\
         }
 
-static QEMUMachine pc_machine_v1_1 = {
-    PC_I440FX_1_2_MACHINE_OPTIONS,
-    .name = "pc-1.1",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v1_1_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_1,
         { /* end of list */ }
-    },
+    };
+    pc_i440fx_1_2_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->name = "pc-1.1";
+}
+
+static TypeInfo pc_machine_v1_1_type_info = {
+    .name = "pc-1.1" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v1_1_class_init,
 };
 
 #define PC_COMPAT_1_0 \
@@ -601,27 +689,45 @@ static QEMUMachine pc_machine_v1_1 = {
             .value    = "no",\
         }
 
-static QEMUMachine pc_machine_v1_0 = {
-    PC_I440FX_1_2_MACHINE_OPTIONS,
-    .name = "pc-1.0",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v1_0_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_0,
         { /* end of list */ }
-    },
-    .hw_version = "1.0",
+    };
+    pc_i440fx_1_2_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->hw_version = "1.0";
+    mc->name = "pc-1.0";
+}
+
+static TypeInfo pc_machine_v1_0_type_info = {
+    .name = "pc-1.0" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v1_0_class_init,
 };
 
 #define PC_COMPAT_0_15 \
         PC_COMPAT_1_0
 
-static QEMUMachine pc_machine_v0_15 = {
-    PC_I440FX_1_2_MACHINE_OPTIONS,
-    .name = "pc-0.15",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v0_15_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_0_15,
         { /* end of list */ }
-    },
-    .hw_version = "0.15",
+    };
+    pc_i440fx_1_2_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->hw_version = "0.15";
+    mc->name = "pc-0.15";
+}
+
+static TypeInfo pc_machine_v0_15_type_info = {
+    .name = "pc-0.15" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v0_15_class_init,
 };
 
 #define PC_COMPAT_0_14 \
@@ -644,10 +750,10 @@ static QEMUMachine pc_machine_v0_15 = {
             .value    = "off",\
         }
 
-static QEMUMachine pc_machine_v0_14 = {
-    PC_I440FX_1_2_MACHINE_OPTIONS,
-    .name = "pc-0.14",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v0_14_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_0_14, 
         {
             .driver   = "qxl",
@@ -659,8 +765,17 @@ static QEMUMachine pc_machine_v0_14 = {
             .value    = stringify(2),
         },
         { /* end of list */ }
-    },
-    .hw_version = "0.14",
+    };
+    pc_i440fx_1_2_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->hw_version = "0.14";
+    mc->name = "pc-0.14";
+}
+
+static TypeInfo pc_machine_v0_14_type_info = {
+    .name = "pc-0.14" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v0_14_class_init,
 };
 
 #define PC_COMPAT_0_13 \
@@ -675,14 +790,16 @@ static QEMUMachine pc_machine_v0_14 = {
             .value    = stringify(1),\
         }
 
-#define PC_I440FX_0_13_MACHINE_OPTIONS \
-    PC_I440FX_1_2_MACHINE_OPTIONS, \
-    .init = pc_init_pci_no_kvmclock
+static void pc_i440fx_0_13_machine_options(MachineClass *mc)
+{
+    pc_i440fx_1_2_machine_options(mc);
+    mc->init = pc_init_pci_no_kvmclock;
+}
 
-static QEMUMachine pc_machine_v0_13 = {
-    PC_I440FX_0_13_MACHINE_OPTIONS,
-    .name = "pc-0.13",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v0_13_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_0_13,
         {
             .driver   = "virtio-9p-pci",
@@ -698,8 +815,17 @@ static QEMUMachine pc_machine_v0_13 = {
             .value    = stringify(0),
         },
         { /* end of list */ }
-    },
-    .hw_version = "0.13",
+    };
+    pc_i440fx_0_13_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->hw_version = "0.13";
+    mc->name = "pc-0.13";
+}
+
+static TypeInfo pc_machine_v0_13_type_info = {
+    .name = "pc-0.13" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v0_13_class_init,
 };
 
 #define PC_COMPAT_0_12 \
@@ -726,10 +852,10 @@ static QEMUMachine pc_machine_v0_13 = {
             .value    = "1",\
         }
 
-static QEMUMachine pc_machine_v0_12 = {
-    PC_I440FX_0_13_MACHINE_OPTIONS,
-    .name = "pc-0.12",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v0_12_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_0_12,
         {
             .driver   = "VGA",
@@ -741,8 +867,17 @@ static QEMUMachine pc_machine_v0_12 = {
             .value    = stringify(0),
         },
         { /* end of list */ }
-    },
-    .hw_version = "0.12",
+    };
+    pc_i440fx_0_13_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->hw_version = "0.12";
+    mc->name = "pc-0.12";
+}
+
+static TypeInfo pc_machine_v0_12_type_info = {
+    .name = "pc-0.12" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v0_12_class_init,
 };
 
 #define PC_COMPAT_0_11 \
@@ -757,10 +892,10 @@ static QEMUMachine pc_machine_v0_12 = {
             .value    = stringify(0),\
         }
 
-static QEMUMachine pc_machine_v0_11 = {
-    PC_I440FX_0_13_MACHINE_OPTIONS,
-    .name = "pc-0.11",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v0_11_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_0_11,
         {
             .driver   = "ide-drive",
@@ -772,14 +907,23 @@ static QEMUMachine pc_machine_v0_11 = {
             .value    = "0.11",
         },
         { /* end of list */ }
-    },
-    .hw_version = "0.11",
+    };
+    pc_i440fx_0_13_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->hw_version = "0.11";
+    mc->name = "pc-0.11";
+}
+
+static TypeInfo pc_machine_v0_11_type_info = {
+    .name = "pc-0.11" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v0_11_class_init,
 };
 
-static QEMUMachine pc_machine_v0_10 = {
-    PC_I440FX_0_13_MACHINE_OPTIONS,
-    .name = "pc-0.10",
-    .compat_props = (GlobalProperty[]) {
+static void pc_machine_v0_10_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_0_11,
         {
             .driver   = "virtio-blk-pci",
@@ -803,31 +947,44 @@ static QEMUMachine pc_machine_v0_10 = {
             .value    = "0.10",
         },
         { /* end of list */ }
-    },
-    .hw_version = "0.10",
+    };
+    pc_i440fx_0_13_machine_options(mc);
+    mc->compat_props = compat_props;
+    mc->hw_version = "0.10";
+    mc->name = "pc-0.10";
+}
+
+static TypeInfo pc_machine_v0_10_type_info = {
+    .name = "pc-0.10" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_machine_v0_10_class_init,
 };
 
-static QEMUMachine isapc_machine = {
-    PC_COMMON_MACHINE_OPTIONS,
-    .name = "isapc",
-    .desc = "ISA-only PC",
-    .init = pc_init_isa,
-    .max_cpus = 1,
-    .compat_props = (GlobalProperty[]) {
+static void isapc_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         { /* end of list */ }
-    },
+    };
+    pc_common_machine_options(mc);
+    mc->desc = "ISA-only PC";
+    mc->init = pc_init_isa;
+    mc->max_cpus = 1;
+    mc->compat_props = compat_props;
+    mc->name = "isapc";
+}
+
+static TypeInfo isapc_machine_type_info = {
+    .name = "isapc" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = isapc_machine_class_init,
 };
 
 #ifdef CONFIG_XEN
-static QEMUMachine xenfv_machine = {
-    PC_COMMON_MACHINE_OPTIONS,
-    .name = "xenfv",
-    .desc = "Xen Fully-virtualized PC",
-    .init = pc_xen_hvm_init,
-    .max_cpus = HVM_MAX_VCPUS,
-    .default_machine_opts = "accel=xen",
-    .hot_add_cpu = pc_hot_add_cpu,
-    .compat_props = (GlobalProperty[]) {
+static void xenfv_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         /* xenfv has no fwcfg and so does not load acpi from QEMU.
          * as such new acpi features don't work.
          */
@@ -837,31 +994,45 @@ static QEMUMachine xenfv_machine = {
             .value    = "off",
         },
         { /* end of list */ }
-    },
+    };
+    pc_common_machine_options(mc);
+    mc->desc = "Xen Fully-virtualized PC";
+    mc->init = pc_xen_hvm_init;
+    mc->max_cpus = HVM_MAX_VCPUS;
+    mc->default_machine_opts = "accel=xen";
+    mc->hot_add_cpu = pc_hot_add_cpu;
+    mc->compat_props = compat_props;
+    mc->name = "xenfv";
+}
+
+static TypeInfo xenfv_machine_type_info = {
+    .name = "xenfv" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = xenfv_machine_class_init,
 };
 #endif
 
 static void pc_machine_init(void)
 {
-    qemu_register_machine(&pc_i440fx_machine_v2_1);
-    qemu_register_machine(&pc_i440fx_machine_v2_0);
-    qemu_register_machine(&pc_i440fx_machine_v1_7);
-    qemu_register_machine(&pc_i440fx_machine_v1_6);
-    qemu_register_machine(&pc_i440fx_machine_v1_5);
-    qemu_register_machine(&pc_i440fx_machine_v1_4);
-    qemu_register_machine(&pc_machine_v1_3);
-    qemu_register_machine(&pc_machine_v1_2);
-    qemu_register_machine(&pc_machine_v1_1);
-    qemu_register_machine(&pc_machine_v1_0);
-    qemu_register_machine(&pc_machine_v0_15);
-    qemu_register_machine(&pc_machine_v0_14);
-    qemu_register_machine(&pc_machine_v0_13);
-    qemu_register_machine(&pc_machine_v0_12);
-    qemu_register_machine(&pc_machine_v0_11);
-    qemu_register_machine(&pc_machine_v0_10);
-    qemu_register_machine(&isapc_machine);
+    type_register_static(&pc_i440fx_machine_v2_1_type_info);
+    type_register_static(&pc_i440fx_machine_v2_0_type_info);
+    type_register_static(&pc_i440fx_machine_v1_7_type_info);
+    type_register_static(&pc_i440fx_machine_v1_6_type_info);
+    type_register_static(&pc_i440fx_machine_v1_5_type_info);
+    type_register_static(&pc_i440fx_machine_v1_4_type_info);
+    type_register_static(&pc_machine_v1_3_type_info);
+    type_register_static(&pc_machine_v1_2_type_info);
+    type_register_static(&pc_machine_v1_1_type_info);
+    type_register_static(&pc_machine_v1_0_type_info);
+    type_register_static(&pc_machine_v0_15_type_info);
+    type_register_static(&pc_machine_v0_14_type_info);
+    type_register_static(&pc_machine_v0_13_type_info);
+    type_register_static(&pc_machine_v0_12_type_info);
+    type_register_static(&pc_machine_v0_11_type_info);
+    type_register_static(&pc_machine_v0_10_type_info);
+    type_register_static(&isapc_machine_type_info);
 #ifdef CONFIG_XEN
-    qemu_register_machine(&xenfv_machine);
+    type_register_static(&xenfv_machine_type_info);
 #endif
 }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index b3c02c1..6e909f7 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -306,90 +306,149 @@ static void pc_q35_init_1_4(MachineState *machine)
     pc_q35_init(machine);
 }
 
-#define PC_Q35_MACHINE_OPTIONS \
-    PC_DEFAULT_MACHINE_OPTIONS, \
-    .desc = "Standard PC (Q35 + ICH9, 2009)", \
-    .hot_add_cpu = pc_hot_add_cpu
-
-#define PC_Q35_2_1_MACHINE_OPTIONS                      \
-    PC_Q35_MACHINE_OPTIONS,                             \
-    .default_machine_opts = "firmware=bios-256k.bin"
-
-static QEMUMachine pc_q35_machine_v2_1 = {
-    PC_Q35_2_1_MACHINE_OPTIONS,
-    .name = "pc-q35-2.1",
-    .alias = "q35",
-    .init = pc_q35_init,
+static void pc_q35_machine_options(MachineClass *mc)
+{
+    pc_default_machine_options(mc);
+    mc->desc = "Standard PC (Q35 + ICH9, 2009)";
+    mc->hot_add_cpu = pc_hot_add_cpu;
+}
+
+static void pc_q35_2_1_machine_options(MachineClass *mc)
+{
+    pc_q35_machine_options(mc);
+    mc->default_machine_opts = "firmware=bios-256k.bin";
+}
+
+static void pc_q35_machine_v2_1_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    pc_q35_2_1_machine_options(mc);
+    mc->alias = "q35";
+    mc->init = pc_q35_init;
+    mc->name = "pc-q35-2.1";
+}
+
+static TypeInfo pc_q35_machine_v2_1_type_info = {
+    .name = "pc-q35-2.1" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_q35_machine_v2_1_class_init,
 };
 
-#define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS
+#define pc_q35_2_0_machine_options pc_q35_2_1_machine_options
 
-static QEMUMachine pc_q35_machine_v2_0 = {
-    PC_Q35_2_0_MACHINE_OPTIONS,
-    .name = "pc-q35-2.0",
-    .init = pc_q35_init_2_0,
-    .compat_props = (GlobalProperty[]) {
+static void pc_q35_machine_v2_0_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_Q35_COMPAT_2_0,
         { /* end of list */ }
-    },
+    };
+    pc_q35_2_0_machine_options(mc);
+    mc->init = pc_q35_init_2_0;
+    mc->compat_props = compat_props;
+    mc->name = "pc-q35-2.0";
+}
+
+static TypeInfo pc_q35_machine_v2_0_type_info = {
+    .name = "pc-q35-2.0" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_q35_machine_v2_0_class_init,
 };
 
-#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
+#define pc_q35_1_7_machine_options pc_q35_machine_options
 
-static QEMUMachine pc_q35_machine_v1_7 = {
-    PC_Q35_1_7_MACHINE_OPTIONS,
-    .name = "pc-q35-1.7",
-    .init = pc_q35_init_1_7,
-    .compat_props = (GlobalProperty[]) {
+static void pc_q35_machine_v1_7_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_Q35_COMPAT_1_7,
         { /* end of list */ }
-    },
+    };
+    pc_q35_1_7_machine_options(mc);
+    mc->init = pc_q35_init_1_7;
+    mc->compat_props = compat_props;
+    mc->name = "pc-q35-1.7";
+}
+
+static TypeInfo pc_q35_machine_v1_7_type_info = {
+    .name = "pc-q35-1.7" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_q35_machine_v1_7_class_init,
 };
 
-#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
+#define pc_q35_1_6_machine_options pc_q35_machine_options
 
-static QEMUMachine pc_q35_machine_v1_6 = {
-    PC_Q35_1_6_MACHINE_OPTIONS,
-    .name = "pc-q35-1.6",
-    .init = pc_q35_init_1_6,
-    .compat_props = (GlobalProperty[]) {
+static void pc_q35_machine_v1_6_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_Q35_COMPAT_1_6,
         { /* end of list */ }
-    },
+    };
+    pc_q35_1_6_machine_options(mc);
+    mc->init = pc_q35_init_1_6;
+    mc->compat_props = compat_props;
+    mc->name = "pc-q35-1.6";
+}
+
+static TypeInfo pc_q35_machine_v1_6_type_info = {
+    .name = "pc-q35-1.6" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_q35_machine_v1_6_class_init,
 };
 
-static QEMUMachine pc_q35_machine_v1_5 = {
-    PC_Q35_1_6_MACHINE_OPTIONS,
-    .name = "pc-q35-1.5",
-    .init = pc_q35_init_1_5,
-    .compat_props = (GlobalProperty[]) {
+static void pc_q35_machine_v1_5_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_Q35_COMPAT_1_5,
         { /* end of list */ }
-    },
+    };
+    pc_q35_1_6_machine_options(mc);
+    mc->init = pc_q35_init_1_5;
+    mc->compat_props = compat_props;
+    mc->name = "pc-q35-1.5";
+}
+
+static TypeInfo pc_q35_machine_v1_5_type_info = {
+    .name = "pc-q35-1.5" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_q35_machine_v1_5_class_init,
 };
 
-#define PC_Q35_1_4_MACHINE_OPTIONS \
-    PC_Q35_1_6_MACHINE_OPTIONS, \
-    .hot_add_cpu = NULL
+static void pc_q35_1_4_machine_options(MachineClass *mc)
+{
+    pc_q35_1_6_machine_options(mc);
+    mc->hot_add_cpu = NULL;
+}
 
-static QEMUMachine pc_q35_machine_v1_4 = {
-    PC_Q35_1_4_MACHINE_OPTIONS,
-    .name = "pc-q35-1.4",
-    .init = pc_q35_init_1_4,
-    .compat_props = (GlobalProperty[]) {
+static void pc_q35_machine_v1_4_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    static GlobalProperty compat_props[] = {
         PC_COMPAT_1_4,
         { /* end of list */ }
-    },
+    };
+    pc_q35_1_4_machine_options(mc);
+    mc->init = pc_q35_init_1_4;
+    mc->compat_props = compat_props;
+    mc->name = "pc-q35-1.4";
+}
+
+static TypeInfo pc_q35_machine_v1_4_type_info = {
+    .name = "pc-q35-1.4" TYPE_MACHINE_SUFFIX,
+    .parent = TYPE_PC_MACHINE,
+    .class_init = pc_q35_machine_v1_4_class_init,
 };
 
 static void pc_q35_machine_init(void)
 {
-    qemu_register_machine(&pc_q35_machine_v2_1);
-    qemu_register_machine(&pc_q35_machine_v2_0);
-    qemu_register_machine(&pc_q35_machine_v1_7);
-    qemu_register_machine(&pc_q35_machine_v1_6);
-    qemu_register_machine(&pc_q35_machine_v1_5);
-    qemu_register_machine(&pc_q35_machine_v1_4);
+    type_register_static(&pc_q35_machine_v2_1_type_info);
+    type_register_static(&pc_q35_machine_v2_0_type_info);
+    type_register_static(&pc_q35_machine_v1_7_type_info);
+    type_register_static(&pc_q35_machine_v1_6_type_info);
+    type_register_static(&pc_q35_machine_v1_5_type_info);
+    type_register_static(&pc_q35_machine_v1_4_type_info);
 }
 
 machine_init(pc_q35_machine_init);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index fa9d997..4d85847 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -7,6 +7,7 @@
 #include "hw/block/fdc.h"
 #include "net/net.h"
 #include "hw/i386/ioapic.h"
+#include "hw/boards.h"
 
 #include "qemu/range.h"
 #include "qemu/bitmap.h"
@@ -438,12 +439,21 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
             .value    = stringify(0),\
         }
 
-#define PC_COMMON_MACHINE_OPTIONS \
-    .default_boot_order = "cad"
+static inline void pc_common_machine_options(MachineClass *mc)
+{
+    mc->default_boot_order = "cad";
+}
+
+static inline void pc_default_machine_options(MachineClass *mc)
+{
+    pc_common_machine_options(mc);
+    mc->hot_add_cpu = pc_hot_add_cpu;
+    mc->max_cpus = 255;
+}
 
 #define PC_DEFAULT_MACHINE_OPTIONS \
-    PC_COMMON_MACHINE_OPTIONS, \
-    .hot_add_cpu = pc_hot_add_cpu, \
-    .max_cpus = 255
+
+
+#define TYPE_PC_MACHINE "pc-machine"
 
 #endif
-- 
1.9.0

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  6:22 [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine Eduardo Habkost
@ 2014-06-12  8:02 ` Igor Mammedov
  2014-06-12  8:12   ` Marcel Apfelbaum
  2014-06-12  8:13 ` Michael S. Tsirkin
  1 sibling, 1 reply; 10+ messages in thread
From: Igor Mammedov @ 2014-06-12  8:02 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Michael S. Tsirkin, Marcel Apfelbaum, Alexander Graf, Don Slutz,
	qemu-devel, Anthony Liguori, Andreas Färber

On Thu, 12 Jun 2014 03:22:24 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> definitions to corresponding class registration code.
> 
> Having the PC code converted to pure QOM registration code will help us
> move PC-specific machine state that is currently held in static
> variables inside PC machine objects, and reduce duplication between
> pc_piix.c and pc_q35.c.

Getting rid of *_machine_options() functions and doing nested
inheritance with necessary overrides in respective *_class_init()
functions, would make code more readable/understandable.

> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  hw/i386/pc.c         |  13 ++
>  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
>  hw/i386/pc_q35.c     | 171 +++++++++++++------
>  include/hw/i386/pc.h |  20 ++-
>  4 files changed, 465 insertions(+), 212 deletions(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 32d1632..56720cd 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
>          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
>      }
>  }
> +
> +static TypeInfo pc_machine_type_info = {
> +        .name       = TYPE_PC_MACHINE,
> +        .parent     = TYPE_MACHINE,
> +        .abstract   = true,
> +};
> +
> +static void pc_machine_init(void)
> +{
> +    type_register_static(&pc_machine_type_info);
> +}
> +
> +type_init(pc_machine_init);
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index a48e263..d4b4033 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -392,81 +392,140 @@ static void pc_xen_hvm_init(MachineState *machine)
>  }
>  #endif
>  
> -#define PC_I440FX_MACHINE_OPTIONS \
> -    PC_DEFAULT_MACHINE_OPTIONS, \
> -    .desc = "Standard PC (i440FX + PIIX, 1996)", \
> -    .hot_add_cpu = pc_hot_add_cpu
> -
> -#define PC_I440FX_2_1_MACHINE_OPTIONS                           \
> -    PC_I440FX_MACHINE_OPTIONS,                                  \
> -    .default_machine_opts = "firmware=bios-256k.bin"
> -
> -static QEMUMachine pc_i440fx_machine_v2_1 = {
> -    PC_I440FX_2_1_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-2.1",
> -    .alias = "pc",
> -    .init = pc_init_pci,
> -    .is_default = 1,
> +static void pc_i440fx_machine_options(MachineClass *mc)
> +{
> +    pc_default_machine_options(mc);
> +    mc->desc = "Standard PC (i440FX + PIIX, 1996)";
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +}
> +
> +static void pc_i440fx_2_1_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_machine_options(mc);
> +    mc->default_machine_opts = "firmware=bios-256k.bin";
> +}
> +
> +static void pc_i440fx_machine_v2_1_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    pc_i440fx_2_1_machine_options(mc);
> +    mc->alias = "pc";
> +    mc->init = pc_init_pci;
> +    mc->is_default = 1;
> +    mc->name = "pc-i440fx-2.1";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v2_1_type_info = {
> +    .name = "pc-i440fx-2.1" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v2_1_class_init,
>  };
>  
> -#define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS
> +#define pc_i440fx_2_0_machine_options pc_i440fx_2_1_machine_options
>  
> -static QEMUMachine pc_i440fx_machine_v2_0 = {
> -    PC_I440FX_2_0_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-2.0",
> -    .init = pc_init_pci_2_0,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v2_0_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_2_0,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_2_0_machine_options(mc);
> +    mc->init = pc_init_pci_2_0;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-2.0";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v2_0_type_info = {
> +    .name = "pc-i440fx-2.0" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v2_0_class_init,
>  };
>  
> -#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> +#define pc_i440fx_1_7_machine_options pc_i440fx_machine_options
>  
> -static QEMUMachine pc_i440fx_machine_v1_7 = {
> -    PC_I440FX_1_7_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.7",
> -    .init = pc_init_pci_1_7,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_7_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_7,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_7_machine_options(mc);
> +    mc->init = pc_init_pci_1_7;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.7";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_7_type_info = {
> +    .name = "pc-i440fx-1.7" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_7_class_init,
>  };
>  
> -#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> +#define pc_i440fx_1_6_machine_options pc_i440fx_machine_options
>  
> -static QEMUMachine pc_i440fx_machine_v1_6 = {
> -    PC_I440FX_1_6_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.6",
> -    .init = pc_init_pci_1_6,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_6_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_6,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_6_machine_options(mc);
> +    mc->init = pc_init_pci_1_6;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.6";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_6_type_info = {
> +    .name = "pc-i440fx-1.6" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_6_class_init,
>  };
>  
> -static QEMUMachine pc_i440fx_machine_v1_5 = {
> -    PC_I440FX_1_6_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.5",
> -    .init = pc_init_pci_1_5,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_5_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_5,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_6_machine_options(mc);
> +    mc->init = pc_init_pci_1_5;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.5";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_5_type_info = {
> +    .name = "pc-i440fx-1.5" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_5_class_init,
>  };
>  
> -#define PC_I440FX_1_4_MACHINE_OPTIONS \
> -    PC_I440FX_1_6_MACHINE_OPTIONS, \
> -    .hot_add_cpu = NULL
> +static void pc_i440fx_1_4_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_1_6_machine_options(mc);
> +    mc->hot_add_cpu = NULL;
> +}
>  
> -static QEMUMachine pc_i440fx_machine_v1_4 = {
> -    PC_I440FX_1_4_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.4",
> -    .init = pc_init_pci_1_4,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_4_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_4,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_4_machine_options(mc);
> +    mc->init = pc_init_pci_1_4;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.4";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_4_type_info = {
> +    .name = "pc-i440fx-1.4" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_4_class_init,
>  };
>  
>  #define PC_COMPAT_1_3 \
> @@ -489,14 +548,23 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
>              .value    = "off",\
>          }
>  
> -static QEMUMachine pc_machine_v1_3 = {
> -    PC_I440FX_1_4_MACHINE_OPTIONS,
> -    .name = "pc-1.3",
> -    .init = pc_init_pci_1_3,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_3_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_3,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_4_machine_options(mc);
> +    mc->init = pc_init_pci_1_3;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-1.3";
> +}
> +
> +static TypeInfo pc_machine_v1_3_type_info = {
> +    .name = "pc-1.3" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_3_class_init,
>  };
>  
>  #define PC_COMPAT_1_2 \
> @@ -527,17 +595,28 @@ static QEMUMachine pc_machine_v1_3 = {
>              .value    = "off",\
>          }
>  
> -#define PC_I440FX_1_2_MACHINE_OPTIONS \
> -    PC_I440FX_1_4_MACHINE_OPTIONS, \
> -    .init = pc_init_pci_1_2
> +static void pc_i440fx_1_2_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_1_4_machine_options(mc);
> +    mc->init = pc_init_pci_1_2;
> +}
>  
> -static QEMUMachine pc_machine_v1_2 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-1.2",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_2_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_2,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-1.2";
> +}
> +
> +static TypeInfo pc_machine_v1_2_type_info = {
> +    .name = "pc-1.2" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_2_class_init,
>  };
>  
>  #define PC_COMPAT_1_1 \
> @@ -572,13 +651,22 @@ static QEMUMachine pc_machine_v1_2 = {
>              .value    = "off",\
>          }
>  
> -static QEMUMachine pc_machine_v1_1 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-1.1",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_1_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_1,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-1.1";
> +}
> +
> +static TypeInfo pc_machine_v1_1_type_info = {
> +    .name = "pc-1.1" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_1_class_init,
>  };
>  
>  #define PC_COMPAT_1_0 \
> @@ -601,27 +689,45 @@ static QEMUMachine pc_machine_v1_1 = {
>              .value    = "no",\
>          }
>  
> -static QEMUMachine pc_machine_v1_0 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-1.0",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_0_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_0,
>          { /* end of list */ }
> -    },
> -    .hw_version = "1.0",
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "1.0";
> +    mc->name = "pc-1.0";
> +}
> +
> +static TypeInfo pc_machine_v1_0_type_info = {
> +    .name = "pc-1.0" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_0_class_init,
>  };
>  
>  #define PC_COMPAT_0_15 \
>          PC_COMPAT_1_0
>  
> -static QEMUMachine pc_machine_v0_15 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-0.15",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_15_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_15,
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.15",
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.15";
> +    mc->name = "pc-0.15";
> +}
> +
> +static TypeInfo pc_machine_v0_15_type_info = {
> +    .name = "pc-0.15" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_15_class_init,
>  };
>  
>  #define PC_COMPAT_0_14 \
> @@ -644,10 +750,10 @@ static QEMUMachine pc_machine_v0_15 = {
>              .value    = "off",\
>          }
>  
> -static QEMUMachine pc_machine_v0_14 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-0.14",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_14_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_14, 
>          {
>              .driver   = "qxl",
> @@ -659,8 +765,17 @@ static QEMUMachine pc_machine_v0_14 = {
>              .value    = stringify(2),
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.14",
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.14";
> +    mc->name = "pc-0.14";
> +}
> +
> +static TypeInfo pc_machine_v0_14_type_info = {
> +    .name = "pc-0.14" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_14_class_init,
>  };
>  
>  #define PC_COMPAT_0_13 \
> @@ -675,14 +790,16 @@ static QEMUMachine pc_machine_v0_14 = {
>              .value    = stringify(1),\
>          }
>  
> -#define PC_I440FX_0_13_MACHINE_OPTIONS \
> -    PC_I440FX_1_2_MACHINE_OPTIONS, \
> -    .init = pc_init_pci_no_kvmclock
> +static void pc_i440fx_0_13_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->init = pc_init_pci_no_kvmclock;
> +}
>  
> -static QEMUMachine pc_machine_v0_13 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.13",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_13_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_13,
>          {
>              .driver   = "virtio-9p-pci",
> @@ -698,8 +815,17 @@ static QEMUMachine pc_machine_v0_13 = {
>              .value    = stringify(0),
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.13",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.13";
> +    mc->name = "pc-0.13";
> +}
> +
> +static TypeInfo pc_machine_v0_13_type_info = {
> +    .name = "pc-0.13" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_13_class_init,
>  };
>  
>  #define PC_COMPAT_0_12 \
> @@ -726,10 +852,10 @@ static QEMUMachine pc_machine_v0_13 = {
>              .value    = "1",\
>          }
>  
> -static QEMUMachine pc_machine_v0_12 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.12",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_12_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_12,
>          {
>              .driver   = "VGA",
> @@ -741,8 +867,17 @@ static QEMUMachine pc_machine_v0_12 = {
>              .value    = stringify(0),
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.12",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.12";
> +    mc->name = "pc-0.12";
> +}
> +
> +static TypeInfo pc_machine_v0_12_type_info = {
> +    .name = "pc-0.12" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_12_class_init,
>  };
>  
>  #define PC_COMPAT_0_11 \
> @@ -757,10 +892,10 @@ static QEMUMachine pc_machine_v0_12 = {
>              .value    = stringify(0),\
>          }
>  
> -static QEMUMachine pc_machine_v0_11 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.11",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_11_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_11,
>          {
>              .driver   = "ide-drive",
> @@ -772,14 +907,23 @@ static QEMUMachine pc_machine_v0_11 = {
>              .value    = "0.11",
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.11",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.11";
> +    mc->name = "pc-0.11";
> +}
> +
> +static TypeInfo pc_machine_v0_11_type_info = {
> +    .name = "pc-0.11" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_11_class_init,
>  };
>  
> -static QEMUMachine pc_machine_v0_10 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.10",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_10_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_11,
>          {
>              .driver   = "virtio-blk-pci",
> @@ -803,31 +947,44 @@ static QEMUMachine pc_machine_v0_10 = {
>              .value    = "0.10",
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.10",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.10";
> +    mc->name = "pc-0.10";
> +}
> +
> +static TypeInfo pc_machine_v0_10_type_info = {
> +    .name = "pc-0.10" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_10_class_init,
>  };
>  
> -static QEMUMachine isapc_machine = {
> -    PC_COMMON_MACHINE_OPTIONS,
> -    .name = "isapc",
> -    .desc = "ISA-only PC",
> -    .init = pc_init_isa,
> -    .max_cpus = 1,
> -    .compat_props = (GlobalProperty[]) {
> +static void isapc_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          { /* end of list */ }
> -    },
> +    };
> +    pc_common_machine_options(mc);
> +    mc->desc = "ISA-only PC";
> +    mc->init = pc_init_isa;
> +    mc->max_cpus = 1;
> +    mc->compat_props = compat_props;
> +    mc->name = "isapc";
> +}
> +
> +static TypeInfo isapc_machine_type_info = {
> +    .name = "isapc" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = isapc_machine_class_init,
>  };
>  
>  #ifdef CONFIG_XEN
> -static QEMUMachine xenfv_machine = {
> -    PC_COMMON_MACHINE_OPTIONS,
> -    .name = "xenfv",
> -    .desc = "Xen Fully-virtualized PC",
> -    .init = pc_xen_hvm_init,
> -    .max_cpus = HVM_MAX_VCPUS,
> -    .default_machine_opts = "accel=xen",
> -    .hot_add_cpu = pc_hot_add_cpu,
> -    .compat_props = (GlobalProperty[]) {
> +static void xenfv_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          /* xenfv has no fwcfg and so does not load acpi from QEMU.
>           * as such new acpi features don't work.
>           */
> @@ -837,31 +994,45 @@ static QEMUMachine xenfv_machine = {
>              .value    = "off",
>          },
>          { /* end of list */ }
> -    },
> +    };
> +    pc_common_machine_options(mc);
> +    mc->desc = "Xen Fully-virtualized PC";
> +    mc->init = pc_xen_hvm_init;
> +    mc->max_cpus = HVM_MAX_VCPUS;
> +    mc->default_machine_opts = "accel=xen";
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +    mc->compat_props = compat_props;
> +    mc->name = "xenfv";
> +}
> +
> +static TypeInfo xenfv_machine_type_info = {
> +    .name = "xenfv" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = xenfv_machine_class_init,
>  };
>  #endif
>  
>  static void pc_machine_init(void)
>  {
> -    qemu_register_machine(&pc_i440fx_machine_v2_1);
> -    qemu_register_machine(&pc_i440fx_machine_v2_0);
> -    qemu_register_machine(&pc_i440fx_machine_v1_7);
> -    qemu_register_machine(&pc_i440fx_machine_v1_6);
> -    qemu_register_machine(&pc_i440fx_machine_v1_5);
> -    qemu_register_machine(&pc_i440fx_machine_v1_4);
> -    qemu_register_machine(&pc_machine_v1_3);
> -    qemu_register_machine(&pc_machine_v1_2);
> -    qemu_register_machine(&pc_machine_v1_1);
> -    qemu_register_machine(&pc_machine_v1_0);
> -    qemu_register_machine(&pc_machine_v0_15);
> -    qemu_register_machine(&pc_machine_v0_14);
> -    qemu_register_machine(&pc_machine_v0_13);
> -    qemu_register_machine(&pc_machine_v0_12);
> -    qemu_register_machine(&pc_machine_v0_11);
> -    qemu_register_machine(&pc_machine_v0_10);
> -    qemu_register_machine(&isapc_machine);
> +    type_register_static(&pc_i440fx_machine_v2_1_type_info);
> +    type_register_static(&pc_i440fx_machine_v2_0_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_7_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_6_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_5_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_4_type_info);
> +    type_register_static(&pc_machine_v1_3_type_info);
> +    type_register_static(&pc_machine_v1_2_type_info);
> +    type_register_static(&pc_machine_v1_1_type_info);
> +    type_register_static(&pc_machine_v1_0_type_info);
> +    type_register_static(&pc_machine_v0_15_type_info);
> +    type_register_static(&pc_machine_v0_14_type_info);
> +    type_register_static(&pc_machine_v0_13_type_info);
> +    type_register_static(&pc_machine_v0_12_type_info);
> +    type_register_static(&pc_machine_v0_11_type_info);
> +    type_register_static(&pc_machine_v0_10_type_info);
> +    type_register_static(&isapc_machine_type_info);
>  #ifdef CONFIG_XEN
> -    qemu_register_machine(&xenfv_machine);
> +    type_register_static(&xenfv_machine_type_info);
>  #endif
>  }
>  
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index b3c02c1..6e909f7 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -306,90 +306,149 @@ static void pc_q35_init_1_4(MachineState *machine)
>      pc_q35_init(machine);
>  }
>  
> -#define PC_Q35_MACHINE_OPTIONS \
> -    PC_DEFAULT_MACHINE_OPTIONS, \
> -    .desc = "Standard PC (Q35 + ICH9, 2009)", \
> -    .hot_add_cpu = pc_hot_add_cpu
> -
> -#define PC_Q35_2_1_MACHINE_OPTIONS                      \
> -    PC_Q35_MACHINE_OPTIONS,                             \
> -    .default_machine_opts = "firmware=bios-256k.bin"
> -
> -static QEMUMachine pc_q35_machine_v2_1 = {
> -    PC_Q35_2_1_MACHINE_OPTIONS,
> -    .name = "pc-q35-2.1",
> -    .alias = "q35",
> -    .init = pc_q35_init,
> +static void pc_q35_machine_options(MachineClass *mc)
> +{
> +    pc_default_machine_options(mc);
> +    mc->desc = "Standard PC (Q35 + ICH9, 2009)";
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +}
> +
> +static void pc_q35_2_1_machine_options(MachineClass *mc)
> +{
> +    pc_q35_machine_options(mc);
> +    mc->default_machine_opts = "firmware=bios-256k.bin";
> +}
> +
> +static void pc_q35_machine_v2_1_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    pc_q35_2_1_machine_options(mc);
> +    mc->alias = "q35";
> +    mc->init = pc_q35_init;
> +    mc->name = "pc-q35-2.1";
> +}
> +
> +static TypeInfo pc_q35_machine_v2_1_type_info = {
> +    .name = "pc-q35-2.1" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v2_1_class_init,
>  };
>  
> -#define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS
> +#define pc_q35_2_0_machine_options pc_q35_2_1_machine_options
>  
> -static QEMUMachine pc_q35_machine_v2_0 = {
> -    PC_Q35_2_0_MACHINE_OPTIONS,
> -    .name = "pc-q35-2.0",
> -    .init = pc_q35_init_2_0,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v2_0_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_2_0,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_2_0_machine_options(mc);
> +    mc->init = pc_q35_init_2_0;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-2.0";
> +}
> +
> +static TypeInfo pc_q35_machine_v2_0_type_info = {
> +    .name = "pc-q35-2.0" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v2_0_class_init,
>  };
>  
> -#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> +#define pc_q35_1_7_machine_options pc_q35_machine_options
>  
> -static QEMUMachine pc_q35_machine_v1_7 = {
> -    PC_Q35_1_7_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.7",
> -    .init = pc_q35_init_1_7,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_7_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_1_7,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_7_machine_options(mc);
> +    mc->init = pc_q35_init_1_7;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.7";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_7_type_info = {
> +    .name = "pc-q35-1.7" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_7_class_init,
>  };
>  
> -#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> +#define pc_q35_1_6_machine_options pc_q35_machine_options
>  
> -static QEMUMachine pc_q35_machine_v1_6 = {
> -    PC_Q35_1_6_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.6",
> -    .init = pc_q35_init_1_6,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_6_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_1_6,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_6_machine_options(mc);
> +    mc->init = pc_q35_init_1_6;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.6";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_6_type_info = {
> +    .name = "pc-q35-1.6" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_6_class_init,
>  };
>  
> -static QEMUMachine pc_q35_machine_v1_5 = {
> -    PC_Q35_1_6_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.5",
> -    .init = pc_q35_init_1_5,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_5_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_1_5,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_6_machine_options(mc);
> +    mc->init = pc_q35_init_1_5;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.5";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_5_type_info = {
> +    .name = "pc-q35-1.5" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_5_class_init,
>  };
>  
> -#define PC_Q35_1_4_MACHINE_OPTIONS \
> -    PC_Q35_1_6_MACHINE_OPTIONS, \
> -    .hot_add_cpu = NULL
> +static void pc_q35_1_4_machine_options(MachineClass *mc)
> +{
> +    pc_q35_1_6_machine_options(mc);
> +    mc->hot_add_cpu = NULL;
> +}
>  
> -static QEMUMachine pc_q35_machine_v1_4 = {
> -    PC_Q35_1_4_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.4",
> -    .init = pc_q35_init_1_4,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_4_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_4,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_4_machine_options(mc);
> +    mc->init = pc_q35_init_1_4;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.4";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_4_type_info = {
> +    .name = "pc-q35-1.4" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_4_class_init,
>  };
>  
>  static void pc_q35_machine_init(void)
>  {
> -    qemu_register_machine(&pc_q35_machine_v2_1);
> -    qemu_register_machine(&pc_q35_machine_v2_0);
> -    qemu_register_machine(&pc_q35_machine_v1_7);
> -    qemu_register_machine(&pc_q35_machine_v1_6);
> -    qemu_register_machine(&pc_q35_machine_v1_5);
> -    qemu_register_machine(&pc_q35_machine_v1_4);
> +    type_register_static(&pc_q35_machine_v2_1_type_info);
> +    type_register_static(&pc_q35_machine_v2_0_type_info);
> +    type_register_static(&pc_q35_machine_v1_7_type_info);
> +    type_register_static(&pc_q35_machine_v1_6_type_info);
> +    type_register_static(&pc_q35_machine_v1_5_type_info);
> +    type_register_static(&pc_q35_machine_v1_4_type_info);
>  }
>  
>  machine_init(pc_q35_machine_init);
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index fa9d997..4d85847 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -7,6 +7,7 @@
>  #include "hw/block/fdc.h"
>  #include "net/net.h"
>  #include "hw/i386/ioapic.h"
> +#include "hw/boards.h"
>  
>  #include "qemu/range.h"
>  #include "qemu/bitmap.h"
> @@ -438,12 +439,21 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
>              .value    = stringify(0),\
>          }
>  
> -#define PC_COMMON_MACHINE_OPTIONS \
> -    .default_boot_order = "cad"
> +static inline void pc_common_machine_options(MachineClass *mc)
> +{
> +    mc->default_boot_order = "cad";
> +}
> +
> +static inline void pc_default_machine_options(MachineClass *mc)
> +{
> +    pc_common_machine_options(mc);
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +    mc->max_cpus = 255;
> +}
>  
>  #define PC_DEFAULT_MACHINE_OPTIONS \
> -    PC_COMMON_MACHINE_OPTIONS, \
> -    .hot_add_cpu = pc_hot_add_cpu, \
> -    .max_cpus = 255
> +
> +
> +#define TYPE_PC_MACHINE "pc-machine"
>  
>  #endif

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  8:02 ` Igor Mammedov
@ 2014-06-12  8:12   ` Marcel Apfelbaum
  2014-06-12  8:20     ` Michael S. Tsirkin
  2014-06-12  8:23     ` Igor Mammedov
  0 siblings, 2 replies; 10+ messages in thread
From: Marcel Apfelbaum @ 2014-06-12  8:12 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Eduardo Habkost, Michael S. Tsirkin, Alexander Graf, Don Slutz,
	qemu-devel, Anthony Liguori, Andreas Färber

On Thu, 2014-06-12 at 10:02 +0200, Igor Mammedov wrote:
> On Thu, 12 Jun 2014 03:22:24 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> > definitions to corresponding class registration code.
> > 
> > Having the PC code converted to pure QOM registration code will help us
> > move PC-specific machine state that is currently held in static
> > variables inside PC machine objects, and reduce duplication between
> > pc_piix.c and pc_q35.c.
> 
> Getting rid of *_machine_options() functions and doing nested
> inheritance with necessary overrides in respective *_class_init()
> functions, would make code more readable/understandable.
While I agree with you that this is the right direction, Eduardo's
patch is a good step forward getting rid of QEMUMachine and those
defines. I say we implement the hierarchy on top of this patch.
 
> 
> > 
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  hw/i386/pc.c         |  13 ++
> >  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
> >  hw/i386/pc_q35.c     | 171 +++++++++++++------
> >  include/hw/i386/pc.h |  20 ++-
> >  4 files changed, 465 insertions(+), 212 deletions(-)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 32d1632..56720cd 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
> >          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
> >      }
> >  }
> > +
> > +static TypeInfo pc_machine_type_info = {
> > +        .name       = TYPE_PC_MACHINE,
> > +        .parent     = TYPE_MACHINE,
> > +        .abstract   = true,
> > +};
Igor's series already introduces TYPE_PC_MACHINE, you may want to rebase on it:
http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00133.html

Thanks,
Marcel

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  6:22 [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine Eduardo Habkost
  2014-06-12  8:02 ` Igor Mammedov
@ 2014-06-12  8:13 ` Michael S. Tsirkin
  2014-06-12  8:37   ` Igor Mammedov
  1 sibling, 1 reply; 10+ messages in thread
From: Michael S. Tsirkin @ 2014-06-12  8:13 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: Marcel Apfelbaum, Alexander Graf, Don Slutz, qemu-devel,
	Anthony Liguori, Andreas Färber

On Thu, Jun 12, 2014 at 03:22:24AM -0300, Eduardo Habkost wrote:
> This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> definitions to corresponding class registration code.
> 
> Having the PC code converted to pure QOM registration code will help us
> move PC-specific machine state that is currently held in static
> variables inside PC machine objects, and reduce duplication between
> pc_piix.c and pc_q35.c.
> 
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> ---
>  hw/i386/pc.c         |  13 ++
>  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
>  hw/i386/pc_q35.c     | 171 +++++++++++++------
>  include/hw/i386/pc.h |  20 ++-
>  4 files changed, 465 insertions(+), 212 deletions(-)

Hmm amount of boilerplate code seems to have doubled.
Can we find a solution that does away with code duplication?
Here's one idea: create one giant array with all necessary data, look it
up by name at runtime and fill everything in.
Not sure it's going to work out but might be worth a try.

> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 32d1632..56720cd 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
>          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
>      }
>  }
> +
> +static TypeInfo pc_machine_type_info = {
> +        .name       = TYPE_PC_MACHINE,
> +        .parent     = TYPE_MACHINE,
> +        .abstract   = true,
> +};
> +
> +static void pc_machine_init(void)
> +{
> +    type_register_static(&pc_machine_type_info);
> +}
> +
> +type_init(pc_machine_init);
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index a48e263..d4b4033 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -392,81 +392,140 @@ static void pc_xen_hvm_init(MachineState *machine)
>  }
>  #endif
>  
> -#define PC_I440FX_MACHINE_OPTIONS \
> -    PC_DEFAULT_MACHINE_OPTIONS, \
> -    .desc = "Standard PC (i440FX + PIIX, 1996)", \
> -    .hot_add_cpu = pc_hot_add_cpu
> -
> -#define PC_I440FX_2_1_MACHINE_OPTIONS                           \
> -    PC_I440FX_MACHINE_OPTIONS,                                  \
> -    .default_machine_opts = "firmware=bios-256k.bin"
> -
> -static QEMUMachine pc_i440fx_machine_v2_1 = {
> -    PC_I440FX_2_1_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-2.1",
> -    .alias = "pc",
> -    .init = pc_init_pci,
> -    .is_default = 1,
> +static void pc_i440fx_machine_options(MachineClass *mc)
> +{
> +    pc_default_machine_options(mc);
> +    mc->desc = "Standard PC (i440FX + PIIX, 1996)";
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +}
> +
> +static void pc_i440fx_2_1_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_machine_options(mc);
> +    mc->default_machine_opts = "firmware=bios-256k.bin";
> +}
> +
> +static void pc_i440fx_machine_v2_1_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    pc_i440fx_2_1_machine_options(mc);
> +    mc->alias = "pc";
> +    mc->init = pc_init_pci;
> +    mc->is_default = 1;
> +    mc->name = "pc-i440fx-2.1";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v2_1_type_info = {
> +    .name = "pc-i440fx-2.1" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v2_1_class_init,
>  };
>  
> -#define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS
> +#define pc_i440fx_2_0_machine_options pc_i440fx_2_1_machine_options
>  
> -static QEMUMachine pc_i440fx_machine_v2_0 = {
> -    PC_I440FX_2_0_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-2.0",
> -    .init = pc_init_pci_2_0,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v2_0_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_2_0,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_2_0_machine_options(mc);
> +    mc->init = pc_init_pci_2_0;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-2.0";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v2_0_type_info = {
> +    .name = "pc-i440fx-2.0" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v2_0_class_init,
>  };
>  
> -#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> +#define pc_i440fx_1_7_machine_options pc_i440fx_machine_options
>  
> -static QEMUMachine pc_i440fx_machine_v1_7 = {
> -    PC_I440FX_1_7_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.7",
> -    .init = pc_init_pci_1_7,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_7_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_7,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_7_machine_options(mc);
> +    mc->init = pc_init_pci_1_7;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.7";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_7_type_info = {
> +    .name = "pc-i440fx-1.7" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_7_class_init,
>  };
>  
> -#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> +#define pc_i440fx_1_6_machine_options pc_i440fx_machine_options
>  
> -static QEMUMachine pc_i440fx_machine_v1_6 = {
> -    PC_I440FX_1_6_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.6",
> -    .init = pc_init_pci_1_6,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_6_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_6,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_6_machine_options(mc);
> +    mc->init = pc_init_pci_1_6;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.6";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_6_type_info = {
> +    .name = "pc-i440fx-1.6" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_6_class_init,
>  };
>  
> -static QEMUMachine pc_i440fx_machine_v1_5 = {
> -    PC_I440FX_1_6_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.5",
> -    .init = pc_init_pci_1_5,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_5_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_5,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_6_machine_options(mc);
> +    mc->init = pc_init_pci_1_5;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.5";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_5_type_info = {
> +    .name = "pc-i440fx-1.5" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_5_class_init,
>  };
>  
> -#define PC_I440FX_1_4_MACHINE_OPTIONS \
> -    PC_I440FX_1_6_MACHINE_OPTIONS, \
> -    .hot_add_cpu = NULL
> +static void pc_i440fx_1_4_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_1_6_machine_options(mc);
> +    mc->hot_add_cpu = NULL;
> +}
>  
> -static QEMUMachine pc_i440fx_machine_v1_4 = {
> -    PC_I440FX_1_4_MACHINE_OPTIONS,
> -    .name = "pc-i440fx-1.4",
> -    .init = pc_init_pci_1_4,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_i440fx_machine_v1_4_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_4,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_4_machine_options(mc);
> +    mc->init = pc_init_pci_1_4;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-i440fx-1.4";
> +}
> +
> +static TypeInfo pc_i440fx_machine_v1_4_type_info = {
> +    .name = "pc-i440fx-1.4" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_i440fx_machine_v1_4_class_init,
>  };
>  
>  #define PC_COMPAT_1_3 \
> @@ -489,14 +548,23 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
>              .value    = "off",\
>          }
>  
> -static QEMUMachine pc_machine_v1_3 = {
> -    PC_I440FX_1_4_MACHINE_OPTIONS,
> -    .name = "pc-1.3",
> -    .init = pc_init_pci_1_3,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_3_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_3,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_4_machine_options(mc);
> +    mc->init = pc_init_pci_1_3;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-1.3";
> +}
> +
> +static TypeInfo pc_machine_v1_3_type_info = {
> +    .name = "pc-1.3" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_3_class_init,
>  };
>  
>  #define PC_COMPAT_1_2 \
> @@ -527,17 +595,28 @@ static QEMUMachine pc_machine_v1_3 = {
>              .value    = "off",\
>          }
>  
> -#define PC_I440FX_1_2_MACHINE_OPTIONS \
> -    PC_I440FX_1_4_MACHINE_OPTIONS, \
> -    .init = pc_init_pci_1_2
> +static void pc_i440fx_1_2_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_1_4_machine_options(mc);
> +    mc->init = pc_init_pci_1_2;
> +}
>  
> -static QEMUMachine pc_machine_v1_2 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-1.2",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_2_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_2,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-1.2";
> +}
> +
> +static TypeInfo pc_machine_v1_2_type_info = {
> +    .name = "pc-1.2" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_2_class_init,
>  };
>  
>  #define PC_COMPAT_1_1 \
> @@ -572,13 +651,22 @@ static QEMUMachine pc_machine_v1_2 = {
>              .value    = "off",\
>          }
>  
> -static QEMUMachine pc_machine_v1_1 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-1.1",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_1_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_1,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-1.1";
> +}
> +
> +static TypeInfo pc_machine_v1_1_type_info = {
> +    .name = "pc-1.1" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_1_class_init,
>  };
>  
>  #define PC_COMPAT_1_0 \
> @@ -601,27 +689,45 @@ static QEMUMachine pc_machine_v1_1 = {
>              .value    = "no",\
>          }
>  
> -static QEMUMachine pc_machine_v1_0 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-1.0",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v1_0_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_0,
>          { /* end of list */ }
> -    },
> -    .hw_version = "1.0",
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "1.0";
> +    mc->name = "pc-1.0";
> +}
> +
> +static TypeInfo pc_machine_v1_0_type_info = {
> +    .name = "pc-1.0" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v1_0_class_init,
>  };
>  
>  #define PC_COMPAT_0_15 \
>          PC_COMPAT_1_0
>  
> -static QEMUMachine pc_machine_v0_15 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-0.15",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_15_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_15,
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.15",
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.15";
> +    mc->name = "pc-0.15";
> +}
> +
> +static TypeInfo pc_machine_v0_15_type_info = {
> +    .name = "pc-0.15" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_15_class_init,
>  };
>  
>  #define PC_COMPAT_0_14 \
> @@ -644,10 +750,10 @@ static QEMUMachine pc_machine_v0_15 = {
>              .value    = "off",\
>          }
>  
> -static QEMUMachine pc_machine_v0_14 = {
> -    PC_I440FX_1_2_MACHINE_OPTIONS,
> -    .name = "pc-0.14",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_14_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_14, 
>          {
>              .driver   = "qxl",
> @@ -659,8 +765,17 @@ static QEMUMachine pc_machine_v0_14 = {
>              .value    = stringify(2),
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.14",
> +    };
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.14";
> +    mc->name = "pc-0.14";
> +}
> +
> +static TypeInfo pc_machine_v0_14_type_info = {
> +    .name = "pc-0.14" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_14_class_init,
>  };
>  
>  #define PC_COMPAT_0_13 \
> @@ -675,14 +790,16 @@ static QEMUMachine pc_machine_v0_14 = {
>              .value    = stringify(1),\
>          }
>  
> -#define PC_I440FX_0_13_MACHINE_OPTIONS \
> -    PC_I440FX_1_2_MACHINE_OPTIONS, \
> -    .init = pc_init_pci_no_kvmclock
> +static void pc_i440fx_0_13_machine_options(MachineClass *mc)
> +{
> +    pc_i440fx_1_2_machine_options(mc);
> +    mc->init = pc_init_pci_no_kvmclock;
> +}
>  
> -static QEMUMachine pc_machine_v0_13 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.13",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_13_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_13,
>          {
>              .driver   = "virtio-9p-pci",
> @@ -698,8 +815,17 @@ static QEMUMachine pc_machine_v0_13 = {
>              .value    = stringify(0),
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.13",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.13";
> +    mc->name = "pc-0.13";
> +}
> +
> +static TypeInfo pc_machine_v0_13_type_info = {
> +    .name = "pc-0.13" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_13_class_init,
>  };
>  
>  #define PC_COMPAT_0_12 \
> @@ -726,10 +852,10 @@ static QEMUMachine pc_machine_v0_13 = {
>              .value    = "1",\
>          }
>  
> -static QEMUMachine pc_machine_v0_12 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.12",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_12_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_12,
>          {
>              .driver   = "VGA",
> @@ -741,8 +867,17 @@ static QEMUMachine pc_machine_v0_12 = {
>              .value    = stringify(0),
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.12",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.12";
> +    mc->name = "pc-0.12";
> +}
> +
> +static TypeInfo pc_machine_v0_12_type_info = {
> +    .name = "pc-0.12" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_12_class_init,
>  };
>  
>  #define PC_COMPAT_0_11 \
> @@ -757,10 +892,10 @@ static QEMUMachine pc_machine_v0_12 = {
>              .value    = stringify(0),\
>          }
>  
> -static QEMUMachine pc_machine_v0_11 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.11",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_11_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_11,
>          {
>              .driver   = "ide-drive",
> @@ -772,14 +907,23 @@ static QEMUMachine pc_machine_v0_11 = {
>              .value    = "0.11",
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.11",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.11";
> +    mc->name = "pc-0.11";
> +}
> +
> +static TypeInfo pc_machine_v0_11_type_info = {
> +    .name = "pc-0.11" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_11_class_init,
>  };
>  
> -static QEMUMachine pc_machine_v0_10 = {
> -    PC_I440FX_0_13_MACHINE_OPTIONS,
> -    .name = "pc-0.10",
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_machine_v0_10_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_0_11,
>          {
>              .driver   = "virtio-blk-pci",
> @@ -803,31 +947,44 @@ static QEMUMachine pc_machine_v0_10 = {
>              .value    = "0.10",
>          },
>          { /* end of list */ }
> -    },
> -    .hw_version = "0.10",
> +    };
> +    pc_i440fx_0_13_machine_options(mc);
> +    mc->compat_props = compat_props;
> +    mc->hw_version = "0.10";
> +    mc->name = "pc-0.10";
> +}
> +
> +static TypeInfo pc_machine_v0_10_type_info = {
> +    .name = "pc-0.10" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_machine_v0_10_class_init,
>  };
>  
> -static QEMUMachine isapc_machine = {
> -    PC_COMMON_MACHINE_OPTIONS,
> -    .name = "isapc",
> -    .desc = "ISA-only PC",
> -    .init = pc_init_isa,
> -    .max_cpus = 1,
> -    .compat_props = (GlobalProperty[]) {
> +static void isapc_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          { /* end of list */ }
> -    },
> +    };
> +    pc_common_machine_options(mc);
> +    mc->desc = "ISA-only PC";
> +    mc->init = pc_init_isa;
> +    mc->max_cpus = 1;
> +    mc->compat_props = compat_props;
> +    mc->name = "isapc";
> +}
> +
> +static TypeInfo isapc_machine_type_info = {
> +    .name = "isapc" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = isapc_machine_class_init,
>  };
>  
>  #ifdef CONFIG_XEN
> -static QEMUMachine xenfv_machine = {
> -    PC_COMMON_MACHINE_OPTIONS,
> -    .name = "xenfv",
> -    .desc = "Xen Fully-virtualized PC",
> -    .init = pc_xen_hvm_init,
> -    .max_cpus = HVM_MAX_VCPUS,
> -    .default_machine_opts = "accel=xen",
> -    .hot_add_cpu = pc_hot_add_cpu,
> -    .compat_props = (GlobalProperty[]) {
> +static void xenfv_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          /* xenfv has no fwcfg and so does not load acpi from QEMU.
>           * as such new acpi features don't work.
>           */
> @@ -837,31 +994,45 @@ static QEMUMachine xenfv_machine = {
>              .value    = "off",
>          },
>          { /* end of list */ }
> -    },
> +    };
> +    pc_common_machine_options(mc);
> +    mc->desc = "Xen Fully-virtualized PC";
> +    mc->init = pc_xen_hvm_init;
> +    mc->max_cpus = HVM_MAX_VCPUS;
> +    mc->default_machine_opts = "accel=xen";
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +    mc->compat_props = compat_props;
> +    mc->name = "xenfv";
> +}
> +
> +static TypeInfo xenfv_machine_type_info = {
> +    .name = "xenfv" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = xenfv_machine_class_init,
>  };
>  #endif
>  
>  static void pc_machine_init(void)
>  {
> -    qemu_register_machine(&pc_i440fx_machine_v2_1);
> -    qemu_register_machine(&pc_i440fx_machine_v2_0);
> -    qemu_register_machine(&pc_i440fx_machine_v1_7);
> -    qemu_register_machine(&pc_i440fx_machine_v1_6);
> -    qemu_register_machine(&pc_i440fx_machine_v1_5);
> -    qemu_register_machine(&pc_i440fx_machine_v1_4);
> -    qemu_register_machine(&pc_machine_v1_3);
> -    qemu_register_machine(&pc_machine_v1_2);
> -    qemu_register_machine(&pc_machine_v1_1);
> -    qemu_register_machine(&pc_machine_v1_0);
> -    qemu_register_machine(&pc_machine_v0_15);
> -    qemu_register_machine(&pc_machine_v0_14);
> -    qemu_register_machine(&pc_machine_v0_13);
> -    qemu_register_machine(&pc_machine_v0_12);
> -    qemu_register_machine(&pc_machine_v0_11);
> -    qemu_register_machine(&pc_machine_v0_10);
> -    qemu_register_machine(&isapc_machine);
> +    type_register_static(&pc_i440fx_machine_v2_1_type_info);
> +    type_register_static(&pc_i440fx_machine_v2_0_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_7_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_6_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_5_type_info);
> +    type_register_static(&pc_i440fx_machine_v1_4_type_info);
> +    type_register_static(&pc_machine_v1_3_type_info);
> +    type_register_static(&pc_machine_v1_2_type_info);
> +    type_register_static(&pc_machine_v1_1_type_info);
> +    type_register_static(&pc_machine_v1_0_type_info);
> +    type_register_static(&pc_machine_v0_15_type_info);
> +    type_register_static(&pc_machine_v0_14_type_info);
> +    type_register_static(&pc_machine_v0_13_type_info);
> +    type_register_static(&pc_machine_v0_12_type_info);
> +    type_register_static(&pc_machine_v0_11_type_info);
> +    type_register_static(&pc_machine_v0_10_type_info);
> +    type_register_static(&isapc_machine_type_info);
>  #ifdef CONFIG_XEN
> -    qemu_register_machine(&xenfv_machine);
> +    type_register_static(&xenfv_machine_type_info);
>  #endif
>  }
>  
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index b3c02c1..6e909f7 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -306,90 +306,149 @@ static void pc_q35_init_1_4(MachineState *machine)
>      pc_q35_init(machine);
>  }
>  
> -#define PC_Q35_MACHINE_OPTIONS \
> -    PC_DEFAULT_MACHINE_OPTIONS, \
> -    .desc = "Standard PC (Q35 + ICH9, 2009)", \
> -    .hot_add_cpu = pc_hot_add_cpu
> -
> -#define PC_Q35_2_1_MACHINE_OPTIONS                      \
> -    PC_Q35_MACHINE_OPTIONS,                             \
> -    .default_machine_opts = "firmware=bios-256k.bin"
> -
> -static QEMUMachine pc_q35_machine_v2_1 = {
> -    PC_Q35_2_1_MACHINE_OPTIONS,
> -    .name = "pc-q35-2.1",
> -    .alias = "q35",
> -    .init = pc_q35_init,
> +static void pc_q35_machine_options(MachineClass *mc)
> +{
> +    pc_default_machine_options(mc);
> +    mc->desc = "Standard PC (Q35 + ICH9, 2009)";
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +}
> +
> +static void pc_q35_2_1_machine_options(MachineClass *mc)
> +{
> +    pc_q35_machine_options(mc);
> +    mc->default_machine_opts = "firmware=bios-256k.bin";
> +}
> +
> +static void pc_q35_machine_v2_1_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    pc_q35_2_1_machine_options(mc);
> +    mc->alias = "q35";
> +    mc->init = pc_q35_init;
> +    mc->name = "pc-q35-2.1";
> +}
> +
> +static TypeInfo pc_q35_machine_v2_1_type_info = {
> +    .name = "pc-q35-2.1" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v2_1_class_init,
>  };
>  
> -#define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS
> +#define pc_q35_2_0_machine_options pc_q35_2_1_machine_options
>  
> -static QEMUMachine pc_q35_machine_v2_0 = {
> -    PC_Q35_2_0_MACHINE_OPTIONS,
> -    .name = "pc-q35-2.0",
> -    .init = pc_q35_init_2_0,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v2_0_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_2_0,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_2_0_machine_options(mc);
> +    mc->init = pc_q35_init_2_0;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-2.0";
> +}
> +
> +static TypeInfo pc_q35_machine_v2_0_type_info = {
> +    .name = "pc-q35-2.0" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v2_0_class_init,
>  };
>  
> -#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> +#define pc_q35_1_7_machine_options pc_q35_machine_options
>  
> -static QEMUMachine pc_q35_machine_v1_7 = {
> -    PC_Q35_1_7_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.7",
> -    .init = pc_q35_init_1_7,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_7_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_1_7,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_7_machine_options(mc);
> +    mc->init = pc_q35_init_1_7;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.7";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_7_type_info = {
> +    .name = "pc-q35-1.7" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_7_class_init,
>  };
>  
> -#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> +#define pc_q35_1_6_machine_options pc_q35_machine_options
>  
> -static QEMUMachine pc_q35_machine_v1_6 = {
> -    PC_Q35_1_6_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.6",
> -    .init = pc_q35_init_1_6,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_6_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_1_6,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_6_machine_options(mc);
> +    mc->init = pc_q35_init_1_6;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.6";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_6_type_info = {
> +    .name = "pc-q35-1.6" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_6_class_init,
>  };
>  
> -static QEMUMachine pc_q35_machine_v1_5 = {
> -    PC_Q35_1_6_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.5",
> -    .init = pc_q35_init_1_5,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_5_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_Q35_COMPAT_1_5,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_6_machine_options(mc);
> +    mc->init = pc_q35_init_1_5;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.5";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_5_type_info = {
> +    .name = "pc-q35-1.5" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_5_class_init,
>  };
>  
> -#define PC_Q35_1_4_MACHINE_OPTIONS \
> -    PC_Q35_1_6_MACHINE_OPTIONS, \
> -    .hot_add_cpu = NULL
> +static void pc_q35_1_4_machine_options(MachineClass *mc)
> +{
> +    pc_q35_1_6_machine_options(mc);
> +    mc->hot_add_cpu = NULL;
> +}
>  
> -static QEMUMachine pc_q35_machine_v1_4 = {
> -    PC_Q35_1_4_MACHINE_OPTIONS,
> -    .name = "pc-q35-1.4",
> -    .init = pc_q35_init_1_4,
> -    .compat_props = (GlobalProperty[]) {
> +static void pc_q35_machine_v1_4_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    static GlobalProperty compat_props[] = {
>          PC_COMPAT_1_4,
>          { /* end of list */ }
> -    },
> +    };
> +    pc_q35_1_4_machine_options(mc);
> +    mc->init = pc_q35_init_1_4;
> +    mc->compat_props = compat_props;
> +    mc->name = "pc-q35-1.4";
> +}
> +
> +static TypeInfo pc_q35_machine_v1_4_type_info = {
> +    .name = "pc-q35-1.4" TYPE_MACHINE_SUFFIX,
> +    .parent = TYPE_PC_MACHINE,
> +    .class_init = pc_q35_machine_v1_4_class_init,
>  };
>  
>  static void pc_q35_machine_init(void)
>  {
> -    qemu_register_machine(&pc_q35_machine_v2_1);
> -    qemu_register_machine(&pc_q35_machine_v2_0);
> -    qemu_register_machine(&pc_q35_machine_v1_7);
> -    qemu_register_machine(&pc_q35_machine_v1_6);
> -    qemu_register_machine(&pc_q35_machine_v1_5);
> -    qemu_register_machine(&pc_q35_machine_v1_4);
> +    type_register_static(&pc_q35_machine_v2_1_type_info);
> +    type_register_static(&pc_q35_machine_v2_0_type_info);
> +    type_register_static(&pc_q35_machine_v1_7_type_info);
> +    type_register_static(&pc_q35_machine_v1_6_type_info);
> +    type_register_static(&pc_q35_machine_v1_5_type_info);
> +    type_register_static(&pc_q35_machine_v1_4_type_info);
>  }
>  
>  machine_init(pc_q35_machine_init);
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index fa9d997..4d85847 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -7,6 +7,7 @@
>  #include "hw/block/fdc.h"
>  #include "net/net.h"
>  #include "hw/i386/ioapic.h"
> +#include "hw/boards.h"
>  
>  #include "qemu/range.h"
>  #include "qemu/bitmap.h"
> @@ -438,12 +439,21 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
>              .value    = stringify(0),\
>          }
>  
> -#define PC_COMMON_MACHINE_OPTIONS \
> -    .default_boot_order = "cad"
> +static inline void pc_common_machine_options(MachineClass *mc)
> +{
> +    mc->default_boot_order = "cad";
> +}
> +
> +static inline void pc_default_machine_options(MachineClass *mc)
> +{
> +    pc_common_machine_options(mc);
> +    mc->hot_add_cpu = pc_hot_add_cpu;
> +    mc->max_cpus = 255;
> +}
>  
>  #define PC_DEFAULT_MACHINE_OPTIONS \
> -    PC_COMMON_MACHINE_OPTIONS, \
> -    .hot_add_cpu = pc_hot_add_cpu, \
> -    .max_cpus = 255
> +
> +
> +#define TYPE_PC_MACHINE "pc-machine"
>  
>  #endif
> -- 
> 1.9.0

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  8:12   ` Marcel Apfelbaum
@ 2014-06-12  8:20     ` Michael S. Tsirkin
  2014-06-12  8:38       ` Igor Mammedov
  2014-06-12  8:23     ` Igor Mammedov
  1 sibling, 1 reply; 10+ messages in thread
From: Michael S. Tsirkin @ 2014-06-12  8:20 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: Eduardo Habkost, Alexander Graf, Don Slutz, qemu-devel,
	Anthony Liguori, Igor Mammedov, Andreas Färber

On Thu, Jun 12, 2014 at 11:12:01AM +0300, Marcel Apfelbaum wrote:
> On Thu, 2014-06-12 at 10:02 +0200, Igor Mammedov wrote:
> > On Thu, 12 Jun 2014 03:22:24 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> > 
> > > This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> > > definitions to corresponding class registration code.
> > > 
> > > Having the PC code converted to pure QOM registration code will help us
> > > move PC-specific machine state that is currently held in static
> > > variables inside PC machine objects, and reduce duplication between
> > > pc_piix.c and pc_q35.c.
> > 
> > Getting rid of *_machine_options() functions and doing nested
> > inheritance with necessary overrides in respective *_class_init()
> > functions, would make code more readable/understandable.
> While I agree with you that this is the right direction, Eduardo's
> patch is a good step forward getting rid of QEMUMachine and those
> defines. I say we implement the hierarchy on top of this patch.

If we add code as an intermediate step that's fine,
but I'd like to see the whole thing before applying.
There should be net reduction in amount of
boilerplate code at the end of the day.




> > 
> > > 
> > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > > ---
> > >  hw/i386/pc.c         |  13 ++
> > >  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
> > >  hw/i386/pc_q35.c     | 171 +++++++++++++------
> > >  include/hw/i386/pc.h |  20 ++-
> > >  4 files changed, 465 insertions(+), 212 deletions(-)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 32d1632..56720cd 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
> > >          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
> > >      }
> > >  }
> > > +
> > > +static TypeInfo pc_machine_type_info = {
> > > +        .name       = TYPE_PC_MACHINE,
> > > +        .parent     = TYPE_MACHINE,
> > > +        .abstract   = true,
> > > +};
> Igor's series already introduces TYPE_PC_MACHINE, you may want to rebase on it:
> http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00133.html
> 
> Thanks,
> Marcel
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  8:12   ` Marcel Apfelbaum
  2014-06-12  8:20     ` Michael S. Tsirkin
@ 2014-06-12  8:23     ` Igor Mammedov
  1 sibling, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2014-06-12  8:23 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: Eduardo Habkost, Michael S. Tsirkin, qemu-devel, Don Slutz,
	Alexander Graf, Anthony Liguori, Andreas Färber

On Thu, 12 Jun 2014 11:12:01 +0300
Marcel Apfelbaum <marcel.a@redhat.com> wrote:

> On Thu, 2014-06-12 at 10:02 +0200, Igor Mammedov wrote:
> > On Thu, 12 Jun 2014 03:22:24 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> > 
> > > This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> > > definitions to corresponding class registration code.
> > > 
> > > Having the PC code converted to pure QOM registration code will help us
> > > move PC-specific machine state that is currently held in static
> > > variables inside PC machine objects, and reduce duplication between
> > > pc_piix.c and pc_q35.c.
> > 
> > Getting rid of *_machine_options() functions and doing nested
> > inheritance with necessary overrides in respective *_class_init()
> > functions, would make code more readable/understandable.
> While I agree with you that this is the right direction, Eduardo's
> patch is a good step forward getting rid of QEMUMachine and those
> defines. I say we implement the hierarchy on top of this patch.
it's fine if there is the 2nd patch in the same series that does
it right. Otherwise result looks worse than it was before.

> > 
> > > 
> > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > > ---
> > >  hw/i386/pc.c         |  13 ++
> > >  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
> > >  hw/i386/pc_q35.c     | 171 +++++++++++++------
> > >  include/hw/i386/pc.h |  20 ++-
> > >  4 files changed, 465 insertions(+), 212 deletions(-)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 32d1632..56720cd 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
> > >          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
> > >      }
> > >  }
> > > +
> > > +static TypeInfo pc_machine_type_info = {
> > > +        .name       = TYPE_PC_MACHINE,
> > > +        .parent     = TYPE_MACHINE,
> > > +        .abstract   = true,
> > > +};
> Igor's series already introduces TYPE_PC_MACHINE, you may want to rebase on it:
> http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00133.html
> 
> Thanks,
> Marcel
> 
> 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  8:13 ` Michael S. Tsirkin
@ 2014-06-12  8:37   ` Igor Mammedov
  2014-06-12  8:49     ` Michael S. Tsirkin
  2014-06-13  6:08     ` Eduardo Habkost
  0 siblings, 2 replies; 10+ messages in thread
From: Igor Mammedov @ 2014-06-12  8:37 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Eduardo Habkost, Marcel Apfelbaum, qemu-devel, Don Slutz,
	Alexander Graf, Anthony Liguori, Andreas Färber

On Thu, 12 Jun 2014 11:13:49 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Jun 12, 2014 at 03:22:24AM -0300, Eduardo Habkost wrote:
> > This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> > definitions to corresponding class registration code.
> > 
> > Having the PC code converted to pure QOM registration code will help us
> > move PC-specific machine state that is currently held in static
> > variables inside PC machine objects, and reduce duplication between
> > pc_piix.c and pc_q35.c.
> > 
> > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > ---
> >  hw/i386/pc.c         |  13 ++
> >  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
> >  hw/i386/pc_q35.c     | 171 +++++++++++++------
> >  include/hw/i386/pc.h |  20 ++-
> >  4 files changed, 465 insertions(+), 212 deletions(-)
> 
> Hmm amount of boilerplate code seems to have doubled.
> Can we find a solution that does away with code duplication?
> Here's one idea: create one giant array with all necessary data, look it
> up by name at runtime and fill everything in.
> Not sure it's going to work out but might be worth a try.
It's not quite QOMish way,
making version-ed classes nested should reduce amount of boiler plate
and make it easier to read/write.
And if machines are made nested then we should also rethink usage/get rid of
PC_COMPAT_* macros-es utilizing nesting provided by class hierarchy.

This patch could serve as an intermediate step to remove usage of QEMUMachine though.

> 
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 32d1632..56720cd 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
> >          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
> >      }
> >  }
> > +
> > +static TypeInfo pc_machine_type_info = {
> > +        .name       = TYPE_PC_MACHINE,
> > +        .parent     = TYPE_MACHINE,
> > +        .abstract   = true,
> > +};
> > +
> > +static void pc_machine_init(void)
> > +{
> > +    type_register_static(&pc_machine_type_info);
> > +}
> > +
> > +type_init(pc_machine_init);
> > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> > index a48e263..d4b4033 100644
> > --- a/hw/i386/pc_piix.c
> > +++ b/hw/i386/pc_piix.c
> > @@ -392,81 +392,140 @@ static void pc_xen_hvm_init(MachineState *machine)
> >  }
> >  #endif
> >  
> > -#define PC_I440FX_MACHINE_OPTIONS \
> > -    PC_DEFAULT_MACHINE_OPTIONS, \
> > -    .desc = "Standard PC (i440FX + PIIX, 1996)", \
> > -    .hot_add_cpu = pc_hot_add_cpu
> > -
> > -#define PC_I440FX_2_1_MACHINE_OPTIONS                           \
> > -    PC_I440FX_MACHINE_OPTIONS,                                  \
> > -    .default_machine_opts = "firmware=bios-256k.bin"
> > -
> > -static QEMUMachine pc_i440fx_machine_v2_1 = {
> > -    PC_I440FX_2_1_MACHINE_OPTIONS,
> > -    .name = "pc-i440fx-2.1",
> > -    .alias = "pc",
> > -    .init = pc_init_pci,
> > -    .is_default = 1,
> > +static void pc_i440fx_machine_options(MachineClass *mc)
> > +{
> > +    pc_default_machine_options(mc);
> > +    mc->desc = "Standard PC (i440FX + PIIX, 1996)";
> > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > +}
> > +
> > +static void pc_i440fx_2_1_machine_options(MachineClass *mc)
> > +{
> > +    pc_i440fx_machine_options(mc);
> > +    mc->default_machine_opts = "firmware=bios-256k.bin";
> > +}
> > +
> > +static void pc_i440fx_machine_v2_1_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    pc_i440fx_2_1_machine_options(mc);
> > +    mc->alias = "pc";
> > +    mc->init = pc_init_pci;
> > +    mc->is_default = 1;
> > +    mc->name = "pc-i440fx-2.1";
> > +}
> > +
> > +static TypeInfo pc_i440fx_machine_v2_1_type_info = {
> > +    .name = "pc-i440fx-2.1" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_i440fx_machine_v2_1_class_init,
> >  };
> >  
> > -#define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS
> > +#define pc_i440fx_2_0_machine_options pc_i440fx_2_1_machine_options
> >  
> > -static QEMUMachine pc_i440fx_machine_v2_0 = {
> > -    PC_I440FX_2_0_MACHINE_OPTIONS,
> > -    .name = "pc-i440fx-2.0",
> > -    .init = pc_init_pci_2_0,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_i440fx_machine_v2_0_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_2_0,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_2_0_machine_options(mc);
> > +    mc->init = pc_init_pci_2_0;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-i440fx-2.0";
> > +}
> > +
> > +static TypeInfo pc_i440fx_machine_v2_0_type_info = {
> > +    .name = "pc-i440fx-2.0" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_i440fx_machine_v2_0_class_init,
> >  };
> >  
> > -#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> > +#define pc_i440fx_1_7_machine_options pc_i440fx_machine_options
> >  
> > -static QEMUMachine pc_i440fx_machine_v1_7 = {
> > -    PC_I440FX_1_7_MACHINE_OPTIONS,
> > -    .name = "pc-i440fx-1.7",
> > -    .init = pc_init_pci_1_7,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_i440fx_machine_v1_7_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_7,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_1_7_machine_options(mc);
> > +    mc->init = pc_init_pci_1_7;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-i440fx-1.7";
> > +}
> > +
> > +static TypeInfo pc_i440fx_machine_v1_7_type_info = {
> > +    .name = "pc-i440fx-1.7" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_i440fx_machine_v1_7_class_init,
> >  };
> >  
> > -#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> > +#define pc_i440fx_1_6_machine_options pc_i440fx_machine_options
> >  
> > -static QEMUMachine pc_i440fx_machine_v1_6 = {
> > -    PC_I440FX_1_6_MACHINE_OPTIONS,
> > -    .name = "pc-i440fx-1.6",
> > -    .init = pc_init_pci_1_6,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_i440fx_machine_v1_6_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_6,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_1_6_machine_options(mc);
> > +    mc->init = pc_init_pci_1_6;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-i440fx-1.6";
> > +}
> > +
> > +static TypeInfo pc_i440fx_machine_v1_6_type_info = {
> > +    .name = "pc-i440fx-1.6" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_i440fx_machine_v1_6_class_init,
> >  };
> >  
> > -static QEMUMachine pc_i440fx_machine_v1_5 = {
> > -    PC_I440FX_1_6_MACHINE_OPTIONS,
> > -    .name = "pc-i440fx-1.5",
> > -    .init = pc_init_pci_1_5,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_i440fx_machine_v1_5_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_5,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_1_6_machine_options(mc);
> > +    mc->init = pc_init_pci_1_5;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-i440fx-1.5";
> > +}
> > +
> > +static TypeInfo pc_i440fx_machine_v1_5_type_info = {
> > +    .name = "pc-i440fx-1.5" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_i440fx_machine_v1_5_class_init,
> >  };
> >  
> > -#define PC_I440FX_1_4_MACHINE_OPTIONS \
> > -    PC_I440FX_1_6_MACHINE_OPTIONS, \
> > -    .hot_add_cpu = NULL
> > +static void pc_i440fx_1_4_machine_options(MachineClass *mc)
> > +{
> > +    pc_i440fx_1_6_machine_options(mc);
> > +    mc->hot_add_cpu = NULL;
> > +}
> >  
> > -static QEMUMachine pc_i440fx_machine_v1_4 = {
> > -    PC_I440FX_1_4_MACHINE_OPTIONS,
> > -    .name = "pc-i440fx-1.4",
> > -    .init = pc_init_pci_1_4,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_i440fx_machine_v1_4_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_4,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_1_4_machine_options(mc);
> > +    mc->init = pc_init_pci_1_4;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-i440fx-1.4";
> > +}
> > +
> > +static TypeInfo pc_i440fx_machine_v1_4_type_info = {
> > +    .name = "pc-i440fx-1.4" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_i440fx_machine_v1_4_class_init,
> >  };
> >  
> >  #define PC_COMPAT_1_3 \
> > @@ -489,14 +548,23 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
> >              .value    = "off",\
> >          }
> >  
> > -static QEMUMachine pc_machine_v1_3 = {
> > -    PC_I440FX_1_4_MACHINE_OPTIONS,
> > -    .name = "pc-1.3",
> > -    .init = pc_init_pci_1_3,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v1_3_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_3,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_1_4_machine_options(mc);
> > +    mc->init = pc_init_pci_1_3;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-1.3";
> > +}
> > +
> > +static TypeInfo pc_machine_v1_3_type_info = {
> > +    .name = "pc-1.3" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v1_3_class_init,
> >  };
> >  
> >  #define PC_COMPAT_1_2 \
> > @@ -527,17 +595,28 @@ static QEMUMachine pc_machine_v1_3 = {
> >              .value    = "off",\
> >          }
> >  
> > -#define PC_I440FX_1_2_MACHINE_OPTIONS \
> > -    PC_I440FX_1_4_MACHINE_OPTIONS, \
> > -    .init = pc_init_pci_1_2
> > +static void pc_i440fx_1_2_machine_options(MachineClass *mc)
> > +{
> > +    pc_i440fx_1_4_machine_options(mc);
> > +    mc->init = pc_init_pci_1_2;
> > +}
> >  
> > -static QEMUMachine pc_machine_v1_2 = {
> > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > -    .name = "pc-1.2",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v1_2_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_2,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_1_2_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-1.2";
> > +}
> > +
> > +static TypeInfo pc_machine_v1_2_type_info = {
> > +    .name = "pc-1.2" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v1_2_class_init,
> >  };
> >  
> >  #define PC_COMPAT_1_1 \
> > @@ -572,13 +651,22 @@ static QEMUMachine pc_machine_v1_2 = {
> >              .value    = "off",\
> >          }
> >  
> > -static QEMUMachine pc_machine_v1_1 = {
> > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > -    .name = "pc-1.1",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v1_1_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_1,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_i440fx_1_2_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-1.1";
> > +}
> > +
> > +static TypeInfo pc_machine_v1_1_type_info = {
> > +    .name = "pc-1.1" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v1_1_class_init,
> >  };
> >  
> >  #define PC_COMPAT_1_0 \
> > @@ -601,27 +689,45 @@ static QEMUMachine pc_machine_v1_1 = {
> >              .value    = "no",\
> >          }
> >  
> > -static QEMUMachine pc_machine_v1_0 = {
> > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > -    .name = "pc-1.0",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v1_0_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_0,
> >          { /* end of list */ }
> > -    },
> > -    .hw_version = "1.0",
> > +    };
> > +    pc_i440fx_1_2_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->hw_version = "1.0";
> > +    mc->name = "pc-1.0";
> > +}
> > +
> > +static TypeInfo pc_machine_v1_0_type_info = {
> > +    .name = "pc-1.0" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v1_0_class_init,
> >  };
> >  
> >  #define PC_COMPAT_0_15 \
> >          PC_COMPAT_1_0
> >  
> > -static QEMUMachine pc_machine_v0_15 = {
> > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > -    .name = "pc-0.15",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v0_15_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_0_15,
> >          { /* end of list */ }
> > -    },
> > -    .hw_version = "0.15",
> > +    };
> > +    pc_i440fx_1_2_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->hw_version = "0.15";
> > +    mc->name = "pc-0.15";
> > +}
> > +
> > +static TypeInfo pc_machine_v0_15_type_info = {
> > +    .name = "pc-0.15" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v0_15_class_init,
> >  };
> >  
> >  #define PC_COMPAT_0_14 \
> > @@ -644,10 +750,10 @@ static QEMUMachine pc_machine_v0_15 = {
> >              .value    = "off",\
> >          }
> >  
> > -static QEMUMachine pc_machine_v0_14 = {
> > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > -    .name = "pc-0.14",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v0_14_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_0_14, 
> >          {
> >              .driver   = "qxl",
> > @@ -659,8 +765,17 @@ static QEMUMachine pc_machine_v0_14 = {
> >              .value    = stringify(2),
> >          },
> >          { /* end of list */ }
> > -    },
> > -    .hw_version = "0.14",
> > +    };
> > +    pc_i440fx_1_2_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->hw_version = "0.14";
> > +    mc->name = "pc-0.14";
> > +}
> > +
> > +static TypeInfo pc_machine_v0_14_type_info = {
> > +    .name = "pc-0.14" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v0_14_class_init,
> >  };
> >  
> >  #define PC_COMPAT_0_13 \
> > @@ -675,14 +790,16 @@ static QEMUMachine pc_machine_v0_14 = {
> >              .value    = stringify(1),\
> >          }
> >  
> > -#define PC_I440FX_0_13_MACHINE_OPTIONS \
> > -    PC_I440FX_1_2_MACHINE_OPTIONS, \
> > -    .init = pc_init_pci_no_kvmclock
> > +static void pc_i440fx_0_13_machine_options(MachineClass *mc)
> > +{
> > +    pc_i440fx_1_2_machine_options(mc);
> > +    mc->init = pc_init_pci_no_kvmclock;
> > +}
> >  
> > -static QEMUMachine pc_machine_v0_13 = {
> > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > -    .name = "pc-0.13",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v0_13_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_0_13,
> >          {
> >              .driver   = "virtio-9p-pci",
> > @@ -698,8 +815,17 @@ static QEMUMachine pc_machine_v0_13 = {
> >              .value    = stringify(0),
> >          },
> >          { /* end of list */ }
> > -    },
> > -    .hw_version = "0.13",
> > +    };
> > +    pc_i440fx_0_13_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->hw_version = "0.13";
> > +    mc->name = "pc-0.13";
> > +}
> > +
> > +static TypeInfo pc_machine_v0_13_type_info = {
> > +    .name = "pc-0.13" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v0_13_class_init,
> >  };
> >  
> >  #define PC_COMPAT_0_12 \
> > @@ -726,10 +852,10 @@ static QEMUMachine pc_machine_v0_13 = {
> >              .value    = "1",\
> >          }
> >  
> > -static QEMUMachine pc_machine_v0_12 = {
> > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > -    .name = "pc-0.12",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v0_12_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_0_12,
> >          {
> >              .driver   = "VGA",
> > @@ -741,8 +867,17 @@ static QEMUMachine pc_machine_v0_12 = {
> >              .value    = stringify(0),
> >          },
> >          { /* end of list */ }
> > -    },
> > -    .hw_version = "0.12",
> > +    };
> > +    pc_i440fx_0_13_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->hw_version = "0.12";
> > +    mc->name = "pc-0.12";
> > +}
> > +
> > +static TypeInfo pc_machine_v0_12_type_info = {
> > +    .name = "pc-0.12" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v0_12_class_init,
> >  };
> >  
> >  #define PC_COMPAT_0_11 \
> > @@ -757,10 +892,10 @@ static QEMUMachine pc_machine_v0_12 = {
> >              .value    = stringify(0),\
> >          }
> >  
> > -static QEMUMachine pc_machine_v0_11 = {
> > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > -    .name = "pc-0.11",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v0_11_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_0_11,
> >          {
> >              .driver   = "ide-drive",
> > @@ -772,14 +907,23 @@ static QEMUMachine pc_machine_v0_11 = {
> >              .value    = "0.11",
> >          },
> >          { /* end of list */ }
> > -    },
> > -    .hw_version = "0.11",
> > +    };
> > +    pc_i440fx_0_13_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->hw_version = "0.11";
> > +    mc->name = "pc-0.11";
> > +}
> > +
> > +static TypeInfo pc_machine_v0_11_type_info = {
> > +    .name = "pc-0.11" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v0_11_class_init,
> >  };
> >  
> > -static QEMUMachine pc_machine_v0_10 = {
> > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > -    .name = "pc-0.10",
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_machine_v0_10_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_0_11,
> >          {
> >              .driver   = "virtio-blk-pci",
> > @@ -803,31 +947,44 @@ static QEMUMachine pc_machine_v0_10 = {
> >              .value    = "0.10",
> >          },
> >          { /* end of list */ }
> > -    },
> > -    .hw_version = "0.10",
> > +    };
> > +    pc_i440fx_0_13_machine_options(mc);
> > +    mc->compat_props = compat_props;
> > +    mc->hw_version = "0.10";
> > +    mc->name = "pc-0.10";
> > +}
> > +
> > +static TypeInfo pc_machine_v0_10_type_info = {
> > +    .name = "pc-0.10" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_machine_v0_10_class_init,
> >  };
> >  
> > -static QEMUMachine isapc_machine = {
> > -    PC_COMMON_MACHINE_OPTIONS,
> > -    .name = "isapc",
> > -    .desc = "ISA-only PC",
> > -    .init = pc_init_isa,
> > -    .max_cpus = 1,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void isapc_machine_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_common_machine_options(mc);
> > +    mc->desc = "ISA-only PC";
> > +    mc->init = pc_init_isa;
> > +    mc->max_cpus = 1;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "isapc";
> > +}
> > +
> > +static TypeInfo isapc_machine_type_info = {
> > +    .name = "isapc" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = isapc_machine_class_init,
> >  };
> >  
> >  #ifdef CONFIG_XEN
> > -static QEMUMachine xenfv_machine = {
> > -    PC_COMMON_MACHINE_OPTIONS,
> > -    .name = "xenfv",
> > -    .desc = "Xen Fully-virtualized PC",
> > -    .init = pc_xen_hvm_init,
> > -    .max_cpus = HVM_MAX_VCPUS,
> > -    .default_machine_opts = "accel=xen",
> > -    .hot_add_cpu = pc_hot_add_cpu,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void xenfv_machine_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          /* xenfv has no fwcfg and so does not load acpi from QEMU.
> >           * as such new acpi features don't work.
> >           */
> > @@ -837,31 +994,45 @@ static QEMUMachine xenfv_machine = {
> >              .value    = "off",
> >          },
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_common_machine_options(mc);
> > +    mc->desc = "Xen Fully-virtualized PC";
> > +    mc->init = pc_xen_hvm_init;
> > +    mc->max_cpus = HVM_MAX_VCPUS;
> > +    mc->default_machine_opts = "accel=xen";
> > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "xenfv";
> > +}
> > +
> > +static TypeInfo xenfv_machine_type_info = {
> > +    .name = "xenfv" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = xenfv_machine_class_init,
> >  };
> >  #endif
> >  
> >  static void pc_machine_init(void)
> >  {
> > -    qemu_register_machine(&pc_i440fx_machine_v2_1);
> > -    qemu_register_machine(&pc_i440fx_machine_v2_0);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_7);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_6);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_5);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_4);
> > -    qemu_register_machine(&pc_machine_v1_3);
> > -    qemu_register_machine(&pc_machine_v1_2);
> > -    qemu_register_machine(&pc_machine_v1_1);
> > -    qemu_register_machine(&pc_machine_v1_0);
> > -    qemu_register_machine(&pc_machine_v0_15);
> > -    qemu_register_machine(&pc_machine_v0_14);
> > -    qemu_register_machine(&pc_machine_v0_13);
> > -    qemu_register_machine(&pc_machine_v0_12);
> > -    qemu_register_machine(&pc_machine_v0_11);
> > -    qemu_register_machine(&pc_machine_v0_10);
> > -    qemu_register_machine(&isapc_machine);
> > +    type_register_static(&pc_i440fx_machine_v2_1_type_info);
> > +    type_register_static(&pc_i440fx_machine_v2_0_type_info);
> > +    type_register_static(&pc_i440fx_machine_v1_7_type_info);
> > +    type_register_static(&pc_i440fx_machine_v1_6_type_info);
> > +    type_register_static(&pc_i440fx_machine_v1_5_type_info);
> > +    type_register_static(&pc_i440fx_machine_v1_4_type_info);
> > +    type_register_static(&pc_machine_v1_3_type_info);
> > +    type_register_static(&pc_machine_v1_2_type_info);
> > +    type_register_static(&pc_machine_v1_1_type_info);
> > +    type_register_static(&pc_machine_v1_0_type_info);
> > +    type_register_static(&pc_machine_v0_15_type_info);
> > +    type_register_static(&pc_machine_v0_14_type_info);
> > +    type_register_static(&pc_machine_v0_13_type_info);
> > +    type_register_static(&pc_machine_v0_12_type_info);
> > +    type_register_static(&pc_machine_v0_11_type_info);
> > +    type_register_static(&pc_machine_v0_10_type_info);
> > +    type_register_static(&isapc_machine_type_info);
> >  #ifdef CONFIG_XEN
> > -    qemu_register_machine(&xenfv_machine);
> > +    type_register_static(&xenfv_machine_type_info);
> >  #endif
> >  }
> >  
> > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > index b3c02c1..6e909f7 100644
> > --- a/hw/i386/pc_q35.c
> > +++ b/hw/i386/pc_q35.c
> > @@ -306,90 +306,149 @@ static void pc_q35_init_1_4(MachineState *machine)
> >      pc_q35_init(machine);
> >  }
> >  
> > -#define PC_Q35_MACHINE_OPTIONS \
> > -    PC_DEFAULT_MACHINE_OPTIONS, \
> > -    .desc = "Standard PC (Q35 + ICH9, 2009)", \
> > -    .hot_add_cpu = pc_hot_add_cpu
> > -
> > -#define PC_Q35_2_1_MACHINE_OPTIONS                      \
> > -    PC_Q35_MACHINE_OPTIONS,                             \
> > -    .default_machine_opts = "firmware=bios-256k.bin"
> > -
> > -static QEMUMachine pc_q35_machine_v2_1 = {
> > -    PC_Q35_2_1_MACHINE_OPTIONS,
> > -    .name = "pc-q35-2.1",
> > -    .alias = "q35",
> > -    .init = pc_q35_init,
> > +static void pc_q35_machine_options(MachineClass *mc)
> > +{
> > +    pc_default_machine_options(mc);
> > +    mc->desc = "Standard PC (Q35 + ICH9, 2009)";
> > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > +}
> > +
> > +static void pc_q35_2_1_machine_options(MachineClass *mc)
> > +{
> > +    pc_q35_machine_options(mc);
> > +    mc->default_machine_opts = "firmware=bios-256k.bin";
> > +}
> > +
> > +static void pc_q35_machine_v2_1_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    pc_q35_2_1_machine_options(mc);
> > +    mc->alias = "q35";
> > +    mc->init = pc_q35_init;
> > +    mc->name = "pc-q35-2.1";
> > +}
> > +
> > +static TypeInfo pc_q35_machine_v2_1_type_info = {
> > +    .name = "pc-q35-2.1" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_q35_machine_v2_1_class_init,
> >  };
> >  
> > -#define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS
> > +#define pc_q35_2_0_machine_options pc_q35_2_1_machine_options
> >  
> > -static QEMUMachine pc_q35_machine_v2_0 = {
> > -    PC_Q35_2_0_MACHINE_OPTIONS,
> > -    .name = "pc-q35-2.0",
> > -    .init = pc_q35_init_2_0,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_q35_machine_v2_0_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_Q35_COMPAT_2_0,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_q35_2_0_machine_options(mc);
> > +    mc->init = pc_q35_init_2_0;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-q35-2.0";
> > +}
> > +
> > +static TypeInfo pc_q35_machine_v2_0_type_info = {
> > +    .name = "pc-q35-2.0" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_q35_machine_v2_0_class_init,
> >  };
> >  
> > -#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> > +#define pc_q35_1_7_machine_options pc_q35_machine_options
> >  
> > -static QEMUMachine pc_q35_machine_v1_7 = {
> > -    PC_Q35_1_7_MACHINE_OPTIONS,
> > -    .name = "pc-q35-1.7",
> > -    .init = pc_q35_init_1_7,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_q35_machine_v1_7_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_Q35_COMPAT_1_7,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_q35_1_7_machine_options(mc);
> > +    mc->init = pc_q35_init_1_7;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-q35-1.7";
> > +}
> > +
> > +static TypeInfo pc_q35_machine_v1_7_type_info = {
> > +    .name = "pc-q35-1.7" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_q35_machine_v1_7_class_init,
> >  };
> >  
> > -#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> > +#define pc_q35_1_6_machine_options pc_q35_machine_options
> >  
> > -static QEMUMachine pc_q35_machine_v1_6 = {
> > -    PC_Q35_1_6_MACHINE_OPTIONS,
> > -    .name = "pc-q35-1.6",
> > -    .init = pc_q35_init_1_6,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_q35_machine_v1_6_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_Q35_COMPAT_1_6,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_q35_1_6_machine_options(mc);
> > +    mc->init = pc_q35_init_1_6;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-q35-1.6";
> > +}
> > +
> > +static TypeInfo pc_q35_machine_v1_6_type_info = {
> > +    .name = "pc-q35-1.6" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_q35_machine_v1_6_class_init,
> >  };
> >  
> > -static QEMUMachine pc_q35_machine_v1_5 = {
> > -    PC_Q35_1_6_MACHINE_OPTIONS,
> > -    .name = "pc-q35-1.5",
> > -    .init = pc_q35_init_1_5,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_q35_machine_v1_5_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_Q35_COMPAT_1_5,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_q35_1_6_machine_options(mc);
> > +    mc->init = pc_q35_init_1_5;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-q35-1.5";
> > +}
> > +
> > +static TypeInfo pc_q35_machine_v1_5_type_info = {
> > +    .name = "pc-q35-1.5" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_q35_machine_v1_5_class_init,
> >  };
> >  
> > -#define PC_Q35_1_4_MACHINE_OPTIONS \
> > -    PC_Q35_1_6_MACHINE_OPTIONS, \
> > -    .hot_add_cpu = NULL
> > +static void pc_q35_1_4_machine_options(MachineClass *mc)
> > +{
> > +    pc_q35_1_6_machine_options(mc);
> > +    mc->hot_add_cpu = NULL;
> > +}
> >  
> > -static QEMUMachine pc_q35_machine_v1_4 = {
> > -    PC_Q35_1_4_MACHINE_OPTIONS,
> > -    .name = "pc-q35-1.4",
> > -    .init = pc_q35_init_1_4,
> > -    .compat_props = (GlobalProperty[]) {
> > +static void pc_q35_machine_v1_4_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    static GlobalProperty compat_props[] = {
> >          PC_COMPAT_1_4,
> >          { /* end of list */ }
> > -    },
> > +    };
> > +    pc_q35_1_4_machine_options(mc);
> > +    mc->init = pc_q35_init_1_4;
> > +    mc->compat_props = compat_props;
> > +    mc->name = "pc-q35-1.4";
> > +}
> > +
> > +static TypeInfo pc_q35_machine_v1_4_type_info = {
> > +    .name = "pc-q35-1.4" TYPE_MACHINE_SUFFIX,
> > +    .parent = TYPE_PC_MACHINE,
> > +    .class_init = pc_q35_machine_v1_4_class_init,
> >  };
> >  
> >  static void pc_q35_machine_init(void)
> >  {
> > -    qemu_register_machine(&pc_q35_machine_v2_1);
> > -    qemu_register_machine(&pc_q35_machine_v2_0);
> > -    qemu_register_machine(&pc_q35_machine_v1_7);
> > -    qemu_register_machine(&pc_q35_machine_v1_6);
> > -    qemu_register_machine(&pc_q35_machine_v1_5);
> > -    qemu_register_machine(&pc_q35_machine_v1_4);
> > +    type_register_static(&pc_q35_machine_v2_1_type_info);
> > +    type_register_static(&pc_q35_machine_v2_0_type_info);
> > +    type_register_static(&pc_q35_machine_v1_7_type_info);
> > +    type_register_static(&pc_q35_machine_v1_6_type_info);
> > +    type_register_static(&pc_q35_machine_v1_5_type_info);
> > +    type_register_static(&pc_q35_machine_v1_4_type_info);
> >  }
> >  
> >  machine_init(pc_q35_machine_init);
> > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > index fa9d997..4d85847 100644
> > --- a/include/hw/i386/pc.h
> > +++ b/include/hw/i386/pc.h
> > @@ -7,6 +7,7 @@
> >  #include "hw/block/fdc.h"
> >  #include "net/net.h"
> >  #include "hw/i386/ioapic.h"
> > +#include "hw/boards.h"
> >  
> >  #include "qemu/range.h"
> >  #include "qemu/bitmap.h"
> > @@ -438,12 +439,21 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
> >              .value    = stringify(0),\
> >          }
> >  
> > -#define PC_COMMON_MACHINE_OPTIONS \
> > -    .default_boot_order = "cad"
> > +static inline void pc_common_machine_options(MachineClass *mc)
> > +{
> > +    mc->default_boot_order = "cad";
> > +}
> > +
> > +static inline void pc_default_machine_options(MachineClass *mc)
> > +{
> > +    pc_common_machine_options(mc);
> > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > +    mc->max_cpus = 255;
> > +}
> >  
> >  #define PC_DEFAULT_MACHINE_OPTIONS \
> > -    PC_COMMON_MACHINE_OPTIONS, \
> > -    .hot_add_cpu = pc_hot_add_cpu, \
> > -    .max_cpus = 255
> > +
> > +
> > +#define TYPE_PC_MACHINE "pc-machine"
> >  
> >  #endif
> > -- 
> > 1.9.0
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  8:20     ` Michael S. Tsirkin
@ 2014-06-12  8:38       ` Igor Mammedov
  0 siblings, 0 replies; 10+ messages in thread
From: Igor Mammedov @ 2014-06-12  8:38 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Eduardo Habkost, Marcel Apfelbaum, qemu-devel, Don Slutz,
	Alexander Graf, Anthony Liguori, Andreas Färber

On Thu, 12 Jun 2014 11:20:05 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Jun 12, 2014 at 11:12:01AM +0300, Marcel Apfelbaum wrote:
> > On Thu, 2014-06-12 at 10:02 +0200, Igor Mammedov wrote:
> > > On Thu, 12 Jun 2014 03:22:24 -0300
> > > Eduardo Habkost <ehabkost@redhat.com> wrote:
> > > 
> > > > This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> > > > definitions to corresponding class registration code.
> > > > 
> > > > Having the PC code converted to pure QOM registration code will help us
> > > > move PC-specific machine state that is currently held in static
> > > > variables inside PC machine objects, and reduce duplication between
> > > > pc_piix.c and pc_q35.c.
> > > 
> > > Getting rid of *_machine_options() functions and doing nested
> > > inheritance with necessary overrides in respective *_class_init()
> > > functions, would make code more readable/understandable.
> > While I agree with you that this is the right direction, Eduardo's
> > patch is a good step forward getting rid of QEMUMachine and those
> > defines. I say we implement the hierarchy on top of this patch.
> 
> If we add code as an intermediate step that's fine,
> but I'd like to see the whole thing before applying.
> There should be net reduction in amount of
> boilerplate code at the end of the day.
+1

> 
> 
> 
> 
> > > 
> > > > 
> > > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > > > ---
> > > >  hw/i386/pc.c         |  13 ++
> > > >  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
> > > >  hw/i386/pc_q35.c     | 171 +++++++++++++------
> > > >  include/hw/i386/pc.h |  20 ++-
> > > >  4 files changed, 465 insertions(+), 212 deletions(-)
> > > > 
> > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > > index 32d1632..56720cd 100644
> > > > --- a/hw/i386/pc.c
> > > > +++ b/hw/i386/pc.c
> > > > @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
> > > >          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
> > > >      }
> > > >  }
> > > > +
> > > > +static TypeInfo pc_machine_type_info = {
> > > > +        .name       = TYPE_PC_MACHINE,
> > > > +        .parent     = TYPE_MACHINE,
> > > > +        .abstract   = true,
> > > > +};
> > Igor's series already introduces TYPE_PC_MACHINE, you may want to rebase on it:
> > http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00133.html
> > 
> > Thanks,
> > Marcel
> > 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  8:37   ` Igor Mammedov
@ 2014-06-12  8:49     ` Michael S. Tsirkin
  2014-06-13  6:08     ` Eduardo Habkost
  1 sibling, 0 replies; 10+ messages in thread
From: Michael S. Tsirkin @ 2014-06-12  8:49 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Eduardo Habkost, Marcel Apfelbaum, qemu-devel, Don Slutz,
	Alexander Graf, Anthony Liguori, Andreas Färber

On Thu, Jun 12, 2014 at 10:37:29AM +0200, Igor Mammedov wrote:
> On Thu, 12 Jun 2014 11:13:49 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Jun 12, 2014 at 03:22:24AM -0300, Eduardo Habkost wrote:
> > > This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> > > definitions to corresponding class registration code.
> > > 
> > > Having the PC code converted to pure QOM registration code will help us
> > > move PC-specific machine state that is currently held in static
> > > variables inside PC machine objects, and reduce duplication between
> > > pc_piix.c and pc_q35.c.
> > > 
> > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > > ---
> > >  hw/i386/pc.c         |  13 ++
> > >  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
> > >  hw/i386/pc_q35.c     | 171 +++++++++++++------
> > >  include/hw/i386/pc.h |  20 ++-
> > >  4 files changed, 465 insertions(+), 212 deletions(-)
> > 
> > Hmm amount of boilerplate code seems to have doubled.
> > Can we find a solution that does away with code duplication?
> > Here's one idea: create one giant array with all necessary data, look it
> > up by name at runtime and fill everything in.
> > Not sure it's going to work out but might be worth a try.
> It's not quite QOMish way,

Well we did something like this in "e1000: allow command-line selection of card model".

Our goals are full control and introspection of options,
and boilerplate code reduction.
How options are populated seems mostly irrelevant.


> making version-ed classes nested should reduce amount of boiler plate
> and make it easier to read/write.
> And if machines are made nested then we should also rethink usage/get rid of
> PC_COMPAT_* macros-es utilizing nesting provided by class hierarchy.

I'm fine with this too as long as it serves our goals.

> This patch could serve as an intermediate step to remove usage of QEMUMachine though.
> 
> > 
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 32d1632..56720cd 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1456,3 +1456,16 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
> > >          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
> > >      }
> > >  }
> > > +
> > > +static TypeInfo pc_machine_type_info = {
> > > +        .name       = TYPE_PC_MACHINE,
> > > +        .parent     = TYPE_MACHINE,
> > > +        .abstract   = true,
> > > +};
> > > +
> > > +static void pc_machine_init(void)
> > > +{
> > > +    type_register_static(&pc_machine_type_info);
> > > +}
> > > +
> > > +type_init(pc_machine_init);
> > > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> > > index a48e263..d4b4033 100644
> > > --- a/hw/i386/pc_piix.c
> > > +++ b/hw/i386/pc_piix.c
> > > @@ -392,81 +392,140 @@ static void pc_xen_hvm_init(MachineState *machine)
> > >  }
> > >  #endif
> > >  
> > > -#define PC_I440FX_MACHINE_OPTIONS \
> > > -    PC_DEFAULT_MACHINE_OPTIONS, \
> > > -    .desc = "Standard PC (i440FX + PIIX, 1996)", \
> > > -    .hot_add_cpu = pc_hot_add_cpu
> > > -
> > > -#define PC_I440FX_2_1_MACHINE_OPTIONS                           \
> > > -    PC_I440FX_MACHINE_OPTIONS,                                  \
> > > -    .default_machine_opts = "firmware=bios-256k.bin"
> > > -
> > > -static QEMUMachine pc_i440fx_machine_v2_1 = {
> > > -    PC_I440FX_2_1_MACHINE_OPTIONS,
> > > -    .name = "pc-i440fx-2.1",
> > > -    .alias = "pc",
> > > -    .init = pc_init_pci,
> > > -    .is_default = 1,
> > > +static void pc_i440fx_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_default_machine_options(mc);
> > > +    mc->desc = "Standard PC (i440FX + PIIX, 1996)";
> > > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > > +}
> > > +
> > > +static void pc_i440fx_2_1_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_i440fx_machine_options(mc);
> > > +    mc->default_machine_opts = "firmware=bios-256k.bin";
> > > +}
> > > +
> > > +static void pc_i440fx_machine_v2_1_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    pc_i440fx_2_1_machine_options(mc);
> > > +    mc->alias = "pc";
> > > +    mc->init = pc_init_pci;
> > > +    mc->is_default = 1;
> > > +    mc->name = "pc-i440fx-2.1";
> > > +}
> > > +
> > > +static TypeInfo pc_i440fx_machine_v2_1_type_info = {
> > > +    .name = "pc-i440fx-2.1" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_i440fx_machine_v2_1_class_init,
> > >  };
> > >  
> > > -#define PC_I440FX_2_0_MACHINE_OPTIONS PC_I440FX_2_1_MACHINE_OPTIONS
> > > +#define pc_i440fx_2_0_machine_options pc_i440fx_2_1_machine_options
> > >  
> > > -static QEMUMachine pc_i440fx_machine_v2_0 = {
> > > -    PC_I440FX_2_0_MACHINE_OPTIONS,
> > > -    .name = "pc-i440fx-2.0",
> > > -    .init = pc_init_pci_2_0,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_i440fx_machine_v2_0_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_2_0,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_2_0_machine_options(mc);
> > > +    mc->init = pc_init_pci_2_0;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-i440fx-2.0";
> > > +}
> > > +
> > > +static TypeInfo pc_i440fx_machine_v2_0_type_info = {
> > > +    .name = "pc-i440fx-2.0" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_i440fx_machine_v2_0_class_init,
> > >  };
> > >  
> > > -#define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> > > +#define pc_i440fx_1_7_machine_options pc_i440fx_machine_options
> > >  
> > > -static QEMUMachine pc_i440fx_machine_v1_7 = {
> > > -    PC_I440FX_1_7_MACHINE_OPTIONS,
> > > -    .name = "pc-i440fx-1.7",
> > > -    .init = pc_init_pci_1_7,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_i440fx_machine_v1_7_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_7,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_1_7_machine_options(mc);
> > > +    mc->init = pc_init_pci_1_7;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-i440fx-1.7";
> > > +}
> > > +
> > > +static TypeInfo pc_i440fx_machine_v1_7_type_info = {
> > > +    .name = "pc-i440fx-1.7" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_i440fx_machine_v1_7_class_init,
> > >  };
> > >  
> > > -#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
> > > +#define pc_i440fx_1_6_machine_options pc_i440fx_machine_options
> > >  
> > > -static QEMUMachine pc_i440fx_machine_v1_6 = {
> > > -    PC_I440FX_1_6_MACHINE_OPTIONS,
> > > -    .name = "pc-i440fx-1.6",
> > > -    .init = pc_init_pci_1_6,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_i440fx_machine_v1_6_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_6,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_1_6_machine_options(mc);
> > > +    mc->init = pc_init_pci_1_6;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-i440fx-1.6";
> > > +}
> > > +
> > > +static TypeInfo pc_i440fx_machine_v1_6_type_info = {
> > > +    .name = "pc-i440fx-1.6" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_i440fx_machine_v1_6_class_init,
> > >  };
> > >  
> > > -static QEMUMachine pc_i440fx_machine_v1_5 = {
> > > -    PC_I440FX_1_6_MACHINE_OPTIONS,
> > > -    .name = "pc-i440fx-1.5",
> > > -    .init = pc_init_pci_1_5,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_i440fx_machine_v1_5_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_5,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_1_6_machine_options(mc);
> > > +    mc->init = pc_init_pci_1_5;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-i440fx-1.5";
> > > +}
> > > +
> > > +static TypeInfo pc_i440fx_machine_v1_5_type_info = {
> > > +    .name = "pc-i440fx-1.5" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_i440fx_machine_v1_5_class_init,
> > >  };
> > >  
> > > -#define PC_I440FX_1_4_MACHINE_OPTIONS \
> > > -    PC_I440FX_1_6_MACHINE_OPTIONS, \
> > > -    .hot_add_cpu = NULL
> > > +static void pc_i440fx_1_4_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_i440fx_1_6_machine_options(mc);
> > > +    mc->hot_add_cpu = NULL;
> > > +}
> > >  
> > > -static QEMUMachine pc_i440fx_machine_v1_4 = {
> > > -    PC_I440FX_1_4_MACHINE_OPTIONS,
> > > -    .name = "pc-i440fx-1.4",
> > > -    .init = pc_init_pci_1_4,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_i440fx_machine_v1_4_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_4,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_1_4_machine_options(mc);
> > > +    mc->init = pc_init_pci_1_4;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-i440fx-1.4";
> > > +}
> > > +
> > > +static TypeInfo pc_i440fx_machine_v1_4_type_info = {
> > > +    .name = "pc-i440fx-1.4" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_i440fx_machine_v1_4_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_1_3 \
> > > @@ -489,14 +548,23 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
> > >              .value    = "off",\
> > >          }
> > >  
> > > -static QEMUMachine pc_machine_v1_3 = {
> > > -    PC_I440FX_1_4_MACHINE_OPTIONS,
> > > -    .name = "pc-1.3",
> > > -    .init = pc_init_pci_1_3,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v1_3_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_3,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_1_4_machine_options(mc);
> > > +    mc->init = pc_init_pci_1_3;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-1.3";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v1_3_type_info = {
> > > +    .name = "pc-1.3" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v1_3_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_1_2 \
> > > @@ -527,17 +595,28 @@ static QEMUMachine pc_machine_v1_3 = {
> > >              .value    = "off",\
> > >          }
> > >  
> > > -#define PC_I440FX_1_2_MACHINE_OPTIONS \
> > > -    PC_I440FX_1_4_MACHINE_OPTIONS, \
> > > -    .init = pc_init_pci_1_2
> > > +static void pc_i440fx_1_2_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_i440fx_1_4_machine_options(mc);
> > > +    mc->init = pc_init_pci_1_2;
> > > +}
> > >  
> > > -static QEMUMachine pc_machine_v1_2 = {
> > > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > > -    .name = "pc-1.2",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v1_2_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_2,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_1_2_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-1.2";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v1_2_type_info = {
> > > +    .name = "pc-1.2" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v1_2_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_1_1 \
> > > @@ -572,13 +651,22 @@ static QEMUMachine pc_machine_v1_2 = {
> > >              .value    = "off",\
> > >          }
> > >  
> > > -static QEMUMachine pc_machine_v1_1 = {
> > > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > > -    .name = "pc-1.1",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v1_1_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_1,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_i440fx_1_2_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-1.1";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v1_1_type_info = {
> > > +    .name = "pc-1.1" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v1_1_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_1_0 \
> > > @@ -601,27 +689,45 @@ static QEMUMachine pc_machine_v1_1 = {
> > >              .value    = "no",\
> > >          }
> > >  
> > > -static QEMUMachine pc_machine_v1_0 = {
> > > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > > -    .name = "pc-1.0",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v1_0_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_0,
> > >          { /* end of list */ }
> > > -    },
> > > -    .hw_version = "1.0",
> > > +    };
> > > +    pc_i440fx_1_2_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->hw_version = "1.0";
> > > +    mc->name = "pc-1.0";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v1_0_type_info = {
> > > +    .name = "pc-1.0" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v1_0_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_0_15 \
> > >          PC_COMPAT_1_0
> > >  
> > > -static QEMUMachine pc_machine_v0_15 = {
> > > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > > -    .name = "pc-0.15",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v0_15_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_0_15,
> > >          { /* end of list */ }
> > > -    },
> > > -    .hw_version = "0.15",
> > > +    };
> > > +    pc_i440fx_1_2_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->hw_version = "0.15";
> > > +    mc->name = "pc-0.15";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v0_15_type_info = {
> > > +    .name = "pc-0.15" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v0_15_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_0_14 \
> > > @@ -644,10 +750,10 @@ static QEMUMachine pc_machine_v0_15 = {
> > >              .value    = "off",\
> > >          }
> > >  
> > > -static QEMUMachine pc_machine_v0_14 = {
> > > -    PC_I440FX_1_2_MACHINE_OPTIONS,
> > > -    .name = "pc-0.14",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v0_14_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_0_14, 
> > >          {
> > >              .driver   = "qxl",
> > > @@ -659,8 +765,17 @@ static QEMUMachine pc_machine_v0_14 = {
> > >              .value    = stringify(2),
> > >          },
> > >          { /* end of list */ }
> > > -    },
> > > -    .hw_version = "0.14",
> > > +    };
> > > +    pc_i440fx_1_2_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->hw_version = "0.14";
> > > +    mc->name = "pc-0.14";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v0_14_type_info = {
> > > +    .name = "pc-0.14" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v0_14_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_0_13 \
> > > @@ -675,14 +790,16 @@ static QEMUMachine pc_machine_v0_14 = {
> > >              .value    = stringify(1),\
> > >          }
> > >  
> > > -#define PC_I440FX_0_13_MACHINE_OPTIONS \
> > > -    PC_I440FX_1_2_MACHINE_OPTIONS, \
> > > -    .init = pc_init_pci_no_kvmclock
> > > +static void pc_i440fx_0_13_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_i440fx_1_2_machine_options(mc);
> > > +    mc->init = pc_init_pci_no_kvmclock;
> > > +}
> > >  
> > > -static QEMUMachine pc_machine_v0_13 = {
> > > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > > -    .name = "pc-0.13",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v0_13_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_0_13,
> > >          {
> > >              .driver   = "virtio-9p-pci",
> > > @@ -698,8 +815,17 @@ static QEMUMachine pc_machine_v0_13 = {
> > >              .value    = stringify(0),
> > >          },
> > >          { /* end of list */ }
> > > -    },
> > > -    .hw_version = "0.13",
> > > +    };
> > > +    pc_i440fx_0_13_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->hw_version = "0.13";
> > > +    mc->name = "pc-0.13";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v0_13_type_info = {
> > > +    .name = "pc-0.13" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v0_13_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_0_12 \
> > > @@ -726,10 +852,10 @@ static QEMUMachine pc_machine_v0_13 = {
> > >              .value    = "1",\
> > >          }
> > >  
> > > -static QEMUMachine pc_machine_v0_12 = {
> > > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > > -    .name = "pc-0.12",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v0_12_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_0_12,
> > >          {
> > >              .driver   = "VGA",
> > > @@ -741,8 +867,17 @@ static QEMUMachine pc_machine_v0_12 = {
> > >              .value    = stringify(0),
> > >          },
> > >          { /* end of list */ }
> > > -    },
> > > -    .hw_version = "0.12",
> > > +    };
> > > +    pc_i440fx_0_13_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->hw_version = "0.12";
> > > +    mc->name = "pc-0.12";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v0_12_type_info = {
> > > +    .name = "pc-0.12" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v0_12_class_init,
> > >  };
> > >  
> > >  #define PC_COMPAT_0_11 \
> > > @@ -757,10 +892,10 @@ static QEMUMachine pc_machine_v0_12 = {
> > >              .value    = stringify(0),\
> > >          }
> > >  
> > > -static QEMUMachine pc_machine_v0_11 = {
> > > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > > -    .name = "pc-0.11",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v0_11_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_0_11,
> > >          {
> > >              .driver   = "ide-drive",
> > > @@ -772,14 +907,23 @@ static QEMUMachine pc_machine_v0_11 = {
> > >              .value    = "0.11",
> > >          },
> > >          { /* end of list */ }
> > > -    },
> > > -    .hw_version = "0.11",
> > > +    };
> > > +    pc_i440fx_0_13_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->hw_version = "0.11";
> > > +    mc->name = "pc-0.11";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v0_11_type_info = {
> > > +    .name = "pc-0.11" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v0_11_class_init,
> > >  };
> > >  
> > > -static QEMUMachine pc_machine_v0_10 = {
> > > -    PC_I440FX_0_13_MACHINE_OPTIONS,
> > > -    .name = "pc-0.10",
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_machine_v0_10_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_0_11,
> > >          {
> > >              .driver   = "virtio-blk-pci",
> > > @@ -803,31 +947,44 @@ static QEMUMachine pc_machine_v0_10 = {
> > >              .value    = "0.10",
> > >          },
> > >          { /* end of list */ }
> > > -    },
> > > -    .hw_version = "0.10",
> > > +    };
> > > +    pc_i440fx_0_13_machine_options(mc);
> > > +    mc->compat_props = compat_props;
> > > +    mc->hw_version = "0.10";
> > > +    mc->name = "pc-0.10";
> > > +}
> > > +
> > > +static TypeInfo pc_machine_v0_10_type_info = {
> > > +    .name = "pc-0.10" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_machine_v0_10_class_init,
> > >  };
> > >  
> > > -static QEMUMachine isapc_machine = {
> > > -    PC_COMMON_MACHINE_OPTIONS,
> > > -    .name = "isapc",
> > > -    .desc = "ISA-only PC",
> > > -    .init = pc_init_isa,
> > > -    .max_cpus = 1,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void isapc_machine_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_common_machine_options(mc);
> > > +    mc->desc = "ISA-only PC";
> > > +    mc->init = pc_init_isa;
> > > +    mc->max_cpus = 1;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "isapc";
> > > +}
> > > +
> > > +static TypeInfo isapc_machine_type_info = {
> > > +    .name = "isapc" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = isapc_machine_class_init,
> > >  };
> > >  
> > >  #ifdef CONFIG_XEN
> > > -static QEMUMachine xenfv_machine = {
> > > -    PC_COMMON_MACHINE_OPTIONS,
> > > -    .name = "xenfv",
> > > -    .desc = "Xen Fully-virtualized PC",
> > > -    .init = pc_xen_hvm_init,
> > > -    .max_cpus = HVM_MAX_VCPUS,
> > > -    .default_machine_opts = "accel=xen",
> > > -    .hot_add_cpu = pc_hot_add_cpu,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void xenfv_machine_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          /* xenfv has no fwcfg and so does not load acpi from QEMU.
> > >           * as such new acpi features don't work.
> > >           */
> > > @@ -837,31 +994,45 @@ static QEMUMachine xenfv_machine = {
> > >              .value    = "off",
> > >          },
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_common_machine_options(mc);
> > > +    mc->desc = "Xen Fully-virtualized PC";
> > > +    mc->init = pc_xen_hvm_init;
> > > +    mc->max_cpus = HVM_MAX_VCPUS;
> > > +    mc->default_machine_opts = "accel=xen";
> > > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "xenfv";
> > > +}
> > > +
> > > +static TypeInfo xenfv_machine_type_info = {
> > > +    .name = "xenfv" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = xenfv_machine_class_init,
> > >  };
> > >  #endif
> > >  
> > >  static void pc_machine_init(void)
> > >  {
> > > -    qemu_register_machine(&pc_i440fx_machine_v2_1);
> > > -    qemu_register_machine(&pc_i440fx_machine_v2_0);
> > > -    qemu_register_machine(&pc_i440fx_machine_v1_7);
> > > -    qemu_register_machine(&pc_i440fx_machine_v1_6);
> > > -    qemu_register_machine(&pc_i440fx_machine_v1_5);
> > > -    qemu_register_machine(&pc_i440fx_machine_v1_4);
> > > -    qemu_register_machine(&pc_machine_v1_3);
> > > -    qemu_register_machine(&pc_machine_v1_2);
> > > -    qemu_register_machine(&pc_machine_v1_1);
> > > -    qemu_register_machine(&pc_machine_v1_0);
> > > -    qemu_register_machine(&pc_machine_v0_15);
> > > -    qemu_register_machine(&pc_machine_v0_14);
> > > -    qemu_register_machine(&pc_machine_v0_13);
> > > -    qemu_register_machine(&pc_machine_v0_12);
> > > -    qemu_register_machine(&pc_machine_v0_11);
> > > -    qemu_register_machine(&pc_machine_v0_10);
> > > -    qemu_register_machine(&isapc_machine);
> > > +    type_register_static(&pc_i440fx_machine_v2_1_type_info);
> > > +    type_register_static(&pc_i440fx_machine_v2_0_type_info);
> > > +    type_register_static(&pc_i440fx_machine_v1_7_type_info);
> > > +    type_register_static(&pc_i440fx_machine_v1_6_type_info);
> > > +    type_register_static(&pc_i440fx_machine_v1_5_type_info);
> > > +    type_register_static(&pc_i440fx_machine_v1_4_type_info);
> > > +    type_register_static(&pc_machine_v1_3_type_info);
> > > +    type_register_static(&pc_machine_v1_2_type_info);
> > > +    type_register_static(&pc_machine_v1_1_type_info);
> > > +    type_register_static(&pc_machine_v1_0_type_info);
> > > +    type_register_static(&pc_machine_v0_15_type_info);
> > > +    type_register_static(&pc_machine_v0_14_type_info);
> > > +    type_register_static(&pc_machine_v0_13_type_info);
> > > +    type_register_static(&pc_machine_v0_12_type_info);
> > > +    type_register_static(&pc_machine_v0_11_type_info);
> > > +    type_register_static(&pc_machine_v0_10_type_info);
> > > +    type_register_static(&isapc_machine_type_info);
> > >  #ifdef CONFIG_XEN
> > > -    qemu_register_machine(&xenfv_machine);
> > > +    type_register_static(&xenfv_machine_type_info);
> > >  #endif
> > >  }
> > >  
> > > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > > index b3c02c1..6e909f7 100644
> > > --- a/hw/i386/pc_q35.c
> > > +++ b/hw/i386/pc_q35.c
> > > @@ -306,90 +306,149 @@ static void pc_q35_init_1_4(MachineState *machine)
> > >      pc_q35_init(machine);
> > >  }
> > >  
> > > -#define PC_Q35_MACHINE_OPTIONS \
> > > -    PC_DEFAULT_MACHINE_OPTIONS, \
> > > -    .desc = "Standard PC (Q35 + ICH9, 2009)", \
> > > -    .hot_add_cpu = pc_hot_add_cpu
> > > -
> > > -#define PC_Q35_2_1_MACHINE_OPTIONS                      \
> > > -    PC_Q35_MACHINE_OPTIONS,                             \
> > > -    .default_machine_opts = "firmware=bios-256k.bin"
> > > -
> > > -static QEMUMachine pc_q35_machine_v2_1 = {
> > > -    PC_Q35_2_1_MACHINE_OPTIONS,
> > > -    .name = "pc-q35-2.1",
> > > -    .alias = "q35",
> > > -    .init = pc_q35_init,
> > > +static void pc_q35_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_default_machine_options(mc);
> > > +    mc->desc = "Standard PC (Q35 + ICH9, 2009)";
> > > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > > +}
> > > +
> > > +static void pc_q35_2_1_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_q35_machine_options(mc);
> > > +    mc->default_machine_opts = "firmware=bios-256k.bin";
> > > +}
> > > +
> > > +static void pc_q35_machine_v2_1_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    pc_q35_2_1_machine_options(mc);
> > > +    mc->alias = "q35";
> > > +    mc->init = pc_q35_init;
> > > +    mc->name = "pc-q35-2.1";
> > > +}
> > > +
> > > +static TypeInfo pc_q35_machine_v2_1_type_info = {
> > > +    .name = "pc-q35-2.1" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_q35_machine_v2_1_class_init,
> > >  };
> > >  
> > > -#define PC_Q35_2_0_MACHINE_OPTIONS PC_Q35_2_1_MACHINE_OPTIONS
> > > +#define pc_q35_2_0_machine_options pc_q35_2_1_machine_options
> > >  
> > > -static QEMUMachine pc_q35_machine_v2_0 = {
> > > -    PC_Q35_2_0_MACHINE_OPTIONS,
> > > -    .name = "pc-q35-2.0",
> > > -    .init = pc_q35_init_2_0,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_q35_machine_v2_0_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_Q35_COMPAT_2_0,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_q35_2_0_machine_options(mc);
> > > +    mc->init = pc_q35_init_2_0;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-q35-2.0";
> > > +}
> > > +
> > > +static TypeInfo pc_q35_machine_v2_0_type_info = {
> > > +    .name = "pc-q35-2.0" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_q35_machine_v2_0_class_init,
> > >  };
> > >  
> > > -#define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> > > +#define pc_q35_1_7_machine_options pc_q35_machine_options
> > >  
> > > -static QEMUMachine pc_q35_machine_v1_7 = {
> > > -    PC_Q35_1_7_MACHINE_OPTIONS,
> > > -    .name = "pc-q35-1.7",
> > > -    .init = pc_q35_init_1_7,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_q35_machine_v1_7_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_Q35_COMPAT_1_7,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_q35_1_7_machine_options(mc);
> > > +    mc->init = pc_q35_init_1_7;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-q35-1.7";
> > > +}
> > > +
> > > +static TypeInfo pc_q35_machine_v1_7_type_info = {
> > > +    .name = "pc-q35-1.7" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_q35_machine_v1_7_class_init,
> > >  };
> > >  
> > > -#define PC_Q35_1_6_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
> > > +#define pc_q35_1_6_machine_options pc_q35_machine_options
> > >  
> > > -static QEMUMachine pc_q35_machine_v1_6 = {
> > > -    PC_Q35_1_6_MACHINE_OPTIONS,
> > > -    .name = "pc-q35-1.6",
> > > -    .init = pc_q35_init_1_6,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_q35_machine_v1_6_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_Q35_COMPAT_1_6,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_q35_1_6_machine_options(mc);
> > > +    mc->init = pc_q35_init_1_6;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-q35-1.6";
> > > +}
> > > +
> > > +static TypeInfo pc_q35_machine_v1_6_type_info = {
> > > +    .name = "pc-q35-1.6" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_q35_machine_v1_6_class_init,
> > >  };
> > >  
> > > -static QEMUMachine pc_q35_machine_v1_5 = {
> > > -    PC_Q35_1_6_MACHINE_OPTIONS,
> > > -    .name = "pc-q35-1.5",
> > > -    .init = pc_q35_init_1_5,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_q35_machine_v1_5_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_Q35_COMPAT_1_5,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_q35_1_6_machine_options(mc);
> > > +    mc->init = pc_q35_init_1_5;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-q35-1.5";
> > > +}
> > > +
> > > +static TypeInfo pc_q35_machine_v1_5_type_info = {
> > > +    .name = "pc-q35-1.5" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_q35_machine_v1_5_class_init,
> > >  };
> > >  
> > > -#define PC_Q35_1_4_MACHINE_OPTIONS \
> > > -    PC_Q35_1_6_MACHINE_OPTIONS, \
> > > -    .hot_add_cpu = NULL
> > > +static void pc_q35_1_4_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_q35_1_6_machine_options(mc);
> > > +    mc->hot_add_cpu = NULL;
> > > +}
> > >  
> > > -static QEMUMachine pc_q35_machine_v1_4 = {
> > > -    PC_Q35_1_4_MACHINE_OPTIONS,
> > > -    .name = "pc-q35-1.4",
> > > -    .init = pc_q35_init_1_4,
> > > -    .compat_props = (GlobalProperty[]) {
> > > +static void pc_q35_machine_v1_4_class_init(ObjectClass *oc, void *data)
> > > +{
> > > +    MachineClass *mc = MACHINE_CLASS(oc);
> > > +    static GlobalProperty compat_props[] = {
> > >          PC_COMPAT_1_4,
> > >          { /* end of list */ }
> > > -    },
> > > +    };
> > > +    pc_q35_1_4_machine_options(mc);
> > > +    mc->init = pc_q35_init_1_4;
> > > +    mc->compat_props = compat_props;
> > > +    mc->name = "pc-q35-1.4";
> > > +}
> > > +
> > > +static TypeInfo pc_q35_machine_v1_4_type_info = {
> > > +    .name = "pc-q35-1.4" TYPE_MACHINE_SUFFIX,
> > > +    .parent = TYPE_PC_MACHINE,
> > > +    .class_init = pc_q35_machine_v1_4_class_init,
> > >  };
> > >  
> > >  static void pc_q35_machine_init(void)
> > >  {
> > > -    qemu_register_machine(&pc_q35_machine_v2_1);
> > > -    qemu_register_machine(&pc_q35_machine_v2_0);
> > > -    qemu_register_machine(&pc_q35_machine_v1_7);
> > > -    qemu_register_machine(&pc_q35_machine_v1_6);
> > > -    qemu_register_machine(&pc_q35_machine_v1_5);
> > > -    qemu_register_machine(&pc_q35_machine_v1_4);
> > > +    type_register_static(&pc_q35_machine_v2_1_type_info);
> > > +    type_register_static(&pc_q35_machine_v2_0_type_info);
> > > +    type_register_static(&pc_q35_machine_v1_7_type_info);
> > > +    type_register_static(&pc_q35_machine_v1_6_type_info);
> > > +    type_register_static(&pc_q35_machine_v1_5_type_info);
> > > +    type_register_static(&pc_q35_machine_v1_4_type_info);
> > >  }
> > >  
> > >  machine_init(pc_q35_machine_init);
> > > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > > index fa9d997..4d85847 100644
> > > --- a/include/hw/i386/pc.h
> > > +++ b/include/hw/i386/pc.h
> > > @@ -7,6 +7,7 @@
> > >  #include "hw/block/fdc.h"
> > >  #include "net/net.h"
> > >  #include "hw/i386/ioapic.h"
> > > +#include "hw/boards.h"
> > >  
> > >  #include "qemu/range.h"
> > >  #include "qemu/bitmap.h"
> > > @@ -438,12 +439,21 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
> > >              .value    = stringify(0),\
> > >          }
> > >  
> > > -#define PC_COMMON_MACHINE_OPTIONS \
> > > -    .default_boot_order = "cad"
> > > +static inline void pc_common_machine_options(MachineClass *mc)
> > > +{
> > > +    mc->default_boot_order = "cad";
> > > +}
> > > +
> > > +static inline void pc_default_machine_options(MachineClass *mc)
> > > +{
> > > +    pc_common_machine_options(mc);
> > > +    mc->hot_add_cpu = pc_hot_add_cpu;
> > > +    mc->max_cpus = 255;
> > > +}
> > >  
> > >  #define PC_DEFAULT_MACHINE_OPTIONS \
> > > -    PC_COMMON_MACHINE_OPTIONS, \
> > > -    .hot_add_cpu = pc_hot_add_cpu, \
> > > -    .max_cpus = 255
> > > +
> > > +
> > > +#define TYPE_PC_MACHINE "pc-machine"
> > >  
> > >  #endif
> > > -- 
> > > 1.9.0
> > 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine
  2014-06-12  8:37   ` Igor Mammedov
  2014-06-12  8:49     ` Michael S. Tsirkin
@ 2014-06-13  6:08     ` Eduardo Habkost
  1 sibling, 0 replies; 10+ messages in thread
From: Eduardo Habkost @ 2014-06-13  6:08 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Marcel Apfelbaum, Michael S. Tsirkin, qemu-devel, Don Slutz,
	Alexander Graf, Anthony Liguori, Andreas Färber

On Thu, Jun 12, 2014 at 10:37:29AM +0200, Igor Mammedov wrote:
> On Thu, 12 Jun 2014 11:13:49 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Jun 12, 2014 at 03:22:24AM -0300, Eduardo Habkost wrote:
> > > This is a (mostly) blind and mechanical conversion of the PC QEMUMachine
> > > definitions to corresponding class registration code.
> > > 
> > > Having the PC code converted to pure QOM registration code will help us
> > > move PC-specific machine state that is currently held in static
> > > variables inside PC machine objects, and reduce duplication between
> > > pc_piix.c and pc_q35.c.
> > > 
> > > Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> > > ---
> > >  hw/i386/pc.c         |  13 ++
> > >  hw/i386/pc_piix.c    | 473 +++++++++++++++++++++++++++++++++++----------------
> > >  hw/i386/pc_q35.c     | 171 +++++++++++++------
> > >  include/hw/i386/pc.h |  20 ++-
> > >  4 files changed, 465 insertions(+), 212 deletions(-)
> > 
> > Hmm amount of boilerplate code seems to have doubled.
> > Can we find a solution that does away with code duplication?
> > Here's one idea: create one giant array with all necessary data, look it
> > up by name at runtime and fill everything in.
> > Not sure it's going to work out but might be worth a try.
> It's not quite QOMish way,
> making version-ed classes nested should reduce amount of boiler plate
> and make it easier to read/write.
> And if machines are made nested then we should also rethink usage/get rid of
> PC_COMPAT_* macros-es utilizing nesting provided by class hierarchy.
> 
> This patch could serve as an intermediate step to remove usage of QEMUMachine though.

I am working to make only one hierarchy/nesting structure (class_init
hierarchy). Today we have the same hierarchy/nesting pattern duplicated
in multiple levels:

 * PC_COMPAT_* (compat_props) nesting
 * pc_compat_*() function nesting
 * pc_init*() function duplication (all with the same compat+pc_init1()
   pattern)
 * QEMUMachine/PC_*_MACHINE_OPTIONS nesting/duplication

On my work in progress branch I've moved all hierarchy/nesting to
class_init, except for pc_compat_*(), which is still necessary in a few
cases because of the CPUID compat stuff.

My goal is to get all machine-types declared using only a class_init +
TypeInfo pair, and nothing else. That should also make us stop creating
new compat global variables on every release. :)

WIP can be seen at:
https://github.com/ehabkost/qemu-hacks/commits/work/pc-machine-class
Code now looks like this:
https://github.com/ehabkost/qemu-hacks/blob/24398f32268b333354d850da7437c1db263891ff/hw/i386/pc_piix.c

I'm not submitting an RFC right now because I need some sleep first, but
I plan to send one tomorrow.

I plan to addres the piix/q35 code duplication too. It should be much
easier to eliminate duplication now that we can have PC-specific
machine-type information in a PCMachineClass struct, and PC-specific
machine state information in a PCMachineState struct.

-- 
Eduardo

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2014-06-13  6:09 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-12  6:22 [Qemu-devel] [RFC] pc: Register machine classes directly instead of using QEMUMachine Eduardo Habkost
2014-06-12  8:02 ` Igor Mammedov
2014-06-12  8:12   ` Marcel Apfelbaum
2014-06-12  8:20     ` Michael S. Tsirkin
2014-06-12  8:38       ` Igor Mammedov
2014-06-12  8:23     ` Igor Mammedov
2014-06-12  8:13 ` Michael S. Tsirkin
2014-06-12  8:37   ` Igor Mammedov
2014-06-12  8:49     ` Michael S. Tsirkin
2014-06-13  6:08     ` Eduardo Habkost

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.