summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-09-08 14:44:44 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-09-08 14:44:44 +0100
commita1ae46d1b4f2a95ad5d3da8d15bc6403bcdbb24a (patch)
treeb2d02f48aa15e70cecc4c61401634d122d408035
parent74bbfe024da80a50dbe51fbb17f219d2f3e4d2dd (diff)
parent7cca3e466eb0baa36d1cc29d5aeb5da74a260711 (diff)
downloadfocaccia-qemu-a1ae46d1b4f2a95ad5d3da8d15bc6403bcdbb24a.tar.gz
focaccia-qemu-a1ae46d1b4f2a95ad5d3da8d15bc6403bcdbb24a.zip
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.11-20170908' into staging
ppc patch queue 2017-09-08

This is the first batch of ppc related patches for qemu-2.11, and it's
accumulated quite a few things.  Includes:

  * A cleanup to handling of ppc cpu models from Igor
  * First parts of fixes to handling of guest vs. host SMT modes from
    Sam Bobroff
  * Preliminary patches towards supporting the Sam460 board from
    Balaton Zoltan
  * Several fixes for hotplug logic
  * Assorted other fixes and cleanups

# gpg: Signature made Fri 08 Sep 2017 06:28:42 BST
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>"
# gpg:                 aka "David Gibson (Red Hat) <dgibson@redhat.com>"
# gpg:                 aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>"
# gpg:                 aka "David Gibson (kernel.org) <dwg@kernel.org>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.11-20170908: (40 commits)
  ppc: spapr: Move VCPU ID calculation into sPAPR
  ppc: remove non implemented cpu models
  ppc: drop caching ObjectClass from PowerPCCPUAlias
  ppc: simplify cpu model lookup by PVR
  ppc: replace inter-function cyclic dependency/recurssion with 2 simple lookups
  ppc: make cpu alias point only to real cpu models
  ppc: make cpu_model translation to type consistent
  ppc: use macros to make cpu type name from string literal
  target/ppc: Remove old STATUS file
  PPC: KVM: Support machine option to set VSMT mode
  spapr: fallback to raw mode if best compat mode cannot be set during CAS
  hw/nvram/spapr_nvram: Device can not be created by the users
  hw/ppc/spapr_cpu_core: Add a proper check for spapr machine
  ppc4xx: Export ECB and PLB emulation
  ppc4xx_i2c: Move to hw/i2c
  ppc4xx_i2c: QOMify
  ppc4xx: Split off 4xx I2C emulation from ppc405_uc to its own file
  ppc4xx: Make MAL emulation more generic
  ppc4xx: Move MAL from ppc405_uc to ppc4xx_devs
  spapr_iommu: Realloc guest visible TCE table when hot(un)plugging vfio-pci
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--default-configs/ppc-softmmu.mak1
-rw-r--r--default-configs/ppc64-softmmu.mak1
-rw-r--r--default-configs/ppcemb-softmmu.mak1
-rw-r--r--hw/i2c/Makefile.objs1
-rw-r--r--hw/i2c/ppc4xx_i2c.c216
-rw-r--r--hw/nvram/spapr_nvram.c2
-rw-r--r--hw/ppc/e500.c8
-rw-r--r--hw/ppc/ppc.c21
-rw-r--r--hw/ppc/ppc405.h3
-rw-r--r--hw/ppc/ppc405_uc.c515
-rw-r--r--hw/ppc/ppc4xx_devs.c227
-rw-r--r--hw/ppc/spapr.c166
-rw-r--r--hw/ppc/spapr_cpu_core.c40
-rw-r--r--hw/ppc/spapr_drc.c37
-rw-r--r--hw/ppc/spapr_events.c11
-rw-r--r--hw/ppc/spapr_hcall.c22
-rw-r--r--hw/ppc/spapr_iommu.c57
-rw-r--r--hw/ppc/spapr_pci.c6
-rw-r--r--hw/ppc/spapr_rtas.c4
-rw-r--r--include/hw/i2c/ppc4xx_i2c.h61
-rw-r--r--include/hw/ppc/ppc4xx.h3
-rw-r--r--include/hw/ppc/spapr.h5
-rw-r--r--include/hw/ppc/spapr_drc.h1
-rwxr-xr-xscripts/device-crash-test3
-rw-r--r--target/ppc/STATUS550
-rw-r--r--target/ppc/cpu-models.c1021
-rw-r--r--target/ppc/cpu-models.h4
-rw-r--r--target/ppc/cpu.h51
-rw-r--r--target/ppc/kvm.c46
-rw-r--r--target/ppc/kvm_ppc.h14
-rw-r--r--target/ppc/mmu_helper.c16
-rw-r--r--target/ppc/translate_init.c232
32 files changed, 1310 insertions, 2036 deletions
diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak
index 1f1cd85b12..d4d44eb66b 100644
--- a/default-configs/ppc-softmmu.mak
+++ b/default-configs/ppc-softmmu.mak
@@ -3,6 +3,7 @@
 include pci.mak
 include sound.mak
 include usb.mak
+CONFIG_PPC4XX=y
 CONFIG_ESCC=y
 CONFIG_M48T59=y
 CONFIG_SERIAL=y
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index 46c9599321..af32589b38 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -3,6 +3,7 @@
 include pci.mak
 include sound.mak
 include usb.mak
+CONFIG_PPC4XX=y
 CONFIG_VIRTIO_VGA=y
 CONFIG_ESCC=y
 CONFIG_M48T59=y
diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak
index 94340de356..635923a166 100644
--- a/default-configs/ppcemb-softmmu.mak
+++ b/default-configs/ppcemb-softmmu.mak
@@ -3,6 +3,7 @@
 include pci.mak
 include sound.mak
 include usb.mak
+CONFIG_PPC4XX=y
 CONFIG_M48T59=y
 CONFIG_SERIAL=y
 CONFIG_SERIAL_ISA=y
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index a081b8ef2c..0594dea3ae 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -8,3 +8,4 @@ common-obj-$(CONFIG_EXYNOS4) += exynos4210_i2c.o
 common-obj-$(CONFIG_IMX_I2C) += imx_i2c.o
 common-obj-$(CONFIG_ASPEED_SOC) += aspeed_i2c.o
 obj-$(CONFIG_OMAP) += omap_i2c.o
+obj-$(CONFIG_PPC4XX) += ppc4xx_i2c.o
diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c
new file mode 100644
index 0000000000..5a6bde951e
--- /dev/null
+++ b/hw/i2c/ppc4xx_i2c.c
@@ -0,0 +1,216 @@
+/*
+ * PPC4xx I2C controller emulation
+ *
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "cpu.h"
+#include "hw/hw.h"
+#include "hw/i2c/ppc4xx_i2c.h"
+
+/*#define DEBUG_I2C*/
+
+#define PPC4xx_I2C_MEM_SIZE 0x11
+
+static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size)
+{
+    PPC4xxI2CState *i2c = PPC4xx_I2C(opaque);
+    uint64_t ret;
+
+#ifdef DEBUG_I2C
+    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
+#endif
+    switch (addr) {
+    case 0x00:
+        /*i2c_readbyte(&i2c->mdata);*/
+        ret = i2c->mdata;
+        break;
+    case 0x02:
+        ret = i2c->sdata;
+        break;
+    case 0x04:
+        ret = i2c->lmadr;
+        break;
+    case 0x05:
+        ret = i2c->hmadr;
+        break;
+    case 0x06:
+        ret = i2c->cntl;
+        break;
+    case 0x07:
+        ret = i2c->mdcntl;
+        break;
+    case 0x08:
+        ret = i2c->sts;
+        break;
+    case 0x09:
+        ret = i2c->extsts;
+        break;
+    case 0x0A:
+        ret = i2c->lsadr;
+        break;
+    case 0x0B:
+        ret = i2c->hsadr;
+        break;
+    case 0x0C:
+        ret = i2c->clkdiv;
+        break;
+    case 0x0D:
+        ret = i2c->intrmsk;
+        break;
+    case 0x0E:
+        ret = i2c->xfrcnt;
+        break;
+    case 0x0F:
+        ret = i2c->xtcntlss;
+        break;
+    case 0x10:
+        ret = i2c->directcntl;
+        break;
+    default:
+        ret = 0x00;
+        break;
+    }
+#ifdef DEBUG_I2C
+    printf("%s: addr " TARGET_FMT_plx " %02" PRIx64 "\n", __func__, addr, ret);
+#endif
+
+    return ret;
+}
+
+static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
+                              unsigned int size)
+{
+    PPC4xxI2CState *i2c = opaque;
+#ifdef DEBUG_I2C
+    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n",
+           __func__, addr, value);
+#endif
+    switch (addr) {
+    case 0x00:
+        i2c->mdata = value;
+        /*i2c_sendbyte(&i2c->mdata);*/
+        break;
+    case 0x02:
+        i2c->sdata = value;
+        break;
+    case 0x04:
+        i2c->lmadr = value;
+        break;
+    case 0x05:
+        i2c->hmadr = value;
+        break;
+    case 0x06:
+        i2c->cntl = value;
+        break;
+    case 0x07:
+        i2c->mdcntl = value & 0xDF;
+        break;
+    case 0x08:
+        i2c->sts &= ~(value & 0x0A);
+        break;
+    case 0x09:
+        i2c->extsts &= ~(value & 0x8F);
+        break;
+    case 0x0A:
+        i2c->lsadr = value;
+        break;
+    case 0x0B:
+        i2c->hsadr = value;
+        break;
+    case 0x0C:
+        i2c->clkdiv = value;
+        break;
+    case 0x0D:
+        i2c->intrmsk = value;
+        break;
+    case 0x0E:
+        i2c->xfrcnt = value & 0x77;
+        break;
+    case 0x0F:
+        i2c->xtcntlss = value;
+        break;
+    case 0x10:
+        i2c->directcntl = value & 0x7;
+        break;
+    }
+}
+
+static const MemoryRegionOps ppc4xx_i2c_ops = {
+    .read = ppc4xx_i2c_readb,
+    .write = ppc4xx_i2c_writeb,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 1,
+    .impl.max_access_size = 1,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void ppc4xx_i2c_reset(DeviceState *s)
+{
+    PPC4xxI2CState *i2c = PPC4xx_I2C(s);
+
+    i2c->mdata = 0x00;
+    i2c->sdata = 0x00;
+    i2c->cntl = 0x00;
+    i2c->mdcntl = 0x00;
+    i2c->sts = 0x00;
+    i2c->extsts = 0x00;
+    i2c->clkdiv = 0x00;
+    i2c->xfrcnt = 0x00;
+    i2c->directcntl = 0x0F;
+}
+
+static void ppc4xx_i2c_init(Object *o)
+{
+    PPC4xxI2CState *s = PPC4xx_I2C(o);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &ppc4xx_i2c_ops, s,
+                          TYPE_PPC4xx_I2C, PPC4xx_I2C_MEM_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);
+    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
+    s->bus = i2c_init_bus(DEVICE(s), "i2c");
+}
+
+static void ppc4xx_i2c_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = ppc4xx_i2c_reset;
+}
+
+static const TypeInfo ppc4xx_i2c_type_info = {
+    .name = TYPE_PPC4xx_I2C,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(PPC4xxI2CState),
+    .instance_init = ppc4xx_i2c_init,
+    .class_init = ppc4xx_i2c_class_init,
+};
+
+static void ppc4xx_i2c_register_types(void)
+{
+    type_register_static(&ppc4xx_i2c_type_info);
+}
+
+type_init(ppc4xx_i2c_register_types)
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index bc355a4348..4a0aec8e1d 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -264,6 +264,8 @@ static void spapr_nvram_class_init(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     dc->props = spapr_nvram_properties;
     dc->vmsd = &vmstate_spapr_nvram;
+    /* Reason: Internal device only, uses spapr_rtas_register() in realize() */
+    dc->user_creatable = false;
 }
 
 static const TypeInfo spapr_nvram_type_info = {
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index f0596f34ff..55cad780f4 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -382,7 +382,6 @@ static int ppce500_load_device_tree(MachineState *machine,
        the first node as boot node and be happy */
     for (i = smp_cpus - 1; i >= 0; i--) {
         CPUState *cpu;
-        PowerPCCPU *pcpu;
         char cpu_name[128];
         uint64_t cpu_release_addr = params->spin_base + (i * 0x20);
 
@@ -391,16 +390,13 @@ static int ppce500_load_device_tree(MachineState *machine,
             continue;
         }
         env = cpu->env_ptr;
-        pcpu = POWERPC_CPU(cpu);
 
-        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x",
-                 ppc_get_vcpu_dt_id(pcpu));
+        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", i);
         qemu_fdt_add_subnode(fdt, cpu_name);
         qemu_fdt_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);
         qemu_fdt_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);
         qemu_fdt_setprop_string(fdt, cpu_name, "device_type", "cpu");
-        qemu_fdt_setprop_cell(fdt, cpu_name, "reg",
-                              ppc_get_vcpu_dt_id(pcpu));
+        qemu_fdt_setprop_cell(fdt, cpu_name, "reg", i);
         qemu_fdt_setprop_cell(fdt, cpu_name, "d-cache-line-size",
                               env->dcache_line_size);
         qemu_fdt_setprop_cell(fdt, cpu_name, "i-cache-line-size",
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 224184d66d..f76886f4d3 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -1358,27 +1358,6 @@ void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val)
     }
 }
 
