summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rwxr-xr-xconfigure2
-rw-r--r--hw/alpha/dp264.c4
-rw-r--r--hw/cris/axis_dev88.c7
-rw-r--r--hw/i386/pc.c2
-rw-r--r--hw/lm32/lm32_boards.c14
-rw-r--r--hw/lm32/milkymist.c7
-rw-r--r--hw/m68k/an5206.c7
-rw-r--r--hw/m68k/mcf5208.c7
-rw-r--r--hw/mips/boston.c14
-rw-r--r--hw/mips/cps.c4
-rw-r--r--hw/mips/mips_fulong2e.c7
-rw-r--r--hw/mips/mips_jazz.c8
-rw-r--r--hw/mips/mips_malta.c36
-rw-r--r--hw/mips/mips_mipssim.c15
-rw-r--r--hw/mips/mips_r4k.c16
-rw-r--r--hw/moxie/moxiesim.c7
-rw-r--r--hw/openrisc/openrisc_sim.c8
-rw-r--r--hw/sh4/r2d.c8
-rw-r--r--hw/sh4/shix.c7
-rw-r--r--hw/sparc/leon3.c8
-rw-r--r--hw/sparc/sun4m.c29
-rw-r--r--hw/sparc64/niagara.c4
-rw-r--r--hw/sparc64/sparc64.c8
-rw-r--r--hw/sparc64/sun4u.c8
-rw-r--r--hw/tricore/tricore_testboard.c6
-rw-r--r--hw/unicore32/puv3.c8
-rw-r--r--hw/xtensa/sim.c8
-rw-r--r--hw/xtensa/xtfpga.c11
-rw-r--r--include/hw/mips/cps.h2
-rw-r--r--include/hw/sparc/sparc64.h3
-rw-r--r--linux-user/main.c2
-rw-r--r--numa.c19
-rw-r--r--qga/commands-posix.c74
-rw-r--r--qga/commands-win32.c86
-rw-r--r--qga/qapi-schema.json38
-rw-r--r--qga/vss-win32/install.cpp13
-rw-r--r--qga/vss-win32/requester.cpp12
-rw-r--r--target/alpha/cpu.c107
-rw-r--r--target/alpha/cpu.h3
-rw-r--r--target/cris/cpu.c81
-rw-r--r--target/cris/cpu.h3
-rw-r--r--target/lm32/cpu.c74
-rw-r--r--target/lm32/cpu.h3
-rw-r--r--target/m68k/cpu.c75
-rw-r--r--target/m68k/cpu.h3
-rw-r--r--target/mips/cpu.c2
-rw-r--r--target/mips/cpu.h8
-rw-r--r--target/mips/translate.c20
-rw-r--r--target/mips/translate_init.c12
-rw-r--r--target/moxie/cpu.c61
-rw-r--r--target/moxie/cpu.h3
-rw-r--r--target/openrisc/cpu.c69
-rw-r--r--target/openrisc/cpu.h3
-rw-r--r--target/sh4/cpu-qom.h8
-rw-r--r--target/sh4/cpu.c107
-rw-r--r--target/sh4/cpu.h3
-rw-r--r--target/sparc/cpu.c2
-rw-r--r--target/sparc/cpu.h3
-rw-r--r--target/tricore/cpu.c68
-rw-r--r--target/tricore/cpu.h2
-rw-r--r--target/unicore32/cpu.c61
-rw-r--r--target/unicore32/cpu.h3
-rw-r--r--target/xtensa/cpu.c2
-rw-r--r--target/xtensa/cpu.h4
-rw-r--r--target/xtensa/helper.c2
65 files changed, 614 insertions, 697 deletions
diff --git a/configure b/configure
index 23eddc2f50..285d123dbf 100755
--- a/configure
+++ b/configure
@@ -828,7 +828,7 @@ if test "$mingw32" = "yes" ; then
   sysconfdir="\${prefix}"
   local_statedir=
   confsuffix=""
-  libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -liphlpapi -lnetapi32 $libs_qga"
+  libs_qga="-lws2_32 -lwinmm -lpowrprof -lwtsapi32 -lwininet -liphlpapi -lnetapi32 $libs_qga"
 fi
 
 werror=""
diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c
index 1b121306c2..babd6ea514 100644
--- a/hw/alpha/dp264.c
+++ b/hw/alpha/dp264.c
@@ -51,7 +51,6 @@ static int clipper_pci_map_irq(PCIDevice *d, int irq_num)
 static void clipper_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model ? machine->cpu_model : "ev67";
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -67,7 +66,7 @@ static void clipper_init(MachineState *machine)
     /* Create up to 4 cpus.  */
     memset(cpus, 0, sizeof(cpus));
     for (i = 0; i < smp_cpus; ++i) {
-        cpus[i] = ALPHA_CPU(cpu_generic_init(TYPE_ALPHA_CPU, cpu_model));
+        cpus[i] = ALPHA_CPU(cpu_create(machine->cpu_type));
     }
 
     cpus[0]->env.trap_arg0 = ram_size;
@@ -179,6 +178,7 @@ static void clipper_machine_init(MachineClass *mc)
     mc->block_default_type = IF_IDE;
     mc->max_cpus = 4;
     mc->is_default = 1;
+    mc->default_cpu_type = ALPHA_CPU_TYPE_NAME("ev67");
 }
 
 DEFINE_MACHINE("clipper", clipper_machine_init)
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 5eb552bce2..9ccc4350a5 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -251,7 +251,6 @@ static
 void axisdev88_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     CRISCPU *cpu;
@@ -268,10 +267,7 @@ void axisdev88_init(MachineState *machine)
     MemoryRegion *phys_intmem = g_new(MemoryRegion, 1);
 
     /* init CPUs */
-    if (cpu_model == NULL) {
-        cpu_model = "crisv32";
-    }
-    cpu = CRIS_CPU(cpu_generic_init(TYPE_CRIS_CPU, cpu_model));
+    cpu = CRIS_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     /* allocate RAM */
@@ -359,6 +355,7 @@ static void axisdev88_machine_init(MachineClass *mc)
     mc->desc = "AXIS devboard 88";
     mc->init = axisdev88_init;
     mc->is_default = 1;
+    mc->default_cpu_type = CRIS_CPU_TYPE_NAME("crisv32");
 }
 
 DEFINE_MACHINE("axis-dev88", axisdev88_machine_init)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 8e307f7aff..e11a65b545 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1228,7 +1228,7 @@ void pc_machine_done(Notifier *notifier, void *data)
         fw_cfg_modify_i16(pcms->fw_cfg, FW_CFG_NB_CPUS, pcms->boot_cpus);
     }
 
-    if (pcms->apic_id_limit > 255) {
+    if (pcms->apic_id_limit > 255 && !xen_enabled()) {
         IntelIOMMUState *iommu = INTEL_IOMMU_DEVICE(x86_iommu_get_default());
 
         if (!iommu || !iommu->x86_iommu.intr_supported ||
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index b0bb3ef58a..002d638edd 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -75,7 +75,6 @@ static void main_cpu_reset(void *opaque)
 
 static void lm32_evr_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     LM32CPU *cpu;
     CPULM32State *env;
@@ -101,10 +100,7 @@ static void lm32_evr_init(MachineState *machine)
 
     reset_info = g_malloc0(sizeof(ResetInfo));
 
-    if (cpu_model == NULL) {
-        cpu_model = "lm32-full";
-    }
-    cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));
+    cpu = LM32_CPU(cpu_create(machine->cpu_type));
 
     env = &cpu->env;
     reset_info->cpu = cpu;
@@ -163,7 +159,6 @@ static void lm32_evr_init(MachineState *machine)
 
 static void lm32_uclinux_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -198,10 +193,7 @@ static void lm32_uclinux_init(MachineState *machine)
 
     reset_info = g_malloc0(sizeof(ResetInfo));
 
-    if (cpu_model == NULL) {
-        cpu_model = "lm32-full";
-    }
-    cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));
+    cpu = LM32_CPU(cpu_create(machine->cpu_type));
 
     env = &cpu->env;
     reset_info->cpu = cpu;
@@ -295,6 +287,7 @@ static void lm32_evr_class_init(ObjectClass *oc, void *data)
     mc->desc = "LatticeMico32 EVR32 eval system";
     mc->init = lm32_evr_init;
     mc->is_default = 1;
+    mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
 }
 
 static const TypeInfo lm32_evr_type = {
@@ -310,6 +303,7 @@ static void lm32_uclinux_class_init(ObjectClass *oc, void *data)
     mc->desc = "lm32 platform for uClinux and u-boot by Theobroma Systems";
     mc->init = lm32_uclinux_init;
     mc->is_default = 0;
+    mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
 }
 
 static const TypeInfo lm32_uclinux_type = {
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 4db4d2d533..d4e765f2eb 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -80,7 +80,6 @@ static void main_cpu_reset(void *opaque)
 static void
 milkymist_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -108,10 +107,7 @@ milkymist_init(MachineState *machine)
 
     reset_info = g_malloc0(sizeof(ResetInfo));
 
-    if (cpu_model == NULL) {
-        cpu_model = "lm32-full";
-    }
-    cpu = LM32_CPU(cpu_generic_init(TYPE_LM32_CPU, cpu_model));
+    cpu = LM32_CPU(cpu_create(machine->cpu_type));
 
     env = &cpu->env;
     reset_info->cpu = cpu;
@@ -216,6 +212,7 @@ static void milkymist_machine_init(MachineClass *mc)
     mc->desc = "Milkymist One";
     mc->init = milkymist_init;
     mc->is_default = 0;
+    mc->default_cpu_type = LM32_CPU_TYPE_NAME("lm32-full");
 }
 
 DEFINE_MACHINE("milkymist", milkymist_machine_init)
diff --git a/hw/m68k/an5206.c b/hw/m68k/an5206.c
index db634cbe89..5e067ea1c3 100644
--- a/hw/m68k/an5206.c
+++ b/hw/m68k/an5206.c
@@ -28,7 +28,6 @@
 static void an5206_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     M68kCPU *cpu;
     CPUM68KState *env;
@@ -39,10 +38,7 @@ static void an5206_init(MachineState *machine)
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *sram = g_new(MemoryRegion, 1);
 
-    if (!cpu_model) {
-        cpu_model = "m5206";
-    }
-    cpu = M68K_CPU(cpu_generic_init(TYPE_M68K_CPU, cpu_model));
+    cpu = M68K_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     /* Initialize CPU registers.  */
@@ -94,6 +90,7 @@ static void an5206_machine_init(MachineClass *mc)
 {
     mc->desc = "Arnewsh 5206";
     mc->init = an5206_init;
+    mc->default_cpu_type = M68K_CPU_TYPE_NAME("m5206");
 }
 
 DEFINE_MACHINE("an5206", an5206_machine_init)
diff --git a/hw/m68k/mcf5208.c b/hw/m68k/mcf5208.c
index 68589c36d2..fac0d09cbc 100644
--- a/hw/m68k/mcf5208.c
+++ b/hw/m68k/mcf5208.c
@@ -218,7 +218,6 @@ static void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd, hwaddr base,
 static void mcf5208evb_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     M68kCPU *cpu;
     CPUM68KState *env;
@@ -230,10 +229,7 @@ static void mcf5208evb_init(MachineState *machine)
     MemoryRegion *ram = g_new(MemoryRegion, 1);
     MemoryRegion *sram = g_new(MemoryRegion, 1);
 
-    if (!cpu_model) {
-        cpu_model = "m5208";
-    }
-    cpu = M68K_CPU(cpu_generic_init(TYPE_M68K_CPU, cpu_model));
+    cpu = M68K_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     /* Initialize CPU registers.  */
@@ -322,6 +318,7 @@ static void mcf5208evb_machine_init(MachineClass *mc)
     mc->desc = "MCF5206EVB";
     mc->init = mcf5208evb_init;
     mc->is_default = 1;
+    mc->default_cpu_type = M68K_CPU_TYPE_NAME("m5208");
 }
 
 DEFINE_MACHINE("mcf5208evb", mcf5208evb_machine_init)
diff --git a/hw/mips/boston.c b/hw/mips/boston.c
index 776ee283e1..1cb4b6aca2 100644
--- a/hw/mips/boston.c
+++ b/hw/mips/boston.c
@@ -437,7 +437,6 @@ static void boston_mach_init(MachineState *machine)
     DeviceState *dev;
     BostonState *s;
     Error *err = NULL;
-    const char *cpu_model;
     MemoryRegion *flash, *ddr, *ddr_low_alias, *lcd, *platreg;
     MemoryRegion *sys_mem = get_system_memory();
     XilinxPCIEHost *pcie2;
@@ -453,26 +452,24 @@ static void boston_mach_init(MachineState *machine)
         exit(1);
     }
 
-    cpu_model = machine->cpu_model ?: "I6400";
-
     dev = qdev_create(NULL, TYPE_MIPS_BOSTON);
     qdev_init_nofail(dev);
 
     s = BOSTON(dev);
     s->mach = machine;
-    s->cps = g_new0(MIPSCPSState, 1);
 
-    if (!cpu_supports_cps_smp(cpu_model)) {
+    if (!cpu_supports_cps_smp(machine->cpu_type)) {
         error_report("Boston requires CPUs which support CPS");
         exit(1);
     }
 
-    is_64b = cpu_supports_isa(cpu_model, ISA_MIPS64);
+    is_64b = cpu_supports_isa(machine->cpu_type, ISA_MIPS64);
 
-    object_initialize(s->cps, sizeof(MIPSCPSState), TYPE_MIPS_CPS);
+    s->cps = MIPS_CPS(object_new(TYPE_MIPS_CPS));
     qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default());
 
-    object_property_set_str(OBJECT(s->cps), cpu_model, "cpu-model", &err);
+    object_property_set_str(OBJECT(s->cps), machine->cpu_type, "cpu-type",
+                            &err);
     object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err);
     object_property_set_bool(OBJECT(s->cps), true, "realized", &err);
 
