From nobody Sun Feb 8 18:10:39 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=eik.bme.hu Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1666196101990827.641530447394; Wed, 19 Oct 2022 09:15:01 -0700 (PDT) Received: from localhost ([::1]:46140 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1olBic-0002eQ-4J for importer@patchew.org; Wed, 19 Oct 2022 12:14:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59848) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1olBXK-0006hT-A2; Wed, 19 Oct 2022 12:03:58 -0400 Received: from zero.eik.bme.hu ([152.66.115.2]:60144) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1olBX0-0001Rp-99; Wed, 19 Oct 2022 12:03:15 -0400 Received: from zero.eik.bme.hu (blah.eik.bme.hu [152.66.115.182]) by localhost (Postfix) with SMTP id 65A7175A174; Wed, 19 Oct 2022 18:02:53 +0200 (CEST) Received: by zero.eik.bme.hu (Postfix, from userid 432) id 2A4D575A16C; Wed, 19 Oct 2022 18:02:53 +0200 (CEST) Message-Id: <3ea98072dbeb757942e25dcfcdd6a7a47738d2ca.1666194485.git.balaton@eik.bme.hu> In-Reply-To: References: From: BALATON Zoltan Subject: [PATCH v7 2/8] ppc4xx_devs.c: Move DDR SDRAM controller model to ppc4xx_sdram.c MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Cc: clg@kaod.org, philmd@linaro.org, Daniel Henrique Barboza Date: Wed, 19 Oct 2022 18:02:53 +0200 (CEST) X-Spam-Probability: 8% Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=152.66.115.2; envelope-from=balaton@eik.bme.hu; helo=zero.eik.bme.hu X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_PASS=-0.001, T_SPF_HELO_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1666196103521100001 Signed-off-by: BALATON Zoltan Reviewed-by: Daniel Henrique Barboza --- hw/ppc/ppc4xx_devs.c | 352 ---------------------------------------- hw/ppc/ppc4xx_sdram.c | 365 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 365 insertions(+), 352 deletions(-) diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c index 12af90f244..f737dbb3d6 100644 --- a/hw/ppc/ppc4xx_devs.c +++ b/hw/ppc/ppc4xx_devs.c @@ -24,357 +24,10 @@ =20 #include "qemu/osdep.h" #include "qemu/units.h" -#include "sysemu/reset.h" #include "cpu.h" -#include "hw/irq.h" -#include "hw/ppc/ppc.h" #include "hw/ppc/ppc4xx.h" #include "hw/qdev-properties.h" -#include "qemu/log.h" -#include "exec/address-spaces.h" -#include "qemu/error-report.h" #include "qapi/error.h" -#include "trace.h" - -/*************************************************************************= ****/ -/* SDRAM controller */ -enum { - SDRAM0_CFGADDR =3D 0x010, - SDRAM0_CFGDATA =3D 0x011, -}; - -/* - * XXX: TOFIX: some patches have made this code become inconsistent: - * there are type inconsistencies, mixing hwaddr, target_ulong - * and uint32_t - */ -static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) -{ - uint32_t bcr; - - switch (ram_size) { - case 4 * MiB: - bcr =3D 0; - break; - case 8 * MiB: - bcr =3D 0x20000; - break; - case 16 * MiB: - bcr =3D 0x40000; - break; - case 32 * MiB: - bcr =3D 0x60000; - break; - case 64 * MiB: - bcr =3D 0x80000; - break; - case 128 * MiB: - bcr =3D 0xA0000; - break; - case 256 * MiB: - bcr =3D 0xC0000; - break; - default: - qemu_log_mask(LOG_GUEST_ERROR, - "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func_= _, - ram_size); - return 0; - } - bcr |=3D ram_base & 0xFF800000; - bcr |=3D 1; - - return bcr; -} - -static inline hwaddr sdram_ddr_base(uint32_t bcr) -{ - return bcr & 0xFF800000; -} - -static target_ulong sdram_ddr_size(uint32_t bcr) -{ - target_ulong size; - int sh; - - sh =3D (bcr >> 17) & 0x7; - if (sh =3D=3D 7) { - size =3D -1; - } else { - size =3D (4 * MiB) << sh; - } - - return size; -} - -static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i, - uint32_t bcr, int enabled) -{ - if (sdram->bank[i].bcr & 1) { - /* Unmap RAM */ - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].container); - memory_region_del_subregion(&sdram->bank[i].container, - &sdram->bank[i].ram); - object_unparent(OBJECT(&sdram->bank[i].container)); - } - sdram->bank[i].bcr =3D bcr & 0xFFDEE001; - if (enabled && (bcr & 1)) { - trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr)); - memory_region_init(&sdram->bank[i].container, NULL, "sdram-contain= er", - sdram_ddr_size(bcr)); - memory_region_add_subregion(&sdram->bank[i].container, 0, - &sdram->bank[i].ram); - memory_region_add_subregion(get_system_memory(), - sdram_ddr_base(bcr), - &sdram->bank[i].container); - } -} - -static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i =3D 0; i < sdram->nbanks; i++) { - if (sdram->bank[i].size !=3D 0) { - sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base, - sdram->bank[i].size)= , 1); - } else { - sdram_ddr_set_bcr(sdram, i, 0, 0); - } - } -} - -static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram) -{ - int i; - - for (i =3D 0; i < sdram->nbanks; i++) { - trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), - sdram_ddr_size(sdram->bank[i].bcr)); - memory_region_del_subregion(get_system_memory(), - &sdram->bank[i].ram); - } -} - -static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) -{ - Ppc4xxSdramDdrState *sdram =3D opaque; - uint32_t ret; - - switch (dcrn) { - case SDRAM0_CFGADDR: - ret =3D sdram->addr; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* SDRAM_BESR0 */ - ret =3D sdram->besr0; - break; - case 0x08: /* SDRAM_BESR1 */ - ret =3D sdram->besr1; - break; - case 0x10: /* SDRAM_BEAR */ - ret =3D sdram->bear; - break; - case 0x20: /* SDRAM_CFG */ - ret =3D sdram->cfg; - break; - case 0x24: /* SDRAM_STATUS */ - ret =3D sdram->status; - break; - case 0x30: /* SDRAM_RTR */ - ret =3D sdram->rtr; - break; - case 0x34: /* SDRAM_PMIT */ - ret =3D sdram->pmit; - break; - case 0x40: /* SDRAM_B0CR */ - ret =3D sdram->bank[0].bcr; - break; - case 0x44: /* SDRAM_B1CR */ - ret =3D sdram->bank[1].bcr; - break; - case 0x48: /* SDRAM_B2CR */ - ret =3D sdram->bank[2].bcr; - break; - case 0x4C: /* SDRAM_B3CR */ - ret =3D sdram->bank[3].bcr; - break; - case 0x80: /* SDRAM_TR */ - ret =3D -1; /* ? */ - break; - case 0x94: /* SDRAM_ECCCFG */ - ret =3D sdram->ecccfg; - break; - case 0x98: /* SDRAM_ECCESR */ - ret =3D sdram->eccesr; - break; - default: /* Error */ - ret =3D -1; - break; - } - break; - default: - /* Avoid gcc warning */ - ret =3D 0; - break; - } - - return ret; -} - -static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) -{ - Ppc4xxSdramDdrState *sdram =3D opaque; - - switch (dcrn) { - case SDRAM0_CFGADDR: - sdram->addr =3D val; - break; - case SDRAM0_CFGDATA: - switch (sdram->addr) { - case 0x00: /* SDRAM_BESR0 */ - sdram->besr0 &=3D ~val; - break; - case 0x08: /* SDRAM_BESR1 */ - sdram->besr1 &=3D ~val; - break; - case 0x10: /* SDRAM_BEAR */ - sdram->bear =3D val; - break; - case 0x20: /* SDRAM_CFG */ - val &=3D 0xFFE00000; - if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) { - trace_ppc4xx_sdram_enable("enable"); - /* validate all RAM mappings */ - sdram_ddr_map_bcr(sdram); - sdram->status &=3D ~0x80000000; - } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) { - trace_ppc4xx_sdram_enable("disable"); - /* invalidate all RAM mappings */ - sdram_ddr_unmap_bcr(sdram); - sdram->status |=3D 0x80000000; - } - if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) { - sdram->status |=3D 0x40000000; - } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) { - sdram->status &=3D ~0x40000000; - } - sdram->cfg =3D val; - break; - case 0x24: /* SDRAM_STATUS */ - /* Read-only register */ - break; - case 0x30: /* SDRAM_RTR */ - sdram->rtr =3D val & 0x3FF80000; - break; - case 0x34: /* SDRAM_PMIT */ - sdram->pmit =3D (val & 0xF8000000) | 0x07C00000; - break; - case 0x40: /* SDRAM_B0CR */ - sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000); - break; - case 0x44: /* SDRAM_B1CR */ - sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000); - break; - case 0x48: /* SDRAM_B2CR */ - sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000); - break; - case 0x4C: /* SDRAM_B3CR */ - sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000); - break; - case 0x80: /* SDRAM_TR */ - sdram->tr =3D val & 0x018FC01F; - break; - case 0x94: /* SDRAM_ECCCFG */ - sdram->ecccfg =3D val & 0x00F00000; - break; - case 0x98: /* SDRAM_ECCESR */ - val &=3D 0xFFF0F000; - if (sdram->eccesr =3D=3D 0 && val !=3D 0) { - qemu_irq_raise(sdram->irq); - } else if (sdram->eccesr !=3D 0 && val =3D=3D 0) { - qemu_irq_lower(sdram->irq); - } - sdram->eccesr =3D val; - break; - default: /* Error */ - break; - } - break; - } -} - -static void ppc4xx_sdram_ddr_reset(DeviceState *dev) -{ - Ppc4xxSdramDdrState *sdram =3D PPC4xx_SDRAM_DDR(dev); - - sdram->addr =3D 0; - sdram->bear =3D 0; - sdram->besr0 =3D 0; /* No error */ - sdram->besr1 =3D 0; /* No error */ - sdram->cfg =3D 0; - sdram->ecccfg =3D 0; /* No ECC */ - sdram->eccesr =3D 0; /* No error */ - sdram->pmit =3D 0x07C00000; - sdram->rtr =3D 0x05F00000; - sdram->tr =3D 0x00854009; - /* We pre-initialize RAM banks */ - sdram->status =3D 0; - sdram->cfg =3D 0x00800000; -} - -static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) -{ - Ppc4xxSdramDdrState *s =3D PPC4xx_SDRAM_DDR(dev); - Ppc4xxDcrDeviceState *dcr =3D PPC4xx_DCR_DEVICE(dev); - const ram_addr_t valid_bank_sizes[] =3D { - 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * M= iB, 0 - }; - - 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); -} - -static Property ppc4xx_sdram_ddr_props[] =3D { - DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REG= ION, - 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 =3D DEVICE_CLASS(oc); - - dc->realize =3D ppc4xx_sdram_ddr_realize; - dc->reset =3D ppc4xx_sdram_ddr_reset; - /* Reason: only works as function of a ppc4xx SoC */ - dc->user_creatable =3D false; - device_class_set_props(dc, ppc4xx_sdram_ddr_props); -} - -void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) -{ - sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20); - sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000); -} =20 /* * Split RAM between SDRAM banks. @@ -963,11 +616,6 @@ static void ppc4xx_dcr_class_init(ObjectClass *oc, voi= d *data) =20 static const TypeInfo ppc4xx_types[] =3D { { - .name =3D TYPE_PPC4xx_SDRAM_DDR, - .parent =3D TYPE_PPC4xx_DCR_DEVICE, - .instance_size =3D sizeof(Ppc4xxSdramDdrState), - .class_init =3D ppc4xx_sdram_ddr_class_init, - }, { .name =3D TYPE_PPC4xx_MAL, .parent =3D TYPE_PPC4xx_DCR_DEVICE, .instance_size =3D sizeof(Ppc4xxMalState), diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index b49a7ed60a..d88363bc3d 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -1,4 +1,27 @@ /* + * QEMU PowerPC 4xx embedded processors SDRAM controller emulation + * + * DDR SDRAM controller: + * 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"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * 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 OT= HER + * 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. + * * DDR2 SDRAM controller: * Copyright (c) 2012 Fran=C3=A7ois Revol * Copyright (c) 2016-2019 BALATON Zoltan @@ -9,7 +32,9 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" +#include "qemu/log.h" #include "exec/address-spaces.h" /* get_system_memory() */ +#include "exec/cpu-defs.h" /* target_ulong */ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/ppc/ppc4xx.h" @@ -38,6 +63,341 @@ enum { SDRAM0_CFGDATA =3D 0x011, }; =20 +/*************************************************************************= ****/ +/* DDR SDRAM controller */ +/* + * XXX: TOFIX: some patches have made this code become inconsistent: + * there are type inconsistencies, mixing hwaddr, target_ulong + * and uint32_t + */ +static uint32_t sdram_ddr_bcr(hwaddr ram_base, hwaddr ram_size) +{ + uint32_t bcr; + + switch (ram_size) { + case 4 * MiB: + bcr =3D 0; + break; + case 8 * MiB: + bcr =3D 0x20000; + break; + case 16 * MiB: + bcr =3D 0x40000; + break; + case 32 * MiB: + bcr =3D 0x60000; + break; + case 64 * MiB: + bcr =3D 0x80000; + break; + case 128 * MiB: + bcr =3D 0xA0000; + break; + case 256 * MiB: + bcr =3D 0xC0000; + break; + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: invalid RAM size 0x%" HWADDR_PRIx "\n", __func_= _, + ram_size); + return 0; + } + bcr |=3D ram_base & 0xFF800000; + bcr |=3D 1; + + return bcr; +} + +static inline hwaddr sdram_ddr_base(uint32_t bcr) +{ + return bcr & 0xFF800000; +} + +static target_ulong sdram_ddr_size(uint32_t bcr) +{ + target_ulong size; + int sh; + + sh =3D (bcr >> 17) & 0x7; + if (sh =3D=3D 7) { + size =3D -1; + } else { + size =3D (4 * MiB) << sh; + } + + return size; +} + +static void sdram_ddr_set_bcr(Ppc4xxSdramDdrState *sdram, int i, + uint32_t bcr, int enabled) +{ + if (sdram->bank[i].bcr & 1) { + /* Unmap RAM */ + trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), + sdram_ddr_size(sdram->bank[i].bcr)); + memory_region_del_subregion(get_system_memory(), + &sdram->bank[i].container); + memory_region_del_subregion(&sdram->bank[i].container, + &sdram->bank[i].ram); + object_unparent(OBJECT(&sdram->bank[i].container)); + } + sdram->bank[i].bcr =3D bcr & 0xFFDEE001; + if (enabled && (bcr & 1)) { + trace_ppc4xx_sdram_map(sdram_ddr_base(bcr), sdram_ddr_size(bcr)); + memory_region_init(&sdram->bank[i].container, NULL, "sdram-contain= er", + sdram_ddr_size(bcr)); + memory_region_add_subregion(&sdram->bank[i].container, 0, + &sdram->bank[i].ram); + memory_region_add_subregion(get_system_memory(), + sdram_ddr_base(bcr), + &sdram->bank[i].container); + } +} + +static void sdram_ddr_map_bcr(Ppc4xxSdramDdrState *sdram) +{ + int i; + + for (i =3D 0; i < sdram->nbanks; i++) { + if (sdram->bank[i].size !=3D 0) { + sdram_ddr_set_bcr(sdram, i, sdram_ddr_bcr(sdram->bank[i].base, + sdram->bank[i].size)= , 1); + } else { + sdram_ddr_set_bcr(sdram, i, 0, 0); + } + } +} + +static void sdram_ddr_unmap_bcr(Ppc4xxSdramDdrState *sdram) +{ + int i; + + for (i =3D 0; i < sdram->nbanks; i++) { + trace_ppc4xx_sdram_unmap(sdram_ddr_base(sdram->bank[i].bcr), + sdram_ddr_size(sdram->bank[i].bcr)); + memory_region_del_subregion(get_system_memory(), + &sdram->bank[i].ram); + } +} + +static uint32_t sdram_ddr_dcr_read(void *opaque, int dcrn) +{ + Ppc4xxSdramDdrState *sdram =3D opaque; + uint32_t ret; + + switch (dcrn) { + case SDRAM0_CFGADDR: + ret =3D sdram->addr; + break; + case SDRAM0_CFGDATA: + switch (sdram->addr) { + case 0x00: /* SDRAM_BESR0 */ + ret =3D sdram->besr0; + break; + case 0x08: /* SDRAM_BESR1 */ + ret =3D sdram->besr1; + break; + case 0x10: /* SDRAM_BEAR */ + ret =3D sdram->bear; + break; + case 0x20: /* SDRAM_CFG */ + ret =3D sdram->cfg; + break; + case 0x24: /* SDRAM_STATUS */ + ret =3D sdram->status; + break; + case 0x30: /* SDRAM_RTR */ + ret =3D sdram->rtr; + break; + case 0x34: /* SDRAM_PMIT */ + ret =3D sdram->pmit; + break; + case 0x40: /* SDRAM_B0CR */ + ret =3D sdram->bank[0].bcr; + break; + case 0x44: /* SDRAM_B1CR */ + ret =3D sdram->bank[1].bcr; + break; + case 0x48: /* SDRAM_B2CR */ + ret =3D sdram->bank[2].bcr; + break; + case 0x4C: /* SDRAM_B3CR */ + ret =3D sdram->bank[3].bcr; + break; + case 0x80: /* SDRAM_TR */ + ret =3D -1; /* ? */ + break; + case 0x94: /* SDRAM_ECCCFG */ + ret =3D sdram->ecccfg; + break; + case 0x98: /* SDRAM_ECCESR */ + ret =3D sdram->eccesr; + break; + default: /* Error */ + ret =3D -1; + break; + } + break; + default: + /* Avoid gcc warning */ + ret =3D 0; + break; + } + + return ret; +} + +static void sdram_ddr_dcr_write(void *opaque, int dcrn, uint32_t val) +{ + Ppc4xxSdramDdrState *sdram =3D opaque; + + switch (dcrn) { + case SDRAM0_CFGADDR: + sdram->addr =3D val; + break; + case SDRAM0_CFGDATA: + switch (sdram->addr) { + case 0x00: /* SDRAM_BESR0 */ + sdram->besr0 &=3D ~val; + break; + case 0x08: /* SDRAM_BESR1 */ + sdram->besr1 &=3D ~val; + break; + case 0x10: /* SDRAM_BEAR */ + sdram->bear =3D val; + break; + case 0x20: /* SDRAM_CFG */ + val &=3D 0xFFE00000; + if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) { + trace_ppc4xx_sdram_enable("enable"); + /* validate all RAM mappings */ + sdram_ddr_map_bcr(sdram); + sdram->status &=3D ~0x80000000; + } else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) { + trace_ppc4xx_sdram_enable("disable"); + /* invalidate all RAM mappings */ + sdram_ddr_unmap_bcr(sdram); + sdram->status |=3D 0x80000000; + } + if (!(sdram->cfg & 0x40000000) && (val & 0x40000000)) { + sdram->status |=3D 0x40000000; + } else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000)) { + sdram->status &=3D ~0x40000000; + } + sdram->cfg =3D val; + break; + case 0x24: /* SDRAM_STATUS */ + /* Read-only register */ + break; + case 0x30: /* SDRAM_RTR */ + sdram->rtr =3D val & 0x3FF80000; + break; + case 0x34: /* SDRAM_PMIT */ + sdram->pmit =3D (val & 0xF8000000) | 0x07C00000; + break; + case 0x40: /* SDRAM_B0CR */ + sdram_ddr_set_bcr(sdram, 0, val, sdram->cfg & 0x80000000); + break; + case 0x44: /* SDRAM_B1CR */ + sdram_ddr_set_bcr(sdram, 1, val, sdram->cfg & 0x80000000); + break; + case 0x48: /* SDRAM_B2CR */ + sdram_ddr_set_bcr(sdram, 2, val, sdram->cfg & 0x80000000); + break; + case 0x4C: /* SDRAM_B3CR */ + sdram_ddr_set_bcr(sdram, 3, val, sdram->cfg & 0x80000000); + break; + case 0x80: /* SDRAM_TR */ + sdram->tr =3D val & 0x018FC01F; + break; + case 0x94: /* SDRAM_ECCCFG */ + sdram->ecccfg =3D val & 0x00F00000; + break; + case 0x98: /* SDRAM_ECCESR */ + val &=3D 0xFFF0F000; + if (sdram->eccesr =3D=3D 0 && val !=3D 0) { + qemu_irq_raise(sdram->irq); + } else if (sdram->eccesr !=3D 0 && val =3D=3D 0) { + qemu_irq_lower(sdram->irq); + } + sdram->eccesr =3D val; + break; + default: /* Error */ + break; + } + break; + } +} + +static void ppc4xx_sdram_ddr_reset(DeviceState *dev) +{ + Ppc4xxSdramDdrState *sdram =3D PPC4xx_SDRAM_DDR(dev); + + sdram->addr =3D 0; + sdram->bear =3D 0; + sdram->besr0 =3D 0; /* No error */ + sdram->besr1 =3D 0; /* No error */ + sdram->cfg =3D 0; + sdram->ecccfg =3D 0; /* No ECC */ + sdram->eccesr =3D 0; /* No error */ + sdram->pmit =3D 0x07C00000; + sdram->rtr =3D 0x05F00000; + sdram->tr =3D 0x00854009; + /* We pre-initialize RAM banks */ + sdram->status =3D 0; + sdram->cfg =3D 0x00800000; +} + +static void ppc4xx_sdram_ddr_realize(DeviceState *dev, Error **errp) +{ + Ppc4xxSdramDdrState *s =3D PPC4xx_SDRAM_DDR(dev); + Ppc4xxDcrDeviceState *dcr =3D PPC4xx_DCR_DEVICE(dev); + const ram_addr_t valid_bank_sizes[] =3D { + 256 * MiB, 128 * MiB, 64 * MiB, 32 * MiB, 16 * MiB, 8 * MiB, 4 * M= iB, 0 + }; + + 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); +} + +static Property ppc4xx_sdram_ddr_props[] =3D { + DEFINE_PROP_LINK("dram", Ppc4xxSdramDdrState, dram_mr, TYPE_MEMORY_REG= ION, + 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 =3D DEVICE_CLASS(oc); + + dc->realize =3D ppc4xx_sdram_ddr_realize; + dc->reset =3D ppc4xx_sdram_ddr_reset; + /* Reason: only works as function of a ppc4xx SoC */ + dc->user_creatable =3D false; + device_class_set_props(dc, ppc4xx_sdram_ddr_props); +} + +void ppc4xx_sdram_ddr_enable(Ppc4xxSdramDdrState *s) +{ + sdram_ddr_dcr_write(s, SDRAM0_CFGADDR, 0x20); + sdram_ddr_dcr_write(s, SDRAM0_CFGDATA, 0x80000000); +} + /*************************************************************************= ****/ /* DDR2 SDRAM controller */ enum { @@ -338,6 +698,11 @@ void ppc4xx_sdram_ddr2_enable(Ppc4xxSdramDdr2State *s) =20 static const TypeInfo ppc4xx_sdram_types[] =3D { { + .name =3D TYPE_PPC4xx_SDRAM_DDR, + .parent =3D TYPE_PPC4xx_DCR_DEVICE, + .instance_size =3D sizeof(Ppc4xxSdramDdrState), + .class_init =3D ppc4xx_sdram_ddr_class_init, + }, { .name =3D TYPE_PPC4xx_SDRAM_DDR2, .parent =3D TYPE_PPC4xx_DCR_DEVICE, .instance_size =3D sizeof(Ppc4xxSdramDdr2State), --=20 2.30.4