diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index 56881b181ba1..8c19d167391c 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -228,12 +228,9 @@ struct Ppc405SoCState {
     DeviceState parent_obj;
 
     /* Public */
-    MemoryRegion ram_banks[2];
-    hwaddr ram_bases[2], ram_sizes[2];
-    bool do_dram_init;
-
     MemoryRegion *dram_mr;
     hwaddr ram_size;
+    uint32_t nr_banks;
 
     PowerPCCPU cpu;
     PPCUIC uic;
@@ -241,6 +238,7 @@ struct Ppc405SoCState {
     Ppc405GptState gpt;
     Ppc405OcmState ocm;
     Ppc405GpioState gpio;
+    Ppc4xxSdramState sdram;
     Ppc405DmaState dma;
     PPC4xxI2CState i2c;
     Ppc405EbcState ebc;
diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
index acd096cb2394..b841f6600b55 100644
--- a/include/hw/ppc/ppc4xx.h
+++ b/include/hw/ppc/ppc4xx.h
@@ -87,4 +87,36 @@ struct Ppc4xxMalState {
 void ppc4xx_mal_init(CPUPPCState *env, uint8_t txcnum, uint8_t rxcnum,
                      qemu_irq irqs[4]);
 
+/* SDRAM controller */
+#define TYPE_PPC4xx_SDRAM "ppc4xx-sdram"
+OBJECT_DECLARE_SIMPLE_TYPE(Ppc4xxSdramState, PPC4xx_SDRAM);
+struct Ppc4xxSdramState {
+    Ppc4xxDcrDeviceState parent_obj;
+
+    MemoryRegion *dram_mr;
+    bool dram_init;
+
+    MemoryRegion containers[4]; /* used for clipping */
+    MemoryRegion *ram_memories;
+    hwaddr *ram_bases;
+    hwaddr *ram_sizes;
+    uint32_t nb_ram_bases;
+    uint32_t nb_ram_sizes;
+    uint32_t nbanks; /* Redundant */
+
+    uint32_t addr;
+    uint32_t besr0;
+    uint32_t besr1;
+    uint32_t bear;
+    uint32_t cfg;
+    uint32_t status;
+    uint32_t rtr;
+    uint32_t pmit;
+    uint32_t bcr[4];
+    uint32_t tr;
+    uint32_t ecccfg;
+    uint32_t eccesr;
+    qemu_irq irq;
+};
+
 #endif /* PPC4XX_H */
diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 1045f5f13e6c..fe0c92ba0d54 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -1361,6 +1361,9 @@ static void ppc405_soc_instance_init(Object *obj)
 
     object_initialize_child(obj, "gpio", &s->gpio, TYPE_PPC405_GPIO);
 
+    object_initialize_child(obj, "sdram", &s->sdram, TYPE_PPC4xx_SDRAM);
+    object_property_add_alias(obj, "dram-init", OBJECT(&s->sdram), "dram-init");
+
     object_initialize_child(obj, "dma", &s->dma, TYPE_PPC405_DMA);
 
     object_initialize_child(obj, "i2c", &s->i2c, TYPE_PPC4xx_I2C);
@@ -1432,15 +1435,28 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 
     /* SDRAM controller */
         /* XXX 405EP has no ECC interrupt */
-    s->ram_bases[0] = 0;
-    s->ram_sizes[0] = s->ram_size;
-    memory_region_init_alias(&s->ram_banks[0], OBJECT(s),
-                             "ppc405.sdram0", s->dram_mr,
-                             s->ram_bases[0], s->ram_sizes[0]);
+    object_property_set_link(OBJECT(&s->sdram), "dram", OBJECT(s->dram_mr),
+                             &error_abort);
+
+    qdev_prop_set_uint32(DEVICE(&s->sdram), "len-ram-sizes", s->nr_banks);
+    qdev_prop_set_uint32(DEVICE(&s->sdram), "len-ram-bases", s->nr_banks);
 
-    ppc4xx_sdram_init(env, qdev_get_gpio_in(DEVICE(&s->uic), 17), 1,
-                      s->ram_banks, s->ram_bases, s->ram_sizes,
-                      s->do_dram_init);
+    for (i = 0; i < s->nr_banks; i++) {
+        char name[32];
+        snprintf(name, sizeof(name), "ram-bases[%d]", i);
+        qdev_prop_set_uint32(DEVICE(&s->sdram), name,
+                             i * s->ram_size / s->nr_banks);
+
+        snprintf(name, sizeof(name), "ram-sizes[%d]", i);
+        qdev_prop_set_uint32(DEVICE(&s->sdram), name,
+                             s->ram_size / s->nr_banks);
+    }
+
+    if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->sdram), &s->cpu, errp)) {
+        return;
+    }
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->sdram), 0,
+                       qdev_get_gpio_in(DEVICE(&s->uic), 17));
 
     /* External bus controller */
     if (!ppc4xx_dcr_realize(PPC4xx_DCR_DEVICE(&s->ebc), &s->cpu, errp)) {
@@ -1520,7 +1536,7 @@ static void ppc405_soc_realize(DeviceState *dev, Error **errp)
 static Property ppc405_soc_properties[] = {
     DEFINE_PROP_LINK("dram", Ppc405SoCState, dram_mr, TYPE_MEMORY_REGION,
                      MemoryRegion *),
-    DEFINE_PROP_BOOL("dram-init", Ppc405SoCState, do_dram_init, 0),
+    DEFINE_PROP_UINT32("nr-banks", Ppc405SoCState, nr_banks, 2),
     DEFINE_PROP_UINT64("ram-size", Ppc405SoCState, ram_size, 0),
     DEFINE_PROP_END_OF_LIST(),
 };
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index c06c20b195cd..a9ceea13f218 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -39,28 +39,6 @@
 
 /*****************************************************************************/
 /* SDRAM controller */
-typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
-struct ppc4xx_sdram_t {
-    uint32_t addr;
-    int nbanks;
-    MemoryRegion containers[4]; /* used for clipping */
-    MemoryRegion *ram_memories;
-    hwaddr ram_bases[4];
-    hwaddr ram_sizes[4];
-    uint32_t besr0;
-    uint32_t besr1;
-    uint32_t bear;
-    uint32_t cfg;
-    uint32_t status;
-    uint32_t rtr;
-    uint32_t pmit;
-    uint32_t bcr[4];
-    uint32_t tr;
-    uint32_t ecccfg;
-    uint32_t eccesr;
-    qemu_irq irq;
-};
-
 enum {
     SDRAM0_CFGADDR = 0x010,
     SDRAM0_CFGDATA = 0x011,
@@ -128,7 +106,7 @@ static target_ulong sdram_size (uint32_t bcr)
     return size;
 }
 
-static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
+static void sdram_set_bcr(Ppc4xxSdramState *sdram, int i,
                           uint32_t bcr, int enabled)
 {
     if (sdram->bcr[i] & 0x00000001) {
@@ -154,7 +132,7 @@ static void sdram_set_bcr(ppc4xx_sdram_t *sdram, int i,
     }
 }
 
-static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
+static void sdram_map_bcr(Ppc4xxSdramState *sdram)
 {
     int i;
 
@@ -168,7 +146,7 @@ static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
     }
 }
 
-static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
+static void sdram_unmap_bcr(Ppc4xxSdramState *sdram)
 {
     int i;
 
@@ -182,7 +160,7 @@ static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
 
 static uint32_t dcr_read_sdram (void *opaque, int dcrn)
 {
-    ppc4xx_sdram_t *sdram;
+    Ppc4xxSdramState *sdram;
     uint32_t ret;
 
     sdram = opaque;
@@ -250,7 +228,7 @@ static uint32_t dcr_read_sdram (void *opaque, int dcrn)
 
 static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val)
 {
-    ppc4xx_sdram_t *sdram;
+    Ppc4xxSdramState *sdram;
 
     sdram = opaque;
     switch (dcrn) {
@@ -329,11 +307,10 @@ static void dcr_write_sdram (void *opaque, int dcrn, uint32_t val)
     }
 }
 
-static void sdram_reset (void *opaque)
+static void ppc4xx_sdram_reset(DeviceState *dev)
 {
-    ppc4xx_sdram_t *sdram;
+    Ppc4xxSdramState *sdram = (Ppc4xxSdramState *) dev;
 
-    sdram = opaque;
     sdram->addr = 0x00000000;
     sdram->bear = 0x00000000;
     sdram->besr0 = 0x00000000; /* No error */
@@ -349,21 +326,88 @@ static void sdram_reset (void *opaque)
     sdram->cfg = 0x00800000;
 }
 
+static void sdram_reset(void *opaque)
+{
+    ppc4xx_sdram_reset(opaque);
+}
+
+static void ppc4xx_sdram_realize(DeviceState *dev, Error **errp)
+{
+    Ppc4xxSdramState *s = PPC4xx_SDRAM(dev);
+    Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
+    int i;
+
+    sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+
+    ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, &dcr_read_sdram, &dcr_write_sdram);
+    ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, &dcr_read_sdram, &dcr_write_sdram);
+
+    if (!s->nb_ram_bases || s->nb_ram_bases != s->nb_ram_sizes) {
+        error_setg(errp, "Invalid number of RAM banks");
+        return;
+    }
+
+    s->ram_memories = g_new0(MemoryRegion, s->nb_ram_bases);
+    for (i = 0; i < s->nb_ram_bases; i++) {
+        g_autofree char *name = g_strdup_printf(TYPE_PPC4xx_SDRAM "%d", i);
+
+        if (!sdram_bcr(s->ram_bases[i], s->ram_sizes[i])) {
+            error_setg(errp, "Invalid RAM size 0x%" HWADDR_PRIx,
+                       s->ram_sizes[i]);
+            return;
+        }
+
+        memory_region_init_alias(&s->ram_memories[i], OBJECT(s), name,
+                                 s->dram_mr, s->ram_bases[i], s->ram_sizes[i]);
+    }
+
+    s->nbanks = s->nb_ram_sizes;
+    if (s->dram_init) {
+        sdram_map_bcr(s);
+    }
+}
+
+static Property ppc4xx_sdram_properties[] = {
+    DEFINE_PROP_LINK("dram", Ppc4xxSdramState, dram_mr, TYPE_MEMORY_REGION,
+                     MemoryRegion *),
+    DEFINE_PROP_BOOL("dram-init", Ppc4xxSdramState, dram_init, false),
+    DEFINE_PROP_ARRAY("ram-sizes", Ppc4xxSdramState, nb_ram_sizes,
+                      ram_sizes, qdev_prop_uint64, uint64_t),
+    DEFINE_PROP_ARRAY("ram-bases", Ppc4xxSdramState, nb_ram_bases,
+                      ram_bases, qdev_prop_uint64, uint64_t),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc4xx_sdram_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = ppc4xx_sdram_realize;
+    dc->user_creatable = false;
+    dc->reset = ppc4xx_sdram_reset;
+    device_class_set_props(dc, ppc4xx_sdram_properties);
+}
+
 void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
                         MemoryRegion *ram_memories,
                         hwaddr *ram_bases,
                         hwaddr *ram_sizes,
                         int do_init)
 {
-    ppc4xx_sdram_t *sdram;
+    Ppc4xxSdramState *sdram;
 
-    sdram = g_new0(ppc4xx_sdram_t, 1);
+    sdram = g_new0(Ppc4xxSdramState, 1);
     sdram->irq = irq;
     sdram->nbanks = nbanks;
     sdram->ram_memories = ram_memories;
+
+    sdram->ram_bases = g_new0(hwaddr, 4);
+
     memset(sdram->ram_bases, 0, 4 * sizeof(hwaddr));
     memcpy(sdram->ram_bases, ram_bases,
            nbanks * sizeof(hwaddr));
+
+    sdram->ram_sizes = g_new0(hwaddr, 4);
     memset(sdram->ram_sizes, 0, 4 * sizeof(hwaddr));
     memcpy(sdram->ram_sizes, ram_sizes,
            nbanks * sizeof(hwaddr));
@@ -683,6 +727,11 @@ static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data)
 
 static const TypeInfo ppc4xx_types[] = {
     {
+        .name           = TYPE_PPC4xx_SDRAM,
+        .parent         = TYPE_PPC4xx_DCR_DEVICE,
+        .instance_size  = sizeof(Ppc4xxSdramState),
+        .class_init     = ppc4xx_sdram_class_init,
+    }, {
         .name           = TYPE_PPC4xx_MAL,
         .parent         = TYPE_PPC4xx_DCR_DEVICE,
         .instance_size  = sizeof(Ppc4xxMalState),