@@ -572,6 +569,7 @@ static void boston_mach_class_init(MachineClass *mc)
     mc->block_default_type = IF_IDE;
     mc->default_ram_size = 1 * G_BYTE;
     mc->max_cpus = 16;
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("I6400");
 }
 
 DEFINE_MACHINE("boston", boston_mach_class_init)
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index fe5c630af6..4285d1964e 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -71,7 +71,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
     bool itu_present = false;
 
     for (i = 0; i < s->num_vp; i++) {
-        cpu = MIPS_CPU(cpu_generic_init(TYPE_MIPS_CPU, s->cpu_model));
+        cpu = MIPS_CPU(cpu_create(s->cpu_type));
 
         /* Init internal devices */
         cpu_mips_irq_init_cpu(cpu);
@@ -160,7 +160,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
 static Property mips_cps_properties[] = {
     DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1),
     DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 256),
-    DEFINE_PROP_STRING("cpu-model", MIPSCPSState, cpu_model),
+    DEFINE_PROP_STRING("cpu-type", MIPSCPSState, cpu_type),
     DEFINE_PROP_END_OF_LIST()
 };
 
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 75318680e1..146cf0fccd 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -258,7 +258,6 @@ static void network_init (PCIBus *pci_bus)
 static void mips_fulong2e_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -277,10 +276,7 @@ static void mips_fulong2e_init(MachineState *machine)
     CPUMIPSState *env;
 
     /* init CPUs */
-    if (cpu_model == NULL) {
-        cpu_model = "Loongson-2E";
-    }
-    cpu = MIPS_CPU(cpu_generic_init(TYPE_MIPS_CPU, cpu_model));
+    cpu = MIPS_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     qemu_register_reset(main_cpu_reset, cpu);
@@ -385,6 +381,7 @@ static void mips_fulong2e_machine_init(MachineClass *mc)
     mc->desc = "Fulong 2e mini pc";
     mc->init = mips_fulong2e_init;
     mc->block_default_type = IF_IDE;
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("Loongson-2E");
 }
 
 DEFINE_MACHINE("fulong2e", mips_fulong2e_machine_init)
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 7e6626dc88..fe4f17389f 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -122,7 +122,6 @@ static void mips_jazz_init(MachineState *machine,
                            enum jazz_model_e jazz_model)
 {
     MemoryRegion *address_space = get_system_memory();
-    const char *cpu_model = machine->cpu_model;
     char *filename;
     int bios_size, n;
     MIPSCPU *cpu;
@@ -148,10 +147,7 @@ static void mips_jazz_init(MachineState *machine,
     MemoryRegion *bios2 = g_new(MemoryRegion, 1);
 
     /* init CPUs */
-    if (cpu_model == NULL) {
-        cpu_model = "R4000";
-    }
-    cpu = MIPS_CPU(cpu_generic_init(TYPE_MIPS_CPU, cpu_model));
+    cpu = MIPS_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
     qemu_register_reset(main_cpu_reset, cpu);
 
@@ -349,6 +345,7 @@ static void mips_magnum_class_init(ObjectClass *oc, void *data)
     mc->desc = "MIPS Magnum";
     mc->init = mips_magnum_init;
     mc->block_default_type = IF_SCSI;
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000");
 }
 
 static const TypeInfo mips_magnum_type = {
@@ -364,6 +361,7 @@ static void mips_pica61_class_init(ObjectClass *oc, void *data)
     mc->desc = "Acer Pica 61";
     mc->init = mips_pica61_init;
     mc->block_default_type = IF_SCSI;
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000");
 }
 
 static const TypeInfo mips_pica61_type = {
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 2adb9bcf89..ec6af4a277 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -923,7 +923,7 @@ static void main_cpu_reset(void *opaque)
     }
 }
 