-/* CPU device-tree ID helpers */
-int ppc_get_vcpu_dt_id(PowerPCCPU *cpu)
-{
-    return cpu->cpu_dt_id;
-}
-
-PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id)
-{
-    CPUState *cs;
-
-    CPU_FOREACH(cs) {
-        PowerPCCPU *cpu = POWERPC_CPU(cs);
-
-        if (cpu->cpu_dt_id == cpu_dt_id) {
-            return cpu;
-        }
-    }
-
-    return NULL;
-}
-
 void ppc_cpu_parse_features(const char *cpu_model)
 {
     CPUClass *cc;
diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index a9ffc87f19..7ed25cfa1b 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -59,6 +59,9 @@ struct ppc4xx_bd_info_t {
 ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd,
                                 uint32_t flags);
 
+void ppc4xx_plb_init(CPUPPCState *env);
+void ppc405_ebc_init(CPUPPCState *env);
+
 CPUPPCState *ppc405cr_init(MemoryRegion *address_space_mem,
                         MemoryRegion ram_memories[4],
                         hwaddr ram_bases[4],
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index f6fe3e6f5e..e621d0aec5 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -28,6 +28,7 @@
 #include "hw/hw.h"
 #include "hw/ppc/ppc.h"
 #include "hw/boards.h"
+#include "hw/i2c/ppc4xx_i2c.h"
 #include "ppc405.h"
 #include "hw/char/serial.h"
 #include "qemu/timer.h"
@@ -40,9 +41,7 @@
 //#define DEBUG_GPIO
 //#define DEBUG_SERIAL
 //#define DEBUG_OCM
-//#define DEBUG_I2C
 //#define DEBUG_GPT
-//#define DEBUG_MAL
 //#define DEBUG_CLOCKS
 //#define DEBUG_CLOCKS_LL
 
@@ -175,7 +174,7 @@ static void ppc4xx_plb_reset (void *opaque)
     plb->besr = 0x00000000;
 }
 
-static void ppc4xx_plb_init(CPUPPCState *env)
+void ppc4xx_plb_init(CPUPPCState *env)
 {
     ppc4xx_plb_t *plb;
 
@@ -586,7 +585,7 @@ static void ebc_reset (void *opaque)
     ebc->cfg = 0x80400000;
 }
 
-static void ppc405_ebc_init(CPUPPCState *env)
+void ppc405_ebc_init(CPUPPCState *env)
 {
     ppc4xx_ebc_t *ebc;
 
@@ -994,246 +993,6 @@ static void ppc405_ocm_init(CPUPPCState *env)
 }
 
 /*****************************************************************************/
-/* I2C controller */
-typedef struct ppc4xx_i2c_t ppc4xx_i2c_t;
-struct ppc4xx_i2c_t {
-    qemu_irq irq;
-    MemoryRegion iomem;
-    uint8_t mdata;
-    uint8_t lmadr;
-    uint8_t hmadr;
-    uint8_t cntl;
-    uint8_t mdcntl;
-    uint8_t sts;
-    uint8_t extsts;
-    uint8_t sdata;
-    uint8_t lsadr;
-    uint8_t hsadr;
-    uint8_t clkdiv;
-    uint8_t intrmsk;
-    uint8_t xfrcnt;
-    uint8_t xtcntlss;
-    uint8_t directcntl;
-};
-
-static uint32_t ppc4xx_i2c_readb (void *opaque, hwaddr addr)
-{
-    ppc4xx_i2c_t *i2c;
-    uint32_t ret;
-
-#ifdef DEBUG_I2C
-    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-    i2c = opaque;
-    switch (addr) {
-    case 0x00:
-        //        i2c_readbyte(&i2c->mdata);
-        ret = i2c->mdata;
-        break;
-    case 0x02:
-        ret = i2c->sdata;
-        break;
-    case 0x04:
-        ret = i2c->lmadr;
-        break;
-    case 0x05:
-        ret = i2c->hmadr;
-        break;
-    case 0x06:
-        ret = i2c->cntl;
-        break;
-    case 0x07:
-        ret = i2c->mdcntl;
-        break;
-    case 0x08:
-        ret = i2c->sts;
-        break;
-    case 0x09:
-        ret = i2c->extsts;
-        break;
-    case 0x0A:
-        ret = i2c->lsadr;
-        break;
-    case 0x0B:
-        ret = i2c->hsadr;
-        break;
-    case 0x0C:
-        ret = i2c->clkdiv;
-        break;
-    case 0x0D:
-        ret = i2c->intrmsk;
-        break;
-    case 0x0E:
-        ret = i2c->xfrcnt;
-        break;
-    case 0x0F:
-        ret = i2c->xtcntlss;
-        break;
-    case 0x10:
-        ret = i2c->directcntl;
-        break;
-    default:
-        ret = 0x00;
-        break;
-    }
-#ifdef DEBUG_I2C
-    printf("%s: addr " TARGET_FMT_plx " %02" PRIx32 "\n", __func__, addr, ret);
-#endif
-
-    return ret;
-}
-
-static void ppc4xx_i2c_writeb (void *opaque,
-                               hwaddr addr, uint32_t value)
-{
-    ppc4xx_i2c_t *i2c;
-
-#ifdef DEBUG_I2C
-    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
-           value);
-#endif
-    i2c = opaque;
-    switch (addr) {
-    case 0x00:
-        i2c->mdata = value;
-        //        i2c_sendbyte(&i2c->mdata);
-        break;
-    case 0x02:
-        i2c->sdata = value;
-        break;
-    case 0x04:
-        i2c->lmadr = value;
-        break;
-    case 0x05:
-        i2c->hmadr = value;
-        break;
-    case 0x06:
-        i2c->cntl = value;
-        break;
-    case 0x07:
-        i2c->mdcntl = value & 0xDF;
-        break;
-    case 0x08:
-        i2c->sts &= ~(value & 0x0A);
-        break;
-    case 0x09:
-        i2c->extsts &= ~(value & 0x8F);
-        break;
-    case 0x0A:
-        i2c->lsadr = value;
-        break;
-    case 0x0B:
-        i2c->hsadr = value;
-        break;
-    case 0x0C:
-        i2c->clkdiv = value;
-        break;
-    case 0x0D:
-        i2c->intrmsk = value;
-        break;
-    case 0x0E:
-        i2c->xfrcnt = value & 0x77;
-        break;
-    case 0x0F:
-        i2c->xtcntlss = value;
-        break;
-    case 0x10:
-        i2c->directcntl = value & 0x7;
-        break;
-    }
-}
-
-static uint32_t ppc4xx_i2c_readw (void *opaque, hwaddr addr)
-{
-    uint32_t ret;
-
-#ifdef DEBUG_I2C
-    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-    ret = ppc4xx_i2c_readb(opaque, addr) << 8;
-    ret |= ppc4xx_i2c_readb(opaque, addr + 1);
-
-    return ret;
-}
-
-static void ppc4xx_i2c_writew (void *opaque,
-                               hwaddr addr, uint32_t value)
-{
-#ifdef DEBUG_I2C
-    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
-           value);
-#endif
-    ppc4xx_i2c_writeb(opaque, addr, value >> 8);
-    ppc4xx_i2c_writeb(opaque, addr + 1, value);
-}
-
-static uint32_t ppc4xx_i2c_readl (void *opaque, hwaddr addr)
-{
-    uint32_t ret;
-
-#ifdef DEBUG_I2C
-    printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
-#endif
-    ret = ppc4xx_i2c_readb(opaque, addr) << 24;
-    ret |= ppc4xx_i2c_readb(opaque, addr + 1) << 16;
-    ret |= ppc4xx_i2c_readb(opaque, addr + 2) << 8;
-    ret |= ppc4xx_i2c_readb(opaque, addr + 3);
-
-    return ret;
-}
-
-static void ppc4xx_i2c_writel (void *opaque,
-                               hwaddr addr, uint32_t value)
-{
-#ifdef DEBUG_I2C
-    printf("%s: addr " TARGET_FMT_plx " val %08" PRIx32 "\n", __func__, addr,
-           value);
-#endif
-    ppc4xx_i2c_writeb(opaque, addr, value >> 24);
-    ppc4xx_i2c_writeb(opaque, addr + 1, value >> 16);
-    ppc4xx_i2c_writeb(opaque, addr + 2, value >> 8);
-    ppc4xx_i2c_writeb(opaque, addr + 3, value);
-}
-
-static const MemoryRegionOps i2c_ops = {
-    .old_mmio = {
-        .read = { ppc4xx_i2c_readb, ppc4xx_i2c_readw, ppc4xx_i2c_readl, },
-        .write = { ppc4xx_i2c_writeb, ppc4xx_i2c_writew, ppc4xx_i2c_writel, },
-    },
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static void ppc4xx_i2c_reset (void *opaque)
-{
-    ppc4xx_i2c_t *i2c;
-
-    i2c = opaque;
-    i2c->mdata = 0x00;
-    i2c->sdata = 0x00;
-    i2c->cntl = 0x00;
-    i2c->mdcntl = 0x00;
-    i2c->sts = 0x00;
-    i2c->extsts = 0x00;
-    i2c->clkdiv = 0x00;
-    i2c->xfrcnt = 0x00;
-    i2c->directcntl = 0x0F;
-}
-
-static void ppc405_i2c_init(hwaddr base, qemu_irq irq)
-{
-    ppc4xx_i2c_t *i2c;
-
-    i2c = g_malloc0(sizeof(ppc4xx_i2c_t));
-    i2c->irq = irq;
-#ifdef DEBUG_I2C
-    printf("%s: offset " TARGET_FMT_plx "\n", __func__, base);
-#endif
-    memory_region_init_io(&i2c->iomem, NULL, &i2c_ops, i2c, "i2c", 0x011);
-    memory_region_add_subregion(get_system_memory(), base, &i2c->iomem);
-    qemu_register_reset(ppc4xx_i2c_reset, i2c);
-}
-
-/*****************************************************************************/
 /* General purpose timers */
 typedef struct ppc4xx_gpt_t ppc4xx_gpt_t;
 struct ppc4xx_gpt_t {
@@ -1513,268 +1272,6 @@ static void ppc4xx_gpt_init(hwaddr base, qemu_irq irqs[5])
 }
 
 /*****************************************************************************/
-/* MAL */
-enum {
-    MAL0_CFG      = 0x180,
-    MAL0_ESR      = 0x181,
-    MAL0_IER      = 0x182,
-    MAL0_TXCASR   = 0x184,
-    MAL0_TXCARR   = 0x185,
-    MAL0_TXEOBISR = 0x186,
-    MAL0_TXDEIR   = 0x187,
-    MAL0_RXCASR   = 0x190,
-    MAL0_RXCARR   = 0x191,
-    MAL0_RXEOBISR = 0x192,
-    MAL0_RXDEIR   = 0x193,
-    MAL0_TXCTP0R  = 0x1A0,
-    MAL0_TXCTP1R  = 0x1A1,
-    MAL0_TXCTP2R  = 0x1A2,
-    MAL0_TXCTP3R  = 0x1A3,
-    MAL0_RXCTP0R  = 0x1C0,
-    MAL0_RXCTP1R  = 0x1C1,
-    MAL0_RCBS0    = 0x1E0,
-    MAL0_RCBS1    = 0x1E1,
-};
-
-typedef struct ppc40x_mal_t ppc40x_mal_t;
-struct ppc40x_mal_t {
-    qemu_irq irqs[4];
-    uint32_t cfg;
-    uint32_t esr;
-    uint32_t ier;
-    uint32_t txcasr;
-    uint32_t txcarr;
-    uint32_t txeobisr;
-    uint32_t txdeir;
-    uint32_t rxcasr;
-    uint32_t rxcarr;
-    uint32_t rxeobisr;
-    uint32_t rxdeir;
-    uint32_t txctpr[4];
-    uint32_t rxctpr[2];
-    uint32_t rcbs[2];
-};
-
-static void ppc40x_mal_reset (void *opaque);
-
-static uint32_t dcr_read_mal (void *opaque, int dcrn)
-{
-    ppc40x_mal_t *mal;
-    uint32_t ret;
-
-    mal = opaque;
-    switch (dcrn) {
-    case MAL0_CFG:
-        ret = mal->cfg;
-        break;
-    case MAL0_ESR:
-        ret = mal->esr;
-        break;
-    case MAL0_IER:
-        ret = mal->ier;
-        break;
-    case MAL0_TXCASR:
-        ret = mal->txcasr;
-        break;
-    case MAL0_TXCARR:
-        ret = mal->txcarr;
-        break;
-    case MAL0_TXEOBISR:
-        ret = mal->txeobisr;
-        break;
-    case MAL0_TXDEIR:
-        ret = mal->txdeir;
-        break;
-    case MAL0_RXCASR:
-        ret = mal->rxcasr;
-        break;
-    case MAL0_RXCARR:
-        ret = mal->rxcarr;
-        break;
-    case MAL0_RXEOBISR:
-        ret = mal->rxeobisr;
-        break;
-    case MAL0_RXDEIR:
-        ret = mal->rxdeir;
-        break;
-    case MAL0_TXCTP0R:
-        ret = mal->txctpr[0];
-        break;
-    case MAL0_TXCTP1R:
-        ret = mal->txctpr[1];
-        break;
-    case MAL0_TXCTP2R:
-        ret = mal->txctpr[2];
-        break;
-    case MAL0_TXCTP3R:
-        ret = mal->txctpr[3];
-        break;
-    case MAL0_RXCTP0R:
-        ret = mal->rxctpr[0];
-        break;
-    case MAL0_RXCTP1R:
-        ret = mal->rxctpr[1];
-        break;
-    case MAL0_RCBS0:
-        ret = mal->rcbs[0];
-        break;
-    case MAL0_RCBS1:
-        ret = mal->rcbs[1];
-        break;
-    default:
-        ret = 0;
-        break;
-    }
-
-    return ret;
-}
-
-static void dcr_write_mal (void *opaque, int dcrn, uint32_t val)
-{
-    ppc40x_mal_t *mal;
-    int idx;
-
-    mal = opaque;
-    switch (dcrn) {
-    case MAL0_CFG:
-        if (val & 0x80000000)
-            ppc40x_mal_reset(mal);
-        mal->cfg = val & 0x00FFC087;
-        break;
-    case MAL0_ESR:
-        /* Read/clear */
-        mal->esr &= ~val;
-        break;
-    case MAL0_IER:
-        mal->ier = val & 0x0000001F;
-        break;
-    case MAL0_TXCASR:
-        mal->txcasr = val & 0xF0000000;
-        break;
-    case MAL0_TXCARR:
-        mal->txcarr = val & 0xF0000000;
-        break;
-    case MAL0_TXEOBISR:
-        /* Read/clear */
-        mal->txeobisr &= ~val;
-        break;
-    case MAL0_TXDEIR:
-        /* Read/clear */
-        mal->txdeir &= ~val;
-        break;
-    case MAL0_RXCASR:
-        mal->rxcasr = val & 0xC0000000;
-        break;
-    case MAL0_RXCARR:
-        mal->rxcarr = val & 0xC0000000;
-        break;
-    case MAL0_RXEOBISR:
-        /* Read/clear */
-        mal->rxeobisr &= ~val;
-        break;
-    case MAL0_RXDEIR:
-        /* Read/clear */
-        mal->rxdeir &= ~val;
-        break;
-    case MAL0_TXCTP0R:
-        idx = 0;
-        goto update_tx_ptr;
-    case MAL0_TXCTP1R:
-        idx = 1;
-        goto update_tx_ptr;
-    case MAL0_TXCTP2R:
-        idx = 2;
-        goto update_tx_ptr;
-    case MAL0_TXCTP3R:
-        idx = 3;
-    update_tx_ptr:
-        mal->txctpr[idx] = val;
-        break;
-    case MAL0_RXCTP0R:
-        idx = 0;
-        goto update_rx_ptr;
-    case MAL0_RXCTP1R:
-        idx = 1;
-    update_rx_ptr:
-        mal->rxctpr[idx] = val;
-        break;
-    case MAL0_RCBS0:
-        idx = 0;
-        goto update_rx_size;
-    case MAL0_RCBS1:
-        idx = 1;
-    update_rx_size:
-        mal->rcbs[idx] = val & 0x000000FF;
-        break;
-    }
-}
-
-static void ppc40x_mal_reset (void *opaque)
-{
-    ppc40x_mal_t *mal;
-
-    mal = opaque;
-    mal->cfg = 0x0007C000;
-    mal->esr = 0x00000000;
-    mal->ier = 0x00000000;
-    mal->rxcasr = 0x00000000;
-    mal->rxdeir = 0x00000000;
-    mal->rxeobisr = 0x00000000;
-    mal->txcasr = 0x00000000;
-    mal->txdeir = 0x00000000;
-    mal->txeobisr = 0x00000000;
-}
-
-static void ppc405_mal_init(CPUPPCState *env, qemu_irq irqs[4])
-{
-    ppc40x_mal_t *mal;
-    int i;
-
-    mal = g_malloc0(sizeof(ppc40x_mal_t));
-    for (i = 0; i < 4; i++)
-        mal->irqs[i] = irqs[i];
-    qemu_register_reset(&ppc40x_mal_reset, mal);
-    ppc_dcr_register(env, MAL0_CFG,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_ESR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_IER,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXCASR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXCARR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXEOBISR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXDEIR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RXCASR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RXCARR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RXEOBISR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RXDEIR,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXCTP0R,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXCTP1R,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXCTP2R,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_TXCTP3R,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RXCTP0R,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RXCTP1R,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RCBS0,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-    ppc_dcr_register(env, MAL0_RCBS1,
-                     mal, &dcr_read_mal, &dcr_write_mal);
-}
-
-/*****************************************************************************/
 /* SPR */
 void ppc40x_core_reset(PowerPCCPU *cpu)
 {
@@ -2167,7 +1664,7 @@ CPUPPCState *ppc405cr_init(MemoryRegion *address_space_mem,
                        DEVICE_BIG_ENDIAN);
     }
     /* IIC controller */
-    ppc405_i2c_init(0xef600500, pic[2]);
+    sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500, pic[2]);
     /* GPIO */
     ppc405_gpio_init(0xef600700);
     /* CPU control */
@@ -2514,7 +2011,7 @@ CPUPPCState *ppc405ep_init(MemoryRegion *address_space_mem,
     dma_irqs[3] = pic[8];
     ppc405_dma_init(env, dma_irqs);
     /* IIC controller */
-    ppc405_i2c_init(0xef600500, pic[2]);
+    sysbus_create_simple(TYPE_PPC4xx_I2C, 0xef600500, pic[2]);
     /* GPIO */
     ppc405_gpio_init(0xef600700);
     /* Serial ports */
@@ -2544,7 +2041,7 @@ CPUPPCState *ppc405ep_init(MemoryRegion *address_space_mem,
     mal_irqs[1] = pic[12];
     mal_irqs[2] = pic[13];
     mal_irqs[3] = pic[14];
-    ppc405_mal_init(env, mal_irqs);
+    ppc4xx_mal_init(env, 4, 2, mal_irqs);
     /* Ethernet */
     /* Uses pic[9], pic[15], pic[17] */
     /* CPU control */
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 6b38ed7bc7..ec90f13295 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -734,3 +734,230 @@ ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
 
     return ram_size;
 }
+
+/*****************************************************************************/
+/* MAL */
+
+enum {
+    MAL0_CFG      = 0x180,
+    MAL0_ESR      = 0x181,
+    MAL0_IER      = 0x182,
+    MAL0_TXCASR   = 0x184,
+    MAL0_TXCARR   = 0x185,
+    MAL0_TXEOBISR = 0x186,
+    MAL0_TXDEIR   = 0x187,
+    MAL0_RXCASR   = 0x190,
+    MAL0_RXCARR   = 0x191,
+    MAL0_RXEOBISR = 0x192,
+    MAL0_RXDEIR   = 0x193,
+    MAL0_TXCTP0R  = 0x1A0,
+    MAL0_RXCTP0R  = 0x1C0,
+    MAL0_RCBS0    = 0x1E0,
+    MAL0_RCBS1    = 0x1E1,
+};
+
+typedef struct ppc4xx_mal_t ppc4xx_mal_t;
+struct ppc4xx_mal_t {
+    qemu_irq irqs[4];
+    uint32_t cfg;
+    uint32_t esr;
+    uint32_t ier;
+    uint32_t txcasr;
+    uint32_t txcarr;
+    uint32_t txeobisr;
+    uint32_t txdeir;
+    uint32_t rxcasr;
+    uint32_t rxcarr;
+    uint32_t rxeobisr;
+    uint32_t rxdeir;
+    uint32_t *txctpr;
+    uint32_t *rxctpr;
+    uint32_t *rcbs;
+    uint8_t  txcnum;
+    uint8_t  rxcnum;
+};
+
+static void ppc4xx_mal_reset(void *opaque)
+{
+    ppc4xx_mal_t *mal;
+
+    mal = opaque;
+    mal->cfg = 0x0007C000;
+    mal->esr = 0x00000000;
+    mal->ier = 0x00000000;
+    mal->rxcasr = 0x00000000;
+    mal->rxdeir = 0x00000000;
+    mal->rxeobisr = 0x00000000;
+    mal->txcasr = 0x00000000;
+    mal->txdeir = 0x00000000;
+    mal->txeobisr = 0x00000000;
+}
+
+static uint32_t dcr_read_mal(void *opaque, int dcrn)
+{
+    ppc4xx_mal_t *mal;
+    uint32_t ret;
+
+    mal = opaque;
+    switch (dcrn) {
+    case MAL0_CFG:
+        ret = mal->cfg;
+        break;
+    case MAL0_ESR:
+        ret = mal->esr;
+        break;
+    case MAL0_IER:
+        ret = mal->ier;
+        break;
+    case MAL0_TXCASR:
+        ret = mal->txcasr;
+        break;
+    case MAL0_TXCARR:
+        ret = mal->txcarr;
+        break;
+    case MAL0_TXEOBISR:
+        ret = mal->txeobisr;
+        break;
+    case MAL0_TXDEIR:
+        ret = mal->txdeir;
+        break;
+    case MAL0_RXCASR:
+        ret = mal->rxcasr;
+        break;
+    case MAL0_RXCARR:
+        ret = mal->rxcarr;
+        break;
+    case MAL0_RXEOBISR:
+        ret = mal->rxeobisr;
+        break;
+    case MAL0_RXDEIR:
+        ret = mal->rxdeir;
+        break;
+    default:
+        ret = 0;
+        break;
+    }
+    if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
+        ret = mal->txctpr[dcrn - MAL0_TXCTP0R];
+    }
+    if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
+        ret = mal->rxctpr[dcrn - MAL0_RXCTP0R];
+    }
+    if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
+        ret = mal->rcbs[dcrn - MAL0_RCBS0];
+    }
+
+    return ret;
+}
+
+static void dcr_write_mal(void *opaque, int dcrn, uint32_t val)
+{
+    ppc4xx_mal_t *mal;
+
+    mal = opaque;
+    switch (dcrn) {
+    case MAL0_CFG:
+        if (val & 0x80000000) {
+            ppc4xx_mal_reset(mal);
+        }
+        mal->cfg = val & 0x00FFC087;
+        break;
+    case MAL0_ESR:
+        /* Read/clear */
+        mal->esr &= ~val;
+        break;
+    case MAL0_IER:
+        mal->ier = val & 0x0000001F;
+        break;
+    case MAL0_TXCASR:
+        mal->txcasr = val & 0xF0000000;
+        break;
+    case MAL0_TXCARR:
+        mal->txcarr = val & 0xF0000000;
+        break;
+    case MAL0_TXEOBISR:
+        /* Read/clear */
+        mal->txeobisr &= ~val;
+        break;
+    case MAL0_TXDEIR:
+        /* Read/clear */
+        mal->txdeir &= ~val;
+        break;
+    case MAL0_RXCASR:
+        mal->rxcasr = val & 0xC0000000;
+        break;
+    case MAL0_RXCARR:
+        mal->rxcarr = val & 0xC0000000;
+        break;
+    case MAL0_RXEOBISR:
+        /* Read/clear */
+        mal->rxeobisr &= ~val;
+        break;
+    case MAL0_RXDEIR:
+        /* Read/clear */
+        mal->rxdeir &= ~val;
+        break;
+    }
+    if (dcrn >= MAL0_TXCTP0R && dcrn < MAL0_TXCTP0R + mal->txcnum) {
+        mal->txctpr[dcrn - MAL0_TXCTP0R] = val;
+    }
+    if (dcrn >= MAL0_RXCTP0R && dcrn < MAL0_RXCTP0R + mal->rxcnum) {
+        mal->rxctpr[dcrn - MAL0_RXCTP0R] = val;
+    }
+    if (dcrn >= MAL0_RCBS0 && dcrn < MAL0_RCBS0 + mal->rxcnum) {
+        mal->rcbs[dcrn - MAL0_RCBS0] = val & 0x000000FF;
+    }
+}
+
+void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
+                     qemu_irq irqs[4])
+{
+    ppc4xx_mal_t *mal;
+    int i;
+
+    assert(txcnum <= 32 && rxcnum <= 32);
+    mal = g_malloc0(sizeof(*mal));
+    mal->txcnum = txcnum;
+    mal->rxcnum = rxcnum;
+    mal->txctpr = g_new0(uint32_t, txcnum);
+    mal->rxctpr = g_new0(uint32_t, rxcnum);
+    mal->rcbs = g_new0(uint32_t, rxcnum);
+    for (i = 0; i < 4; i++) {
+        mal->irqs[i] = irqs[i];
+    }
+    qemu_register_reset(&ppc4xx_mal_reset, mal);
+    ppc_dcr_register(env, MAL0_CFG,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_ESR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_IER,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_TXCASR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_TXCARR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_TXEOBISR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_TXDEIR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_RXCASR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_RXCARR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_RXEOBISR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    ppc_dcr_register(env, MAL0_RXDEIR,
+                     mal, &dcr_read_mal, &dcr_write_mal);
+    for (i = 0; i < txcnum; i++) {
+        ppc_dcr_register(env, MAL0_TXCTP0R + i,
+                         mal, &dcr_read_mal, &dcr_write_mal);
+    }
+    for (i = 0; i < rxcnum; i++) {
+        ppc_dcr_register(env, MAL0_RXCTP0R + i,
+                         mal, &dcr_read_mal, &dcr_write_mal);
+    }
+    for (i = 0; i < rxcnum; i++) {
+        ppc_dcr_register(env, MAL0_RCBS0 + i,
+                         mal, &dcr_read_mal, &dcr_write_mal);
+    }
+}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index cec441cbf4..caffa12763 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -26,6 +26,7 @@
  */
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include "qapi/visitor.h"
 #include "sysemu/sysemu.h"
 #include "sysemu/numa.h"
 #include "hw/hw.h"
@@ -208,7 +209,7 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
     int i, ret = 0;
     uint32_t servers_prop[smt_threads];
     uint32_t gservers_prop[smt_threads * 2];
-    int index = ppc_get_vcpu_dt_id(cpu);
+    int index = spapr_vcpu_id(cpu);
 
     if (cpu->compat_pvr) {
         ret = fdt_setprop_cell(fdt, offset, "cpu-version", cpu->compat_pvr);
@@ -237,7 +238,7 @@ static int spapr_fixup_cpu_smt_dt(void *fdt, int offset, PowerPCCPU *cpu,
 
 static int spapr_fixup_cpu_numa_dt(void *fdt, int offset, PowerPCCPU *cpu)
 {
-    int index = ppc_get_vcpu_dt_id(cpu);
+    int index = spapr_vcpu_id(cpu);
     uint32_t associativity[] = {cpu_to_be32(0x5),
                                 cpu_to_be32(0x0),
                                 cpu_to_be32(0x0),
@@ -341,7 +342,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPRMachineState *spapr)
         PowerPCCPU *cpu = POWERPC_CPU(cs);
         CPUPPCState *env = &cpu->env;
         DeviceClass *dc = DEVICE_GET_CLASS(cs);
-        int index = ppc_get_vcpu_dt_id(cpu);
+        int index = spapr_vcpu_id(cpu);
         int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));
 
         if ((index % smt) != 0) {
@@ -493,7 +494,7 @@ static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     CPUPPCState *env = &cpu->env;
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);
-    int index = ppc_get_vcpu_dt_id(cpu);
+    int index = spapr_vcpu_id(cpu);
     uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),
                        0xffffffff, 0xffffffff};
     uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq()
@@ -626,7 +627,7 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr)
      */
     CPU_FOREACH_REVERSE(cs) {
         PowerPCCPU *cpu = POWERPC_CPU(cs);
-        int index = ppc_get_vcpu_dt_id(cpu);
+        int index = spapr_vcpu_id(cpu);
         DeviceClass *dc = DEVICE_GET_CLASS(cs);
         int offset;
 
@@ -790,6 +791,26 @@ out:
     return ret;
 }
 
