diff options
author | BALATON Zoltan <balaton@eik.bme.hu> | 2022-09-24 14:28:05 +0200 |
---|---|---|
committer | Daniel Henrique Barboza <danielhb413@gmail.com> | 2022-10-17 16:15:09 -0300 |
commit | 5f7effe4df91702add08e3e3dc1871fd35a8903f (patch) | |
tree | 89358baf72693eebfcda20b276612de1d74dfc94 /hw/ppc/ppc440_uc.c | |
parent | ef10aebb9a71f0c60f0b7aae808498333bb7bfd9 (diff) |
ppc440_sdram: QOM'ify
Change the ppc440_sdram model to a QOM class derived from the
PPC4xx-dcr-device and name it ppc4xx-sdram-ddr2. This is mostly
modelling the DDR2 SDRAM controller found in the 460EX (used on the
sam460ex board). Newer SoCs (regardless of their PPC core, e.g. 405EX)
may have this controller but we only emulate enough of it for the
sam460ex u-boot firmware.
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Reviewed-by: Cédric Le Goater <clg@kaod.org>
Message-Id: <3e82ae575c7c41e464a0082d55ecb4ebcc4d4329.1664021647.git.balaton@eik.bme.hu>
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Diffstat (limited to 'hw/ppc/ppc440_uc.c')
-rw-r--r-- | hw/ppc/ppc440_uc.c | 121 |
1 files changed, 74 insertions, 47 deletions
diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index dd873d892c..55082f2b88 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -484,13 +484,6 @@ void ppc4xx_sdr_init(CPUPPCState *env) /*****************************************************************************/ /* SDRAM controller */ -typedef struct ppc440_sdram_t { - uint32_t addr; - uint32_t mcopt2; - int nbanks; /* Banks to use from the 4, e.g. when board has less slots */ - Ppc4xxSdramBank bank[4]; -} ppc440_sdram_t; - enum { SDRAM0_CFGADDR = 0x10, SDRAM0_CFGDATA, @@ -581,7 +574,7 @@ static void sdram_bank_unmap(Ppc4xxSdramBank *bank) object_unparent(OBJECT(&bank->container)); } -static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i, +static void sdram_ddr2_set_bcr(Ppc4xxSdramDdr2State *sdram, int i, uint32_t bcr, int enabled) { if (sdram->bank[i].bcr & 1) { @@ -597,7 +590,7 @@ static void sdram_ddr2_set_bcr(ppc440_sdram_t *sdram, int i, } } -static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram) +static void sdram_ddr2_map_bcr(Ppc4xxSdramDdr2State *sdram) { int i; @@ -612,7 +605,7 @@ static void sdram_ddr2_map_bcr(ppc440_sdram_t *sdram) } } -static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram) +static void sdram_ddr2_unmap_bcr(Ppc4xxSdramDdr2State *sdram) { int i; @@ -625,7 +618,7 @@ static void sdram_ddr2_unmap_bcr(ppc440_sdram_t *sdram) static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) { - ppc440_sdram_t *sdram = opaque; + Ppc4xxSdramDdr2State *sdram = opaque; uint32_t ret = 0; switch (dcrn) { @@ -680,7 +673,7 @@ static uint32_t sdram_ddr2_dcr_read(void *opaque, int dcrn) static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) { - ppc440_sdram_t *sdram = opaque; + Ppc4xxSdramDdr2State *sdram = opaque; switch (dcrn) { case SDRAM_R0BAS: @@ -724,18 +717,18 @@ static void sdram_ddr2_dcr_write(void *opaque, int dcrn, uint32_t val) } } -static void sdram_ddr2_reset(void *opaque) +static void ppc4xx_sdram_ddr2_reset(DeviceState *dev) { - ppc440_sdram_t *sdram = opaque; + Ppc4xxSdramDdr2State *sdram = PPC4xx_SDRAM_DDR2(dev); sdram->addr = 0; sdram->mcopt2 = 0; } -void ppc440_sdram_init(CPUPPCState *env, int nbanks, - MemoryRegion *ram) +static void ppc4xx_sdram_ddr2_realize(DeviceState *dev, Error **errp) { - ppc440_sdram_t *s; + Ppc4xxSdramDdr2State *s = PPC4xx_SDRAM_DDR2(dev); + Ppc4xxDcrDeviceState *dcr = PPC4xx_DCR_DEVICE(dev); /* * SoC also has 4 GiB but that causes problem with 32 bit * builds (4*GiB overflows the 32 bit ram_addr_t). @@ -745,41 +738,75 @@ void ppc440_sdram_init(CPUPPCState *env, int nbanks, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 0 }; - s = g_malloc0(sizeof(*s)); - s->nbanks = nbanks; - ppc4xx_sdram_banks(ram, s->nbanks, s->bank, valid_bank_sizes); - qemu_register_reset(&sdram_ddr2_reset, s); - ppc_dcr_register(env, SDRAM0_CFGADDR, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM0_CFGDATA, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - - ppc_dcr_register(env, SDRAM_R0BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_R1BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_R2BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_R3BAS, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_CONF1HB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_PLBADDULL, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_CONF1LL, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_CONFPATHB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); - ppc_dcr_register(env, SDRAM_PLBADDUHB, - s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + 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); + + ppc4xx_dcr_register(dcr, SDRAM0_CFGADDR, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM0_CFGDATA, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + + ppc4xx_dcr_register(dcr, SDRAM_R0BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R1BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R2BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_R3BAS, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONF1HB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_PLBADDULL, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONF1LL, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_CONFPATHB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); + ppc4xx_dcr_register(dcr, SDRAM_PLBADDUHB, + s, &sdram_ddr2_dcr_read, &sdram_ddr2_dcr_write); +} + +static Property ppc4xx_sdram_ddr2_props[] = { + DEFINE_PROP_LINK("dram", Ppc4xxSdramDdr2State, dram_mr, TYPE_MEMORY_REGION, + MemoryRegion *), + DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4), + DEFINE_PROP_END_OF_LIST(), +}; + +static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = ppc4xx_sdram_ddr2_realize; + dc->reset = ppc4xx_sdram_ddr2_reset; + /* Reason: only works as function of a ppc4xx SoC */ + dc->user_creatable = false; + device_class_set_props(dc, ppc4xx_sdram_ddr2_props); } -void ppc4xx_sdram_ddr2_enable(CPUPPCState *env) +void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) { - ppc_dcr_write(env->dcr_env, SDRAM0_CFGADDR, 0x21); - ppc_dcr_write(env->dcr_env, SDRAM0_CFGDATA, 0x08000000); + sdram_ddr2_dcr_write(s, SDRAM0_CFGADDR, 0x21); + sdram_ddr2_dcr_write(s, SDRAM0_CFGDATA, 0x08000000); } +static const TypeInfo ppc4xx_types[] = { + { + .name = TYPE_PPC4xx_SDRAM_DDR2, + .parent = TYPE_PPC4xx_DCR_DEVICE, + .instance_size = sizeof(Ppc4xxSdramDdr2State), + .class_init = ppc4xx_sdram_ddr2_class_init, + } +}; +DEFINE_TYPES(ppc4xx_types) + /*****************************************************************************/ /* PLB to AHB bridge */ enum { |