-static void create_cpu_without_cps(const char *cpu_model,
+static void create_cpu_without_cps(const char *cpu_type,
                                    qemu_irq *cbus_irq, qemu_irq *i8259_irq)
 {
     CPUMIPSState *env;
@@ -931,7 +931,7 @@ static void create_cpu_without_cps(const char *cpu_model,
     int i;
 
     for (i = 0; i < smp_cpus; i++) {
-        cpu = MIPS_CPU(cpu_generic_init(TYPE_MIPS_CPU, cpu_model));
+        cpu = MIPS_CPU(cpu_create(cpu_type));
 
         /* Init internal devices */
         cpu_mips_irq_init_cpu(cpu);
@@ -945,16 +945,15 @@ static void create_cpu_without_cps(const char *cpu_model,
     *cbus_irq = env->irq[4];
 }
 
-static void create_cps(MaltaState *s, const char *cpu_model,
+static void create_cps(MaltaState *s, const char *cpu_type,
                        qemu_irq *cbus_irq, qemu_irq *i8259_irq)
 {
     Error *err = NULL;
-    s->cps = g_new0(MIPSCPSState, 1);
 
-    object_initialize(s->cps, sizeof(MIPSCPSState), TYPE_MIPS_CPS);
+    s->cps = MIPS_CPS(object_new(TYPE_MIPS_CPS));
     qdev_set_parent_bus(DEVICE(s->cps), sysbus_get_default());
 
-    object_property_set_str(OBJECT(s->cps), cpu_model, "cpu-model", &err);
+    object_property_set_str(OBJECT(s->cps), cpu_type, "cpu-type", &err);
     object_property_set_int(OBJECT(s->cps), smp_cpus, "num-vp", &err);
     object_property_set_bool(OBJECT(s->cps), true, "realized", &err);
     if (err != NULL) {
@@ -968,21 +967,13 @@ static void create_cps(MaltaState *s, const char *cpu_model,
     *cbus_irq = NULL;
 }
 
-static void create_cpu(MaltaState *s, const char *cpu_model,
-                       qemu_irq *cbus_irq, qemu_irq *i8259_irq)
+static void mips_create_cpu(MaltaState *s, const char *cpu_type,
+                            qemu_irq *cbus_irq, qemu_irq *i8259_irq)
 {
-    if (cpu_model == NULL) {
-#ifdef TARGET_MIPS64
-        cpu_model = "20Kc";
-#else
-        cpu_model = "24Kf";
-#endif
-    }
-
-    if ((smp_cpus > 1) && cpu_supports_cps_smp(cpu_model)) {
-        create_cps(s, cpu_model, cbus_irq, i8259_irq);
+    if ((smp_cpus > 1) && cpu_supports_cps_smp(cpu_type)) {
+        create_cps(s, cpu_type, cbus_irq, i8259_irq);
     } else {
-        create_cpu_without_cps(cpu_model, cbus_irq, i8259_irq);
+        create_cpu_without_cps(cpu_type, cbus_irq, i8259_irq);
     }
 }
 
@@ -1039,7 +1030,7 @@ void mips_malta_init(MachineState *machine)
     }
 
     /* create CPU */
-    create_cpu(s, machine->cpu_model, &cbus_irq, &i8259_irq);
+    mips_create_cpu(s, machine->cpu_type, &cbus_irq, &i8259_irq);
 
     /* allocate RAM */
     if (ram_size > (2048u << 20)) {
@@ -1265,6 +1256,11 @@ static void mips_malta_machine_init(MachineClass *mc)
     mc->block_default_type = IF_IDE;
     mc->max_cpus = 16;
     mc->is_default = 1;
+#ifdef TARGET_MIPS64
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("20Kc");
+#else
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("24Kf");
+#endif
 }
 
 DEFINE_MACHINE("malta", mips_malta_machine_init)
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index a092072e2a..e5d3654586 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -141,7 +141,6 @@ static void
 mips_mipssim_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -156,14 +155,7 @@ mips_mipssim_init(MachineState *machine)
     int bios_size;
 
     /* Init CPUs. */
-    if (cpu_model == NULL) {
-#ifdef TARGET_MIPS64
-        cpu_model = "5Kf";
-#else
-        cpu_model = "24Kf";
-#endif
-    }
-    cpu = MIPS_CPU(cpu_generic_init(TYPE_MIPS_CPU, cpu_model));
+    cpu = MIPS_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
@@ -235,6 +227,11 @@ static void mips_mipssim_machine_init(MachineClass *mc)
 {
     mc->desc = "MIPS MIPSsim platform";
     mc->init = mips_mipssim_init;
+#ifdef TARGET_MIPS64
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("5Kf");
+#else
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("24Kf");
+#endif
 }
 
 DEFINE_MACHINE("mipssim", mips_mipssim_machine_init)
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 1272d4ef9d..3bbb1827e1 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -163,7 +163,6 @@ static
 void mips_r4k_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -186,14 +185,7 @@ void mips_r4k_init(MachineState *machine)
     int be;
 
     /* init CPUs */
-    if (cpu_model == NULL) {
-#ifdef TARGET_MIPS64
-        cpu_model = "R4000";
-#else
-        cpu_model = "24Kf";
-#endif
-    }
-    cpu = MIPS_CPU(cpu_generic_init(TYPE_MIPS_CPU, cpu_model));
+    cpu = MIPS_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
@@ -303,6 +295,12 @@ static void mips_machine_init(MachineClass *mc)
     mc->desc = "mips r4k platform";
     mc->init = mips_r4k_init;
     mc->block_default_type = IF_IDE;
+#ifdef TARGET_MIPS64
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("R4000");
+#else
+    mc->default_cpu_type = MIPS_CPU_TYPE_NAME("24Kf");
+#endif
+
 }
 
 DEFINE_MACHINE("mips", mips_machine_init)
diff --git a/hw/moxie/moxiesim.c b/hw/moxie/moxiesim.c
index 5ea8dd3a93..3ba58481d0 100644
--- a/hw/moxie/moxiesim.c
+++ b/hw/moxie/moxiesim.c
@@ -103,7 +103,6 @@ static void moxiesim_init(MachineState *machine)
 {
     MoxieCPU *cpu = NULL;
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -115,10 +114,7 @@ static void moxiesim_init(MachineState *machine)
     LoaderParams loader_params;
 
     /* Init CPUs. */
-    if (cpu_model == NULL) {
-        cpu_model = "MoxieLite-moxie-cpu";
-    }
-    cpu = MOXIE_CPU(cpu_generic_init(TYPE_MOXIE_CPU, cpu_model));
+    cpu = MOXIE_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     qemu_register_reset(main_cpu_reset, cpu);
@@ -150,6 +146,7 @@ static void moxiesim_machine_init(MachineClass *mc)
     mc->desc = "Moxie simulator platform";
     mc->init = moxiesim_init;
     mc->is_default = 1;
+    mc->default_cpu_type = MOXIE_CPU_TYPE_NAME("MoxieLite");
 }
 
 DEFINE_MACHINE("moxiesim", moxiesim_machine_init)
diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c
index 58638c6ecd..e9558f1ca4 100644
--- a/hw/openrisc/openrisc_sim.c
+++ b/hw/openrisc/openrisc_sim.c
@@ -125,7 +125,6 @@ static void openrisc_load_kernel(ram_addr_t ram_size,
 static void openrisc_sim_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     OpenRISCCPU *cpu = NULL;
     MemoryRegion *ram;
@@ -133,12 +132,8 @@ static void openrisc_sim_init(MachineState *machine)
     qemu_irq serial_irq;
     int n;
 
-    if (!cpu_model) {
-        cpu_model = "or1200";
-    }
-
     for (n = 0; n < smp_cpus; n++) {
-        cpu = OPENRISC_CPU(cpu_generic_init(TYPE_OPENRISC_CPU, cpu_model));
+        cpu = OPENRISC_CPU(cpu_create(machine->cpu_type));
         if (cpu == NULL) {
             fprintf(stderr, "Unable to find CPU definition!\n");
             exit(1);
@@ -180,6 +175,7 @@ static void openrisc_sim_machine_init(MachineClass *mc)
     mc->init = openrisc_sim_init;
     mc->max_cpus = 2;
     mc->is_default = 1;
+    mc->default_cpu_type = OPENRISC_CPU_TYPE_NAME("or1200");
 }
 
 DEFINE_MACHINE("or1k-sim", openrisc_sim_machine_init)
diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c
index 16b9ed2db2..458ed83297 100644
--- a/hw/sh4/r2d.c
+++ b/hw/sh4/r2d.c
@@ -225,7 +225,6 @@ static struct QEMU_PACKED
 
 static void r2d_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *kernel_cmdline = machine->kernel_cmdline;
     const char *initrd_filename = machine->initrd_filename;
@@ -242,11 +241,7 @@ static void r2d_init(MachineState *machine)
     MemoryRegion *address_space_mem = get_system_memory();
     PCIBus *pci_bus;
 
-    if (cpu_model == NULL) {
-        cpu_model = "SH7751R";
-    }
-
-    cpu = SUPERH_CPU(cpu_generic_init(TYPE_SUPERH_CPU, cpu_model));
+    cpu = SUPERH_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     reset_info = g_malloc0(sizeof(ResetData));
@@ -365,6 +360,7 @@ static void r2d_machine_init(MachineClass *mc)
     mc->desc = "r2d-plus board";
     mc->init = r2d_init;
     mc->block_default_type = IF_IDE;
+    mc->default_cpu_type = TYPE_SH7751R_CPU;
 }
 
 DEFINE_MACHINE("r2d", r2d_machine_init)
diff --git a/hw/sh4/shix.c b/hw/sh4/shix.c
index 50ee36a5c5..4add2309eb 100644
--- a/hw/sh4/shix.c
+++ b/hw/sh4/shix.c
@@ -45,7 +45,6 @@
 
 static void shix_init(MachineState *machine)
 {
-    const char *cpu_model = machine->cpu_model;
     int ret;
     SuperHCPU *cpu;
     struct SH7750State *s;
@@ -53,10 +52,7 @@ static void shix_init(MachineState *machine)
     MemoryRegion *rom = g_new(MemoryRegion, 1);
     MemoryRegion *sdram = g_new(MemoryRegion, 2);
     
-    if (!cpu_model)
-        cpu_model = "any";
-
-    cpu = SUPERH_CPU(cpu_generic_init(TYPE_SUPERH_CPU, cpu_model));
+    cpu = SUPERH_CPU(cpu_create(machine->cpu_type));
 
     /* Allocate memory space */
     memory_region_init_ram(rom, NULL, "shix.rom", 0x4000, &error_fatal);
@@ -89,6 +85,7 @@ static void shix_machine_init(MachineClass *mc)
     mc->desc = "shix card";
     mc->init = shix_init;
     mc->is_default = 1;
+    mc->default_cpu_type = TYPE_SH7750R_CPU;
 }
 
 DEFINE_MACHINE("shix", shix_machine_init)
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index ec2816bf94..8c66d5af24 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -107,7 +107,6 @@ static void leon3_set_pil_in(void *opaque, uint32_t pil_in)
 static void leon3_generic_hw_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     SPARCCPU *cpu;
     CPUSPARCState   *env;
@@ -122,11 +121,7 @@ static void leon3_generic_hw_init(MachineState *machine)
     ResetData  *reset_info;
 
     /* Init CPU */
-    if (!cpu_model) {
-        cpu_model = "LEON3";
-    }
-
-    cpu = SPARC_CPU(cpu_generic_init(TYPE_SPARC_CPU, cpu_model));
+    cpu = SPARC_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     cpu_sparc_set_id(env, 0);
@@ -222,6 +217,7 @@ static void leon3_generic_machine_init(MachineClass *mc)
 {
     mc->desc = "Leon-3 generic";
     mc->init = leon3_generic_hw_init;
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("LEON3");
 }
 
 DEFINE_MACHINE("leon3_generic", leon3_generic_machine_init)
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index e1bdd4828d..68b23784c5 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -94,7 +94,6 @@ struct sun4m_hwdef {
     } vsimm[MAX_VSIMMS];
     hwaddr ecc_base;
     uint64_t max_mem;
-    const char * const default_cpu_model;
     uint32_t ecc_version;
     uint32_t iommu_version;
     uint16_t machine_id;
@@ -790,14 +789,14 @@ static const TypeInfo ram_info = {
     .class_init    = ram_class_init,
 };
 
-static void cpu_devinit(const char *cpu_model, unsigned int id,
+static void cpu_devinit(const char *cpu_type, unsigned int id,
                         uint64_t prom_addr, qemu_irq **cpu_irqs)
 {
     CPUState *cs;
     SPARCCPU *cpu;
     CPUSPARCState *env;
 
-    cpu = SPARC_CPU(cpu_generic_init(TYPE_SPARC_CPU, cpu_model));
+    cpu = SPARC_CPU(cpu_create(cpu_type));
     env = &cpu->env;
 
     cpu_sparc_set_id(env, id);
@@ -820,7 +819,6 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
                           MachineState *machine)
 {
     DeviceState *slavio_intctl;
-    const char *cpu_model = machine->cpu_model;
     unsigned int i;
     void *iommu, *espdma, *ledma, *nvram;
     qemu_irq *cpu_irqs[MAX_CPUS], slavio_irq[32], slavio_cpu_irq[MAX_CPUS],
@@ -833,11 +831,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef,
     unsigned int num_vsimms;
 
     /* init CPUs */
-    if (!cpu_model)
-        cpu_model = hwdef->default_cpu_model;
-
     for(i = 0; i < smp_cpus; i++) {
-        cpu_devinit(cpu_model, i, hwdef->slavio_base, &cpu_irqs[i]);
+        cpu_devinit(machine->cpu_type, i, hwdef->slavio_base, &cpu_irqs[i]);
     }
 
     for (i = smp_cpus; i < MAX_CPUS; i++)
@@ -1074,7 +1069,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = ss5_id,
         .iommu_version = 0x05000000,
         .max_mem = 0x10000000,
-        .default_cpu_model = "Fujitsu MB86904",
     },
     /* SS-10 */
     {
@@ -1100,7 +1094,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = ss10_id,
         .iommu_version = 0x03000000,
         .max_mem = 0xf00000000ULL,
-        .default_cpu_model = "TI SuperSparc II",
     },
     /* SS-600MP */
     {
@@ -1124,7 +1117,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = ss600mp_id,
         .iommu_version = 0x01000000,
         .max_mem = 0xf00000000ULL,
-        .default_cpu_model = "TI SuperSparc II",
     },
     /* SS-20 */
     {
@@ -1166,7 +1158,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = ss20_id,
         .iommu_version = 0x13000000,
         .max_mem = 0xf00000000ULL,
-        .default_cpu_model = "TI SuperSparc II",
     },
     /* Voyager */
     {
@@ -1190,7 +1181,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = vger_id,
         .iommu_version = 0x05000000,
         .max_mem = 0x10000000,
-        .default_cpu_model = "Fujitsu MB86904",
     },
     /* LX */
     {
@@ -1215,7 +1205,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = lx_id,
         .iommu_version = 0x04000000,
         .max_mem = 0x10000000,
-        .default_cpu_model = "TI MicroSparc I",
     },
     /* SS-4 */
     {
@@ -1240,7 +1229,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = ss4_id,
         .iommu_version = 0x05000000,
         .max_mem = 0x10000000,
-        .default_cpu_model = "Fujitsu MB86904",
     },
     /* SPARCClassic */
     {
@@ -1264,7 +1252,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = scls_id,
         .iommu_version = 0x05000000,
         .max_mem = 0x10000000,
-        .default_cpu_model = "TI MicroSparc I",
     },
     /* SPARCbook */
     {
@@ -1288,7 +1275,6 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
         .machine_id = sbook_id,
         .iommu_version = 0x05000000,
         .max_mem = 0x10000000,
-        .default_cpu_model = "TI MicroSparc I",
     },
 };
 
@@ -1355,6 +1341,7 @@ static void ss5_class_init(ObjectClass *oc, void *data)
     mc->block_default_type = IF_SCSI;
     mc->is_default = 1;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904");
 }
 
 static const TypeInfo ss5_type = {
@@ -1372,6 +1359,7 @@ static void ss10_class_init(ObjectClass *oc, void *data)
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II");
 }
 
 static const TypeInfo ss10_type = {
@@ -1389,6 +1377,7 @@ static void ss600mp_class_init(ObjectClass *oc, void *data)
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II");
 }
 
 static const TypeInfo ss600mp_type = {
@@ -1406,6 +1395,7 @@ static void ss20_class_init(ObjectClass *oc, void *data)
     mc->block_default_type = IF_SCSI;
     mc->max_cpus = 4;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-SuperSparc-II");
 }
 
 static const TypeInfo ss20_type = {
@@ -1422,6 +1412,7 @@ static void voyager_class_init(ObjectClass *oc, void *data)
     mc->init = vger_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904");
 }
 
 static const TypeInfo voyager_type = {
@@ -1438,6 +1429,7 @@ static void ss_lx_class_init(ObjectClass *oc, void *data)
     mc->init = ss_lx_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I");
 }
 
 static const TypeInfo ss_lx_type = {
@@ -1454,6 +1446,7 @@ static void ss4_class_init(ObjectClass *oc, void *data)
     mc->init = ss4_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Fujitsu-MB86904");
 }
 
 static const TypeInfo ss4_type = {
@@ -1470,6 +1463,7 @@ static void scls_class_init(ObjectClass *oc, void *data)
     mc->init = scls_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I");
 }
 
 static const TypeInfo scls_type = {
@@ -1486,6 +1480,7 @@ static void sbook_class_init(ObjectClass *oc, void *data)
     mc->init = sbook_init;
     mc->block_default_type = IF_SCSI;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-MicroSparc-I");
 }
 
 static const TypeInfo sbook_type = {
diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c
index 9a8d6109d4..7a723326c5 100644
--- a/hw/sparc64/niagara.c
+++ b/hw/sparc64/niagara.c
@@ -106,8 +106,7 @@ static void niagara_init(MachineState *machine)
     MemoryRegion *sysmem = get_system_memory();
 
     /* init CPUs */
-    sparc64_cpu_devinit(machine->cpu_model, "Sun UltraSparc T1",
-                        NIAGARA_PROM_BASE);
+    sparc64_cpu_devinit(machine->cpu_type, NIAGARA_PROM_BASE);
     /* set up devices */
     memory_region_allocate_system_memory(&s->hv_ram, NULL, "sun4v-hv.ram",
                                          NIAGARA_HV_RAM_SIZE);
@@ -174,6 +173,7 @@ static void niagara_class_init(ObjectClass *oc, void *data)
     mc->init = niagara_init;
     mc->max_cpus = 1; /* XXX for now */
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Sun-UltraSparc-T1");
 }
 
 static const TypeInfo niagara_type = {
diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c
index 097d529ff1..9453e2c390 100644
--- a/hw/sparc64/sparc64.c
+++ b/hw/sparc64/sparc64.c
@@ -339,8 +339,7 @@ void cpu_tick_set_limit(CPUTimer *timer, uint64_t limit)
     }
 }
 
-SPARCCPU *sparc64_cpu_devinit(const char *cpu_model,
-                              const char *default_cpu_model, uint64_t prom_addr)
+SPARCCPU *sparc64_cpu_devinit(const char *cpu_type, uint64_t prom_addr)
 {
     SPARCCPU *cpu;
     CPUSPARCState *env;
@@ -350,10 +349,7 @@ SPARCCPU *sparc64_cpu_devinit(const char *cpu_model,
     uint32_t  stick_frequency = 100 * 1000000;
     uint32_t hstick_frequency = 100 * 1000000;
 
-    if (cpu_model == NULL) {
-        cpu_model = default_cpu_model;
-    }
-    cpu = SPARC_CPU(cpu_generic_init(TYPE_SPARC_CPU, cpu_model));
+    cpu = SPARC_CPU(cpu_create(cpu_type));
     env = &cpu->env;
 
     env->tick = cpu_timer_create("tick", cpu, tick_irq,
diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index 77a787466a..1672f256e7 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -75,7 +75,6 @@
 #define IVEC_MAX             0x40
 
 struct hwdef {
-    const char * const default_cpu_model;
     uint16_t machine_id;
     uint64_t prom_addr;
     uint64_t console_serial_base;
@@ -446,8 +445,7 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
     bool onboard_nic;
 
     /* init CPUs */
-    cpu = sparc64_cpu_devinit(machine->cpu_model, hwdef->default_cpu_model,
-                              hwdef->prom_addr);
+    cpu = sparc64_cpu_devinit(machine->cpu_type, hwdef->prom_addr);
 
     /* set up devices */
     ram_init(0, machine->ram_size);
@@ -599,14 +597,12 @@ enum {
 static const struct hwdef hwdefs[] = {
     /* Sun4u generic PC-like machine */
     {
-        .default_cpu_model = "TI UltraSparc IIi",
         .machine_id = sun4u_id,
         .prom_addr = 0x1fff0000000ULL,
         .console_serial_base = 0,
     },
     /* Sun4v generic PC-like machine */
     {
-        .default_cpu_model = "Sun UltraSparc T1",
         .machine_id = sun4v_id,
         .prom_addr = 0x1fff0000000ULL,
         .console_serial_base = 0,
@@ -635,6 +631,7 @@ static void sun4u_class_init(ObjectClass *oc, void *data)
     mc->max_cpus = 1; /* XXX for now */
     mc->is_default = 1;
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-UltraSparc-IIi");
 }
 
 static const TypeInfo sun4u_type = {
@@ -652,6 +649,7 @@ static void sun4v_class_init(ObjectClass *oc, void *data)
     mc->block_default_type = IF_IDE;
     mc->max_cpus = 1; /* XXX for now */
     mc->default_boot_order = "c";
+    mc->default_cpu_type = SPARC_CPU_TYPE_NAME("Sun-UltraSparc-T1");
 }
 
 static const TypeInfo sun4v_type = {
diff --git a/hw/tricore/tricore_testboard.c b/hw/tricore/tricore_testboard.c
index 0486f8a1d9..ac75eb2128 100644
--- a/hw/tricore/tricore_testboard.c
+++ b/hw/tricore/tricore_testboard.c
@@ -71,10 +71,7 @@ static void tricore_testboard_init(MachineState *machine, int board_id)
     MemoryRegion *pcp_data = g_new(MemoryRegion, 1);
     MemoryRegion *pcp_text = g_new(MemoryRegion, 1);
 
-    if (!machine->cpu_model) {
-        machine->cpu_model = "tc1796";
-    }
-    cpu = TRICORE_CPU(cpu_generic_init(TYPE_TRICORE_CPU, machine->cpu_model));
+    cpu = TRICORE_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
     memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram",
                            2 * 1024 * 1024, &error_fatal);
@@ -114,6 +111,7 @@ static void ttb_machine_init(MachineClass *mc)
     mc->desc = "a minimal TriCore board";
     mc->init = tricoreboard_init;
     mc->is_default = 0;
+    mc->default_cpu_type = TRICORE_CPU_TYPE_NAME("tc1796");
 }
 
 DEFINE_MACHINE("tricore_testboard", ttb_machine_init)
diff --git a/hw/unicore32/puv3.c b/hw/unicore32/puv3.c
index 504ea46211..1b39cc035b 100644
--- a/hw/unicore32/puv3.c
+++ b/hw/unicore32/puv3.c
@@ -112,7 +112,6 @@ static void puv3_load_kernel(const char *kernel_filename)
 static void puv3_init(MachineState *machine)
 {
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     const char *initrd_filename = machine->initrd_filename;
     CPUUniCore32State *env;
@@ -123,11 +122,7 @@ static void puv3_init(MachineState *machine)
         exit(1);
     }
 
-    if (!cpu_model) {
-        cpu_model = "UniCore-II";
-    }
-
-    cpu = UNICORE32_CPU(cpu_generic_init(TYPE_UNICORE32_CPU, cpu_model));
+    cpu = UNICORE32_CPU(cpu_create(machine->cpu_type));
     env = &cpu->env;
 
     puv3_soc_init(env);
@@ -140,6 +135,7 @@ static void puv3_machine_init(MachineClass *mc)
     mc->desc = "PKUnity Version-3 based on UniCore32";
     mc->init = puv3_init;
     mc->is_default = 1;
+    mc->default_cpu_type = UNICORE32_CPU_TYPE_NAME("UniCore-II");
 }
 
 DEFINE_MACHINE("puv3", puv3_machine_init)
diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c
index b3580b11fa..2bb883b664 100644
--- a/hw/xtensa/sim.c
+++ b/hw/xtensa/sim.c
@@ -75,16 +75,11 @@ static void xtensa_sim_init(MachineState *machine)
     XtensaCPU *cpu = NULL;
     CPUXtensaState *env = NULL;
     ram_addr_t ram_size = machine->ram_size;
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = machine->kernel_filename;
     int n;
 
-    if (!cpu_model) {
-        cpu_model = XTENSA_DEFAULT_CPU_MODEL;
-    }
-
     for (n = 0; n < smp_cpus; n++) {
-        cpu = XTENSA_CPU(cpu_generic_init(TYPE_XTENSA_CPU, cpu_model));
+        cpu = XTENSA_CPU(cpu_create(machine->cpu_type));
         env = &cpu->env;
 
         env->sregs[PRID] = n;
@@ -133,6 +128,7 @@ static void xtensa_sim_machine_init(MachineClass *mc)
     mc->init = xtensa_sim_init;
     mc->max_cpus = 4;
     mc->no_serial = 1;
+    mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
 }
 
 DEFINE_MACHINE("sim", xtensa_sim_machine_init)
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index a19ccebdba..1971ecfdc5 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -220,19 +220,14 @@ static void lx_init(const LxBoardDesc *board, MachineState *machine)
     DriveInfo *dinfo;
     pflash_t *flash = NULL;
     QemuOpts *machine_opts = qemu_get_machine_opts();
-    const char *cpu_model = machine->cpu_model;
     const char *kernel_filename = qemu_opt_get(machine_opts, "kernel");
     const char *kernel_cmdline = qemu_opt_get(machine_opts, "append");
     const char *dtb_filename = qemu_opt_get(machine_opts, "dtb");
     const char *initrd_filename = qemu_opt_get(machine_opts, "initrd");
     int n;
 
-    if (!cpu_model) {
-        cpu_model = XTENSA_DEFAULT_CPU_MODEL;
-    }
-
     for (n = 0; n < smp_cpus; n++) {
-        cpu = XTENSA_CPU(cpu_generic_init(TYPE_XTENSA_CPU, cpu_model));
+        cpu = XTENSA_CPU(cpu_create(machine->cpu_type));
         env = &cpu->env;
 
         env->sregs[PRID] = n;
@@ -454,6 +449,7 @@ static void xtensa_lx60_class_init(ObjectClass *oc, void *data)
     mc->desc = "lx60 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_lx60_init;
     mc->max_cpus = 4;
+    mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
 }
 
 static const TypeInfo xtensa_lx60_type = {
@@ -469,6 +465,7 @@ static void xtensa_lx200_class_init(ObjectClass *oc, void *data)
     mc->desc = "lx200 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_lx200_init;
     mc->max_cpus = 4;
+    mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
 }
 
 static const TypeInfo xtensa_lx200_type = {
@@ -484,6 +481,7 @@ static void xtensa_ml605_class_init(ObjectClass *oc, void *data)
     mc->desc = "ml605 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_ml605_init;
     mc->max_cpus = 4;
+    mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
 }
 
 static const TypeInfo xtensa_ml605_type = {
@@ -499,6 +497,7 @@ static void xtensa_kc705_class_init(ObjectClass *oc, void *data)
     mc->desc = "kc705 EVB (" XTENSA_DEFAULT_CPU_MODEL ")";
     mc->init = xtensa_kc705_init;
     mc->max_cpus = 4;
+    mc->default_cpu_type = XTENSA_DEFAULT_CPU_TYPE;
 }
 
 static const TypeInfo xtensa_kc705_type = {
diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h
index 526b8d0b11..aab1af926d 100644
--- a/include/hw/mips/cps.h
+++ b/include/hw/mips/cps.h
@@ -34,7 +34,7 @@ typedef struct MIPSCPSState {
 
     uint32_t num_vp;
     uint32_t num_irq;
-    char *cpu_model;
+    char *cpu_type;
 
     MemoryRegion container;
     MIPSGCRState gcr;
diff --git a/include/hw/sparc/sparc64.h b/include/hw/sparc/sparc64.h
index 7748939a97..ca3bb4be71 100644
--- a/include/hw/sparc/sparc64.h
+++ b/include/hw/sparc/sparc64.h
@@ -1,5 +1,4 @@
 
-SPARCCPU *sparc64_cpu_devinit(const char *cpu_model,
-                              const char *dflt_cpu_model, uint64_t prom_addr);
+SPARCCPU *sparc64_cpu_devinit(const char *cpu_type, uint64_t prom_addr);
 
 void sparc64_cpu_set_ivec_irq(void *opaque, int irq, int level);
diff --git a/linux-user/main.c b/linux-user/main.c
index 28353f1a75..aa02f25b85 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -4331,7 +4331,7 @@ int main(int argc, char **argv, char **envp)
         cpu_model = "750";
 # endif
 #elif defined TARGET_SH4
-        cpu_model = TYPE_SH7785_CPU;
+        cpu_model = "sh7785";
 #elif defined TARGET_S390X
         cpu_model = "qemu";
 #else
diff --git a/numa.c b/numa.c
index 100a67febf..8d78d959f6 100644
--- a/numa.c
+++ b/numa.c
@@ -38,6 +38,7 @@
 #include "hw/mem/pc-dimm.h"
 #include "qemu/option.h"
 #include "qemu/config-file.h"
+#include "qemu/cutils.h"
 
 QemuOptsList qemu_numa_opts = {
     .name = "numa",
@@ -142,7 +143,7 @@ uint32_t numa_get_node(ram_addr_t addr, Error **errp)
 }
 
 static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
-                            QemuOpts *opts, Error **errp)
+                            Error **errp)
 {
     uint16_t nodenr;
     uint16List *cpus = NULL;
@@ -199,13 +200,7 @@ static void parse_numa_node(MachineState *ms, NumaNodeOptions *node,
     }
 
     if (node->has_mem) {
-        uint64_t mem_size = node->mem;
-        const char *mem_str = qemu_opt_get(opts, "mem");
-        /* Fix up legacy suffix-less format */
-        if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
-            mem_size <<= 20;
-        }
-        numa_info[nodenr].node_mem = mem_size;
+        numa_info[nodenr].node_mem = node->mem;
     }
     if (node->has_memdev) {
         Object *o;
@@ -275,9 +270,15 @@ static int parse_numa(void *opaque, QemuOpts *opts, Error **errp)
         goto end;
     }
 
+    /* Fix up legacy suffix-less format */
+    if ((object->type == NUMA_OPTIONS_TYPE_NODE) && object->u.node.has_mem) {
+        const char *mem_str = qemu_opt_get(opts, "mem");
+        qemu_strtosz_MiB(mem_str, NULL, &object->u.node.mem);
+    }
+
     switch (object->type) {
     case NUMA_OPTIONS_TYPE_NODE:
-        parse_numa_node(ms, &object->u.node, opts, &err);
+        parse_numa_node(ms, &object->u.node, &err);
         if (err) {
             goto end;
         }
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index ab0c63d931..e809e382eb 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -1643,6 +1643,67 @@ guest_find_interface(GuestNetworkInterfaceList *head,
     return head;
 }
 
+static int guest_get_network_stats(const char *name,
+                       GuestNetworkInterfaceStat *stats)
+{
+    int name_len;
+    char const *devinfo = "/proc/net/dev";
+    FILE *fp;
+    char *line = NULL, *colon;
+    size_t n = 0;
+    fp = fopen(devinfo, "r");
+    if (!fp) {
+        return -1;
+    }
+    name_len = strlen(name);
+    while (getline(&line, &n, fp) != -1) {
+        long long dummy;
+        long long rx_bytes;
+        long long rx_packets;
+        long long rx_errs;
+        long long rx_dropped;
+        long long tx_bytes;
+        long long tx_packets;
+        long long tx_errs;
+        long long tx_dropped;
+        char *trim_line;
+        trim_line = g_strchug(line);
+        if (trim_line[0] == '\0') {
+            continue;
+        }
+        colon = strchr(trim_line, ':');
+        if (!colon) {
+            continue;
+        }
+        if (colon - name_len  == trim_line &&
+           strncmp(trim_line, name, name_len) == 0) {
+            if (sscanf(colon + 1,
+                "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld",
+                  &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
+                  &dummy, &dummy, &dummy, &dummy,
+                  &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
+                  &dummy, &dummy, &dummy, &dummy) != 16) {
+                continue;
+            }
+            stats->rx_bytes = rx_bytes;
+            stats->rx_packets = rx_packets;
+            stats->rx_errs = rx_errs;
+            stats->rx_dropped = rx_dropped;
+            stats->tx_bytes = tx_bytes;
+            stats->tx_packets = tx_packets;
+            stats->tx_errs = tx_errs;
+            stats->tx_dropped = tx_dropped;
+            fclose(fp);
+            g_free(line);
+            return 0;
+        }
+    }
+    fclose(fp);
+    g_free(line);
+    g_debug("/proc/net/dev: Interface '%s' not found", name);
+    return -1;
+}
+
 /*
  * Build information about guest interfaces
  */
@@ -1659,6 +1720,7 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
     for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
         GuestNetworkInterfaceList *info;
         GuestIpAddressList **address_list = NULL, *address_item = NULL;
+        GuestNetworkInterfaceStat  *interface_stat = NULL;
         char addr4[INET_ADDRSTRLEN];
         char addr6[INET6_ADDRSTRLEN];
         int sock;
@@ -1778,7 +1840,17 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
 
         info->value->has_ip_addresses = true;
 
-
+        if (!info->value->has_statistics) {
+            interface_stat = g_malloc0(sizeof(*interface_stat));
+            if (guest_get_network_stats(info->value->name,
+                interface_stat) == -1) {
+                info->value->has_statistics = false;
+                g_free(interface_stat);
+            } else {
+                info->value->statistics = interface_stat;
+                info->value->has_statistics = true;
+            }
+        }
     }
 
     freeifaddrs(ifap);
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 619dbd2bc2..0322188a73 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -29,6 +29,7 @@
 #endif
 #include <lm.h>
 #include <wtsapi32.h>
+#include <wininet.h>
 
 #include "qga/guest-agent-core.h"
 #include "qga/vss-win32.h"
@@ -1152,6 +1153,44 @@ out:
 }
 #endif
 
+#define INTERFACE_PATH_BUF_SZ 512
+
+static DWORD get_interface_index(const char *guid)
+{
+    ULONG index;
+    DWORD status;
+    wchar_t wbuf[INTERFACE_PATH_BUF_SZ];
+    snwprintf(wbuf, INTERFACE_PATH_BUF_SZ, L"\\device\\tcpip_%s", guid);
+    wbuf[INTERFACE_PATH_BUF_SZ - 1] = 0;
+    status = GetAdapterIndex (wbuf, &index);
+    if (status != NO_ERROR) {
+        return (DWORD)~0;
+    } else {
+        return index;
+    }
+}
+static int guest_get_network_stats(const char *name,
+                       GuestNetworkInterfaceStat *stats)
+{
+    DWORD if_index = 0;
+    MIB_IFROW a_mid_ifrow;
+    memset(&a_mid_ifrow, 0, sizeof(a_mid_ifrow));
+    if_index = get_interface_index(name);
+    a_mid_ifrow.dwIndex = if_index;
+    if (NO_ERROR == GetIfEntry(&a_mid_ifrow)) {
+        stats->rx_bytes = a_mid_ifrow.dwInOctets;
+        stats->rx_packets = a_mid_ifrow.dwInUcastPkts;
+        stats->rx_errs = a_mid_ifrow.dwInErrors;
+        stats->rx_dropped = a_mid_ifrow.dwInDiscards;
+        stats->tx_bytes = a_mid_ifrow.dwOutOctets;
+        stats->tx_packets = a_mid_ifrow.dwOutUcastPkts;
+        stats->tx_errs = a_mid_ifrow.dwOutErrors;
+        stats->tx_dropped = a_mid_ifrow.dwOutDiscards;
+        return 0;
+    }
+    return -1;
+}
+
 GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
 {
     IP_ADAPTER_ADDRESSES *adptr_addrs, *addr;
@@ -1159,6 +1198,7 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
     GuestNetworkInterfaceList *head = NULL, *cur_item = NULL;
     GuestIpAddressList *head_addr, *cur_addr;
     GuestNetworkInterfaceList *info;
+    GuestNetworkInterfaceStat *interface_stat = NULL;
     GuestIpAddressList *address_item = NULL;
     unsigned char *mac_addr;
     char *addr_str;
@@ -1238,6 +1278,17 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
             info->value->has_ip_addresses = true;
             info->value->ip_addresses = head_addr;
         }
+        if (!info->value->has_statistics) {
+            interface_stat = g_malloc0(sizeof(*interface_stat));
+            if (guest_get_network_stats(addr->AdapterName,
+                interface_stat) == -1) {
+                info->value->has_statistics = false;
+                g_free(interface_stat);
+            } else {
+                info->value->statistics = interface_stat;
+                info->value->has_statistics = true;
+            }
+        }
     }
     WSACleanup();
 out:
@@ -1277,8 +1328,41 @@ void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
          * RTC yet:
          *
          * https://msdn.microsoft.com/en-us/library/aa908981.aspx
+         *
+         * Instead, a workaround is to use the Windows win32tm command to
+         * resync the time using the Windows Time service.
          */
-        error_setg(errp, "Time argument is required on this platform");
+        LPVOID msg_buffer;
+        DWORD ret_flags;
+
+        HRESULT hr = system("w32tm /resync /nowait");
+
+        if (GetLastError() != 0) {
+            strerror_s((LPTSTR) & msg_buffer, 0, errno);
+            error_setg(errp, "system(...) failed: %s", (LPCTSTR)msg_buffer);
+        } else if (hr != 0) {
+            if (hr == HRESULT_FROM_WIN32(ERROR_SERVICE_NOT_ACTIVE)) {
+                error_setg(errp, "Windows Time service not running on the "
+                                 "guest");
+            } else {
+                if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                                   FORMAT_MESSAGE_FROM_SYSTEM |
+                                   FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
+                                   (DWORD)hr, MAKELANGID(LANG_NEUTRAL,
+                                   SUBLANG_DEFAULT), (LPTSTR) & msg_buffer, 0,
+                                   NULL)) {
+                    error_setg(errp, "w32tm failed with error (0x%lx), couldn'"
+                                     "t retrieve error message", hr);
+                } else {
+                    error_setg(errp, "w32tm failed with error (0x%lx): %s", hr,
+                               (LPCTSTR)msg_buffer);
+                    LocalFree(msg_buffer);
+                }
+            }
+        } else if (!InternetGetConnectedState(&ret_flags, 0)) {
+            error_setg(errp, "No internet connection on guest, sync not "
+                             "accurate");
+        }
         return;
     }
 
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 90a0c8602b..17884c7c70 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -643,6 +643,38 @@
            'prefix': 'int'} }
 
 ##
+# @GuestNetworkInterfaceStat:
+#
+# @rx-bytes: total bytes received
+#
+# @rx-packets: total packets received
+#
+# @rx-errs: bad packets received
+#
+# @rx-dropped: receiver dropped packets
+#
+# @tx-bytes: total bytes transmitted
+#
+# @tx-packets: total packets transmitted
+#
+# @tx-errs: packet transmit problems
+#
+# @tx-dropped: dropped packets transmitted
+#
+# Since: 2.11
+##
+{ 'struct': 'GuestNetworkInterfaceStat',
+  'data': {'rx-bytes': 'uint64',
+            'rx-packets': 'uint64',
+            'rx-errs': 'uint64',
+            'rx-dropped': 'uint64',
+            'tx-bytes': 'uint64',
+            'tx-packets': 'uint64',
+            'tx-errs': 'uint64',
+            'tx-dropped': 'uint64'
+           } }
+
+##
 # @GuestNetworkInterface:
 #
 # @name: The name of interface for which info are being delivered
@@ -651,12 +683,16 @@
 #
 # @ip-addresses: List of addresses assigned to @name
 #
+# @statistics: various statistic counters related to @name
+# (since 2.11)
+#
 # Since: 1.1
 ##
 { 'struct': 'GuestNetworkInterface',
   'data': {'name': 'str',
            '*hardware-address': 'str',
-           '*ip-addresses': ['GuestIpAddress'] } }
+           '*ip-addresses': ['GuestIpAddress'],
+           '*statistics': 'GuestNetworkInterfaceStat' } }
 
 ##
 # @guest-network-get-interfaces:
diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
index ba7c94eb25..6713e58670 100644
--- a/qga/vss-win32/install.cpp
+++ b/qga/vss-win32/install.cpp
@@ -148,10 +148,15 @@ static HRESULT getNameByStringSID(
     DWORD domainNameLen = BUFFER_SIZE;
     wchar_t domainName[BUFFER_SIZE];
 
-    chk(ConvertStringSidToSidW(sid, &psid));
-    LookupAccountSidW(NULL, psid, buffer, bufferLen,
-                domainName, &domainNameLen, &groupType);
-    hr = HRESULT_FROM_WIN32(GetLastError());
+    if (!ConvertStringSidToSidW(sid, &psid)) {
+        hr = HRESULT_FROM_WIN32(GetLastError());
+        goto out;
+    }
+    if (!LookupAccountSidW(NULL, psid, buffer, bufferLen,
+                           domainName, &domainNameLen, &groupType)) {
+        hr = HRESULT_FROM_WIN32(GetLastError());
+        /* Fall through and free psid */
+    }
 
     LocalFree(psid);
 
diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp
index 301762d8b1..3d9c9716c0 100644
--- a/qga/vss-win32/requester.cpp
+++ b/qga/vss-win32/requester.cpp
@@ -419,6 +419,16 @@ void requester_freeze(int *num_vols, ErrorSet *errset)
             break;
         }
     }
