aboutsummaryrefslogtreecommitdiff
path: root/hw/ppc/ppc4xx_devs.c
diff options
context:
space:
mode:
authorBALATON Zoltan <balaton@eik.bme.hu>2022-09-24 14:27:56 +0200
committerDaniel Henrique Barboza <danielhb413@gmail.com>2022-10-17 16:15:09 -0300
commit4fc30e153a0fbb11bd6826cf67d52b1d9122bac3 (patch)
treeebfc6d64ccd657f940c2dbccf8e4429161a9857b /hw/ppc/ppc4xx_devs.c
parent0aedcc8a8db88967d3abbff433bdd1f5a4b9ce6d (diff)
ppc4xx_sdram: QOM'ify
Change the ppc4xx_sdram model to a QOM class derived from the PPC4xx-dcr-device and name it ppc4xx-sdram-ddr. This is mostly modelling the DDR SDRAM controller found in the 440EP (used on the bamboo board) but also backward compatible with the older DDR controllers on some 405 SoCs so we also use it for those now. This likely does not cause problems for guests we run as the new features are just not accessed but to model 405 SoC accurately some features may have to be disabled or the model split between 440 and older. Newer SoCs (regardless of their PPC core, e.g. 405EX) may have an updated DDR2 SDRAM controller implemented by the ppc440_sdram model (only partially, enough for the 460EX on the sam460ex) that is not yet QOM'ified in this patch. That is intended to become ppc4xx-sdram-ddr2 when QOM'ified later. Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu> Reviewed-by: Cédric Le Goater <clg@kaod.org> Message-Id: <8f820487fc9011343032c422ecdf3e8ee74d8c11.1664021647.git.balaton@eik.bme.hu> Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Diffstat (limited to 'hw/ppc/ppc4xx_devs.c')
-rw-r--r--hw/ppc/ppc4xx_devs.c105
1 files changed, 57 insertions, 48 deletions
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index 2e0343970f..3d700e5c85 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -38,24 +38,6 @@
/*****************************************************************************/
/* SDRAM controller */
-typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
-struct ppc4xx_sdram_t {
- uint32_t addr;
- int nbanks; /* Banks to use from the 4, e.g. when board has less slots */
- Ppc4xxSdramBank bank[4];
- uint32_t besr0;
- uint32_t besr1;
- uint32_t bear;
- uint32_t cfg;
- uint32_t status;
- uint32_t rtr;
- uint32_t pmit;
- uint32_t tr;
- uint32_t ecccfg;
- uint32_t eccesr;
- qemu_irq irq;
-};
-
enum {
SDRAM0_CFGADDR = 0x010,
SDRAM0_CFGDATA = 0x011,
@@ -66,7 +48,7 @@ enum {
* there are type inconsistencies, mixing hwaddr, target_ulong
* and uint32_t
*/
-static uint32_t sdram_bcr(hwaddr ram_base, hwaddr ram_size)
+static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size)
{
uint32_t bcr;
@@ -124,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(Ppc4xxSdramDdrState *sdram, int i,
uint32_t bcr, int enabled)
{
if (sdram->bank[i].bcr & 0x00000001) {
@@ -150,21 +132,21 @@ 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(Ppc4xxSdramDdrState *sdram)
{
int i;
for (i = 0; i < sdram->nbanks; i++) {
if (sdram->bank[i].size != 0) {
- sdram_set_bcr(sdram, i, sdram_bcr(sdram->bank[i].base,
- sdram->bank[i].size), 1);
+ sdram_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base,
+ sdram->bank[i].size), 1);
} else {
sdram_set_bcr(sdram, i, 0x00000000, 0);
}
}
}
-static void sdram_unmap_bcr(ppc4xx_sdram_t *sdram)
+static void sdram_unmap_bcr(Ppc4xxSdramDdrState *sdram)
{
int i;
@@ -176,12 +158,11 @@ static void sdram_unmap_bcr(ppc4xx_sdram_t *sdram)
}
}
-static uint32_t dcr_read_sdram(void *opaque, int dcrn)
+static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn)
{
- ppc4xx_sdram_t *sdram;
+ Ppc4xxSdramDdrState *sdram = opaque;
uint32_t ret;
- sdram = opaque;
switch (dcrn) {
case SDRAM0_CFGADDR:
ret = sdram->addr;
@@ -244,11 +225,10 @@ static uint32_t dcr_read_sdram(void *opaque, int dcrn)
return ret;
}
-static void dcr_write_sdram(void *opaque, int dcrn, uint32_t val)
+static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val)
{
- ppc4xx_sdram_t *sdram;
+ Ppc4xxSdramDdrState *sdram = opaque;
- sdram = opaque;
switch (dcrn) {
case SDRAM0_CFGADDR:
sdram->addr = val;
@@ -327,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_ddr_reset(DeviceState *dev)
{
- ppc4xx_sdram_t *sdram;
+ Ppc4xxSdramDdrState *sdram = PPC4xx_SDRAM_DDR(dev);
- sdram = opaque;
sdram->addr = 0x00000000;
sdram->bear = 0x00000000;
sdram->besr0 = 0x00000000; /* No error */
@@ -347,29 +326,54 @@ static void sdram_reset(void *opaque)
sdram->cfg = 0x00800000;
}
-void ppc4xx_sdram_init(CPUPPCState *env, qemu_irq irq, int nbanks,
- MemoryRegion *ram)
+static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp)
{
- ppc4xx_sdram_t *sdram;
+ Ppc4xxSdramDdrState *s = PPC4xx_SDRAM_DDR(dev);
+ Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev);
const ram_addr_t valid_bank_sizes[] = {
256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * MiB, 0
};
- sdram = g_new0(ppc4xx_sdram_t, 1);
- sdram->irq = irq;
- sdram->nbanks = nbanks;
- ppc4xx_sdram_banks(ram, sdram->nbanks, sdram->bank, valid_bank_sizes);
- qemu_register_reset(&sdram_reset, sdram);
- ppc_dcr_register(env, SDRAM0_CFGADDR,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
- ppc_dcr_register(env, SDRAM0_CFGDATA,
- sdram, &dcr_read_sdram, &dcr_write_sdram);
+ if (s->nbanks < 1 || s->nbanks > 4) {
+ error_setg(errp, "Invalid number of RAM banks");
+ return;
+ }
+ if (!s->dram_mr) {
+ error_setg(errp, "Missing dram memory region");
+ return;
+ }
+ ppc4xx_sdram_banks(s->dram_mr, s->nbanks, s->bank, valid_bank_sizes);
+
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
+
+ ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR,
+ s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
+ ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA,
+ s, &sdram_ddr_dcr_read, &sdram_ddr_dcr_write);
}
-void ppc4xx_sdram_enable(CPUPPCState *env)
+static Property ppc4xx_sdram_ddr_props[] = {
+ DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REGION,
+ MemoryRegion *),
+ DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+
+ dc->realize = ppc4xx_sdram_ddr_realize;
+ dc->reset = ppc4xx_sdram_ddr_reset;
+ /* Reason: only works as function of a ppc4xx SoC */
+ dc->user_creatable = false;
+ device_class_set_props(dc, ppc4xx_sdram_ddr_props);
+}
+
+void ppc4xx_sdram_enable(Ppc4xxSdramDdrState *s)
{
- ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x20);
- ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x80000000);
+ sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20);
+ sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000);
}
/*
@@ -959,6 +963,11 @@ static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data)
static const TypeInfo ppc4xx_types[] = {
{
+ .name = TYPE_PPC4xx_SDRAM_DDR,
+ .parent = TYPE_PPC4xx_DCR_DEVICE,
+ .instance_size = sizeof(Ppc4xxSdramDdrState),
+ .class_init = ppc4xx_sdram_ddr_class_init,
+ }, {
.name = TYPE_PPC4xx_MAL,
.parent = TYPE_PPC4xx_DCR_DEVICE,
.instance_size = sizeof(Ppc4xxMalState),