+static bool spapr_hotplugged_dev_before_cas(void)
+{
+    Object *drc_container, *obj;
+    ObjectProperty *prop;
+    ObjectPropertyIterator iter;
+
+    drc_container = container_get(object_get_root(), "/dr-connector");
+    object_property_iter_init(&iter, drc_container);
+    while ((prop = object_property_iter_next(&iter))) {
+        if (!strstart(prop->type, "link<", NULL)) {
+            continue;
+        }
+        obj = object_property_get_link(drc_container, prop->name, NULL);
+        if (spapr_drc_needed(obj)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
                                  target_ulong addr, target_ulong size,
                                  sPAPROptionVector *ov5_updates)
@@ -797,9 +818,13 @@ int spapr_h_cas_compose_response(sPAPRMachineState *spapr,
     void *fdt, *fdt_skel;
     sPAPRDeviceTreeUpdateHeader hdr = { .version_id = 1 };
 
+    if (spapr_hotplugged_dev_before_cas()) {
+        return 1;
+    }
+
     size -= sizeof(hdr);
 
-    /* Create sceleton */
+    /* Create skeleton */
     fdt_skel = g_malloc0(size);
     _FDT((fdt_create(fdt_skel, size)));
     _FDT((fdt_begin_node(fdt_skel, "")));
@@ -1392,6 +1417,7 @@ static void ppc_spapr_reset(void)
     }
 
     qemu_devices_reset();
+    spapr_clear_pending_events(spapr);
 
     /*
      * We place the device tree and RTAS just below either the top of the RMA,
@@ -2140,6 +2166,61 @@ static void spapr_init_cpus(sPAPRMachineState *spapr)
     g_free(type);
 }
 
+static void spapr_set_vsmt_mode(sPAPRMachineState *spapr, Error **errp)
+{
+    Error *local_err = NULL;
+    bool vsmt_user = !!spapr->vsmt;
+    int kvm_smt = kvmppc_smt_threads();
+    int ret;
+
+    if (!kvm_enabled() && (smp_threads > 1)) {
+        error_setg(&local_err, "TCG cannot support more than 1 thread/core "
+                     "on a pseries machine");
+        goto out;
+    }
+    if (!is_power_of_2(smp_threads)) {
+        error_setg(&local_err, "Cannot support %d threads/core on a pseries "
+                     "machine because it must be a power of 2", smp_threads);
+        goto out;
+    }
+
+    /* Detemine the VSMT mode to use: */
+    if (vsmt_user) {
+        if (spapr->vsmt < smp_threads) {
+            error_setg(&local_err, "Cannot support VSMT mode %d"
+                         " because it must be >= threads/core (%d)",
+                         spapr->vsmt, smp_threads);
+            goto out;
+        }
+        /* In this case, spapr->vsmt has been set by the command line */
+    } else {
+        /* Choose a VSMT mode that may be higher than necessary but is
+         * likely to be compatible with hosts that don't have VSMT. */
+        spapr->vsmt = MAX(kvm_smt, smp_threads);
+    }
+
+    /* KVM: If necessary, set the SMT mode: */
+    if (kvm_enabled() && (spapr->vsmt != kvm_smt)) {
+        ret = kvmppc_set_smt_threads(spapr->vsmt);
+        if (ret) {
+            error_setg(&local_err,
+                       "Failed to set KVM's VSMT mode to %d (errno %d)",
+                       spapr->vsmt, ret);
+            if (!vsmt_user) {
+                error_append_hint(&local_err, "On PPC, a VM with %d threads/"
+                             "core on a host with %d threads/core requires "
+                             " the use of VSMT mode %d.\n",
+                             smp_threads, kvm_smt, spapr->vsmt);
+            }
+            kvmppc_hint_smt_possible(&local_err);
+            goto out;
+        }
+    }
+    /* else TCG: nothing to do currently */
+out:
+    error_propagate(errp, local_err);
+}
+
 /* pSeries LPAR / sPAPR hardware init */
 static void ppc_spapr_init(MachineState *machine)
 {
@@ -2272,6 +2353,8 @@ static void ppc_spapr_init(MachineState *machine)
 
     spapr_cpu_parse_features(spapr);
 
+    spapr_set_vsmt_mode(spapr, &error_fatal);
+
     spapr_init_cpus(spapr);
 
     if (kvm_enabled()) {
@@ -2656,6 +2739,18 @@ static void spapr_set_resize_hpt(Object *obj, const char *value, Error **errp)
     }
 }
 
+static void spapr_get_vsmt(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
+static void spapr_set_vsmt(Object *obj, Visitor *v, const char *name,
+                                   void *opaque, Error **errp)
+{
+    visit_type_uint32(v, name, (uint32_t *)opaque, errp);
+}
+
 static void spapr_machine_initfn(Object *obj)
 {
     sPAPRMachineState *spapr = SPAPR_MACHINE(obj);
@@ -2686,6 +2781,11 @@ static void spapr_machine_initfn(Object *obj)
     object_property_set_description(obj, "resize-hpt",
                                     "Resizing of the Hash Page Table (enabled, disabled, required)",
                                     NULL);
+    object_property_add(obj, "vsmt", "uint32", spapr_get_vsmt,
+                        spapr_set_vsmt, NULL, &spapr->vsmt, &error_abort);
+    object_property_set_description(obj, "vsmt",
+                                    "Virtual SMT: KVM behaves as if this were"
+                                    " the host's SMT mode", &error_abort);
 }
 
 static void spapr_machine_finalizefn(Object *obj)
@@ -3000,7 +3100,7 @@ static void *spapr_populate_hotplug_cpu_dt(CPUState *cs, int *fdt_offset,
 {
     PowerPCCPU *cpu = POWERPC_CPU(cs);
     DeviceClass *dc = DEVICE_GET_CLASS(cs);
-    int id = ppc_get_vcpu_dt_id(cpu);
+    int id = spapr_vcpu_id(cpu);
     void *fdt;
     int offset, fdt_size;
     char *nodename;
@@ -3408,9 +3508,9 @@ static void spapr_ics_resend(XICSFabric *dev)
     ics_resend(spapr->ics);
 }
 
-static ICPState *spapr_icp_get(XICSFabric *xi, int cpu_dt_id)
+static ICPState *spapr_icp_get(XICSFabric *xi, int vcpu_id)
 {
-    PowerPCCPU *cpu = ppc_get_vcpu_by_dt_id(cpu_dt_id);
+    PowerPCCPU *cpu = spapr_find_cpu(vcpu_id);
 
     return cpu ? ICP(cpu->intc) : NULL;
 }
@@ -3430,6 +3530,32 @@ static void spapr_pic_print_info(InterruptStatsProvider *obj,
     ics_pic_print_info(spapr->ics, mon);
 }
 
+int spapr_vcpu_id(PowerPCCPU *cpu)
+{
+    CPUState *cs = CPU(cpu);
+
+    if (kvm_enabled()) {
+        return kvm_arch_vcpu_id(cs);
+    } else {
+        return cs->cpu_index;
+    }
+}
+
+PowerPCCPU *spapr_find_cpu(int vcpu_id)
+{
+    CPUState *cs;
+
+    CPU_FOREACH(cs) {
+        PowerPCCPU *cpu = POWERPC_CPU(cs);
+
+        if (spapr_vcpu_id(cpu) == vcpu_id) {
+            return cpu;
+        }
+    }
+
+    return NULL;
+}
+
 static void spapr_machine_class_init(ObjectClass *oc, void *data)
 {
     MachineClass *mc = MACHINE_CLASS(oc);
@@ -3538,18 +3664,36 @@ static const TypeInfo spapr_machine_info = {
     type_init(spapr_machine_register_##suffix)
 
 /*
+ * pseries-2.11
+ */
+static void spapr_machine_2_11_instance_options(MachineState *machine)
+{
+}
+
+static void spapr_machine_2_11_class_options(MachineClass *mc)
+{
+    /* Defaults for the latest behaviour inherited from the base class */
+}
+
+DEFINE_SPAPR_MACHINE(2_11, "2.11", true);
+
+/*
  * pseries-2.10
  */
+#define SPAPR_COMPAT_2_10                                              \
+    HW_COMPAT_2_10                                                     \
+
 static void spapr_machine_2_10_instance_options(MachineState *machine)
 {
 }
 
 static void spapr_machine_2_10_class_options(MachineClass *mc)
 {
-    /* Defaults for the latest behaviour inherited from the base class */
+    spapr_machine_2_11_class_options(mc);
+    SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_10);
 }
 
-DEFINE_SPAPR_MACHINE(2_10, "2.10", true);
+DEFINE_SPAPR_MACHINE(2_10, "2.10", false);
 
 /*
  * pseries-2.9
diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c
index ea278ce2a7..85037ef71e 100644
--- a/hw/ppc/spapr_cpu_core.c
+++ b/hw/ppc/spapr_cpu_core.c
@@ -130,8 +130,10 @@ char *spapr_get_cpu_core_type(const char *model)
 {
     char *core_type;
     gchar **model_pieces = g_strsplit(model, ",", 2);
+    gchar *cpu_model = g_ascii_strdown(model_pieces[0], -1);
+    g_strfreev(model_pieces);
 
-    core_type = g_strdup_printf("%s-%s", model_pieces[0], TYPE_SPAPR_CPU_CORE);
+    core_type = g_strdup_printf("%s-" TYPE_SPAPR_CPU_CORE, cpu_model);
 
     /* Check whether it exists or whether we have to look up an alias name */
     if (!object_class_by_name(core_type)) {
@@ -139,13 +141,13 @@ char *spapr_get_cpu_core_type(const char *model)
 
         g_free(core_type);
         core_type = NULL;
-        realmodel = ppc_cpu_lookup_alias(model_pieces[0]);
+        realmodel = ppc_cpu_lookup_alias(cpu_model);
         if (realmodel) {
             core_type = spapr_get_cpu_core_type(realmodel);
         }
     }
+    g_free(cpu_model);
 
-    g_strfreev(model_pieces);
     return core_type;
 }
 
@@ -211,6 +213,7 @@ error:
 
 static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
 {
+    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
     sPAPRCPUCore *sc = SPAPR_CPU_CORE(OBJECT(dev));
     sPAPRCPUCoreClass *scc = SPAPR_CPU_CORE_GET_CLASS(OBJECT(dev));
     CPUCore *cc = CPU_CORE(OBJECT(dev));
@@ -220,6 +223,11 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
     void *obj;
     int i, j;
 
+    if (!object_dynamic_cast(qdev_get_machine(), TYPE_SPAPR_MACHINE)) {
+        error_setg(errp, "spapr-cpu-core needs a pseries machine");
+        return;
+    }
+
     sc->threads = g_malloc0(size * cc->nr_threads);
     for (i = 0; i < cc->nr_threads; i++) {
         char id[32];
@@ -232,6 +240,16 @@ static void spapr_cpu_core_realize(DeviceState *dev, Error **errp)
         cs = CPU(obj);
         cpu = POWERPC_CPU(cs);
         cs->cpu_index = cc->core_id + i;
+        cpu->vcpu_id = (cc->core_id * spapr->vsmt / smp_threads) + i;
+        if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->vcpu_id)) {
+            error_setg(&local_err, "Can't create CPU with id %d in KVM",
+                       cpu->vcpu_id);
+            error_append_hint(&local_err, "Adjust the number of cpus to %d "
+                              "or try to raise the number of threads per core\n",
+                              cpu->vcpu_id * smp_threads / spapr->vsmt);
+            goto err;
+        }
+
 
         /* Set NUMA node for the threads belonged to core  */
         cpu->node_id = sc->node_id;
@@ -268,31 +286,29 @@ static const char *spapr_core_models[] = {
     "970_v2.2",
 
     /* 970MP variants */
-    "970MP_v1.0",
     "970mp_v1.0",
-    "970MP_v1.1",
     "970mp_v1.1",
 
     /* POWER5+ */
-    "POWER5+_v2.1",
+    "power5+_v2.1",
 
     /* POWER7 */
-    "POWER7_v2.3",
+    "power7_v2.3",
 
     /* POWER7+ */
-    "POWER7+_v2.1",
+    "power7+_v2.1",
 
     /* POWER8 */
-    "POWER8_v2.0",
+    "power8_v2.0",
 
     /* POWER8E */
-    "POWER8E_v2.1",
+    "power8e_v2.1",
 
     /* POWER8NVL */
-    "POWER8NVL_v1.0",
+    "power8nvl_v1.0",
 
     /* POWER9 */
-    "POWER9_v1.0",
+    "power9_v1.0",
 };
 
 static Property spapr_cpu_core_properties[] = {
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 605697d8bd..915e9b51c4 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -460,14 +460,13 @@ static void drc_reset(void *opaque)
     spapr_drc_reset(SPAPR_DR_CONNECTOR(opaque));
 }
 
-static bool spapr_drc_needed(void *opaque)
+bool spapr_drc_needed(void *opaque)
 {
     sPAPRDRConnector *drc = (sPAPRDRConnector *)opaque;
     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);
-    sPAPRDREntitySense value = drck->dr_entity_sense(drc);
 
     /* If no dev is plugged in there is no need to migrate the DRC state */
-    if (value != SPAPR_DR_ENTITY_SENSE_PRESENT) {
+    if (!drc->dev) {
         return false;
     }
 
@@ -493,7 +492,7 @@ static void realize(DeviceState *d, Error **errp)
 {
     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
     Object *root_container;
-    char link_name[256];
+    gchar *link_name;
     gchar *child_name;
     Error *err = NULL;
 
@@ -506,12 +505,13 @@ static void realize(DeviceState *d, Error **errp)
      * existing in the composition tree
      */
     root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
-    snprintf(link_name, sizeof(link_name), "%x", spapr_drc_index(drc));
+    link_name = g_strdup_printf("%x", spapr_drc_index(drc));
     child_name = object_get_canonical_path_component(OBJECT(drc));
     trace_spapr_drc_realize_child(spapr_drc_index(drc), child_name);
     object_property_add_alias(root_container, link_name,
                               drc->owner, child_name, &err);
     g_free(child_name);
+    g_free(link_name);
     if (err) {
         error_propagate(errp, err);
         return;
@@ -526,14 +526,15 @@ static void unrealize(DeviceState *d, Error **errp)
 {
     sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);
     Object *root_container;
-    char name[256];
+    gchar *name;
 
     trace_spapr_drc_unrealize(spapr_drc_index(drc));
     qemu_unregister_reset(drc_reset, drc);
     vmstate_unregister(DEVICE(drc), &vmstate_spapr_drc, drc);
     root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);
-    snprintf(name, sizeof(name), "%x", spapr_drc_index(drc));
+    name = g_strdup_printf("%x", spapr_drc_index(drc));
     object_property_del(root_container, name, errp);
+    g_free(name);
 }
 
 sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
@@ -547,6 +548,7 @@ sPAPRDRConnector *spapr_dr_connector_new(Object *owner, const char *type,
     prop_name = g_strdup_printf("dr-connector[%"PRIu32"]",
                                 spapr_drc_index(drc));
     object_property_add_child(owner, prop_name, OBJECT(drc), &error_abort);
+    object_unref(OBJECT(drc));
     object_property_set_bool(OBJECT(drc), true, "realized", NULL);
     g_free(prop_name);
 
@@ -629,12 +631,28 @@ static void realize_physical(DeviceState *d, Error **errp)
     qemu_register_reset(drc_physical_reset, drcp);
 }
 
+static void unrealize_physical(DeviceState *d, Error **errp)
+{
+    sPAPRDRCPhysical *drcp = SPAPR_DRC_PHYSICAL(d);
+    Error *local_err = NULL;
+
+    unrealize(d, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    vmstate_unregister(DEVICE(drcp), &vmstate_spapr_drc_physical, drcp);
+    qemu_unregister_reset(drc_physical_reset, drcp);
+}
+
 static void spapr_drc_physical_class_init(ObjectClass *k, void *data)
 {
     DeviceClass *dk = DEVICE_CLASS(k);
     sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_CLASS(k);
 
     dk->realize = realize_physical;
+    dk->unrealize = unrealize_physical;
     drck->dr_entity_sense = physical_entity_sense;
     drck->isolate = drc_isolate_physical;
     drck->unisolate = drc_unisolate_physical;
@@ -731,10 +749,11 @@ static const TypeInfo spapr_drc_lmb_info = {
 sPAPRDRConnector *spapr_drc_by_index(uint32_t index)
 {
     Object *obj;
-    char name[256];
+    gchar *name;
 
-    snprintf(name, sizeof(name), "%s/%x", DRC_CONTAINER_PATH, index);
+    name = g_strdup_printf("%s/%x", DRC_CONTAINER_PATH, index);
     obj = object_resolve_path(name, NULL);
+    g_free(name);
 
     return !obj ? NULL : SPAPR_DR_CONNECTOR(obj);
 }
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index f952b78237..66b8164f30 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -700,6 +700,17 @@ static void event_scan(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     rtas_st(rets, 0, RTAS_OUT_NO_ERRORS_FOUND);
 }
 
+void spapr_clear_pending_events(sPAPRMachineState *spapr)
+{
+    sPAPREventLogEntry *entry = NULL;
+
+    QTAILQ_FOREACH(entry, &spapr->pending_events, next) {
+        QTAILQ_REMOVE(&spapr->pending_events, entry, next);
+        g_free(entry->extended_log);
+        g_free(entry);
+    }
+}
+
 void spapr_events_init(sPAPRMachineState *spapr)
 {
     QTAILQ_INIT(&spapr->pending_events);
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 07b3da8dc4..8b3c0e17e7 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -999,7 +999,7 @@ static target_ulong h_register_vpa(PowerPCCPU *cpu, sPAPRMachineState *spapr,
     CPUPPCState *tenv;
     PowerPCCPU *tcpu;
 
-    tcpu = ppc_get_vcpu_by_dt_id(procno);
+    tcpu = spapr_find_cpu(procno);
     if (!tcpu) {
         return H_PARAMETER;
     }
@@ -1431,7 +1431,7 @@ static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
 
     } else {
         /* Unicast */
-        cs = CPU(ppc_get_vcpu_by_dt_id(target));
+        cs = CPU(spapr_find_cpu(target));
         if (cs) {
             run_on_cpu(cs, spapr_do_system_reset_on_cpu, RUN_ON_CPU_NULL);
             return H_SUCCESS;
@@ -1441,7 +1441,8 @@ static target_ulong h_signal_sys_reset(PowerPCCPU *cpu,
 }
 
 static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu,
-                              target_ulong *addr, Error **errp)
+                              target_ulong *addr, bool *raw_mode_supported,
+                              Error **errp)
 {
     bool explicit_match = false; /* Matched the CPU's real PVR */
     uint32_t max_compat = spapr->max_compat_pvr;
@@ -1481,6 +1482,8 @@ static uint32_t cas_check_pvr(sPAPRMachineState *spapr, PowerPCCPU *cpu,
         return 0;
     }
 
+    *raw_mode_supported = explicit_match;
+
     /* Parsing finished */
     trace_spapr_cas_pvr(cpu->compat_pvr, explicit_match, best_compat);
 
@@ -1499,8 +1502,9 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     sPAPROptionVector *ov1_guest, *ov5_guest, *ov5_cas_old, *ov5_updates;
     bool guest_radix;
     Error *local_err = NULL;
+    bool raw_mode_supported = false;
 
-    cas_pvr = cas_check_pvr(spapr, cpu, &addr, &local_err);
+    cas_pvr = cas_check_pvr(spapr, cpu, &addr, &raw_mode_supported, &local_err);
     if (local_err) {
         error_report_err(local_err);
         return H_HARDWARE;
@@ -1510,8 +1514,14 @@ static target_ulong h_client_architecture_support(PowerPCCPU *cpu,
     if (cpu->compat_pvr != cas_pvr) {
         ppc_set_compat_all(cas_pvr, &local_err);
         if (local_err) {
-            error_report_err(local_err);
-            return H_HARDWARE;
+            /* We fail to set compat mode (likely because running with KVM PR),
+             * but maybe we can fallback to raw mode if the guest supports it.
+             */
+            if (!raw_mode_supported) {
+                error_report_err(local_err);
+                return H_HARDWARE;
+            }
+            local_err = NULL;
         }
     }
 
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index ed2d53559a..fa8b969840 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -248,66 +248,59 @@ static const VMStateDescription vmstate_spapr_tce_table = {
     }
 };
 
-static int spapr_tce_table_realize(DeviceState *dev)
+static void spapr_tce_table_realize(DeviceState *dev, Error **errp)
 {
     sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
     Object *tcetobj = OBJECT(tcet);
-    char tmp[32];
+    gchar *tmp;
 
     tcet->fd = -1;
     tcet->need_vfio = false;
-    snprintf(tmp, sizeof(tmp), "tce-root-%x", tcet->liobn);
+    tmp = g_strdup_printf("tce-root-%x", tcet->liobn);
     memory_region_init(&tcet->root, tcetobj, tmp, UINT64_MAX);
+    g_free(tmp);
 
-    snprintf(tmp, sizeof(tmp), "tce-iommu-%x", tcet->liobn);
+    tmp = g_strdup_printf("tce-iommu-%x", tcet->liobn);
     memory_region_init_iommu(&tcet->iommu, sizeof(tcet->iommu),
                              TYPE_SPAPR_IOMMU_MEMORY_REGION,
                              tcetobj, tmp, 0);
+    g_free(tmp);
 
     QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list);
 
     vmstate_register(DEVICE(tcet), tcet->liobn, &vmstate_spapr_tce_table,
                      tcet);
-
-    return 0;
 }
 
 void spapr_tce_set_need_vfio(sPAPRTCETable *tcet, bool need_vfio)
 {
     size_t table_size = tcet->nb_table * sizeof(uint64_t);
-    void *newtable;
+    uint64_t *oldtable;
+    int newfd = -1;
 
-    if (need_vfio == tcet->need_vfio) {
-        /* Nothing to do */
-        return;
-    }
+    g_assert(need_vfio != tcet->need_vfio);
 
-    if (!need_vfio) {
-        /* FIXME: We don't support transition back to KVM accelerated
-         * TCEs yet */
-        return;
-    }
+    tcet->need_vfio = need_vfio;
 
-    tcet->need_vfio = true;
+    oldtable = tcet->table;
 
-    if (tcet->fd < 0) {
-        /* Table is already in userspace, nothing to be do */
-        return;
-    }
-
-    newtable = g_malloc(table_size);
-    memcpy(newtable, tcet->table, table_size);
+    tcet->table = spapr_tce_alloc_table(tcet->liobn,
+                                        tcet->page_shift,
+                                        tcet->bus_offset,
+                                        tcet->nb_table,
+                                        &newfd,
+                                        need_vfio);
+    memcpy(tcet->table, oldtable, table_size);
 
-    kvmppc_remove_spapr_tce(tcet->table, tcet->fd, tcet->nb_table);
+    spapr_tce_free_table(oldtable, tcet->fd, tcet->nb_table);
 
-    tcet->fd = -1;
-    tcet->table = newtable;
+    tcet->fd = newfd;
 }
 
 sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
 {
     sPAPRTCETable *tcet;
-    char tmp[32];
+    gchar *tmp;
 
     if (spapr_tce_find_by_liobn(liobn)) {
         error_report("Attempted to create TCE table with duplicate"
@@ -318,8 +311,10 @@ sPAPRTCETable *spapr_tce_new_table(DeviceState *owner, uint32_t liobn)
     tcet = SPAPR_TCE_TABLE(object_new(TYPE_SPAPR_TCE_TABLE));
     tcet->liobn = liobn;
 
-    snprintf(tmp, sizeof(tmp), "tce-table-%x", liobn);
+    tmp = g_strdup_printf("tce-table-%x", liobn);
     object_property_add_child(OBJECT(owner), tmp, OBJECT(tcet), NULL);
+    g_free(tmp);
+    object_unref(OBJECT(tcet));
 
     object_property_set_bool(OBJECT(tcet), true, "realized", NULL);
 
@@ -372,6 +367,8 @@ static void spapr_tce_table_unrealize(DeviceState *dev, Error **errp)
 {
     sPAPRTCETable *tcet = SPAPR_TCE_TABLE(dev);
 
+    vmstate_unregister(DEVICE(tcet), &vmstate_spapr_tce_table, tcet);
+
     QLIST_REMOVE(tcet, list);
 
     spapr_tce_table_disable(tcet);
@@ -615,7 +612,7 @@ int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
 static void spapr_tce_table_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->init = spapr_tce_table_realize;
+    dc->realize = spapr_tce_table_realize;
     dc->reset = spapr_tce_reset;
     dc->unrealize = spapr_tce_table_unrealize;
     /* Reason: This is just an internal device for handling the hypercalls */
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index d84abf1070..d7880f257a 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -1703,7 +1703,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
     }
 #endif
 
-    memory_region_init_io(&sphb->msiwindow, NULL, &spapr_msi_ops, spapr,
+    memory_region_init_io(&sphb->msiwindow, OBJECT(sphb), &spapr_msi_ops, spapr,
                           "msi", msi_window_size);
     memory_region_add_subregion(&sphb->iommu_root, SPAPR_PCI_MSI_WINDOW,
                                 &sphb->msiwindow);
@@ -1752,8 +1752,8 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp)
                        i, sphb->dtbusname);
             return;
         }
-        memory_region_add_subregion_overlap(&sphb->iommu_root, 0,
-                                            spapr_tce_get_iommu(tcet), 0);
+        memory_region_add_subregion(&sphb->iommu_root, 0,
+                                    spapr_tce_get_iommu(tcet));
     }
 
     sphb->msi = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free);
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 94a2799b99..cdf0b607a0 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -104,7 +104,7 @@ static void rtas_query_cpu_stopped_state(PowerPCCPU *cpu_,
     }
 
     id = rtas_ld(args, 0);
-    cpu = ppc_get_vcpu_by_dt_id(id);
+    cpu = spapr_find_cpu(id);
     if (cpu != NULL) {
         if (CPU(cpu)->halted) {
             rtas_st(rets, 1, 0);
@@ -158,7 +158,7 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
     start = rtas_ld(args, 1);
     r3 = rtas_ld(args, 2);
 
-    cpu = ppc_get_vcpu_by_dt_id(id);
+    cpu = spapr_find_cpu(id);
     if (cpu != NULL) {
         CPUState *cs = CPU(cpu);
         CPUPPCState *env = &cpu->env;
diff --git a/include/hw/i2c/ppc4xx_i2c.h b/include/hw/i2c/ppc4xx_i2c.h
new file mode 100644
index 0000000000..e53042f6d4
--- /dev/null
+++ b/include/hw/i2c/ppc4xx_i2c.h
@@ -0,0 +1,61 @@
+/*
+ * PPC4xx I2C controller emulation
+ *
+ * Copyright (c) 2007 Jocelyn Mayer
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef PPC4XX_I2C_H
+#define PPC4XX_I2C_H
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "hw/sysbus.h"
+#include "hw/i2c/i2c.h"
+
+#define TYPE_PPC4xx_I2C "ppc4xx-i2c"
+#define PPC4xx_I2C(obj) OBJECT_CHECK(PPC4xxI2CState, (obj), TYPE_PPC4xx_I2C)
+
+typedef struct PPC4xxI2CState {
+    /*< private >*/
+    SysBusDevice parent_obj;
+
+    /*< public >*/
+    I2CBus *bus;
+    qemu_irq irq;
+    MemoryRegion iomem;
+    uint8_t mdata;
+    uint8_t lmadr;
+    uint8_t hmadr;
+    uint8_t cntl;
+    uint8_t mdcntl;
+    uint8_t sts;
+    uint8_t extsts;
+    uint8_t sdata;
+    uint8_t lsadr;
+    uint8_t hsadr;
+    uint8_t clkdiv;
+    uint8_t intrmsk;
+    uint8_t xfrcnt;
+    uint8_t xtcntlss;
+    uint8_t directcntl;
+} PPC4xxI2CState;
+
+#endif /* PPC4XX_I2C_H */
diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
index 66e57a5194..cb0bb55cec 100644
--- a/include/hw/ppc/ppc4xx.h
+++ b/include/hw/ppc/ppc4xx.h
@@ -53,6 +53,9 @@ void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
                         hwaddr *ram_sizes,
                         int do_init);
 
+void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
+                     qemu_irq irqs[4]);
+
 #define TYPE_PPC4xx_PCI_HOST_BRIDGE "ppc4xx-pcihost"
 
 #endif /* PPC4XX_H */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 2a303a705c..c1b365f564 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -99,6 +99,7 @@ struct sPAPRMachineState {
     uint64_t rtc_offset; /* Now used only during incoming migration */
     struct PPCTimebase tb;
     bool has_graphics;
+    uint32_t vsmt;       /* Virtual SMT mode (KVM's "core stride") */
 
     Notifier epow_notifier;
     QTAILQ_HEAD(, sPAPREventLogEntry) pending_events;
@@ -662,6 +663,7 @@ void spapr_cpu_parse_features(sPAPRMachineState *spapr);
 int spapr_hpt_shift_for_ramsize(uint64_t ramsize);
 void spapr_reallocate_hpt(sPAPRMachineState *spapr, int shift,
                           Error **errp);
+void spapr_clear_pending_events(sPAPRMachineState *spapr);
 
 /* CPU and LMB DRC release callbacks. */
 void spapr_core_release(DeviceState *dev);
@@ -704,4 +706,7 @@ void spapr_do_system_reset_on_cpu(CPUState *cs, run_on_cpu_data arg);
 
 #define HTAB_SIZE(spapr)        (1ULL << ((spapr)->htab_shift))
 
+int spapr_vcpu_id(PowerPCCPU *cpu);
+PowerPCCPU *spapr_find_cpu(int vcpu_id);
+
 #endif /* HW_SPAPR_H */
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index a7958d0a8d..f8d9f5b231 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -257,6 +257,7 @@ int spapr_drc_populate_dt(void *fdt, int fdt_offset, Object *owner,
 void spapr_drc_attach(sPAPRDRConnector *drc, DeviceState *d, void *fdt,
                       int fdt_start_offset, Error **errp);
 void spapr_drc_detach(sPAPRDRConnector *drc);
+bool spapr_drc_needed(void *opaque);
 
 static inline bool spapr_drc_unplug_requested(sPAPRDRConnector *drc)
 {
diff --git a/scripts/device-crash-test b/scripts/device-crash-test
index 81d65b9617..043b24a4aa 100755
--- a/scripts/device-crash-test
+++ b/scripts/device-crash-test
@@ -160,6 +160,9 @@ ERROR_WHITELIST = [
     {'machine':'q35|pc.*', 'device':'kvm-ioapic', 'expected':True}, # Only 1 ioapics allowed
     {'machine':'q35|pc.*', 'device':'ioapic', 'expected':True},     # Only 1 ioapics allowed
 
+    # "spapr-cpu-core needs a pseries machine"
+    {'machine':'(?!pseries).*', 'device':'.*-spapr-cpu-core', 'expected':True},
+
     # KVM-specific devices shouldn't be tried without accel=kvm:
     {'accel':'(?!kvm).*', 'device':'kvmclock', 'expected':True},
     {'accel':'(?!kvm).*', 'device':'kvm-pci-assign', 'expected':True},
diff --git a/target/ppc/STATUS b/target/ppc/STATUS
deleted file mode 100644
index a4d48a7ca2..0000000000
--- a/target/ppc/STATUS
+++ /dev/null
@@ -1,550 +0,0 @@
-PowerPC emulation status.
-The goal of this file is to provide a reference status to avoid regressions.
-
-===============================================================================
-PowerPC core emulation status
-
-INSN: instruction set.
-      OK => all instructions are emulated
-      KO => some insns are missing or some should be removed
-      ?  => unchecked
-SPR:  special purpose registers set
-      OK => all SPR registered (but some may be fake)
-      KO => some SPR are missing or should be removed
-      ?  => unchecked
-MSR:  MSR bits definitions
-      OK => all MSR bits properly defined
-      KO => MSR definition is incorrect
-      ?  => unchecked
-IRQ:  input signals definitions (mostly interrupts)
-      OK => input signals are properly defined
-      KO => input signals are not implemented (system emulation does not work)
-      ?  => input signals definitions may be incorrect
-MMU:  MMU model implementation
-      OK => MMU model is implemented and Linux is able to boot
-      KO => MMU model not implemented or bugged
-      ?  => MMU model not tested
-EXCP: exceptions model implementation
-      OK => exception model is implemented and Linux is able to boot
-      KO => exception model not implemented or known to be buggy
-      ?  => exception model may be incorrect or is untested
-
-Embedded PowerPC cores
-***
-PowerPC 401:
-INSN  OK
-SPR   OK 401A1
-MSR   OK
-IRQ   KO partially implemented
-MMU   OK
-EXCP  ?
-
-PowerPC 401x2:
-INSN  OK
-SPR   OK 401B2 401C2 401D2 401E2 401F2
-MSR   OK
-IRQ   KO partially implemented
-MMU   OK
-EXCP  ?
-
-PowerPC IOP480:
-INSN  OK
-SPR   OK IOP480
-MSR   OK
-IRQ   KO partially implemented
-MMU   OK
-EXCP  ?
-
-To be checked: 401G2 401B3 Cobra
-
-***
-PowerPC 403:
-INSN  OK
-SPR   OK 403GA 403GB
-MMU   OK
-MSR   OK
-IRQ   KO not implemented
-EXCP  ?
-
-PowerPC 403GCX:
-INSN  OK
-SPR   OK 403GCX
-MMU   OK
-MSR   OK
-IRQ   KO not implemented
-EXCP  ?
-
-To be checked: 403GC
-
-***
-PowerPC 405:
-Checked: 405CRa 405CRb 405CRc 405EP 405GPa 405GPb 405GPc 405GPd 405GPe 405GPR
-         Npe405H Npe405H2 Npe405L
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 boots (at least 1 proprietary firmware).
-         uboot seems to freeze at boot time.
-To be checked: 405D2 405D4 405EZ 405LP Npe4GS3 STB03 STB04 STB25
-               x2vp4 x2vp7 x2vp20 x2vp50
-
-XXX: find what is IBM e407b4
-
-***
-PowerPC 440:
-Checked: 440EPa 440EPb 440GXa 440GXb 440GXc 440GXf 440SP 440SP2
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   KO not implemented
-MMU   ?
-EXCP  ?
-
-PowerPC 440GP:
-Checked: 440GPb 440GPc
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   KO not implemented
-MMU   ?
-EXCP  ?
-
-PowerPC 440x4:
-Checked: 440A4 440B4 440G4 440H4
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   KO not implemented
-MMU   ?
-EXCP  ?
-
-PowerPC 440x5:
-Checked: 440A5 440F5 440G5 440H6 440GRa
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   KO not implemented
-MMU   ?
-EXCP  ?
-
-To be checked: 440EPx 440GRx 440SPE
-
-***
-PowerPC 460: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-PowerPC 460F: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-***
-PowerPC e200: (not implemented)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-***
-PowerPC e300: (not implemented)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-***
-PowerPC e500: (not implemented)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-***
-PowerPC e600: (not implemented)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-***
-32 bits PowerPC
-PowerPC 601: (601 601v2)
-INSN  OK
-SPR   OK is HID15 only on 601v2 ?
-MSR   OK
-IRQ   KO not implemented
-MMU   ?
-EXCP  ?
-Remarks: some instructions should have a specific behavior (not implemented)
-
-PowerPC 602: 602
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   ?
-EXCP  ? at least timer and external interrupt are OK
-Remarks: Linux 2.4 crashes when entering user-mode.
-         Linux 2.6.22 boots on this CPU but does not recognize it.
-
-PowerPC 603: (603)
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU
-         Linux 2.6.22 idem.
-
-PowerPC 603e: (603e11)
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU
-         Linux 2.6.22 idem.
-
-PowerPC G2:
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 boots, recognizes the CPU as a 82xx.
-         Linux 2.6.22 idem.
-
-PowerPC G2le:
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 does not boots. Same symptoms as 602.
-         Linux 2.6.22 boots and properly recognizes the CPU.
-
-PowerPC 604:
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU.
-         Linux 2.6.22 idem.
-
-PowerPC 7x0:
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 boots and properly recognizes the CPU.
-         Linux 2.6.22 idem.
-
-PowerPC 750fx:
-INSN  OK
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  OK
-Remarks: Linux 2.4 boots but does not properly recognizes the CPU.
-         Linux 2.6.22 boots and properly recognizes the CPU.
-
-PowerPC 7x5:
-INSN  ?
-SPR   ?
-MSR   ?
-IRQ   OK
-MMU   ?
-EXCP  OK
-Remarks: Linux 2.4 does not boot.
-         Linux 2.6.22 idem.
-
-PowerPC 7400:
-INSN  KO Altivec missing
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  ?  Altivec, ...
-Remarks: Linux 2.4 boots and properly recognize the CPU.
-         Linux 2.6.22 idem.
-
-PowerPC 7410:
-INSN  KO Altivec missing
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  ?  Altivec, ...
-Remarks: Linux 2.4 boots and properly recognize the CPU.
-         Linux 2.6.22 idem.
-   Note that UM says tlbld & tlbli are implemented but this may be a mistake
-   as TLB loads are managed by the hardware and the CPU does not implement the
-   needed registers.
-
-PowerPC 7441:
-INSN  KO Altivec missing
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  ?  Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
-         Linux 2.6.22 idem.
-
-PowerPC 7450/7451:
-INSN  KO Altivec missing
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  ?  Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
-         Linux 2.6.22 idem.
-
-PowerPC 7445/7447:
-INSN  KO Altivec missing
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  ?  Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
-         Linux 2.6.22 idem.
-
-PowerPC 7455/7457:
-INSN  KO Altivec missing
-SPR   OK
-MSR   OK
-IRQ   OK
-MMU   OK
-EXCP  ?  Altivec, ...
-Remarks: Linux does not have the code to handle TLB miss on this CPU
-         Linux 2.6.22 idem.
-
-64 bits PowerPC
-PowerPC 620: (disabled)
-INSN  KO
-SPR   KO
-MSR   ?
-IRQ   KO
-MMU   KO
-EXCP  KO
-Remarks: not much documentation for this implementation...
-
-PowerPC 970:
-INSN  KO Altivec missing and more
-SPR   KO
-MSR   ?
-IRQ   OK
-MMU   OK
-EXCP  KO partially implemented
-Remarks: Should be able to boot but there is no hw platform currently emulated.
-
-PowerPC 970FX:
-INSN  KO Altivec missing and more
-SPR   KO
-MSR   ?
-IRQ   OK
-MMU   OK
-EXCP  KO partially implemented
-Remarks: Should be able to boot but there is no hw platform currently emulated.
-
-PowerPC Cell:
-INSN  KO Altivec missing and more
-SPR   KO
-MSR   ?
-IRQ   ?
-MMU   ?
-EXCP  ? partially implemented
-Remarks: As the core is mostly a 970, should be able to boot.
-         SPE are not implemented.
-
-PowerPC 630: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-PowerPC 631: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-POWER4: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-POWER4+: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-POWER5: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-POWER5+: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-POWER6: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-RS64: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-RS64-II: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-RS64-III: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-RS64-IV: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-Original POWER
-POWER: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-POWER2: (disabled: lack of detailed specifications)
-INSN  KO
-SPR   KO
-MSR   KO
-IRQ   KO
-MMU   KO
-EXCP  KO
-
-===============================================================================
-PowerPC microcontrollers emulation status
-
-Implemementation should be sufficient to boot Linux:
-(there seem to be problems with uboot freezing at some point)
-- PowerPC 405CR
-- PowerPC 405EP
-
-TODO:
-- PowerPC 401 microcontrollers emulation
-- PowerPC 403 microcontrollers emulation
-- more PowerPC 405 microcontrollers emulation
-- Fixes / more features for implemented PowerPC 405 microcontrollers emulation
-- PowerPC 440 microcontrollers emulation
-- e200 microcontrollers emulation
-- e300 microcontrollers emulation
-- e500 microcontrollers emulation
-- e600 microcontrollers emulation
-
-===============================================================================
-PowerPC based platforms emulation status
-
-* PREP platform (RS/6000 7043...) - TO BE CHECKED (broken)
-- Gentoo Linux live CDROM 1.4
-- Debian Linux 3.0
-- Mandrake Linux 9
-
-* heathrow PowerMac platform (beige PowerMac) - TO BE CHECKED (broken)
-- Gentoo Linux live CDROM 1.4
-- Debian Linux 3.0
-- Mandrake Linux 9
-
-* mac99 platform (white and blue PowerMac, ...)
-- Gentoo Linux live CDROM 1.4 - boots, compiles linux kernel
-- Debian Linux woody - boots from CDROM and HDD
-- Mandrake Linux 9 - boots from CDROM, freezes during install
-- Knoppix 2003-07-13_4 boots from CDROM, pb with X configuration
-  distribution bug: X runs with a properly hand-coded configuration.
-- rock Linux 2.0 runs from CDROM
-
-* Linux 2.6 support seems deadly broken (used to boot...).
-
-* PowerPC 405EP reference boards:
-- can boot Linux 2.4 & 2.6.
-  Need to provide a flash image ready to boot for reproductible tests.
-
-TODO:
-- URGENT: fix PreP and heathrow platforms
-- PowerPC 64 reference platform
-- MCA based RS/6000 emulation
-- CHRP emulation (not PowerMac)
-- PPAR emulation
-- ePPAR emulation
-- misc PowerPC reference boards emulation
-
-===============================================================================
diff --git a/target/ppc/cpu-models.c b/target/ppc/cpu-models.c
index 4d3e6354cf..9626d6b7c4 100644
--- a/target/ppc/cpu-models.c
+++ b/target/ppc/cpu-models.c
@@ -19,11 +19,6 @@
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-/* A lot of PowerPC definition have been included here.
- * Most of them are not usable for now but have been kept
- * inside "#if defined(TODO) ... #endif" statements to make tests easier.
- */
-
 #include "qemu/osdep.h"
 #include "cpu.h"
 #include "cpu-models.h"
@@ -51,7 +46,7 @@
                                                                             \
     static const TypeInfo                                                   \
     glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_type_info) = {         \
-        .name       = _name "-" TYPE_POWERPC_CPU,                           \
+        .name       = POWERPC_CPU_TYPE_NAME(_name),                           \
         .parent     = stringify(_type) "-family-" TYPE_POWERPC_CPU,         \
         .class_init =                                                       \
             glue(POWERPC_DEF_PREFIX(_pvr, _svr, _type), _cpu_class_init),   \
@@ -75,502 +70,199 @@
     POWERPC_DEF("401",           CPU_POWERPC_401,                    401,
                 "Generic PowerPC 401")
     /* PowerPC 401 cores                                                     */
-    POWERPC_DEF("401A1",         CPU_POWERPC_401A1,                  401,
+    POWERPC_DEF("401a1",         CPU_POWERPC_401A1,                  401,
                 "PowerPC 401A1")
-    POWERPC_DEF("401B2",         CPU_POWERPC_401B2,                  401x2,
+    POWERPC_DEF("401b2",         CPU_POWERPC_401B2,                  401x2,
                 "PowerPC 401B2")
-#if defined(TODO)
-    POWERPC_DEF("401B3",         CPU_POWERPC_401B3,                  401x3,
-                "PowerPC 401B3")
-#endif
-    POWERPC_DEF("401C2",         CPU_POWERPC_401C2,                  401x2,
+    POWERPC_DEF("401c2",         CPU_POWERPC_401C2,                  401x2,
                 "PowerPC 401C2")
-    POWERPC_DEF("401D2",         CPU_POWERPC_401D2,                  401x2,
+    POWERPC_DEF("401d2",         CPU_POWERPC_401D2,                  401x2,
                 "PowerPC 401D2")
-    POWERPC_DEF("401E2",         CPU_POWERPC_401E2,                  401x2,
+    POWERPC_DEF("401e2",         CPU_POWERPC_401E2,                  401x2,
                 "PowerPC 401E2")
-    POWERPC_DEF("401F2",         CPU_POWERPC_401F2,                  401x2,
+    POWERPC_DEF("401f2",         CPU_POWERPC_401F2,                  401x2,
                 "PowerPC 401F2")
     /* XXX: to be checked */
-    POWERPC_DEF("401G2",         CPU_POWERPC_401G2,                  401x2,
+    POWERPC_DEF("401g2",         CPU_POWERPC_401G2,                  401x2,
                 "PowerPC 401G2")
     /* PowerPC 401 microcontrollers                                          */
-#if defined(TODO)
-    POWERPC_DEF("401GF",         CPU_POWERPC_401GF,                  401,
-                "PowerPC 401GF")
-#endif
-    POWERPC_DEF("IOP480",        CPU_POWERPC_IOP480,                 IOP480,
+    POWERPC_DEF("iop480",        CPU_POWERPC_IOP480,                 IOP480,
                 "IOP480 (401 microcontroller)")
-    POWERPC_DEF("Cobra",         CPU_POWERPC_COBRA,                  401,
+    POWERPC_DEF("cobra",         CPU_POWERPC_COBRA,                  401,
                 "IBM Processor for Network Resources")
-#if defined(TODO)
-    POWERPC_DEF("Xipchip",       CPU_POWERPC_XIPCHIP,                401,
-                NULL)
-#endif
     /* PowerPC 403 family                                                    */
     /* PowerPC 403 microcontrollers                                          */
-    POWERPC_DEF("403GA",         CPU_POWERPC_403GA,                  403,
+    POWERPC_DEF("403ga",         CPU_POWERPC_403GA,                  403,
                 "PowerPC 403 GA")
-    POWERPC_DEF("403GB",         CPU_POWERPC_403GB,                  403,
+    POWERPC_DEF("403gb",         CPU_POWERPC_403GB,                  403,
                 "PowerPC 403 GB")
-    POWERPC_DEF("403GC",         CPU_POWERPC_403GC,                  403,
+    POWERPC_DEF("403gc",         CPU_POWERPC_403GC,                  403,
                 "PowerPC 403 GC")
-    POWERPC_DEF("403GCX",        CPU_POWERPC_403GCX,                 403GCX,
+    POWERPC_DEF("403gcx",        CPU_POWERPC_403GCX,                 403GCX,
                 "PowerPC 403 GCX")
-#if defined(TODO)
-    POWERPC_DEF("403GP",         CPU_POWERPC_403GP,                  403,
-                "PowerPC 403 GP")
-#endif
     /* PowerPC 405 family                                                    */
     /* PowerPC 405 cores                                                     */
-#if defined(TODO)
-    POWERPC_DEF("405A3",         CPU_POWERPC_405A3,                  405,
-                "PowerPC 405 A3")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405A4",         CPU_POWERPC_405A4,                  405,
-                "PowerPC 405 A4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405B3",         CPU_POWERPC_405B3,                  405,
-                "PowerPC 405 B3")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405B4",         CPU_POWERPC_405B4,                  405,
-                "PowerPC 405 B4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405C3",         CPU_POWERPC_405C3,                  405,
-                "PowerPC 405 C3")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405C4",         CPU_POWERPC_405C4,                  405,
-                "PowerPC 405 C4")
-#endif
-    POWERPC_DEF("405D2",         CPU_POWERPC_405D2,                  405,
+    POWERPC_DEF("405d2",         CPU_POWERPC_405D2,                  405,
                 "PowerPC 405 D2")
-#if defined(TODO)
-    POWERPC_DEF("405D3",         CPU_POWERPC_405D3,                  405,
-                "PowerPC 405 D3")
-#endif
-    POWERPC_DEF("405D4",         CPU_POWERPC_405D4,                  405,
+    POWERPC_DEF("405d4",         CPU_POWERPC_405D4,                  405,
                 "PowerPC 405 D4")
-#if defined(TODO)
-    POWERPC_DEF("405D5",         CPU_POWERPC_405D5,                  405,
-                "PowerPC 405 D5")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405E4",         CPU_POWERPC_405E4,                  405,
-                "PowerPC 405 E4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405F4",         CPU_POWERPC_405F4,                  405,
-                "PowerPC 405 F4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405F5",         CPU_POWERPC_405F5,                  405,
-                "PowerPC 405 F5")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405F6",         CPU_POWERPC_405F6,                  405,
-                "PowerPC 405 F6")
-#endif
     /* PowerPC 405 microcontrollers                                          */
-    POWERPC_DEF("405CRa",        CPU_POWERPC_405CRa,                 405,
+    POWERPC_DEF("405cra",        CPU_POWERPC_405CRa,                 405,
                 "PowerPC 405 CRa")
-    POWERPC_DEF("405CRb",        CPU_POWERPC_405CRb,                 405,
+    POWERPC_DEF("405crb",        CPU_POWERPC_405CRb,                 405,
                 "PowerPC 405 CRb")
-    POWERPC_DEF("405CRc",        CPU_POWERPC_405CRc,                 405,
+    POWERPC_DEF("405crc",        CPU_POWERPC_405CRc,                 405,
                 "PowerPC 405 CRc")
-    POWERPC_DEF("405EP",         CPU_POWERPC_405EP,                  405,
+    POWERPC_DEF("405ep",         CPU_POWERPC_405EP,                  405,
                 "PowerPC 405 EP")
-#if defined(TODO)
-    POWERPC_DEF("405EXr",        CPU_POWERPC_405EXr,                 405,
-                "PowerPC 405 EXr")
-#endif
-    POWERPC_DEF("405EZ",         CPU_POWERPC_405EZ,                  405,
+    POWERPC_DEF("405ez",         CPU_POWERPC_405EZ,                  405,
                 "PowerPC 405 EZ")
-#if defined(TODO)
-    POWERPC_DEF("405FX",         CPU_POWERPC_405FX,                  405,
-                "PowerPC 405 FX")
-#endif
-    POWERPC_DEF("405GPa",        CPU_POWERPC_405GPa,                 405,
+    POWERPC_DEF("405gpa",        CPU_POWERPC_405GPa,                 405,
                 "PowerPC 405 GPa")
-    POWERPC_DEF("405GPb",        CPU_POWERPC_405GPb,                 405,
+    POWERPC_DEF("405gpb",        CPU_POWERPC_405GPb,                 405,
                 "PowerPC 405 GPb")
-    POWERPC_DEF("405GPc",        CPU_POWERPC_405GPc,                 405,
+    POWERPC_DEF("405gpc",        CPU_POWERPC_405GPc,                 405,
                 "PowerPC 405 GPc")
-    POWERPC_DEF("405GPd",        CPU_POWERPC_405GPd,                 405,
+    POWERPC_DEF("405gpd",        CPU_POWERPC_405GPd,                 405,
                 "PowerPC 405 GPd")
-    POWERPC_DEF("405GPR",        CPU_POWERPC_405GPR,                 405,
+    POWERPC_DEF("405gpr",        CPU_POWERPC_405GPR,                 405,
                 "PowerPC 405 GPR")
-#if defined(TODO)
-    POWERPC_DEF("405H",          CPU_POWERPC_405H,                   405,
-                "PowerPC 405 H")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405L",          CPU_POWERPC_405L,                   405,
-                "PowerPC 405 L")
-#endif
-    POWERPC_DEF("405LP",         CPU_POWERPC_405LP,                  405,
+    POWERPC_DEF("405lp",         CPU_POWERPC_405LP,                  405,
                 "PowerPC 405 LP")
-#if defined(TODO)
-    POWERPC_DEF("405PM",         CPU_POWERPC_405PM,                  405,
-                "PowerPC 405 PM")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405PS",         CPU_POWERPC_405PS,                  405,
-                "PowerPC 405 PS")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("405S",          CPU_POWERPC_405S,                   405,
-                "PowerPC 405 S")
-#endif
-    POWERPC_DEF("Npe405H",       CPU_POWERPC_NPE405H,                405,
+    POWERPC_DEF("npe405h",       CPU_POWERPC_NPE405H,                405,
                 "Npe405 H")
-    POWERPC_DEF("Npe405H2",      CPU_POWERPC_NPE405H2,               405,
+    POWERPC_DEF("npe405h2",      CPU_POWERPC_NPE405H2,               405,
                 "Npe405 H2")
-    POWERPC_DEF("Npe405L",       CPU_POWERPC_NPE405L,                405,
+    POWERPC_DEF("npe405l",       CPU_POWERPC_NPE405L,                405,
                 "Npe405 L")
-    POWERPC_DEF("Npe4GS3",       CPU_POWERPC_NPE4GS3,                405,
+    POWERPC_DEF("npe4gs3",       CPU_POWERPC_NPE4GS3,                405,
                 "Npe4GS3")
-#if defined(TODO)
-    POWERPC_DEF("Npcxx1",        CPU_POWERPC_NPCxx1,                 405,
-                NULL)
-#endif
-#if defined(TODO)
-    POWERPC_DEF("Npr161",        CPU_POWERPC_NPR161,                 405,
-                NULL)
-#endif
-#if defined(TODO)
-    POWERPC_DEF("LC77700",       CPU_POWERPC_LC77700,                405,
-                "PowerPC LC77700 (Sanyo)")
-#endif
     /* PowerPC 401/403/405 based set-top-box microcontrollers                */
-#if defined(TODO)
-    POWERPC_DEF("STB01000",      CPU_POWERPC_STB01000,               401x2,
-                "STB010000")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("STB01010",      CPU_POWERPC_STB01010,               401x2,
-                "STB01010")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("STB0210",       CPU_POWERPC_STB0210,                401x3,
-                "STB0210")
-#endif
-    POWERPC_DEF("STB03",         CPU_POWERPC_STB03,                  405,
+    POWERPC_DEF("stb03",         CPU_POWERPC_STB03,                  405,
                 "STB03xx")
-#if defined(TODO)
-    POWERPC_DEF("STB043",        CPU_POWERPC_STB043,                 405,
-                "STB043x")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("STB045",        CPU_POWERPC_STB045,                 405,
-                "STB045x")
-#endif
-    POWERPC_DEF("STB04",         CPU_POWERPC_STB04,                  405,
+    POWERPC_DEF("stb04",         CPU_POWERPC_STB04,                  405,
                 "STB04xx")
-    POWERPC_DEF("STB25",         CPU_POWERPC_STB25,                  405,
+    POWERPC_DEF("stb25",         CPU_POWERPC_STB25,                  405,
                 "STB25xx")
-#if defined(TODO)
-    POWERPC_DEF("STB130",        CPU_POWERPC_STB130,                 405,
-                "STB130")
-#endif
     /* Xilinx PowerPC 405 cores                                              */
     POWERPC_DEF("x2vp4",         CPU_POWERPC_X2VP4,                  405,
                 NULL)
     POWERPC_DEF("x2vp20",        CPU_POWERPC_X2VP20,                 405,
                 NULL)
-#if defined(TODO)
-    POWERPC_DEF("zl10310",       CPU_POWERPC_ZL10310,                405,
-                "Zarlink ZL10310")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("zl10311",       CPU_POWERPC_ZL10311,                405,
-                "Zarlink ZL10311")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("zl10320",       CPU_POWERPC_ZL10320,                405,
-                "Zarlink ZL10320")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("zl10321",       CPU_POWERPC_ZL10321,                405,
-                "Zarlink ZL10321")
-#endif
     /* PowerPC 440 family                                                    */
 #if defined(TODO_USER_ONLY)
     POWERPC_DEF("440",           CPU_POWERPC_440,                    440GP,
                 "Generic PowerPC 440")
 #endif
     /* PowerPC 440 cores                                                     */
-#if defined(TODO)
-    POWERPC_DEF("440A4",         CPU_POWERPC_440A4,                  440x4,
-                "PowerPC 440 A4")
-#endif
-    POWERPC_DEF("440-Xilinx",    CPU_POWERPC_440_XILINX,             440x5,
+    POWERPC_DEF("440-xilinx",    CPU_POWERPC_440_XILINX,             440x5,
                 "PowerPC 440 Xilinx 5")
 
-    POWERPC_DEF("440-Xilinx-w-dfpu",    CPU_POWERPC_440_XILINX, 440x5wDFPU,
+    POWERPC_DEF("440-xilinx-w-dfpu",    CPU_POWERPC_440_XILINX, 440x5wDFPU,
                 "PowerPC 440 Xilinx 5 With a Double Prec. FPU")
-#if defined(TODO)
-    POWERPC_DEF("440A5",         CPU_POWERPC_440A5,                  440x5,
-                "PowerPC 440 A5")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("440B4",         CPU_POWERPC_440B4,                  440x4,
-                "PowerPC 440 B4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("440G4",         CPU_POWERPC_440G4,                  440x4,
-                "PowerPC 440 G4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("440F5",         CPU_POWERPC_440F5,                  440x5,
-                "PowerPC 440 F5")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("440G5",         CPU_POWERPC_440G5,                  440x5,
-                "PowerPC 440 G5")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("440H4",         CPU_POWERPC_440H4,                  440x4,
-                "PowerPC 440H4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("440H6",         CPU_POWERPC_440H6,                  440Gx5,
-                "PowerPC 440H6")
-#endif
     /* PowerPC 440 microcontrollers                                          */
-    POWERPC_DEF("440EPa",        CPU_POWERPC_440EPa,                 440EP,
+    POWERPC_DEF("440epa",        CPU_POWERPC_440EPa,                 440EP,
                 "PowerPC 440 EPa")
-    POWERPC_DEF("440EPb",        CPU_POWERPC_440EPb,                 440EP,
+    POWERPC_DEF("440epb",        CPU_POWERPC_440EPb,                 440EP,
                 "PowerPC 440 EPb")
-    POWERPC_DEF("440EPX",        CPU_POWERPC_440EPX,                 440EP,
+    POWERPC_DEF("440epx",        CPU_POWERPC_440EPX,                 440EP,
                 "PowerPC 440 EPX")
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GPb",        CPU_POWERPC_440GPb,                 440GP,
+    POWERPC_DEF("440gpb",        CPU_POWERPC_440GPb,                 440GP,
                 "PowerPC 440 GPb")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GPc",        CPU_POWERPC_440GPc,                 440GP,
+    POWERPC_DEF("440gpc",        CPU_POWERPC_440GPc,                 440GP,
                 "PowerPC 440 GPc")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GRa",        CPU_POWERPC_440GRa,                 440x5,
+    POWERPC_DEF("440gra",        CPU_POWERPC_440GRa,                 440x5,
                 "PowerPC 440 GRa")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GRX",        CPU_POWERPC_440GRX,                 440x5,
+    POWERPC_DEF("440grx",        CPU_POWERPC_440GRX,                 440x5,
                 "PowerPC 440 GRX")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GXa",        CPU_POWERPC_440GXa,                 440EP,
+    POWERPC_DEF("440gxa",        CPU_POWERPC_440GXa,                 440EP,
                 "PowerPC 440 GXa")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GXb",        CPU_POWERPC_440GXb,                 440EP,
+    POWERPC_DEF("440gxb",        CPU_POWERPC_440GXb,                 440EP,
                 "PowerPC 440 GXb")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GXc",        CPU_POWERPC_440GXc,                 440EP,
+    POWERPC_DEF("440gxc",        CPU_POWERPC_440GXc,                 440EP,
                 "PowerPC 440 GXc")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440GXf",        CPU_POWERPC_440GXf,                 440EP,
+    POWERPC_DEF("440gxf",        CPU_POWERPC_440GXf,                 440EP,
                 "PowerPC 440 GXf")
 #endif
-#if defined(TODO)
-    POWERPC_DEF("440S",          CPU_POWERPC_440S,                   440,
-                "PowerPC 440 S")
-#endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440SP",         CPU_POWERPC_440SP,                  440EP,
+    POWERPC_DEF("440sp",         CPU_POWERPC_440SP,                  440EP,
                 "PowerPC 440 SP")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440SP2",        CPU_POWERPC_440SP2,                 440EP,
+    POWERPC_DEF("440sp2",        CPU_POWERPC_440SP2,                 440EP,
                 "PowerPC 440 SP2")
 #endif
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("440SPE",        CPU_POWERPC_440SPE,                 440EP,
+    POWERPC_DEF("440spe",        CPU_POWERPC_440SPE,                 440EP,
                 "PowerPC 440 SPE")
 #endif
-    /* PowerPC 460 family                                                    */
-#if defined(TODO)
-    POWERPC_DEF("464",           CPU_POWERPC_464,                    460,
-                "Generic PowerPC 464")
-#endif
-    /* PowerPC 464 microcontrollers                                          */
-#if defined(TODO)
-    POWERPC_DEF("464H90",        CPU_POWERPC_464H90,                 460,
-                "PowerPC 464H90")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("464H90F",       CPU_POWERPC_464H90F,                460F,
-                "PowerPC 464H90F")
-#endif
     /* Freescale embedded PowerPC cores                                      */
     /* MPC5xx family (aka RCPU)                                              */
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("MPC5xx",        CPU_POWERPC_MPC5xx,                 MPC5xx,
+    POWERPC_DEF("mpc5xx",        CPU_POWERPC_MPC5xx,                 MPC5xx,
                 "Generic MPC5xx core")
 #endif
     /* MPC8xx family (aka PowerQUICC)                                        */
 #if defined(TODO_USER_ONLY)
-    POWERPC_DEF("MPC8xx",        CPU_POWERPC_MPC8xx,                 MPC8xx,
+    POWERPC_DEF("mpc8xx",        CPU_POWERPC_MPC8xx,                 MPC8xx,
                 "Generic MPC8xx core")
 #endif
     /* MPC82xx family (aka PowerQUICC-II)                                    */
-    POWERPC_DEF("G2",            CPU_POWERPC_G2,                     G2,
+    POWERPC_DEF("g2",            CPU_POWERPC_G2,                     G2,
                 "PowerPC G2 core")
-    POWERPC_DEF("G2H4",          CPU_POWERPC_G2H4,                   G2,
+    POWERPC_DEF("g2h4",          CPU_POWERPC_G2H4,                   G2,
                 "PowerPC G2 H4 core")
-    POWERPC_DEF("G2GP",          CPU_POWERPC_G2gp,                   G2,
+    POWERPC_DEF("g2gp",          CPU_POWERPC_G2gp,                   G2,
                 "PowerPC G2 GP core")
-    POWERPC_DEF("G2LS",          CPU_POWERPC_G2ls,                   G2,
+    POWERPC_DEF("g2ls",          CPU_POWERPC_G2ls,                   G2,
                 "PowerPC G2 LS core")
-    POWERPC_DEF("G2HiP3",        CPU_POWERPC_G2_HIP3,                G2,
+    POWERPC_DEF("g2hip3",        CPU_POWERPC_G2_HIP3,                G2,
                 "PowerPC G2 HiP3 core")
-    POWERPC_DEF("G2HiP4",        CPU_POWERPC_G2_HIP4,                G2,
+    POWERPC_DEF("g2hip4",        CPU_POWERPC_G2_HIP4,                G2,
                 "PowerPC G2 HiP4 core")
-    POWERPC_DEF("MPC603",        CPU_POWERPC_MPC603,                 603E,
+    POWERPC_DEF("mpc603",        CPU_POWERPC_MPC603,                 603E,
                 "PowerPC MPC603 core")
-    POWERPC_DEF("G2le",          CPU_POWERPC_G2LE,                   G2LE,
+    POWERPC_DEF("g2le",          CPU_POWERPC_G2LE,                   G2LE,
         "PowerPC G2le core (same as G2 plus little-endian mode support)")
-    POWERPC_DEF("G2leGP",        CPU_POWERPC_G2LEgp,                 G2LE,
+    POWERPC_DEF("g2legp",        CPU_POWERPC_G2LEgp,                 G2LE,
                 "PowerPC G2LE GP core")
-    POWERPC_DEF("G2leLS",        CPU_POWERPC_G2LEls,                 G2LE,
+    POWERPC_DEF("g2lels",        CPU_POWERPC_G2LEls,                 G2LE,
                 "PowerPC G2LE LS core")
-    POWERPC_DEF("G2leGP1",       CPU_POWERPC_G2LEgp1,                G2LE,
+    POWERPC_DEF("g2legp1",       CPU_POWERPC_G2LEgp1,                G2LE,
                 "PowerPC G2LE GP1 core")
-    POWERPC_DEF("G2leGP3",       CPU_POWERPC_G2LEgp3,                G2LE,
+    POWERPC_DEF("g2legp3",       CPU_POWERPC_G2LEgp3,                G2LE,
                 "PowerPC G2LE GP3 core")
     /* PowerPC G2 microcontrollers                                           */
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5121", "MPC5121",
-                    CPU_POWERPC_MPC5121,      POWERPC_SVR_5121,      G2LE)
-#endif
-    POWERPC_DEF_SVR("MPC5200_v10", "MPC5200 v1.0",
+    POWERPC_DEF_SVR("mpc5200_v10", "MPC5200 v1.0",
                     CPU_POWERPC_MPC5200_v10,  POWERPC_SVR_5200_v10,  G2LE)
-    POWERPC_DEF_SVR("MPC5200_v11", "MPC5200 v1.1",
+    POWERPC_DEF_SVR("mpc5200_v11", "MPC5200 v1.1",
                     CPU_POWERPC_MPC5200_v11,  POWERPC_SVR_5200_v11,  G2LE)
-    POWERPC_DEF_SVR("MPC5200_v12", "MPC5200 v1.2",
+    POWERPC_DEF_SVR("mpc5200_v12", "MPC5200 v1.2",
                     CPU_POWERPC_MPC5200_v12,  POWERPC_SVR_5200_v12,  G2LE)
-    POWERPC_DEF_SVR("MPC5200B_v20", "MPC5200B v2.0",
+    POWERPC_DEF_SVR("mpc5200b_v20", "MPC5200B v2.0",
                     CPU_POWERPC_MPC5200B_v20, POWERPC_SVR_5200B_v20, G2LE)
-    POWERPC_DEF_SVR("MPC5200B_v21", "MPC5200B v2.1",
+    POWERPC_DEF_SVR("mpc5200b_v21", "MPC5200B v2.1",
                     CPU_POWERPC_MPC5200B_v21, POWERPC_SVR_5200B_v21, G2LE)
     /* e200 family                                                           */
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC55xx", "Generic MPC55xx core",
-                    CPU_POWERPC_MPC55xx,      POWERPC_SVR_55xx,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF("e200z0",        CPU_POWERPC_e200z0,                 e200,
-                "PowerPC e200z0 core")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("e200z1",        CPU_POWERPC_e200z1,                 e200,
-                "PowerPC e200z1 core")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("e200z3",        CPU_POWERPC_e200z3,                 e200,
-                "PowerPC e200z3 core")
-#endif
     POWERPC_DEF("e200z5",        CPU_POWERPC_e200z5,                 e200,
                 "PowerPC e200z5 core")
     POWERPC_DEF("e200z6",        CPU_POWERPC_e200z6,                 e200,
                 "PowerPC e200z6 core")
-    /* PowerPC e200 microcontrollers                                         */
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5514E", "MPC5514E",
-                    CPU_POWERPC_MPC5514E,     POWERPC_SVR_5514E,     e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5514E_v0", "MPC5514E v0",
-                    CPU_POWERPC_MPC5514E_v0,  POWERPC_SVR_5514E_v0,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5514E_v1", "MPC5514E v1",
-                    CPU_POWERPC_MPC5514E_v1,  POWERPC_SVR_5514E_v1,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5514G", "MPC5514G",
-                    CPU_POWERPC_MPC5514G,     POWERPC_SVR_5514G,     e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5514G_v0", "MPC5514G v0",
-                    CPU_POWERPC_MPC5514G_v0,  POWERPC_SVR_5514G_v0,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5514G_v1", "MPC5514G v1",
-                    CPU_POWERPC_MPC5514G_v1,  POWERPC_SVR_5514G_v1,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5515S", "MPC5515S",
-                    CPU_POWERPC_MPC5515S,     POWERPC_SVR_5515S,     e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5516E", "MPC5516E",
-                    CPU_POWERPC_MPC5516E,     POWERPC_SVR_5516E,     e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5516E_v0", "MPC5516E v0",
-                    CPU_POWERPC_MPC5516E_v0,  POWERPC_SVR_5516E_v0,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5516E_v1", "MPC5516E v1",
-                    CPU_POWERPC_MPC5516E_v1,  POWERPC_SVR_5516E_v1,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5516G", "MPC5516G",
-                    CPU_POWERPC_MPC5516G,     POWERPC_SVR_5516G,     e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5516G_v0", "MPC5516G v0",
-                    CPU_POWERPC_MPC5516G_v0,  POWERPC_SVR_5516G_v0,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5516G_v1", "MPC5516G v1",
-                    CPU_POWERPC_MPC5516G_v1,  POWERPC_SVR_5516G_v1,  e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5516S", "MPC5516S",
-                    CPU_POWERPC_MPC5516S,     POWERPC_SVR_5516S,     e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5533", "MPC5533",
-                    CPU_POWERPC_MPC5533,      POWERPC_SVR_5533,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5534", "MPC5534",
-                    CPU_POWERPC_MPC5534,      POWERPC_SVR_5534,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5553", "MPC5553",
-                    CPU_POWERPC_MPC5553,      POWERPC_SVR_5553,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5554", "MPC5554",
-                    CPU_POWERPC_MPC5554,      POWERPC_SVR_5554,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5561", "MPC5561",
-                    CPU_POWERPC_MPC5561,      POWERPC_SVR_5561,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5565", "MPC5565",
-                    CPU_POWERPC_MPC5565,      POWERPC_SVR_5565,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5566", "MPC5566",
-                    CPU_POWERPC_MPC5566,      POWERPC_SVR_5566,      e200)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC5567", "MPC5567",
-                    CPU_POWERPC_MPC5567,      POWERPC_SVR_5567,      e200)
-#endif
     /* e300 family                                                           */
     POWERPC_DEF("e300c1",        CPU_POWERPC_e300c1,                 e300,
                 "PowerPC e300c1 core")
@@ -581,97 +273,49 @@
     POWERPC_DEF("e300c4",        CPU_POWERPC_e300c4,                 e300,
                 "PowerPC e300c4 core")
     /* PowerPC e300 microcontrollers                                         */
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8313", "MPC8313",
-                    CPU_POWERPC_MPC831x,      POWERPC_SVR_8313,      e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8313E", "MPC8313E",
-                    CPU_POWERPC_MPC831x,      POWERPC_SVR_8313E,     e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8314", "MPC8314",
-                    CPU_POWERPC_MPC831x,      POWERPC_SVR_8314,      e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8314E", "MPC8314E",
-                    CPU_POWERPC_MPC831x,      POWERPC_SVR_8314E,     e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8315", "MPC8315",
-                    CPU_POWERPC_MPC831x,      POWERPC_SVR_8315,      e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8315E", "MPC8315E",
-                    CPU_POWERPC_MPC831x,      POWERPC_SVR_8315E,     e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8321", "MPC8321",
-                    CPU_POWERPC_MPC832x,      POWERPC_SVR_8321,      e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8321E", "MPC8321E",
-                    CPU_POWERPC_MPC832x,      POWERPC_SVR_8321E,     e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8323", "MPC8323",
-                    CPU_POWERPC_MPC832x,      POWERPC_SVR_8323,      e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8323E", "MPC8323E",
-                    CPU_POWERPC_MPC832x,      POWERPC_SVR_8323E,     e300)
-#endif
-    POWERPC_DEF_SVR("MPC8343", "MPC8343",
+    POWERPC_DEF_SVR("mpc8343", "MPC8343",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8343,      e300)
-    POWERPC_DEF_SVR("MPC8343A", "MPC8343A",
+    POWERPC_DEF_SVR("mpc8343a", "MPC8343A",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8343A,     e300)
-    POWERPC_DEF_SVR("MPC8343E", "MPC8343E",
+    POWERPC_DEF_SVR("mpc8343e", "MPC8343E",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8343E,     e300)
-    POWERPC_DEF_SVR("MPC8343EA", "MPC8343EA",
+    POWERPC_DEF_SVR("mpc8343ea", "MPC8343EA",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8343EA,    e300)
-    POWERPC_DEF_SVR("MPC8347T", "MPC8347T",
+    POWERPC_DEF_SVR("mpc8347t", "MPC8347T",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347T,     e300)
-    POWERPC_DEF_SVR("MPC8347P", "MPC8347P",
+    POWERPC_DEF_SVR("mpc8347p", "MPC8347P",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347P,     e300)
-    POWERPC_DEF_SVR("MPC8347AT", "MPC8347AT",
+    POWERPC_DEF_SVR("mpc8347at", "MPC8347AT",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347AT,    e300)
-    POWERPC_DEF_SVR("MPC8347AP", "MPC8347AP",
+    POWERPC_DEF_SVR("mpc8347ap", "MPC8347AP",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347AP,    e300)
-    POWERPC_DEF_SVR("MPC8347ET", "MPC8347ET",
+    POWERPC_DEF_SVR("mpc8347et", "MPC8347ET",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347ET,    e300)
-    POWERPC_DEF_SVR("MPC8347EP", "MPC8343EP",
+    POWERPC_DEF_SVR("mpc8347ep", "MPC8343EP",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347EP,    e300)
-    POWERPC_DEF_SVR("MPC8347EAT", "MPC8347EAT",
+    POWERPC_DEF_SVR("mpc8347eat", "MPC8347EAT",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347EAT,   e300)
-    POWERPC_DEF_SVR("MPC8347EAP", "MPC8343EAP",
+    POWERPC_DEF_SVR("mpc8347eap", "MPC8343EAP",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8347EAP,   e300)
-    POWERPC_DEF_SVR("MPC8349", "MPC8349",
+    POWERPC_DEF_SVR("mpc8349", "MPC8349",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8349,      e300)
-    POWERPC_DEF_SVR("MPC8349A", "MPC8349A",
+    POWERPC_DEF_SVR("mpc8349a", "MPC8349A",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8349A,     e300)
-    POWERPC_DEF_SVR("MPC8349E", "MPC8349E",
+    POWERPC_DEF_SVR("mpc8349e", "MPC8349E",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8349E,     e300)
-    POWERPC_DEF_SVR("MPC8349EA", "MPC8349EA",
+    POWERPC_DEF_SVR("mpc8349ea", "MPC8349EA",
                     CPU_POWERPC_MPC834x,      POWERPC_SVR_8349EA,    e300)
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8358E", "MPC8358E",
-                    CPU_POWERPC_MPC835x,      POWERPC_SVR_8358E,     e300)
-#endif
-#if defined(TODO)
-    POWERPC_DEF_SVR("MPC8360E", "MPC8360E",
-                    CPU_POWERPC_MPC836x,      POWERPC_SVR_8360E,     e300)
-#endif
-    POWERPC_DEF_SVR("MPC8377", "MPC8377",
+    POWERPC_DEF_SVR("mpc8377", "MPC8377",
                     CPU_POWERPC_MPC837x,      POWERPC_SVR_8377,      e300)
-    POWERPC_DEF_SVR("MPC8377E", "MPC8377E",
+    POWERPC_DEF_SVR("mpc8377e", "MPC8377E",
                     CPU_POWERPC_MPC837x,      POWERPC_SVR_8377E,     e300)
-    POWERPC_DEF_SVR("MPC8378", "MPC8378",
+    POWERPC_DEF_SVR("mpc8378", "MPC8378",
                     CPU_POWERPC_MPC837x,      POWERPC_SVR_8378,      e300)
-    POWERPC_DEF_SVR("MPC8378E", "MPC8378E",
+    POWERPC_DEF_SVR("mpc8378e", "MPC8378E",
                     CPU_POWERPC_MPC837x,      POWERPC_SVR_8378E,     e300)
-    POWERPC_DEF_SVR("MPC8379", "MPC8379",
+    POWERPC_DEF_SVR("mpc8379", "MPC8379",
                     CPU_POWERPC_MPC837x,      POWERPC_SVR_8379,      e300)
-    POWERPC_DEF_SVR("MPC8379E", "MPC8379E",
+    POWERPC_DEF_SVR("mpc8379e", "MPC8379E",
                     CPU_POWERPC_MPC837x,      POWERPC_SVR_8379E,     e300)
     /* e500 family                                                           */
     POWERPC_DEF_SVR("e500_v10", "PowerPC e500 v1.0 core",
@@ -693,117 +337,119 @@
 #ifdef TARGET_PPC64
     POWERPC_DEF_SVR("e5500", "e5500",
                     CPU_POWERPC_e5500,        POWERPC_SVR_E500,      e5500)
+    POWERPC_DEF_SVR("e6500", "e6500",
+                    CPU_POWERPC_e6500,        POWERPC_SVR_E500,      e6500)
 #endif
     /* PowerPC e500 microcontrollers                                         */
-    POWERPC_DEF_SVR("MPC8533_v10", "MPC8533 v1.0",
+    POWERPC_DEF_SVR("mpc8533_v10", "MPC8533 v1.0",
                     CPU_POWERPC_MPC8533_v10,  POWERPC_SVR_8533_v10,  e500v2)
-    POWERPC_DEF_SVR("MPC8533_v11", "MPC8533 v1.1",
+    POWERPC_DEF_SVR("mpc8533_v11", "MPC8533 v1.1",
                     CPU_POWERPC_MPC8533_v11,  POWERPC_SVR_8533_v11,  e500v2)
-    POWERPC_DEF_SVR("MPC8533E_v10", "MPC8533E v1.0",
+    POWERPC_DEF_SVR("mpc8533e_v10", "MPC8533E v1.0",
                     CPU_POWERPC_MPC8533E_v10, POWERPC_SVR_8533E_v10, e500v2)
-    POWERPC_DEF_SVR("MPC8533E_v11", "MPC8533E v1.1",
+    POWERPC_DEF_SVR("mpc8533e_v11", "MPC8533E v1.1",
                     CPU_POWERPC_MPC8533E_v11, POWERPC_SVR_8533E_v11, e500v2)
-    POWERPC_DEF_SVR("MPC8540_v10", "MPC8540 v1.0",
+    POWERPC_DEF_SVR("mpc8540_v10", "MPC8540 v1.0",
                     CPU_POWERPC_MPC8540_v10,  POWERPC_SVR_8540_v10,  e500v1)
-    POWERPC_DEF_SVR("MPC8540_v20", "MPC8540 v2.0",
+    POWERPC_DEF_SVR("mpc8540_v20", "MPC8540 v2.0",
                     CPU_POWERPC_MPC8540_v20,  POWERPC_SVR_8540_v20,  e500v1)
-    POWERPC_DEF_SVR("MPC8540_v21", "MPC8540 v2.1",
+    POWERPC_DEF_SVR("mpc8540_v21", "MPC8540 v2.1",
                     CPU_POWERPC_MPC8540_v21,  POWERPC_SVR_8540_v21,  e500v1)
-    POWERPC_DEF_SVR("MPC8541_v10", "MPC8541 v1.0",
+    POWERPC_DEF_SVR("mpc8541_v10", "MPC8541 v1.0",
                     CPU_POWERPC_MPC8541_v10,  POWERPC_SVR_8541_v10,  e500v1)
-    POWERPC_DEF_SVR("MPC8541_v11", "MPC8541 v1.1",
+    POWERPC_DEF_SVR("mpc8541_v11", "MPC8541 v1.1",
                     CPU_POWERPC_MPC8541_v11,  POWERPC_SVR_8541_v11,  e500v1)
-    POWERPC_DEF_SVR("MPC8541E_v10", "MPC8541E v1.0",
+    POWERPC_DEF_SVR("mpc8541e_v10", "MPC8541E v1.0",
                     CPU_POWERPC_MPC8541E_v10, POWERPC_SVR_8541E_v10, e500v1)
-    POWERPC_DEF_SVR("MPC8541E_v11", "MPC8541E v1.1",
+    POWERPC_DEF_SVR("mpc8541e_v11", "MPC8541E v1.1",
                     CPU_POWERPC_MPC8541E_v11, POWERPC_SVR_8541E_v11, e500v1)
-    POWERPC_DEF_SVR("MPC8543_v10", "MPC8543 v1.0",
+    POWERPC_DEF_SVR("mpc8543_v10", "MPC8543 v1.0",
                     CPU_POWERPC_MPC8543_v10,  POWERPC_SVR_8543_v10,  e500v2)
-    POWERPC_DEF_SVR("MPC8543_v11", "MPC8543 v1.1",
+    POWERPC_DEF_SVR("mpc8543_v11", "MPC8543 v1.1",
                     CPU_POWERPC_MPC8543_v11,  POWERPC_SVR_8543_v11,  e500v2)
-    POWERPC_DEF_SVR("MPC8543_v20", "MPC8543 v2.0",
+    POWERPC_DEF_SVR("mpc8543_v20", "MPC8543 v2.0",
                     CPU_POWERPC_MPC8543_v20,  POWERPC_SVR_8543_v20,  e500v2)
-    POWERPC_DEF_SVR("MPC8543_v21", "MPC8543 v2.1",
+    POWERPC_DEF_SVR("mpc8543_v21", "MPC8543 v2.1",
                     CPU_POWERPC_MPC8543_v21,  POWERPC_SVR_8543_v21,  e500v2)
-    POWERPC_DEF_SVR("MPC8543E_v10", "MPC8543E v1.0",
+    POWERPC_DEF_SVR("mpc8543e_v10", "MPC8543E v1.0",
                     CPU_POWERPC_MPC8543E_v10, POWERPC_SVR_8543E_v10, e500v2)
-    POWERPC_DEF_SVR("MPC8543E_v11", "MPC8543E v1.1",
+    POWERPC_DEF_SVR("mpc8543e_v11", "MPC8543E v1.1",
                     CPU_POWERPC_MPC8543E_v11, POWERPC_SVR_8543E_v11, e500v2)
-    POWERPC_DEF_SVR("MPC8543E_v20", "MPC8543E v2.0",
+    POWERPC_DEF_SVR("mpc8543e_v20", "MPC8543E v2.0",
                     CPU_POWERPC_MPC8543E_v20, POWERPC_SVR_8543E_v20, e500v2)
-    POWERPC_DEF_SVR("MPC8543E_v21", "MPC8543E v2.1",
+    POWERPC_DEF_SVR("mpc8543e_v21", "MPC8543E v2.1",
                     CPU_POWERPC_MPC8543E_v21, POWERPC_SVR_8543E_v21, e500v2)
-    POWERPC_DEF_SVR("MPC8544_v10", "MPC8544 v1.0",
+    POWERPC_DEF_SVR("mpc8544_v10", "MPC8544 v1.0",
                     CPU_POWERPC_MPC8544_v10,  POWERPC_SVR_8544_v10,  e500v2)
-    POWERPC_DEF_SVR("MPC8544_v11", "MPC8544 v1.1",
+    POWERPC_DEF_SVR("mpc8544_v11", "MPC8544 v1.1",
                     CPU_POWERPC_MPC8544_v11,  POWERPC_SVR_8544_v11,  e500v2)
-    POWERPC_DEF_SVR("MPC8544E_v10", "MPC8544E v1.0",
+    POWERPC_DEF_SVR("mpc8544e_v10", "MPC8544E v1.0",
                     CPU_POWERPC_MPC8544E_v10, POWERPC_SVR_8544E_v10, e500v2)
-    POWERPC_DEF_SVR("MPC8544E_v11", "MPC8544E v1.1",
+    POWERPC_DEF_SVR("mpc8544e_v11", "MPC8544E v1.1",
                     CPU_POWERPC_MPC8544E_v11, POWERPC_SVR_8544E_v11, e500v2)
-    POWERPC_DEF_SVR("MPC8545_v20", "MPC8545 v2.0",
+    POWERPC_DEF_SVR("mpc8545_v20", "MPC8545 v2.0",
                     CPU_POWERPC_MPC8545_v20,  POWERPC_SVR_8545_v20,  e500v2)
-    POWERPC_DEF_SVR("MPC8545_v21", "MPC8545 v2.1",
+    POWERPC_DEF_SVR("mpc8545_v21", "MPC8545 v2.1",
                     CPU_POWERPC_MPC8545_v21,  POWERPC_SVR_8545_v21,  e500v2)
-    POWERPC_DEF_SVR("MPC8545E_v20", "MPC8545E v2.0",
+    POWERPC_DEF_SVR("mpc8545e_v20", "MPC8545E v2.0",
                     CPU_POWERPC_MPC8545E_v20, POWERPC_SVR_8545E_v20, e500v2)
-    POWERPC_DEF_SVR("MPC8545E_v21", "MPC8545E v2.1",
+    POWERPC_DEF_SVR("mpc8545e_v21", "MPC8545E v2.1",
                     CPU_POWERPC_MPC8545E_v21, POWERPC_SVR_8545E_v21, e500v2)
-    POWERPC_DEF_SVR("MPC8547E_v20", "MPC8547E v2.0",
+    POWERPC_DEF_SVR("mpc8547e_v20", "MPC8547E v2.0",
                     CPU_POWERPC_MPC8547E_v20, POWERPC_SVR_8547E_v20, e500v2)
-    POWERPC_DEF_SVR("MPC8547E_v21", "MPC8547E v2.1",
+    POWERPC_DEF_SVR("mpc8547e_v21", "MPC8547E v2.1",
                     CPU_POWERPC_MPC8547E_v21, POWERPC_SVR_8547E_v21, e500v2)
-    POWERPC_DEF_SVR("MPC8548_v10", "MPC8548 v1.0",
+    POWERPC_DEF_SVR("mpc8548_v10", "MPC8548 v1.0",
                     CPU_POWERPC_MPC8548_v10,  POWERPC_SVR_8548_v10,  e500v2)
-    POWERPC_DEF_SVR("MPC8548_v11", "MPC8548 v1.1",
+    POWERPC_DEF_SVR("mpc8548_v11", "MPC8548 v1.1",
                     CPU_POWERPC_MPC8548_v11,  POWERPC_SVR_8548_v11,  e500v2)
-    POWERPC_DEF_SVR("MPC8548_v20", "MPC8548 v2.0",
+    POWERPC_DEF_SVR("mpc8548_v20", "MPC8548 v2.0",
                     CPU_POWERPC_MPC8548_v20,  POWERPC_SVR_8548_v20,  e500v2)
-    POWERPC_DEF_SVR("MPC8548_v21", "MPC8548 v2.1",
+    POWERPC_DEF_SVR("mpc8548_v21", "MPC8548 v2.1",
                     CPU_POWERPC_MPC8548_v21,  POWERPC_SVR_8548_v21,  e500v2)
-    POWERPC_DEF_SVR("MPC8548E_v10", "MPC8548E v1.0",
+    POWERPC_DEF_SVR("mpc8548e_v10", "MPC8548E v1.0",
                     CPU_POWERPC_MPC8548E_v10, POWERPC_SVR_8548E_v10, e500v2)
-    POWERPC_DEF_SVR("MPC8548E_v11", "MPC8548E v1.1",
+    POWERPC_DEF_SVR("mpc8548e_v11", "MPC8548E v1.1",
                     CPU_POWERPC_MPC8548E_v11, POWERPC_SVR_8548E_v11, e500v2)
-    POWERPC_DEF_SVR("MPC8548E_v20", "MPC8548E v2.0",
+    POWERPC_DEF_SVR("mpc8548e_v20", "MPC8548E v2.0",
                     CPU_POWERPC_MPC8548E_v20, POWERPC_SVR_8548E_v20, e500v2)
-    POWERPC_DEF_SVR("MPC8548E_v21", "MPC8548E v2.1",
+    POWERPC_DEF_SVR("mpc8548e_v21", "MPC8548E v2.1",
                     CPU_POWERPC_MPC8548E_v21, POWERPC_SVR_8548E_v21, e500v2)
-    POWERPC_DEF_SVR("MPC8555_v10", "MPC8555 v1.0",
+    POWERPC_DEF_SVR("mpc8555_v10", "MPC8555 v1.0",
                     CPU_POWERPC_MPC8555_v10,  POWERPC_SVR_8555_v10,  e500v2)
-    POWERPC_DEF_SVR("MPC8555_v11", "MPC8555 v1.1",
+    POWERPC_DEF_SVR("mpc8555_v11", "MPC8555 v1.1",
                     CPU_POWERPC_MPC8555_v11,  POWERPC_SVR_8555_v11,  e500v2)
-    POWERPC_DEF_SVR("MPC8555E_v10", "MPC8555E v1.0",
+    POWERPC_DEF_SVR("mpc8555e_v10", "MPC8555E v1.0",
                     CPU_POWERPC_MPC8555E_v10, POWERPC_SVR_8555E_v10, e500v2)
-    POWERPC_DEF_SVR("MPC8555E_v11", "MPC8555E v1.1",
+    POWERPC_DEF_SVR("mpc8555e_v11", "MPC8555E v1.1",
                     CPU_POWERPC_MPC8555E_v11, POWERPC_SVR_8555E_v11, e500v2)
-    POWERPC_DEF_SVR("MPC8560_v10", "MPC8560 v1.0",
+    POWERPC_DEF_SVR("mpc8560_v10", "MPC8560 v1.0",
                     CPU_POWERPC_MPC8560_v10,  POWERPC_SVR_8560_v10,  e500v2)
-    POWERPC_DEF_SVR("MPC8560_v20", "MPC8560 v2.0",
+    POWERPC_DEF_SVR("mpc8560_v20", "MPC8560 v2.0",
                     CPU_POWERPC_MPC8560_v20,  POWERPC_SVR_8560_v20,  e500v2)
-    POWERPC_DEF_SVR("MPC8560_v21", "MPC8560 v2.1",
+    POWERPC_DEF_SVR("mpc8560_v21", "MPC8560 v2.1",
                     CPU_POWERPC_MPC8560_v21,  POWERPC_SVR_8560_v21,  e500v2)
-    POWERPC_DEF_SVR("MPC8567", "MPC8567",
+    POWERPC_DEF_SVR("mpc8567", "MPC8567",
                     CPU_POWERPC_MPC8567,      POWERPC_SVR_8567,      e500v2)
-    POWERPC_DEF_SVR("MPC8567E", "MPC8567E",
+    POWERPC_DEF_SVR("mpc8567e", "MPC8567E",
                     CPU_POWERPC_MPC8567E,     POWERPC_SVR_8567E,     e500v2)
-    POWERPC_DEF_SVR("MPC8568", "MPC8568",
+    POWERPC_DEF_SVR("mpc8568", "MPC8568",
                     CPU_POWERPC_MPC8568,      POWERPC_SVR_8568,      e500v2)
-    POWERPC_DEF_SVR("MPC8568E", "MPC8568E",
+    POWERPC_DEF_SVR("mpc8568e", "MPC8568E",
                     CPU_POWERPC_MPC8568E,     POWERPC_SVR_8568E,     e500v2)
-    POWERPC_DEF_SVR("MPC8572", "MPC8572",
+    POWERPC_DEF_SVR("mpc8572", "MPC8572",
                     CPU_POWERPC_MPC8572,      POWERPC_SVR_8572,      e500v2)
-    POWERPC_DEF_SVR("MPC8572E", "MPC8572E",
+    POWERPC_DEF_SVR("mpc8572e", "MPC8572E",
                     CPU_POWERPC_MPC8572E,     POWERPC_SVR_8572E,     e500v2)
     /* e600 family                                                           */
     POWERPC_DEF("e600",          CPU_POWERPC_e600,                   e600,
                 "PowerPC e600 core")
     /* PowerPC e600 microcontrollers                                         */
-    POWERPC_DEF_SVR("MPC8610", "MPC8610",
+    POWERPC_DEF_SVR("mpc8610", "MPC8610",
                     CPU_POWERPC_MPC8610,      POWERPC_SVR_8610,      e600)
-    POWERPC_DEF_SVR("MPC8641", "MPC8641",
+    POWERPC_DEF_SVR("mpc8641", "MPC8641",
                     CPU_POWERPC_MPC8641,      POWERPC_SVR_8641,      e600)
-    POWERPC_DEF_SVR("MPC8641D", "MPC8641D",
+    POWERPC_DEF_SVR("mpc8641d", "MPC8641D",
                     CPU_POWERPC_MPC8641D,     POWERPC_SVR_8641D,     e600)
     /* 32 bits "classic" PowerPC                                             */
     /* PowerPC 6xx family                                                    */
@@ -855,10 +501,6 @@
                 "PowerPC 604e v2.4")
     POWERPC_DEF("604r",          CPU_POWERPC_604R,                   604E,
                 "PowerPC 604r (aka PIDA)")
-#if defined(TODO)
-    POWERPC_DEF("604ev",         CPU_POWERPC_604EV,                  604E,
-                "PowerPC 604ev")
-#endif
     /* PowerPC 7xx family                                                    */
     POWERPC_DEF("740_v1.0",      CPU_POWERPC_7x0_v10,                740,
                 "PowerPC 740 v1.0 (G3)")
@@ -996,12 +638,6 @@
                 "PowerPC 745 v2.8")
     POWERPC_DEF("755_v2.8",      CPU_POWERPC_7x5_v28,                755,
                 "PowerPC 755 v2.8")
-#if defined(TODO)
-    POWERPC_DEF("745p",          CPU_POWERPC_7x5P,                   745,
-                "PowerPC 745P (G3)")
-    POWERPC_DEF("755p",          CPU_POWERPC_7x5P,                   755,
-                "PowerPC 755P (G3)")
-#endif
     /* PowerPC 74xx family                                                   */
     POWERPC_DEF("7400_v1.0",     CPU_POWERPC_7400_v10,               7400,
                 "PowerPC 7400 v1.0 (G4)")
@@ -1089,62 +725,36 @@
                 "PowerPC 7457 v1.1 (G4)")
     POWERPC_DEF("7457_v1.2",     CPU_POWERPC_74x7_v12,               7455,
                 "PowerPC 7457 v1.2 (G4)")
-    POWERPC_DEF("7447A_v1.0",    CPU_POWERPC_74x7A_v10,              7445,
+    POWERPC_DEF("7447a_v1.0",    CPU_POWERPC_74x7A_v10,              7445,
                 "PowerPC 7447A v1.0 (G4)")
-    POWERPC_DEF("7457A_v1.0",    CPU_POWERPC_74x7A_v10,              7455,
+    POWERPC_DEF("7457a_v1.0",    CPU_POWERPC_74x7A_v10,              7455,
                 "PowerPC 7457A v1.0 (G4)")
-    POWERPC_DEF("7447A_v1.1",    CPU_POWERPC_74x7A_v11,              7445,
+    POWERPC_DEF("7447a_v1.1",    CPU_POWERPC_74x7A_v11,              7445,
                 "PowerPC 7447A v1.1 (G4)")
-    POWERPC_DEF("7457A_v1.1",    CPU_POWERPC_74x7A_v11,              7455,
+    POWERPC_DEF("7457a_v1.1",    CPU_POWERPC_74x7A_v11,              7455,
                 "PowerPC 7457A v1.1 (G4)")
-    POWERPC_DEF("7447A_v1.2",    CPU_POWERPC_74x7A_v12,              7445,
+    POWERPC_DEF("7447a_v1.2",    CPU_POWERPC_74x7A_v12,              7445,
                 "PowerPC 7447A v1.2 (G4)")
-    POWERPC_DEF("7457A_v1.2",    CPU_POWERPC_74x7A_v12,              7455,
+    POWERPC_DEF("7457a_v1.2",    CPU_POWERPC_74x7A_v12,              7455,
                 "PowerPC 7457A v1.2 (G4)")
     /* 64 bits PowerPC                                                       */
 #if defined (TARGET_PPC64)
-#if defined(TODO)
-    POWERPC_DEF("620",           CPU_POWERPC_620,                    620,
-                "PowerPC 620")
-    POWERPC_DEF("630",           CPU_POWERPC_630,                    630,
-                "PowerPC 630 (POWER3)")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("631",           CPU_POWERPC_631,                    631,
-                "PowerPC 631 (Power 3+)")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("POWER4",        CPU_POWERPC_POWER4,                 POWER4,
-                "POWER4")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("POWER4+",       CPU_POWERPC_POWER4P,                POWER4P,
-                "POWER4p")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("POWER5",        CPU_POWERPC_POWER5,                 POWER5,
-                "POWER5")
-#endif
-    POWERPC_DEF("POWER5+_v2.1",  CPU_POWERPC_POWER5P_v21,            POWER5P,
+    POWERPC_DEF("power5+_v2.1",  CPU_POWERPC_POWER5P_v21,            POWER5P,
                 "POWER5+ v2.1")
-#if defined(TODO)
-    POWERPC_DEF("POWER6",        CPU_POWERPC_POWER6,                 POWER6,
-                "POWER6")
-#endif
-    POWERPC_DEF("POWER7_v2.3",   CPU_POWERPC_POWER7_v23,             POWER7,
+    POWERPC_DEF("power7_v2.3",   CPU_POWERPC_POWER7_v23,             POWER7,
                 "POWER7 v2.3")
-    POWERPC_DEF("POWER7+_v2.1",  CPU_POWERPC_POWER7P_v21,            POWER7,
+    POWERPC_DEF("power7+_v2.1",  CPU_POWERPC_POWER7P_v21,            POWER7,
                 "POWER7+ v2.1")
-    POWERPC_DEF("POWER8E_v2.1",  CPU_POWERPC_POWER8E_v21,            POWER8,
+    POWERPC_DEF("power8e_v2.1",  CPU_POWERPC_POWER8E_v21,            POWER8,
                 "POWER8E v2.1")
-    POWERPC_DEF("POWER8_v2.0",   CPU_POWERPC_POWER8_v20,             POWER8,
+    POWERPC_DEF("power8_v2.0",   CPU_POWERPC_POWER8_v20,             POWER8,
                 "POWER8 v2.0")
-    POWERPC_DEF("POWER8NVL_v1.0",CPU_POWERPC_POWER8NVL_v10,          POWER8,
+    POWERPC_DEF("power8nvl_v1.0", CPU_POWERPC_POWER8NVL_v10,         POWER8,
                 "POWER8NVL v1.0")
     POWERPC_DEF("970_v2.2",      CPU_POWERPC_970_v22,                970,
                 "PowerPC 970 v2.2")
 
-    POWERPC_DEF("POWER9_v1.0",   CPU_POWERPC_POWER9_BASE,            POWER9,
+    POWERPC_DEF("power9_v1.0",   CPU_POWERPC_POWER9_BASE,            POWER9,
                 "POWER9 v1.0")
 
     POWERPC_DEF("970fx_v1.0",    CPU_POWERPC_970FX_v10,              970,
@@ -1161,237 +771,178 @@
                 "PowerPC 970MP v1.0")
     POWERPC_DEF("970mp_v1.1",    CPU_POWERPC_970MP_v11,              970,
                 "PowerPC 970MP v1.1")
-#if defined(TODO)
-    POWERPC_DEF("Cell",          CPU_POWERPC_CELL,                   970,
-                "PowerPC Cell")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("Cell_v1.0",     CPU_POWERPC_CELL_v10,               970,
-                "PowerPC Cell v1.0")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("Cell_v2.0",     CPU_POWERPC_CELL_v20,               970,
-                "PowerPC Cell v2.0")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("Cell_v3.0",     CPU_POWERPC_CELL_v30,               970,
-                "PowerPC Cell v3.0")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("Cell_v3.1",     CPU_POWERPC_CELL_v31,               970,
-                "PowerPC Cell v3.1")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("Cell_v3.2",     CPU_POWERPC_CELL_v32,               970,
-                "PowerPC Cell v3.2")
-#endif
-#if defined(TODO)
-    /* This one seems to support the whole POWER2 instruction set
-     * and the PowerPC 64 one.
-     */
-    /* What about A10 & A30 ? */
-    POWERPC_DEF("RS64",          CPU_POWERPC_RS64,                   RS64,
-                "RS64 (Apache/A35)")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("RS64-II",       CPU_POWERPC_RS64II,                 RS64,
-                "RS64-II (NorthStar/A50)")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("RS64-III",      CPU_POWERPC_RS64III,                RS64,
-                "RS64-III (Pulsar)")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("RS64-IV",       CPU_POWERPC_RS64IV,                 RS64,
-                "RS64-IV (IceStar/IStar/SStar)")
-#endif
 #endif /* defined (TARGET_PPC64) */
-    /* POWER                                                                 */
-#if defined(TODO)
-    POWERPC_DEF("POWER",         CPU_POWERPC_POWER,                  POWER,
-                "Original POWER")
-#endif
-#if defined(TODO)
-    POWERPC_DEF("POWER2",        CPU_POWERPC_POWER2,                 POWER,
-                "POWER2")
-#endif
-    /* PA semi cores                                                         */
-#if defined(TODO)
-    POWERPC_DEF("PA6T",          CPU_POWERPC_PA6T,                   PA6T,
-                "PA PA6T")
-#endif
-
 
 /***************************************************************************/
 /* PowerPC CPU aliases                                                     */
 
 PowerPCCPUAlias ppc_cpu_aliases[] = {
-    { "403", "403GC" },
-    { "405", "405D4" },
-    { "405CR", "405CRc" },
-    { "405GP", "405GPd" },
-    { "405GPe", "405CRc" },
+    { "403", "403gc" },
+    { "405", "405d4" },
+    { "405cr", "405crc" },
+    { "405gp", "405gpd" },
+    { "405gpe", "405crc" },
     { "x2vp7", "x2vp4" },
     { "x2vp50", "x2vp20" },
 
-    { "440EP", "440EPb" },
-    { "440GP", "440GPc" },
-    { "440GR", "440GRa" },
-    { "440GX", "440GXf" },
+    { "440ep", "440epb" },
+#if defined(TODO_USER_ONLY)
+    { "440gp", "440gpc" },
+    { "440gr", "440gra" },
+    { "440gx", "440gxf" },
 
-    { "RCPU", "MPC5xx" },
+    { "rcpu", "mpc5xx" },
     /* MPC5xx microcontrollers */
-    { "MGT560", "MPC5xx" },
-    { "MPC509", "MPC5xx" },
-    { "MPC533", "MPC5xx" },
-    { "MPC534", "MPC5xx" },
-    { "MPC555", "MPC5xx" },
-    { "MPC556", "MPC5xx" },
-    { "MPC560", "MPC5xx" },
-    { "MPC561", "MPC5xx" },
-    { "MPC562", "MPC5xx" },
-    { "MPC563", "MPC5xx" },
-    { "MPC564", "MPC5xx" },
-    { "MPC565", "MPC5xx" },
-    { "MPC566", "MPC5xx" },
+    { "mgt560", "mpc5xx" },
+    { "mpc509", "mpc5xx" },
+    { "mpc533", "mpc5xx" },
+    { "mpc534", "mpc5xx" },
+    { "mpc555", "mpc5xx" },
+    { "mpc556", "mpc5xx" },
+    { "mpc560", "mpc5xx" },
+    { "mpc561", "mpc5xx" },
+    { "mpc562", "mpc5xx" },
+    { "mpc563", "mpc5xx" },
+    { "mpc564", "mpc5xx" },
+    { "mpc565", "mpc5xx" },
+    { "mpc566", "mpc5xx" },
 
-    { "PowerQUICC", "MPC8xx" },
+    { "powerquicc", "mpc8xx" },
     /* MPC8xx microcontrollers */
-    { "MGT823", "MPC8xx" },
-    { "MPC821", "MPC8xx" },
-    { "MPC823", "MPC8xx" },
-    { "MPC850", "MPC8xx" },
-    { "MPC852T", "MPC8xx" },
-    { "MPC855T", "MPC8xx" },
-    { "MPC857", "MPC8xx" },
-    { "MPC859", "MPC8xx" },
-    { "MPC860", "MPC8xx" },
-    { "MPC862", "MPC8xx" },
-    { "MPC866", "MPC8xx" },
-    { "MPC870", "MPC8xx" },
-    { "MPC875", "MPC8xx" },
-    { "MPC880", "MPC8xx" },
-    { "MPC885", "MPC8xx" },
+    { "mgt823", "mpc8xx" },
+    { "mpc821", "mpc8xx" },
+    { "mpc823", "mpc8xx" },
+    { "mpc850", "mpc8xx" },
+    { "mpc852t", "mpc8xx" },
+    { "mpc855t", "mpc8xx" },
+    { "mpc857", "mpc8xx" },
+    { "mpc859", "mpc8xx" },
+    { "mpc860", "mpc8xx" },
+    { "mpc862", "mpc8xx" },
+    { "mpc866", "mpc8xx" },
+    { "mpc870", "mpc8xx" },
+    { "mpc875", "mpc8xx" },
+    { "mpc880", "mpc8xx" },
+    { "mpc885", "mpc8xx" },
+#endif
 
     /* PowerPC MPC603 microcontrollers */
-    { "MPC8240", "603" },
+    { "mpc8240", "603" },
 
-    { "MPC52xx", "MPC5200" },
-    { "MPC5200", "MPC5200_v12" },
-    { "MPC5200B", "MPC5200B_v21" },
+    { "mpc52xx", "mpc5200_v12" },
+    { "mpc5200", "mpc5200_v12" },
+    { "mpc5200b", "mpc5200b_v21" },
 
-    { "MPC82xx", "MPC8280" },
-    { "PowerQUICC-II", "MPC82xx" },
-    { "MPC8241", "G2HiP4" },
-    { "MPC8245", "G2HiP4" },
-    { "MPC8247", "G2leGP3" },
-    { "MPC8248", "G2leGP3" },
-    { "MPC8250", "MPC8250_HiP4" },
-    { "MPC8250_HiP3", "G2HiP3" },
-    { "MPC8250_HiP4", "G2HiP4" },
-    { "MPC8255", "MPC8255_HiP4" },
-    { "MPC8255_HiP3", "G2HiP3" },
-    { "MPC8255_HiP4", "G2HiP4" },
-    { "MPC8260", "MPC8260_HiP4" },
-    { "MPC8260_HiP3", "G2HiP3" },
-    { "MPC8260_HiP4", "G2HiP4" },
-    { "MPC8264", "MPC8264_HiP4" },
-    { "MPC8264_HiP3", "G2HiP3" },
-    { "MPC8264_HiP4", "G2HiP4" },
-    { "MPC8265", "MPC8265_HiP4" },
-    { "MPC8265_HiP3", "G2HiP3" },
-    { "MPC8265_HiP4", "G2HiP4" },
-    { "MPC8266", "MPC8266_HiP4" },
-    { "MPC8266_HiP3", "G2HiP3" },
-    { "MPC8266_HiP4", "G2HiP4" },
-    { "MPC8270", "G2leGP3" },
-    { "MPC8271", "G2leGP3" },
-    { "MPC8272", "G2leGP3" },
-    { "MPC8275", "G2leGP3" },
-    { "MPC8280", "G2leGP3" },
+    { "mpc82xx", "g2legp3" },
+    { "powerquicc-ii", "g2legp3" },
+    { "mpc8241", "g2hip4" },
+    { "mpc8245", "g2hip4" },
+    { "mpc8247", "g2legp3" },
+    { "mpc8248", "g2legp3" },
+    { "mpc8250", "g2hip4" },
+    { "mpc8250_hip3", "g2hip3" },
+    { "mpc8250_hip4", "g2hip4" },
+    { "mpc8255", "g2hip4" },
+    { "mpc8255_hip3", "g2hip3" },
+    { "mpc8255_hip4", "g2hip4" },
+    { "mpc8260", "g2hip4" },
+    { "mpc8260_hip3", "g2hip3" },
+    { "mpc8260_hip4", "g2hip4" },
+    { "mpc8264", "g2hip4" },
+    { "mpc8264_hip3", "g2hip3" },
+    { "mpc8264_hip4", "g2hip4" },
+    { "mpc8265", "g2hip4" },
+    { "mpc8265_hip3", "g2hip3" },
+    { "mpc8265_hip4", "g2hip4" },
+    { "mpc8266", "g2hip4" },
+    { "mpc8266_hip3", "g2hip3" },
+    { "mpc8266_hip4", "g2hip4" },
+    { "mpc8270", "g2legp3" },
+    { "mpc8271", "g2legp3" },
+    { "mpc8272", "g2legp3" },
+    { "mpc8275", "g2legp3" },
+    { "mpc8280", "g2legp3" },
     { "e200", "e200z6" },
     { "e300", "e300c3" },
-    { "MPC8347", "MPC8347T" },
-    { "MPC8347A", "MPC8347AT" },
-    { "MPC8347E", "MPC8347ET" },
-    { "MPC8347EA", "MPC8347EAT" },
+    { "mpc8347", "mpc8347t" },
+    { "mpc8347a", "mpc8347at" },
+    { "mpc8347e", "mpc8347et" },
+    { "mpc8347ea", "mpc8347eat" },
     { "e500", "e500v2_v22" },
     { "e500v1", "e500_v20" },
     { "e500v2", "e500v2_v22" },
-    { "MPC8533", "MPC8533_v11" },
-    { "MPC8533E", "MPC8533E_v11" },
-    { "MPC8540", "MPC8540_v21" },
-    { "MPC8541", "MPC8541_v11" },
-    { "MPC8541E", "MPC8541E_v11" },
-    { "MPC8543", "MPC8543_v21" },
-    { "MPC8543E", "MPC8543E_v21" },
-    { "MPC8544", "MPC8544_v11" },
-    { "MPC8544E", "MPC8544E_v11" },
-    { "MPC8545", "MPC8545_v21" },
-    { "MPC8545E", "MPC8545E_v21" },
-    { "MPC8547E", "MPC8547E_v21" },
-    { "MPC8548", "MPC8548_v21" },
-    { "MPC8548E", "MPC8548E_v21" },
-    { "MPC8555", "MPC8555_v11" },
-    { "MPC8555E", "MPC8555E_v11" },
-    { "MPC8560", "MPC8560_v21" },
+    { "mpc8533", "mpc8533_v11" },
+    { "mpc8533e", "mpc8533e_v11" },
+    { "mpc8540", "mpc8540_v21" },
+    { "mpc8541", "mpc8541_v11" },
+    { "mpc8541e", "mpc8541e_v11" },
+    { "mpc8543", "mpc8543_v21" },
+    { "mpc8543e", "mpc8543e_v21" },
+    { "mpc8544", "mpc8544_v11" },
+    { "mpc8544e", "mpc8544e_v11" },
+    { "mpc8545", "mpc8545_v21" },
+    { "mpc8545e", "mpc8545e_v21" },
+    { "mpc8547e", "mpc8547e_v21" },
+    { "mpc8548", "mpc8548_v21" },
+    { "mpc8548e", "mpc8548e_v21" },
+    { "mpc8555", "mpc8555_v11" },
+    { "mpc8555e", "mpc8555e_v11" },
+    { "mpc8560", "mpc8560_v21" },
     { "601",  "601_v2" },
     { "601v", "601_v2" },
-    { "Vanilla", "603" },
+    { "vanilla", "603" },
     { "603e", "603e_v4.1" },
-    { "Stretch", "603e" },
-    { "Vaillant", "603e7v" },
+    { "stretch", "603e_v4.1" },
+    { "vaillant", "603e7v" },
     { "603r", "603e7t" },
-    { "Goldeneye", "603r" },
+    { "goldeneye", "603e7t" },
     { "604e", "604e_v2.4" },
-    { "Sirocco", "604e" },
-    { "Mach5", "604r" },
+    { "sirocco", "604e_v2.4" },
+    { "mach5", "604r" },
     { "740", "740_v3.1" },
-    { "Arthur", "740" },
+    { "arthur", "740_v3.1" },
     { "750", "750_v3.1" },
-    { "Typhoon", "750" },
-    { "G3",      "750" },
-    { "Conan/Doyle", "750p" },
+    { "typhoon", "750_v3.1" },
+    { "g3",      "750_v3.1" },
+    { "conan/doyle", "750p" },
     { "750cl", "750cl_v2.0" },
     { "750cx", "750cx_v2.2" },
     { "750cxe", "750cxe_v3.1b" },
     { "750fx", "750fx_v2.3" },
     { "750gx", "750gx_v1.2" },
     { "750l", "750l_v3.2" },
-    { "LoneStar", "750l" },
+    { "lonestar", "750l_v3.2" },
     { "745", "745_v2.8" },
     { "755", "755_v2.8" },
-    { "Goldfinger", "755" },
+    { "goldfinger", "755_v2.8" },
     { "7400", "7400_v2.9" },
-    { "Max", "7400" },
-    { "G4",  "7400" },
+    { "max", "7400_v2.9" },
+    { "g4",  "7400_v2.9" },
     { "7410", "7410_v1.4" },
-    { "Nitro", "7410" },
+    { "nitro", "7410_v1.4" },
     { "7448", "7448_v2.1" },
     { "7450", "7450_v2.1" },
-    { "Vger", "7450" },
+    { "vger", "7450_v2.1" },
     { "7441", "7441_v2.3" },
     { "7451", "7451_v2.3" },
     { "7445", "7445_v3.2" },
     { "7455", "7455_v3.2" },
-    { "Apollo6", "7455" },
+    { "apollo6", "7455_v3.2" },
     { "7447", "7447_v1.1" },
     { "7457", "7457_v1.2" },
-    { "Apollo7", "7457" },
-    { "7447A", "7447A_v1.2" },
-    { "7457A", "7457A_v1.2" },
-    { "Apollo7PM", "7457A_v1.0" },
+    { "apollo7", "7457_v1.2" },
+    { "7447a", "7447a_v1.2" },
+    { "7457a", "7457a_v1.2" },
+    { "apollo7pm", "7457a_v1.0" },
 #if defined(TARGET_PPC64)
-    { "POWER3", "630" },
-    { "POWER3+", "631" },
-    { "POWER5+", "POWER5+_v2.1" },
-    { "POWER5gs", "POWER5+_v2.1" },
-    { "POWER7", "POWER7_v2.3" },
-    { "POWER7+", "POWER7+_v2.1" },
-    { "POWER8E", "POWER8E_v2.1" },
-    { "POWER8", "POWER8_v2.0" },
-    { "POWER8NVL", "POWER8NVL_v1.0" },
-    { "POWER9", "POWER9_v1.0" },
+    { "power5+", "power5+_v2.1" },
+    { "power5gs", "power5+_v2.1" },
+    { "power7", "power7_v2.3" },
+    { "power7+", "power7+_v2.1" },
+    { "power8e", "power8e_v2.1" },
+    { "power8", "power8_v2.0" },
+    { "power8nvl", "power8nvl_v1.0" },
+    { "power9", "power9_v1.0" },
     { "970", "970_v2.2" },
     { "970fx", "970fx_v3.1" },
     { "970mp", "970mp_v1.1" },
@@ -1399,10 +950,10 @@ PowerPCCPUAlias ppc_cpu_aliases[] = {
 
     /* Generic PowerPCs */
 #if defined(TARGET_PPC64)
-    { "ppc64", "970fx" },
+    { "ppc64", "970fx_v3.1" },
 #endif
     { "ppc32", "604" },
-    { "ppc", "ppc32" },
-    { "default", "ppc" },
+    { "ppc", "604" },
+    { "default", "604" },
     { NULL, NULL }
 };
diff --git a/target/ppc/cpu-models.h b/target/ppc/cpu-models.h
index b563c45b68..df31d7f492 100644
--- a/target/ppc/cpu-models.h
+++ b/target/ppc/cpu-models.h
@@ -24,14 +24,13 @@
 /**
  * PowerPCCPUAlias:
  * @alias: The alias name.
- * @model: The CPU model @alias refers to.
+ * @model: The CPU model @alias refers to, that directly resolves into CPU type
  *
  * A mapping entry from CPU @alias to CPU @model.
  */
 typedef struct PowerPCCPUAlias {
     const char *alias;
     const char *model;
-    ObjectClass *oc;
 } PowerPCCPUAlias;
 
 extern PowerPCCPUAlias ppc_cpu_aliases[];
@@ -346,6 +345,7 @@ enum {
     CPU_POWERPC_e500v2_v30         = 0x80210030,
     CPU_POWERPC_e500mc             = 0x80230020,
     CPU_POWERPC_e5500              = 0x80240020,
+    CPU_POWERPC_e6500              = 0x80400020,
     /* MPC85xx microcontrollers */
 #define CPU_POWERPC_MPC8533_v10      CPU_POWERPC_e500v2_v21
 #define CPU_POWERPC_MPC8533_v11      CPU_POWERPC_e500v2_v22
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 12f09492fb..c9d3ffa89b 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -1188,7 +1188,7 @@ typedef struct PPCVirtualHypervisorClass PPCVirtualHypervisorClass;
 /**
  * PowerPCCPU:
  * @env: #CPUPPCState
- * @cpu_dt_id: CPU index used in the device tree. KVM uses this index too
+ * @vcpu_id: vCPU identifier given to KVM
  * @compat_pvr: Current logical PVR, zero if in "raw" mode
  *
  * A PowerPC CPU.
@@ -1199,7 +1199,7 @@ struct PowerPCCPU {
     /*< public >*/
 
     CPUPPCState env;
-    int cpu_dt_id;
+    int vcpu_id;
     uint32_t compat_pvr;
     PPCVirtualHypervisor *vhyp;
     Object *intc;
@@ -1354,6 +1354,9 @@ int ppc_dcr_write (ppc_dcr_t *dcr_env, int dcrn, uint32_t val);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_POWERPC_CPU, cpu_model)
 
+#define POWERPC_CPU_TYPE_SUFFIX "-" TYPE_POWERPC_CPU
+#define POWERPC_CPU_TYPE_NAME(model) model POWERPC_CPU_TYPE_SUFFIX
+
 #define cpu_signal_handler cpu_ppc_signal_handler
 #define cpu_list ppc_cpu_list
 
@@ -2473,10 +2476,10 @@ static inline ppcmas_tlb_t *booke206_get_tlbm(CPUPPCState *env, const int tlbn,
 /* returns bitmap of supported page sizes for a given TLB */
 static inline uint32_t booke206_tlbnps(CPUPPCState *env, const int tlbn)
 {
-    bool mav2 = false;
     uint32_t ret = 0;
 
-    if (mav2) {
+    if ((env->spr[SPR_MMUCFG] & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
+        /* MAV2 */
         ret = env->spr[SPR_BOOKE_TLB0PS + tlbn];
     } else {
         uint32_t tlbncfg = env->spr[SPR_BOOKE_TLB0CFG + tlbn];
@@ -2491,6 +2494,28 @@ static inline uint32_t booke206_tlbnps(CPUPPCState *env, const int tlbn)
     return ret;
 }
 
+static inline void booke206_fixed_size_tlbn(CPUPPCState *env, const int tlbn,
+                                            ppcmas_tlb_t *tlb)
+{
+    uint8_t i;
+    int32_t tsize = -1;
+
+    for (i = 0; i < 32; i++) {
+        if ((env->spr[SPR_BOOKE_TLB0PS + tlbn]) & (1ULL << i)) {
+            if (tsize == -1) {
+                tsize = i;
+            } else {
+                return;
+            }
+        }
+    }
+
+    /* TLBnPS unimplemented? Odd.. */
+    assert(tsize != -1);
+    tlb->mas1 &= ~MAS1_TSIZE_MASK;
+    tlb->mas1 |= ((uint32_t)tsize) << MAS1_TSIZE_SHIFT;
+}
+
 #endif
 
 static inline bool msr_is_64bit(CPUPPCState *env, target_ulong msr)
@@ -2514,23 +2539,5 @@ static inline bool lsw_reg_in_range(int start, int nregs, int rx)
 
 void dump_mmu(FILE *f, fprintf_function cpu_fprintf, CPUPPCState *env);
 
-/**
- * ppc_get_vcpu_dt_id:
- * @cs: a PowerPCCPU struct.
- *
- * Returns a device-tree ID for a CPU.
- */
-int ppc_get_vcpu_dt_id(PowerPCCPU *cpu);
-
-/**
- * ppc_get_vcpu_by_dt_id:
- * @cpu_dt_id: a device tree id
- *
- * Searches for a CPU by @cpu_dt_id.
- *
- * Returns: a PowerPCCPU struct
- */
-PowerPCCPU *ppc_get_vcpu_by_dt_id(int cpu_dt_id);
-
 void ppc_maybe_bswap_register(CPUPPCState *env, uint8_t *mem_buf, int len);
 #endif /* PPC_CPU_H */
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index f31c67e1b1..6442dfcb95 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -74,6 +74,7 @@ static int cap_interrupt_level = false;
 static int cap_segstate;
 static int cap_booke_sregs;
 static int cap_ppc_smt;
+static int cap_ppc_smt_possible;
 static int cap_ppc_rma;
 static int cap_spapr_tce;
 static int cap_spapr_tce_64;
@@ -130,7 +131,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
     cap_interrupt_level = kvm_check_extension(s, KVM_CAP_PPC_IRQ_LEVEL);
     cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE);
     cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS);
-    cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT);
+    cap_ppc_smt_possible = kvm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE);
     cap_ppc_rma = kvm_check_extension(s, KVM_CAP_PPC_RMA);
     cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE);
     cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64);
@@ -144,6 +145,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
      * only activated after this by kvmppc_set_papr() */
     cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD);
     cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL);
+    cap_ppc_smt = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT);
     cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM);
     cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX);
     cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3);
@@ -520,7 +522,7 @@ bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path)
 
 unsigned long kvm_arch_vcpu_id(CPUState *cpu)
 {
-    return ppc_get_vcpu_dt_id(POWERPC_CPU(cpu));
+    return POWERPC_CPU(cpu)->vcpu_id;
 }
 
 /* e500 supports 2 h/w breakpoint and 2 watchpoint.
@@ -2134,6 +2136,41 @@ int kvmppc_smt_threads(void)
     return cap_ppc_smt ? cap_ppc_smt : 1;
 }
 
+int kvmppc_set_smt_threads(int smt)
+{
+    int ret;
+
+    ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_PPC_SMT, 0, smt, 0);
+    if (!ret) {
+        cap_ppc_smt = smt;
+    }
+    return ret;
+}
+
+void kvmppc_hint_smt_possible(Error **errp)
+{
+    int i;
+    GString *g;
+    char *s;
+
+    assert(kvm_enabled());
+    if (cap_ppc_smt_possible) {
+        g = g_string_new("Available VSMT modes:");
+        for (i = 63; i >= 0; i--) {
+            if ((1UL << i) & cap_ppc_smt_possible) {
+                g_string_append_printf(g, " %lu", (1UL << i));
+            }
+        }
+        s = g_string_free(g, false);
+        error_append_hint(errp, "%s.\n", s);
+        g_free(s);
+    } else {
+        error_append_hint(errp,
+                          "This KVM seems to be too old to support VSMT.\n");
+    }
+}
+
+
 #ifdef TARGET_PPC64
 off_t kvmppc_alloc_rma(void **rma)
 {
@@ -2488,15 +2525,14 @@ static int kvm_ppc_register_host_cpu_type(void)
      */
     dc = DEVICE_CLASS(ppc_cpu_get_family_class(pvr_pcc));
     for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
-        if (strcmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
+        if (strcasecmp(ppc_cpu_aliases[i].alias, dc->desc) == 0) {
             char *suffix;
 
             ppc_cpu_aliases[i].model = g_strdup(object_class_get_name(oc));
-            suffix = strstr(ppc_cpu_aliases[i].model, "-"TYPE_POWERPC_CPU);
+            suffix = strstr(ppc_cpu_aliases[i].model, POWERPC_CPU_TYPE_SUFFIX);
             if (suffix) {
                 *suffix = 0;
             }
-            ppc_cpu_aliases[i].oc = oc;
             break;
         }
     }
diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
index 381afe6240..f780e6ec7b 100644
--- a/target/ppc/kvm_ppc.h
+++ b/target/ppc/kvm_ppc.h
@@ -9,7 +9,7 @@
 #ifndef KVM_PPC_H
 #define KVM_PPC_H
 
-#define TYPE_HOST_POWERPC_CPU "host-" TYPE_POWERPC_CPU
+#define TYPE_HOST_POWERPC_CPU POWERPC_CPU_TYPE_NAME("host")
 
 #ifdef CONFIG_KVM
 
@@ -29,6 +29,8 @@ void kvmppc_set_papr(PowerPCCPU *cpu);
 int kvmppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr);
 void kvmppc_set_mpic_proxy(PowerPCCPU *cpu, int mpic_proxy);
 int kvmppc_smt_threads(void);
+void kvmppc_hint_smt_possible(Error **errp);
+int kvmppc_set_smt_threads(int smt);
 int kvmppc_clear_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
 int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits);
 int kvmppc_set_tcr(PowerPCCPU *cpu);
@@ -148,6 +150,16 @@ static inline int kvmppc_smt_threads(void)
     return 1;
 }
 
+static inline void kvmppc_hint_smt_possible(Error **errp)
+{
+    return;
+}
+
+static inline int kvmppc_set_smt_threads(int smt)
+{
+    return 0;
+}
+
 static inline int kvmppc_or_tsr_bits(PowerPCCPU *cpu, uint32_t tsr_bits)
 {
     return 0;
diff --git a/target/ppc/mmu_helper.c b/target/ppc/mmu_helper.c
index f06b9382b4..2a1f9902c9 100644
--- a/target/ppc/mmu_helper.c
+++ b/target/ppc/mmu_helper.c
@@ -2632,12 +2632,16 @@ void helper_booke206_tlbwe(CPUPPCState *env)
         env->spr[SPR_BOOKE_MAS3];
     tlb->mas1 = env->spr[SPR_BOOKE_MAS1];
 
-    /* MAV 1.0 only */
-    if (!(tlbncfg & TLBnCFG_AVAIL)) {
-        /* force !AVAIL TLB entries to correct page size */
-        tlb->mas1 &= ~MAS1_TSIZE_MASK;
-        /* XXX can be configured in MMUCSR0 */
-        tlb->mas1 |= (tlbncfg & TLBnCFG_MINSIZE) >> 12;
+    if ((env->spr[SPR_MMUCFG] & MMUCFG_MAVN) == MMUCFG_MAVN_V2) {
+        /* For TLB which has a fixed size TSIZE is ignored with MAV2 */
+        booke206_fixed_size_tlbn(env, tlbn, tlb);
+    } else {
+        if (!(tlbncfg & TLBnCFG_AVAIL)) {
+            /* force !AVAIL TLB entries to correct page size */
+            tlb->mas1 &= ~MAS1_TSIZE_MASK;
+            /* XXX can be configured in MMUCSR0 */
+            tlb->mas1 |= (tlbncfg & TLBnCFG_MINSIZE) >> 12;
+        }
     }
 
     /* Make a mask from TLB size to discard invalid bits in EPN field */
diff --git a/target/ppc/translate_init.c b/target/ppc/translate_init.c
index 43be9a8331..c827d1e388 100644
--- a/target/ppc/translate_init.c
+++ b/target/ppc/translate_init.c
@@ -34,6 +34,7 @@
 #include "hw/ppc/ppc.h"
 #include "mmu-book3s-v3.h"
 #include "sysemu/qtest.h"
+#include "qemu/cutils.h"
 
 //#define PPC_DUMP_CPU
 //#define PPC_DEBUG_SPR
@@ -1842,7 +1843,7 @@ static inline uint32_t gen_tlbncfg(uint32_t assoc, uint32_t minsize,
 
 /* BookE 2.06 storage control registers */
 static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
-                              uint32_t *tlbncfg)
+                             uint32_t *tlbncfg, uint32_t mmucfg)
 {
 #if !defined(CONFIG_USER_ONLY)
     const char *mas_names[8] = {
@@ -1886,7 +1887,7 @@ static void gen_spr_BookE206(CPUPPCState *env, uint32_t mas_mask,
     spr_register(env, SPR_MMUCFG, "MMUCFG",
                  SPR_NOACCESS, SPR_NOACCESS,
                  &spr_read_generic, SPR_NOACCESS,
-                 0x00000000); /* TOFIX */
+                 mmucfg);
     switch (env->nb_ways) {
     case 4:
         spr_register(env, SPR_BOOKE_TLB3CFG, "TLB3CFG",
@@ -4615,7 +4616,7 @@ static void init_proc_e200(CPUPPCState *env)
                  &spr_read_spefscr, &spr_write_spefscr,
                  0x00000000);
     /* Memory management */
-    gen_spr_BookE206(env, 0x0000005D, NULL);
+    gen_spr_BookE206(env, 0x0000005D, NULL, 0);
     /* XXX : not implemented */
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -4888,6 +4889,7 @@ enum fsl_e500_version {
     fsl_e500v2,
     fsl_e500mc,
     fsl_e5500,
+    fsl_e6500,
 };
 
 static void init_proc_e500(CPUPPCState *env, int version)
@@ -4900,6 +4902,7 @@ static void init_proc_e500(CPUPPCState *env, int version)
                     | 0x0020; /* 32 kb */
     uint32_t l1cfg1 = 0x3800  /* 8 ways */
                     | 0x0020; /* 32 kb */
+    uint32_t mmucfg = 0;
 #if !defined(CONFIG_USER_ONLY)
     int i;
 #endif
@@ -4921,6 +4924,9 @@ static void init_proc_e500(CPUPPCState *env, int version)
         case fsl_e5500:
             ivor_mask = 0x000003FE0000FFFFULL;
             break;
+        case fsl_e6500:
+            ivor_mask = 0x000003FF0000FFFFULL;
+            break;
     }
     gen_spr_BookE(env, ivor_mask);
     gen_spr_usprg3(env);
@@ -4953,6 +4959,12 @@ static void init_proc_e500(CPUPPCState *env, int version)
         tlbncfg[0] = gen_tlbncfg(4, 1, 1, 0, 512);
         tlbncfg[1] = gen_tlbncfg(64, 1, 12, TLBnCFG_AVAIL | TLBnCFG_IPROT, 64);
         break;
+    case fsl_e6500:
+        mmucfg = 0x6510B45;
+        env->nb_pids = 1;
+        tlbncfg[0] = 0x08052400;
+        tlbncfg[1] = 0x40028040;
+        break;
     default:
         cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
     }
@@ -4971,10 +4983,16 @@ static void init_proc_e500(CPUPPCState *env, int version)
         l1cfg0 |= 0x1000000; /* 64 byte cache block size */
         l1cfg1 |= 0x1000000; /* 64 byte cache block size */
         break;
+    case fsl_e6500:
+        env->dcache_line_size = 32;
+        env->icache_line_size = 32;
+        l1cfg0 |= 0x0F83820;
+        l1cfg1 |= 0x0B83820;
+        break;
     default:
         cpu_abort(CPU(cpu), "Unknown CPU: " TARGET_FMT_lx "\n", env->spr[SPR_PVR]);
     }
-    gen_spr_BookE206(env, 0x000000DF, tlbncfg);
+    gen_spr_BookE206(env, 0x000000DF, tlbncfg, mmucfg);
     /* XXX : not implemented */
     spr_register(env, SPR_HID0, "HID0",
                  SPR_NOACCESS, SPR_NOACCESS,
@@ -5049,7 +5067,7 @@ static void init_proc_e500(CPUPPCState *env, int version)
                  &spr_read_generic, SPR_NOACCESS,
                  0x00000000);
     /* XXX better abstract into Emb.xxx features */
-    if (version == fsl_e5500) {
+    if ((version == fsl_e5500) || (version == fsl_e6500)) {
         spr_register(env, SPR_BOOKE_EPCR, "EPCR",
                      SPR_NOACCESS, SPR_NOACCESS,
                      &spr_read_generic, &spr_write_generic,
@@ -5061,6 +5079,30 @@ static void init_proc_e500(CPUPPCState *env, int version)
         ivpr_mask = (target_ulong)~0xFFFFULL;
     }
 
+    if (version == fsl_e6500) {
+        spr_register(env, SPR_BOOKE_SPRG8, "SPRG8",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     0x00000000);
+        spr_register(env, SPR_BOOKE_SPRG9, "SPRG9",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, &spr_write_generic,
+                     0x00000000);
+        /* Thread identification */
+        spr_register(env, SPR_TIR, "TIR",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, SPR_NOACCESS,
+                     0x00000000);
+        spr_register(env, SPR_BOOKE_TLB0PS, "TLB0PS",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, SPR_NOACCESS,
+                     0x00000004);
+        spr_register(env, SPR_BOOKE_TLB1PS, "TLB1PS",
+                     SPR_NOACCESS, SPR_NOACCESS,
+                     &spr_read_generic, SPR_NOACCESS,
+                     0x7FFFFFFC);
+    }
+
 #if !defined(CONFIG_USER_ONLY)
     env->nb_tlb = 0;
     env->tlb_type = TLB_MAS;
@@ -5253,6 +5295,55 @@ POWERPC_FAMILY(e5500)(ObjectClass *oc, void *data)
     pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
                  POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK;
 }
+
+static void init_proc_e6500(CPUPPCState *env)
+{
+    init_proc_e500(env, fsl_e6500);
+}
+
+POWERPC_FAMILY(e6500)(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
+
+    dc->desc = "e6500 core";
+    pcc->init_proc = init_proc_e6500;
+    pcc->check_pow = check_pow_none;
+    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_MFTB |
+                       PPC_WRTEE | PPC_RFDI | PPC_RFMCI |
+                       PPC_CACHE | PPC_CACHE_LOCK | PPC_CACHE_ICBI |
+                       PPC_CACHE_DCBZ | PPC_CACHE_DCBA |
+                       PPC_FLOAT | PPC_FLOAT_FRES |
+                       PPC_FLOAT_FRSQRTE | PPC_FLOAT_FSEL |
+                       PPC_FLOAT_STFIWX | PPC_WAIT |
+                       PPC_MEM_TLBSYNC | PPC_TLBIVAX | PPC_MEM_SYNC |
+                       PPC_64B | PPC_POPCNTB | PPC_POPCNTWD | PPC_ALTIVEC;
+    pcc->insns_flags2 = PPC2_BOOKE206 | PPC2_PRCNTL | PPC2_PERM_ISA206 | \
+                        PPC2_FP_CVT_S64 | PPC2_ATOMIC_ISA206;
+    pcc->msr_mask = (1ull << MSR_CM) |
+                    (1ull << MSR_GS) |
+                    (1ull << MSR_UCLE) |
+                    (1ull << MSR_CE) |
+                    (1ull << MSR_EE) |
+                    (1ull << MSR_PR) |
+                    (1ull << MSR_FP) |
+                    (1ull << MSR_ME) |
+                    (1ull << MSR_FE0) |
+                    (1ull << MSR_DE) |
+                    (1ull << MSR_FE1) |
+                    (1ull << MSR_IS) |
+                    (1ull << MSR_DS) |
+                    (1ull << MSR_PX) |
+                    (1ull << MSR_RI) |
+                    (1ull << MSR_VR);
+    pcc->mmu_model = POWERPC_MMU_BOOKE206;
+    pcc->excp_model = POWERPC_EXCP_BOOKE;
+    pcc->bus_model = PPC_FLAGS_INPUT_BookE;
+    pcc->bfd_mach = bfd_mach_ppc_e500;
+    pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE |
+                 POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE;
+}
+
 #endif
 
 /* Non-embedded PowerPC                                                      */
@@ -9813,42 +9904,15 @@ static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
     PowerPCCPU *cpu = POWERPC_CPU(dev);
     PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
     Error *local_err = NULL;
-#if !defined(CONFIG_USER_ONLY)
-    int max_smt = kvmppc_smt_threads();
-#endif
-
-#if !defined(CONFIG_USER_ONLY)
-    if (smp_threads > max_smt) {
-        error_setg(errp, "Cannot support more than %d threads on PPC with %s",
-                   max_smt, kvm_enabled() ? "KVM" : "TCG");
-        return;
-    }
-    if (!is_power_of_2(smp_threads)) {
-        error_setg(errp, "Cannot support %d threads on PPC with %s, "
-                   "threads count must be a power of 2.",
-                   smp_threads, kvm_enabled() ? "KVM" : "TCG");
-        return;
-    }
-#endif
 
     cpu_exec_realizefn(cs, &local_err);
     if (local_err != NULL) {
         error_propagate(errp, local_err);
         return;
     }
-
-#if !defined(CONFIG_USER_ONLY)
-    cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
-        + (cs->cpu_index % smp_threads);
-
-    if (kvm_enabled() && !kvm_vcpu_id_is_valid(cpu->cpu_dt_id)) {
-        error_setg(errp, "Can't create CPU with id %d in KVM", cpu->cpu_dt_id);
-        error_append_hint(errp, "Adjust the number of cpus to %d "
-                          "or try to raise the number of threads per core\n",
-                          cpu->cpu_dt_id * smp_threads / max_smt);
-        goto unrealize;
+    if (cpu->vcpu_id == UNASSIGNED_CPU_INDEX) {
+        cpu->vcpu_id = cs->cpu_index;
     }
-#endif
 
     if (tcg_enabled()) {
         if (ppc_fixup_cpu(cpu) != 0) {
@@ -10176,83 +10240,38 @@ PowerPCCPUClass *ppc_cpu_class_by_pvr_mask(uint32_t pvr)
     return pcc;
 }
 
-static gint ppc_cpu_compare_class_name(gconstpointer a, gconstpointer b)
-{
-    ObjectClass *oc = (ObjectClass *)a;
-    const char *name = b;
-    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);
-
-    if (strncasecmp(name, object_class_get_name(oc), strlen(name)) == 0 &&
-        ppc_cpu_is_valid(pcc) &&
-        strcmp(object_class_get_name(oc) + strlen(name),
-               "-" TYPE_POWERPC_CPU) == 0) {
-        return 0;
-    }
-    return -1;
-}
-
-
-static ObjectClass *ppc_cpu_class_by_name(const char *name);
-
-static ObjectClass *ppc_cpu_class_by_alias(PowerPCCPUAlias *alias)
-{
-    ObjectClass *invalid_class = (void*)ppc_cpu_class_by_alias;
-
-    /* Cache target class lookups in the alias table */
-    if (!alias->oc) {
-        alias->oc = ppc_cpu_class_by_name(alias->model);
-        if (!alias->oc) {
-            /* Fast check for non-existing aliases */
-            alias->oc = invalid_class;
-        }
-    }
-
-    if (alias->oc == invalid_class) {
-        return NULL;
-    } else {
-        return alias->oc;
-    }
-}
-
 static ObjectClass *ppc_cpu_class_by_name(const char *name)
 {
-    GSList *list, *item;
-    ObjectClass *ret = NULL;
+    char *cpu_model, *typename;
+    ObjectClass *oc;
     const char *p;
-    int i, len;
-
-    /* Check if the given name is a PVR */
-    len = strlen(name);
-    if (len == 10 && name[0] == '0' && name[1] == 'x') {
-        p = name + 2;
-        goto check_pvr;
-    } else if (len == 8) {
-        p = name;
-    check_pvr:
-        for (i = 0; i < 8; i++) {
-            if (!qemu_isxdigit(*p++))
-                break;
-        }
-        if (i == 8) {
-            return OBJECT_CLASS(ppc_cpu_class_by_pvr(strtoul(name, NULL, 16)));
+    unsigned long pvr;
+
+    /* Lookup by PVR if cpu_model is valid 8 digit hex number
+     * (excl: 0x prefix if present)
+     */
+    if (!qemu_strtoul(name, &p, 16, &pvr)) {
+        int len = p - name;
+        len = (len == 10) && (name[1] == 'x') ? len - 2 : len;
+        if ((len == 8) && (*p == '\0')) {
+            return OBJECT_CLASS(ppc_cpu_class_by_pvr(pvr));
         }
     }
 
-    list = object_class_get_list(TYPE_POWERPC_CPU, false);
-    item = g_slist_find_custom(list, name, ppc_cpu_compare_class_name);
-    if (item != NULL) {
-        ret = OBJECT_CLASS(item->data);
+    cpu_model = g_ascii_strdown(name, -1);
+    p = ppc_cpu_lookup_alias(cpu_model);
+    if (p) {
+        g_free(cpu_model);
+        cpu_model = g_strdup(p);
     }
-    g_slist_free(list);
 
-    if (ret) {
-        return ret;
-    }
+    typename = g_strdup_printf("%s" POWERPC_CPU_TYPE_SUFFIX, cpu_model);
+    oc = object_class_by_name(typename);
+    g_free(typename);
+    g_free(cpu_model);
 
-    for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
-        if (strcmp(ppc_cpu_aliases[i].alias, name) == 0) {
-            return ppc_cpu_class_by_alias(&ppc_cpu_aliases[i]);
-        }
+    if (oc && ppc_cpu_is_valid(POWERPC_CPU_CLASS(oc))) {
+        return oc;
     }
 
     return NULL;
@@ -10327,12 +10346,12 @@ static void ppc_cpu_list_entry(gpointer data, gpointer user_data)
     }
 
     name = g_strndup(typename,
-                     strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
+                     strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
     (*s->cpu_fprintf)(s->file, "PowerPC %-16s PVR %08x\n",
                       name, pcc->pvr);
     for (i = 0; ppc_cpu_aliases[i].alias != NULL; i++) {
         PowerPCCPUAlias *alias = &ppc_cpu_aliases[i];
-        ObjectClass *alias_oc = ppc_cpu_class_by_alias(alias);
+        ObjectClass *alias_oc = ppc_cpu_class_by_name(alias->model);
 
         if (alias_oc != oc) {
             continue;
@@ -10388,7 +10407,7 @@ static void ppc_cpu_defs_entry(gpointer data, gpointer user_data)
     typename = object_class_get_name(oc);
     info = g_malloc0(sizeof(*info));
     info->name = g_strndup(typename,
-                           strlen(typename) - strlen("-" TYPE_POWERPC_CPU));
+                           strlen(typename) - strlen(POWERPC_CPU_TYPE_SUFFIX));
 
     entry = g_malloc0(sizeof(*entry));
     entry->value = info;
@@ -10412,7 +10431,7 @@ CpuDefinitionInfoList *arch_query_cpu_definitions(Error **errp)
         CpuDefinitionInfoList *entry;
         CpuDefinitionInfo *info;
 
-        oc = ppc_cpu_class_by_alias(alias);
+        oc = ppc_cpu_class_by_name(alias->model);
         if (oc == NULL) {
             continue;
         }
@@ -10544,6 +10563,7 @@ static void ppc_cpu_initfn(Object *obj)
     CPUPPCState *env = &cpu->env;
 
     cs->env_ptr = env;
+    cpu->vcpu_id = UNASSIGNED_CPU_INDEX;
 
     env->msr_mask = pcc->msr_mask;
     env->mmu_model = pcc->mmu_model;