+
+    if (wait_status == WAIT_TIMEOUT) {
+        err_set(errset, E_FAIL,
+                "timeout when try to receive Frozen event from VSS provider");
+        /* If we are here, VSS had timeout.
+         * Don't call AbortBackup, just return directly.
+         */
+        goto out1;
+    }
+
     if (wait_status != WAIT_OBJECT_0) {
         err_set(errset, E_FAIL,
                 "couldn't receive Frozen event from VSS provider");
@@ -432,6 +442,8 @@ out:
     if (vss_ctx.pVssbc) {
         vss_ctx.pVssbc->AbortBackup();
     }
+
+out1:
     requester_cleanup();
     CoUninitialize();
 }
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index bc9520535b..7d6366bae9 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -108,21 +108,18 @@ void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 }
 
 /* Models */
-
-#define TYPE(model) model "-" TYPE_ALPHA_CPU
-
 typedef struct AlphaCPUAlias {
     const char *alias;
     const char *typename;
 } AlphaCPUAlias;
 
 static const AlphaCPUAlias alpha_cpu_aliases[] = {
-    { "21064",   TYPE("ev4") },
-    { "21164",   TYPE("ev5") },
-    { "21164a",  TYPE("ev56") },
-    { "21164pc", TYPE("pca56") },
-    { "21264",   TYPE("ev6") },
-    { "21264a",  TYPE("ev67") },
+    { "21064",   ALPHA_CPU_TYPE_NAME("ev4") },
+    { "21164",   ALPHA_CPU_TYPE_NAME("ev5") },
+    { "21164a",  ALPHA_CPU_TYPE_NAME("ev56") },
+    { "21164pc", ALPHA_CPU_TYPE_NAME("pca56") },
+    { "21264",   ALPHA_CPU_TYPE_NAME("ev6") },
+    { "21264a",  ALPHA_CPU_TYPE_NAME("ev67") },
 };
 
 static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model)
@@ -145,7 +142,7 @@ static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model)
         }
     }
 
-    typename = g_strdup_printf("%s-" TYPE_ALPHA_CPU, cpu_model);
+    typename = g_strdup_printf(ALPHA_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (oc != NULL && object_class_is_abstract(oc)) {
@@ -155,7 +152,7 @@ static ObjectClass *alpha_cpu_class_by_name(const char *cpu_model)
     /* TODO: remove match everything nonsense */
     /* Default to ev67; no reason not to emulate insns by default. */
     if (!oc) {
-        oc = object_class_by_name(TYPE("ev67"));
+        oc = object_class_by_name(ALPHA_CPU_TYPE_NAME("ev67"));
     }
 
     return oc;
@@ -169,12 +166,6 @@ static void ev4_cpu_initfn(Object *obj)
     env->implver = IMPLVER_2106x;
 }
 
-static const TypeInfo ev4_cpu_type_info = {
-    .name = TYPE("ev4"),
-    .parent = TYPE_ALPHA_CPU,
-    .instance_init = ev4_cpu_initfn,
-};
-
 static void ev5_cpu_initfn(Object *obj)
 {
     AlphaCPU *cpu = ALPHA_CPU(obj);
@@ -183,12 +174,6 @@ static void ev5_cpu_initfn(Object *obj)
     env->implver = IMPLVER_21164;
 }
 
-static const TypeInfo ev5_cpu_type_info = {
-    .name = TYPE("ev5"),
-    .parent = TYPE_ALPHA_CPU,
-    .instance_init = ev5_cpu_initfn,
-};
-
 static void ev56_cpu_initfn(Object *obj)
 {
     AlphaCPU *cpu = ALPHA_CPU(obj);
@@ -197,12 +182,6 @@ static void ev56_cpu_initfn(Object *obj)
     env->amask |= AMASK_BWX;
 }
 
-static const TypeInfo ev56_cpu_type_info = {
-    .name = TYPE("ev56"),
-    .parent = TYPE("ev5"),
-    .instance_init = ev56_cpu_initfn,
-};
-
 static void pca56_cpu_initfn(Object *obj)
 {
     AlphaCPU *cpu = ALPHA_CPU(obj);
@@ -211,12 +190,6 @@ static void pca56_cpu_initfn(Object *obj)
     env->amask |= AMASK_MVI;
 }
 
-static const TypeInfo pca56_cpu_type_info = {
-    .name = TYPE("pca56"),
-    .parent = TYPE("ev56"),
-    .instance_init = pca56_cpu_initfn,
-};
-
 static void ev6_cpu_initfn(Object *obj)
 {
     AlphaCPU *cpu = ALPHA_CPU(obj);
@@ -226,12 +199,6 @@ static void ev6_cpu_initfn(Object *obj)
     env->amask = AMASK_BWX | AMASK_FIX | AMASK_MVI | AMASK_TRAP;
 }
 
-static const TypeInfo ev6_cpu_type_info = {
-    .name = TYPE("ev6"),
-    .parent = TYPE_ALPHA_CPU,
-    .instance_init = ev6_cpu_initfn,
-};
-
 static void ev67_cpu_initfn(Object *obj)
 {
     AlphaCPU *cpu = ALPHA_CPU(obj);
@@ -240,17 +207,6 @@ static void ev67_cpu_initfn(Object *obj)
     env->amask |= AMASK_CIX | AMASK_PREFETCH;
 }
 
-static const TypeInfo ev67_cpu_type_info = {
-    .name = TYPE("ev67"),
-    .parent = TYPE("ev6"),
-    .instance_init = ev67_cpu_initfn,
-};
-
-static const TypeInfo ev68_cpu_type_info = {
-    .name = TYPE("ev68"),
-    .parent = TYPE("ev67"),
-};
-
 static void alpha_cpu_initfn(Object *obj)
 {
     CPUState *cs = CPU(obj);
@@ -302,26 +258,31 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
     cc->gdb_num_core_regs = 67;
 }
 
-static const TypeInfo alpha_cpu_type_info = {
-    .name = TYPE_ALPHA_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(AlphaCPU),
-    .instance_init = alpha_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(AlphaCPUClass),
-    .class_init = alpha_cpu_class_init,
+#define DEFINE_ALPHA_CPU_TYPE(base_type, cpu_model, initfn) \
+     {                                                      \
+         .parent = base_type,                               \
+         .instance_init = initfn,                           \
+         .name = ALPHA_CPU_TYPE_NAME(cpu_model),            \
+     }
+
+static const TypeInfo alpha_cpu_type_infos[] = {
+    {
+        .name = TYPE_ALPHA_CPU,
+        .parent = TYPE_CPU,
+        .instance_size = sizeof(AlphaCPU),
+        .instance_init = alpha_cpu_initfn,
+        .abstract = true,
+        .class_size = sizeof(AlphaCPUClass),
+        .class_init = alpha_cpu_class_init,
+    },
+    DEFINE_ALPHA_CPU_TYPE(TYPE_ALPHA_CPU, "ev4", ev4_cpu_initfn),
+    DEFINE_ALPHA_CPU_TYPE(TYPE_ALPHA_CPU, "ev5", ev5_cpu_initfn),
+    DEFINE_ALPHA_CPU_TYPE(ALPHA_CPU_TYPE_NAME("ev5"), "ev56", ev56_cpu_initfn),
+    DEFINE_ALPHA_CPU_TYPE(ALPHA_CPU_TYPE_NAME("ev56"), "pca56",
+                          pca56_cpu_initfn),
+    DEFINE_ALPHA_CPU_TYPE(TYPE_ALPHA_CPU, "ev6", ev6_cpu_initfn),
+    DEFINE_ALPHA_CPU_TYPE(ALPHA_CPU_TYPE_NAME("ev6"), "ev67", ev67_cpu_initfn),
+    DEFINE_ALPHA_CPU_TYPE(ALPHA_CPU_TYPE_NAME("ev67"), "ev68", NULL),
 };
 
-static void alpha_cpu_register_types(void)
-{
-    type_register_static(&alpha_cpu_type_info);
-    type_register_static(&ev4_cpu_type_info);
-    type_register_static(&ev5_cpu_type_info);
-    type_register_static(&ev56_cpu_type_info);
-    type_register_static(&pca56_cpu_type_info);
-    type_register_static(&ev6_cpu_type_info);
-    type_register_static(&ev67_cpu_type_info);
-    type_register_static(&ev68_cpu_type_info);
-}
-
-type_init(alpha_cpu_register_types)
+DEFINE_TYPES(alpha_cpu_type_infos)
diff --git a/target/alpha/cpu.h b/target/alpha/cpu.h
index 6ae240969b..0a9ad35f06 100644
--- a/target/alpha/cpu.h
+++ b/target/alpha/cpu.h
@@ -470,6 +470,9 @@ void alpha_translate_init(void);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_ALPHA_CPU, cpu_model)
 
+#define ALPHA_CPU_TYPE_SUFFIX "-" TYPE_ALPHA_CPU
+#define ALPHA_CPU_TYPE_NAME(model) model ALPHA_CPU_TYPE_SUFFIX
+
 void alpha_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 /* you can call this signal handler from your SIGBUS and SIGSEGV
    signal handlers to inform the virtual CPU of exceptions. non zero
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 527a3448bf..949c7a6e25 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -71,11 +71,11 @@ static ObjectClass *cris_cpu_class_by_name(const char *cpu_model)
 
 #if defined(CONFIG_USER_ONLY)
     if (strcasecmp(cpu_model, "any") == 0) {
-        return object_class_by_name("crisv32-" TYPE_CRIS_CPU);
+        return object_class_by_name(CRIS_CPU_TYPE_NAME("crisv32"));
     }
 #endif
 
-    typename = g_strdup_printf("%s-" TYPE_CRIS_CPU, cpu_model);
+    typename = g_strdup_printf(CRIS_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_CRIS_CPU) ||
@@ -108,7 +108,7 @@ static void cris_cpu_list_entry(gpointer data, gpointer user_data)
     const char *typename = object_class_get_name(oc);
     char *name;
 
-    name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_CRIS_CPU));
+    name = g_strndup(typename, strlen(typename) - strlen(CRIS_CPU_TYPE_SUFFIX));
     (*s->cpu_fprintf)(s->file, "  %s\n", name);
     g_free(name);
 }
@@ -254,38 +254,6 @@ static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
     ccc->vr = 32;
 }
 
-#define TYPE(model) model "-" TYPE_CRIS_CPU
-
-static const TypeInfo cris_cpu_model_type_infos[] = {
-    {
-        .name = TYPE("crisv8"),
-        .parent = TYPE_CRIS_CPU,
-        .class_init = crisv8_cpu_class_init,
-    }, {
-        .name = TYPE("crisv9"),
-        .parent = TYPE_CRIS_CPU,
-        .class_init = crisv9_cpu_class_init,
-    }, {
-        .name = TYPE("crisv10"),
-        .parent = TYPE_CRIS_CPU,
-        .class_init = crisv10_cpu_class_init,
-    }, {
-        .name = TYPE("crisv11"),
-        .parent = TYPE_CRIS_CPU,
-        .class_init = crisv11_cpu_class_init,
-    }, {
-        .name = TYPE("crisv17"),
-        .parent = TYPE_CRIS_CPU,
-        .class_init = crisv17_cpu_class_init,
-    }, {
-        .name = TYPE("crisv32"),
-        .parent = TYPE_CRIS_CPU,
-        .class_init = crisv32_cpu_class_init,
-    }
-};
-
-#undef TYPE
-
 static void cris_cpu_class_init(ObjectClass *oc, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(oc);
@@ -320,24 +288,29 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
     cc->tcg_initialize = cris_initialize_tcg;
 }
 
-static const TypeInfo cris_cpu_type_info = {
-    .name = TYPE_CRIS_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(CRISCPU),
-    .instance_init = cris_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(CRISCPUClass),
-    .class_init = cris_cpu_class_init,
-};
+#define DEFINE_CRIS_CPU_TYPE(cpu_model, initfn) \
+     {                                          \
+         .parent = TYPE_CRIS_CPU,               \
+         .class_init = initfn,                  \
+         .name = CRIS_CPU_TYPE_NAME(cpu_model), \
+     }
 
-static void cris_cpu_register_types(void)
-{
-    int i;
-
-    type_register_static(&cris_cpu_type_info);
-    for (i = 0; i < ARRAY_SIZE(cris_cpu_model_type_infos); i++) {
-        type_register_static(&cris_cpu_model_type_infos[i]);
-    }
-}
+static const TypeInfo cris_cpu_model_type_infos[] = {
+    {
+        .name = TYPE_CRIS_CPU,
+        .parent = TYPE_CPU,
+        .instance_size = sizeof(CRISCPU),
+        .instance_init = cris_cpu_initfn,
+        .abstract = true,
+        .class_size = sizeof(CRISCPUClass),
+        .class_init = cris_cpu_class_init,
+    },
+    DEFINE_CRIS_CPU_TYPE("crisv8", crisv8_cpu_class_init),
+    DEFINE_CRIS_CPU_TYPE("crisv9", crisv9_cpu_class_init),
+    DEFINE_CRIS_CPU_TYPE("crisv10", crisv10_cpu_class_init),
+    DEFINE_CRIS_CPU_TYPE("crisv11", crisv11_cpu_class_init),
+    DEFINE_CRIS_CPU_TYPE("crisv17", crisv17_cpu_class_init),
+    DEFINE_CRIS_CPU_TYPE("crisv32", crisv32_cpu_class_init),
+};
 
-type_init(cris_cpu_register_types)
+DEFINE_TYPES(cris_cpu_model_type_infos)
diff --git a/target/cris/cpu.h b/target/cris/cpu.h
index 5d822dee16..b64fa3542c 100644
--- a/target/cris/cpu.h
+++ b/target/cris/cpu.h
@@ -269,6 +269,9 @@ enum {
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_CRIS_CPU, cpu_model)
 
+#define CRIS_CPU_TYPE_SUFFIX "-" TYPE_CRIS_CPU
+#define CRIS_CPU_TYPE_NAME(name) (name CRIS_CPU_TYPE_SUFFIX)
+
 #define cpu_signal_handler cpu_cris_signal_handler
 
 /* MMU modes definitions */
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 7f3a292f2b..6f5c14767b 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -51,7 +51,7 @@ static void lm32_cpu_list_entry(gpointer data, gpointer user_data)
     const char *typename = object_class_get_name(oc);
     char *name;
 
-    name = g_strndup(typename, strlen(typename) - strlen("-" TYPE_LM32_CPU));
+    name = g_strndup(typename, strlen(typename) - strlen(LM32_CPU_TYPE_SUFFIX));
     (*s->cpu_fprintf)(s->file, "  %s\n", name);
     g_free(name);
 }
