target-ppc: move PPC4xx SDRAM controller emulation from ppc405_uc.c to ppc4xx_devs.c
The SDRAM controller is shared across almost all 405 and 440 embedded processors, with some slight differences such as the sizes supported for each memory bank. Code movement only; no functional changes. Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6061 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
f5d6f51ba6
commit
61b2440503
@ -66,11 +66,6 @@ void ppc4xx_pob_init (CPUState *env);
|
||||
/* OPB arbitrer */
|
||||
void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio,
|
||||
target_phys_addr_t offset);
|
||||
/* SDRAM controller */
|
||||
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
|
||||
target_phys_addr_t *ram_bases,
|
||||
target_phys_addr_t *ram_sizes,
|
||||
int do_init);
|
||||
/* Peripheral controller */
|
||||
void ppc405_ebc_init (CPUState *env);
|
||||
/* DMA controller */
|
||||
|
341
hw/ppc405_uc.c
341
hw/ppc405_uc.c
@ -400,347 +400,6 @@ void ppc4xx_opba_init (CPUState *env, ppc4xx_mmio_t *mmio,
|
||||
/* Code decompression controller */
|
||||
/* XXX: TODO */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SDRAM controller */
|
||||
typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
|
||||
struct ppc4xx_sdram_t {
|
||||
uint32_t addr;
|
||||
int nbanks;
|
||||
target_phys_addr_t ram_bases[4];
|
||||
target_phys_addr_t 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,
|
||||
};
|
||||
|
||||
/* XXX: TOFIX: some patches have made this code become inconsistent:
|
||||
* there are type inconsistencies, mixing target_phys_addr_t, target_ulong
|
||||
* and uint32_t
|
||||
*/
|
||||
static uint32_t sdram_bcr (target_phys_addr_t ram_base,
|
||||
target_phys_addr_t ram_size)
|
||||
{
|
||||
uint32_t bcr;
|
||||
|
||||
switch (ram_size) {
|
||||
case (4 * 1024 * 1024):
|
||||
bcr = 0x00000000;
|
||||
break;
|
||||
case (8 * 1024 * 1024):
|
||||
bcr = 0x00020000;
|
||||
break;
|
||||
case (16 * 1024 * 1024):
|
||||
bcr = 0x00040000;
|
||||
break;
|
||||
case (32 * 1024 * 1024):
|
||||
bcr = 0x00060000;
|
||||
break;
|
||||
case (64 * 1024 * 1024):
|
||||
bcr = 0x00080000;
|
||||
break;
|
||||
case (128 * 1024 * 1024):
|
||||
bcr = 0x000A0000;
|
||||
break;
|
||||
case (256 * 1024 * 1024):
|
||||
bcr = 0x000C0000;
|
||||
break;
|
||||
default:
|
||||
printf("%s: invalid RAM size " PADDRX "\n", __func__, ram_size);
|
||||
return 0x00000000;
|
||||
}
|
||||
bcr |= ram_base & 0xFF800000;
|
||||
bcr |= 1;
|
||||
|
||||
return bcr;
|
||||
}
|
||||
|
||||
static always_inline target_phys_addr_t sdram_base (uint32_t bcr)
|
||||
{
|
||||
return bcr & 0xFF800000;
|
||||
}
|
||||
|
||||
static target_ulong sdram_size (uint32_t bcr)
|
||||
{
|
||||
target_ulong size;
|
||||
int sh;
|
||||
|
||||
sh = (bcr >> 17) & 0x7;
|
||||
if (sh == 7)
|
||||
size = -1;
|
||||
else
|
||||
size = (4 * 1024 * 1024) << sh;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
|
||||
{
|
||||
if (*bcrp & 0x00000001) {
|
||||
/* Unmap RAM */
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: unmap RAM area " PADDRX " " ADDRX "\n",
|
||||
__func__, sdram_base(*bcrp), sdram_size(*bcrp));
|
||||
#endif
|
||||
cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),
|
||||
IO_MEM_UNASSIGNED);
|
||||
}
|
||||
*bcrp = bcr & 0xFFDEE001;
|
||||
if (enabled && (bcr & 0x00000001)) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: Map RAM area " PADDRX " " ADDRX "\n",
|
||||
__func__, sdram_base(bcr), sdram_size(bcr));
|
||||
#endif
|
||||
cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),
|
||||
sdram_base(bcr) | IO_MEM_RAM);
|
||||
}
|
||||
}
|
||||
|
||||
static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sdram->nbanks; i++) {
|
||||
if (sdram->ram_sizes[i] != 0) {
|
||||
sdram_set_bcr(&sdram->bcr[i],
|
||||
sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
|
||||
1);
|
||||
} else {
|
||||
sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sdram->nbanks; i++) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: Unmap RAM area " PADDRX " " ADDRX "\n",
|
||||
__func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
|
||||
#endif
|
||||
cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
|
||||
sdram_size(sdram->bcr[i]),
|
||||
IO_MEM_UNASSIGNED);
|
||||
}
|
||||
}
|
||||
|
||||
static target_ulong dcr_read_sdram (void *opaque, int dcrn)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
target_ulong ret;
|
||||
|
||||
sdram = opaque;
|
||||
switch (dcrn) {
|
||||
case SDRAM0_CFGADDR:
|
||||
ret = sdram->addr;
|
||||
break;
|
||||
case SDRAM0_CFGDATA:
|
||||
switch (sdram->addr) {
|
||||
case 0x00: /* SDRAM_BESR0 */
|
||||
ret = sdram->besr0;
|
||||
break;
|
||||
case 0x08: /* SDRAM_BESR1 */
|
||||
ret = sdram->besr1;
|
||||
break;
|
||||
case 0x10: /* SDRAM_BEAR */
|
||||
ret = sdram->bear;
|
||||
break;
|
||||
case 0x20: /* SDRAM_CFG */
|
||||
ret = sdram->cfg;
|
||||
break;
|
||||
case 0x24: /* SDRAM_STATUS */
|
||||
ret = sdram->status;
|
||||
break;
|
||||
case 0x30: /* SDRAM_RTR */
|
||||
ret = sdram->rtr;
|
||||
break;
|
||||
case 0x34: /* SDRAM_PMIT */
|
||||
ret = sdram->pmit;
|
||||
break;
|
||||
case 0x40: /* SDRAM_B0CR */
|
||||
ret = sdram->bcr[0];
|
||||
break;
|
||||
case 0x44: /* SDRAM_B1CR */
|
||||
ret = sdram->bcr[1];
|
||||
break;
|
||||
case 0x48: /* SDRAM_B2CR */
|
||||
ret = sdram->bcr[2];
|
||||
break;
|
||||
case 0x4C: /* SDRAM_B3CR */
|
||||
ret = sdram->bcr[3];
|
||||
break;
|
||||
case 0x80: /* SDRAM_TR */
|
||||
ret = -1; /* ? */
|
||||
break;
|
||||
case 0x94: /* SDRAM_ECCCFG */
|
||||
ret = sdram->ecccfg;
|
||||
break;
|
||||
case 0x98: /* SDRAM_ECCESR */
|
||||
ret = sdram->eccesr;
|
||||
break;
|
||||
default: /* Error */
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Avoid gcc warning */
|
||||
ret = 0x00000000;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dcr_write_sdram (void *opaque, int dcrn, target_ulong val)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
|
||||
sdram = opaque;
|
||||
switch (dcrn) {
|
||||
case SDRAM0_CFGADDR:
|
||||
sdram->addr = val;
|
||||
break;
|
||||
case SDRAM0_CFGDATA:
|
||||
switch (sdram->addr) {
|
||||
case 0x00: /* SDRAM_BESR0 */
|
||||
sdram->besr0 &= ~val;
|
||||
break;
|
||||
case 0x08: /* SDRAM_BESR1 */
|
||||
sdram->besr1 &= ~val;
|
||||
break;
|
||||
case 0x10: /* SDRAM_BEAR */
|
||||
sdram->bear = val;
|
||||
break;
|
||||
case 0x20: /* SDRAM_CFG */
|
||||
val &= 0xFFE00000;
|
||||
if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: enable SDRAM controller\n", __func__);
|
||||
#endif
|
||||
/* validate all RAM mappings */
|
||||
sdram_map_bcr(sdram);
|
||||
sdram->status &= ~0x80000000;
|
||||
} else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: disable SDRAM controller\n", __func__);
|
||||
#endif
|
||||
/* invalidate all RAM mappings */
|
||||
sdram_unmap_bcr(sdram);
|
||||
sdram->status |= 0x80000000;
|
||||
}
|
||||
if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
|
||||
sdram->status |= 0x40000000;
|
||||
else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
|
||||
sdram->status &= ~0x40000000;
|
||||
sdram->cfg = val;
|
||||
break;
|
||||
case 0x24: /* SDRAM_STATUS */
|
||||
/* Read-only register */
|
||||
break;
|
||||
case 0x30: /* SDRAM_RTR */
|
||||
sdram->rtr = val & 0x3FF80000;
|
||||
break;
|
||||
case 0x34: /* SDRAM_PMIT */
|
||||
sdram->pmit = (val & 0xF8000000) | 0x07C00000;
|
||||
break;
|
||||
case 0x40: /* SDRAM_B0CR */
|
||||
sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x44: /* SDRAM_B1CR */
|
||||
sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x48: /* SDRAM_B2CR */
|
||||
sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x4C: /* SDRAM_B3CR */
|
||||
sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x80: /* SDRAM_TR */
|
||||
sdram->tr = val & 0x018FC01F;
|
||||
break;
|
||||
case 0x94: /* SDRAM_ECCCFG */
|
||||
sdram->ecccfg = val & 0x00F00000;
|
||||
break;
|
||||
case 0x98: /* SDRAM_ECCESR */
|
||||
val &= 0xFFF0F000;
|
||||
if (sdram->eccesr == 0 && val != 0)
|
||||
qemu_irq_raise(sdram->irq);
|
||||
else if (sdram->eccesr != 0 && val == 0)
|
||||
qemu_irq_lower(sdram->irq);
|
||||
sdram->eccesr = val;
|
||||
break;
|
||||
default: /* Error */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sdram_reset (void *opaque)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
|
||||
sdram = opaque;
|
||||
sdram->addr = 0x00000000;
|
||||
sdram->bear = 0x00000000;
|
||||
sdram->besr0 = 0x00000000; /* No error */
|
||||
sdram->besr1 = 0x00000000; /* No error */
|
||||
sdram->cfg = 0x00000000;
|
||||
sdram->ecccfg = 0x00000000; /* No ECC */
|
||||
sdram->eccesr = 0x00000000; /* No error */
|
||||
sdram->pmit = 0x07C00000;
|
||||
sdram->rtr = 0x05F00000;
|
||||
sdram->tr = 0x00854009;
|
||||
/* We pre-initialize RAM banks */
|
||||
sdram->status = 0x00000000;
|
||||
sdram->cfg = 0x00800000;
|
||||
sdram_unmap_bcr(sdram);
|
||||
}
|
||||
|
||||
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
|
||||
target_phys_addr_t *ram_bases,
|
||||
target_phys_addr_t *ram_sizes,
|
||||
int do_init)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
|
||||
sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));
|
||||
if (sdram != NULL) {
|
||||
sdram->irq = irq;
|
||||
sdram->nbanks = nbanks;
|
||||
memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
|
||||
memcpy(sdram->ram_bases, ram_bases,
|
||||
nbanks * sizeof(target_phys_addr_t));
|
||||
memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));
|
||||
memcpy(sdram->ram_sizes, ram_sizes,
|
||||
nbanks * sizeof(target_phys_addr_t));
|
||||
sdram_reset(sdram);
|
||||
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 (do_init)
|
||||
sdram_map_bcr(sdram);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Peripheral controller */
|
||||
typedef struct ppc4xx_ebc_t ppc4xx_ebc_t;
|
||||
|
@ -48,6 +48,11 @@ enum {
|
||||
qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
|
||||
uint32_t dcr_base, int has_ssr, int has_vr);
|
||||
|
||||
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
|
||||
target_phys_addr_t *ram_bases,
|
||||
target_phys_addr_t *ram_sizes,
|
||||
int do_init);
|
||||
|
||||
PCIBus *ppc4xx_pci_init(CPUState *env, qemu_irq pci_irqs[4],
|
||||
target_phys_addr_t config_space,
|
||||
target_phys_addr_t int_ack,
|
||||
|
341
hw/ppc4xx_devs.c
341
hw/ppc4xx_devs.c
@ -532,3 +532,344 @@ qemu_irq *ppcuic_init (CPUState *env, qemu_irq *irqs,
|
||||
|
||||
return qemu_allocate_irqs(&ppcuic_set_irq, uic, UIC_MAX_IRQ);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* SDRAM controller */
|
||||
typedef struct ppc4xx_sdram_t ppc4xx_sdram_t;
|
||||
struct ppc4xx_sdram_t {
|
||||
uint32_t addr;
|
||||
int nbanks;
|
||||
target_phys_addr_t ram_bases[4];
|
||||
target_phys_addr_t 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,
|
||||
};
|
||||
|
||||
/* XXX: TOFIX: some patches have made this code become inconsistent:
|
||||
* there are type inconsistencies, mixing target_phys_addr_t, target_ulong
|
||||
* and uint32_t
|
||||
*/
|
||||
static uint32_t sdram_bcr (target_phys_addr_t ram_base,
|
||||
target_phys_addr_t ram_size)
|
||||
{
|
||||
uint32_t bcr;
|
||||
|
||||
switch (ram_size) {
|
||||
case (4 * 1024 * 1024):
|
||||
bcr = 0x00000000;
|
||||
break;
|
||||
case (8 * 1024 * 1024):
|
||||
bcr = 0x00020000;
|
||||
break;
|
||||
case (16 * 1024 * 1024):
|
||||
bcr = 0x00040000;
|
||||
break;
|
||||
case (32 * 1024 * 1024):
|
||||
bcr = 0x00060000;
|
||||
break;
|
||||
case (64 * 1024 * 1024):
|
||||
bcr = 0x00080000;
|
||||
break;
|
||||
case (128 * 1024 * 1024):
|
||||
bcr = 0x000A0000;
|
||||
break;
|
||||
case (256 * 1024 * 1024):
|
||||
bcr = 0x000C0000;
|
||||
break;
|
||||
default:
|
||||
printf("%s: invalid RAM size " PADDRX "\n", __func__, ram_size);
|
||||
return 0x00000000;
|
||||
}
|
||||
bcr |= ram_base & 0xFF800000;
|
||||
bcr |= 1;
|
||||
|
||||
return bcr;
|
||||
}
|
||||
|
||||
static always_inline target_phys_addr_t sdram_base (uint32_t bcr)
|
||||
{
|
||||
return bcr & 0xFF800000;
|
||||
}
|
||||
|
||||
static target_ulong sdram_size (uint32_t bcr)
|
||||
{
|
||||
target_ulong size;
|
||||
int sh;
|
||||
|
||||
sh = (bcr >> 17) & 0x7;
|
||||
if (sh == 7)
|
||||
size = -1;
|
||||
else
|
||||
size = (4 * 1024 * 1024) << sh;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void sdram_set_bcr (uint32_t *bcrp, uint32_t bcr, int enabled)
|
||||
{
|
||||
if (*bcrp & 0x00000001) {
|
||||
/* Unmap RAM */
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: unmap RAM area " PADDRX " " ADDRX "\n",
|
||||
__func__, sdram_base(*bcrp), sdram_size(*bcrp));
|
||||
#endif
|
||||
cpu_register_physical_memory(sdram_base(*bcrp), sdram_size(*bcrp),
|
||||
IO_MEM_UNASSIGNED);
|
||||
}
|
||||
*bcrp = bcr & 0xFFDEE001;
|
||||
if (enabled && (bcr & 0x00000001)) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: Map RAM area " PADDRX " " ADDRX "\n",
|
||||
__func__, sdram_base(bcr), sdram_size(bcr));
|
||||
#endif
|
||||
cpu_register_physical_memory(sdram_base(bcr), sdram_size(bcr),
|
||||
sdram_base(bcr) | IO_MEM_RAM);
|
||||
}
|
||||
}
|
||||
|
||||
static void sdram_map_bcr (ppc4xx_sdram_t *sdram)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sdram->nbanks; i++) {
|
||||
if (sdram->ram_sizes[i] != 0) {
|
||||
sdram_set_bcr(&sdram->bcr[i],
|
||||
sdram_bcr(sdram->ram_bases[i], sdram->ram_sizes[i]),
|
||||
1);
|
||||
} else {
|
||||
sdram_set_bcr(&sdram->bcr[i], 0x00000000, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sdram_unmap_bcr (ppc4xx_sdram_t *sdram)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sdram->nbanks; i++) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: Unmap RAM area " PADDRX " " ADDRX "\n",
|
||||
__func__, sdram_base(sdram->bcr[i]), sdram_size(sdram->bcr[i]));
|
||||
#endif
|
||||
cpu_register_physical_memory(sdram_base(sdram->bcr[i]),
|
||||
sdram_size(sdram->bcr[i]),
|
||||
IO_MEM_UNASSIGNED);
|
||||
}
|
||||
}
|
||||
|
||||
static target_ulong dcr_read_sdram (void *opaque, int dcrn)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
target_ulong ret;
|
||||
|
||||
sdram = opaque;
|
||||
switch (dcrn) {
|
||||
case SDRAM0_CFGADDR:
|
||||
ret = sdram->addr;
|
||||
break;
|
||||
case SDRAM0_CFGDATA:
|
||||
switch (sdram->addr) {
|
||||
case 0x00: /* SDRAM_BESR0 */
|
||||
ret = sdram->besr0;
|
||||
break;
|
||||
case 0x08: /* SDRAM_BESR1 */
|
||||
ret = sdram->besr1;
|
||||
break;
|
||||
case 0x10: /* SDRAM_BEAR */
|
||||
ret = sdram->bear;
|
||||
break;
|
||||
case 0x20: /* SDRAM_CFG */
|
||||
ret = sdram->cfg;
|
||||
break;
|
||||
case 0x24: /* SDRAM_STATUS */
|
||||
ret = sdram->status;
|
||||
break;
|
||||
case 0x30: /* SDRAM_RTR */
|
||||
ret = sdram->rtr;
|
||||
break;
|
||||
case 0x34: /* SDRAM_PMIT */
|
||||
ret = sdram->pmit;
|
||||
break;
|
||||
case 0x40: /* SDRAM_B0CR */
|
||||
ret = sdram->bcr[0];
|
||||
break;
|
||||
case 0x44: /* SDRAM_B1CR */
|
||||
ret = sdram->bcr[1];
|
||||
break;
|
||||
case 0x48: /* SDRAM_B2CR */
|
||||
ret = sdram->bcr[2];
|
||||
break;
|
||||
case 0x4C: /* SDRAM_B3CR */
|
||||
ret = sdram->bcr[3];
|
||||
break;
|
||||
case 0x80: /* SDRAM_TR */
|
||||
ret = -1; /* ? */
|
||||
break;
|
||||
case 0x94: /* SDRAM_ECCCFG */
|
||||
ret = sdram->ecccfg;
|
||||
break;
|
||||
case 0x98: /* SDRAM_ECCESR */
|
||||
ret = sdram->eccesr;
|
||||
break;
|
||||
default: /* Error */
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* Avoid gcc warning */
|
||||
ret = 0x00000000;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dcr_write_sdram (void *opaque, int dcrn, target_ulong val)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
|
||||
sdram = opaque;
|
||||
switch (dcrn) {
|
||||
case SDRAM0_CFGADDR:
|
||||
sdram->addr = val;
|
||||
break;
|
||||
case SDRAM0_CFGDATA:
|
||||
switch (sdram->addr) {
|
||||
case 0x00: /* SDRAM_BESR0 */
|
||||
sdram->besr0 &= ~val;
|
||||
break;
|
||||
case 0x08: /* SDRAM_BESR1 */
|
||||
sdram->besr1 &= ~val;
|
||||
break;
|
||||
case 0x10: /* SDRAM_BEAR */
|
||||
sdram->bear = val;
|
||||
break;
|
||||
case 0x20: /* SDRAM_CFG */
|
||||
val &= 0xFFE00000;
|
||||
if (!(sdram->cfg & 0x80000000) && (val & 0x80000000)) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: enable SDRAM controller\n", __func__);
|
||||
#endif
|
||||
/* validate all RAM mappings */
|
||||
sdram_map_bcr(sdram);
|
||||
sdram->status &= ~0x80000000;
|
||||
} else if ((sdram->cfg & 0x80000000) && !(val & 0x80000000)) {
|
||||
#ifdef DEBUG_SDRAM
|
||||
printf("%s: disable SDRAM controller\n", __func__);
|
||||
#endif
|
||||
/* invalidate all RAM mappings */
|
||||
sdram_unmap_bcr(sdram);
|
||||
sdram->status |= 0x80000000;
|
||||
}
|
||||
if (!(sdram->cfg & 0x40000000) && (val & 0x40000000))
|
||||
sdram->status |= 0x40000000;
|
||||
else if ((sdram->cfg & 0x40000000) && !(val & 0x40000000))
|
||||
sdram->status &= ~0x40000000;
|
||||
sdram->cfg = val;
|
||||
break;
|
||||
case 0x24: /* SDRAM_STATUS */
|
||||
/* Read-only register */
|
||||
break;
|
||||
case 0x30: /* SDRAM_RTR */
|
||||
sdram->rtr = val & 0x3FF80000;
|
||||
break;
|
||||
case 0x34: /* SDRAM_PMIT */
|
||||
sdram->pmit = (val & 0xF8000000) | 0x07C00000;
|
||||
break;
|
||||
case 0x40: /* SDRAM_B0CR */
|
||||
sdram_set_bcr(&sdram->bcr[0], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x44: /* SDRAM_B1CR */
|
||||
sdram_set_bcr(&sdram->bcr[1], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x48: /* SDRAM_B2CR */
|
||||
sdram_set_bcr(&sdram->bcr[2], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x4C: /* SDRAM_B3CR */
|
||||
sdram_set_bcr(&sdram->bcr[3], val, sdram->cfg & 0x80000000);
|
||||
break;
|
||||
case 0x80: /* SDRAM_TR */
|
||||
sdram->tr = val & 0x018FC01F;
|
||||
break;
|
||||
case 0x94: /* SDRAM_ECCCFG */
|
||||
sdram->ecccfg = val & 0x00F00000;
|
||||
break;
|
||||
case 0x98: /* SDRAM_ECCESR */
|
||||
val &= 0xFFF0F000;
|
||||
if (sdram->eccesr == 0 && val != 0)
|
||||
qemu_irq_raise(sdram->irq);
|
||||
else if (sdram->eccesr != 0 && val == 0)
|
||||
qemu_irq_lower(sdram->irq);
|
||||
sdram->eccesr = val;
|
||||
break;
|
||||
default: /* Error */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void sdram_reset (void *opaque)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
|
||||
sdram = opaque;
|
||||
sdram->addr = 0x00000000;
|
||||
sdram->bear = 0x00000000;
|
||||
sdram->besr0 = 0x00000000; /* No error */
|
||||
sdram->besr1 = 0x00000000; /* No error */
|
||||
sdram->cfg = 0x00000000;
|
||||
sdram->ecccfg = 0x00000000; /* No ECC */
|
||||
sdram->eccesr = 0x00000000; /* No error */
|
||||
sdram->pmit = 0x07C00000;
|
||||
sdram->rtr = 0x05F00000;
|
||||
sdram->tr = 0x00854009;
|
||||
/* We pre-initialize RAM banks */
|
||||
sdram->status = 0x00000000;
|
||||
sdram->cfg = 0x00800000;
|
||||
sdram_unmap_bcr(sdram);
|
||||
}
|
||||
|
||||
void ppc405_sdram_init (CPUState *env, qemu_irq irq, int nbanks,
|
||||
target_phys_addr_t *ram_bases,
|
||||
target_phys_addr_t *ram_sizes,
|
||||
int do_init)
|
||||
{
|
||||
ppc4xx_sdram_t *sdram;
|
||||
|
||||
sdram = qemu_mallocz(sizeof(ppc4xx_sdram_t));
|
||||
if (sdram != NULL) {
|
||||
sdram->irq = irq;
|
||||
sdram->nbanks = nbanks;
|
||||
memset(sdram->ram_bases, 0, 4 * sizeof(target_phys_addr_t));
|
||||
memcpy(sdram->ram_bases, ram_bases,
|
||||
nbanks * sizeof(target_phys_addr_t));
|
||||
memset(sdram->ram_sizes, 0, 4 * sizeof(target_phys_addr_t));
|
||||
memcpy(sdram->ram_sizes, ram_sizes,
|
||||
nbanks * sizeof(target_phys_addr_t));
|
||||
sdram_reset(sdram);
|
||||
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 (do_init)
|
||||
sdram_map_bcr(sdram);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user