@@ -215,32 +215,12 @@ static void lm32_full_cpu_initfn(Object *obj)
                   | LM32_FEATURE_CYCLE_COUNT;
 }
 
-typedef struct LM32CPUInfo {
-    const char *name;
-    void (*initfn)(Object *obj);
-} LM32CPUInfo;
-
-static const LM32CPUInfo lm32_cpus[] = {
-    {
-        .name = "lm32-basic",
-        .initfn = lm32_basic_cpu_initfn,
-    },
-    {
-        .name = "lm32-standard",
-        .initfn = lm32_standard_cpu_initfn,
-    },
-    {
-        .name = "lm32-full",
-        .initfn = lm32_full_cpu_initfn,
-    },
-};
-
 static ObjectClass *lm32_cpu_class_by_name(const char *cpu_model)
 {
     ObjectClass *oc;
     char *typename;
 
-    typename = g_strdup_printf("%s-" TYPE_LM32_CPU, cpu_model);
+    typename = g_strdup_printf(LM32_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_LM32_CPU) ||
@@ -283,36 +263,26 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
     cc->tcg_initialize = lm32_translate_init;
 }
 
-static void lm32_register_cpu_type(const LM32CPUInfo *info)
-{
-    TypeInfo type_info = {
-        .parent = TYPE_LM32_CPU,
-        .instance_init = info->initfn,
-    };
-
-    type_info.name = g_strdup_printf("%s-" TYPE_LM32_CPU, info->name);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-}
+#define DEFINE_LM32_CPU_TYPE(cpu_model, initfn) \
+    { \
+        .parent = TYPE_LM32_CPU, \
+        .name = LM32_CPU_TYPE_NAME(cpu_model), \
+        .instance_init = initfn, \
+    }
 
-static const TypeInfo lm32_cpu_type_info = {
-    .name = TYPE_LM32_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(LM32CPU),
-    .instance_init = lm32_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(LM32CPUClass),
-    .class_init = lm32_cpu_class_init,
+static const TypeInfo lm32_cpus_type_infos[] = {
+    { /* base class should be registered first */
+         .name = TYPE_LM32_CPU,
+         .parent = TYPE_CPU,
+         .instance_size = sizeof(LM32CPU),
+         .instance_init = lm32_cpu_initfn,
+         .abstract = true,
+         .class_size = sizeof(LM32CPUClass),
+         .class_init = lm32_cpu_class_init,
+    },
+    DEFINE_LM32_CPU_TYPE("lm32-basic", lm32_basic_cpu_initfn),
+    DEFINE_LM32_CPU_TYPE("lm32-standard", lm32_standard_cpu_initfn),
+    DEFINE_LM32_CPU_TYPE("lm32-full", lm32_full_cpu_initfn),
 };
 
-static void lm32_cpu_register_types(void)
-{
-    int i;
-
-    type_register_static(&lm32_cpu_type_info);
-    for (i = 0; i < ARRAY_SIZE(lm32_cpus); i++) {
-        lm32_register_cpu_type(&lm32_cpus[i]);
-    }
-}
-
-type_init(lm32_cpu_register_types)
+DEFINE_TYPES(lm32_cpus_type_infos)
diff --git a/target/lm32/cpu.h b/target/lm32/cpu.h
index de265b50d1..2279594f40 100644
--- a/target/lm32/cpu.h
+++ b/target/lm32/cpu.h
@@ -257,6 +257,9 @@ bool lm32_cpu_do_semihosting(CPUState *cs);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_LM32_CPU, cpu_model)
 
+#define LM32_CPU_TYPE_SUFFIX "-" TYPE_LM32_CPU
+#define LM32_CPU_TYPE_NAME(model) model LM32_CPU_TYPE_SUFFIX
+
 #define cpu_list lm32_cpu_list
 #define cpu_signal_handler cpu_lm32_signal_handler
 
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 5da19e570b..0a3dd83548 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -87,7 +87,7 @@ static ObjectClass *m68k_cpu_class_by_name(const char *cpu_model)
     ObjectClass *oc;
     char *typename;
 
-    typename = g_strdup_printf("%s-" TYPE_M68K_CPU, cpu_model);
+    typename = g_strdup_printf(M68K_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (oc != NULL && (object_class_dynamic_cast(oc, TYPE_M68K_CPU) == NULL ||
@@ -202,23 +202,6 @@ static void any_cpu_initfn(Object *obj)
     m68k_set_feature(env, M68K_FEATURE_WORD_INDEX);
 }
 
-typedef struct M68kCPUInfo {
-    const char *name;
-    void (*instance_init)(Object *obj);
-} M68kCPUInfo;
-
-static const M68kCPUInfo m68k_cpus[] = {
-    { .name = "m68000", .instance_init = m68000_cpu_initfn },
-    { .name = "m68020", .instance_init = m68020_cpu_initfn },
-    { .name = "m68030", .instance_init = m68030_cpu_initfn },
-    { .name = "m68040", .instance_init = m68040_cpu_initfn },
-    { .name = "m68060", .instance_init = m68060_cpu_initfn },
-    { .name = "m5206", .instance_init = m5206_cpu_initfn },
-    { .name = "m5208", .instance_init = m5208_cpu_initfn },
-    { .name = "cfv4e", .instance_init = cfv4e_cpu_initfn },
-    { .name = "any",   .instance_init = any_cpu_initfn },
-};
-
 static void m68k_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
@@ -290,36 +273,32 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
     dc->vmsd = &vmstate_m68k_cpu;
 }
 
-static void register_cpu_type(const M68kCPUInfo *info)
-{
-    TypeInfo type_info = {
-        .parent = TYPE_M68K_CPU,
-        .instance_init = info->instance_init,
-    };
-
-    type_info.name = g_strdup_printf("%s-" TYPE_M68K_CPU, info->name);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-}
+#define DEFINE_M68K_CPU_TYPE(cpu_model, initfn) \
+    {                                           \
+        .name = M68K_CPU_TYPE_NAME(cpu_model),  \
+        .instance_init = initfn,                \
+        .parent = TYPE_M68K_CPU,                \
+    }
 
-static const TypeInfo m68k_cpu_type_info = {
-    .name = TYPE_M68K_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(M68kCPU),
-    .instance_init = m68k_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(M68kCPUClass),
-    .class_init = m68k_cpu_class_init,
+static const TypeInfo m68k_cpus_type_infos[] = {
+    { /* base class should be registered first */
+        .name = TYPE_M68K_CPU,
+        .parent = TYPE_CPU,
+        .instance_size = sizeof(M68kCPU),
+        .instance_init = m68k_cpu_initfn,
+        .abstract = true,
+        .class_size = sizeof(M68kCPUClass),
+        .class_init = m68k_cpu_class_init,
+    },
+    DEFINE_M68K_CPU_TYPE("m68000", m68000_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("m68020", m68020_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("m68030", m68030_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("m68040", m68040_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("m68060", m68060_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("m5206", m5206_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("m5208", m5208_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("cfv4e", cfv4e_cpu_initfn),
+    DEFINE_M68K_CPU_TYPE("any", any_cpu_initfn),
 };
 
-static void m68k_cpu_register_types(void)
-{
-    int i;
-
-    type_register_static(&m68k_cpu_type_info);
-    for (i = 0; i < ARRAY_SIZE(m68k_cpus); i++) {
-        register_cpu_type(&m68k_cpus[i]);
-    }
-}
-
-type_init(m68k_cpu_register_types)
+DEFINE_TYPES(m68k_cpus_type_infos)
diff --git a/target/m68k/cpu.h b/target/m68k/cpu.h
index d9365476e5..afae5f68ac 100644
--- a/target/m68k/cpu.h
+++ b/target/m68k/cpu.h
@@ -323,6 +323,9 @@ void register_m68k_insns (CPUM68KState *env);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_M68K_CPU, cpu_model)
 
+#define M68K_CPU_TYPE_SUFFIX "-" TYPE_M68K_CPU
+#define M68K_CPU_TYPE_NAME(model) model M68K_CPU_TYPE_SUFFIX
+
 #define cpu_signal_handler cpu_m68k_signal_handler
 #define cpu_list m68k_cpu_list
 
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 80812f3e08..069f93560e 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -154,7 +154,7 @@ static void mips_cpu_initfn(Object *obj)
 
 static char *mips_cpu_type_name(const char *cpu_model)
 {
-    return g_strdup_printf("%s-" TYPE_MIPS_CPU, cpu_model);
+    return g_strdup_printf(MIPS_CPU_TYPE_NAME("%s"), cpu_model);
 }
 
 static ObjectClass *mips_cpu_class_by_name(const char *cpu_model)
diff --git a/target/mips/cpu.h b/target/mips/cpu.h
index 66265e4eb6..7f8ba5ff3e 100644
--- a/target/mips/cpu.h
+++ b/target/mips/cpu.h
@@ -740,8 +740,12 @@ enum {
 int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_MIPS_CPU, cpu_model)
-bool cpu_supports_cps_smp(const char *cpu_model);
-bool cpu_supports_isa(const char *cpu_model, unsigned int isa);
+
+#define MIPS_CPU_TYPE_SUFFIX "-" TYPE_MIPS_CPU
+#define MIPS_CPU_TYPE_NAME(model) model MIPS_CPU_TYPE_SUFFIX
+
+bool cpu_supports_cps_smp(const char *cpu_type);
+bool cpu_supports_isa(const char *cpu_type, unsigned int isa);
 void cpu_set_exception_base(int vp_index, target_ulong address);
 
 /* mips_int.c */
diff --git a/target/mips/translate.c b/target/mips/translate.c
index d0690f7df6..b022f840c9 100644
--- a/target/mips/translate.c
+++ b/target/mips/translate.c
@@ -20512,24 +20512,16 @@ void cpu_mips_realize_env(CPUMIPSState *env)
     mvp_init(env, env->cpu_model);
 }
 
-bool cpu_supports_cps_smp(const char *cpu_model)
+bool cpu_supports_cps_smp(const char *cpu_type)
 {
-    const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
-    if (!def) {
-        return false;
-    }
-
-    return (def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
+    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
+    return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
 }
 
-bool cpu_supports_isa(const char *cpu_model, unsigned int isa)
+bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
 {
-    const mips_def_t *def = cpu_mips_find_by_name(cpu_model);
-    if (!def) {
-        return false;
-    }
-
-    return (def->insn_flags & isa) != 0;
+    const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
+    return (mcc->cpu_def->insn_flags & isa) != 0;
 }
 
 void cpu_set_exception_base(int vp_index, target_ulong address)
diff --git a/target/mips/translate_init.c b/target/mips/translate_init.c
index 8bbded46c4..c7ba6ee5f9 100644
--- a/target/mips/translate_init.c
+++ b/target/mips/translate_init.c
@@ -755,18 +755,6 @@ const mips_def_t mips_defs[] =
 };
 const int mips_defs_number = ARRAY_SIZE(mips_defs);
 
-static const mips_def_t *cpu_mips_find_by_name (const char *name)
-{
-    int i;
-
-    for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
-        if (strcasecmp(name, mips_defs[i].name) == 0) {
-            return &mips_defs[i];
-        }
-    }
-    return NULL;
-}
-
 void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf)
 {
     int i;
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
index 24ab3f3708..f1389e5097 100644
--- a/target/moxie/cpu.c
+++ b/target/moxie/cpu.c
@@ -83,7 +83,12 @@ static void moxie_cpu_initfn(Object *obj)
 
 static ObjectClass *moxie_cpu_class_by_name(const char *cpu_model)
 {
-    ObjectClass *oc = object_class_by_name(cpu_model);
+    ObjectClass *oc;
+    char *typename;
+
+    typename = g_strdup_printf(MOXIE_CPU_TYPE_NAME("%s"), cpu_model);
+    oc = object_class_by_name(typename);
+    g_free(typename);
     if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_MOXIE_CPU) ||
                        object_class_is_abstract(oc))) {
         return NULL;
@@ -129,46 +134,24 @@ static void moxie_any_initfn(Object *obj)
     /* Set cpu feature flags */
 }
 
-typedef struct MoxieCPUInfo {
-    const char *name;
-    void (*initfn)(Object *obj);
-} MoxieCPUInfo;
-
-static const MoxieCPUInfo moxie_cpus[] = {
-    { .name = "MoxieLite",      .initfn = moxielite_initfn },
-    { .name = "any",            .initfn = moxie_any_initfn },
-};
+#define DEFINE_MOXIE_CPU_TYPE(cpu_model, initfn) \
+    {                                            \
+        .parent = TYPE_MOXIE_CPU,                \
+        .instance_init = initfn,                 \
+        .name = MOXIE_CPU_TYPE_NAME(cpu_model),  \
+    }
 
-static void cpu_register(const MoxieCPUInfo *info)
-{
-    TypeInfo type_info = {
-        .parent = TYPE_MOXIE_CPU,
+static const TypeInfo moxie_cpus_type_infos[] = {
+    { /* base class should be registered first */
+        .name = TYPE_MOXIE_CPU,
+        .parent = TYPE_CPU,
         .instance_size = sizeof(MoxieCPU),
-        .instance_init = info->initfn,
+        .instance_init = moxie_cpu_initfn,
         .class_size = sizeof(MoxieCPUClass),
-    };
-
-    type_info.name = g_strdup_printf("%s-" TYPE_MOXIE_CPU, info->name);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-}
-
-static const TypeInfo moxie_cpu_type_info = {
-    .name = TYPE_MOXIE_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(MoxieCPU),
-    .instance_init = moxie_cpu_initfn,
-    .class_size = sizeof(MoxieCPUClass),
-    .class_init = moxie_cpu_class_init,
+        .class_init = moxie_cpu_class_init,
+    },
+    DEFINE_MOXIE_CPU_TYPE("MoxieLite", moxielite_initfn),
+    DEFINE_MOXIE_CPU_TYPE("any", moxie_any_initfn),
 };
 
-static void moxie_cpu_register_types(void)
-{
-    int i;
-    type_register_static(&moxie_cpu_type_info);
-    for (i = 0; i < ARRAY_SIZE(moxie_cpus); i++) {
-        cpu_register(&moxie_cpus[i]);
-    }
-}
-
-type_init(moxie_cpu_register_types)
+DEFINE_TYPES(moxie_cpus_type_infos)
diff --git a/target/moxie/cpu.h b/target/moxie/cpu.h
index 75decaadd6..d37e6a5572 100644
--- a/target/moxie/cpu.h
+++ b/target/moxie/cpu.h
@@ -122,6 +122,9 @@ int cpu_moxie_signal_handler(int host_signum, void *pinfo,
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_MOXIE_CPU, cpu_model)
 
+#define MOXIE_CPU_TYPE_SUFFIX "-" TYPE_MOXIE_CPU
+#define MOXIE_CPU_TYPE_NAME(model) model MOXIE_CPU_TYPE_SUFFIX
+
 #define cpu_signal_handler cpu_moxie_signal_handler
 
 static inline int cpu_mmu_index(CPUMoxieState *env, bool ifetch)
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index a8db869e50..e0394b8b06 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -101,7 +101,7 @@ static ObjectClass *openrisc_cpu_class_by_name(const char *cpu_model)
     ObjectClass *oc;
     char *typename;
 
-    typename = g_strdup_printf("%s-" TYPE_OPENRISC_CPU, cpu_model);
+    typename = g_strdup_printf(OPENRISC_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_OPENRISC_CPU) ||
@@ -126,16 +126,6 @@ static void openrisc_any_initfn(Object *obj)
     cpu->env.cpucfgr = CPUCFGR_NSGF | CPUCFGR_OB32S | CPUCFGR_EVBARP;
 }
 
-typedef struct OpenRISCCPUInfo {
-    const char *name;
-    void (*initfn)(Object *obj);
-} OpenRISCCPUInfo;
-
-static const OpenRISCCPUInfo openrisc_cpus[] = {
-    { .name = "or1200",      .initfn = or1200_initfn },
-    { .name = "any",         .initfn = openrisc_any_initfn },
-};
-
 static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
 {
     OpenRISCCPUClass *occ = OPENRISC_CPU_CLASS(oc);
@@ -166,40 +156,6 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
     cc->tcg_initialize = openrisc_translate_init;
 }
 
-static void cpu_register(const OpenRISCCPUInfo *info)
-{
-    TypeInfo type_info = {
-        .parent = TYPE_OPENRISC_CPU,
-        .instance_size = sizeof(OpenRISCCPU),
-        .instance_init = info->initfn,
-        .class_size = sizeof(OpenRISCCPUClass),
-    };
-
-    type_info.name = g_strdup_printf("%s-" TYPE_OPENRISC_CPU, info->name);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-}
-
-static const TypeInfo openrisc_cpu_type_info = {
-    .name = TYPE_OPENRISC_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(OpenRISCCPU),
-    .instance_init = openrisc_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(OpenRISCCPUClass),
-    .class_init = openrisc_cpu_class_init,
-};
-
-static void openrisc_cpu_register_types(void)
-{
-    int i;
-
-    type_register_static(&openrisc_cpu_type_info);
-    for (i = 0; i < ARRAY_SIZE(openrisc_cpus); i++) {
-        cpu_register(&openrisc_cpus[i]);
-    }
-}
-
 /* Sort alphabetically by type name, except for "any". */
 static gint openrisc_cpu_list_compare(gconstpointer a, gconstpointer b)
 {
@@ -248,4 +204,25 @@ void cpu_openrisc_list(FILE *f, fprintf_function cpu_fprintf)
     g_slist_free(list);
 }
 
-type_init(openrisc_cpu_register_types)
+#define DEFINE_OPENRISC_CPU_TYPE(cpu_model, initfn) \
+    {                                               \
+        .parent = TYPE_OPENRISC_CPU,                \
+        .instance_init = initfn,                    \
+        .name = OPENRISC_CPU_TYPE_NAME(cpu_model),  \
+    }
+
+static const TypeInfo openrisc_cpus_type_infos[] = {
+    { /* base class should be registered first */
+        .name = TYPE_OPENRISC_CPU,
+        .parent = TYPE_CPU,
+        .instance_size = sizeof(OpenRISCCPU),
+        .instance_init = openrisc_cpu_initfn,
+        .abstract = true,
+        .class_size = sizeof(OpenRISCCPUClass),
+        .class_init = openrisc_cpu_class_init,
+    },
+    DEFINE_OPENRISC_CPU_TYPE("or1200", or1200_initfn),
+    DEFINE_OPENRISC_CPU_TYPE("any", openrisc_any_initfn),
+};
+
+DEFINE_TYPES(openrisc_cpus_type_infos)
diff --git a/target/openrisc/cpu.h b/target/openrisc/cpu.h
index 892dc4210f..cc22dc8871 100644
--- a/target/openrisc/cpu.h
+++ b/target/openrisc/cpu.h
@@ -392,6 +392,9 @@ int cpu_openrisc_get_phys_data(OpenRISCCPU *cpu,
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_OPENRISC_CPU, cpu_model)
 
+#define OPENRISC_CPU_TYPE_SUFFIX "-" TYPE_OPENRISC_CPU
+#define OPENRISC_CPU_TYPE_NAME(model) model OPENRISC_CPU_TYPE_SUFFIX
+
 #include "exec/cpu-all.h"
 
 #define TB_FLAGS_DFLAG 1
diff --git a/target/sh4/cpu-qom.h b/target/sh4/cpu-qom.h
index 01abb206e4..0f9fb4dd31 100644
--- a/target/sh4/cpu-qom.h
+++ b/target/sh4/cpu-qom.h
@@ -24,9 +24,9 @@
 
 #define TYPE_SUPERH_CPU "superh-cpu"
 
-#define TYPE_SH7750R_CPU "sh7750r-" TYPE_SUPERH_CPU
-#define TYPE_SH7751R_CPU "sh7751r-" TYPE_SUPERH_CPU
-#define TYPE_SH7785_CPU "sh7785-" TYPE_SUPERH_CPU
+#define TYPE_SH7750R_CPU SUPERH_CPU_TYPE_NAME("sh7750r")
+#define TYPE_SH7751R_CPU SUPERH_CPU_TYPE_NAME("sh7751r")
+#define TYPE_SH7785_CPU  SUPERH_CPU_TYPE_NAME("sh7785")
 
 #define SUPERH_CPU_CLASS(klass) \
     OBJECT_CLASS_CHECK(SuperHCPUClass, (klass), TYPE_SUPERH_CPU)
@@ -39,7 +39,6 @@
  * SuperHCPUClass:
  * @parent_realize: The parent class' realize handler.
  * @parent_reset: The parent class' reset handler.
- * @name: The name.
  * @pvr: Processor Version Register
  * @prr: Processor Revision Register
  * @cvr: Cache Version Register
@@ -54,7 +53,6 @@ typedef struct SuperHCPUClass {
     DeviceRealize parent_realize;
     void (*parent_reset)(CPUState *cpu);
 
-    const char *name;
     uint32_t pvr;
     uint32_t prr;
     uint32_t cvr;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 89abce2472..e0b99fbc89 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -98,12 +98,11 @@ static gint superh_cpu_list_compare(gconstpointer a, gconstpointer b)
 
 static void superh_cpu_list_entry(gpointer data, gpointer user_data)
 {
-    ObjectClass *oc = data;
-    SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc);
     SuperHCPUListState *s = user_data;
+    const char *typename = object_class_get_name(OBJECT_CLASS(data));
+    int len = strlen(typename) - strlen(SUPERH_CPU_TYPE_SUFFIX);
 
-    (*s->cpu_fprintf)(s->file, "%s\n",
-                      scc->name);
+    (*s->cpu_fprintf)(s->file, "%.*s\n", len, typename);
 }
 
 void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf)
@@ -120,36 +119,26 @@ void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf)
     g_slist_free(list);
 }
 
-static gint superh_cpu_name_compare(gconstpointer a, gconstpointer b)
-{
-    const SuperHCPUClass *scc = SUPERH_CPU_CLASS(a);
-    const char *name = b;
-
-    return strcasecmp(scc->name, name);
-}
-
 static ObjectClass *superh_cpu_class_by_name(const char *cpu_model)
 {
     ObjectClass *oc;
-    GSList *list, *item;
+    char *s, *typename = NULL;
 
-    if (strcasecmp(cpu_model, "any") == 0) {
-        return object_class_by_name(TYPE_SH7750R_CPU);
+    s = g_ascii_strdown(cpu_model, -1);
+    if (strcmp(s, "any") == 0) {
+        oc = object_class_by_name(TYPE_SH7750R_CPU);
+        goto out;
     }
 
-    oc = object_class_by_name(cpu_model);
-    if (oc != NULL && object_class_dynamic_cast(oc, TYPE_SUPERH_CPU) != NULL
-        && !object_class_is_abstract(oc)) {
-        return oc;
+    typename = g_strdup_printf(SUPERH_CPU_TYPE_NAME("%s"), s);
+    oc = object_class_by_name(typename);
+    if (oc != NULL && object_class_is_abstract(oc)) {
+        oc = NULL;
     }
 
-    oc = NULL;
-    list = object_class_get_list(TYPE_SUPERH_CPU, false);
-    item = g_slist_find_custom(list, cpu_model, superh_cpu_name_compare);
-    if (item != NULL) {
-        oc = item->data;
-    }
-    g_slist_free(list);
+out:
+    g_free(s);
+    g_free(typename);
     return oc;
 }
 
@@ -166,19 +155,11 @@ static void sh7750r_class_init(ObjectClass *oc, void *data)
 {
     SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc);
 
-    scc->name = "SH7750R";
     scc->pvr = 0x00050000;
     scc->prr = 0x00000100;
     scc->cvr = 0x00110000;
 }
 
-static const TypeInfo sh7750r_type_info = {
-    .name = TYPE_SH7750R_CPU,
-    .parent = TYPE_SUPERH_CPU,
-    .class_init = sh7750r_class_init,
-    .instance_init = sh7750r_cpu_initfn,
-};
-
 static void sh7751r_cpu_initfn(Object *obj)
 {
     SuperHCPU *cpu = SUPERH_CPU(obj);
@@ -192,19 +173,11 @@ static void sh7751r_class_init(ObjectClass *oc, void *data)
 {
     SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc);
 
-    scc->name = "SH7751R";
     scc->pvr = 0x04050005;
     scc->prr = 0x00000113;
     scc->cvr = 0x00110000; /* Neutered caches, should be 0x20480000 */
 }
 
-static const TypeInfo sh7751r_type_info = {
-    .name = TYPE_SH7751R_CPU,
-    .parent = TYPE_SUPERH_CPU,
-    .class_init = sh7751r_class_init,
-    .instance_init = sh7751r_cpu_initfn,
-};
-
 static void sh7785_cpu_initfn(Object *obj)
 {
     SuperHCPU *cpu = SUPERH_CPU(obj);
@@ -218,19 +191,11 @@ static void sh7785_class_init(ObjectClass *oc, void *data)
 {
     SuperHCPUClass *scc = SUPERH_CPU_CLASS(oc);
 
-    scc->name = "SH7785";
     scc->pvr = 0x10300700;
     scc->prr = 0x00000200;
     scc->cvr = 0x71440211;
 }
 
-static const TypeInfo sh7785_type_info = {
-    .name = TYPE_SH7785_CPU,
-    .parent = TYPE_SUPERH_CPU,
-    .class_init = sh7785_class_init,
-    .instance_init = sh7785_cpu_initfn,
-};
-
 static void superh_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
@@ -300,22 +265,30 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
     dc->vmsd = &vmstate_sh_cpu;
 }
 
-static const TypeInfo superh_cpu_type_info = {
-    .name = TYPE_SUPERH_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(SuperHCPU),
-    .instance_init = superh_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(SuperHCPUClass),
-    .class_init = superh_cpu_class_init,
-};
+#define DEFINE_SUPERH_CPU_TYPE(type_name, cinit, initfn) \
+    {                                                    \
+        .name = type_name,                               \
+        .parent = TYPE_SUPERH_CPU,                       \
+        .class_init = cinit,                             \
+        .instance_init = initfn,                         \
+    }
+static const TypeInfo superh_cpu_type_infos[] = {
+    {
+        .name = TYPE_SUPERH_CPU,
+        .parent = TYPE_CPU,
+        .instance_size = sizeof(SuperHCPU),
+        .instance_init = superh_cpu_initfn,
+        .abstract = true,
+        .class_size = sizeof(SuperHCPUClass),
+        .class_init = superh_cpu_class_init,
+    },
+    DEFINE_SUPERH_CPU_TYPE(TYPE_SH7750R_CPU, sh7750r_class_init,
+                           sh7750r_cpu_initfn),
+    DEFINE_SUPERH_CPU_TYPE(TYPE_SH7751R_CPU, sh7751r_class_init,
+                           sh7751r_cpu_initfn),
+    DEFINE_SUPERH_CPU_TYPE(TYPE_SH7785_CPU, sh7785_class_init,
+                           sh7785_cpu_initfn),
 
-static void superh_cpu_register_types(void)
-{
-    type_register_static(&superh_cpu_type_info);
-    type_register_static(&sh7750r_type_info);
-    type_register_static(&sh7751r_type_info);
-    type_register_static(&sh7785_type_info);
-}
+};
 
-type_init(superh_cpu_register_types)
+DEFINE_TYPES(superh_cpu_type_infos)
diff --git a/target/sh4/cpu.h b/target/sh4/cpu.h
index 123f34783a..960b46870d 100644
--- a/target/sh4/cpu.h
+++ b/target/sh4/cpu.h
@@ -274,6 +274,9 @@ void cpu_load_tlb(CPUSH4State * env);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_SUPERH_CPU, cpu_model)
 
+#define SUPERH_CPU_TYPE_SUFFIX "-" TYPE_SUPERH_CPU
+#define SUPERH_CPU_TYPE_NAME(model) model SUPERH_CPU_TYPE_SUFFIX
+
 #define cpu_signal_handler cpu_sh4_signal_handler
 #define cpu_list sh4_cpu_list
 
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 47d0927707..c7adc281de 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -712,7 +712,7 @@ static bool sparc_cpu_has_work(CPUState *cs)
 
 static char *sparc_cpu_type_name(const char *cpu_model)
 {
-    char *name = g_strdup_printf("%s-" TYPE_SPARC_CPU, cpu_model);
+    char *name = g_strdup_printf(SPARC_CPU_TYPE_NAME("%s"), cpu_model);
     char *s = name;
 
     /* SPARC cpu model names happen to have whitespaces,
diff --git a/target/sparc/cpu.h b/target/sparc/cpu.h
index bf2b8931cc..9fde547fac 100644
--- a/target/sparc/cpu.h
+++ b/target/sparc/cpu.h
@@ -658,6 +658,9 @@ int cpu_sparc_signal_handler(int host_signum, void *pinfo, void *puc);
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_SPARC_CPU, cpu_model)
 #endif
 
+#define SPARC_CPU_TYPE_SUFFIX "-" TYPE_SPARC_CPU
+#define SPARC_CPU_TYPE_NAME(model) model SPARC_CPU_TYPE_SUFFIX
+
 #define cpu_signal_handler cpu_sparc_signal_handler
 #define cpu_list sparc_cpu_list
 
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index cd93806d47..179c997aa4 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -116,7 +116,7 @@ static ObjectClass *tricore_cpu_class_by_name(const char *cpu_model)
     ObjectClass *oc;
     char *typename;
 
-    typename = g_strdup_printf("%s-" TYPE_TRICORE_CPU, cpu_model);
+    typename = g_strdup_printf(TRICORE_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (!oc || !object_class_dynamic_cast(oc, TYPE_TRICORE_CPU) ||
@@ -147,19 +147,6 @@ static void tc27x_initfn(Object *obj)
     set_feature(&cpu->env, TRICORE_FEATURE_161);
 }
 
-typedef struct TriCoreCPUInfo {
-    const char *name;
-    void (*initfn)(Object *obj);
-    void (*class_init)(ObjectClass *oc, void *data);
-} TriCoreCPUInfo;
-
-static const TriCoreCPUInfo tricore_cpus[] = {
-    { .name = "tc1796",      .initfn = tc1796_initfn },
-    { .name = "tc1797",      .initfn = tc1797_initfn },
-    { .name = "tc27x",       .initfn = tc27x_initfn },
-    { .name = NULL }
-};
-
 static void tricore_cpu_class_init(ObjectClass *c, void *data)
 {
     TriCoreCPUClass *mcc = TRICORE_CPU_CLASS(c);
@@ -181,41 +168,26 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
     cc->tcg_initialize = tricore_tcg_init;
 }
 
-static void cpu_register(const TriCoreCPUInfo *info)
-{
-    TypeInfo type_info = {
-        .parent = TYPE_TRICORE_CPU,
+#define DEFINE_TRICORE_CPU_TYPE(cpu_model, initfn) \
+    {                                              \
+        .parent = TYPE_TRICORE_CPU,                \
+        .instance_init = initfn,                   \
+        .name = TRICORE_CPU_TYPE_NAME(cpu_model),  \
+    }
+
+static const TypeInfo tricore_cpu_type_infos[] = {
+    {
+        .name = TYPE_TRICORE_CPU,
+        .parent = TYPE_CPU,
         .instance_size = sizeof(TriCoreCPU),
-        .instance_init = info->initfn,
+        .instance_init = tricore_cpu_initfn,
+        .abstract = true,
         .class_size = sizeof(TriCoreCPUClass),
-        .class_init = info->class_init,
-    };
-
-    type_info.name = g_strdup_printf("%s-" TYPE_TRICORE_CPU, info->name);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-}
-
-static const TypeInfo tricore_cpu_type_info = {
-    .name = TYPE_TRICORE_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(TriCoreCPU),
-    .instance_init = tricore_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(TriCoreCPUClass),
-    .class_init = tricore_cpu_class_init,
+        .class_init = tricore_cpu_class_init,
+    },
+    DEFINE_TRICORE_CPU_TYPE("tc1796", tc1796_initfn),
+    DEFINE_TRICORE_CPU_TYPE("tc1797", tc1797_initfn),
+    DEFINE_TRICORE_CPU_TYPE("tc27x", tc27x_initfn),
 };
 
-static void tricore_cpu_register_types(void)
-{
-    const TriCoreCPUInfo *info = tricore_cpus;
-
-    type_register_static(&tricore_cpu_type_info);
-
-    while (info->name) {
-        cpu_register(info);
-        info++;
-    }
-}
-
-type_init(tricore_cpu_register_types)
+DEFINE_TYPES(tricore_cpu_type_infos)
diff --git a/target/tricore/cpu.h b/target/tricore/cpu.h
index bc53c40774..f41d2ceb69 100644
--- a/target/tricore/cpu.h
+++ b/target/tricore/cpu.h
@@ -413,6 +413,8 @@ static inline void cpu_get_tb_cpu_state(CPUTriCoreState *env, target_ulong *pc,
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_TRICORE_CPU, cpu_model)
 
+#define TRICORE_CPU_TYPE_SUFFIX "-" TYPE_TRICORE_CPU
+#define TRICORE_CPU_TYPE_NAME(model) model TRICORE_CPU_TYPE_SUFFIX
 
 /* helpers.c */
 int cpu_tricore_handle_mmu_fault(CPUState *cpu, target_ulong address,
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 526604ff78..17dc1504d7 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -44,7 +44,7 @@ static ObjectClass *uc32_cpu_class_by_name(const char *cpu_model)
     ObjectClass *oc;
     char *typename;
 
-    typename = g_strdup_printf("%s-" TYPE_UNICORE32_CPU, cpu_model);
+    typename = g_strdup_printf(UNICORE32_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_UNICORE32_CPU) ||
@@ -54,11 +54,6 @@ static ObjectClass *uc32_cpu_class_by_name(const char *cpu_model)
     return oc;
 }
 
-typedef struct UniCore32CPUInfo {
-    const char *name;
-    void (*instance_init)(Object *obj);
-} UniCore32CPUInfo;
-
 static void unicore_ii_cpu_initfn(Object *obj)
 {
     UniCore32CPU *cpu = UNICORE32_CPU(obj);
@@ -90,11 +85,6 @@ static void uc32_any_cpu_initfn(Object *obj)
     set_snan_bit_is_one(1, &env->ucf64.fp_status);
 }
 
-static const UniCore32CPUInfo uc32_cpus[] = {
-    { .name = "UniCore-II", .instance_init = unicore_ii_cpu_initfn },
-    { .name = "any",        .instance_init = uc32_any_cpu_initfn },
-};
-
 static void uc32_cpu_realizefn(DeviceState *dev, Error **errp)
 {
     CPUState *cs = CPU(dev);
@@ -160,36 +150,25 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
     dc->vmsd = &vmstate_uc32_cpu;
 }
 
-static void uc32_register_cpu_type(const UniCore32CPUInfo *info)
-{
-    TypeInfo type_info = {
-        .parent = TYPE_UNICORE32_CPU,
-        .instance_init = info->instance_init,
-    };
-
-    type_info.name = g_strdup_printf("%s-" TYPE_UNICORE32_CPU, info->name);
-    type_register(&type_info);
-    g_free((void *)type_info.name);
-}
+#define DEFINE_UNICORE32_CPU_TYPE(cpu_model, initfn) \
+    {                                                \
+        .parent = TYPE_UNICORE32_CPU,                \
+        .instance_init = initfn,                     \
+        .name = UNICORE32_CPU_TYPE_NAME(cpu_model),  \
+    }
 
-static const TypeInfo uc32_cpu_type_info = {
-    .name = TYPE_UNICORE32_CPU,
-    .parent = TYPE_CPU,
-    .instance_size = sizeof(UniCore32CPU),
-    .instance_init = uc32_cpu_initfn,
-    .abstract = true,
-    .class_size = sizeof(UniCore32CPUClass),
-    .class_init = uc32_cpu_class_init,
+static const TypeInfo uc32_cpu_type_infos[] = {
+    {
+        .name = TYPE_UNICORE32_CPU,
+        .parent = TYPE_CPU,
+        .instance_size = sizeof(UniCore32CPU),
+        .instance_init = uc32_cpu_initfn,
+        .abstract = true,
+        .class_size = sizeof(UniCore32CPUClass),
+        .class_init = uc32_cpu_class_init,
+    },
+    DEFINE_UNICORE32_CPU_TYPE("UniCore-II", unicore_ii_cpu_initfn),
+    DEFINE_UNICORE32_CPU_TYPE("any", uc32_any_cpu_initfn),
 };
 
-static void uc32_cpu_register_types(void)
-{
-    int i;
-
-    type_register_static(&uc32_cpu_type_info);
-    for (i = 0; i < ARRAY_SIZE(uc32_cpus); i++) {
-        uc32_register_cpu_type(&uc32_cpus[i]);
-    }
-}
-
-type_init(uc32_cpu_register_types)
+DEFINE_TYPES(uc32_cpu_type_infos)
diff --git a/target/unicore32/cpu.h b/target/unicore32/cpu.h
index 7724108281..3dc6fbc6c7 100644
--- a/target/unicore32/cpu.h
+++ b/target/unicore32/cpu.h
@@ -167,6 +167,9 @@ static inline int cpu_mmu_index(CPUUniCore32State *env, bool ifetch)
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_UNICORE32_CPU, cpu_model)
 
+#define UNICORE32_CPU_TYPE_SUFFIX "-" TYPE_UNICORE32_CPU
+#define UNICORE32_CPU_TYPE_NAME(model) model UNICORE32_CPU_TYPE_SUFFIX
+
 static inline void cpu_get_tb_cpu_state(CPUUniCore32State *env, target_ulong *pc,
                                         target_ulong *cs_base, uint32_t *flags)
 {
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index a5651e5dab..91961789a5 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -83,7 +83,7 @@ static ObjectClass *xtensa_cpu_class_by_name(const char *cpu_model)
     ObjectClass *oc;
     char *typename;
 
-    typename = g_strdup_printf("%s-" TYPE_XTENSA_CPU, cpu_model);
+    typename = g_strdup_printf(XTENSA_CPU_TYPE_NAME("%s"), cpu_model);
     oc = object_class_by_name(typename);
     g_free(typename);
     if (oc == NULL || !object_class_dynamic_cast(oc, TYPE_XTENSA_CPU) ||
diff --git a/target/xtensa/cpu.h b/target/xtensa/cpu.h
index 48033313c5..b17d7d96e9 100644
--- a/target/xtensa/cpu.h
+++ b/target/xtensa/cpu.h
@@ -469,11 +469,15 @@ void xtensa_cpu_do_unaligned_access(CPUState *cpu, vaddr addr,
 #define cpu_signal_handler cpu_xtensa_signal_handler
 #define cpu_list xtensa_cpu_list
 
+#define XTENSA_CPU_TYPE_SUFFIX "-" TYPE_XTENSA_CPU
+#define XTENSA_CPU_TYPE_NAME(model) model XTENSA_CPU_TYPE_SUFFIX
+
 #ifdef TARGET_WORDS_BIGENDIAN
 #define XTENSA_DEFAULT_CPU_MODEL "fsf"
 #else
 #define XTENSA_DEFAULT_CPU_MODEL "dc232b"
 #endif
+#define XTENSA_DEFAULT_CPU_TYPE XTENSA_CPU_TYPE_NAME(XTENSA_DEFAULT_CPU_MODEL)
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_XTENSA_CPU, cpu_model)
 
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
index e8fba20918..216f1988aa 100644
--- a/target/xtensa/helper.c
+++ b/target/xtensa/helper.c
@@ -76,7 +76,7 @@ void xtensa_register_core(XtensaConfigList *node)
 
     node->next = xtensa_cores;
     xtensa_cores = node;
-    type.name = g_strdup_printf("%s-" TYPE_XTENSA_CPU, node->config->name);
+    type.name = g_strdup_printf(XTENSA_CPU_TYPE_NAME("%s"), node->config->name);
     type_register(&type);
     g_free((gpointer)type.name);
 }